Σκηνή Γκράφι
Α Σενάριο γραφικών είναι το βασικό μοντέλο δεδομένων του Aspose.3D FOSS για Python. κάθε αρχείο 3D, είτε φορτώθηκε από δίσκο ή κατασκευασμένο στη μνήμη, αντιπροσωπεύεται ως ένα δέντρο της Node αντικείμενα που ριζώνουν σε Scene.root_node.Κάθε κόμβος μπορεί να κρατήσει τα παιδικά κόμπια και ένα ή περισσότερα. Entity Η κατανόηση του γραφείου σκηνής σας δίνει άμεση πρόσβαση στη γεωμετρία, τα υλικά και τις διαστημικές μετασχηματισμοί κάθε αντικειμένου σε μια σκιά.
Εγκατάσταση και εγκατάστασης
Εγκαταστήστε τη βιβλιοθήκη από το PyPI:
pip install aspose-3d-fossΔεν απαιτούνται εγχώριες επέκτασης, συνθέτες ή πρόσθετα πακέτα συστήματος. Για πλήρη οδηγίες εγκατάστασης, δείτε το Οδηγός εγκατάστασης.
Ετικέτες: Scene Graph Concepts
Το γραφείο σκηνής στο Aspose.3D FOSS ακολουθεί μια απλή ιεραρχία συσκευασίας:
Scene
└── root_node (Node)
├── child_node_A (Node)
│ ├── entity: Mesh
│ └── transform: translation, rotation, scale
├── child_node_B (Node)
│ └── child_node_C (Node)
│ └── entity: Mesh
└── ...| αντικείμενο | Ρόλος |
|---|---|
Scene | Κερατόπεδα - Καρδιάς root_node, asset_info, animation_clips,και sub_scenes. |
Node | Έχει έναν γονέα, μηδέν ή περισσότερα παιδιά, 0 ή περισσότερες οντότητες και ένα τοπικό Transform. |
Entity | Γεωμετρία ή σκηνικό αντικείμενο που συνδέεται με ένα κόμβο. κοινοί τύποι οντοτήτων: Mesh, Camera, Light. |
Transform | Τοπική θέση-διαστήματος, περιστροφή και κλίμακα για ένα κόμβο. το αποτέλεσμα του κόσμου-διάστης διαβάζεται από global_transform. |
Βήμα προς βήμα: Δημιουργία γραφικών σκηνής με προγραμματισμό
Βήμα 1: Δημιουργία σκηνής
Μια νέα Scene Πάντα ξεκινά με ένα κενό. root_node:
from aspose.threed import Scene
scene = Scene()
print(scene.root_node.name) # "" (empty string — root node has no name by default)
print(len(scene.root_node.child_nodes)) # 0Scene είναι το σημείο εισόδου για όλα: φορτίζοντας αρχεία, αποθηκεύοντας τα αρχείο, δημιουργώντας κλιπ κινουμένων σχεδίων και πρόσβαση στο δέντρο κόμβων.
Βήμα 2: Δημιουργία παιδικών ντοκιμαντέρ
Χρησιμοποιήστε create_child_node(name) Για να προσθέσετε ονομαστικούς κόμβους στο δέντρο:
from aspose.threed import Scene
scene = Scene()
parent = scene.root_node.create_child_node("parent")
child = parent.create_child_node("child")
print(parent.name) # "parent"
print(child.parent_node.name) # "parent"
print(len(scene.root_node.child_nodes)) # 1Εναλλακτικά, δημιουργήστε ένα standalone Node Και το προσθέτουμε ρητά:
from aspose.threed import Scene, Node
scene = Scene()
node = Node("standalone")
scene.root_node.add_child_node(node)Και οι δύο προσεγγίσεις παράγουν το ίδιο αποτέλεσμα. create_child_node Είναι πιο λεπτό για την ενδοσυνταγματική κατασκευή.
Βήμα 3: Δημιουργήστε μια οντότητα Mesh και προσθέστε την
Α Mesh Η αναφορά των δεδομένων (control_pointsκαι την ορθολογική (polygonsΔημιουργήστε ένα, προσθέστε γεωμετρία και στη συνέχεια το συνδέσετε σε έναν κόμβο:
from aspose.threed import Scene, Node
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3, Vector4
scene = Scene()
parent = scene.root_node.create_child_node("parent")
child = parent.create_child_node("child")
##Create a quad mesh (four vertices, one polygon)
# Note: control_points returns a copy of the internal list; append to
# _control_points directly to actually add vertices. This is a known
# library limitation — a public add_control_point() API is not yet available.
mesh = Mesh("cube")
mesh._control_points.append(Vector4(0, 0, 0, 1))
mesh._control_points.append(Vector4(1, 0, 0, 1))
mesh._control_points.append(Vector4(1, 1, 0, 1))
mesh._control_points.append(Vector4(0, 1, 0, 1))
mesh.create_polygon(0, 1, 2, 3)
child.add_entity(mesh)
print(f"Mesh name: {mesh.name}")
print(f"Vertex count: {len(mesh.control_points)}")
print(f"Polygon count: {mesh.polygon_count}")Vector4(x, y, z, w) Εξαρτάται από ομοιογενή συντονισμό. χρησιμοποιώντας w=1 για τακτικές θέσεις.
create_polygon(*indices) Αποδέχεται δεξιότητες και καταγράφει ένα πρόσωπο στη λίστα πολυγών. περάσει τρεις δείκτες για έναν τρίγωνο, τέσσερις για ένα τετράγωνος.
Βήμα 4: Εισάγετε μετασχηματισμούς νώτων
Κάθε κόμβος έχει ένα Transform που ελέγχει τη θέση, την κατεύθυνση και το μέγεθος του στο τοπικό χώρο:
from aspose.threed.utilities import Vector3, Quaternion
##Translate the node 2 units along the X axis
child.transform.translation = Vector3(2.0, 0.0, 0.0)
##Scale the node to half its natural size
child.transform.scaling = Vector3(0.5, 0.5, 0.5)
##Rotate 45 degrees around the Y axis using Euler angles
child.transform.euler_angles = Vector3(0.0, 45.0, 0.0)Οι μετασχηματισμοί είναι συσσωρευτικές: η θέση του κόσμου-διαστήματος ενός παιδικού κόμβου είναι η σύνθεση της δικής του μεταμόρφωσης με όλες τις μεταμορφώσεις των προγόνων. node.global_transform (Αντιμετωπές και μόνο διάβασμα).
Βήμα 5: Περπατήστε το γραφείο σκηνής επαναλαμβανόμενα
Περπατήστε το ολόκληρο δέντρο, περπατώντας μέσα από node.child_nodes:
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)Παράδειγμα εξόδου για την σκηνή που έχει κατασκευαστεί παραπάνω (το όνομα ρίζας είναι μια κενή γραμμή):
[None]
parent [None]
child [Mesh]Για σκηνές με πολλαπλές οντότητες ανά κόμβο, iterate node.entities Αντί να node.entity:
def traverse_full(node, depth=0):
indent = " " * depth
entity_names = [type(e).__name__ for e in node.entities] or ["None"]
print(f"{indent}{node.name} [{', '.join(entity_names)}]")
for child in node.child_nodes:
traverse_full(child, depth + 1)
traverse_full(scene.root_node)Βήμα 6: Σώστε την σκηνή
Πάρτε ένα αρχείο δρόμο για scene.save().Η μορφή εξάγεται από την επέκταση αρχείου:
scene.save("scene.gltf") # JSON glTF 2.0
scene.save("scene.glb") # Binary GLB container
scene.save("scene.obj") # Wavefront OBJ
scene.save("scene.stl") # STLΓια επιλογές που είναι συγκεκριμένες σε μορφή, περάστε ένα αντικείμενο επιλογών αποθήκευσης ως δεύτερο επιχειρηματικό στοιχείο:
from aspose.threed.formats import GltfSaveOptions
opts = GltfSaveOptions()
scene.save("scene.gltf", opts)Συμβουλές και βέλτιστες πρακτικές
- Όνομα κάθε κόμβου. Η παροχή νόημα των ονομάτων σε κόμβους καθιστά την αποσύνδεση των διαδρομών πολύ ευκολότερη και εξασφαλίζει ότι τα ονόματα διατηρούνται στο εξαγοράμενο αρχείο.
- 1 μίγμα ανά κόμβο. Η διατήρηση των οντοτήτων 1:1 με κόμβους απλοποιεί τις μετασχηματιστικές και συγκρούσεις ερωτήσεις.
- Χρησιμοποιήστε
create_child_nodeΜε το χειροκίνητο προσάρτημα. Εισάγει αυτόματα την αναφορά γονέα και είναι λιγότερο ελαττωματική. - Διαβάστε
global_transformΜετά την κατασκευή της ιεραρχίας. Το αποτέλεσμα του διαστήματος είναι σταθερό μόνο όταν καθοριστούν όλες οι μετασχηματισμοί των προγόνων. - Μην μεταλλάξετε το δέντρο κατά τη διάρκεια της διαδρομής. Προσθήκη ή αφαιρέστε τα παιδικά κόμβα κατά τη διάρκεια της ιταρίσματος
child_nodesΘα παράγει απρόβλεπτη συμπεριφορά. συλλέξτε πρώτα τα κόμβα, στη συνέχεια τροποποιήστε. - Χρησιμοποιήστε τα σημεία ελέγχου
Vector4,ΟχιVector3. Πάντα πέρασεw=1για τις συνήθεις θέσεις του βερτεξού,;w=0αντιπροσωπεύει ένα κατευθυντικό vector (όχι σημείο). mesh.control_pointsΕπιστρέφει ένα αντίγραφο. Ηcontrol_pointsΕπιστροφή ακινήτωνlist(self._control_points)- η προσθήκη στη λίστα που επιστρέφεται δεν τροποποιεί το μασχ. Πάντα προσθέστε στοmesh._control_pointsΑυτό είναι ένα γνωστό περιορισμό της βιβλιοθήκης. μια δημόσια μεταλλαγή API δεν υπάρχει ακόμα.
κοινά ζητήματα
| Θέμα | Ψήφισμα |
|---|---|
AttributeError: 'NoneType' object has no attribute 'polygons' | Φύλαξη με if node.entity is not None πριν από την πρόσβαση σε ιδιότητες οντότητας. ένα κόμβο χωρίς ονόματα έχει entity = None. |
Η Μασχ εμφανίζεται στην προέλευση παρά τη διάθεση translation | transform.translation Εάν το ίδιο το μητρικό κόμβο έχει μετασχηματισμό μη ταυτότητας, η θέση του κόσμου μπορεί να διαφέρει. global_transform. |
Παιδικά κόμβοι που λείπουν μετά από scene.save() / Ρεάλ | Ορισμένες μορφές (OBJ) σφραγίζουν τη ιεραρχία. χρησιμοποιήστε glTF ή COLLADA για να διατηρήσετε το πλήρες δέντρο κόμβου. |
polygon_count 0 μετά από mesh.create_polygon(...) | Βεβαιωθείτε ότι οι δείκτες vertex έχουν περάσει στο create_polygon Εδώ είναι στο εύρος (0 Για να len(control_points) - 1). |
Node.get_child(name) Επιστροφή None | Το όνομα είναι ευαίσθητο σε περίπτωση. επιβεβαιώστε την ακριβή γραμμή ονόματος που χρησιμοποιείται κατά τη διάρκεια της δημιουργίας. |
| Ταξιδιωτικές επισκέψεις σε απροσδόκητη σειρά | child_nodes Τα παιδιά επιστρέφουν στην εντολή εισαγωγής (η εντολη add_child_node / create_child_node και καλείται). |