Kako konvertovati 3D modele u Pythonu
Konverzija formata uz Aspose.3D FOSS za Python je dvostepeni proces: učitajte u Scene objekat, a zatim sačuvajte u željeni izlazni format. Pošto je sva geometrija zadržana u zajedničkoj internom predstavljanju, nisu potrebni format‑specifični međukoraci. Donji odeljci prikazuju najčešće konverzije sa radnim kodom.
Vodič korak po korak
Korak 1: Instalirajte paket
pip install aspose-3d-fossNisu potrebne sistemske biblioteke, kompajleri ili dodatne runtime zavisnosti.
Korak 2: Učitaj izvorni model
Koristite Scene.from_file() za najjednostavniji slučaj: format se automatski otkriva iz ekstenzije fajla:
from aspose.threed import Scene
scene = Scene.from_file("model.obj")Za OBJ datoteke kod kojih je potrebno kontrolisati koordinatni sistem ili učitavanje materijala, koristite scene.open() sa 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)Oba pristupa proizvode identičan Scene objekat za sledeći korak čuvanja.
Korak 3: Pregled učitane scene
Pre nego što se odlučite na konverziju, vredi proveriti da li je geometrija pravilno učitana. Nedostajući fajl, nepodržana FBX funkcija ili problem sa putanjom u .mtl fajlu mogu sve proizvesti praznu scenu.
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")Korak 4: Sačuvajte u ciljani format
Pozovite scene.save() sa putanjom izlaza. Prosledite objekat save‑options specifičan za format za kontrolu binarnog naspram ASCII izlaza, koordinatnih osa i kompresije.
OBJ u STL (binarni)
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 u 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")Da biste sačuvali kao samostalni GLB binarni fajl umesto .gltf + eksternih bafera, promenite ekstenziju izlaza u .glb:
scene.save("model.glb", save_opts)OBJ u 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 u glTF 2.0
Isti obrazac važi bez obzira na izvorni format:
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")Korak 5: Proverite izlaz
Nakon čuvanja, potvrdite da izlazni fajl postoji i da ima nenultu veličinu. Za temeljitiju proveru, ponovo ga učitajte i uporedite broj mreža:
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")Uobičajeni problemi i popravke
Izlazni fajl je kreiran, ali ne sadrži geometriju
Izvorni fajl može biti učitan bez ikakvih mreža. Dodajte korak inspekcije iz koraka 3 pre čuvanja. Takođe potvrdite da ekstenzija fajla odgovara stvarnom formatu; Aspose.3D koristi ekstenziju za odabir parsera.
glTF izlaz nema teksture
Aspose.3D FOSS prenosi geometriju i svojstva materijala kroz konverziju. Ako izvorni OBJ referiše spoljne slikovne fajlove u .mtl, ti slikovni fajlovi se ne kopiraju automatski uz .gltf. Kopirajte teksturne slike u izlazni direktorijum ručno nakon čuvanja.
STL izlaz izgleda unutra‑napolju (normale lica okrenute)
STL ne nosi metapodatke o redosledu obrtanja. Ako su izlazni normali invertovani, postavite opcije StlSaveOptions ako su dostupne, ili preokrenite koordinatni sistem prilikom učitavanja: ObjLoadOptions.flip_coordinate_system = True.
ValueError: unsupported format prilikom čuvanja
Proverite da je ekstenzija izlaznog fajla jedna od .obj, .stl, .gltf, .glb, .dae, .3mf. Ekstenzije su osetljive na veličinu slova na Linuxu.
Vrlo velike datoteke uzrokuju sporu konverziju
Aspose.3D FOSS obrađuje geometriju u memoriji. Za fajlove sa milionima poligona, obezbedite dovoljno RAM-a. Trenutno ne postoji API za streaming‑pisanje.
Često postavljana pitanja (FAQ)
Mogu li konvertovati fajl bez da ga prvo upišem na disk?
Да. И 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)Da li je FBX podržan kao izvorni format za konverziju?
FBX tokenizacija je delimično implementirana, ali parser nije kompletan. FBX ulaz može proizvesti nepotpune scene. Koristite OBJ, STL, glTF, COLLADA ili 3MF kao pouzdane izvorne formate.
Da li će materijali preživeti konverziju iz OBJ u glTF?
Osnovna Phong/Lambert svojstva materijala (difuzna boja) prenose se kroz model Scene i upisuju u glTF blok materijala. Proceduralni ili prilagođeni parametri shader‑a koji se ne mogu izraziti u glTF modelu materijala se odbacuju.
Могу ли да конвертујем више датотека у петљи?
Да. Svaki Scene.from_file() poziv kreira nezavisni objekat, pa je petlja preko liste putanja jednostavna:
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}")Da li konverzija očuva hijerarhiju scene (roditeljski/dete čvorovi)?
Da. Stablo čvorova se čuva u meri u kojoj to dozvoljava odredišni format. Formati poput STL čuvaju samo ravnu geometriju bez strukture čvorova; hijerarhija se izravnava prilikom čuvanja. Formati poput glTF i COLLADA zadržavaju potpunu hijerarhiju.