Tính năng và Chức năng

Aspose.3D FOSS cho Python cung cấp một API đồ thị cảnh hoàn chỉnh để đọc, xây dựng và ghi nội dung 3D ở nhiều định dạng tiêu chuẩn công nghiệp. Trang này tài liệu hoá mọi khu vực tính năng chính với các ví dụ mã Python hoạt động sử dụng API thư viện thực tế.

Cài đặt và Thiết lập

Cài đặt thư viện từ PyPI bằng một lệnh duy nhất:

pip install aspose-3d-foss

Không cần các gói hệ thống bổ sung, phần mở rộng gốc, hay bộ công cụ biên dịch. Thư viện thuần Python và hỗ trợ Python 3.7 đến 3.12 trên Windows, macOS và Linux.

Để xác minh việc cài đặt:

from aspose.threed import Scene

scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")

Tính năng và Chức năng

Hỗ trợ Định dạng

Aspose.3D FOSS cho Python đọc và ghi các định dạng sau:

Định dạngPhần mở rộngĐọcGhiGhi chú
Wavefront OBJ.obj.mtl material loading supported
STL (nhị phân).stlĐã xác nhận vòng quay (39 bài kiểm tra)
STL (ASCII).stlĐã xác nhận vòng quay
glTF 2.0.gltfĐồ thị cảnh đầy đủ được bảo tồn
GLB (binary glTF).glbBộ chứa nhị phân đơn tệp
COLLADA.daeCây phân cấp cảnh và vật liệu
3MF.3mfĐịnh dạng sản xuất gia tăng
FBX.fbxMột phầnKhôngTrình tách token hoạt động; trình phân tích có các lỗi đã biết

Tải OBJ với Các Tùy chọn

ObjLoadOptions kiểm soát cách các tệp OBJ được phân tích:

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

Lưu thành STL

StlSaveOptions kiểm soát đầu ra nhị phân so với ASCII và các cài đặt đặc thù cho STL khác:

from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions

scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)

Đồ thị Cảnh

Tất cả nội dung 3D được tổ chức dưới dạng cây của Node đối tượng. Gốc của cây là scene.root_node. Mỗi nút có thể chứa các nút con và mang một Entity (mesh, camera, hoặc light) cộng với một Transform.

Duyệt Cây Cảnh

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)

Xây dựng Cảnh bằng Chương trình

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

Kiểm tra GlobalTransform

GlobalTransform cung cấp phép biến đổi không gian thế giới của một nút sau khi tích lũy tất cả các phép biến đổi của tổ tiên:

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

API Lưới

The Mesh thực thể cung cấp quyền truy cập vào dữ liệu hình học bao gồm các điểm điều khiển (đỉnh), đa giác và các phần tử đỉnh cho pháp tuyến, UV và màu sắc.

Đọc Hình Học Lưới

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

Truy cập các Phần tử Đỉnh

Các phần tử đỉnh chứa dữ liệu theo từng đỉnh hoặc theo từng đa giác. Các phần tử phổ biến nhất là pháp tuyến, tọa độ UV, màu đỉnh và nhóm làm mịn:

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

Hệ thống Vật liệu

Aspose.3D FOSS hỗ trợ hai loại vật liệu: LambertMaterial (đổ bóng khuếch tán) và PhongMaterial (đổ bóng phản chiếu). Cả hai đều được tải tự động từ các tệp .mtl khi sử dụng ObjLoadOptions với enable_materials = True.

Đọc Vật liệu từ 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}")

Gán Vật liệu Theo Chương Trình

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

Tiện ích Toán học

The aspose.threed.utilities module cung cấp tất cả các kiểu toán học hình học cần thiết cho việc xây dựng và kiểm tra cảnh.

LớpMục đích
Vector22D floating-point vector (UV coordinates)
Vector33D double-precision vector (positions, normals)
Vector44D double-precision vector (homogeneous coordinates)
FVector33D single-precision vector (compact storage)
QuaternionBiểu diễn quay mà không bị gimbal lock
Matrix44×4 transformation matrix
BoundingBoxHộp bao giới hạn theo trục với các góc tối thiểu/tối đa

Làm việc với Biến đổi

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

Tính Hộp Bao

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

Hoạt ảnh

Aspose.3D FOSS cung cấp mô hình hoạt hình dựa trên AnimationClip, AnimationNode, KeyFrame, và KeyframeSequence. Dữ liệu hoạt hình được lưu trong các tệp đã tải (glTF, COLLADA) có thể truy cập được thông qua các đối tượng này.

Đọc Các Clip Hoạt hình

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

Tùy chọn Tải và Lưu

Mỗi định dạng được hỗ trợ đều có một lớp tùy chọn tương ứng, điều khiển hành vi phân tích và tuần tự hoá.

