Funksjoner og funksjonalitet

Funksjoner og funksjonalitet

Aspose.3D FOSS for Python gir et komplett scene‑graf API for å lese, konstruere og skrive 3D‑innhold i flere bransjestandardformater. Denne siden dokumenterer hvert viktig funksjonsområde med fungerende Python kodeeksempler som bruker det faktiske bibliotek‑API‑et.

Installasjon og oppsett

Installer biblioteket fra PyPI med en enkelt kommando:

pip install aspose-3d-foss

Ingen ekstra systempakker, native utvidelser eller kompilatorverktøykjeder er påkrevd. Biblioteket er ren Python og støtter Python 3.7 til 3.12 på Windows, macOS og Linux.

For å verifisere installasjonen:

from aspose.threed import Scene

scene = Scene()
print("Aspose.3D FOSS installed successfully")
print(f"Root node name: {scene.root_node.name}")

Funksjoner og funksjonalitet

Formatstøtte

Aspose.3D FOSS for Python leser og skriver følgende formater:

FormatFiltypeLesSkrivNotater
Wavefront OBJ.objJaJa.mtl-materiallasting støttes
STL (binær).stlJaJaRundtur verifisert (39 tester)
STL (ASCII).stlJaJaRundtur verifisert
glTF 2.0.gltfJaJaFullt scenegraf bevart
GLB (binær glTF).glbJaJaEnkeltfil binær beholder
COLLADA.daeJaJaSceneshierarki og materialer
3MF.3mfJaJaAdditivt produksjonsformat
FBX.fbxDelvisNeiTokenizer fungerer; parser har kjente feil

Laste inn OBJ med alternativer

ObjLoadOptions styrer hvordan OBJ-filer blir tolket:

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

options = ObjLoadOptions()
options.enable_materials = True        # Load accompanying .mtl file
options.flip_coordinate_system = False # Preserve original handedness
options.normalize_normal = True        # Normalize vertex normals to unit length
options.scale = 1.0                    # Apply a uniform scale factor at load time

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

print(f"Loaded {len(scene.root_node.child_nodes)} top-level nodes")

Lagring til STL

StlSaveOptions styrer binær vs. ASCII-utdata og andre STL-spesifikke innstillinger:

from aspose.threed import Scene
from aspose.threed.formats import StlSaveOptions

scene = Scene.from_file("model.obj")
options = StlSaveOptions()
scene.save("output.stl", options)

Scenegraf

Alt 3D-innhold er organisert som et tre av Node objekter. Roten av treet er scene.root_node. Hver node kan inneholde undernoder og bære en Entity (mesh, kamera eller lys) pluss en Transform.

Traversere scenehierarkiet

from aspose.threed import Scene

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

def traverse(node, depth=0):
    indent = "  " * depth
    entity_type = type(node.entity).__name__ if node.entity else "none"
    print(f"{indent}{node.name} [{entity_type}]")
    for child in node.child_nodes:
        traverse(child, depth + 1)

traverse(scene.root_node)

Bygge en scene programmatisk

from aspose.threed import Scene, Node, Entity
from aspose.threed.entities import Mesh
from aspose.threed.utilities import Vector3

scene = Scene()
root = scene.root_node

##Create a child node and position it
child = root.create_child_node("my_object")
child.transform.translation = Vector3(1.0, 0.0, 0.0)
child.transform.scaling = Vector3(2.0, 2.0, 2.0)

scene.save("constructed.glb")

Inspisere GlobalTransform

GlobalTransform gir verdensromtransformasjonen til en node etter å ha akkumulert alle overordnede transformasjoner:

from aspose.threed import Scene

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

for node in scene.root_node.child_nodes:
    gt = node.global_transform
    print(f"Node: {node.name}")
    print(f"  World translation: {gt.translation}")
    print(f"  World scale: {gt.scale}")

Mesh API

