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-fossKhô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ạng | Phần mở rộng | Đọc | Ghi | Ghi chú |
|---|---|---|---|---|
| Wavefront OBJ | .obj | Có | Có | .mtl material loading supported |
| STL (nhị phân) | .stl | Có | Có | Đã xác nhận vòng quay (39 bài kiểm tra) |
| STL (ASCII) | .stl | Có | Có | Đã xác nhận vòng quay |
| glTF 2.0 | .gltf | Có | Có | Đồ thị cảnh đầy đủ được bảo tồn |
| GLB (binary glTF) | .glb | Có | Có | Bộ chứa nhị phân đơn tệp |
| COLLADA | .dae | Có | Có | Cây phân cấp cảnh và vật liệu |
| 3MF | .3mf | Có | Có | Định dạng sản xuất gia tăng |
| FBX | .fbx | Một phần | Không | Trì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ớp | Mục đích |
|---|---|
Vector2 | 2D floating-point vector (UV coordinates) |
Vector3 | 3D double-precision vector (positions, normals) |
Vector4 | 4D double-precision vector (homogeneous coordinates) |
FVector3 | 3D single-precision vector (compact storage) |
Quaternion | Biểu diễn quay mà không bị gimbal lock |
Matrix4 | 4×4 transformation matrix |
BoundingBox | Hộ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ạng | Các thuộc tính chính |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Chế độ 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 = Truekhi 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 = Truekhi 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ềuscene.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
ObjLoadOptionshoặcStlSaveOptionsđố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()vàscene.save()các lời gọi trongtry/exceptkhố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ân | Giải pháp |
|---|---|---|
| Lưới xuất hiện bị lật ngược sau khi tải | Sự 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 0 | Tệ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ừ OBJ | enable_materials là False (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ỗng | Tệp sử dụng định dạng FBX | Bộ 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ớn | Tệ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.polygons | Thực thể Node không phải là Mesh | Bả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ộng | Sử 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 choopen(),from_file(), vàsave().Node: Nút cây trong đồ thị cảnh. Mangentity,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ớicontrol_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ớidiffuse_colorvàemissive_color.PhongMaterial: Thêm mô hình shading phản chiếuspecular_colorvàshininess.
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ớifrom_angle_axis()vàto_matrix().Matrix4: Ma trận biến đổi 4×4.BoundingBox: Hộp bao trùm căn trục vớiminimumvàmaximum: 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ộtNode.Light: Thực thể nguồn sáng, có thể gắn vào mộtNode.