Kā konvertēt 3D modeļus Python

Kā konvertēt 3D modeļus Python

Formāta konvertēšana ar Aspose.3D FOSS for Python ir divpakāpīgs process: ielādēt Scene objektā, pēc tam saglabāt vēlamajā izvades formātā. Tā kā visa ģeometrija tiek glabāta kopējā atmiņā, nav nepieciešami formātam specifiski starpposma soļi. Zemāk esošās sadaļas parāda visbiežāk sastopamās konvertācijas ar darbināmu kodu.

Rokasgrāmata soli pa solim

1. solis: instalēt pakotni

pip install aspose-3d-foss

Nav nepieciešamas sistēmas bibliotēkas, kompilatori vai papildu izpildlaika atkarības.


2. solis: ielādēt avota modeli

Izmantojiet Scene.from_file() vienkāršākajam gadījumam: formāts tiek noteikts automātiski no faila paplašinājuma:

from aspose.threed import Scene

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

OBJ failiem, kur nepieciešama kontrole pār koordinātu sistēmu vai materiālu ielādi, izmantojiet scene.open() kopā ar ObjLoadOptions:

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)

Abas pieejas rada identisku Scene objektu turpmākajam saglabāšanas solim.


3. solis: Pārbaudiet ielādēto ainu

Pirms veikt konversiju, ir vērts pārbaudīt, vai ģeometrija ir ielādēta pareizi. Trūkstošs fails, neatbalstīta FBX funkcija vai ceļa problēma ar .mtl failu var visi radīt tukšu ainu.

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. solis: Saglabāt mērķa formātā

Izsauciet scene.save() ar izvades ceļu. Nododiet formātam specifisku saglabāšanas opciju objektu, lai kontrolētu bināro un ASCII izvadi, koordinātu asis un kompresiju.

OBJ uz STL (binārs)

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 uz glTF 2.0

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

Lai saglabātu kā pašpietiekamu GLB bināro failu, nevis .gltf + ārējus buferus, mainiet izvades paplašinājumu uz .glb:

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

OBJ uz 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 uz glTF 2.0

Tas pats modelis attiecas neatkarīgi no avota formāta:

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. solis: pārbaudiet izvadi

Pēc saglabāšanas pārliecinieties, ka izvades fails pastāv un tam ir nenulles izmērs. Lai veiktu rūpīgāku pārbaudi, ielādējiet to atkārtoti un salīdziniet tīklu skaitu:

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

Biežas problēmas un risinājumi

Izvades fails ir izveidots, bet tajā nav ģeometrijas

Avota fails var būt ielādēts ar nulles tīklu. Pievienojiet pārbaudes soli no 3. soļa pirms saglabāšanas. Arī pārliecinieties, ka faila paplašinājums atbilst faktiskajam formātam; Aspose.3D izmanto paplašinājumu, lai izvēlētos parsētāju.

glTF izvade trūkst tekstūrām

Aspose.3D FOSS nēsā ģeometrijas un materiālu īpašības caur konvertēšanu. Ja avota OBJ atsaucas uz ārējiem attēlu failiem .mtl, šie attēlu faili netiek automātiski kopēti kopā ar .gltf. Kopējiet tekstūru attēlus uz izvades direktoriju manuāli pēc saglabāšanas.

STL izvade izskatās iekšpusē (virsmu normāles apgrieztas)

STL nesatur vītnes secības metadatus. Ja izvades normāles ir apgrieztas, iestatiet StlSaveOptions opcijas, ja tās ir pieejamas, vai arī apgrieziet koordinātu sistēmu ielādes laikā: ObjLoadOptions.flip_coordinate_system = True.

ValueError: unsupported format saglabājot

Pārbaudiet, vai izvades faila paplašinājums ir viens no .obj, .stl, .gltf, .glb, .dae, .3mf. Paplašinājumi ir reģistrjutīgi Linux operētājsistēmā.

Ļoti lieli faili izraisa lēnu konvertēšanu

Aspose.3D FOSS apstrādā ģeometriju atmiņā. Failiem ar miljoniem poligonu nodrošiniet pietiekamu RAM. Pašlaik nav straumēšanas rakstīšanas API.


Biežāk uzdotie jautājumi (BUJ)

Vai varu konvertēt failu, nepierakstot to uz disku vispirms?

Jā. Gan scene.open(), gan scene.save() pieņem binārus failu‑līdzīgus objektus papildus faila ceļiem. Nododiet jebkuru objektu, kas īsteno read() ielādei vai write() saglabāšanai:

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)

Vai FBX tiek atbalstīts kā avota formāts konvertēšanai?

FBX tokenizācija ir daļēji īstenota, bet parsētājs nav pabeigts. FBX ievade var radīt nepilnīgus ainas. Izmantojiet OBJ, STL, glTF, COLLADA vai 3MF kā uzticamus avota formātus.

Vai materiāli izdzīvo OBJ uz glTF konversijā?

Pamata Phong/Lambert materiāla īpašības (diffūzā krāsa) tiek pārvadātas caur Scene modeli un ierakstītas glTF materiāla blokā. Procedurālie vai pielāgotie shader parametri, kurus nevar izteikt glTF materiāla modelī, tiek izlaisti.

Vai es varu konvertēt vairākus failus ciklā?

Jā. Katrs Scene.from_file() izsaukums izveido neatkarīgu objektu, tāpēc cikls pār ceļu sarakstu ir vienkāršs:

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

Vai pārveidošana saglabā skenes hierarhiju (vecāka/bērna mezgli)?

Jā. Mezglu koks tiek saglabāts, cik vien tas ir iespējams mērķa formātā. Formāti, piemēram, STL, saglabā tikai plakanu ģeometriju bez mezglu struktūras; hierarhija tiek sablīvēta saglabāšanas laikā. Formāti, piemēram, glTF un COLLADA, saglabā pilnu hierarhiju.

 Latviešu