Den Mesh Entiteten gir tilgang til geometridata inkludert kontrollpunkter (vertices), polygoner, og vertex-elementer for normaler, UV-er og farger.

Lese Mesh-geometri

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

options = ObjLoadOptions()
options.enable_materials = True
options.flip_coordinate_system = False

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

for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity
    print(f"Mesh: {node.name}")
    print(f"  Vertices: {len(mesh.control_points)}")
    print(f"  Polygons: {len(mesh.polygons)}")

Tilgang til vertex-elementer

Vertex-elementer inneholder data per vertex eller per polygon. De mest vanlige elementene er normaler, UV-koordinater, vertex-farger og jevningsgrupper:

from aspose.threed import Scene
from aspose.threed.entities import VertexElementNormal, VertexElementUV

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

for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity

    # Iterate vertex elements to find normals and UVs
    for element in mesh.vertex_elements:
        if isinstance(element, VertexElementNormal):
            print(f"  Normals count: {len(element.data)}")
        elif isinstance(element, VertexElementUV):
            print(f"  UV count: {len(element.data)}")

Materialsystem

Aspose.3D FOSS støtter to materialtyper: LambertMaterial (diffus belysning) og PhongMaterial (spekulær belysning). Begge lastes automatisk fra .mtl-filer når du bruker ObjLoadOptions med enable_materials = True.

Lese materialer fra OBJ

from aspose.threed import Scene
from aspose.threed.shading import LambertMaterial, PhongMaterial
from aspose.threed.formats import ObjLoadOptions

options = ObjLoadOptions()
options.enable_materials = True

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

for node in scene.root_node.child_nodes:
    mat = node.material
    if mat is None:
        continue
    print(f"Node: {node.name}")
    if isinstance(mat, PhongMaterial):
        print(f"  Type: Phong")
        print(f"  Diffuse: {mat.diffuse_color}")
        print(f"  Specular: {mat.specular_color}")
    elif isinstance(mat, LambertMaterial):
        print(f"  Type: Lambert")
        print(f"  Diffuse: {mat.diffuse_color}")

Tilordning av materiale programmatisk

from aspose.threed import Scene, Node
from aspose.threed.shading import PhongMaterial
from aspose.threed.utilities import Vector3

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

material = PhongMaterial()
material.diffuse_color = Vector3(0.8, 0.2, 0.2)   # Red diffuse
material.specular_color = Vector3(1.0, 1.0, 1.0)  # White specular

##Apply to the first mesh node
for node in scene.root_node.child_nodes:
    if node.entity is not None:
        node.material = material
        break

scene.save("recolored.glb")

Matematikkverktøy

Den aspose.threed.utilities modulen gir alle geometriske matematiske typer som trengs for scenekonstruksjon og inspeksjon.

KlasseFormål
Vector22D floating-point vector (UV coordinates)
Vector33D double-precision vector (positions, normals)
Vector44D double-precision vector (homogeneous coordinates)
FVector33D single-precision vector (compact storage)
QuaternionRotasjonsrepresentasjon uten gimbal-lock
Matrix44×4 transformation matrix
BoundingBoxAksialt justert avgrensningsboks med min/maks hjørner

Arbeide med transformasjoner

from aspose.threed.utilities import Vector3, Quaternion, Matrix4
import math

##Build a rotation quaternion from axis-angle
axis = Vector3(0.0, 1.0, 0.0)          # Y-axis
angle_rad = math.radians(45.0)
q = Quaternion.from_angle_axis(angle_rad, axis)

print(f"Quaternion: x={q.x:.4f} y={q.y:.4f} z={q.z:.4f} w={q.w:.4f}")

##Convert to rotation matrix
mat = q.to_matrix()
print(f"Rotation matrix row 0: {mat[0, 0]:.4f} {mat[0, 1]:.4f} {mat[0, 2]:.4f}")

Beregning av en omsluttende boks

from aspose.threed import Scene

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

