Характеристики и функционалности

Характеристики и функционалности

Aspose.3D FOSS за Python предоставя пълен API за граф на сцена за четене, създаване и записване на 3D съдържание в множество индустриално‑стандартни формати. Тази страница документира всяка основна област на функционалност с работещи Python примерни кодове, които използват реалния API на библиотеката.

Инсталиране и настройка

Инсталирайте библиотеката от PyPI с една единствена команда:

pip install aspose-3d-foss

Не са необходими допълнителни системни пакети, native разширения или компилаторски инструменти. Библиотеката е чиста Python и поддържа Python 3.7 до 3.12 на Windows, macOS и Linux.

За да проверите инсталацията:

from aspose.threed import Scene

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

Характеристики и функционалности

Поддръжка на формати

Aspose.3D FOSS за Python чете и записва следните формати:

ФорматРазширениеЧетенеЗаписБележки
Wavefront OBJ.objДаДа.mtl зареждането на материали се поддържа
STL (бинарен).stlДаДаПотвърдено (39 теста)
STL (ASCII).stlДаДаПотвърдено
glTF 2.0.gltfДаДаПълен граф на сцената е запазен
GLB (binary glTF).glbДаДаЕднофайлов бинарен контейнер
COLLADA.daeДаДаЙерархия на сцената и материали
3MF.3mfДаДаФормат за адитивно производство
FBX.fbxЧастичноНеТокенизаторът работи; парсерът има известни грешки

Зареждане на OBJ с опции

ObjLoadOptions контролира как се парсират OBJ файловете:

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

Записване в STL

StlSaveOptions контролира бинарния срещу ASCII изход и други специфични за STL настройки:

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

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

Граф на сцената

Цялото 3D съдържание е организирано като дърво от Node обекти. Коренът на дървото е scene.root_node. Every node can contain child nodes and carry an Entity (mesh, camera, or light) plus a Transform.

Претърсване на йерархията на сцената

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)

Програмирано създаване на сцена

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

Преглед на GlobalTransform

GlobalTransform gives the world-space transform of a node after accumulating all ancestor transforms:

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

Този Mesh обектът предоставя достъп до геометрични данни, включително контролни точки (върхове), полигони и елементи на върховете за нормали, UV координати и цветове.

Четене на геометрията на 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)}")

Достъп до елементите на върховете

Елементите на върховете съдържат данни за всеки връх или полигон. Най-често срещаните елементи са нормали, UV координати, цветове на върховете и групи за изглаждане:

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

Система за материали

Aspose.3D FOSS поддържа два типа материали: LambertMaterial (дифузно осветление) и PhongMaterial (спекуларно осветление). И двете се зареждат автоматично от .mtl файлове при използване на ObjLoadOptions с enable_materials = True.

Четене на материали от 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}")

Присвояване на материал програмно

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

Помощни функции за математика

Този aspose.threed.utilities модулът предоставя всички геометрични математически типове, необходими за изграждане и инспекция на сцената.

КласЦел
Vector22D floating-point vector (UV coordinates)
Vector33D double-precision vector (positions, normals)
Vector44D double-precision vector (homogeneous coordinates)
FVector33D single-precision vector (compact storage)
QuaternionПредставяне на въртене без gimbal lock
Matrix44×4 transformation matrix
BoundingBoxОразмерена спрямо осите ограничителна кутия с минимални/максимални ъгли

Работа с трансформации

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

Изчисляване на ограничителна кутия

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

Анимация

Aspose.3D FOSS предоставя анимационен модел, базиран на AnimationClip, AnimationNode, KeyFrame, и KeyframeSequence. Анимационните данни, съхранени в заредените файлове (glTF, COLLADA), са достъпни чрез тези обекти.

Четене на анимационни клипове

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

Опции за зареждане и запазване

Всеки поддържан формат има съответен клас с опции, който контролира поведението при парсиране и сериализация.

КласФорматКлючови свойства
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLБинарен vs. ASCII режим на изход
(glTF използва стойности по подразбиране)glTF / GLBГрафът на сцената и материалите се запазват автоматично

Примери за употреба

Пример 1: Конвертиране от OBJ към STL формат

Конвертирайте OBJ файл (с материали) в бинарен STL, като отпечатвате статистика за мрежата по пътя:

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

Пример 2: Пакетно опаковане от glTF към GLB

Презапишете директория с отделни glTF + текстурни файлове като самостоятелни GLB бинарни файлове:

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

Пример 3: Инспекция на графа на сцената и отчет за експорта

Прегледайте графа на сцената в COLLADA файл, съберете статистика за всяка мрежа и отпечатайте структуриран отчет:

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

Съвети и най‑добри практики

Избор на формат

  • glTF 2.0 / GLB е препоръчителният формат за обмен за сцени, които включват материали, анимации и сложни йерархии. Предпочитайте GLB (бинарен) пред glTF (текст + външни файлове) за преносимост.
  • STL е правилният избор, когато потребителят надолу по веригата е резачка, CAD инструмент или който и да е инструмент, който се нуждае само от геометрия. STL не съдържа данни за материал или анимация.
  • OBJ е широко поддържан и добър избор, когато данните за материал трябва да се обменят със стари инструменти. Винаги пазете .mtl файла заедно с .obj файла.

Координатни системи

  • Различните приложения използват различни конвенции за ръка. Задайте ObjLoadOptions.flip_coordinate_system = True при импортиране на OBJ файлове от инструменти, които използват дясна координатна система, ако вашият процес очаква лява координатна система, и обратно.
  • Проверете конвенцията за осите на изходния ресурс, преди да приложите обръщане. Двойното обръщане води до неправилна геометрия.