LớpĐịnh dạngCác thuộc tính chính
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLChế độ xuất Binary vs. ASCII
(glTF sử dụng mặc định)glTF / GLBĐồ thị cảnh và vật liệu được bảo tồn tự động

Ví dụ Sử dụng

Ví dụ 1: Chuyển đổi Định dạng OBJ sang STL

Chuyển đổi một tệp OBJ (có vật liệu) sang STL nhị phân, đồng thời in thống kê lưới trong quá trình thực hiện:

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

Ví dụ 2: Đóng gói Hàng loạt glTF sang GLB

Lưu lại một thư mục các tệp glTF + texture riêng biệt dưới dạng các tệp nhị phân GLB tự chứa:

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

Ví dụ 3: Kiểm tra Đồ thị Cảnh và Báo cáo Xuất

Duyệt đồ thị cảnh của tệp COLLADA, thu thập thống kê cho mỗi lưới, và in báo cáo có cấu trúc:

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

Mẹo và Thực hành Tốt nhất

Lựa chọn Định dạng

  • glTF 2.0 / GLB là định dạng trao đổi được khuyến nghị cho các cảnh bao gồm vật liệu, hoạt ảnh và cấu trúc phức tạp. Ưu tiên GLB (nhị phân) hơn glTF (văn bản + tệp ngoại vi) để tăng tính di động.
  • STL là lựa chọn phù hợp khi người tiêu dùng downstream là một slicer, công cụ CAD, hoặc bất kỳ công cụ nào chỉ cần hình học. STL không chứa dữ liệu vật liệu hay hoạt ảnh.
  • OBJ được hỗ trợ rộng rãi và là lựa chọn tốt khi dữ liệu vật liệu cần được trao đổi với các công cụ cũ. Luôn giữ tệp .mtl bên cạnh tệp .obj.

Hệ tọa độ

  • Các ứng dụng khác nhau sử dụng các quy ước handedness khác nhau. Đặt ObjLoadOptions.flip_coordinate_system = True khi nhập tệp OBJ từ các công cụ sử dụng hệ tọa độ phải nếu pipeline của bạn mong đợi hệ tọa độ trái, và ngược lại.
  • Xác minh quy ước trục của tài sản nguồn trước khi áp dụng bất kỳ việc lật nào. Lật hai lần sẽ tạo ra hình học không chính xác.

Chuẩn hoá

  • Luôn đặt ObjLoadOptions.normalize_normal = True khi pipeline downstream mong đợi các vector pháp tuyến đơn vị (ví dụ, khi truyền pháp tuyến vào shader hoặc thực hiện các phép tính chiếu sáng dot‑product). Các vector pháp tuyến chưa chuẩn hoá từ tệp OBJ được tạo không đúng gây ra các hiện tượng lỗi ánh sáng.

Hiệu suất

  • Tải tệp một lần và biến đổi đồ thị cảnh trong bộ nhớ thay vì tải lại từ đĩa cho mỗi định dạng đầu ra. Một Scene.from_file() lần gọi tiếp theo bởi nhiều scene.save() lần gọi là hiệu quả hơn so với việc tải lại nhiều lần.
  • Khi xử lý các lô lớn, tạo một ObjLoadOptions hoặc StlSaveOptions đối tượng và tái sử dụng nó cho tất cả các tệp thay vì tạo một đối tượng tùy chọn mới cho mỗi tệp.

Xử lý lỗi

  • Bao bọc scene.open()scene.save() các lời gọi trong try/except khối khi xử lý các tệp không đáng tin cậy hoặc do người dùng cung cấp. Báo cáo tên tệp trong thông báo ngoại lệ để đơn giản hoá việc gỡ lỗi trong các pipeline hàng loạt.

Các vấn đề thường gặp

Vấn đềNguyên nhânGiải pháp
Lưới xuất hiện bị lật ngược sau khi tảiSự không khớp về hướng hệ tọa độChuyển đổi ObjLoadOptions.flip_coordinate_system
Các vector pháp tuyến có độ dài bằng 0Tệp nguồn có các vector pháp tuyến chưa chuẩn hoáThiết lập ObjLoadOptions.normalize_normal = True
Vật liệu không được tải từ OBJenable_materialsFalse (mặc định)Thiết lập ObjLoadOptions.enable_materials = True
Cảnh được tải nhưng tất cả các nút đều rỗngTệp sử dụng định dạng FBXBộ phân tích FBX đang được phát triển; hãy sử dụng OBJ, STL hoặc glTF thay thế
Mô hình quá nhỏ hoặc quá lớnTệp nguồn sử dụng các đơn vị không phải métÁp dụng ObjLoadOptions.scale để chuyển đổi sang đơn vị mục tiêu của bạn
AttributeError bật mesh.polygonsThực thể Node không phải là MeshBảo vệ bằng if node.entity is not None trước khi truy cập các thuộc tính của thực thể
Tệp GLB bị trình xem từ chốiĐã lưu với .gltf phần mở rộngSử dụng .glb phần mở rộng khi gọi scene.save() để kích hoạt container nhị phân

