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-fossVerifică 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_polygon | Verificaț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ârfuri | mesh.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ârfuri | Câ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 salvat | Confirmaț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ă 0 | polygon_count citește aceeași listă ca polygons. Dacă create_polygon nu a fost apelat, lista este goală. |
| Normalele par incorecte în vizualizator | Asigură-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.