Kuinka ladata 3D-malleja Pythonissa

Kuinka ladata 3D-malleja Pythonissa

Aspose.3D FOSS for Python tarjoaa suoraviivaisen API:n 3D-tiedostojen avaamiseen ilman natiiviriippuvuuksia. Kun tiedosto on ladattu Scene-objektiin, voit käydä läpi soluhierarkian ja lukea raakageometriset tiedot jokaisesta meshistä kohtauksessa.

Vaiheittainen opas

Vaihe 1: Asenna paketti

Asenna Aspose.3D FOSS PyPI:stä. Lisäjärjestelmäkirjastoja ei tarvita.

pip install aspose-3d-foss

Tuetut Python-versiot: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


Vaihe 2: Tuo Scene-luokka

Scene-luokka on ylimmän tason säiliö kaikelle 3D‑datalle. Tuo se yhdessä kaikkien tarvitsemiesi latausvaihtoehto‑luokkien kanssa.

from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions

Kaikki julkiset luokat sijaitsevat aspose.threed:n alla tai sen alipaketeissa (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).


Vaihe 3: Lataa tiedosto

Käytä staattista Scene.from_file()-metodia avata minkä tahansa tuetun formaatin. Kirjasto havaitsee formaatin automaattisesti tiedostopäätteestä.

##Automatic format detection
scene = Scene.from_file("model.obj")

Vaihtoehtoisesti luo Scene-instanssi ja kutsu open(); hyödyllistä, kun haluat välittää latausasetuksia tai käsitellä virheitä eksplisiittisesti:

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

Molemmat menetelmät tukevat OBJ, STL (binääri- ja ASCII), glTF 2.0 / GLB, COLLADA (DAE) ja 3MF‑tiedostoja.


Vaihe 4: Käy läpi kohtauksen solmut

Ladattu kohtaus on Node-objektien puu, jonka juuri on scene.root_node. Toista rekursiivisesti löytääksesi kaikki solmut:

from aspose.threed import Scene, Node

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

def walk(node: Node, depth: int = 0) -> None:
    indent = "  " * depth
    print(f"{indent}Node: {node.name!r}")
    for child in node.child_nodes:
        walk(child, depth + 1)

walk(scene.root_node)

Jokainen Node voi kantaa nolla tai useampia Entity-objekteja (verkkoja, kameroita, valoja). Tarkista node.entities nähdäksesi, mitä on liitetty.


Vaihe 5: Pääsy solmu- ja monikulmiotietoihin

Muunna solmun entiteetti Mesh:ksi ja lue sen ohjauspisteet (solmujen sijainnit) ja polygonit (kasvojen indeksilistat):

from aspose.threed import Scene
from aspose.threed.entities import Mesh

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

for node in scene.root_node.child_nodes:
    for entity in node.entities:
        if isinstance(entity, Mesh):
            mesh: Mesh = entity
            print(f"Mesh '{node.name}': "
                  f"{len(mesh.control_points)} vertices, "
                  f"{len(mesh.polygons)} polygons")

            # First vertex position
            if mesh.control_points:
                v = mesh.control_points[0]
                print(f"  First vertex: ({v.x:.4f}, {v.y:.4f}, {v.z:.4f})")

            # First polygon face (list of control-point indices)
            if mesh.polygons:
                print(f"  First polygon: {mesh.polygons[0]}")

mesh.control_points on luettelo Vector4-objekteja; x, y, z sisältävät sijainnin ja w on homogeeninen koordinaatti (normaalisti 1.0).

mesh.polygons on listojen lista kokonaislukuja, jossa jokainen sisempi lista on yhden pinnan ohjauspisteindeksien järjestetty joukko.


Vaihe 6: Käytä formaattiin liittyviä latausasetuksia

Saadaksesi hienojakoista hallintaa siitä, miten OBJ‑tiedosto tulkitaan, lähetä ObjLoadOptions‑instanssi scene.open():

from aspose.threed import Scene
from aspose.threed.formats import ObjLoadOptions

