Πώς να μετατρέψετε 3D μοντέλα σε Python
Η μετατροπή μορφής με το Aspose.3D FOSS για Python είναι μια διαδικασία δύο βημάτων: φόρτωση σε ένα αντικείμενο Scene, στη συνέχεια αποθήκευση στην επιθυμητή μορφή εξόδου. Επειδή όλη η γεωμετρία διατηρείται σε μια κοινή αναπαράσταση στη μνήμη, δεν απαιτούνται ενδιάμεσα βήματα ειδικά για τη μορφή. Οι παρακάτω ενότητες δείχνουν τις πιο συνηθισμένες μετατροπές με λειτουργικό κώδικα.
Οδηγός βήμα-βήμα
Βήμα 1: Εγκατάσταση του πακέτου
pip install aspose-3d-fossΔεν απαιτούνται βιβλιοθήκες συστήματος, μεταγλωττιστές ή πρόσθετες εξαρτήσεις χρόνου εκτέλεσης.
Βήμα 2: Φόρτωση του Πηγαίου Μοντέλου
Χρησιμοποιήστε Scene.from_file() για την πιο απλή περίπτωση: η μορφή ανιχνεύεται αυτόματα από την επέκταση του αρχείου:
from aspose.threed import Scene
scene = Scene.from_file("model.obj")Για αρχεία OBJ όπου χρειάζεστε έλεγχο του συστήματος συντεταγμένων ή της φόρτωσης υλικού, χρησιμοποιήστε scene.open() με ObjLoadOptions:
from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions
options = ObjLoadOptions()
options.flip_coordinate_system = True # Convert to Z-up if needed
options.enable_materials = True # Load the accompanying .mtl file
options.normalize_normal = True
scene = Scene()
scene.open("model.obj", options)Και οι δύο προσεγγίσεις παράγουν ένα ταυτόσημο αντικείμενο Scene για το επόμενο βήμα αποθήκευσης.
Βήμα 3: Επιθεωρήστε τη Φορτωμένη Σκηνή
Πριν προχωρήσετε σε μια μετατροπή, αξίζει να ελέγξετε ότι η γεωμετρία φορτώθηκε σωστά. Ένα αρχείο που λείπει, μια μη υποστηριζόμενη λειτουργία του FBX ή ένα πρόβλημα διαδρομής με ένα αρχείο .mtl μπορεί όλα να παράγουν μια κενή σκηνή.
from aspose.threed import Scene
from aspose.threed.entities import Mesh
scene = Scene.from_file("model.obj")
mesh_count = 0
total_vertices = 0
def count_meshes(node) -> None:
global mesh_count, total_vertices
for entity in node.entities:
if isinstance(entity, Mesh):
mesh_count += 1
total_vertices += len(entity.control_points)
for child in node.child_nodes:
count_meshes(child)
count_meshes(scene.root_node)
print(f"Loaded {mesh_count} mesh(es), {total_vertices} total vertices")
if mesh_count == 0:
raise ValueError("Scene contains no geometry: check the source file path and format")Βήμα 4: Αποθήκευση στη μορφή προορισμού
Καλέστε scene.save() με τη διαδρομή εξόδου. Περνάτε ένα αντικείμενο save-options ειδικό για τη μορφή για έλεγχο της δυαδικής έναντι ASCII εξόδου, των αξόνων συντεταγμένων και της συμπίεσης.
OBJ σε STL (δυαδικό)
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
scene = Scene.from_file("model.obj")
save_opts = StlSaveOptions()
##StlSaveOptions defaults to binary output, which is more compact.
scene.save("model.stl", save_opts)
print("Saved model.stl")OBJ σε glTF 2.0
from aspose.threed import Scene
from aspose.threed.formats import GltfSaveOptions
scene = Scene.from_file("model.obj")
save_opts = GltfSaveOptions()
scene.save("model.gltf", save_opts)
print("Saved model.gltf")Για να αποθηκεύσετε ως ένα αυτόνομο δυαδικό GLB αντί για ένα .gltf + εξωτερικά buffers, αλλάξτε την επέκταση εξόδου σε .glb:
scene.save("model.glb", save_opts)OBJ σε 3MF
from aspose.threed import Scene
from aspose.threed.formats import ThreeMfSaveOptions
scene = Scene.from_file("model.obj")
save_opts = ThreeMfSaveOptions()
scene.save("model.3mf", save_opts)
print("Saved model.3mf")STL σε glTF 2.0
Το ίδιο μοτίβο ισχύει ανεξάρτητα από τη μορφή προέλευσης:
from aspose.threed import Scene
from aspose.threed.formats import GltfSaveOptions
scene = Scene.from_file("input.stl")
scene.save("output.gltf", GltfSaveOptions())
print("Saved output.gltf")Βήμα 5: Επαλήθευση του Αποτελέσματος
Μετά την αποθήκευση, επιβεβαιώστε ότι το αρχείο εξόδου υπάρχει και έχει μη μηδενικό μέγεθος. Για πιο λεπτομερή έλεγχο, φορτώστε το ξανά και συγκρίνετε τους αριθμούς πλεγμάτων:
import os
from aspose.threed import Scene
from aspose.threed.entities import Mesh
output_path = "model.stl"
##Basic file-system check
size = os.path.getsize(output_path)
print(f"Output file size: {size} bytes")
if size == 0:
raise RuntimeError("Output file is empty: save may have failed silently")
##Round-trip verification: reload and count geometry
def _iter_nodes(node):
yield node
for child in node.child_nodes:
yield from _iter_nodes(child)
reloaded = Scene.from_file(output_path)
mesh_count = sum(
1
for node in _iter_nodes(reloaded.root_node)
for entity in node.entities
if isinstance(entity, Mesh)
)
print(f"Round-trip check: {mesh_count} mesh(es) in output")Κοινά προβλήματα και διορθώσεις
Το αρχείο εξόδου δημιουργείται αλλά δεν περιέχει γεωμετρία
Το αρχείο προέλευσης ενδέχεται να έχει φορτωθεί με μηδενικά πλέγματα. Προσθέστε το βήμα επιθεώρησης από το Βήμα 3 πριν από την αποθήκευση. Επίσης, βεβαιωθείτε ότι η επέκταση του αρχείου ταιριάζει με την πραγματική μορφή· Aspose.3D χρησιμοποιεί την επέκταση για να επιλέξει τον αναλυτή.
Η έξοδος glTF δεν περιέχει υφές
Aspose.3D FOSS μεταφέρει γεωμετρία και ιδιότητες υλικού μέσω της μετατροπής. Εάν το πηγαίο OBJ αναφέρει εξωτερικά αρχεία εικόνας στο .mtl, αυτά τα αρχεία εικόνας δεν αντιγράφονται αυτόματα μαζί με το .gltf. Αντιγράψτε τις εικόνες υφής στον φάκελο εξόδου χειροκίνητα μετά την αποθήκευση.
Η έξοδος STL φαίνεται ανάποδη (οι κανονικές των προσώπων είναι αντιστραμμένες)
Το STL δεν μεταφέρει μεταδεδομένα σειράς περιδρόμησης. Εάν οι κανονικές εξόδου είναι αντιστραμμένες, ορίστε τις επιλογές StlSaveOptions εάν είναι διαθέσιμες, ή αντιστρέψτε το σύστημα συντεταγμένων κατά τη φόρτωση: ObjLoadOptions.flip_coordinate_system = True.
ValueError: unsupported format όταν αποθηκεύεται
Ελέγξτε ότι η επέκταση του αρχείου εξόδου είναι μία από τις .obj, .stl, .gltf, .glb, .dae, .3mf. Οι επεκτάσεις είναι ευαίσθητες σε πεζά/κεφαλαία στο Linux.
Τα πολύ μεγάλα αρχεία προκαλούν αργή μετατροπή
Aspose.3D FOSS επεξεργάζεται τη γεωμετρία στη μνήμη. Για αρχεία με εκατομμύρια πολύγωνα, εξασφαλίστε επαρκή RAM. Προς το παρόν δεν υπάρχει streaming-write API.
Συχνές Ερωτήσεις (FAQ)
Μπορώ να μετατρέψω ένα αρχείο χωρίς να το γράψω πρώτα στο δίσκο;
Ναι. Και τα scene.open() και scene.save() δέχονται δυαδικά αντικείμενα τύπου αρχείου εκτός από διαδρομές αρχείων. Περνάτε οποιοδήποτε αντικείμενο που υλοποιεί read() για φόρτωση ή write() για αποθήκευση:
import io
from aspose.threed import Scene
# Load from an in-memory buffer
data = open('model.obj', 'rb').read()
scene = Scene()
scene.open(io.BytesIO(data))
# Save to an in-memory buffer
buf = io.BytesIO()
scene.save(buf)Υποστηρίζεται το FBX ως μορφή πηγής για μετατροπή;
Η τοκενικοποίηση του FBX έχει υλοποιηθεί εν μέρει, αλλά ο αναλυτής δεν είναι πλήρης. Η είσοδος FBX μπορεί να παράγει ελλιπείς σκηνές. Χρησιμοποιήστε τα OBJ, STL, glTF, COLLADA ή 3MF ως αξιόπιστες μορφές πηγής.
Θα διατηρηθούν τα υλικά σε μια μετατροπή OBJ‑σε‑glTF;
Οι βασικές ιδιότητες υλικού Phong/Lambert (χρώμα διάχυσης) μεταφέρονται μέσω του μοντέλου Scene και γράφονται στο μπλοκ υλικού glTF. Οι διαδικαστικές ή προσαρμοσμένες παράμετροι shader που δεν μπορούν να εκφραστούν στο μοντέλο υλικού glTF απορρίπτονται.
Μπορώ να μετατρέψω πολλαπλά αρχεία σε βρόχο;
Ναι. Κάθε κλήση Scene.from_file() δημιουργεί ένα ανεξάρτητο αντικείμενο, οπότε ένας βρόχος πάνω σε μια λίστα διαδρομών είναι απλός:
from pathlib import Path
from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions
source_dir = Path("input")
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
opts = StlSaveOptions()
for obj_file in source_dir.glob("*.obj"):
scene = Scene.from_file(str(obj_file))
out_path = output_dir / obj_file.with_suffix(".stl").name
scene.save(str(out_path), opts)
print(f"Converted {obj_file.name} -> {out_path.name}")Διατηρεί η μετατροπή την ιεραρχία σκηνής (γονέων/παιδιών κόμβων);
Ναι. Το δέντρο κόμβων διατηρείται όσο το επιτρέπει η μορφή προορισμού. Μορφές όπως το STL αποθηκεύουν μόνο επίπεδη γεωμετρία χωρίς δομή κόμβων· η ιεραρχία ισοπεδώνεται κατά την αποθήκευση. Μορφές όπως το glTF και το COLLADA διατηρούν την πλήρη ιεραρχία.