Kuinka muuntaa 3D-mallit Pythonilla

Kuinka muuntaa 3D-mallit Pythonilla

Muodon muuntaminen Aspose.3D FOSS for Pythonilla on kaksivaiheinen prosessi: ladataan Scene-objektiin, jonka jälkeen tallennetaan haluttuun lähtömuotoon. Koska kaikki geometria on tallennettu yhteiseen muistissa olevaan esitykseen, formaattikohtaisia välivaiheita ei tarvita. Alla olevat osiot esittelevät yleisimmät muunnokset toimivan koodin kanssa.

Vaiheittainen opas

Vaihe 1: Asenna paketti

pip install aspose-3d-foss

Järjestelmäkirjastoja, kääntäjiä tai lisäajonaikaisia riippuvuuksia ei tarvita.


Vaihe 2: Lataa lähdemalli

Käytä Scene.from_file() yksinkertaisimmassa tapauksessa: formaatti tunnistetaan automaattisesti tiedostopäätteestä:

from aspose.threed import Scene

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

OBJ‑tiedostoja varten, kun tarvitset hallintaa koordinaatistojärjestelmästä tai materiaalin lataamisesta, käytä scene.open() yhdessä ObjLoadOptions kanssa:

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)

Molemmat lähestymistavat tuottavat identtisen Scene-objektin seuraavaa tallennusvaihetta varten.


Vaihe 3: Tarkastele ladattua kohtaa

Ennen muunnoksen tekemistä kannattaa tarkistaa, että geometria latautui oikein. Puuttuva tiedosto, tukematon FBX-ominaisuus tai polkuongelma .mtl-tiedoston kanssa voivat kaikki aiheuttaa tyhjän kohtauksen.

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

Vaihe 4: Tallenna kohdeformaattiin

Kutsu scene.save() lähtöpolulla. Anna formaattiin spesifinen tallennusasetusten objekti binäärisen ja ASCII-tulosteen, koordinaattiakselien ja pakkaamisen hallitsemiseksi.

OBJ → STL (binäärinen)

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

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

Tallentaaksesi itse sisältävänä GLB-binäärinä .gltf + ulkoisten puskurien sijaan, muuta tulosteen tiedostopäätettä .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

Sama malli pätee riippumatta lähdeformaatista:

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

Vaihe 5: Vahvista tulos

Kun tallennus on suoritettu, vahvista, että tulostiedosto on olemassa eikä sen koko ole nolla. Tarkempaa tarkistusta varten lataa se uudelleen ja vertaa mesh-määriä:

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

Yleisiä ongelmia ja korjauksia

Tulostetiedosto luodaan, mutta se ei sisällä geometriaa

Lähdetiedosto on saattanut latautua ilman mesh-objekteja. Lisää tarkistusvaihe vaiheesta 3 ennen tallentamista. Varmista myös, että tiedostopääte vastaa todellista formaattia; Aspose.3D käyttää päätettä parserin valitsemiseen.

glTF-tulosteesta puuttuvat tekstuurit

Aspose.3D FOSS siirtää geometria- ja materiaalipropetioita konversiosta. Jos lähde‑OBJ viittaa ulkoisiin kuvatiedostoihin .mtl, näitä kuvatiedostoja ei automaattisesti kopioida .gltf mukana. Kopioi tekstuurikuvat käsin tulostushakemistoon tallentamisen jälkeen.

STL-tuloste näyttää sisäpuolelta (kasvojen normaalit käännetty)

STL ei sisällä kierrejärjestyksen metatietoja. Jos tulosteen normaalit ovat käännettyjä, aseta StlSaveOptions -asetukset, jos ne ovat saatavilla, tai käännä koordinaatisto latauksen aikana: ObjLoadOptions.flip_coordinate_system = True.

ValueError: unsupported format tallennettaessa

Tarkista, että tulostetiedoston tiedostopääte on yksi seuraavista: .obj, .stl, .gltf, .glb, .dae, .3mf. Pääteet ovat kirjainkoolla riippuvaisia Linuxissa.

Erittäin suuret tiedostot aiheuttavat hidasta muuntamista

Aspose.3D FOSS käsittelee geometriaa muistissa. Miljoonien polygonien sisältävissä tiedostoissa varmista riittävä RAM. Tällä hetkellä ei ole streaming-write API.


Usein kysytyt kysymykset (UKK)

Voinko muuntaa tiedoston kirjoittamatta sitä ensin levylle?

Kyllä. Sekä scene.open() että scene.save() hyväksyvät binaarisia tiedostomaisia objekteja tiedostopolkujen lisäksi. Anna mikä tahansa objekti, joka toteuttaa read() lataamista varten tai write() tallentamista varten:

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)

Onko FBX tuettu lähdeformaattina muunnokselle?

FBX-tokenisointi on osittain toteutettu, mutta jäsentäjä ei ole valmis. FBX-syöte saattaa tuottaa puutteellisia kohtauksia. Käytä OBJ-, STL-, glTF-, COLLADA- tai 3MF-muotoja luotettavina lähdeformaatteina.

Selviytyvätkö materiaalit OBJ-to-glTF -muunnoksessa?

Perus Phong/Lambert -materiaalin ominaisuudet (diffuusiväri) siirretään Scene -mallin kautta ja kirjoitetaan glTF-materiaalilohkoon. Proceduraaliset tai mukautetut shader-parametrit, joita ei voida ilmaista glTF-materiaalimallissa, hylätään.

Voinko muuntaa useita tiedostoja silmukassa?

Kyllä. Jokainen Scene.from_file()-kutsu luo itsenäisen objektin, joten silmukka polkujen listan yli on suoraviivaista:

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

Säilyttääkö muunnos kohtauksen hierarkian (vanhempi/lapsi-solmut)?

Kyllä. Solmupuu säilytetään niin pitkälle kuin kohdeformaatti sallii. STL:n kaltaiset formaatit tallentavat vain tasaisen geometrian ilman solmurakennetta; hierarkia litistetään tallennuksen yhteydessä. glTF:n ja COLLADA:n kaltaiset formaatit säilyttävät täyden hierarkian.

 Suomi