Aspose.3D를 Python에서 사용하여 3D 메쉬를 만드는 방법

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) 또는 사전 정규화된 값을 전달하십시오.

자주 묻는 질문

다음 사이의 차이점은 무엇입니까 Vector3Vector4 제어점에 대해?

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-곤을 제자리에서 삼각형으로 변환합니다. 이는 삼각형만 지원하는 포맷으로 저장하기 전에 유용합니다.

 한국어