Kaip konvertuoti 3D modelius naudojant Python
Formato konvertavimas su Aspose.3D FOSS for Python yra dviejų žingsnių procesas: įkelti į Scene objektą, tada išsaugoti į norimą išvesties formatą. Kadangi visa geometrija saugoma bendroje atminties reprezentacijoje, nėra reikalingi formatui specifiniai tarpiniai žingsniai. Žemiau pateiktos skiltys rodo dažniausiai pasitaikančius konvertavimus su veikiamu kodu.
Žingsnis po žingsnio vadovas
Žingsnis 1: Įdiekite paketą
pip install aspose-3d-fossNereikia jokių sisteminių bibliotekų, kompiliatorių ar papildomų vykdymo laiko priklausomybių.
Žingsnis 2: Įkelti šaltinio modelį
Naudokite Scene.from_file() paprasčiausiam atvejui: formatas automatiškai nustatomas pagal failo plėtinį:
from aspose.threed import Scene
scene = Scene.from_file("model.obj")OBJ failams, kai reikia valdyti koordinačių sistemą arba medžiagų įkėlimą, naudokite scene.open() su 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)Abu metodai sukuria identišką Scene objektą vėlesniam įrašymo žingsniui.
Žingsnis 3: Peržiūrėkite įkeltą sceną
Prieš pradedant konvertavimą, verta patikrinti, ar geometrija įkelta teisingai. Trūkstamas failas, nepalaikoma FBX funkcija arba kelio problema su .mtl failu gali sukelti tuščią sceną.
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")Žingsnis 4: Išsaugoti į tikslinį formatą
Iškvieskite scene.save() su išvesties keliu. Perduokite formatui specifinį išsaugojimo parinkčių objektą, kad kontroliuotumėte dvejetainį ir ASCII išvestį, koordinačių ašis ir suspaudimą.
OBJ į STL (binari)
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")Norėdami išsaugoti kaip savarankišką GLB binarinį failą, o ne .gltf + išorinius buferius, pakeiskite išvesties plėtinį į .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
Tas pats modelis taikomas nepriklausomai nuo šaltinio formato:
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")Žingsnis 5: Patikrinkite išvestį
Po išsaugojimo patikrinkite, ar išvesties failas egzistuoja ir turi ne nulinį dydį. Daugiau išsamiai patikrinimui įkelkite jį iš naujo ir palyginkite tinklo skaičius:
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")Dažnos problemos ir sprendimai
Išvesties failas sukurtas, bet neturi geometrijos
Šaltinio failas gali būti įkeltas be jokių tinklų. Prieš išsaugojant pridėkite patikrinimo žingsnį iš 3 žingsnio. Taip pat patikrinkite, ar failo plėtinys atitinka faktinį formatą; Aspose.3D naudoja plėtinį, kad pasirinktų analizatorių.
glTF išvestyje trūksta tekstūrų
Aspose.3D FOSS perkelia geometrijos ir medžiagų savybes konvertavimo metu. Jei šaltinio OBJ nurodo išorinius vaizdo failus .mtl, šie vaizdo failai nėra automatiškai kopijuojami kartu su .gltf. Rankiniu būdu nukopijuokite tekstūros vaizdus į išvesties katalogą po išsaugojimo.
STL išvestis atrodo iš vidaus į išorę (veido normalės apverstos)
STL neperduoda vėjimo tvarkos metaduomenų. Jei išvesties normalės yra apverstos, nustatykite StlSaveOptions parinktis, jei jos prieinamos, arba perkelkite koordinačių sistemą įkrovimo metu: ObjLoadOptions.flip_coordinate_system = True.
ValueError: unsupported format išsaugant
Patikrinkite, ar išvesties failo plėtinys yra vienas iš .obj, .stl, .gltf, .glb, .dae, .3mf. Plėtiniai Linux sistemoje yra jautrūs raidžių dydžiui.
Labai dideli failai sukelia lėtą konvertavimą
Aspose.3D FOSS apdoroja geometriją atmintyje. Failams su milijonais daugiakampių įsitikinkite, kad turite pakankamai RAM. Šiuo metu nėra srautinio rašymo API.
Dažniausiai užduodami klausimai (DUK)
Ar galiu konvertuoti failą be jo įrašymo į diską pirmiausia?
Taip. Tiek scene.open(), tiek scene.save() priima dvejetainius failų tipo objektus, be failų kelių. Perduokite bet kurį objektą, kuris įgyvendina read() įkėlimui arba write() išsaugojimui:
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)Ar FBX palaikomas kaip šaltinio formatas konvertavimui?
FBX tokenizavimas yra dalinai įgyvendintas, tačiau analizatorius nėra baigtas. FBX įvestis gali sukurti nepilnas scenas. Naudokite OBJ, STL, glTF, COLLADA arba 3MF kaip patikimus šaltinio formatus.
Ar medžiagos išliks OBJ-to-glTF konversijoje?
Pagrindinės Phong/Lambert medžiagos savybės (difuzinė spalva) yra perduodamos per Scene modelį ir įrašomos į glTF medžiagos bloką. Procedūriniai arba pasirinktiniai šešėlių parametrai, kurių negalima išreikšti glTF medžiagos modelyje, atmesti.
Ar galiu konvertuoti kelis failus cikle?
Taip. Kiekvienas Scene.from_file() iškvietimas sukuria nepriklausomą objektą, todėl kilpa per kelių sąrašą yra paprasta:
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}")Ar konvertavimas išsaugo scenos hierarchiją (tėvų/vaikų mazgus)?
Taip. Mazgų medis išsaugomas tiek, kiek leidžia paskirties formatas. Formatai kaip STL saugo tik plokščią geometriją be mazgų struktūros; hierarchija išlyginta išsaugojant. Formatai kaip glTF ir COLLADA išlaiko visą hierarchiją.