Sådan konverteres 3D-modeller i Python
Formatkonvertering med Aspose.3D FOSS for Python er en totrinsproces: indlæs i et Scene‑objekt, og gem derefter i det ønskede outputformat. Da al geometri holdes i en fælles in‑memory‑repræsentation, er der ingen format‑specifikke mellemliggende trin nødvendige. Sektionerne nedenfor viser de mest almindelige konverteringer med fungerende kode.
Trin-for-trin guide
Trin 1: Installer pakken
pip install aspose-3d-fossIngen systembiblioteker, compilere eller yderligere runtime-afhængigheder er påkrævet.
Trin 2: Indlæs kilde-modellen
Brug Scene.from_file() til det enkleste tilfælde: formatet opdages automatisk ud fra filendelsen:
from aspose.threed import Scene
scene = Scene.from_file("model.obj")For OBJ‑filer, hvor du har brug for kontrol over koordinatsystemet eller materialelæsning, brug scene.open() med 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)Begge tilgange producerer et identisk Scene-objekt til det efterfølgende gemmestrin.
Trin 3: Inspicer den indlæste scene
Før du foretager en konvertering, er det værd at tjekke, at geometrien er indlæst korrekt. En manglende fil, en ikke‑understøttet FBX‑funktion eller et sti‑problem med en .mtl‑fil kan alle producere en tom scene.
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")Trin 4: Gem i målformatet
Kald scene.save() med outputstien. Overfør et format‑specifikt gemmeindstillingsobjekt for kontrol over binær vs ASCII‑output, koordinatakser og komprimering.
OBJ til STL (binær)
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 til 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")For at gemme som en selvstændig GLB-binær i stedet for en .gltf + eksterne buffere, skal du ændre output‑filendelsen til .glb:
scene.save("model.glb", save_opts)OBJ til 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 til glTF 2.0
Det samme mønster gælder uanset kildeformat:
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")Trin 5: Verificer outputtet
Efter at have gemt, bekræft at outputfilen findes og har en størrelse større end nul. For en mere grundig kontrol, genindlæs den og sammenlign mesh-antal:
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")Almindelige problemer og rettelser
Outputfilen er oprettet, men indeholder ingen geometri
Kildefilen kan være indlæst med nul mesh. Tilføj inspektionstrinnet fra trin 3 før du gemmer. Bekræft også, at filendelsen svarer til det faktiske format; Aspose.3D bruger endelsen til at vælge parseren.
glTF output mangler teksturer
Aspose.3D FOSS overfører geometri‑ og materialegenskaber gennem konvertering. Hvis kilde‑OBJ’en refererer til eksterne billedfiler i .mtl, kopieres disse billedfiler ikke automatisk sammen med .gltf. Kopier teksturbilleder til output‑mappen manuelt efter gemning.
STL-output ser indvendigt ud (flippede flade normaler)
STL indeholder ikke metadata om winding-order. Hvis outputnormalerne er inverteret, skal du indstille StlSaveOptions-indstillinger, hvis de er tilgængelige, eller vende koordinatsystemet under indlæsning: ObjLoadOptions.flip_coordinate_system = True.
ValueError: unsupported format ved lagring
Kontroller, at outputfilens filendelse er en af .obj, .stl, .gltf, .glb, .dae, .3mf. Filendelser er case‑sensitiv på Linux.
Meget store filer forårsager langsom konvertering
Aspose.3D FOSS behandler geometri i hukommelsen. For filer med millioner af polygoner, sørg for tilstrækkelig RAM. Der er i øjeblikket ingen streaming-write API.
Ofte stillede spørgsmål (FAQ)
Kan jeg konvertere en fil uden at skrive den til disk først?
Ja. Både scene.open() og scene.save() accepterer binære fil‑lignende objekter ud over filstier. Videregiv ethvert objekt, der implementerer read() til indlæsning eller write() til lagring:
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)Er FBX understøttet som kildeformat til konvertering?
FBX-tokenisering er delvist implementeret, men parseren er ikke fuldstændig. FBX-inddata kan producere ufuldstændige scener. Brug OBJ, STL, glTF, COLLADA eller 3MF som pålidelige kildeformater.
Vil materialer overleve en OBJ-til-glTF konvertering?
Grundlæggende Phong/Lambert-materialegenskaber (diffus farve) overføres gennem Scene-modellen og skrives ind i glTF-materialeblokken. Procedurale eller brugerdefinerede shaderparametre, der ikke kan udtrykkes i glTF-materialemodellen, droppes.
Kan jeg konvertere flere filer i en løkke?
Ja. Hvert Scene.from_file()‑kald opretter et uafhængigt objekt, så en løkke over en liste over stier er ligetil:
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}")Bevarer konverteringen scenens hierarki (forældre/børne‑noder)?
Ja. Nodetræet bevares så vidt som målformatet tillader. Formater som STL gemmer kun flad geometri uden nodestruktur; hierarkiet flades ud ved lagring. Formater som glTF og COLLADA bevarer det fulde hierarki.