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-fossVerifiera 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
| Issue | Resolution |
|---|---|
IndexError i create_polygon | Verifiera att alla index är inom range(len(mesh.control_points)). Index är 0-baserade. |
| Mesh exporteras med noll vertexar | mesh.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 vertexar | När du använder MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, måste normals.data ha exakt len(control_points) poster. |
| Mesh saknas i sparad fil | Bekrä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 0 | polygon_count läser samma lista som polygons. Om create_polygon inte anropades är listan tom. |
| Normaler visas felaktiga i visaren | Sä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.