Características e funcionalidades

Características e funcionalidades

Aspose.3D FOSS para Python fornece um Scene Objeto para carregamento, construção e armazenamento de conteúdo 3D em vários formatos de arquivo. Esta página documenta todas as principais áreas com exemplos de código Python que usam a API da biblioteca real.

Instalação e configuração

Instalar a biblioteca do PyPI usando um único comando de instalação pip:

asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.

Não são necessários pacotes de sistema adicionais, extensões nativas ou cadeias de ferramentas do compilador.

Execute o seguinte código para confirmar que a biblioteca foi carregada corretamente:

from aspose.threed import Scene

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

Características e funcionalidades

Suporte de formato

Aspose.3D FOSS para Python lê e escreve os seguintes formatos:

Formatos de imagemExtensãoLeia.Escrever .Notas
OBJ.obj- Sim , sim .- Sim , sim .Objetos de carga do material suportados.
STL.stl- Sim , sim .- Sim , sim .Variantes binárias e ASCII; viagem de ida e volta verificada
GTF.gltf / .glb- Sim , sim .- Sim , sim .Container binário JSON e GLB glTF 2.0
COLLADA.dae- Sim , sim .- Sim , sim .Hierarquia de cenas e materiais
3MF.3mf- Sim , sim .- Sim , sim .Formatos de fabrico aditivo
FBX.fbxParcialmenteTokenizer funcionando; o parser tem erros conhecidos

Carregamento do OBJ com opções

Passagem . ObjLoadOptions a) para o scene.open() para controlar a carga do material, a orientação das coordenadas e a escala dos vértices no tempo de análise:

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

Salvamento para STL

StlSaveOptions Controla a saída binária versus ASCII e outras configurações específicas do 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)

Gráfico de cena

Todo o conteúdo 3D é organizado como uma árvore de Node A raiz da árvore é a base do seu corpo. scene.root_node.Cada nó pode conter nós filhos e levar um Entity (mesca, câmara ou luz) mais um Transform.

Atravessar a hierarquia de cenas

Chama-me . traverse() de forma recursiva em: scene.root_node para imprimir o nome de cada nó e o tipo da entidade ligada:

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)

Construir uma cena programaticamente

Criar nós filhos com: root.create_child_node() e definido transform.translation e a) transform.scaling para os posicionar na hierarquia:

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

Inspecção da GlobalTransform

GlobalTransform dá a transformação de espaço-mundo de um nó após acumular todas as transformações ancestrais:

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 de malha

A Comissão Mesh A entidade dá acesso a dados de geometria, incluindo pontos de controlo (vertices), polígonos e elementos de vértice para normais, UVs e cores.

Geometria de malha de leitura

Acessos node.entity para recuperar a malha, então ler control_points para dados de vértice e polygons para a topologia das faces:

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

Acesso a elementos de Vértice

Os elementos de vértice carregam dados por vértex ou por polígono. Os mais comuns são os normais, as coordenadas UV, cores dos vértebras e grupos de alisamento:

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

Sistema de materiais

Aspose.3D FOSS suporta dois tipos de material: LambertMaterial (sombras difusas) e PhongMaterial Ambos são carregados automaticamente a partir de arquivos .mtl quando se utiliza o sistema. ObjLoadOptions com: enable_materials = True.

Leitura de materiais do OBJ

Após a carga com: enable_materials = True, inspecionar o material de cada nó e verificar seu tipo para aceder às propriedades difusas e especulares:

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

Asignação de Material por Programação

Construir um PhongMaterial, definir as suas propriedades de cor, em seguida, atribuí-lo a node.material no nó de malha alvo:

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

Utilidades de Matemática

A Comissão aspose.threed.utilities O módulo fornece vector, matriz, quaternio e tipos de caixa-limite usados na construção da cena.

Classe:Objectivo:
Vector22D floating-point vector (UV coordinates)
Vector33D double-precision vector (positions, normals)
Vector44D double-precision vector (homogeneous coordinates)
FVector33D single-precision vector (compact storage)
QuaternionRepresentação de rotação sem bloqueio do gimbal
Matrix44×4 transformation matrix
BoundingBoxCaixa de contorno alinhada ao eixo com cantos mínimos/máximos

Trabalhar com transforms

