Hvordan bygge et 3D-mesh med Aspose.3D i Python
Aspose.3D FOSS for Python lar deg bygge 3D-geometri helt i kode: ingen ekstern modelleringsverktøy kreves. Du oppretter en Mesh, fyller den med vertex‑posisjoner (control_points) og ansiktsdefinisjoner (polygons), legger ved valgfrie vertex‑attributter som normaler, og lagrer deretter scenen i et hvilket som helst støttet format.
Steg-for-steg guide
Steg 1: Installer pakken
Installer Aspose.3D FOSS fra PyPI. Ingen native-utvidelser eller kompilatorverktøykjede er påkrevd.
pip install aspose-3d-fossBekreft installasjonen:
from aspose.threed import Scene
print("Aspose.3D FOSS ready")Støttede Python‑versjoner: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Trinn 2: Opprett en scene og en node
Hver mesh må leve inne i en scenegraph. Opprett en Scene og legg til en navngitt Node for å holde mesh‑en:
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")Nodenavnet blir bevart i den eksporterte filen og er nyttig for feilsøking og senere henting via node.get_child("triangle").
Trinn 3: Opprett et Mesh-objekt
Opprett en Mesh med et valgfritt beskrivende navn:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")Meshen er i utgangspunktet tom: ingen vertices, ingen polygoner. Du fyller den i følgende trinn.
Steg 4: Legg til kontrollpunkter (hjørner)
Kontrollpunkter er vertex‑posisjonene. Hvert vertex lagres som en Vector4(x, y, z, w) hvor w=1 indikerer et punkt i 3D‑rom:
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)}")Viktig: mesh.control_points returnerer en kopi av den interne vertex‑listen (getteren utfører list(self._control_points)). Å kalle mesh.control_points.append(v) legger til i kopien, ikke i mesh‑en, så vertexen blir stille forkastet. Bruk alltid mesh._control_points.append(v) for å legge til vertexer. Å få tilgang til privat tilstand via _control_points er en kjent løsning; grensesnittet kan endres i en fremtidig versjon av biblioteket.
Steg 5: Opprett polygonflater
Definer face topology ved hjelp av vertex indices. Send vertex indices til create_polygon(). Tre indices gir en trekant; fire gir en quad:
##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 sende fire indekser: mesh.create_polygon(0, 1, 2, 3).
Indekser må være gyldige posisjoner i control_points (0-basert, innenfor området). Vindingen er mot klokken for utadrettede normaler.
Steg 6: Legg til Vertex Normals
Vertexnormaler lagres som en VertexElement festet til nettet. Bruk 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 betyr en normal per vertex. ReferenceMode.DIRECT betyr at normaldataene leses i samme rekkefølge som kontrollpunktene (ingen ekstra indeksbuffer).
Normalvektorer bruker FVector4(x, y, z, w) med w=0 for å indikere en retning i stedet for en posisjon. FVector4 er en enkeltpresisjon flyttallsvektor; vertex‑attributtdata i VertexElementFVector‑subklasser bruker denne typen.
Trinn 7: Koble Mesh til Node og lagre
Legg til mesh i noden, så lagre scenen:
node.add_entity(mesh)
scene.save("triangle.gltf")
print("Saved triangle.gltf")Det komplette fungerende skriptet (alle trinn kombinert):
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")Vanlige problemer
| Problem | Løsning |
|---|---|
IndexError i create_polygon | Bekreft at alle indekser er innenfor range(len(mesh.control_points)). Indekser er 0-baserte. |
| Mesh eksporteres med null vertexer | mesh.control_points.append(...) forkaster stille vertexer fordi egenskapen returnerer en kopi. Bruk mesh._control_points.append(...) i stedet. |
| Antall normaler stemmer ikke overens med antall vertexer | Når du bruker MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, må normals.data ha nøyaktig len(control_points) oppføringer. |
| Mesh mangler i lagret fil | Bekreft at node.add_entity(mesh) ble kalt før scene.save(). En mesh som ikke er festet til noen node blir ikke eksportert. |
| Feil snuringsrekkefølge (flaten ser usynlig ut) | Moturs vertex-rekkefølge gir en normal som peker utover. Vend om på indeksrekkefølgen i create_polygon for å snu den. |
polygon_count returns 0 | polygon_count leser samme liste som polygons. Hvis create_polygon ikke ble kalt, er listen tom. |
| Normaler ser feil ut i viseren | Sørg for at alle normalvektorer har enhetslengde. Beregn med n / abs(n) eller send inn forhåndsnormerte verdier. |
Ofte stilte spørsmål
Hva er forskjellen mellom Vector3 og Vector4 for kontrollpunkter?
control_points lagrer Vector4-objekter. w-komponenten er den homogene koordinaten: bruk w=1 for vertexposisjoner og w=0 for retningsvektorer som normaler. Vector3 brukes til transformasjoner (oversettelse, skalering) men ikke for geometrilagring.
Kan jeg bygge et mesh med firkanter i stedet for trekanter?
Ja. Kall mesh.create_polygon(0, 1, 2, 3) med fire indekser for å definere en quad. Noen lagringsmål (STL, 3MF) krever trekanter og vil automatisk triangulere quads. glTF og COLLADA bevarer quads.
Hvordan legger jeg til UV-koordinater?
Bruk mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) for å opprette en VertexElementUV for den diffuse kanalen, og deretter fylle dens data‑liste med Vector4‑oppføringer. UV‑koordinater bruker x og y; z og w er vanligvis 0. Det første argumentet må være en TextureMapping‑konstant (f.eks. TextureMapping.DIFFUSE) som identifiserer hvilken teksturplassering UV‑laget tilhører.
Må mesh ha normaler for å eksporteres korrekt?
Nei. Normaler er valgfrie. Hvis de utelates, beregner de fleste viewers per-face normaler fra polygonets viklingsrekkefølge. Å legge til eksplisitte per-vertex normaler gir jevnere skyggelegging.
Kan jeg legge til flere mesh på én node?
Ja. Kall node.add_entity(mesh) flere ganger. Hvert kall legger til en ny enhet i node.entities. Noen formater kan flate ut flere enheter til én ved eksport.
Hvordan triangulerer jeg et mesh med blandede polygon-typer?
Kall mesh.triangulate() for å konvertere alle firkanter og N‑goner til trekanter på stedet. Dette er nyttig før lagring til formater som kun støtter trekanter.