Нормализация

  • Винаги задавайте ObjLoadOptions.normalize_normal = True когато надолу по веригата процесът очаква единични нормали (например, при предаване на нормали към шейдър или извършване на изчисления на осветление чрез скаларно произведение). Ненормализираните нормали от лошо оформени OBJ файлове причиняват артефакти в осветлението.

Производителност

  • Зареждайте файловете еднократно и трансформирайте графа на сцената в паметта, вместо да ги презареждате от диска за всеки изходен формат. Едно Scene.from_file() извикване, последвано от множество scene.save() извикванията са по-ефективни от многократните зареждания.
  • Когато обработвате големи партиди, създайте един единствен ObjLoadOptions или StlSaveOptions екземпляр и го използвайте отново за всички файлове, вместо да създавате нов обект с опции за всеки файл.

Обработка на грешки

  • Обвийте scene.open() и scene.save() извиквания в try/except блокове, когато обработвате недоверени или предоставени от потребителя файлове. Съобщавайте името на файла в съобщенията за изключения, за да опростите отстраняването на грешки в партидните конвейери.

Чести проблеми

ПроблемПричинаРешение
Мрежата се появява огледално след зарежданеНесъответствие в ориентацията на координатната системаПревключване ObjLoadOptions.flip_coordinate_system
Нормалите имат нулева дължинаИзходният файл съдържа ненормализирани нормалиЗадай ObjLoadOptions.normalize_normal = True
Материалите не са заредени от OBJenable_materials е False (по подразбиране)Задай ObjLoadOptions.enable_materials = True
Сцената се зарежда, но всички възли са празниФайлът използва FBX форматПарсерът за FBX е в процес на разработка; използвайте OBJ, STL или glTF вместо това
Моделът е изключително малък или голямИзходният файл използва не-метрични единициПриложи ObjLoadOptions.scale за конвертиране към вашата целева единица
AttributeError на mesh.polygonsNode entity не е MeshЗащити с if node.entity is not None преди достъп до свойствата на entity
GLB файлът е отхвърлен от визуализатораЗаписано с .gltf разширениеИзползвайте .glb разширение при извикване scene.save() за задействане на бинарен контейнер

Често задавани въпроси

Кои версии на Python се поддържат? Python 3.7, 3.8, 3.9, 3.10, 3.11 и 3.12 са всички поддържани. Библиотеката е чиста Python без нативно разширение, така че работи на всяка платформа, където се изпълнява CPython.

Има ли библиотеката външни зависимости? Не. Aspose.3D FOSS за Python използва само стандартната библиотека Python. Той се инсталира като единствена pip install aspose-3d-foss команда без последващи стъпки.

Поддържа ли се FBX? FBX токенизаторът е реализиран и може да парсира бинарния FBX токен поток, но създателят на графа на сцената върху токенизатора има известни грешки и не е готов за продукция. Използвайте OBJ, STL, glTF, COLLADA или 3MF за надеждна продукционна употреба.

Мога ли да използвам Aspose.3D FOSS в комерсиален продукт? Да. Библиотеката е публикувана под лиценз MIT, който позволява използването ѝ в собственически и комерсиален софтуер без плащане на royalties, при условие че се включи известието за лиценз.

Как да докладвам грешка или да поискам формат? Отворете проблем в хранилището. Включете минимален файл за възпроизвеждане и версията на Python, операционната система и версията на библиотеката от pip show aspose-3d-foss.


Резюме на API справката

Основни класове

  • Scene: Контейнер от най-високо ниво за 3D сцена. Точка за влизане за open(), from_file(), и save().
  • Node: Дървовиден възел в графа на сцената. Пренася entity, transform, global_transform, material, child_nodes, и name.
  • Entity: Базов клас за обекти, прикрепени към възли (Mesh, Camera, Light).
  • Transform: Локална позиция, ротация (Quaternion) и мащаб за възел.
  • GlobalTransform: Трансформация в световно пространство, само за четене, изчислена чрез натрупване на трансформациите на всички предшественици.

Geometry

  • Mesh: Полигонална мрежа с control_points : (списък на върховете) и polygons.
  • VertexElementNormal: Нормални вектори за всеки връх или за всеки полигон.
  • VertexElementUV: UV текстурни координати за всеки връх.
  • VertexElementVertexColor: Данни за цвят за всеки връх.
  • VertexElementSmoothingGroup: Присвоявания на групи за изглаждане на полигоните.

Материали

  • LambertMaterial: Модел на дифузно осветление с diffuse_color : и emissive_color.
  • PhongMaterial: Добавяне на спекулен модел за осветление specular_color и shininess.

Математически помощни функции (aspose.threed.utilities)

  • Vector2: 2‑измерен вектор.
  • Vector3: 3‑измерен вектор с двойна точност.
  • Vector4: 4‑измерен вектор с двойна точност.
  • FVector3: 3‑измерен вектор с единична точност.
  • Quaternion: Кватернион за въртене с from_angle_axis() и to_matrix().
  • Matrix4: 4×4 матрица за трансформация.
  • BoundingBox: Ограничителна кутия, подравнена по осите, с minimum и maximum ъгли.

Анимация

  • AnimationClip: Именен контейнер за набор от анимационни канали и техните ключови кадри.
  • AnimationNode: Данни за анимация по възел в клип.
  • KeyFrame: Единствен ключов кадър с време и стойност.
  • KeyframeSequence: Подредена последователност от ключови кадри за едно анимирано свойство.

Опции за зареждане / запазване

  • ObjLoadOptions: Настройки за зареждане, специфични за OBJ: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: Настройки за запазване, специфични за STL (бинарен vs. ASCII режим).

Камери и светлини

  • Camera: Камера ентитет с настройки за проекция, прикрепяема към a Node.
  • Light: Светлинен източник ентитет, прикрепяема към a Node.
 Български