Kaip sukurti 3D tinklelį naudojant Aspose.3D Python

Kaip sukurti 3D tinklelį naudojant Aspose.3D Python

Aspose.3D FOSS for Python leidžia kurti 3D geometriją visiškai kode: nereikia jokio išorinio modeliavimo įrankio. Jūs sukuriate Mesh, užpildote jį viršūnių pozicijomis (control_points) ir veidų apibrėžimais (polygons), pridedate pasirenkamus viršūnių atributus, pvz., normalės, tada išsaugote sceną bet kuriame palaikomame formate.

Žingsnis po žingsnio vadovas

Žingsnis 1: Įdiekite paketą

Įdiekite Aspose.3D FOSS iš PyPI. Nereikia natūralių plėtinių ar kompiliatoriaus įrankių grandinės.

pip install aspose-3d-foss

Patikrinkite diegimą:

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

Palaikomos Python versijos: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Žingsnis 2: Sukurkite sceną ir mazgą

Kiekvienas tinklas turi būti įkurtas scenos grafike. Sukurkite Scene ir pridėkite pavadintą Node, kad laikytų tinklą:

from aspose.threed import Scene

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

Mazgo pavadinimas išsaugomas eksportuotame faile ir yra naudingas derinimui bei vėlesniam gavimui per node.get_child("triangle").


Žingsnis 3: sukurti tinklo objektą

Sukurkite Mesh su pasirenkamu aprašomu pavadinimu:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Tinklas iš pradžių yra tuščias: nėra viršūnių, nėra daugiakampių. Jūs jį užpildote šiais žingsniais.


Žingsnis 4: Pridėti valdymo taškus (viršūnes)

Kontroliniai taškai yra viršūnių pozicijos. Kiekviena viršūnė yra saugoma kaip Vector4(x, y, z, w), kur w=1 nurodo tašką 3D erdvėje:

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

Svarbu: mesh.control_points grąžina kopiją vidinio viršūnių sąrašo (getter vykdo list(self._control_points)). Iškviečiant mesh.control_points.append(v) pridedama prie kopijos, o ne prie tinklelio, todėl viršūnė tyliai atmesta. Visada naudokite mesh._control_points.append(v), kad pridėtumėte viršūnes. Prieigos prie privačios būsenos per _control_points yra žinomas apeinimas; sąsaja gali pasikeisti būsimoje bibliotekos versijoje.


5 žingsnis: sukurti daugiakampio veidus

Apibrėžkite veido topologiją naudodami viršūnių indeksus. Perduokite viršūnių indeksus create_polygon(). Trys indeksai sukuria trikampį; keturi – kvadratinę figūrą:

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

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

Keturių kraštų tinkleliui turėtumėte perduoti keturis indeksus: mesh.create_polygon(0, 1, 2, 3).

Indeksai turi būti teisingos pozicijos control_points (nulio pagrindu, ribų viduje). Vėjimo tvarka yra prieš laikrodžio rodyklę, kai normalės nukreiptos į išorę.


Žingsnis 6: Pridėti viršūnių normalės

Viršūnių normalių duomenys saugomi kaip VertexElement, prisegtas prie tinklelio. Naudokite mesh.create_element() kartu su VertexElementType.NORMAL, MappingMode.CONTROL_POINT ir 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 reiškia vieną normalę per viršūnę. ReferenceMode.DIRECT reiškia, kad normalų duomenys skaitomi ta pačia tvarka kaip valdymo taškai (nėra papildomo indeksų buferio).

Normalūs vektoriai naudoja FVector4(x, y, z, w) kartu su w=0, kad nurodytų kryptį, o ne poziciją. FVector4 yra viengubo tikslumo slankaus kablelio vektorius; viršūnių atributo duomenys VertexElementFVector pakaitinėse klasėse naudoja šį tipą.


Žingsnis 7: Prisegti tinklelį prie mazgo ir išsaugoti

