Aspose.3D를 Python에서 사용하여 3D 메쉬를 만드는 방법
Aspose.3D FOSS for Python은(는) 코드를 통해 3D 기하학을 완전히 구축할 수 있게 해줍니다: 외부 모델링 도구가 필요하지 않습니다. 당신은 Mesh, 정점 위치를 채웁니다 (control_points) 및 면 정의 (polygons), 노멀과 같은 선택적 정점 속성을 부착하고, 그런 다음 장면을 지원되는 모든 포맷으로 저장합니다.
단계별 가이드
1단계: 패키지 설치
PyPI에서 Aspose.3D FOSS를 설치합니다. 네이티브 확장이나 컴파일러 툴체인이 필요하지 않습니다.
pip install aspose-3d-foss설치를 확인합니다:
from aspose.threed import Scene
print("Aspose.3D FOSS ready")지원되는 Python 버전: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
단계 2: 씬과 노드 만들기
모든 메시는 씬 그래프 안에 존재해야 합니다. 생성합니다 Scene 그리고 이름이 지정된 Node 메시를 보관할:
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")노드 이름은 내보낸 파일에 보존되며 디버깅 및 이후에 via node.get_child("triangle").
단계 3: Mesh 객체 만들기
를 인스턴스화합니다 Mesh 옵션 설명 이름과 함께:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")메시는 초기에는 비어 있습니다: 정점도 없고, 폴리곤도 없습니다. 다음 단계에서 채워 넣습니다.
단계 4: 제어점(정점) 추가
제어점은 정점 위치입니다. 각 정점은 로 저장됩니다 Vector4(x, y, z, w) 여기서 w=1 3D 공간의 점을 나타냅니다:
from aspose.threed.utilities import Vector4
##Vertex 0: origin
# Note: control_points returns a copy of the internal vertex list.
# Appending to the returned copy discards the vertex silently.
# Use _control_points to mutate the backing list directly.
# This is a known library limitation — a public add_control_point() API is not yet available.
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))
##Vertex 1: 1 unit along X
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))
##Vertex 2: apex
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))
print(f"Vertices added: {len(mesh.control_points)}")중요: mesh.control_points 를 반환합니다 복사본 내부 정점 리스트의 (getter가 실행되는 list(self._control_points)) . 호출 mesh.control_points.append(v) 복사본에 추가되며, 메시에 추가되지 않으므로 정점이 조용히 버려집니다. 항상 사용 mesh._control_points.append(v) 정점을 추가하려면. 프라이빗 상태에 접근하는 방법은 _control_points 알려진 우회 방법입니다; 인터페이스는 라이브러리의 향후 버전에서 변경될 수 있습니다.
단계 5: 폴리곤 면 만들기
정점 인덱스를 사용하여 면 토폴로지를 정의합니다. 정점 인덱스를 «<SEG_3»>에 전달합니다. create_polygon().인덱스 3개는 triangle을 만들고, 4개는 quad를 만듭니다:
##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)
print(f"Polygon count: {mesh.polygon_count}")quad mesh의 경우 네 개의 인덱스를 전달합니다: mesh.create_polygon(0, 1, 2, 3).
인덱스는 «<SEG_6»>에 유효한 위치여야 합니다 control_points (0-based, within range). Winding order는 outward-facing normals에 대해 counter-clockwise입니다.
단계 6: 정점 노멀 추가
Vertex normals는 로 저장됩니다 VertexElement mesh에 연결됩니다. Use mesh.create_element() 와 VertexElementType.NORMAL, MappingMode.CONTROL_POINT, 그리고 ReferenceMode.DIRECT:
from aspose.threed.entities import VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector4, FVector4
##Create the normal element (returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(
VertexElementType.NORMAL,
MappingMode.CONTROL_POINT,
ReferenceMode.DIRECT
)
##One normal per vertex: all pointing out of the XY plane (0, 0, 1)
normals.set_data([
FVector4(0, 0, 1, 0), # vertex 0
FVector4(0, 0, 1, 0), # vertex 1
FVector4(0, 0, 1, 0), # vertex 2
])
print("Normal layer attached.")MappingMode.CONTROL_POINT 정점당 하나의 노멀을 의미합니다. ReferenceMode.DIRECT 노멀 데이터가 control points와 동일한 순서로 읽힌다는 의미입니다 (추가 인덱스 버퍼 없음).
Normal vectors는 사용합니다 FVector4(x, y, z, w) 와 w=0 위치가 아니라 방향을 나타냅니다. FVector4 는 single-precision float vector이며; 정점 속성 데이터는 VertexElementFVector 하위 클래스는 이 유형을 사용합니다.
단계 7: 메쉬를 노드에 연결하고 저장
메쉬를 노드에 추가한 뒤 씬을 저장합니다:
node.add_entity(mesh)
scene.save("triangle.gltf")
print("Saved triangle.gltf")전체 작업 스크립트(모든 단계 결합):
from aspose.threed import Scene
from aspose.threed.entities import Mesh, VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector3, Vector4, FVector4
scene = Scene()
node = scene.root_node.create_child_node("triangle")
mesh = Mesh("triangle")
##Add 3 vertices (x, y, z, w)
# Use _control_points to mutate the backing list directly (control_points returns a copy)
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))
##Create a triangle polygon
mesh.create_polygon(0, 1, 2)
##Add normals (create_element returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(VertexElementType.NORMAL, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT)
normals.set_data([
FVector4(0, 0, 1, 0),
FVector4(0, 0, 1, 0),
FVector4(0, 0, 1, 0),
])
node.add_entity(mesh)
scene.save("triangle.gltf")일반적인 문제
| 문제 | 해결 |
|---|---|
IndexError 에서 create_polygon | 모든 인덱스가 범위 내에 있는지 확인하십시오 range(len(mesh.control_points)). 인덱스는 0부터 시작합니다. |
| 메시가 정점이 0개인 상태로 내보내집니다 | mesh.control_points.append(...) 속성이 복사본을 반환하기 때문에 정점을 조용히 버립니다. 사용하십시오 mesh._control_points.append(...) 대신. |
| 노멀 수가 정점 수와 일치하지 않습니다 | 사용할 때 MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data 정확히 있어야 합니다 len(control_points) 항목. |
| 저장된 파일에 메시가 없습니다 | 다음이 확인되었는지 확인하십시오 node.add_entity(mesh) 가 이전에 호출되었는지 scene.save(). 노드에 연결되지 않은 메시는 내보내지 않습니다. |
| 잘못된 와인딩 순서 (면이 보이지 않음) | 반시계 방향 정점 순서는 외향 노멀을 생성합니다. 인덱스 순서를 뒤집으십시오 create_polygon 그것을 뒤집으려면. |
polygon_count 0을 반환한다 | polygon_count 같은 목록을 읽는다 polygons. 만약 create_polygon 호출되지 않았으며, 리스트가 비어 있습니다. |
| 노멀(Normals)이 뷰어에서 올바르게 표시되지 않습니다. | 모든 노멀 벡터가 단위 길이를 갖도록 하세요. 다음을 사용해 계산합니다. n / abs(n) 또는 사전 정규화된 값을 전달하십시오. |
자주 묻는 질문
다음 사이의 차이점은 무엇입니까 Vector3 와 Vector4 제어점에 대해?
control_points 저장합니다 Vector4 객체들. w 구성 요소는 동차 좌표입니다: 사용하십시오 w=1 정점 위치에, 그리고 w=0 노멀과 같은 방향 벡터에 사용합니다. Vector3 변환(이동, 스케일)에 사용되지만 기하학 저장에는 사용되지 않습니다.
삼각형 대신 사각형으로 메쉬를 만들 수 있나요?
예. 호출하십시오 mesh.create_polygon(0, 1, 2, 3) 네 개의 인덱스로 쿼드를 정의합니다. 일부 저장 형식(STL, 3MF)은 삼각형을 요구하며 쿼드를 자동으로 삼각형화합니다. glTF와 COLLADA는 쿼드를 유지합니다.
UV 좌표를 어떻게 추가하나요?
사용하십시오 mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) 생성하려면 VertexElementUV diffuse 채널에 대해, 그런 다음 해당 data 목록에 Vector4 항목들. UV 좌표는 사용 x 그리고 y; z 그리고 w 는 일반적으로 0입니다. 첫 번째 인수는 반드시 TextureMapping 상수 (예:,., TextureMapping.DIFFUSE) UV 레이어가 속한 텍스처 슬롯을 식별합니다.
메시를 올바르게 내보내려면 노멀(법선)이 필요합니까?
아니요. 노멀은 선택 사항입니다. 생략하면 대부분의 뷰어가 폴리곤 winding order에서 면당 노멀을 계산합니다. 명시적인 정점당 노멀을 추가하면 더 부드러운 쉐이딩을 만들 수 있습니다.
하나의 노드에 여러 개의 메시를 추가할 수 있나요?
예. 호출 node.add_entity(mesh) 여러 번. 각 호출은 새로운 엔티티를 node.entities. 일부 포맷은 내보낼 때 여러 엔티티를 하나로 평탄화할 수 있습니다.
다양한 폴리곤 유형이 혼합된 메시를 어떻게 삼각형화하나요?
호출 mesh.triangulate() 모든 사각형 및 N-곤을 제자리에서 삼각형으로 변환합니다. 이는 삼각형만 지원하는 포맷으로 저장하기 전에 유용합니다.