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 imagem | Extensão | Leia. | 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 | .fbx | Parcialmente | — | Tokenizer 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: |
|---|---|
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 | Representação de rotação sem bloqueio do gimbal |
Matrix4 | 4×4 transformation matrix |
BoundingBox | Caixa 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 imagem | Principais propriedades |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Modo de saída binário vs. ASCII |
| (glTF utiliza padrões) | GLB/GTF | Grafico 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 = Truequando 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 = Truequando 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últiploscene.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.
ObjLoadOptionsou a)StlSaveOptionsinstâ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 entradatry/exceptBloques 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ão | Causa da morte | Resolução |
|---|---|---|
| A malha aparece espelhada após o carregamento. | Desajuste de manobra do sistema de coordenadas | Intercâ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 OBJ | enable_materials foi definido para: False | Set (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 FBX | FBX 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étricas | Aplicar o pedido de autorização ObjLoadOptions.scale Para converter para a sua unidade alvo. |
AttributeError em 1 de Setembro de mesh.polygons | Entidade de nó não é uma malha | Guarda com if node.entity is not None antes de aceder às propriedades da entidade |
| Arquivo GLB é rejeitado pelo espectador | Salvou com .gltf extensão | Utilizaçã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(), esave().Node: Nodo de árvore no gráfico da cena. Carregueentity,transform,global_transform,material,child_nodes, ename.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) epolygons.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_colore a)emissive_color.PhongMaterial: Adição de modelo especular de sombreamentospecular_colore 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:minimume 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 umNode.Light: Unidade de fonte luminosa, ligável a umNode.