Πώς να δημιουργήσετε ένα 3D πλέγμα με Aspose.3D στο Python
Aspose.3D FOSS για Python σας επιτρέπει να δημιουργήσετε 3D γεωμετρία εξ ολοκλήρου σε κώδικα: δεν απαιτείται εξωτερικό εργαλείο μοντελοποίησης. Δημιουργείτε ένα Mesh, το γεμίζετε με θέσεις κορυφών (control_points) και ορισμούς προσώπων (polygons), επισυνάψτε προαιρετικά χαρακτηριστικά κορυφών όπως τα κανονικά, και στη συνέχεια αποθηκεύστε τη σκηνή σε οποιαδήποτε υποστηριζόμενη μορφή.
Οδηγός βήμα προς βήμα
Βήμα 1: Εγκατάσταση του πακέτου
Εγκαταστήστε το Aspose.3D FOSS από το PyPI. Δεν απαιτούνται εγγενείς επεκτάσεις ή αλυσίδα εργαλείων μεταγλωττιστή.
pip install aspose-3d-fossΕπαληθεύστε την εγκατάσταση:
from aspose.threed import Scene
print("Aspose.3D FOSS ready")Υποστηριζόμενες εκδόσεις του Python: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.
Βήμα 2: Δημιουργία Σκηνής και Κόμβου
Κάθε πλέγμα πρέπει να βρίσκεται μέσα σε ένα γράφημα σκηνής. Δημιουργήστε ένα Scene και προσθέστε ένα ονομασμένο Node για να κρατήσει το πλέγμα:
from aspose.threed import Scene
scene = Scene()
node = scene.root_node.create_child_node("triangle")Το όνομα του κόμβου διατηρείται στο εξαγόμενο αρχείο και είναι χρήσιμο για εντοπισμό σφαλμάτων και μετέπειτα ανάκτηση μέσω node.get_child("triangle").
Βήμα 3: Δημιουργία Αντικειμένου Mesh
Δημιουργήστε ένα Mesh με προαιρετικό περιγραφικό όνομα:
from aspose.threed.entities import Mesh
mesh = Mesh("triangle")Το πλέγμα αρχικά είναι κενό: χωρίς κορυφές, χωρίς πολύγωνα. Το γεμίζετε στα επόμενα βήματα.
Βήμα 4: Προσθήκη Σημείων Ελέγχου (Κορυφές)
Τα σημεία ελέγχου είναι οι θέσεις των κορυφών. Κάθε κορυφή αποθηκεύεται ως ένα Vector4(x, y, z, w) όπου w=1 υποδεικνύει ένα σημείο σε 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)}")Σημαντικό: mesh.control_points επιστρέφει ένα αντίγραφο της εσωτερικής λίστας κορυφών (ο getter εκτελεί list(self._control_points)) mesh.control_points.append(v) προσθέτει στο αντίγραφο, όχι στο πλέγμα, έτσι η κορυφή απορρίπτεται σιωπηρά. Πάντα χρησιμοποιήστε mesh._control_points.append(v) για την προσθήκη κορυφών. Η πρόσβαση στην private state μέσω _control_points είναι μια γνωστή λύση παρακάμπτησης· η διεπαφή μπορεί να αλλάξει σε μελλοντική έκδοση της βιβλιοθήκης.
Βήμα 5: Δημιουργία Πολυγωνικών Προσώπων
Ορίστε την τοπολογία των προσώπων χρησιμοποιώντας δείκτες κορυφών. Περνάτε δείκτες κορυφών στο create_polygon().Τρία δείκτες δημιουργούν ένα τρίγωνο· τέσσερα δημιουργούν ένα τετράπλευρο:
##Triangle: connect vertices 0 → 1 → 2
mesh.create_polygon(0, 1, 2)
print(f"Polygon count: {mesh.polygon_count}")Για ένα πλέγμα τετραπλεύρων θα περάσετε τέσσερις δείκτες: mesh.create_polygon(0, 1, 2, 3).
Οι δείκτες πρέπει να είναι έγκυρες θέσεις στο control_points (από το 0, εντός εύρους). Η σειρά περιδίνησης είναι αριστερόστροφη για εξωτερικά κατευθυνόμενα κανονικά.
Βήμα 6: Προσθήκη Κανονικών Κορυφών
Οι κανονικές των κορυφών αποθηκεύονται ως ένα VertexElement συνημμένες στο πλέγμα. Χρησιμοποιήστε mesh.create_element() με VertexElementType.NORMAL, MappingMode.CONTROL_POINT, και 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 σημαίνει μία κανονική ανά κορυφή. ReferenceMode.DIRECT σημαίνει ότι τα δεδομένα των κανονικών διαβάζονται με την ίδια σειρά όπως τα σημεία ελέγχου (χωρίς επιπλέον buffer δεικτών).
Τα διανύσματα κανονικών χρησιμοποιούν FVector4(x, y, z, w) με w=0 για να υποδείξουν μια κατεύθυνση αντί για θέση. FVector4 είναι διάνυσμα κινητής υποδιαστολής μονής ακρίβειας· δεδομένα χαρακτηριστικού κορυφής σε VertexElementFVector οι υποκλάσεις χρησιμοποιούν αυτόν τον τύπο.
Βήμα 7: Προσάρτηση του Πλέγματος στον Κόμβο και Αποθήκευση
Προσθέστε το πλέγμα στον κόμβο, έπειτα αποθηκεύστε τη σκηνή:
node.add_entity(mesh)
scene.save("triangle.gltf")
print("Saved triangle.gltf")Το πλήρες λειτουργικό σενάριο (όλα τα βήματα συνδυασμένα):
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")Συνηθισμένα Προβλήματα
| Πρόβλημα | Επίλυση |
|---|---|
IndexError σε create_polygon | Επαληθεύστε ότι όλοι οι δείκτες είναι εντός range(len(mesh.control_points)). Οι δείκτες είναι 0-βάση. |
| Το πλέγμα εξάγεται με μηδενικές κορυφές | mesh.control_points.append(...) απορρίπτει σιωπηλά τις κορυφές επειδή η ιδιότητα επιστρέφει ένα αντίγραφο. Χρησιμοποιήστε mesh._control_points.append(...) αντί αυτού. |
| Ο αριθμός των κανονικών δεν ταιριάζει με τον αριθμό των κορυφών | Κατά τη χρήση MappingMode.CONTROL_POINT + ReferenceMode.DIRECT, normals.data πρέπει να έχει ακριβώς len(control_points) καταχωρήσεις. |
| Το πλέγμα λείπει από το αποθηκευμένο αρχείο | Επιβεβαιώστε ότι node.add_entity(mesh) κλήθηκε πριν από scene.save(). Ένα πλέγμα που δεν είναι προσαρτημένο σε κανέναν κόμβο δεν εξάγεται. |
| Λάθος σειρά περιδρόμησης (η όψη φαίνεται αόρατη) | Η σειρά κορυφών counter-clockwise παράγει ένα εξωτερικά προσανατολισμένο κανονικό. Αντιστρέψτε τη σειρά των δεικτών στο create_polygon για να το αναστρέψετε. |
polygon_count επιστρέφει 0 | polygon_count διαβάζει την ίδια λίστα όπως polygons. Εάν create_polygon δεν κλήθηκε, η λίστα είναι κενή. |
| Οι κανονικές φαίνονται λανθασμένες στον προβολέα | Βεβαιωθείτε ότι όλα τα διανύσματα κανονικών είναι μονάδες μήκους. Υπολογίστε με n / abs(n) ή περάστε προ-κανονικοποιημένες τιμές. |
Συχνές Ερωτήσεις
Ποια είναι η διαφορά μεταξύ Vector3 και Vector4 για σημεία ελέγχου;?
control_points αποθηκεύει Vector4 αντικείμενα. Το w συστατικό είναι η ομογενής συντεταγμένη: χρησιμοποιήστε w=1 για θέσεις κορυφών και w=0 για διανύσματα κατεύθυνσης όπως οι κανονικές. Vector3 χρησιμοποιείται για μετασχηματισμούς (μετάθεση, κλίμακα) αλλά όχι για αποθήκευση γεωμετρίας.
Μπορώ να δημιουργήσω ένα πλέγμα με τετράπλευρα αντί για τρίγωνα;?
Ναι. Καλέστε mesh.create_polygon(0, 1, 2, 3) με τέσσερις δείκτες για να ορίσετε ένα τετράπλευρο. Ορισμένοι προορισμοί αποθήκευσης (STL, 3MF) απαιτούν τρίγωνα και θα τριγωνοποιήσουν τα τετράπλευρα αυτόματα. Το glTF και το COLLADA διατηρούν τα τετράπλευρα.
Πώς προσθέτω συντεταγμένες UV;?
Χρησιμοποιήστε mesh.create_element_uv(TextureMapping.DIFFUSE, MappingMode.POLYGON_VERTEX) για να δημιουργήσετε ένα VertexElementUV για το κανάλι diffuse, στη συνέχεια να γεμίσετε το data λίστα με Vector4 καταχωρήσεις. Οι συντεταγμένες UV χρησιμοποιούν x και y; z και w είναι συνήθως 0. Το πρώτο όρισμα πρέπει να είναι ένα TextureMapping σταθερά (π.χ., TextureMapping.DIFFUSE) που προσδιορίζει σε ποιο slot υφής ανήκει το στρώμα UV.
Το mesh χρειάζεται normals για να εξαχθεί σωστά;?
Όχι. Τα normals είναι προαιρετικά. Εάν παραλειφθούν, οι περισσότεροι προβολείς υπολογίζουν per‑face normals από τη σειρά περιδίασης των πολυγώνων. Η προσθήκη explicit per‑vertex normals παράγει πιο ομαλή σκίαση.
Μπορώ να προσθέσω πολλαπλά meshes σε έναν node;?
Ναι. Κάλεσε node.add_entity(mesh) πολλές φορές. Κάθε κλήση προσθέτει μια νέα οντότητα στο node.entities. Ορισμένες μορφές ενδέχεται να συγχωνεύσουν πολλές οντότητες σε μία κατά την εξαγωγή.
Πώς μπορώ να τριγωνίσω ένα mesh με μικτές τύπους πολυγώνων;?
Κάλεσε mesh.triangulate() για να μετατρέψετε όλα τα τετράπλευρα και N-γωνικά σε τρίγωνα επί τόπου. Αυτό είναι χρήσιμο πριν από την αποθήκευση σε μορφές που υποστηρίζουν μόνο τρίγωνα.