Ciri-ciri dan Fungsi
Aspose.3D FOSS for Python menyediakan API grafik-pemandangan lengkap untuk membaca, membina, dan menulis kandungan 3D dalam pelbagai format piawaian industri. Halaman ini mendokumentasikan setiap kawasan ciri utama dengan contoh kod Python yang berfungsi menggunakan API perpustakaan sebenar.
Pemasangan dan Persediaan
Pasang perpustakaan dari PyPI dengan satu arahan:
pip install aspose-3d-fossTiada pakej sistem tambahan, sambungan asli, atau rangka kerja pemalam pengkompil yang diperlukan. Perpustakaan ini adalah Python tulen dan menyokong Python 3.7 hingga 3.12 pada Windows, macOS, dan Linux.
Untuk mengesahkan pemasangan:
from aspose.threed import Scene
scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")Ciri-ciri dan Fungsi
Sokongan Format
Aspose.3D FOSS untuk Python membaca dan menulis format berikut:
| Format | Extension | Baca | Tulis | Nota |
|---|---|---|---|---|
| Wavefront OBJ | .obj | Ya | Ya | .mtl pemuatan bahan disokong |
| STL (binary) | .stl | Ya | Ya | Pusingan semula disahkan (39 ujian) |
| STL (ASCII) | .stl | Ya | Ya | Pusingan semula disahkan |
| glTF 2.0 | .gltf | Ya | Ya | Graf adegan penuh dipelihara |
| GLB (binary glTF) | .glb | Ya | Ya | Kontena binari satu fail |
| COLLADA | .dae | Ya | Ya | Hierarki adegan dan bahan |
| 3MF | .3mf | Ya | Ya | Format pembuatan aditif |
| FBX | .fbx | Sebahagian | Tidak | Tokenizer berfungsi; parser mempunyai pepijat yang diketahui |
Memuat OBJ dengan Pilihan
ObjLoadOptions mengawal cara fail OBJ diparse:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True # Load accompanying .mtl file
options.flip_coordinate_system = False # Preserve original handedness
options.normalize_normal = True # Normalize vertex normals to unit length
options.scale = 1.0 # Apply a uniform scale factor at load time
scene = Scene()
scene.open("model.obj", options)
print(f"Loaded {len(scene.root_node.child_nodes)} top-level nodes")Menyimpan ke STL
StlSaveOptions mengawal output binari berbanding ASCII dan tetapan khusus STL yang lain:
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)Graf Adegan
Semua kandungan 3D disusun sebagai pokok objek Node. Akar pokok ialah scene.root_node. Setiap nod boleh mengandungi nod anak dan membawa Entity (mesh, kamera, atau cahaya) serta Transform.
Menelusuri Hierarki Adegan
from aspose.threed import Scene
scene = Scene.from_file("model.glb")
def traverse(node, depth=0):
indent = " " * depth
entity_type = type(node.entity).__name__ if node.entity else "none"
print(f"{indent}{node.name} [{entity_type}]")
for child in node.child_nodes:
traverse(child, depth + 1)
traverse(scene.root_node)Membina Adegan Secara Program
from aspose.threed import Scene, Node, Entity
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3
scene = Scene()
root = scene.root_node
##Create a child node and position it
child = root.create_child_node("my_object")
child.transform.translation = Vector3(1.0, 0.0, 0.0)
child.transform.scaling = Vector3(2.0, 2.0, 2.0)
scene.save("constructed.glb")Menyemak GlobalTransform
GlobalTransform memberikan transformasi ruang-dunia bagi satu nod selepas mengumpulkan semua transformasi nenek moyang:
from aspose.threed import Scene
scene = Scene.from_file("model.dae")
for node in scene.root_node.child_nodes:
gt = node.global_transform
print(f"Node: {node.name}")
print(f" World translation: {gt.translation}")
print(f" World scale: {gt.scale}")Mesh API
Entiti Mesh memberikan akses kepada data geometri termasuk titik kawalan (vertices), poligon, dan elemen vertex untuk normal, UVs, dan warna.
Membaca Geometri Mesh
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
options.flip_coordinate_system = False
scene = Scene()
scene.open("model.obj", options)
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
print(f"Mesh: {node.name}")
print(f" Vertices: {len(mesh.control_points)}")
print(f" Polygons: {len(mesh.polygons)}")Mengakses Elemen Vertex
Elemen vertex membawa data per-vertex atau per-polygon. Elemen yang paling umum ialah normal, koordinat UV, warna vertex, dan kumpulan pelicinan:
from aspose.threed import Scene
from aspose.threed.entities import VertexElementNormal, VertexElementUV
scene = Scene.from_file("model.obj")
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
# Iterate vertex elements to find normals and UVs
for element in mesh.vertex_elements:
if isinstance(element, VertexElementNormal):
print(f" Normals count: {len(element.data)}")
elif isinstance(element, VertexElementUV):
print(f" UV count: {len(element.data)}")Sistem Bahan
Aspose.3D FOSS menyokong dua jenis bahan: LambertMaterial (shading difus) dan PhongMaterial (shading spekular). Kedua-duanya dimuat secara automatik dari fail .mtl apabila menggunakan ObjLoadOptions dengan enable_materials = True.
Bahan Bacaan dari OBJ
from aspose.threed import Scene
from aspose.threed.shading import LambertMaterial, PhongMaterial
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
scene = Scene()
scene.open("model.obj", options)
for node in scene.root_node.child_nodes:
mat = node.material
if mat is None:
continue
print(f"Node: {node.name}")
if isinstance(mat, PhongMaterial):
print(f" Type: Phong")
print(f" Diffuse: {mat.diffuse_color}")
print(f" Specular: {mat.specular_color}")
elif isinstance(mat, LambertMaterial):
print(f" Type: Lambert")
print(f" Diffuse: {mat.diffuse_color}")Menetapkan Material secara Programatik
from aspose.threed import Scene, Node
from aspose.threed.shading import PhongMaterial
from aspose.threed.utilities import Vector3
scene = Scene.from_file("model.glb")
material = PhongMaterial()
material.diffuse_color = Vector3(0.8, 0.2, 0.2) # Red diffuse
material.specular_color = Vector3(1.0, 1.0, 1.0) # White specular
##Apply to the first mesh node
for node in scene.root_node.child_nodes:
if node.entity is not None:
node.material = material
break
scene.save("recolored.glb")Utiliti Matematik
Modul aspose.threed.utilities menyediakan semua jenis matematik geometri yang diperlukan untuk pembinaan adegan dan pemeriksaan.
| Kelas | Tujuan |
|---|---|
Vector2 | vektor titik apung 2D (koordinat UV) |
Vector3 | vektor berketepatan berganda 3D (kedudukan, normal) |
Vector4 | vektor berketepatan berganda 4D (koordinat homogen) |
FVector3 | vektor berketepatan tunggal 3D (penyimpanan mampat) |
Quaternion | representasi putaran tanpa gimbal lock |
Matrix4 | matriks transformasi 4×4 |
BoundingBox | kotak sempadan selari paksi dengan bucu min/maks |
Bekerja dengan Transformasi
from aspose.threed.utilities import Vector3, Quaternion, Matrix4
import math
##Build a rotation quaternion from axis-angle
axis = Vector3(0.0, 1.0, 0.0) # Y-axis
angle_rad = math.radians(45.0)
q = Quaternion.from_angle_axis(angle_rad, axis)
print(f"Quaternion: x={q.x:.4f} y={q.y:.4f} z={q.z:.4f} w={q.w:.4f}")
##Convert to rotation matrix
mat = q.to_matrix()
print(f"Rotation matrix row 0: {mat[0, 0]:.4f} {mat[0, 1]:.4f} {mat[0, 2]:.4f}")Mengira Kotak Sempadan
from aspose.threed import Scene
scene = Scene.from_file("model.stl")
# NOTE: mesh.get_bounding_box() is a stub — it always returns an empty BoundingBox()
# regardless of geometry. Compute bounds manually from control_points:
for node in scene.root_node.child_nodes:
if node.entity is None:
continue
mesh = node.entity
pts = mesh.control_points # returns a copy of the vertex list
if not pts:
continue
xs = [p.x for p in pts]
ys = [p.y for p in pts]
zs = [p.z for p in pts]
print(f"Mesh: {node.name}")
print(f" Min: ({min(xs):.3f}, {min(ys):.3f}, {min(zs):.3f})")
print(f" Max: ({max(xs):.3f}, {max(ys):.3f}, {max(zs):.3f})")Animasi
Aspose.3D FOSS menyediakan model animasi berdasarkan AnimationClip, AnimationNode, KeyFrame, dan KeyframeSequence. Data animasi yang disimpan dalam fail yang dimuatkan (glTF, COLLADA) boleh diakses melalui objek-objek ini.
Membaca Klip Animasi
from aspose.threed import Scene
scene = Scene.from_file("animated.glb")
for clip in scene.animation_clips:
print(f"Clip: {clip.name} ({clip.start:.2f}s – {clip.stop:.2f}s)")
for anim_node in clip.animations:
print(f" Animation node: {anim_node.name}")
for sub in anim_node.sub_animations:
print(f" Sub-animation: {sub.name}")
for bp in anim_node.bind_points:
print(f" Bind point: {bp.name}")Pilihan Muat dan Simpan
Setiap format yang disokong mempunyai kelas pilihan yang sepadan yang mengawal tingkah laku parsing dan serialization.
| Kelas | Format | Ciri-ciri Utama |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Mod output binari vs. ASCII |
| (glTF menggunakan nilai lalai) | glTF / GLB | Graf adegan dan bahan dipelihara secara automatik |
Contoh Penggunaan
Contoh 1: Penukaran Format OBJ ke STL
Tukar fail OBJ (dengan bahan) kepada STL binari, mencetak statistik mesh sepanjang proses:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
from aspose.threed.formats import StlSaveOptions
##Load OBJ with material support
load_opts = ObjLoadOptions()
load_opts.enable_materials = True
load_opts.flip_coordinate_system = False
load_opts.normalize_normal = True
scene = Scene()
scene.open("input.obj", load_opts)
##Report what was loaded
total_vertices = 0
total_polygons = 0
for node in scene.root_node.child_nodes:
if node.entity is not None:
mesh = node.entity
total_vertices += len(mesh.control_points)
total_polygons += len(mesh.polygons)
print(f" {node.name}: {len(mesh.control_points)} vertices, {len(mesh.polygons)} polygons")
print(f"Total: {total_vertices} vertices, {total_polygons} polygons")
##Save as STL
save_opts = StlSaveOptions()
scene.save("output.stl", save_opts)
print("Saved output.stl")Contoh 2: Pembungkusan glTF ke GLB secara Pukal
Simpan semula direktori fail glTF + tekstur berasingan sebagai binari GLB yang berdiri sendiri:
import os
from aspose.threed import Scene
input_dir = "gltf_files"
output_dir = "glb_files"
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.endswith(".gltf"):
continue
src = os.path.join(input_dir, filename)
dst = os.path.join(output_dir, filename.replace(".gltf", ".glb"))
scene = Scene.from_file(src)
scene.save(dst)
print(f"Packed {filename} -> {os.path.basename(dst)}")Contoh 3: Pemeriksaan Graf Adegan dan Laporan Eksport
Lalui graf adegan fail COLLADA, kumpulkan statistik per‑mesh, dan cetak laporan berstruktur:
from aspose.threed import Scene
scene = Scene.from_file("assembly.dae")
report = []
def collect(node, path=""):
full_path = f"{path}/{node.name}" if node.name else path
if node.entity is not None:
mesh = node.entity
gt = node.global_transform
report.append({
"path": full_path,
"vertices": len(mesh.control_points),
"polygons": len(mesh.polygons),
"world_x": gt.translation.x,
"world_y": gt.translation.y,
"world_z": gt.translation.z,
})
for child in node.child_nodes:
collect(child, full_path)
collect(scene.root_node)
print(f"{'Path':<40} {'Verts':>6} {'Polys':>6} {'X':>8} {'Y':>8} {'Z':>8}")
print("-" * 78)
for entry in report:
print(
f"{entry['path']:<40} "
f"{entry['vertices']:>6} "
f"{entry['polygons']:>6} "
f"{entry['world_x']:>8.3f} "
f"{entry['world_y']:>8.3f} "
f"{entry['world_z']:>8.3f}"
)Petua dan Amalan Terbaik
Pemilihan Format
- glTF 2.0 / GLB adalah format pertukaran yang disyorkan untuk adegan yang termasuk bahan, animasi, dan hierarki yang kompleks. Pilih GLB (binari) berbanding glTF (teks + fail luaran) untuk kebolehportingan.
- STL adalah pilihan yang tepat apabila pengguna hiliran adalah slicer, alat CAD, atau mana-mana alat yang hanya memerlukan geometri. STL tidak membawa data bahan atau animasi.
- OBJ disokong secara meluas dan merupakan pilihan yang baik apabila data bahan perlu dipertukarkan dengan alat lama. Sentiasa simpan fail .mtl bersama fail .obj.
Sistem Koordinat
- Aplikasi yang berbeza menggunakan konvensyen handedness yang berbeza. Tetapkan
ObjLoadOptions.flip_coordinate_system = Trueapabila mengimport fail OBJ dari alat yang menggunakan sistem koordinat tangan kanan jika pipeline anda menjangka koordinat tangan kiri, dan sebaliknya. - Sahkan konvensyen paksi aset sumber sebelum melakukan sebarang flip. Membalik dua kali menghasilkan geometri yang tidak betul.
Normalisasi
- Sentiasa tetapkan
ObjLoadOptions.normalize_normal = Trueapabila paip hiliran menjangka normal unit (contohnya, apabila menghantar normal kepada shader atau melakukan pengiraan pencahayaan dot‑product). Normal yang tidak dinormalkan daripada fail OBJ yang dibentuk dengan buruk menyebabkan artifak pencahayaan.
Prestasi
- Muat fail sekali dan ubah graf adegan dalam memori daripada memuat semula dari cakera untuk setiap format output. Satu panggilan
Scene.from_file()diikuti dengan pelbagai panggilanscene.save()lebih cekap daripada muatan berulang. - Apabila memproses kumpulan besar, bina satu contoh
ObjLoadOptionsatauStlSaveOptionsdan gunakan semula ia merentasi semua fail daripada membina objek pilihan baru bagi setiap fail.
Pengendalian Ralat
- Balut panggilan
scene.open()danscene.save()dalam bloktry/exceptapabila memproses fail yang tidak dipercayai atau disediakan oleh pengguna. Laporkan nama fail dalam mesej pengecualian untuk mempermudah penyahpepijatan dalam paip batch.
Isu Umum
| Isu | Punca | Penyelesaian |
|---|---|---|
| Mesh muncul terbalik selepas dimuatkan | Ketidakcocokan tangan sistem koordinat | Togol ObjLoadOptions.flip_coordinate_system |
| Normal mempunyai panjang sifar | Fail sumber mempunyai normal yang tidak dinormalisasi | Tetapkan ObjLoadOptions.normalize_normal = True |
| Bahan tidak dimuatkan dari OBJ | enable_materials ialah False (lalai) | Tetapkan ObjLoadOptions.enable_materials = True |
| Adegan dimuat tetapi semua nod kosong | Fail menggunakan format FBX | Pengurai FBX masih dalam pembangunan; gunakan OBJ, STL, atau glTF sebagai gantinya |
| Model sangat kecil atau besar | Fail sumber menggunakan unit bukan metrik | Gunakan ObjLoadOptions.scale untuk menukar kepada unit sasaran anda |
AttributeError pada mesh.polygons | Entiti nod bukan Mesh | Lindungi dengan if node.entity is not None sebelum mengakses sifat entiti |
| Fail GLB ditolak oleh penonton | Disimpan dengan sambungan .gltf | Gunakan sambungan .glb semasa memanggil scene.save() untuk memicu kontena binari |
Soalan Lazim
Versi Python apa yang disokong?
Python 3.7, 3.8, 3.9, 3.10, 3.11, dan 3.12 semuanya disokong. Perpustakaan ini adalah Python tulen tanpa sambungan asli, jadi ia berfungsi pada mana-mana platform di mana CPython dijalankan.
Adakah perpustakaan mempunyai sebarang kebergantungan luaran?
Tidak. Aspose.3D FOSS for Python hanya menggunakan perpustakaan standard Python. Ia dipasang sebagai satu pip install aspose-3d-foss arahan tanpa langkah susulan.
Adakah FBX disokong? Penanda token FBX telah dilaksanakan dan boleh mengurai aliran token binari FBX, tetapi pembina grafik adegan di atas penanda token mempunyai pepijat yang diketahui dan tidak bersedia untuk pengeluaran. Gunakan OBJ, STL, glTF, COLLADA, atau 3MF untuk penggunaan pengeluaran yang boleh dipercayai.
Bolehkah saya menggunakan Aspose.3D FOSS dalam produk komersial? Ya. Perpustakaan ini dikeluarkan di bawah lesen MIT, yang membenarkan penggunaan dalam perisian proprietari dan komersial tanpa pembayaran royalti, dengan syarat notis lesen disertakan.
Bagaimana saya melaporkan pepijat atau meminta format?
Buka isu dalam repositori. Sertakan fail reproduksi minimum dan versi Python, sistem operasi, serta versi perpustakaan dari pip show aspose-3d-foss.
Ringkasan Rujukan API
Kelas Teras
Scene: Bekas peringkat atas untuk adegan 3D. Titik masuk untukopen(),from_file(), dansave().Node: Nod pokok dalam graf adegan. Membawaentity,transform,global_transform,material,child_nodes, danname.Entity: Kelas asas untuk objek yang dilampirkan pada nod (Mesh, Camera, Light).Transform: Kedudukan ruang setempat, putaran (Quaternion), dan skala untuk nod.GlobalTransform: Transformasi ruang dunia hanya-baca yang dikira dengan mengumpulkan semua transformasi nenek moyang.
Geometri
Mesh: Mesh poligon dengancontrol_points(senarai vertex) danpolygons.VertexElementNormal: Vektor normal per-vertex atau per-poligon.VertexElementUV: Koordinat tekstur UV per-vertex.VertexElementVertexColor: Data warna per-vertex.VertexElementSmoothingGroup: Penetapan kumpulan pelicinan poligon.
Bahan
LambertMaterial: Model shading diffuse dengandiffuse_colordanemissive_color.PhongMaterial: Model shading specular menambahspecular_colordanshininess.
Utiliti Matematik (aspose.threed.utilities)
Vector2: vektor 2D.Vector3: vektor 3D berketepatan berganda.Vector4: vektor 4D berketepatan berganda.FVector3: vektor 3D berketepatan tunggal.Quaternion: Quaternion putaran denganfrom_angle_axis()danto_matrix().Matrix4: matriks transformasi 4×4.BoundingBox: kotak sempadan selari paksi dengan sudutminimumdanmaximum.
Animasi
AnimationClip: Bekas bernama untuk satu set saluran animasi dan bingkai kuncinya.AnimationNode: Data animasi per nod dalam klip.KeyFrame: Satu bingkai kunci dengan masa dan nilai.KeyframeSequence: Urutan teratur bingkai kunci untuk satu sifat yang dianimasikan.
Pilihan Muat / Simpan
ObjLoadOptions: tetapan muat khusus OBJ:enable_materials,flip_coordinate_system,normalize_normal,scale.StlSaveOptions: tetapan simpan khusus STL (mod binari vs. ASCII).
Kamera dan Lampu
Camera: Entiti kamera dengan tetapan unjuran, boleh dilampirkan kepadaNode.Light: Entiti sumber cahaya, boleh dilampirkan kepadaNode.