Kako izgraditi 3D mrežu pomoću Aspose.3D u Pythonu

Kako izgraditi 3D mrežu pomoću Aspose.3D u Pythonu

Aspose.3D FOSS za Python vam omogućava da izgradite 3D geometriju u potpunosti u kodu: nije potreban eksterni alat za modelovanje. Kreirate Mesh, popunjavate ga položajima vrhova (control_points) i definicijama površina (polygons), prikačite opcione atribute vrhova kao što su normale, zatim sačuvate scenu u bilo koji podržani format.

Vodič korak po korak

Korak 1: Instalirajte paket

Instalirajte Aspose.3D FOSS sa PyPI. Nije potreban nativni ekstenzija niti alatni lanac za kompajler.

pip install aspose-3d-foss

Proverite 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: Kreirajte scenu i čvor

Svaki mesh mora da bude unutar scene grafa. Kreirajte Scene i dodajte imenovani Node da sadrži mesh:

from aspose.threed import Scene

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

Naziv čvora se čuva u izvezenom fajlu i koristan je za debugovanje i kasnije preuzimanje putem node.get_child("triangle").


Korak 3: Kreirajte Mesh objekat

Instancirajte Mesh sa opcionim opisnim imenom:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Mreža je početno prazna: nema temena, nema poligona. Popunite je u sledećim koracima.


Korak 4: Dodajte kontrolne tačke (vrhove)

Kontrolne tačke su položaji temena. Svako temena se čuva kao Vector4(x, y, z, w) gde w=1 označava tač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 u kopiju, a ne u mrežu, pa se vrh tiho odbacuje. Uvek koristite mesh._control_points.append(v) za dodavanje vrhova. Pristupanje privatnom stanju putem _control_points je poznat zaobilazni postupak; interfejs može da se promeni u budućoj verziji biblioteke.


Korak 5: Kreirajte poligonalna lica

Definišite topologiju lica koristeći indekse vrhova. Prosledite indekse vrhova u create_polygon(). Tri indeksa formiraju trougao; četiri formiraju četvorougao:

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

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

Za kvadratnu mrežu biste prosledili četiri indeksa: mesh.create_polygon(0, 1, 2, 3).

Indeksi moraju biti važeći položaji u control_points (indeksirani od nule, u opsegu). Redosled uvijanja je suprotan smeru kazaljke na satu za normale usmerene prema spolja.


Korak 6: Dodaj normale vrha

Normale vrha se čuvaju kao VertexElement prikačena na mrežu. Koristite mesh.create_element() sa 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 redosledom kao kontrolne tačke (bez dodatnog indeksa bafera).

Normalni vektori koriste FVector4(x, y, z, w) sa w=0 da bi označili pravac, a ne položaj. FVector4 je vektor sa jednopreciznim float‑om; podaci atributa vrha u podklasama VertexElementFVector koriste ovaj tip.


Korak 7: Prikačite Mesh na Node i sačuvajte

Dodajte mesh u čvor, zatim sačuvajte scenu:

node.add_entity(mesh)

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

Kompletan radni skript (svi koraci kombinovani):

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

Česti problemi

IssueResolution
IndexError in create_polygonProverite da su svi indeksi unutar range(len(mesh.control_points)). Indeksi su bazirani na 0.
Mesh exports with zero verticesmesh.control_points.append(...) tiho odbacuje vrhove jer svojstvo vraća kopiju. Umesto toga koristite mesh._control_points.append(...).
Normals count does not match vertex countKada se koriste MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data mora imati tačno len(control_points) unosa.
Mesh missing from saved filePotvrdite da je node.add_entity(mesh) pozvan pre scene.save(). Mreža koja nije prikačena na nijedan čvor se ne izvozi.
Wrong winding order (face appears invisible)Redosled vrhova u smeru suprotnom od kazaljke na satu daje normalu usmerenu prema spolja. Obrnite redosled indeksa u create_polygon da biste je preokrenuli.
polygon_count returns 0polygon_count čita istu listu kao polygons. Ako create_polygon nije pozvan, lista je prazna.
Normals appear incorrect in viewerOsigurajte da su svi vektori normala jedinične dužine. Izračunajte ih pomoću n / abs(n) ili prosledite unapred normalizovane vrednosti.

Često postavljana pitanja

Koja je razlika između Vector3 i Vector4 za kontrolne tačke?

control_points čuva Vector4 objekte. Komponenta w je homogena koordinata: koristite w=1 za položaje vrhova i w=0 za vektore pravca kao što su normale. Vector3 se koristi za transformacije (translacija, skaliranje), ali ne za skladištenje geometrije.

Могу ли да изградим мрежу са четвороугаоницама уместо троуглова?

Да. Позовите mesh.create_polygon(0, 1, 2, 3) са четири индекса да бисте дефинисали четвороугаоник. Неки формати за чување (STL, 3MF) захтевају троуглове и аутоматски ће треангулирати четвороугаонике. glTF и COLLADA чувају четвороугаонике.

Kako da dodam UV koordinate?

Koristite mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) da biste kreirali VertexElementUV za difuzni kanal, zatim popunite njegovu listu data sa 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 identifikuje kojem slotu teksture pripada UV sloj.

Da li mesh treba normale da bi se pravilno izveze?

Ne. Normale su opciona. Ako se izostave, većina preglednika izračunava normale po površini na osnovu redosleda vrhova poligona. Dodavanje eksplicitnih normala po vrhu daje glatkiju osvetljenost.

Mogu li dodati više meshes u jedan node?

Да. Позовите node.add_entity(mesh) више пута. Сваки позив додаје нови ентитет у node.entities. Неки формати могу спљоштити више ентитета у један при извозу.

Kako da trianguliram mesh sa mešovitim tipovima poligona?

Pozovite mesh.triangulate() da konvertujete sve kvadrate i N‑gone u trouglove na mestu. Ovo je korisno pre nego što sačuvate u formate koji podržavaju samo trouglove.

 Српски