Sådan bygger du et 3D-mesh med Aspose.3D i Python

Sådan bygger du et 3D-mesh med Aspose.3D i Python

Aspose.3D FOSS for Python giver dig mulighed for at bygge 3D-geometri udelukkende i kode: ingen ekstern modelleringsværktøj påkrævet. Du opretter en Mesh, udfylder den med vertex‑positioner (control_points) og flade‑definitioner (polygons), vedhæfter valgfrie vertex‑attributter såsom normaler, og gemmer derefter scenen i ethvert understøttet format.

Trin-for-trin guide

Trin 1: Installer pakken

Installer Aspose.3D FOSS fra PyPI. Ingen native udvidelser eller kompilatorværktøjskæde er påkrævet.

pip install aspose-3d-foss

Bekræft installationen:

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

Understøttede Python-versioner: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Trin 2: Opret en scene og en node

Hvert mesh skal være placeret inden for en scenegraph. Opret en Scene og tilføj en navngivet Node for at holde mesh’en:

from aspose.threed import Scene

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

Node-navnet bevares i den eksporterede fil og er nyttigt til fejlfinding og senere hentning via node.get_child("triangle").


Trin 3: Opret et Mesh-objekt

Instansier en Mesh med et valgfrit beskrivende navn:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Mesh’en er i starten tom: ingen vertexer, ingen polygoner. Du udfylder den i de følgende trin.


Trin 4: Tilføj kontrolpunkter (hjørner)

Kontrolpunkter er vertexpositionerne. Hvert vertex gemmes som en Vector4(x, y, z, w), hvor w=1 angiver et punkt i 3D‑rum:

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

Vigtigt: mesh.control_points returnerer en kopi af den interne vertex-liste (getteren udfører list(self._control_points)). At kalde mesh.control_points.append(v) tilføjer til kopien, ikke til mesh’en, så vertexen bliver tavst fjernet. Brug altid mesh._control_points.append(v) til at tilføje vertexer. At få adgang til privat tilstand via _control_points er en kendt løsning; grænsefladen kan ændre sig i en fremtidig version af biblioteket.


Trin 5: Opret polygonflader

Definér ansigtets topologi ved hjælp af vertex indices. Overfør vertex indices til create_polygon(). Tre indekser producerer en trekant; fire producerer en firkant:

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

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

For et quad‑mesh vil du videregive fire indekser: mesh.create_polygon(0, 1, 2, 3).

Indekser skal være gyldige positioner i control_points (0-baseret, inden for intervallet). Vindingens rækkefølge er mod uret for udadvendte normaler.


Trin 6: Tilføj vertexnormale

Vertexnormaler gemmes som en VertexElement knyttet til mesh’en. Brug mesh.create_element() med VertexElementType.NORMAL, MappingMode.CONTROL_POINT og 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 betyder én normal per vertex. ReferenceMode.DIRECT betyder, at normaldata læses i samme rækkefølge som kontrolpunkterne (ingen ekstra indeksbuffer).

Normalvektorer bruger FVector4(x, y, z, w) med w=0 for at angive en retning i stedet for en position. FVector4 er en single‑precision float‑vektor; vertex‑attributdata i VertexElementFVector‑subklasser bruger denne type.


Trin 7: Tilføj Mesh til Node og gem

Tilføj mesh til noden, og gem derefter scenen:

node.add_entity(mesh)

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

Det komplette fungerende script (alle trin kombineret):

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

Almindelige problemer

ProblemLøsning
IndexError i create_polygonBekræft at alle indekser er inden for range(len(mesh.control_points)). Indekser er 0-baserede.
Mesh eksporterer med nul vertexermesh.control_points.append(...) kasserer tavst vertexer, fordi egenskaben returnerer en kopi. Brug mesh._control_points.append(...) i stedet.
Antallet af normaler svarer ikke til antallet af vertexerNår du bruger MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, skal normals.data have præcis len(control_points) poster.
Mesh mangler i gemt filBekræft at node.add_entity(mesh) blev kaldt før scene.save(). Et mesh, der ikke er knyttet til nogen node, eksporteres ikke.
Forkert winding-orden (fladen fremstår usynlig)Mod‑ur‑ret vertex‑orden giver en udadrettet normal. Vend indeks‑rækkefølgen i create_polygon for at vende den.
polygon_count returns 0polygon_count læser den samme liste som polygons. Hvis create_polygon ikke blev kaldt, er listen tom.
Normaler fremstår forkerte i viewerSørg for at alle normalvektorer har enhedslængde. Beregn med n / abs(n) eller send forud‑normaliserede værdier.

Ofte stillede spørgsmål

Hvad er forskellen mellem Vector3 og Vector4 for kontrolpunkter?

control_points gemmer Vector4 objekter. w‑komponenten er den homogene koordinat: brug w=1 til vertexpositioner og w=0 til retningsvektorer såsom normaler. Vector3 bruges til transformationer (oversættelse, skalering) men ikke til geometrilagring.

Kan jeg bygge et mesh med firkanter i stedet for trekanter?

Ja. Kald mesh.create_polygon(0, 1, 2, 3) med fire indekser for at definere en quad. Nogle gemmemål (STL, 3MF) kræver trekanter og vil automatisk triangulere quads. glTF og COLLADA bevarer quads.

Hvordan tilføjer jeg UV-koordinater?

Brug mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) til at oprette en VertexElementUV for den diffuse kanal, og udfyld derefter dens data‑liste med Vector4‑elementer. UV‑koordinater bruger x og y; z og w er typisk 0. Det første argument skal være en TextureMapping‑konstant (f.eks. TextureMapping.DIFFUSE), der identificerer hvilken teksturslot UV‑laget tilhører.

Behøver mesh’en normaler for at eksportere korrekt?

Nej. Normale er valgfrie. Hvis de udelades, beregner de fleste visningsprogrammer per-flade-normale ud fra polygonens viklingsorden. Tilføjelse af eksplicitte per-vertex-normale giver en glattere belysning.

Kan jeg tilføje flere mesh til én node?

Ja. Kald node.add_entity(mesh) flere gange. Hvert kald tilføjer en ny enhed til node.entities. Nogle formater kan flade flere enheder ud til én ved eksport.

Hvordan triangulerer jeg et mesh med blandede polygon-typer?

Kald mesh.triangulate() for at konvertere alle firkanter og N-goner til trekanter på stedet. Dette er nyttigt, før du gemmer til formater, der kun understøtter trekanter.

 Dansk