3D modellek konvertálása Pythonban

3D modellek konvertálása Pythonban

Az Aspose.3D FOSS for Python használatával a formátumkonverzió kétlépéses folyamat: betöltés egy Scene objektumba, majd mentés a kívánt kimeneti formátumba. Mivel az összes geometria egy közös memóriabeli reprezentációban van tárolva, nincs szükség formátumspecifikus köztes lépésekre. Az alábbi szakaszok a leggyakoribb konverziókat mutatják működő kóddal.

Lépésről‑lépésre útmutató

1. lépés: A csomag telepítése

pip install aspose-3d-foss

Nem szükségesek rendszerkönyvtárak, fordítók vagy további futásidejű függőségek.


2. lépés: Forrásmodell betöltése

Használja a Scene.from_file()-t a legegyszerűbb esetben: a formátum automatikusan a fájlkiterjesztésből kerül felismerésre:

from aspose.threed import Scene

scene = Scene.from_file("model.obj")

OBJ fájlok esetén, amikor a koordináta‑rendszer vagy az anyagbetöltés felett ellenőrzésre van szükség, használja a scene.open()‑t a ObjLoadOptions‑val:

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)

Mindkét megközelítés azonos Scene objektumot hoz létre a következő mentési lépéshez.


3. lépés: A betöltött jelenet ellenőrzése

Mielőtt konverzióra vállalkozna, érdemes ellenőrizni, hogy a geometria helyesen betöltődött‑e. Egy hiányzó fájl, egy nem támogatott FBX funkció, vagy egy útvonalprobléma egy .mtl fájllal mind üres jelenetet eredményezhet.

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. lépés: Mentés a célformátumba

Hívja meg a scene.save()-t a kimeneti útvonallal. Adjon át egy formátum-specifikus mentési beállítási objektumot a bináris és ASCII kimenet, a koordináta tengelyek és a tömörítés szabályozásához.

OBJ STL-re (bináris)

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-ra

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")

A self-contained GLB bináris mentéséhez a .gltf + külső pufferek helyett, módosítsa a kimeneti kiterjesztést .glb-re:

scene.save("model.glb", save_opts)

OBJ 3MF-be

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

Ugyanez a minta alkalmazandó a forrásformátumtól függetlenül:

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. lépés: Ellenőrizze a kimenetet

Mentés után ellenőrizze, hogy a kimeneti fájl létezik-e, és nem nulla méretű. Egy alaposabb ellenőrzéshez töltse be újra, és hasonlítsa össze a hálózatszámokat:

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")

Gyakori problémák és megoldások

Kimeneti fájl létrejött, de nem tartalmaz geometriát

A forrásfájl nulla hálóval töltődhet be. Adja hozzá a 3. lépésben szereplő ellenőrzési lépést a mentés előtt. Ellenőrizze továbbá, hogy a fájlkiterjesztés megegyezik-e a tényleges formátummal; az Aspose.3D a kiterjesztést használja a parser kiválasztásához.

A glTF kimenetben hiányoznak a textúrák

Aspose.3D FOSS a geometriai és anyagtulajdonságokat átviszi a konverzió során. Ha a forrás OBJ külső képfájlokra hivatkozik a .mtl-ben, azok a képfájlok nem kerülnek automatikusan másolásra a .gltf mellett. A textúra képeket manuálisan másolja a kimeneti könyvtárba a mentés után.

Az STL kimenet belülről kifelé néz (a felületi normálok megfordultak)

Az STL nem tartalmaz winding-order metaadatot. Ha a kimeneti normálok fordítottak, állítsa be a StlSaveOptions opciókat, ha elérhetők, vagy fordítsa meg a koordináta‑rendszert betöltéskor: ObjLoadOptions.flip_coordinate_system = True.

ValueError: unsupported format mentéskor

Ellenőrizze, hogy a kimeneti fájlkiterjesztés a következők egyike: .obj, .stl, .gltf, .glb, .dae, .3mf. A kiterjesztések Linuxon kis- és nagybetűérzékenyek.

Nagyon nagy fájlok lassú konvertálást okoznak

Aspose.3D FOSS a geometriát memóriában dolgozza fel. Milliók polygonokkal rendelkező fájlok esetén biztosítson elegendő RAM-ot. Jelenleg nincs streaming-írási API.


Gyakran Ismételt Kérdések (GYIK)

Átalakíthatok egy fájlt anélkül, hogy először lemezre írnám?

Igen. A scene.open() és a scene.save() egyaránt elfogad bináris fájl-szerű objektumokat a fájlútvonalak mellett. Adjon át bármilyen objektumot, amely implementálja a read()‑t a betöltéshez vagy a write()‑t a mentéshez:

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)

Támogatott-e az FBX forrásformátum konvertáláshoz?

Az FBX tokenizálása részben megvalósult, de a parser nem teljes. Az FBX bemenet hiányos jeleneteket eredményezhet. Használjon OBJ, STL, glTF, COLLADA vagy 3MF formátumokat megbízható forrásként.

Megmaradnak az anyagok egy OBJ‑ről glTF‑re konverzió során?

Az alapvető Phong/Lambert anyagtulajdonságok (szórt szín) átkerülnek a Scene modellbe, és a glTF anyagblokkba íródnak. A glTF anyagmodellben kifejezhetetlen eljárásos vagy egyedi shader paraméterek elhagyásra kerülnek.

Konvertálhatok több fájlt egy ciklusban?

Igen. Minden Scene.from_file() hívás egy független objektumot hoz létre, ezért egy útvonalak listáján való ciklus egyszerű:

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}")

Megőrzi a konverzió a jelenet hierarchiáját (szülő/gyermek csomópontok)?

Igen. A csomópontfa megmarad, amennyire a célformátum lehetővé teszi. Az STL-hez hasonló formátumok csak sík geometriát tárolnak csomópontstruktúra nélkül; a hierarchia mentéskor laposra kerül. A glTF-hez és a COLLADA-hoz hasonló formátumok megőrzik a teljes hierarchiát.

 Magyar