# NOTE: mesh.get_bounding_box() is a stub — it always returns an empty BoundingBox()
# regardless of geometry. Compute bounds manually from control_points:
for node in scene.root_node.child_nodes:
    if node.entity is None:
        continue
    mesh = node.entity
    pts = mesh.control_points  # returns a copy of the vertex list
    if not pts:
        continue
    xs = [p.x for p in pts]
    ys = [p.y for p in pts]
    zs = [p.z for p in pts]
    print(f"Mesh: {node.name}")
    print(f"  Min: ({min(xs):.3f}, {min(ys):.3f}, {min(zs):.3f})")
    print(f"  Max: ({max(xs):.3f}, {max(ys):.3f}, {max(zs):.3f})")

Animasjon

Aspose.3D FOSS tilbyr en animasjonsmodell basert på AnimationClip, AnimationNode, KeyFrame, og KeyframeSequence. Animasjonsdata lagret i innlastede filer (glTF, COLLADA) er tilgjengelig gjennom disse objektene.

Lese animasjonsklipp

from aspose.threed import Scene

scene = Scene.from_file("animated.glb")

for clip in scene.animation_clips:
    print(f"Clip: {clip.name}  ({clip.start:.2f}s – {clip.stop:.2f}s)")
    for anim_node in clip.animations:
        print(f"  Animation node: {anim_node.name}")
        for sub in anim_node.sub_animations:
            print(f"    Sub-animation: {sub.name}")
        for bp in anim_node.bind_points:
            print(f"    Bind point: {bp.name}")

Laste- og lagrealternativer

Hvert støttet format har en tilsvarende alternativklasse som styrer parsing- og serialiseringsadferd.

KlasseFormatNøkkelegenskaper
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLBinær vs. ASCII-utdata-modus
(glTF bruker standardinnstillinger)glTF / GLBScenegraph og materialer bevares automatisk

Brukseksempler

Eksempel 1: OBJ til STL-formatkonvertering

Konverter en OBJ-fil (med materialer) til binær STL, og skriv ut nettstatistikk underveis:

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

##Load OBJ with material support
load_opts = ObjLoadOptions()
load_opts.enable_materials = True
load_opts.flip_coordinate_system = False
load_opts.normalize_normal = True

scene = Scene()
scene.open("input.obj", load_opts)

##Report what was loaded
total_vertices = 0
total_polygons = 0
for node in scene.root_node.child_nodes:
    if node.entity is not None:
        mesh = node.entity
        total_vertices += len(mesh.control_points)
        total_polygons += len(mesh.polygons)
        print(f"  {node.name}: {len(mesh.control_points)} vertices, {len(mesh.polygons)} polygons")

print(f"Total: {total_vertices} vertices, {total_polygons} polygons")

##Save as STL
save_opts = StlSaveOptions()
scene.save("output.stl", save_opts)
print("Saved output.stl")

Eksempel 2: Batch glTF til GLB-pakking

Lagre på nytt en mappe med separate glTF‑ og teksturfiler som selvstendige GLB‑binærfiler:

import os
from aspose.threed import Scene

input_dir = "gltf_files"
output_dir = "glb_files"
os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
    if not filename.endswith(".gltf"):
        continue
    src = os.path.join(input_dir, filename)
    dst = os.path.join(output_dir, filename.replace(".gltf", ".glb"))
    scene = Scene.from_file(src)
    scene.save(dst)
    print(f"Packed {filename} -> {os.path.basename(dst)}")

Eksempel 3: Inspeksjon av scenegraf og eksportrapport

Gå gjennom en COLLADA-fils scenegraf, samle inn per‑nettstatistikk, og skriv ut en strukturert rapport:

from aspose.threed import Scene

scene = Scene.from_file("assembly.dae")

report = []

def collect(node, path=""):
    full_path = f"{path}/{node.name}" if node.name else path
    if node.entity is not None:
        mesh = node.entity
        gt = node.global_transform
        report.append({
            "path": full_path,
            "vertices": len(mesh.control_points),
            "polygons": len(mesh.polygons),
            "world_x": gt.translation.x,
            "world_y": gt.translation.y,
            "world_z": gt.translation.z,
        })
    for child in node.child_nodes:
        collect(child, full_path)

