Cara Membuat Mesh 3D dengan Aspose.3D di Python
Aspose.3D FOSS for Python memungkinkan Anda membangun geometri 3D sepenuhnya dalam kode: tidak memerlukan alat pemodelan eksternal. Anda membuat Mesh, mengisinya dengan posisi vertex (control_points) dan definisi wajah (polygons), melampirkan atribut vertex opsional seperti normal, lalu menyimpan adegan ke format yang didukung apa pun.
Panduan Langkah-demi-Langkah
Langkah 1: Instal Paket
Instal Aspose.3D FOSS dari PyPI. Tidak diperlukan ekstensi native atau toolchain kompilator.
pip install aspose-3d-fossVerifikasi instalasi:
from aspose.threed import Scene
print("Aspose.3D FOSS ready")Versi Python yang didukung: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Langkah 2: Buat Scene dan Node
Setiap mesh harus berada di dalam sebuah scene graph. Buat sebuah Scene dan tambahkan sebuah Node yang diberi nama untuk menampung mesh:
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")Nama node dipertahankan dalam file yang diekspor dan berguna untuk debugging serta pengambilan kembali nanti melalui node.get_child("triangle").
Langkah 3: Buat Objek Mesh
Instansiasi Mesh dengan nama deskriptif opsional:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")Mesh awalnya kosong: tidak ada vertex, tidak ada poligon. Anda mengisinya dalam langkah-langkah berikut.
Langkah 4: Tambahkan Titik Kontrol (Vertex)
Titik kontrol adalah posisi vertex. Setiap vertex disimpan sebagai Vector4(x, y, z, w) di mana w=1 menunjukkan sebuah 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 dari daftar vertex internal (getter mengeksekusi list(self._control_points)). Memanggil mesh.control_points.append(v) menambahkan ke salinan, bukan ke mesh, sehingga vertex tersebut diam‑diam dibuang. Selalu gunakan mesh._control_points.append(v) untuk menambahkan vertex. Mengakses state privat melalui _control_points adalah solusi yang diketahui; antarmuka dapat berubah di versi perpustakaan yang akan datang.
Langkah 5: Buat Wajah Poligon
Tentukan topologi wajah menggunakan indeks vertex. Kirimkan indeks vertex ke 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 segi empat Anda akan mengirimkan empat indeks: mesh.create_polygon(0, 1, 2, 3).
Indeks harus menjadi posisi yang valid dalam control_points (berbasis 0, dalam rentang). Urutan winding adalah berlawanan arah jarum jam untuk normal yang menghadap ke luar.
Langkah 6: Tambahkan Normal Vertex
Normal vertex disimpan sebagai VertexElement yang terlampir 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 berarti satu normal per vertex. ReferenceMode.DIRECT berarti data normal dibaca dalam urutan yang sama dengan control points (tanpa buffer indeks tambahan).
Vektor normal menggunakan FVector4(x, y, z, w) dengan w=0 untuk menunjukkan arah bukan posisi. FVector4 adalah vektor float presisi tunggal; data atribut vertex dalam subclass VertexElementFVector menggunakan tipe ini.
Langkah 7: Lampirkan Mesh ke Node dan Simpan
Tambahkan mesh ke node, lalu simpan scene:
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")Masalah Umum
| Issue | Resolution |
|---|---|
IndexError di create_polygon | Verifikasi bahwa semua indeks berada dalam range(len(mesh.control_points)). Indeks bersifat berbasis nol. |
| Mesh mengekspor dengan nol vertex | mesh.control_points.append(...) secara diam-diam membuang vertex karena properti mengembalikan salinan. Gunakan mesh._control_points.append(...) sebagai gantinya. |
| Jumlah normal tidak cocok dengan jumlah vertex | Saat menggunakan MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data harus memiliki tepat len(control_points) entri. |
| Mesh tidak muncul dalam file yang disimpan | Pastikan bahwa node.add_entity(mesh) dipanggil sebelum scene.save(). Mesh yang tidak terhubung ke node manapun tidak akan diekspor. |
| Urutan winding salah (wajah tampak tidak terlihat) | Urutan vertex berlawanan arah jarum jam menghasilkan normal menghadap ke luar. Balikkan urutan indeks dalam create_polygon untuk membaliknya. |
polygon_count mengembalikan 0 | polygon_count membaca daftar yang sama dengan polygons. Jika create_polygon tidak dipanggil, daftar tersebut kosong. |
| Normal tampak tidak tepat di penampil | Pastikan semua vektor normal memiliki panjang satu. Hitung dengan n / abs(n) atau berikan nilai yang sudah ternormalisasi. |
Pertanyaan yang Sering Diajukan
Apa perbedaan antara Vector3 dan Vector4 untuk titik kontrol?
control_points menyimpan objek Vector4. Komponen w adalah koordinat homogen: gunakan w=1 untuk posisi vertex dan w=0 untuk vektor arah seperti normal. Vector3 digunakan untuk transformasi (translasi, skala) tetapi tidak untuk penyimpanan geometri.
Bisakah saya membuat mesh dengan kuad alih-alih segitiga?
Ya. Panggil mesh.create_polygon(0, 1, 2, 3) dengan empat indeks untuk mendefinisikan sebuah quad. Beberapa target penyimpanan (STL, 3MF) memerlukan segitiga dan akan secara otomatis men‑triangulasi quad. glTF dan COLLADA mempertahankan quad.
Bagaimana cara menambahkan koordinat UV?
Gunakan mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) untuk membuat VertexElementUV untuk saluran difus, kemudian isi daftar data‑nya dengan entri Vector4. Koordinat UV menggunakan x dan y; z dan w biasanya 0. Argumen pertama harus berupa konstanta TextureMapping (misalnya, TextureMapping.DIFFUSE) yang mengidentifikasi slot tekstur mana lapisan UV berada.
Apakah mesh memerlukan normal agar dapat diekspor dengan benar?
Tidak. Normal bersifat opsional. Jika diabaikan, kebanyakan penampil menghitung per-face normals dari urutan winding poligon. Menambahkan per-vertex normals secara eksplisit menghasilkan shading yang lebih halus.
Bisakah saya menambahkan beberapa mesh ke satu node?
Ya. Panggil node.add_entity(mesh) beberapa kali. Setiap panggilan menambahkan entitas baru ke node.entities. Beberapa format mungkin meratakan beberapa entitas menjadi satu saat diekspor.
Bagaimana cara saya melakukan triangulasi pada mesh dengan tipe poligon campuran?
Panggil mesh.triangulate() untuk mengonversi semua quad dan N‑gon menjadi segitiga secara langsung. Ini berguna sebelum menyimpan ke format yang hanya mendukung segitiga.