options = ObjLoadOptions()
options.flip_coordinate_system = True   # Convert right-hand Y-up to Z-up
options.scale = 0.01                    # Convert centimetres to metres
options.enable_materials = True         # Load .mtl material file
options.normalize_normal = True         # Normalize all normals to unit length

scene = Scene()
scene.open("model.obj", options)

STL‑tiedostoille vastaava luokka on StlLoadOptions. glTF:lle käytä GltfLoadOptions. Katso API‑viite saadaksesi täydellisen luettelon.


Yleisiä ongelmia ja korjauksia

FileNotFoundError kutsuttaessa Scene.from_file()

Polun on oltava absoluuttinen tai oikea suhteessa suorituksen aikana olevaan työhakemistoon. Käytä pathlib.Path luodaksesi luotettavia polkuja:

from pathlib import Path
from aspose.threed import Scene

path = Path(__file__).parent / "assets" / "model.obj"
scene = Scene.from_file(str(path))

mesh.polygons on tyhjä STL‑tiedoston lataamisen jälkeen

STL‑tiedostot tallentavat kolmiot raakapinnana, eivät indeksoituna verkona. Latauksen jälkeen monikulmiot syntetisoidaan näistä pinnoista. Jos polygons on tyhjä, tarkista len(mesh.control_points); jos lukumäärä on 3:n monikerta, geometria on tallennettu indeksoimattomassa muodossa ja jokainen peräkkäinen kolmen kärjen ryhmä muodostaa yhden kolmion.

Koordinaatistojärjestelmän ristiriita (malli näyttää kiertyneen tai peilikuvana)

Eri työkalut käyttävät erilaisia konventioita (Y‑ylös vs Z‑ylös, vasen käsi vs oikea käsi). Aseta ObjLoadOptions.flip_coordinate_system = True tai sovella kiertoa juurisolmun Transform jälkeen latauksen.

AttributeError: 'NoneType' object has no attribute 'polygons'

Solmun entiteettiluettelo saattaa sisältää ei‑verkkoentiteettejä (kamerat, valot). Suojaa aina isinstance(entity, Mesh) ennen muunnosta.


Usein kysytyt kysymykset (UKK)

Mitä 3D‑muotoja voin ladata?

OBJ (Wavefront), STL (binary and ASCII), glTF 2.0 / GLB, COLLADA (DAE) ja 3MF. FBX-tiedoston tokenisointi on osittain tuettu, mutta täysi jäsentäminen ei ole vielä valmis.

Ladataanko OBJ‑tiedoston lataus myös .mtl‑materiaalin?

Kyllä, kun ObjLoadOptions.enable_materials = True (oletus). Kirjasto etsii .mtl‑tiedostoa samasta hakemistosta kuin .obj‑tiedosto. Jos .mtl puuttuu, geometria ladataan silti ja varoitus annetaan.

Voinko ladata tiedoston tavujonosta polun sijaan?

Kyllä. scene.open() hyväksyy minkä tahansa tiedostomaiseen objektin, jossa on .read()-menetelmä, lisäksi tiedostopolun merkkijono. Välitä avoin binaarinen virta (esim. io.BytesIO) suoraan. Scene.from_file() hyväksyy vain tiedostopolun merkkijonon.

Miten saan pinnan normaalit?

Lataamisen jälkeen tarkista mesh.get_element(VertexElementType.NORMAL). Tämä palauttaa VertexElementNormal, jonka data-lista sisältää yhden normaalivektorin per viite, kartoitetun mapping_mode ja reference_mode mukaisesti.

from aspose.threed.entities import Mesh, VertexElementType

normals = mesh.get_element(VertexElementType.NORMAL)
if normals:
    print(normals.data[0])  # First normal vector

Onko kirjasto säikeiturvallinen useiden tiedostojen samanaikaista lataamista varten?

Jokainen Scene-objekti on itsenäinen. Erillisten tiedostojen lataaminen erillisiin Scene-instansseihin eri säikeistä on turvallista, kunhan et jaa yhtä Scene-objektia säikeiden välillä ilman ulkoista lukitusta.

 Suomi