collect(scene.root_node)

print(f"{'Path':<40} {'Verts':>6} {'Polys':>6} {'X':>8} {'Y':>8} {'Z':>8}")
print("-" * 78)
for entry in report:
    print(
        f"{entry['path']:<40} "
        f"{entry['vertices']:>6} "
        f"{entry['polygons']:>6} "
        f"{entry['world_x']:>8.3f} "
        f"{entry['world_y']:>8.3f} "
        f"{entry['world_z']:>8.3f}"
    )

Tips og beste praksis

Formatvalg

  • glTF 2.0 / GLB er det anbefalte utvekslingsformatet for scener som inkluderer materialer, animasjoner og komplekse hierarkier. Foretrekk GLB (binær) fremfor glTF (tekst + eksterne filer) for portabilitet.
  • STL er det riktige valget når den nedstrøms forbrukeren er en slicer, CAD-verktøy eller ethvert verktøy som kun trenger geometri. STL inneholder ingen material- eller animasjonsdata.
  • OBJ er bredt støttet og et godt valg når materialdata må utveksles med eldre verktøy. Sørg alltid for at .mtl-filen ligger ved siden av .obj-filen.

Koordinatsystemer

  • Ulike applikasjoner bruker ulike håndhetskonvensjoner. Angi ObjLoadOptions.flip_coordinate_system = True ved import av OBJ-filer fra verktøy som bruker et høyrehendt koordinatsystem hvis din pipeline forventer venstrehendte koordinater, og omvendt.
  • Bekreft aksiskonvensjonen til kilde‑assetet før du anvender noen vending. Å vende to ganger gir feil geometri.

Normalisering

  • Angi alltid ObjLoadOptions.normalize_normal = True når den nedstrøms pipeline forventer enhetsnormaler (for eksempel når normaler sendes til en shader eller ved dot-produkt belysningsberegninger). Ikke-normaliserte normaler fra dårlig formede OBJ-filer forårsaker belysningsartefakter.

Ytelse

  • Last inn filer én gang og transformer scenegrafen i minnet i stedet for å laste på nytt fra disk for hvert output-format. En enkelt Scene.from_file() kall etterfulgt av flere scene.save() kall er mer effektivt enn gjentatte innlastinger.
  • Når du behandler store batcher, konstruer en enkelt ObjLoadOptions eller StlSaveOptions instans og gjenbruk den på tvers av alle filer i stedet for å konstruere et nytt alternativobjekt per fil.

Feilhåndtering

  • Pakk inn scene.open() og scene.save() kall i try/except blokker når du behandler upålitelige eller brukerleverte filer. Rapporter filnavnet i unntaksmeldinger for å forenkle feilsøking i batch pipelines.

Vanlige problemer

ProblemÅrsakLøsning
Mesh ser speilet ut etter lastingUoverensstemmelse i koordinatsystemets håndhetVeksle ObjLoadOptions.flip_coordinate_system
Normaler har null lengdeKildefilen har ikke-normaliserte normalerSett ObjLoadOptions.normalize_normal = True
Materialer ble ikke lastet fra OBJenable_materials er False (standard)Sett ObjLoadOptions.enable_materials = True
Scenen lastes, men alle noder er tommeFilen bruker FBX-formatFBX-parseren er under utvikling; bruk OBJ, STL eller glTF i stedet
Modellen er ekstremt liten eller storKildefilen bruker ikke-metriske enheterBruk ObjLoadOptions.scale for å konvertere til ønsket enhet
AttributeErrormesh.polygonsNode-entitet er ikke et MeshBeskytt med if node.entity is not None før du får tilgang til entitetsegenskaper
GLB-filen blir avvist av viserenLagret med .gltf utvidelseBruk .glb utvidelse når du kaller scene.save() for å utløse binær beholder

