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-foss

Tiada 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:

FormatExtensionBacaTulisNota
Wavefront OBJ.objYaYa.mtl pemuatan bahan disokong
STL (binary).stlYaYaPusingan semula disahkan (39 ujian)
STL (ASCII).stlYaYaPusingan semula disahkan
glTF 2.0.gltfYaYaGraf adegan penuh dipelihara
GLB (binary glTF).glbYaYaKontena binari satu fail
COLLADA.daeYaYaHierarki adegan dan bahan
3MF.3mfYaYaFormat pembuatan aditif
FBX.fbxSebahagianTidakTokenizer 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.

KelasTujuan
Vector2vektor titik apung 2D (koordinat UV)
Vector3vektor berketepatan berganda 3D (kedudukan, normal)
Vector4vektor berketepatan berganda 4D (koordinat homogen)
FVector3vektor berketepatan tunggal 3D (penyimpanan mampat)
Quaternionrepresentasi putaran tanpa gimbal lock
Matrix4matriks transformasi 4×4
BoundingBoxkotak 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.

KelasFormatCiri-ciri Utama
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLMod output binari vs. ASCII
(glTF menggunakan nilai lalai)glTF / GLBGraf 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 = True apabila 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 = True apabila 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 panggilan scene.save() lebih cekap daripada muatan berulang.
  • Apabila memproses kumpulan besar, bina satu contoh ObjLoadOptions atau StlSaveOptions dan gunakan semula ia merentasi semua fail daripada membina objek pilihan baru bagi setiap fail.

Pengendalian Ralat

  • Balut panggilan scene.open() dan scene.save() dalam blok try/except apabila memproses fail yang tidak dipercayai atau disediakan oleh pengguna. Laporkan nama fail dalam mesej pengecualian untuk mempermudah penyahpepijatan dalam paip batch.

Isu Umum

IsuPuncaPenyelesaian
Mesh muncul terbalik selepas dimuatkanKetidakcocokan tangan sistem koordinatTogol ObjLoadOptions.flip_coordinate_system
Normal mempunyai panjang sifarFail sumber mempunyai normal yang tidak dinormalisasiTetapkan ObjLoadOptions.normalize_normal = True
Bahan tidak dimuatkan dari OBJenable_materials ialah False (lalai)Tetapkan ObjLoadOptions.enable_materials = True
Adegan dimuat tetapi semua nod kosongFail menggunakan format FBXPengurai FBX masih dalam pembangunan; gunakan OBJ, STL, atau glTF sebagai gantinya
Model sangat kecil atau besarFail sumber menggunakan unit bukan metrikGunakan ObjLoadOptions.scale untuk menukar kepada unit sasaran anda
AttributeError pada mesh.polygonsEntiti nod bukan MeshLindungi dengan if node.entity is not None sebelum mengakses sifat entiti
Fail GLB ditolak oleh penontonDisimpan dengan sambungan .gltfGunakan 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 untuk open(), from_file(), dan save().
  • Node: Nod pokok dalam graf adegan. Membawa entity, transform, global_transform, material, child_nodes, dan name.
  • 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 dengan control_points (senarai vertex) dan polygons.
  • 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 dengan diffuse_color dan emissive_color.
  • PhongMaterial: Model shading specular menambah specular_color dan shininess.

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 dengan from_angle_axis() dan to_matrix().
  • Matrix4: matriks transformasi 4×4.
  • BoundingBox: kotak sempadan selari paksi dengan sudut minimum dan maximum.

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 kepada Node.
  • Light: Entiti sumber cahaya, boleh dilampirkan kepada Node.
 Bahasa Melayu