Jak převést 3D modely v Pythonu
Formátová konverze s Aspose.3D FOSS pro Python je dvoustupňový proces: načíst do objektu Scene, poté uložit do požadovaného výstupního formátu. Protože veškerá geometrie je uložena ve společné paměťové reprezentaci, nejsou potřeba žádné formátově specifické mezikroky. Níže uvedené sekce ukazují nejčastější konverze s funkčním kódem.
Průvodce krok za krokem
Krok 1: Nainstalujte balíček
pip install aspose-3d-fossNejsou vyžadovány žádné systémové knihovny, kompilátory ani další běhové závislosti.
Krok 2: Načíst zdrojový model
Použijte Scene.from_file() pro nejjednodušší případ: formát je detekován automaticky z přípony souboru:
from aspose.threed import Scene
scene = Scene.from_file("model.obj")Pro soubory OBJ, kde potřebujete kontrolu nad souřadnicovým systémem nebo načítáním materiálů, použijte scene.open() s 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 přístupy vytvářejí identický objekt Scene pro následný krok uložení.
Krok 3: Prohlédněte načtenou scénu
Před provedením konverze stojí za to zkontrolovat, zda se geometrie načetla správně. Chybějící soubor, nepodporovaná funkce FBX nebo problém s cestou k souboru .mtl může vést k prázdné scéně.
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")Krok 4: Uložit do cílového formátu
Zavolejte scene.save() s výstupní cestou. Předávejte objekt specifických možností uložení pro kontrolu binárního vs ASCII výstupu, souřadnicových os a komprese.
OBJ na STL (binární)
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 do 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")Chcete-li uložit jako samostatný binární GLB místo .gltf + externích bufferů, změňte výstupní příponu na .glb:
scene.save("model.glb", save_opts)OBJ do 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 na glTF 2.0
Stejný vzor platí bez ohledu na vstupní formát:
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")Krok 5: Ověřte výstup
Po uložení potvrďte, že výstupní soubor existuje a má nenulovou velikost. Pro důkladnější kontrolu jej načtěte znovu a porovnejte počty meshů:
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")Běžné problémy a opravy
Výstupní soubor je vytvořen, ale neobsahuje žádnou geometrii
Zdrojový soubor se mohl načíst s nulovým počtem meshů. Přidejte krok kontroly ze kroku 3 před uložením. Také ověřte, že přípona souboru odpovídá skutečnému formátu; Aspose.3D používá příponu k výběru parseru.
glTF výstup postrádá textury
Aspose.3D FOSS přenáší geometrii a vlastnosti materiálu během konverze. Pokud zdrojový OBJ odkazuje na externí soubory obrázků v .mtl, tyto soubory obrázků nejsou automaticky zkopírovány spolu s .gltf. Zkopírujte textury do výstupního adresáře ručně po uložení.
STL výstup vypadá uvnitř ven (normály plochy jsou převráceny)
STL neobsahuje metadata o pořadí otáčení. Pokud jsou výstupní normály obráceny, nastavte možnosti StlSaveOptions, pokud jsou k dispozici, nebo při načítání převeďte souřadnicový systém: ObjLoadOptions.flip_coordinate_system = True.
ValueError: unsupported format při ukládání
Zkontrolujte, že přípona výstupního souboru je jedna z .obj, .stl, .gltf, .glb, .dae, .3mf. Přípony jsou v Linuxu rozlišovány podle velikosti písmen.
Velmi velké soubory způsobují pomalou konverzi
Aspose.3D FOSS zpracovává geometrii v paměti. Pro soubory s miliony polygonů zajistěte dostatečnou RAM. V současné době neexistuje API pro zápis streamování.
Často kladené otázky (FAQ)
Mohu převést soubor, aniž bych jej nejprve zapsal na disk?
Ano. Oba scene.open() i scene.save() přijímají binární objekty podobné souborům kromě cest k souborům. Předávejte libovolný objekt, který implementuje read() pro načítání nebo write() pro ukládání:
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)Je FBX podporován jako vstupní formát pro konverzi?
Tokenizace FBX je částečně implementována, ale parser není kompletní. Vstup FBX může vytvářet neúplné scény. Použijte OBJ, STL, glTF, COLLADA nebo 3MF jako spolehlivé zdrojové formáty.
Přežijí materiály při konverzi OBJ na glTF?
Základní vlastnosti materiálu Phong/Lambert (difúzní barva) jsou přeneseny modelem Scene a zapsány do bloku materiálu glTF. Procedurální nebo vlastní parametry shaderu, které nelze vyjádřit v modelu materiálu glTF, jsou zahazovány.
Mohu převádět více souborů ve smyčce?
Ano. Každé volání Scene.from_file() vytvoří nezávislý objekt, takže smyčka přes seznam cest je jednoduchá:
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}")Zachovává převod hierarchii scény (rodičovské/dětské uzly)?
Ano. Strom uzlů je zachován, pokud to cílový formát umožňuje. Formáty jako STL ukládají pouze plochou geometrii bez struktury uzlů; hierarchie je při ukládání zploštěna. Formáty jako glTF a COLLADA zachovávají plnou hierarchii.