Kako izgraditi 3D mrežu s Aspose.3D u Pythonu

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-foss

Provjerite 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

ProblemRješenje
IndexError u create_polygonProvjerite da su svi indeksi unutar range(len(mesh.control_points)). Indeksi su 0‑bazirani.
Mesh izvozi s nula vrhovamesh.control_points.append(...) tiho odbacuje vrhove jer svojstvo vraća kopiju. Umjesto toga koristite mesh._control_points.append(...).
Broj normala ne odgovara broju vrhovaKada se koriste MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data mora imati točno len(control_points) unosa.
Mreža nedostaje u spremljenoj datoteciPotvrdite 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 0polygon_count čita isti popis kao polygons. Ako create_polygon nije pozvan, popis je prazan.
Normale se prikazuju netočno u preglednikuOsigurajte 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.

 Hrvatski