Utilização: Quaternion.from_angle_axis() para construir uma rotação a partir de um ângulo e vector do eixo, em seguida, chamar to_matrix() para a converter numa matriz de rotação 4×4:

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

Computação de uma caixa de limites

Iteração mesh.control_points e acompanhar os valores mínimos/máximos por eixo para calcular manualmente a caixa de contorno alinhada ao eijo:

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

Animação

Aspose.3D FOSS fornece um modelo de animação baseado em: AnimationClip, AnimationNode, KeyFrame, e KeyframeSequence.Os dados de animação armazenados em ficheiros carregados (glTF, COLLADA) são acessíveis através destes objetos.

Leitura de vídeos animados

Iteração scene.animation_clips para aceder ao intervalo de tempo de cada clipe e aos nós de animação que ele controla:

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

Opções de carregamento e salvação

Cada formato suportado tem uma classe de opções correspondente que controla o comportamento de análise e serialização.

Classe:Formatos de imagemPrincipais propriedades
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLModo de saída binário vs. ASCII
(glTF utiliza padrões)GLB/GTFGrafico de cena e materiais conservados automaticamente

Exemplos de uso

Exemplo 1: conversão de formato OBJ para STL

Converter um arquivo OBJ (com materiais) para STL binário, imprimindo estatísticas de malha ao longo do caminho:

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

Exemplo 2: Embalagem de lotes glTF para GLB

Re-salvar um diretório de arquivos separados glTF + texture como binários GLB autônomos:

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

Exemplo 3: Inspecção de gráficos e relatório sobre exportação

Caminhe no gráfico de cena do arquivo COLLADA, recolha estatísticas por malha e imprima um relatório estruturado:

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

Dicas e melhores práticas

Seleção de formato

  • GTF 2.0 / GLB é o formato de intercâmbio recomendado para cenas que incluem materiais, animações e hierarquias complexas. Preferir GLB (binário) sobre glTF (texto + arquivos externos) para portabilidade.
  • STL O STL não transporta dados de material ou animação.
  • OBJ É amplamente suportado e uma boa escolha quando os dados materiais devem ser trocados com ferramentas mais antigas. Mantenha sempre o arquivo .mtl ao lado do arquivos .obj.

Sistemas de Coordenação

  • Aplicações diferentes usam convenções de manidade diferentes. ObjLoadOptions.flip_coordinate_system = True quando importa ficheiros OBJ de ferramentas que utilizam um sistema de coordenadas para a direita, se o seu pipeline espera coordenações para esquerda e vice-versa.
  • Verificar a convenção do eixo da fonte antes de aplicar qualquer flip. Flipping duas vezes produz geometria incorreta.

Normalização

  • Sempre definido. ObjLoadOptions.normalize_normal = True quando o pipeline a jusante espera valores normais unitários (por exemplo, ao passar valores para um shader ou fazer cálculos de iluminação por ponto). Normal não normalizado de ficheiros OBJ mal formados causa artefatos de luz.

Desempenho

  • Carregue os arquivos uma vez e transforme o gráfico de cena na memória em vez de recarregar do disco para cada formato de saída. Scene.from_file() chamada seguida de múltiplo scene.save() O sistema de chamadas é mais eficiente do que as cargas repetidas.
  • Quando se processam grandes lotes, deve ser construído um único sistema de produção. ObjLoadOptions ou a) StlSaveOptions instância e reutilizar em todos os arquivos, ao invés de construir um novo objeto opções por arquivo.

Tratamento de erros

  • Embalagem scene.open() e a) scene.save() chamadas de entrada try/except Bloques quando processar arquivos não confiáveis ou fornecidos pelo usuário. Relate o nome do arquivo em mensagens de exceção para simplificar a depuração nos pipelines por lotes.

Problemas comuns

EmissãoCausa da morteResolução
A malha aparece espelhada após o carregamento.Desajuste de manobra do sistema de coordenadasIntercâmbio ObjLoadOptions.flip_coordinate_system
Normal é zero-longitude.O arquivo de origem tem valores normais não normalizados .Set (s) ObjLoadOptions.normalize_normal = True
Materiais não carregados a partir de OBJenable_materials foi definido para: FalseSet (s) ObjLoadOptions.enable_materials = True (este já é o padrão)
A cena está carregada mas todos os nós estão vazios .Arquivo utiliza formato FBXFBX parser está em andamento; use OBJ, STL ou glTF em vez disso
Modelo extremamente pequeno ou grande.Arquivo de origem usa unidades não métricasAplicar o pedido de autorização ObjLoadOptions.scale Para converter para a sua unidade alvo.
AttributeError em 1 de Setembro de mesh.polygonsEntidade de nó não é uma malhaGuarda com if node.entity is not None antes de aceder às propriedades da entidade
Arquivo GLB é rejeitado pelo espectadorSalvou com .gltf extensãoUtilização: .glb extensão ao ligar scene.save() para acionar o contêiner binário.

