Comment créer un maillage 3D avec Aspose.3D en Python
Aspose.3D FOSS for Python vous permet de créer une géométrie 3D entièrement en code : aucun outil de modélisation externe requis. Vous créez un Mesh, le remplissez avec des positions de sommets (control_points) et des définitions de faces (polygons), ajoutez des attributs de sommet optionnels tels que les normales, puis enregistrez la scène dans n’importe quel format pris en charge.
Guide étape par étape
Étape 1 : Installer le package
Installez Aspose.3D FOSS depuis PyPI. Aucune extension native ou chaîne d’outils du compilateur n’est requise.
pip install aspose-3d-fossVérifiez l’installation :
from aspose.threed import Scene
print("Aspose.3D FOSS ready")Versions Python prises en charge : 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Étape 2 : Créer une scène et un nœud
Chaque maillage doit vivre à l’intérieur d’un graphe de scène. Créez un Scene et ajoutez un Node nommé pour contenir le maillage :
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")Le nom du nœud est conservé dans le fichier exporté et est utile pour le débogage et la récupération ultérieure via node.get_child("triangle").
Étape 3 : Créer un objet Mesh
Instanciez un Mesh avec un nom descriptif facultatif:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")Le maillage est initialement vide : aucun sommet, aucun polygone. Vous le remplissez dans les étapes suivantes.
Étape 4 : Ajouter des points de contrôle (sommets)
Les points de contrôle sont les positions des sommets. Chaque sommet est stocké sous forme d’un Vector4(x, y, z, w) où w=1 indique un point dans l’espace 3D :
from aspose.threed.utilities import Vector4
##Vertex 0: origin
# Note: control_points returns a copy of the internal vertex list.
# Appending to the returned copy discards the vertex silently.
# Use _control_points to mutate the backing list directly.
# This is a known library limitation — a public add_control_point() API is not yet available.
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))
##Vertex 1: 1 unit along X
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))
##Vertex 2: apex
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))
print(f"Vertices added: {len(mesh.control_points)}")Important : mesh.control_points renvoie une copie de la liste interne des sommets (le getter exécute list(self._control_points)). L’appel de mesh.control_points.append(v) ajoute à la copie, pas au maillage, de sorte que le sommet est silencieusement ignoré. Utilisez toujours mesh._control_points.append(v) pour ajouter des sommets. Accéder à l’état privé via _control_points est une solution de contournement connue ; l’interface peut changer dans une version future de la bibliothèque.
Étape 5 : Créer des faces polygonales
Définissez la topologie de la face à l’aide des indices de sommet. Transmettez les indices de sommet à create_polygon(). Trois indices produisent un triangle ; quatre produisent un quadrilatère :
##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)
print(f"Polygon count: {mesh.polygon_count}")Pour un maillage quadrangulaire, vous passeriez quatre indices : mesh.create_polygon(0, 1, 2, 3).
Les indices doivent être des positions valides dans control_points (indexés à partir de 0, dans les limites). L’ordre de parcours est dans le sens inverse des aiguilles d’une montre pour les normales orientées vers l’extérieur.
Étape 6 : Ajouter les normales de sommet
Les normales de sommet sont stockées sous forme de VertexElement attachée au maillage. Utilisez mesh.create_element() avec VertexElementType.NORMAL, MappingMode.CONTROL_POINT et ReferenceMode.DIRECT :
from aspose.threed.entities import VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector4, FVector4
##Create the normal element (returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(
VertexElementType.NORMAL,
MappingMode.CONTROL_POINT,
ReferenceMode.DIRECT
)
##One normal per vertex: all pointing out of the XY plane (0, 0, 1)
normals.set_data([
FVector4(0, 0, 1, 0), # vertex 0
FVector4(0, 0, 1, 0), # vertex 1
FVector4(0, 0, 1, 0), # vertex 2
])
print("Normal layer attached.")MappingMode.CONTROL_POINT signifie une normale par sommet. ReferenceMode.DIRECT signifie que les données de normales sont lues dans le même ordre que les points de contrôle (pas de tampon d’index supplémentaire).
Les vecteurs normaux utilisent FVector4(x, y, z, w) avec w=0 pour indiquer une direction plutôt qu’une position. FVector4 est un vecteur à virgule flottante simple précision ; les données d’attribut de sommet dans les sous‑classes VertexElementFVector utilisent ce type.
Étape 7 : Attacher le maillage au nœud et enregistrer
Ajoutez le maillage au nœud, puis enregistrez la scène :
node.add_entity(mesh)
scene.save("triangle.gltf")
print("Saved triangle.gltf")Le script complet fonctionnel (toutes les étapes combinées) :
from aspose.threed import Scene
from aspose.threed.entities import Mesh, VertexElementType, MappingMode, ReferenceMode, VertexElementNormal
from aspose.threed.utilities import Vector3, Vector4, FVector4
scene = Scene()
node = scene.root_node.create_child_node("triangle")
mesh = Mesh("triangle")
##Add 3 vertices (x, y, z, w)
# Use _control_points to mutate the backing list directly (control_points returns a copy)
mesh._control_points.append(Vector4(0.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(1.0, 0.0, 0.0, 1.0))
mesh._control_points.append(Vector4(0.5, 1.0, 0.0, 1.0))
##Create a triangle polygon
mesh.create_polygon(0, 1, 2)
##Add normals (create_element returns VertexElementNormal, a VertexElementFVector subclass)
normals: VertexElementNormal = mesh.create_element(VertexElementType.NORMAL, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT)
normals.set_data([
FVector4(0, 0, 1, 0),
FVector4(0, 0, 1, 0),
FVector4(0, 0, 1, 0),
])
node.add_entity(mesh)
scene.save("triangle.gltf")Problèmes courants
| Problème | Résolution |
|---|---|
IndexError dans create_polygon | Vérifiez que tous les indices sont dans range(len(mesh.control_points)). Les indices sont à base zéro. |
| Exportation du maillage avec zéro sommet | mesh.control_points.append(...) supprime silencieusement les sommets parce que la propriété renvoie une copie. Utilisez mesh._control_points.append(...) à la place. |
| Le nombre de normales ne correspond pas au nombre de sommets | Lors de l’utilisation de MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data doit contenir exactement len(control_points) entrées. |
| Maillage manquant dans le fichier enregistré | Confirmez que node.add_entity(mesh) a été appelé avant scene.save(). Un maillage non attaché à un nœud n’est pas exporté. |
| Ordre de rotation incorrect (la face apparaît invisible) | Un ordre de sommets dans le sens antihoraire produit une normale orientée vers l’extérieur. Inversez l’ordre des indices dans create_polygon pour le retourner. |
polygon_count renvoie 0 | polygon_count lit la même liste que polygons. Si create_polygon n’a pas été appelé, la liste est vide. |
| Les normales apparaissent incorrectes dans le visualiseur | Assurez-vous que tous les vecteurs normaux sont de longueur unité. Calculez-les avec n / abs(n) ou transmettez des valeurs prénormalisées. |
Foire aux questions
Quelle est la différence entre Vector3 et Vector4 pour les points de contrôle ?
control_points stocke des objets Vector4. Le composant w est la coordonnée homogène : utilisez w=1 pour les positions des sommets et w=0 pour les vecteurs de direction tels que les normales. Vector3 est utilisé pour les transformations (translation, mise à l’échelle) mais pas pour le stockage de la géométrie.
Puis-je créer un maillage avec des quads au lieu de triangles ?
Oui. Appelez mesh.create_polygon(0, 1, 2, 3) avec quatre indices pour définir un quad. Certains formats de sauvegarde (STL, 3MF) nécessitent des triangles et trianguleront automatiquement les quads. glTF et COLLADA conservent les quads.
Comment ajouter des coordonnées UV ?
Utilisez mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) pour créer un VertexElementUV pour le canal diffuse, puis remplissez sa liste data avec Vector4 entrées. Les coordonnées UV utilisent x et y ; z et w sont généralement à 0. Le premier argument doit être une constante TextureMapping (par exemple, TextureMapping.DIFFUSE) identifiant le slot de texture auquel appartient la couche UV.
Le maillage a-t-il besoin de normales pour être exporté correctement ?
Non. Les normales sont facultatives. Si elles sont omises, la plupart des visionneuses calculent les normales par face à partir de l’ordre de parcours des polygones. Ajouter des normales explicites par sommet produit un ombrage plus doux.
Puis-je ajouter plusieurs maillages à un nœud ?
Oui. Appelez node.add_entity(mesh) plusieurs fois. Chaque appel ajoute une nouvelle entité à node.entities. Certains formats peuvent aplatir plusieurs entités en une seule lors de l’exportation.
Comment trianguler un maillage avec des types de polygones mixtes ?
Appelez mesh.triangulate() pour convertir tous les quadrilatères et N‑gons en triangles sur place. Ceci est utile avant d’enregistrer dans des formats qui ne prennent en charge que les triangles.