Cara Membina Mesh 3D dengan Aspose.3D dalam Python

Cara Membina Mesh 3D dengan Aspose.3D dalam Python

Aspose.3D FOSS untuk Python membolehkan anda membina geometri 3D sepenuhnya dalam kod: tiada alat pemodelan luaran diperlukan. Anda mencipta Mesh, mengisinya dengan kedudukan vertex (control_points) dan definisi muka (polygons), melampirkan atribut vertex pilihan seperti normal, kemudian menyimpan adegan ke mana-mana format yang disokong.

Panduan Langkah demi Langkah

Langkah 1: Pasang Pakej

Pasang Aspose.3D FOSS dari PyPI. Tiada sambungan asli atau rantaian alat penyusun diperlukan.

pip install aspose-3d-foss

Sahkan pemasangan:

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

Versi Python yang disokong: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Langkah 2: Cipta Adegan dan Node

Setiap mesh mesti berada di dalam graf adegan. Cipta Scene dan tambahkan Node yang dinamakan untuk menampung mesh:

from aspose.threed import Scene

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

Nama nod dipelihara dalam fail yang dieksport dan berguna untuk penyahpepijatan serta pengambilan kemudian melalui node.get_child("triangle").


Langkah 3: Buat Objek Mesh

Cipta satu Mesh dengan nama deskriptif pilihan:

from aspose.threed.entities import Mesh

mesh = Mesh("triangle")

Mesh itu pada mulanya kosong: tiada titik, tiada poligon. Anda mengisinya dalam langkah‑langkah berikut.


Langkah 4: Tambah Titik Kawalan (Vertices)

Titik kawalan adalah kedudukan verteks. Setiap verteks disimpan sebagai Vector4(x, y, z, w) di mana w=1 menunjukkan satu titik dalam ruang 3D:

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 mengembalikan salinan senarai vertex dalaman (getter melaksanakan list(self._control_points)). Memanggil mesh.control_points.append(v) menambah ke salinan, bukan ke mesh, jadi vertex tersebut dibuang secara senyap. Sentiasa gunakan mesh._control_points.append(v) untuk menambah vertex. Mengakses keadaan peribadi melalui _control_points adalah penyelesaian sementara yang diketahui; antara muka mungkin berubah dalam versi perpustakaan yang akan datang.


Langkah 5: Cipta Muka Poligon

Tentukan topologi muka menggunakan indeks verteks. Hantar indeks verteks kepada create_polygon(). Tiga indeks menghasilkan segitiga; empat menghasilkan kuad:

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

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

Untuk mesh kuad anda akan menyerahkan empat indeks: mesh.create_polygon(0, 1, 2, 3).

Indeks mesti merupakan kedudukan yang sah dalam control_points (berdasarkan 0, dalam julat). Susunan lilitan adalah berlawanan arah jam untuk normal yang menghadap ke luar.


Langkah 6: Tambah Normal Vertex

Normal vertex disimpan sebagai VertexElement yang dilampirkan pada mesh. Gunakan mesh.create_element() dengan VertexElementType.NORMAL, MappingMode.CONTROL_POINT, dan 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 bermaksud satu normal bagi setiap vertex. ReferenceMode.DIRECT bermaksud data normal dibaca dalam susunan yang sama seperti titik kawalan (tiada penampan indeks tambahan).

Vektor normal menggunakan FVector4(x, y, z, w) dengan w=0 untuk menunjukkan arah bukannya kedudukan. FVector4 ialah vektor titik terapung tepat tunggal; data atribut vertex dalam subkelas VertexElementFVector menggunakan jenis ini.


Langkah 7: Lampirkan Mesh ke Node dan Simpan

Tambah mesh ke nod, kemudian simpan adegan:

node.add_entity(mesh)

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

Skrip lengkap yang berfungsi (semua langkah digabungkan):

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

Isu Umum

IssueResolution
IndexError dalam create_polygonPastikan semua indeks berada dalam range(len(mesh.control_points)). Indeks adalah berasaskan 0.
Mesh dieksport dengan sifar titikmesh.control_points.append(...) secara senyap membuang titik kerana sifat tersebut mengembalikan salinan. Gunakan mesh._control_points.append(...) sebagai gantinya.
Kiraan normal tidak sepadan dengan kiraan titikApabila menggunakan MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data mesti mempunyai tepat len(control_points) entri.
Mesh tidak muncul dalam fail yang disimpanSahkan bahawa node.add_entity(mesh) dipanggil sebelum scene.save(). Mesh yang tidak dilampirkan kepada mana-mana nod tidak akan dieksport.
Susunan lilitan salah (muka kelihatan tidak kelihatan)Susunan titik mengikut arah lawan jam menghasilkan normal menghadap ke luar. Songsangkan susunan indeks dalam create_polygon untuk membaliknya.
polygon_count mengembalikan 0polygon_count membaca senarai yang sama seperti polygons. Jika create_polygon tidak dipanggil, senarai itu kosong.
Normal kelihatan tidak betul dalam penontonPastikan semua vektor normal bersaiz unit. Kira dengan n / abs(n) atau hantarkan nilai pra-normalisasi.

Soalan Lazim

Apakah perbezaan antara Vector3 dan Vector4 untuk titik kawalan?

control_points menyimpan objek Vector4. Komponen w adalah koordinat homogen: gunakan w=1 untuk kedudukan verteks dan w=0 untuk vektor arah seperti normal. Vector3 digunakan untuk transformasi (terjemahan, skala) tetapi bukan untuk penyimpanan geometri.

Bolehkah saya membina mesh dengan quads dan bukannya segitiga?

Ya. Panggil mesh.create_polygon(0, 1, 2, 3) dengan empat indeks untuk mendefinisikan quad. Beberapa sasaran simpan (STL, 3MF) memerlukan segitiga dan akan triangulate quad secara automatik. glTF dan COLLADA mengekalkan quad.

Bagaimana saya menambah koordinat UV?

Gunakan mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) untuk membuat VertexElementUV bagi saluran difus, kemudian isi senarai datanya dengan entri Vector4. Koordinat UV menggunakan x dan y; z dan w biasanya 0. Argumen pertama mesti menjadi konstanta TextureMapping (contoh, TextureMapping.DIFFUSE) yang mengenal pasti slot tekstur mana lapisan UV tergolong.

Adakah mesh memerlukan normal untuk dieksport dengan betul?

Tidak. Normals adalah pilihan. Jika diabaikan, kebanyakan penonton mengira per-face normals dari urutan lilitan poligon. Menambah per-vertex normals secara eksplisit menghasilkan shading yang lebih halus.

Bolehkah saya menambah pelbagai mesh ke satu nod?

Ya. Panggil node.add_entity(mesh) berbilang kali. Setiap panggilan menambah entiti baru ke node.entities. Beberapa format mungkin meratakan berbilang entiti menjadi satu semasa eksport.

Bagaimana saya men‑triangulasi mesh dengan jenis poligon campuran?

Panggil mesh.triangulate() untuk menukar semua kuad dan N-gon kepada segitiga di tempat. Ini berguna sebelum menyimpan ke format yang hanya menyokong segitiga.

 Bahasa Melayu