Perguntas Frequentes

Quais versões do Python são suportadas? Python 3.7, 3.8, 3.9, 3.10, 3.11, e 3.12 são todos suportados. A biblioteca é pura Python sem extensão nativa, então funciona em qualquer plataforma onde CPython seja executado.

A biblioteca tem dependências externas? Não. Aspose.3D FOSS para Python só usa a biblioteca padrão do Python. Instala como um único pip install aspose-3d-foss comando sem seguimento.

O FBX é suportado? O tokenizer FBX pode analisar a estrutura do arquivo, mas o construtor de gráficos de cena tem erros conhecidos; trate os resultados da leitura do FBx como experimentais e verifique-os antes do uso. Para resultados confiáveis, glTF, OBJ, STL, COLLADA e 3MF são escolhas estáveis e bem testadas.

Posso utilizar o Aspose.3D FOSS num produto comercial? Sim, a biblioteca é lançada sob licença MIT que permite o uso em software proprietário e comercial sem pagamento de royalties.

Como posso relatar um erro ou solicitar um formato? Inclua um arquivo de reprodução mínima e a versão Python, sistema operacional e biblioteca da pip show aspose-3d-foss.


Resumo de referência da API

Classes de núcleo

  • Scene: Container de nível superior para uma cena 3D. Ponto de entrada para a visualização da imagem em formato digital, com o objetivo de permitir que os espectadores possam ver as cenas em um ambiente mais amplo e visual. open(), from_file(), e save().
  • Node: Nodo de árvore no gráfico da cena. Carregue entity, transform, global_transform, material, child_nodes, e name.
  • Entity: Classe base para objetos ligados a nós (Mesh, Camera, Light).
  • Transform: Posição no espaço local, rotação (Quaternion) e escala para um nó.
  • GlobalTransform: Transformação de espaço-mundo somente para leitura, calculada por acúmulo de todas as transformações ancestrais.

Geometria

  • Mesh: Melas poligonais com: control_points (lista de vértices) e polygons.
  • VertexElementNormal: Vectores normais por vértice ou por polígono.
  • VertexElementUV: Coordenadas de textura UV per-vertex.
  • VertexElementVertexColor:Dados de cor per-vertex.
  • VertexElementSmoothingGroup: atribuições de grupo para a suavização do polígono.

Materiais

  • LambertMaterial:Modelo de sombreamento difuso com: diffuse_color e a) emissive_color.
  • PhongMaterial: Adição de modelo especular de sombreamento specular_color e a) shininess.

Utilidades de Matemática (aspose.threed.utilities)

  • Vector2:Vector 2D.
  • Vector3:Vector de dupla precisão em 3D.
  • Vector4:Vector de dupla precisão 4D.
  • FVector3:Vector de precisão única em 3D.
  • Quaternion: Quaternio de rotação com: from_angle_axis() e a) to_matrix().
  • Matrix4:Matriz de transformação 4x4.
  • BoundingBox: Caixa de contorno alinhada ao eixo com: minimum e a) maximum - As esquinas.

Animação

  • AnimationClip: Container nomeado para um conjunto de canais de animação e seus keyframes.
  • AnimationNode: Dados de animação por nó dentro de um clipe.
  • KeyFrame: Um único quadro de chave com tempo e valor.
  • KeyframeSequence: Sequência ordenada de quadros-chave para uma única propriedade animada.

Opções de Carregar / Salvar

  • ObjLoadOptions: Ajustes de carga específicos do OBJ: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: Configurações de salva específicas para STL (modo binário vs. ASCII).

Câmeras e luzes

  • Camera: Unidade de câmara com configurações de projecção, acoplável a um Node.
  • Light: Unidade de fonte luminosa, ligável a um Node.

Ver também:

 Português