Jak vytvořit 3D síť s Aspose.3D v Pythonu

Jak vytvořit 3D síť s Aspose.3D v Pythonu

Aspose.3D FOSS pro Python vám umožňuje vytvářet 3D geometrii kompletně v kódu: není potřeba žádný externí modelovací nástroj. Vytvoříte Mesh, naplníte jej pozicemi vrcholů (control_points) a definicemi ploch (polygons), připojíte volitelné atributy vrcholů, jako jsou normály, a poté scénu uložíte do libovolného podporovaného formátu.

Průvodce krok za krokem

Krok 1: Nainstalujte balíček

Nainstalujte Aspose.3D FOSS z PyPI. Není vyžadováno žádné nativní rozšíření ani kompilátorový nástrojový řetězec.

pip install aspose-3d-foss

Ověřte instalaci:

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

Podporované verze Pythonu: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Krok 2: Vytvořte scénu a uzel

Každá síť musí být uvnitř grafu scény. Vytvořte Scene a přidejte pojmenovaný Node, který bude síť držet:

from aspose.threed import Scene

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

Název uzlu je zachován v exportovaném souboru a je užitečný pro ladění a pozdější načtení pomocí node.get_child("triangle").


Krok 3: Vytvořte Mesh objekt

Vytvořte instanci Mesh s volitelným popisným názvem:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Síť je zpočátku prázdná: žádné vrcholy, žádné polygonů. Naplníte ji v následujících krocích.


Krok 4: Přidat kontrolní body (vrcholy)

Řídicí body jsou pozice vrcholů. Každý vrchol je uložen jako Vector4(x, y, z, w), kde w=1 označuje bod ve 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)}")

Důležité: mesh.control_points vrací kopii interního seznamu vrcholů (getter provádí list(self._control_points)). Volání mesh.control_points.append(v) přidá do kopie, ne do mesh, takže vrchol je tiše zahazován. Vždy používejte mesh._control_points.append(v) k přidání vrcholů. Přístup k soukromému stavu přes _control_points je známý workaround; rozhraní se může v budoucí verzi knihovny změnit.


Krok 5: Vytvořit polygonové plochy

Definujte topologii plochy pomocí indexů vrcholů. Předávejte indexy vrcholů do create_polygon(). Tři indexy vytvoří trojúhelník; čtyři vytvoří čtyřúhelník:

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

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

Pro čtyřúhelníkovou síť byste předali čtyři indexy: mesh.create_polygon(0, 1, 2, 3).

Indexy musí být platné pozice v control_points (základě 0, v rozsahu). Směr otáčení je proti směru hodinových ručiček pro normály směřující ven.


Krok 6: Přidat normály vrcholů

Normály vrcholů jsou uloženy jako VertexElement připojený k síti. Použijte mesh.create_element() s VertexElementType.NORMAL, MappingMode.CONTROL_POINT a 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 znamená jeden normál na vrchol. ReferenceMode.DIRECT znamená, že data normálů jsou čtena ve stejném pořadí jako řídicí body (žádný extra indexový buffer).

Normálové vektory používají FVector4(x, y, z, w) s w=0 k označení směru místo polohy. FVector4 je vektor s jednoduchou přesností typu float; data atributů vrcholů v podtřídách VertexElementFVector používají tento typ.


Krok 7: Připojte síť k uzlu a uložte

Přidejte síť do uzlu a poté uložte scénu:

node.add_entity(mesh)

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

Kompletní fungující skript (všechny kroky kombinovány):

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

Časté problémy

IssueResolution
IndexError v create_polygonOvěřte, že všechny indexy jsou v range(len(mesh.control_points)). Indexy jsou nulové (0‑based).
Mesh exports with zero verticesmesh.control_points.append(...) tiše zahazuje vrcholy, protože vlastnost vrací kopii. Místo toho použijte mesh._control_points.append(...).
Normals count does not match vertex countPři použití MappingMode.CONTROL_POINT + ReferenceMode.DIRECT musí normals.data mít přesně len(control_points) položek.
Mesh missing from saved filePotvrďte, že node.add_entity(mesh) bylo zavoláno před scene.save(). Síť, která není připojena k žádnému uzlu, není exportována.
Wrong winding order (face appears invisible)Pořadí vrcholů ve směru proti hodinám vytváří normálu směřující ven. Obrácením pořadí indexů v create_polygon ji přetočíte.
polygon_count returns 0polygon_count čte stejný seznam jako polygons. Pokud nebylo zavoláno create_polygon, je seznam prázdný.
Normals appear incorrect in viewerUjistěte se, že všechny normálové vektory mají jednotkovou délku. Vypočítejte je pomocí n / abs(n) nebo předávejte předem normalizované hodnoty.

Často kladené otázky

Jaký je rozdíl mezi Vector3 a Vector4 pro kontrolní body?

control_points ukládá Vector4 objekty. Komponenta w je homogenní souřadnice: použijte w=1 pro pozice vrcholů a w=0 pro směrové vektory, jako jsou normály. Vector3 se používá pro transformace (posunutí, měřítko), ale ne pro ukládání geometrie.

Mohu vytvořit síť s čtyřúhelníky místo trojúhelníků?

Ano. Zavolejte mesh.create_polygon(0, 1, 2, 3) se čtyřmi indexy pro definování čtyřúhelníku. Některé cíle ukládání (STL, 3MF) vyžadují trojúhelníky a automaticky převádějí čtyřúhelníky na trojúhelníky. glTF a COLLADA zachovávají čtyřúhelníky.

Jak přidám UV souřadnice?

Použijte mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) k vytvoření VertexElementUV pro difúzní kanál, poté naplňte jeho seznam data položkami Vector4. UV souřadnice používají x a y; z a w jsou obvykle 0. První argument musí být konstanta TextureMapping (např. TextureMapping.DIFFUSE) určující, do které texturové slotu patří UV vrstva.

Potřebuje mesh normály pro správný export?

Ne. Normály jsou volitelné. Pokud jsou vynechány, většina prohlížečů vypočítá normály pro každou plochu z pořadí vrcholů polygonu. Přidání explicitních normál na vrcholy produkuje hladší stínování.

Mohu přidat více meshů do jednoho uzlu?

Ano. Zavolejte node.add_entity(mesh) vícekrát. Každé volání přidá novou entitu do node.entities. Některé formáty mohou při exportu sloučit více entit do jedné.

Jak triangulovat síť s různými typy polygonů?

Zavolejte mesh.triangulate() pro převod všech čtyřúhelníků a N-gonů na trojúhelníky na místě. To je užitečné před uložením do formátů, které podporují pouze trojúhelníky.

 Čeština