Πώς να περάσετε ένα 3D σκηνικό γραφικά στο Python
Το γραφικό σκηνής στο Aspose.3D FOSS είναι ένα δέντρο του Node αντικείμενα που ριζώνουν σε scene.root_node.Κάθε αρχείο 3D, είτε φορτώθηκε από OBJ, glTF, STL, COLLADA ή 3MF , παράγει την ίδια δομή δέντρου. Γνωρίζοντας πώς να περάσει το επιτρέπει να ελέγξετε τη γεωμετρία, να μετράτε πολυγόνες, τα αντικείμενα φιλτραρίσματος ανά τύπο και να επεξεργαστείτε συγκεκριμένα μέρη μιας σύνθετης σκηνής.
Βήμα προς βήμα οδηγός
Βήμα 1: Εγκατάσταση και εισαγωγή
Εισάγετε το Aspose.3D FOSS από την PyPI:
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
Εισαγωγή των τάξεων που χρειάζεστε:
from aspose.threed import Scene
from aspose.threed.entities import MeshΌλες οι δημόσιες τάξεις ζουν κάτω από το aspose.threed και τα υποσυσκευαστικά του (aspose.threed.entities, aspose.threed.utilities).
Βήμα 2: Κατεβάστε μια σκηνή από ένα αρχείο
Χρησιμοποιήστε το στατικό Scene.from_file() Η μέθοδος για να ανοίξετε οποιαδήποτε υποστηριζόμενη μορφή.Η μορφοποίηση ανιχνεύεται αυτόματα από την επέκταση αρχείου:
scene = Scene.from_file("model.gltf")Μπορείτε επίσης να ανοίξετε με τις επιλογές εκφραστικής φόρτωσης:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.enable_materials = True
scene = Scene()
scene.open("model.obj", options)Μετά την φόρτιση, scene.root_node Όλα τα εισαγόμενα κόμβα είναι παιδιά ή απογόνους αυτού του κόμματος.
Βήμα 3: Γράψτε μια αναδρομική ταξιδιωτική λειτουργία
Η πιο απλή διαδρομή επισκέπτεται κάθε κόμβο σε πρώτη σειρά:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def traverse(node, depth=0):
prefix = " " * depth
entity_name = type(node.entity).__name__ if node.entity else "-"
print(f"{prefix}[{entity_name}] {node.name}")
for child in node.child_nodes:
traverse(child, depth + 1)
scene = Scene.from_file("model.gltf")
traverse(scene.root_node)Παραδείγματα παραγωγής:
[-]
[-] Armature
[Mesh] Body
[Mesh] Eyes
[-] Ground
[Mesh] Plane<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”
<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>
Σημείωση : Το κενό έχει ένα άδειο όνομα (
""1) Η πρώτη γραμμή δείχνει[-]χωρίς όνομα που ακολουθεί.
node.child_nodes επιστρέφει τα παιδιά σε εντολή εισαγωγής (η εντολής στην οποία ο εισαγγελέας ή ο χρήστης τους προσθέτει).
Βήμα 4: Πρόσβαση σε ιδιότητες οντότητας σε κάθε κόμβο
Χρησιμοποιήστε node.entity να λάβει την πρώτη οντότητα συνδεδεμένη σε ένα κόμβο, ή node.entities Για να τα ιταρίσετε όλα. ελέγξτε τον τύπο πριν από την πρόσβαση σε ιδιότητες που είναι ειδικές για μορφή:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def print_entity_details(node, depth=0):
indent = " " * depth
for entity in node.entities:
if isinstance(entity, Mesh):
mesh = entity
print(f"{indent}Mesh '{node.name}':")
print(f"{indent} vertices : {len(mesh.control_points)}")
print(f"{indent} polygons : {mesh.polygon_count}")
print(f"{indent} cast_shadows : {mesh.cast_shadows}")
print(f"{indent} receive_shadows: {mesh.receive_shadows}")
for child in node.child_nodes:
print_entity_details(child, depth + 1)
scene = Scene.from_file("model.gltf")
print_entity_details(scene.root_node)node.transform.translation, node.transform.rotation,και node.transform.scaling Να μεταμορφώσουμε τον τοπικό χώρο. node.global_transform δίνει το αξιολογημένο αποτέλεσμα του κόσμου (με global_transform.scale για την παγκόσμια κλίμακα).
Βήμα 5: Φιλτράρετε τα κενά ανά τύπο οντότητας
Για να λειτουργεί μόνο σε συγκεκριμένους τύπους οντοτήτων, προσθέστε ένα isinstance Η διαφύλαξη μέσα στο πέρασμα:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def find_mesh_nodes(node, results=None):
if results is None:
results = []
for entity in node.entities:
if isinstance(entity, Mesh):
results.append(node)
break # One match per node is enough
for child in node.child_nodes:
find_mesh_nodes(child, results)
return results
scene = Scene.from_file("model.gltf")
mesh_nodes = find_mesh_nodes(scene.root_node)
print(f"Found {len(mesh_nodes)} mesh node(s)")
for n in mesh_nodes:
print(f" {n.name}")Αυτό το πρότυπο είναι χρήσιμο για τις δραστηριότητες των μαζών: εφαρμόζοντας μια μετατροπή σε κάθε κόμβο μαστού, αντικαθιστώντας τα υλικά ή εξάγοντας υποδέντρα.
Βήμα 6: Συλλέξτε όλες τις μάζες και εκτυπώστε τα κέρματα Vertex
Συγκεντρώστε τα στατιστικά στοιχεία με ένα μόνο πέρασμα:
from aspose.threed import Scene
from aspose.threed.entities import Mesh
def collect_meshes(node, results=None):
if results is None:
results = []
if isinstance(node.entity, Mesh):
results.append((node.name, node.entity))
for child in node.child_nodes:
collect_meshes(child, results)
return results
scene = Scene.from_file("model.gltf")
meshes = collect_meshes(scene.root_node)
print(f"Total meshes: {len(meshes)}")
total_verts = 0
total_polys = 0
for name, mesh in meshes:
verts = len(mesh.control_points)
polys = mesh.polygon_count
total_verts += verts
total_polys += polys
print(f" {name}: {verts} vertices, {polys} polygons")
print(f"Scene totals: {total_verts} vertices, {total_polys} polygons")κοινά ζητήματα
| Θέμα | Ψήφισμα |
|---|---|
AttributeError: 'NoneType' object has no attribute 'polygons' | Φύλαξη με if node.entity is not None ή isinstance(node.entity, Mesh) πριν από την πρόσβαση σε ιδιότητες μασχ. Σημεία χωρίς οντότητες επιστροφή None. |
| Ταξιδεύουν νωρίς | Να διασφαλιστεί ότι η αναδρομή φτάνει στο node.child_nodes.Αν το απλώς ερμηνεύεις scene.root_node.child_nodes (Δεν επαναλαμβάνετε), λείπουν όλοι οι απογόνες σας. |
| Απαλλαγή από τα συλλεχθέντα αποτελέσματα | Βεβαιωθείτε ότι η μορφή αρχείου διατηρεί την ιεραρχία. OBJ στρέφει όλη τη γεωμετρία σε ένα επίπεδο κόμβου. Χρησιμοποιήστε glTF ή COLLADA για βαθιές ιοραξίες. |
node.entity Επέστρεψε μόνο την πρώτη οντότητα. | Χρησιμοποιήστε node.entities (η πλήρης λίστα) όταν ένα κόμβο φέρει πολλαπλές οντότητες. node.entity Είναι ένα μικρό χέρι για node.entities[0] Όταν entities Είναι άδικο. |
collect_meshes Επιστρέφει 0 αποτελέσματα για ένα φορτισμένο STL | Τα αρχεία STL συνήθως παράγουν ένα ενιαίο επίπεδη κόμβο με μία οντότητα μασής απευθείας κάτω από το root_node.Ελέγξτε root_node.child_nodes[0].entity απευθείας . |
| Τα ονόματα των κόμβων είναι άδειες γραμμές | Ορισμένες μορφές (binary STL, ορισμένα αρχεία OBJ) δεν αποθηκεύουν ονόματα αντικειμένων. name Σημειώνεται ότι χρησιμοποιεί τον δείκτη για την αναγνώριση. |
Συχνές ερωτήσεις
Πόσο βαθιά μπορεί να είναι ένα γραφείο σκηνής;?
Δεν υπάρχει σκληρός όρος. ο προεπιλεγμένος όγκος αναδρομίας του Python (1000 πλαίσια) ισχύει για τις αναδυόμενες διασταυρωτικές λειτουργίες. Για πολύ βαθιές ιεραρχίες, μετατρέψτε την ανακάλυψη σε μια σαφή γραμμή:
from collections import deque
from aspose.threed import Scene
scene = Scene.from_file("deep.gltf")
queue = deque([(scene.root_node, 0)])
while queue:
node, depth = queue.popleft()
print(" " * depth + node.name)
for child in node.child_nodes:
queue.append((child, depth + 1))Μπορώ να αλλάξω το δέντρο ενώ περνάω;?
Μην προσθέτετε ή αφαιρέστε κόντρα από το child_nodes Συλλέξτε τα κόμβα για να τροποποιήσετε σε ένα πρώτο πέρασμα, στη συνέχεια εφαρμόστε αλλαγές σε μια δεύτερη πέρασή.
Πώς μπορώ να βρω ένα συγκεκριμένο κόμβο με το όνομα;?
Χρησιμοποιήστε node.get_child(name) Για μια βαθιά αναζήτηση, διασχίστε το δέντρο με ένα φίλτρο ονόματος:
def find_by_name(root, name):
if root.name == name:
return root
for child in root.child_nodes:
result = find_by_name(child, name)
if result:
return result
return None
target = find_by_name(scene.root_node, "Wheel_FL")Η ΚΕ node.entity Πάντα επιστρέφει ένα μαστίκι;?
Ένα κόμβο μπορεί να έχει οποιοδήποτε είδος οντότητας: Mesh, Camera, Light,ΕΝΑ ΠΟΛΙΤΙΚΟ ΑΡΘΡΟ.Πάντα ελέγξτε με isinstance(node.entity, Mesh) πριν από τη χρήση ειδικών ιδιότητες.
Πώς μπορώ να πάρω τη θέση του κόσμου-διαστημικού ενός κόμβου;?
Διαβάστε node.global_transform.translation.Αυτή είναι η αξιολογημένη θέση στο παγκόσμιο διάστημα, με βάση όλες τις μετασχηματιστικές προγόνες. node.transform.translation Να επαναφέρει το κόμβο.
Μπορώ να μετρήσω τα πλήρη πολυγόνους σε μια σκηνή χωρίς να γράψω ένα διασταύρωση;?
Όχι απευθείας μέσω της API, δεν υπάρχει scene.total_polygon_count Ιδιοκτησία - Χρήση collect_meshes και το sum mesh.polygon_count Τα αποτελέσματα, όπως δείχνουν στο βήμα 6.