Kako izgraditi 3D mrežu s Aspose.3D u Pythonu
Aspose.3D FOSS za Python omogućuje izgradnju 3D geometrije u potpunosti putem koda: nije potreban vanjski alat za modeliranje. Stvorite Mesh, popunite ga položajima vrhova (control_points) i definicijama površina (polygons), dodajte opcionalne atribute vrhova poput normala, a zatim spremite scenu u bilo koji podržani format.
Vodič korak po korak
Korak 1: Instalirajte paket
Instalirajte Aspose.3D FOSS s PyPI-ja. Nisu potrebni izvorni proširenja ili alatni lanac za kompilaciju.
pip install aspose-3d-fossProvjerite instalaciju:
from aspose.threed import Scene
print("Aspose.3D FOSS ready")Podržane Python verzije: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Korak 2: Stvori scenu i čvor
Svaka mreža mora biti unutar grafova scene. Stvori Scene i dodaj imenovani Node za držanje mreže:
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")Naziv čvora se čuva u izvezenoj datoteci i koristan je za otklanjanje pogrešaka i kasnije dohvaćanje putem node.get_child("triangle").
Korak 3: Stvori Mesh objekt
Instancirajte Mesh s opcionalnim opisnim nazivom:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")Mreža je isprva prazna: nema vrhova, nema poligona. Popunite je sljedećim koracima.
Korak 4: Dodaj kontrolne točke (vrhove)
Kontrolne točke su položaji vrhova. Svaki vrh pohranjen je kao Vector4(x, y, z, w) gdje w=1 označava točku u 3D prostoru:
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)}")Važno: mesh.control_points vraća kopiju interne liste vrhova (getter izvršava list(self._control_points)). Pozivanje mesh.control_points.append(v) dodaje na kopiju, a ne na mrežu, pa se vrh tiho odbacuje. Uvijek koristite mesh._control_points.append(v) za dodavanje vrhova. Pristupanje privatnom stanju putem _control_points je poznati zaobilazni način; sučelje se može promijeniti u budućoj verziji biblioteke.
Korak 5: Stvaranje poligonalnih lica
Definirajte topologiju lica koristeći indekse vrhova. Proslijedite indekse vrhova u create_polygon(). Tri indeksa stvaraju trokut; četiri stvaraju četverokut:
##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)
print(f"Polygon count: {mesh.polygon_count}")Za kvadratnu mrežu biste proslijedili četiri indeksa: mesh.create_polygon(0, 1, 2, 3).
Indeksi moraju biti valjani položaji u control_points (0‑bazirano, unutar raspona). Redoslijed namotavanja je suprotan smjeru kazaljke na satu za normale okrenute prema van.
Korak 6: Dodaj normale vrha
Normale vrhova pohranjene su kao VertexElement pričvršćene uz mrežu. Koristite mesh.create_element() s 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 znači jedan normal po vrhu. ReferenceMode.DIRECT znači da se podaci o normalama čitaju istim redoslijedom kao kontrolne točke (bez dodatnog indeksa).
Normalni vektori koriste FVector4(x, y, z, w) s w=0 za označavanje smjera, a ne položaja. FVector4 je jednoprecizni float vektor; podaci atributa vrha u podklasama VertexElementFVector koriste ovu vrstu.
Korak 7: Prikvači mrežu na čvor i spremi
Dodajte mesh u čvor, zatim spremite scenu:
node.add_entity(mesh)
scene.save("triangle.gltf")
print("Saved triangle.gltf")Potpuni radni skript (svi koraci kombinirani):
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")Uobičajeni problemi
| Problem | Rješenje |
|---|---|
IndexError u create_polygon | Provjerite da su svi indeksi unutar range(len(mesh.control_points)). Indeksi su 0‑bazirani. |
| Mesh izvozi s nula vrhova | mesh.control_points.append(...) tiho odbacuje vrhove jer svojstvo vraća kopiju. Umjesto toga koristite mesh._control_points.append(...). |
| Broj normala ne odgovara broju vrhova | Kada se koriste MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data mora imati točno len(control_points) unosa. |
| Mreža nedostaje u spremljenoj datoteci | Potvrdite da je node.add_entity(mesh) pozvan prije scene.save(). Mreža koja nije povezana s nijednim čvorom ne izvozi se. |
| Pogrešan redoslijed vrhova (lica se čini nevidljivim) | Redoslijed vrhova u smjeru suprotnom od kazaljke na satu daje normalu usmjerenu prema van. Obratite redoslijed indeksa u create_polygon da ga preokrenete. |
polygon_count vraća 0 | polygon_count čita isti popis kao polygons. Ako create_polygon nije pozvan, popis je prazan. |
| Normale se prikazuju netočno u pregledniku | Osigurajte da su svi vektori normala jedinične duljine. Izračunajte s n / abs(n) ili proslijedite unaprijed normalizirane vrijednosti. |
Često postavljana pitanja
Koja je razlika između Vector3 i Vector4 za kontrolne točke?
control_points pohranjuje Vector4 objekte. Komponenta w je homogena koordinata: koristite w=1 za položaje vrhova i w=0 za vektore smjera poput normala. Vector3 se koristi za transformacije (translacija, skaliranje), ali ne za pohranu geometrije.
Mogu li izraditi mrežu s četverokutima umjesto trokuta?
Da. Pozovite mesh.create_polygon(0, 1, 2, 3) s četiri indeksa da definirate četverokut. Neki odredišni formati za spremanje (STL, 3MF) zahtijevaju trokute i automatski će triangulirati četverokute. glTF i COLLADA očuvavaju četverokute.
Kako dodati UV koordinate?
Koristite mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) za stvaranje VertexElementUV za difuzni kanal, a zatim popunite njegovu data listu s Vector4 unosima. UV koordinate koriste x i y; z i w su obično 0. Prvi argument mora biti konstanta TextureMapping (npr., TextureMapping.DIFFUSE) koja identificira kojem slotu teksture pripada UV sloj.
Treba li mesh imati normale za ispravan izvoz?
Ne. Normale su opcionalne. Ako se izostave, većina preglednika izračunava normale po površini iz redoslijeda vrhova poligona. Dodavanje eksplicitnih normala po vrhu daje glatkije sjenčanje.
Mogu li dodati više mreža u jedan čvor?
Da. Pozovite node.add_entity(mesh) više puta. Svaki poziv dodaje novi entitet u node.entities. Neki formati mogu izravnati više entiteta u jedan pri izvozu.
Kako triangulirati mrežu s mješovitim tipovima poligona?
Pozovite mesh.triangulate() da pretvorite sve četverokute i N‑poligone u trokute na mjestu. Ovo je korisno prije spremanja u formate koji podržavaju samo trokute.