Hur man bygger ett 3D-mesh med Aspose.3D i Python

Hur man bygger ett 3D-mesh med Aspose.3D i Python

Aspose.3D FOSS för Python låter dig bygga 3D-geometri helt i kod: inget externt modelleringsverktyg behövs. Du skapar en Mesh, fyller den med vertexpositioner (control_points) och ytdefinitioner (polygons), bifogar valfria vertexattribut såsom normaler, och sparar sedan scenen i vilket stödformat som helst.

Steg-för-steg-guide

Steg 1: Installera paketet

Installera Aspose.3D FOSS från PyPI. Inga inhemska tillägg eller kompilatorverktygskedja krävs.

pip install aspose-3d-foss

Verifiera installationen:

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

Stödda Python-versioner: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Steg 2: Skapa en scen och en nod

Varje mesh måste finnas i en scengraf. Skapa en Scene och lägg till en namngiven Node för att hålla meshen:

from aspose.threed import Scene

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

Nodnamnet bevaras i den exporterade filen och är användbart för felsökning och senare hämtning via node.get_child("triangle").


Steg 3: Skapa ett Mesh-objekt

Instansiera en Mesh med ett valfritt beskrivande namn:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Meshen är initialt tom: inga vertices, inga polygons. Du fyller den i följande steg.


Steg 4: Lägg till kontrollpunkter (hörn)

Kontrollpunkter är vertexpositionerna. Varje vertex lagras som en Vector4(x, y, z, w) där w=1 indikerar en punkt i 3D‑rymden:

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

Important: mesh.control_points returnerar en kopia av den interna vertexlistan (getter‑metoden kör list(self._control_points)). Att anropa mesh.control_points.append(v) lägger till i kopian, inte i meshen, så vertexen kastas tyst bort. Använd alltid mesh._control_points.append(v) för att lägga till vertexar. Att komma åt privat tillstånd via _control_points är en känd lösning; gränssnittet kan förändras i en framtida version av biblioteket.


Steg 5: Skapa polygonytor

Definiera ansiktets topologi med vertex-index. Skicka vertex-index till create_polygon(). Tre index ger en triangel; fyra ger en fyrkant:

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

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

För en quad mesh skulle du skicka fyra index: mesh.create_polygon(0, 1, 2, 3).

Indexen måste vara giltiga positioner i control_points (0‑baserade, inom intervallet). Vridningsordningen är moturs för utåtriktade normaler.


Steg 6: Lägg till vertexnormaler

Vertexnormaler lagras som en VertexElement som är bifogad till meshen. Använd mesh.create_element() med VertexElementType.NORMAL, MappingMode.CONTROL_POINT och 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 en normal per vertex. ReferenceMode.DIRECT betyder att normaldata läses i samma ordning som kontrollpunkterna (ingen extra indexbuffert).

Normalvektorer använder FVector4(x, y, z, w) med w=0 för att ange en riktning snarare än en position. FVector4 är en enkelprecision flyttalsvektor; vertexattributdata i VertexElementFVector-subklasser använder denna typ.


Steg 7: Fäst Mesh till noden och spara

Lägg till meshen i noden, spara sedan scenen:

node.add_entity(mesh)

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

Det kompletta fungerande skriptet (alla steg kombinerade):

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

Vanliga problem

IssueResolution
IndexError i create_polygonVerifiera att alla index är inom range(len(mesh.control_points)). Index är 0-baserade.
Mesh exporteras med noll vertexarmesh.control_points.append(...) kastar tyst bort vertexar eftersom egenskapen returnerar en kopia. Använd mesh._control_points.append(...) istället.
Antalet normaler matchar inte antalet vertexarNär du använder MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, måste normals.data ha exakt len(control_points) poster.
Mesh saknas i sparad filBekräfta att node.add_entity(mesh) anropades före scene.save(). En mesh som inte är bifogad till någon nod exporteras inte.
Fel vridningsordning (ytan verkar osynlig)Moturs vertexordning ger en normal som pekar utåt. Vänd på indexordningen i create_polygon för att vända den.
polygon_count returnerar 0polygon_count läser samma lista som polygons. Om create_polygon inte anropades är listan tom.
Normaler visas felaktiga i visarenSäkerställ att alla normalvektorer har enhetslängd. Beräkna med n / abs(n) eller skicka förnormaliserade värden.

Vanliga frågor

Vad är skillnaden mellan Vector3 och Vector4 för kontrollpunkter?

control_points lagrar Vector4-objekt. w-komponenten är den homogena koordinaten: använd w=1 för vertexpositioner och w=0 för riktningsvektorer såsom normaler. Vector3 används för transformationer (översättning, skalning) men inte för geometrilagring.

Kan jag bygga ett mesh med fyrkanter istället för trianglar?

Ja. Anropa mesh.create_polygon(0, 1, 2, 3) med fyra index för att definiera en quad. Vissa sparmål (STL, 3MF) kräver trianglar och kommer automatiskt att triangulera quads. glTF och COLLADA bevarar quads.

Hur lägger jag till UV-koordinater?

Använd mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) för att skapa en VertexElementUV för den diffusa kanalen, och fyll sedan dess data‑lista med Vector4‑poster. UV‑koordinater använder x och y; z och w är vanligtvis 0. Det första argumentet måste vara en TextureMapping‑konstant (t.ex. TextureMapping.DIFFUSE) som identifierar vilken texturslot UV‑lagret tillhör.

Behöver meshen normaler för att exporteras korrekt?

Nej. Normaler är valfria. Om de utelämnas beräknar de flesta visare per-face normals från polygonens slingningsordning. Att lägga till explicita per-vertex normals ger mjukare skuggning.

Kan jag lägga till flera meshar till en nod?

Ja. Anropa node.add_entity(mesh) flera gånger. Varje anrop lägger till en ny entitet i node.entities. Vissa format kan platta till flera entiteter till en vid export.

Hur triangulerar jag ett mesh med blandade polygontyper?

Anropa mesh.triangulate() för att konvertera alla fyrhörningar och N‑gon till trianglar på plats. Detta är användbart innan du sparar till format som endast stödjer trianglar.

 Svenska