Ofte stilte spørsmål

Hvilke Python-versjoner støttes? Python 3.7, 3.8, 3.9, 3.10, 3.11 og 3.12 støttes alle. Biblioteket er ren Python uten native-utvidelse, så det fungerer på alle plattformer der CPython kjører.

Har biblioteket noen eksterne avhengigheter? Nei. Aspose.3D FOSS for Python bruker kun standardbiblioteket Python. Det installeres som en enkelt pip install aspose-3d-foss kommando uten påfølgende trinn.

Støttes FBX? FBX-tokenizeren er implementert og kan parse den binære FBX-tokenstrømmen, men scene‑graf‑byggeren på toppen av tokenizeren har kjente feil og er ikke klar for produksjon. Bruk OBJ, STL, glTF, COLLADA eller 3MF for pålitelig produksjonsbruk.

Kan jeg bruke Aspose.3D FOSS i et kommersielt produkt? Ja. Biblioteket er utgitt under MIT‑lisensen, som tillater bruk i proprietær og kommersiell programvare uten royalty‑betalinger, forutsatt at lisensmerknaden er inkludert.

Hvordan rapporterer jeg en feil eller ber om et format? Åpne en sak i depotet. Inkluder en minimal reproduksjonsfil og Python-versjonen, operativsystemet og bibliotekversjonen fra pip show aspose-3d-foss.


API-referansesammendrag

Kjerneklasser

  • Scene: Toppnivåbeholder for en 3D-scene. Inngangspunkt for open(), from_file(), og save().
  • Node: Treetnode i scenegrafen. Bærer entity, transform, global_transform, material, child_nodes, og name.
  • Entity: Basisklasse for objekter festet til noder (Mesh, Camera, Light).
  • Transform: Lokalt romposisjon, rotasjon (Quaternion) og skala for en node.
  • GlobalTransform: Skrivebeskyttet verdensromtransformasjon beregnet ved å akkumulere alle foreldertransformasjoner.

Geometri

  • Mesh: Polygonnett med control_points (vertex-liste) og polygons.
  • VertexElementNormal: Per-vertex eller per-polygon normalvektorer.
  • VertexElementUV: Per-vertex UV-teksturkoordinater.
  • VertexElementVertexColor: Per-vertex fargedata.
  • VertexElementSmoothingGroup: Polygonutjevningsgruppe-tildelinger.

Materialer

  • LambertMaterial: Diffus skyggelegningsmodell med diffuse_color og emissive_color.
  • PhongMaterial: Legger til spekulær skygge-modell specular_color og shininess.

Matematikkverktøy (aspose.threed.utilities)

  • Vector2: 2D‑vektor.
  • Vector3: 3D dobbelpresisjon vektor.
  • Vector4: 4D dobbelpresisjon vektor.
  • FVector3: 3D enkeltpresisjon vektor.
  • Quaternion: Rotasjonskvaternion med from_angle_axis() og to_matrix().
  • Matrix4: 4×4 transformasjonsmatrise.
  • BoundingBox: Aksjejustert avgrensningsboks med minimum og maximum hjørner.

Animasjon

  • AnimationClip: Navngitt beholder for et sett med animasjonskanaler og deres nøkkelrammer.
  • AnimationNode: Per-node animasjonsdata i et klipp.
  • KeyFrame: Enkel nøkkelramme med tid og verdi.
  • KeyframeSequence: Ordnet sekvens av nøkkelrammer for en enkelt animert egenskap.

Last inn / lagre-alternativer

  • ObjLoadOptions: OBJ-spesifikke innlastingsinnstillinger: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: STL-spesifikke lagringsinnstillinger (binær vs. ASCII-modus).

Kameraer og lys

  • Camera: Kameraenhet med projeksjonsinnstillinger, kan festes til en Node.
  • Light: Lyskildeenhet, festbar til en Node.
 Norsk