Pridėkite tinklelį prie mazgo, tada išsaugokite sceną:

node.add_entity(mesh)

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

Pilnas veikiantis scenarijus (visi žingsniai sujungti):

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

Dažnos problemos

IssueResolution
IndexError į create_polygonPatikrinkite, ar visi indeksai yra range(len(mesh.control_points)) ribose. Indeksai yra nulio pagrindo.
Mesh eksportas su nuliniais viršūnėmismesh.control_points.append(...) tyliai pašalina viršūnes, nes savybė grąžina kopiją. Vietoj to naudokite mesh._control_points.append(...).
Normalų skaičius neatitinka viršūnių skaičiausNaudojant MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data turi turėti lygiai len(control_points) įrašų.
Mesh nerandamas išsaugotame failePatikrinkite, ar node.add_entity(mesh) buvo iškviestas prieš scene.save(). Tinklas, nepriskirtas jokiam mazgui, nėra eksportuojamas.
Neteisinga virpimo tvarka (veidas atrodo nematomas)Prieš laikrodžio rodyklę einanti viršūnių tvarka sukuria išorės nukreiptą normalę. Apverskite indeksų tvarką create_polygon, kad ją pakeistumėte.
polygon_count grąžina 0polygon_count skaito tą patį sąrašą kaip polygons. Jei create_polygon nebuvo iškviestas, sąrašas yra tuščias.
Normalės atrodo neteisingos peržiūros programojeĮsitikinkite, kad visi normalės vektoriai yra vienetinio ilgio. Apskaičiuokite naudodami n / abs(n) arba perduokite iš anksto normalizuotas reikšmes.

Dažnai užduodami klausimai

Kuo skiriasi Vector3 ir Vector4 valdymo taškams?

control_points saugo Vector4 objektus. w komponentas yra homogeninė koordinatė: naudokite w=1 viršūnių pozicijoms ir w=0 krypties vektoriams, tokiems kaip normalės. Vector3 naudojamas transformacijoms (perkėlimas, mastelis), bet ne geometrijos saugojimui.

Ar galiu sukurti tinklelį su kvadratais vietoj trikampių?

Taip. Iškvieskite mesh.create_polygon(0, 1, 2, 3) su keturiais indeksais, kad apibrėžtumėte quad. Kai kurie išsaugojimo tikslai (STL, 3MF) reikalauja trikampių ir automatiškai trianguliuos quads. glTF ir COLLADA išsaugo quads.

Kaip pridėti UV koordinates?

Naudokite mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX), kad sukurtumėte VertexElementUV difuziniam kanalui, tada užpildykite jo data sąrašą Vector4 įrašais. UV koordinatės naudoja x ir y; z ir w paprastai yra 0. Pirmasis argumentas turi būti TextureMapping konstanta (pvz., TextureMapping.DIFFUSE), nurodanti, kuriam tekstūros lizdui priklauso UV sluoksnis.

Ar meshui reikia normalių, kad būtų teisingai eksportuota?

Ne. Normalės yra neprivalomos. Jei jos praleidžiamos, dauguma peržiūros programų apskaičiuoja per-face normalės iš daugiakampio vėjimo tvarkos. Pridedant aiškias per-vertex normalės, gaunamas lygesnis šešėliavimas.

Ar galiu pridėti kelis meshes į vieną node?

Taip. Iškviesti node.add_entity(mesh) kelis kartus. Kiekvienas iškvietimas prideda naują objektą į node.entities. Kai kurie formatai gali sujungti kelis objektus į vieną eksportuojant.

Kaip sutrianguliuoti tinklelį su mišrių daugiakampių tipais?

Iškvieskite mesh.triangulate(), kad vietoje konvertuotumėte visus kvadratus ir N‑gonus į trikampius. Tai naudinga prieš išsaugant į formatus, kurie palaiko tik trikampius.

 Lietuvių