Fonctionnalités et capacités
Aspose.3D FOSS pour Python fournit une API complète de graphe de scène pour lire, construire et écrire du contenu 3D dans plusieurs formats standards de l’industrie. Cette page documente chaque domaine fonctionnel majeur avec des exemples de code Python fonctionnels qui utilisent l’API réelle de la bibliothèque.
Installation et configuration
Installez la bibliothèque depuis PyPI avec une seule commande :
pip install aspose-3d-fossAucun paquet système supplémentaire, aucune extension native, ni aucune chaîne d’outils de compilation ne sont requis. La bibliothèque est pure Python et prend en charge Python 3.7 à 3.12 sur Windows, macOS et Linux.
Pour vérifier l’installation :
from aspose.threed import Scene
scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")Fonctionnalités et capacités
Prise en charge des formats
Aspose.3D FOSS pour Python lit et écrit les formats suivants :
| Format | Extension | Lire | Écrire | Remarques |
|---|---|---|---|---|
| Wavefront OBJ | .obj | Oui | Oui | .Chargement du matériau .mtl pris en charge |
| STL (binaire) | .stl | Oui | Oui | Vérification du roundtrip (39 tests) |
| STL (ASCII) | .stl | Oui | Oui | Vérification du roundtrip |
| glTF 2.0 | .gltf | Oui | Oui | Graph complet de la scène conservé |
| GLB (binary glTF) | .glb | Oui | Oui | Conteneur binaire à fichier unique |
| COLLADA | .dae | Oui | Oui | Hiérarchie de scène et matériaux |
| 3MF | .3mf | Oui | Oui | Format de fabrication additive |
| FBX | .fbx | Partiel | Non | Le tokenizer fonctionne ; le parser a des bugs connus |
Chargement d’OBJ avec options
ObjLoadOptions contrôle la façon dont les fichiers OBJ sont analysés :
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")Enregistrement au format STL
StlSaveOptions contrôle la sortie binaire vs. ASCII et d’autres paramètres spécifiques à 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)Graphe de scène
Tout le contenu 3D est organisé sous forme d’arbre de Node objets. La racine de l’arbre est scene.root_node. Chaque nœud peut contenir des nœuds enfants et porter un Entity (maillage, caméra ou lumière) plus un Transform.
Parcourir la hiérarchie de la scène
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)Construire une scène par programmation
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")Inspecter GlobalTransform
GlobalTransform donne la transformation en espace mondial d’un nœud après avoir accumulé toutes les transformations des ancêtres :
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 Mesh
Le Mesh l’entité donne accès aux données géométriques, y compris les points de contrôle (sommets), les polygones et les éléments de sommet pour les normales, les UV et les couleurs.
Lecture de la géométrie 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)}")Accès aux éléments de sommet
Les éléments de sommet contiennent des données par sommet ou par polygone. Les éléments les plus courants sont les normales, les coordonnées UV, les couleurs de sommet et les groupes de lissage :
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)}")Système de matériaux
Aspose.3D FOSS prend en charge deux types de matériaux : LambertMaterial (ombrage diffus) et PhongMaterial (ombrage spéculaire). Les deux sont chargés automatiquement à partir des fichiers .mtl lors de l’utilisation ObjLoadOptions avec enable_materials = True.
Lecture des matériaux depuis 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}")Assignation d’un matériau par programmation
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")Utilitaires mathématiques
Le aspose.threed.utilities module fournit tous les types mathématiques géométriques nécessaires à la construction et à l’inspection de scènes.
| Classe | Objectif |
|---|---|
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 | Représentation de la rotation sans blocage de cardan |
Matrix4 | 4×4 transformation matrix |
BoundingBox | Boîte englobante alignée sur les axes avec coins min/max |
Travailler avec les transformations
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}")Calcul d’une boîte englobante
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})")Animation
Aspose.3D FOSS fournit un modèle d’animation basé sur AnimationClip, AnimationNode, KeyFrame, et KeyframeSequence. Les données d’animation stockées dans les fichiers chargés (glTF, COLLADA) sont accessibles via ces objets.
Lecture des clips d’animation
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}")Options de chargement et d’enregistrement
Chaque format pris en charge possède une classe d’options correspondante qui contrôle le comportement d’analyse et de sérialisation.
| Classe | Format | Propriétés clés |
|---|---|---|
ObjLoadOptions | OBJ | enable_materials, flip_coordinate_system, normalize_normal, scale |
StlSaveOptions | STL | Mode de sortie binaire vs. ASCII |
| (glTF utilise les valeurs par défaut) | glTF / GLB | Graph de scène et matériaux préservés automatiquement |
Exemples d’utilisation
Exemple 1 : Conversion du format OBJ vers STL
Convertir un fichier OBJ (avec matériaux) en STL binaire, en affichant les statistiques du maillage au fur et à mesure :
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")Exemple 2 : Empaquetage par lots de glTF vers GLB
Réenregistrer un répertoire contenant des fichiers glTF + textures séparés en binaires GLB autonomes :
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)}")Exemple 3 : Inspection du graphe de scène et rapport d’exportation
Parcourir le graphe de scène d’un fichier COLLADA, collecter les statistiques par maillage et imprimer un rapport structuré :
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}"
)Conseils et bonnes pratiques
Sélection du format
- glTF 2.0 / GLB est le format d’échange recommandé pour les scènes incluant des matériaux, des animations et des hiérarchies complexes. Privilégiez GLB (binaire) plutôt que glTF (texte + fichiers externes) pour la portabilité.
- STL est le bon choix lorsque le consommateur en aval est un trancheur, un outil CAO ou tout autre outil qui ne nécessite que la géométrie. STL ne contient aucune donnée de matériau ou d’animation.
- OBJ est largement supporté et constitue un bon choix lorsque les données de matériau doivent être échangées avec des outils plus anciens. Conservez toujours le fichier .mtl à côté du fichier .obj.
Systèmes de coordonnées
- Différentes applications utilisent des conventions d’orientation différentes. Set
ObjLoadOptions.flip_coordinate_system = Truelors de l’importation de fichiers OBJ provenant d’outils qui utilisent un système de coordonnées right‑handed si votre pipeline attend des coordonnées left‑handed, et vice‑versa. - Vérifiez la convention d’axes de l’actif source avant d’appliquer tout retournement. Un retournement double produit une géométrie incorrecte.
Normalisation
- Toujours définir
ObjLoadOptions.normalize_normal = Truelorsque le pipeline en aval attend des normales unitaires (par exemple, lors du passage des normales à un shader ou du calcul d’éclairage par produit scalaire). Les normales non normalisées provenant de fichiers OBJ mal formés provoquent des artefacts d’éclairage.
Performance
- Chargez les fichiers une fois et transformez le graphe de scène en mémoire plutôt que de recharger depuis le disque pour chaque format de sortie. Un seul
Scene.from_file()appel suivi de plusieursscene.save()appels est plus efficace que des chargements répétés. - Lors du traitement de gros lots, construisez un seul
ObjLoadOptionsouStlSaveOptionsinstance et réutilisez‑la pour tous les fichiers au lieu de créer un nouvel objet d’options par fichier.
Gestion des erreurs
- Enveloppez
scene.open()etscene.save()appels danstry/exceptblocs lors du traitement de fichiers non fiables ou fournis par l’utilisateur. Signalez le nom de fichier dans les messages d’exception pour simplifier le débogage dans les pipelines batch.
Problèmes courants
| Problème | Cause | Solution |
|---|---|---|
| Le maillage apparaît en miroir après le chargement | Incohérence de la main du système de coordonnées | Basculer ObjLoadOptions.flip_coordinate_system |
| Les normales ont une longueur nulle | Le fichier source contient des normales non normalisées | Définir ObjLoadOptions.normalize_normal = True |
| Matériaux non chargés depuis OBJ | enable_materials est False (par défaut) | Définir ObjLoadOptions.enable_materials = True |
| La scène se charge mais tous les nœuds sont vides | Le fichier utilise le format FBX | Le parseur FBX est en cours de développement ; utilisez OBJ, STL ou glTF à la place |
| Le modèle est très petit ou très grand | Le fichier source utilise des unités non métriques | Appliquer ObjLoadOptions.scale pour convertir en votre unité cible |
AttributeError sur mesh.polygons | L’entité Node n’est pas un Mesh | Protéger avec if node.entity is not None avant d’accéder aux propriétés de l’entité |
| Le fichier GLB est rejeté par le visualiseur | Enregistré avec .gltf extension | Utilisez .glb l’extension lors de l’appel scene.save() pour déclencher le conteneur binaire |
Foire aux questions
Quelles versions de Python sont prises en charge ? Les versions Python 3.7, 3.8, 3.9, 3.10, 3.11 et 3.12 sont toutes prises en charge. La bibliothèque est pure Python sans extension native, elle fonctionne donc sur toute plateforme où CPython s’exécute.
La bibliothèque a-t-elle des dépendances externes ? Non. Aspose.3D FOSS pour Python n’utilise que la bibliothèque standard Python. Il s’installe en une seule pip install aspose-3d-foss commande sans étapes supplémentaires.
FBX est-il pris en charge ? Le tokenizer FBX est implémenté et peut analyser le flux binaire de tokens FBX, mais le constructeur de graphe de scène au-dessus du tokenizer présente des bugs connus et n’est pas prêt pour la production. Utilisez OBJ, STL, glTF, COLLADA ou 3MF pour un usage fiable en production.
Puis-je utiliser Aspose.3D FOSS dans un produit commercial ? Oui. La bibliothèque est publiée sous licence MIT, qui autorise l’utilisation dans des logiciels propriétaires et commerciaux sans paiement de redevances, à condition que l’avis de licence soit inclus.
Comment signaler un bug ou demander un format ? Ouvrez une issue dans le dépôt. Incluez un fichier de reproduction minimal ainsi que la version Python, le système d’exploitation et la version de la bibliothèque provenant de pip show aspose-3d-foss.
Résumé de la référence API
Classes de base
Scene: Conteneur de niveau supérieur pour une scène 3D. Point d’entrée pouropen(),from_file(),: , etsave().Node: Nœud d’arbre dans le graphe de scène. Contiententity,transform,global_transform,material,child_nodes,: , etname.Entity: Classe de base pour les objets attachés aux nœuds (Mesh, Camera, Light).Transform: Position, rotation (Quaternion) et échelle en espace local pour un nœud.GlobalTransform: Transformation en espace mondial en lecture seule calculée en accumulant toutes les transformations des ancêtres.
Géométrie
Mesh: Maillage polygonal aveccontrol_points: (liste de sommets) etpolygons.VertexElementNormal: Vecteurs normaux par sommet ou par polygone.VertexElementUV: Coordonnées de texture UV par sommet.VertexElementVertexColor: Données de couleur par sommet.VertexElementSmoothingGroup: Affectations de groupes de lissage de polygones.
Matériaux
LambertMaterial: Modèle d’ombrage diffus avecdiffuse_color: etemissive_color.PhongMaterial: Modèle d’ombrage spéculaire ajoutantspecular_color: etshininess.
: Utilitaires mathématiques (aspose.threed.utilities)
Vector2: Vecteur 2D.Vector3: Vecteur 3D double précision.Vector4: Vecteur 4D double précision.FVector3: Vecteur 3D simple précision.Quaternion: Quaternion de rotation avecfrom_angle_axis(): etto_matrix().Matrix4: matrice de transformation 4×4.BoundingBox: Boîte englobante alignée sur les axes avecminimum: etmaximum: coins.
Animation
AnimationClip: Conteneur nommé pour un ensemble de canaux d’animation et leurs images clés.AnimationNode: Données d’animation par nœud dans un clip.KeyFrame: Image clé unique avec le temps et la valeur.KeyframeSequence: Séquence ordonnée d’images clés pour une seule propriété animée.
Options de chargement / d’enregistrement
ObjLoadOptions: Paramètres de chargement spécifiques à OBJ:enable_materials,flip_coordinate_system,normalize_normal,scale.StlSaveOptions: Paramètres d’enregistrement spécifiques à STL (mode binaire vs. mode ASCII).
Caméras et lumières
Camera: Entité caméra avec paramètres de projection, attachable à unNode.Light: Entité source de lumière, attachable à unNode.