Câu hỏi thường gặp

Phiên bản Python nào được hỗ trợ? Python 3.7, 3.8, 3.9, 3.10, 3.11, và 3.12 đều được hỗ trợ. Thư viện là Python thuần túy không có phần mở rộng gốc, vì vậy nó hoạt động trên bất kỳ nền tảng nào mà CPython chạy.

Thư viện có bất kỳ phụ thuộc bên ngoài nào không? Không. Aspose.3D FOSS cho Python chỉ sử dụng thư viện chuẩn Python. Nó được cài đặt như một pip install aspose-3d-foss lệnh mà không cần các bước tiếp theo.

FBX có được hỗ trợ không? Trình phân tích FBX đã được triển khai và có thể phân tích luồng token nhị phân FBX, nhưng bộ xây dựng đồ thị cảnh trên trình phân tích này có các lỗi đã biết và chưa sẵn sàng cho môi trường sản xuất. Hãy sử dụng OBJ, STL, glTF, COLLADA hoặc 3MF cho việc sử dụng sản xuất đáng tin cậy.

Tôi có thể sử dụng Aspose.3D FOSS trong một sản phẩm thương mại không? Có. Thư viện được phát hành dưới giấy phép MIT, cho phép sử dụng trong phần mềm sở hữu độc quyền và thương mại mà không phải trả tiền bản quyền, với điều kiện bao gồm thông báo giấy phép.

Làm thế nào để tôi báo cáo lỗi hoặc yêu cầu một định dạng? Mở một issue trong kho lưu trữ. Bao gồm một tệp tái tạo tối thiểu và phiên bản Python, hệ điều hành, và phiên bản thư viện từ pip show aspose-3d-foss.


Tóm tắt Tham chiếu API

Các lớp cốt lõi

  • Scene: Bộ chứa cấp cao nhất cho một cảnh 3D. Điểm vào cho open(), from_file(), và save().
  • Node: Nút cây trong đồ thị cảnh. Mang entity, transform, global_transform, material, child_nodes, và name.
  • Entity: Lớp cơ sở cho các đối tượng được gắn vào nút (Mesh, Camera, Light).
  • Transform: Vị trí, quay (Quaternion) và tỉ lệ trong không gian cục bộ cho một nút.
  • GlobalTransform: Biến đổi không gian thế giới chỉ đọc được tính toán bằng cách tích lũy tất cả các biến đổi của các nút cha.

Hình học

  • Mesh: Lưới đa giác với control_points (danh sách đỉnh) và polygons.
  • VertexElementNormal: Vectơ pháp tuyến mỗi đỉnh hoặc mỗi đa giác.
  • VertexElementUV: Tọa độ UV texture mỗi đỉnh.
  • VertexElementVertexColor: Dữ liệu màu mỗi đỉnh.
  • VertexElementSmoothingGroup: Các gán nhóm làm mịn đa giác.

Vật liệu

  • LambertMaterial: Mô hình shading khuếch tán với diffuse_coloremissive_color.
  • PhongMaterial: Thêm mô hình shading phản chiếu specular_colorshininess.

Tiện ích Toán học (aspose.threed.utilities)

  • Vector2: vector 2D.
  • Vector3: Vector 3D độ chính xác kép.
  • Vector4: Vector 4D độ chính xác kép.
  • FVector3: Vector 3D độ chính xác đơn.
  • Quaternion: Quaternion quay với from_angle_axis()to_matrix().
  • Matrix4: Ma trận biến đổi 4×4.
  • BoundingBox: Hộp bao trùm căn trục với minimummaximum : các góc.

Hoạt ảnh

  • AnimationClip: Bộ chứa có tên cho một tập hợp các kênh hoạt hình và các khung khóa của chúng.
  • AnimationNode: Dữ liệu hoạt hình theo nút trong một clip.
  • KeyFrame: Khung khóa đơn với thời gian và giá trị.
  • KeyframeSequence: Chuỗi có thứ tự các khung khóa cho một thuộc tính hoạt hình đơn.

Tùy chọn Tải / Lưu

  • ObjLoadOptions: Cài đặt tải đặc thù cho OBJ: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: Cài đặt lưu đặc thù cho STL (chế độ nhị phân so với ASCII).

Camera và Đèn

  • Camera: Thực thể camera với cài đặt chiếu, có thể gắn vào một Node.
  • Light: Thực thể nguồn sáng, có thể gắn vào một Node.
 Tiếng Việt