Cum să construiești o plasă 3D cu Aspose.3D în Python

Cum să construiești o plasă 3D cu Aspose.3D în Python

Aspose.3D FOSS pentru Python vă permite să construiți geometrie 3D în întregime în cod: nu este necesar niciun instrument de modelare extern. Creați un Mesh, populați-l cu pozițiile vârfurilor (control_points) și definiții de fețe (polygons), atașați atribute opționale ale vârfurilor, cum ar fi normalele, apoi salvați scena în orice format suportat.

Ghid pas cu pas

Pasul 1: Instalează pachetul

Instalează Aspose.3D FOSS de pe PyPI. Nu sunt necesare extensii native sau lanț de instrumente de compilare.

pip install aspose-3d-foss

Verifică instalarea:

from aspose.threed import Scene
print("Aspose.3D FOSS ready")

Versiuni Python suportate: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Pasul 2: Crează o scenă și un nod

Fiecare plasă trebuie să trăiască în interiorul unui graf de scenă. Creați un Scene și adăugați un numit Node pentru a conține plasa:

from aspose.threed import Scene

scene = Scene()
node = scene.root_node.create_child_node("triangle")

Numele nodului este păstrat în fișierul exportat și este util pentru depanare și recuperarea ulterioară prin node.get_child("triangle").


Pasul 3: Crează un obiect Mesh

Instanțiați un Mesh cu un nume descriptiv opțional:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Mesh-ul este inițial gol: fără vârfuri, fără poligoane. Îl populezi în pașii următori.


Pasul 4: Adaugă puncte de control (vârfuri)

Punctele de control sunt pozițiile vârfurilor. Fiecare vârf este stocat ca un Vector4(x, y, z, w) unde w=1 indică un punct în spațiu 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)}")

Important: mesh.control_points returnează un copie a listei interne de vârfuri (getter-ul execută list(self._control_points)). Apelarea mesh.control_points.append(v) adaugă la copie, nu la mesh, astfel că vârful este eliminat în tăcere. Folosiți întotdeauna mesh._control_points.append(v) pentru a adăuga vârfuri. Accesarea stării private prin _control_points este o soluție de ocolire cunoscută; interfața poate să se schimbe într-o versiune viitoare a bibliotecii.


Pasul 5: Crează fețe poligonale

Definiți topologia feței utilizând indecșii de vârf. Transmiteți indecșii de vârf către create_polygon(). Trei indecși produc un triunghi; patru produc un quad:

##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)

print(f"Polygon count: {mesh.polygon_count}")

Pentru o plasă quad ați transmite patru indecși: mesh.create_polygon(0, 1, 2, 3).

Indecșii trebuie să fie poziții valide în control_points (bazat pe 0, în interval). Ordinea de înfășurare este în sens trigonometric pentru normale orientate spre exterior.


Pasul 6: Adaugă normalele de vârf

Normalele vârfului sunt stocate ca un VertexElement atașate la plasă. Utilizați mesh.create_element() cu VertexElementType.NORMAL, MappingMode.CONTROL_POINT, și 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 înseamnă o normală pe vârf. ReferenceMode.DIRECT înseamnă că datele de normale sunt citite în aceeași ordine ca punctele de control (fără buffer de indecși suplimentar).

Vectorii normali utilizează FVector4(x, y, z, w) cu w=0 pentru a indica o direcție mai degrabă decât o poziție. FVector4 este un vector float cu precizie simplă; datele de atribute ale vârfului în VertexElementFVector subclasele utilizează acest tip.


Pasul 7: Atașează mesh-ul la nod și salvează

Adaugă mesh-ul la nod, apoi salvează scena:

node.add_entity(mesh)

scene.save("triangle.gltf")
print("Saved triangle.gltf")

Scriptul complet funcțional (toate pașii combinați):

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")

Probleme comune

ProblemăRezolvare
IndexError în create_polygonVerificați că toate indecșii se află în range(len(mesh.control_points)). Indecșii sunt numerotați de la 0.
Export de mesh cu zero vârfurimesh.control_points.append(...) elimină în tăcere vârfurile deoarece proprietatea returnează o copie. Utilizați mesh._control_points.append(...) în schimb.
Numărul de normale nu corespunde numărului de vârfuriCând se folosește MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data trebuie să aibă exact len(control_points) intrări.
Mesh lipsă din fișierul salvatConfirmați că node.add_entity(mesh) a fost apelat înainte de scene.save(). Un mesh neatașat niciunui nod nu este exportat.
Ordine de înfășurare incorectă (fața apare invizibilă)Ordinea vârfurilor în sens trigonometric produce o normală orientată spre exterior. Inversează ordinea indicilor în create_polygon pentru a o inversa.
polygon_count returnează 0polygon_count citește aceeași listă ca polygons. Dacă create_polygon nu a fost apelat, lista este goală.
Normalele par incorecte în vizualizatorAsigură-te că toți vectorii normali au lungime unitate. Calculează cu n / abs(n) sau transmite valori pre-normalizate.

Întrebări frecvente

Care este diferența dintre Vector3 și Vector4 pentru puncte de control?

control_points stochează Vector4 obiecte. The w componenta este coordonata omogenă: folosește w=1 pentru pozițiile vârfurilor și w=0 pentru vectorii de direcție, cum ar fi normalele. Vector3 este utilizat pentru transformări (translație, scară), dar nu pentru stocarea geometriei.

Pot să construiesc un mesh cu cvadrate în loc de triunghiuri?

Da. Apelează mesh.create_polygon(0, 1, 2, 3) cu patru indici pentru a defini un cvadrilat. Unele destinații de salvare (STL, 3MF) necesită triunghiuri și vor triangula cvadrilatele automat. glTF și COLLADA păstrează cvadrilatele.

Cum adaug coordonate UV?

Folosește mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) pentru a crea un VertexElementUV pentru canalul difuz, apoi populează-l data lista cu Vector4 intrări. Coordonatele UV folosesc x și y; z și w sunt de obicei 0. Primul argument trebuie să fie un TextureMapping constant (de ex., TextureMapping.DIFFUSE) identificând care slot de textură aparține stratul UV.

Are necesare normalele pentru ca mesh-ul să fie exportat corect?

Nu. Normalele sunt opționale. Dacă sunt omise, majoritatea vizualizatoarelor calculează normalele pe față din ordinea de înfășurare a poligoanelor. Adăugarea de normale explicite pe vârf produce o umbrire mai netedă.

Pot să adaug mai multe mesh-uri la un nod?

Da. Apelează node.add_entity(mesh) de mai multe ori. Fiecare apel adaugă o nouă entitate la node.entities. Unele formate pot aplatiza mai multe entități într-una singură la export.

Cum triangulez un mesh cu tipuri mixte de poligoane?

Apel mesh.triangulate() pentru a converti toate cvadraturile și N-gonurile în triunghiuri la fața locului. Acest lucru este util înainte de a salva în formate care suportă doar triunghiuri.

 Română