Kuinka ladata 3D-mallit Python:ssa

Kuinka ladata 3D-mallit Python:ssa

Aspose.3D FOSS for Python tarjoaa suoraviivaisen API:n 3D‑tiedostojen avaamiseen ilman natiiviriippuvuuksia. Kun tiedosto on ladattu Scene objektiin, voit käydä solmuhierarkian läpi ja lukea raakageometriatiedot jokaisesta verkosta (mesh) 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

The Scene luokka on ylimmän tason säiliö kaikille 3D‑datalle. Tuo se yhdessä kaikkien tarvitsemiesi latausvaihtoehtoluokkien kanssa.

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

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


Vaihe 3: Lataa tiedosto

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

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

Vaihtoehtoisesti luo Scene instanssin ja kutsu open(); hyödyllinen, kun haluat välittää latausvaihtoehtoja 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 Scene-solmut

Ladattu kohtaus on puu, jonka solmut ovat Node objekteja, joiden juuri on scene.root_node. Käy rekursiivisesti läpi 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 sisältää nolla tai useampia Entity objekteja (meshes, cameras, lights). Tarkista node.entities tarkista, mitä on liitetty.


Vaihe 5: Pääsy Vertex- ja Polygon-tietoihin

Muunna solmun entiteetti tyyppiin Mesh ja lue sen control points (vertex positions) ja polygons (face index lists):

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 kantaa sijaintia ja w on homogeeninen koordinaatti (yleensä 1.0).

mesh.polygons on luettelo kokonaislukulistoja, joissa jokainen sisempi lista on yhden pinnan ohjauspisteindeksien järjestetty joukko.


Vaihe 6: Käytä formaattiin spesifisiä latausvaihtoehtoja

Hienojakoista hallintaa siitä, miten OBJ‑tiedosto tulkitaan, anna 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 täydellistä luetteloa varten.


Yleisiä ongelmia ja korjauksia

FileNotFoundError kutsuttaessa Scene.from_file()

Polun on oltava absoluuttinen tai oikea suhteessa suorituskansion kanssa ajon aikana. Käytä pathlib.Path luomaan 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 raakapintoina, eivät indeksoituna verkona. Latauksen jälkeen polygonit syntetisoidaan näistä pinnoista. Jos polygons näyttää tyhjältä, 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 epäsopivuus (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 soveltaa kiertoa juurisolmun Transform lataamisen jälkeen.

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

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


Usein kysytyt kysymykset (UKK)

Mitkä 3D-formaatit voin ladata?

OBJ (Wavefront), STL (binääri- ja 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-tiedostoa ladattaessa myös .mtl materiaali?

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() metodi tiedostopolku-merkkijonon lisäksi. Anna avoin binäärivirta (esim.., io.BytesIO) suoraan. Scene.from_file() hyväksyy vain tiedostopolku-merkkijonon.

Kuinka 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, kartoitettu seuraavasti mapping_mode ja reference_mode.

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, kun ladataan useita tiedostoja samanaikaisesti?

Jokainen Scene objekti on itsenäinen. Ladataan erillisiä tiedostoja erillisiin Scene instanssit erillisistä säikeistä ovat turvallisia, kunhan et jaa yhtä Scene säikeiden välillä ilman ulkoista lukitusta.

 Suomi