Kā ielādēt 3D modeļus Python

Kā ielādēt 3D modeļus Python

Aspose.3D FOSS for Python nodrošina vienkāršu API, lai atvērtu 3D failus bez jebkādām vietējām atkarībām. Pēc faila ielādēšanas Scene objektā jūs varat pārvietoties pa mezglu hierarhiju un nolasīt neapstrādātus ģeometrijas datus katram mesh ainas.

Soli pa solim ceļvedis

1. solis: instalēt pakotni

Instalējiet Aspose.3D FOSS no PyPI. Nav vajadzīgas papildu sistēmas bibliotēkas.

pip install aspose-3d-foss

Atbalstītās Python versijas: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12.


2. solis: Importēt Scene klasi

Scene klase ir augstākā līmeņa konteineris visiem 3D datiem. Importējiet to kopā ar jebkurām vajadzīgajām ielādes opciju klasēm.

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

Visas publiskās klases atrodas zem aspose.threed vai tās apakšpakotnēs (aspose.threed.entities, aspose.threed.formats, aspose.threed.utilities).


3. solis: Ielādēt failu

Izmantojiet statisko Scene.from_file() metodi, lai atvērtu jebkuru atbalstītu formātu. Bibliotēka automātiski nosaka formātu no faila paplašinājuma.

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

Alternatīvi izveidojiet Scene instance un izsauciet open(); noderīgi, ja vēlaties nodot ielādes opcijas vai explicitīgi apstrādāt kļūdas:

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

Abas metodes atbalsta OBJ, STL (bināro un ASCII), glTF 2.0 / GLB, COLLADA (DAE) un 3MF failus.


Solis 4: Pārlūkot ainas mezglus

Ielādēta aina ir Node objektu koks, kura sakne ir scene.root_node. Rekursīvi iterējiet, lai atrastu visus mezglus:

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)

Katrs Node var nēsāt nulles vai vairāk Entity objektus (meshes, cameras, lights). Pārbaudiet node.entities, lai redzētu, kas ir pievienots.


5. solis: Piekļūt virsotņu un daudzstūru datiem

Pārveidojiet mezgla objektu uz Mesh un nolasiet tā kontroles punktus (virsotņu pozīcijas) un daudzstūrus (seju indeksa saraksti):

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 ir saraksts ar Vector4 objektiem; x, y, z nes pozīciju, un w ir homogēnā koordināta (parasti 1.0).

mesh.polygons ir saraksts ar veselu skaitļu sarakstiem, kur katrs iekšējais saraksts ir sakārtots kontrolpunktu indeksu kopums vienam sejam.


Solis 6: Lietot formāta specifiskās ielādes iespējas

Lai iegūtu smalku kontroli pār to, kā tiek interpretēts OBJ fails, nododiet ObjLoadOptions instanci uz 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 failiem ekvivalenta klase ir StlLoadOptions. glTF gadījumā izmantojiet GltfLoadOptions. Skatiet API reference pilnu sarakstu.


Biežāk sastopamās problēmas un risinājumi

FileNotFoundError izsaucot Scene.from_file()

Ceļam jābūt absolūtam vai pareizi relatīvam attiecībā uz darba direktoriju izpildlaikā. Izmantojiet pathlib.Path, lai izveidotu uzticamus ceļus:

from pathlib import Path
from aspose.threed import Scene

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

mesh.polygons ir tukšs pēc STL faila ielādes

STL faili saglabā trīsstūrus kā neapstrādātas fasetes, nevis indeksētu režģi. Pēc ielādes poligoni tiek sintezēti no šīm fasetēm. Ja polygons ir tukšs, pārbaudiet len(mesh.control_points); ja skaitlis ir 3 reizinājums, ģeometrija tiek saglabāta neindeksētā formā, un katrs secīgs trīs virsotņu komplekts veido vienu trīsstūri.

Koordinātu sistēmas nesakritība (modelis izskatās pagriezts vai spoguļots)

Dažādi rīki izmanto dažādas konvencijas (Y‑augšup pret Z‑augšup, kreisā roka pret labo roku). Iestatiet ObjLoadOptions.flip_coordinate_system = True vai piemērojiet rotāciju saknes mezgla Transform pēc ielādes.

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

Mezgla entītiju saraksts var saturēt ne‑mesh entītijas (kameras, gaismas). Vienmēr aizsargājiet ar isinstance(entity, Mesh) pirms pārveidošanas.


Biežāk uzdotie jautājumi (BUJ)

Kādus 3D formātus es varu ielādēt?

OBJ (Wavefront), STL (binārs un ASCII), glTF 2.0 / GLB, COLLADA (DAE) un 3MF. FBX faila tokenizācija ir daļēji atbalstīta, bet pilna parsēšana vēl nav pabeigta.

Vai OBJ faila ielāde arī ielādē .mtl materiālu?

Jā, kad ObjLoadOptions.enable_materials = True (noklusējums). Bibliotēka meklē .mtl failu tajā pašā direktorijā kā .obj fails. Ja .mtl trūkst, ģeometrija joprojām tiek ielādēta un tiek izvadīts brīdinājums.

Vai varu ielādēt failu no baitu plūsmas, nevis no ceļa?

Jā. scene.open() pieņem jebkuru faila līdzīgu objektu ar .read() metodi papildus faila ceļa virknei. Nododiet atvērtu bināro straumi (piemēram, io.BytesIO) tieši. Scene.from_file() pieņem tikai faila ceļa virkni.

Kā es varu iegūt virsmas normāles?

Pēc ielādes pārbaudiet mesh.get_element(VertexElementType.NORMAL). Tas atgriež VertexElementNormal, kura data saraksts satur vienu normālu vektoru katrai atsaucei, kas kartēts saskaņā ar mapping_mode un reference_mode.

from aspose.threed.entities import Mesh, VertexElementType

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

Vai bibliotēka ir pavediena droša vairāku failu vienlaicīgai ielādei?

Katrs Scene objekts ir neatkarīgs. Atsevišķu failu ielāde atsevišķās Scene instancēs no atsevišķām pavedieniem ir droša, ja vien jūs neizdalāt vienu Scene starp pavedieniem bez ārējās bloķēšanas.

 Latviešu