Funktioner og funktionaliteter

Funktioner og funktionaliteter

Aspose.3D FOSS for Python leverer et komplet scene‑graph API til at læse, konstruere og skrive 3D‑indhold i flere branchestandard‑formater. Denne side dokumenterer hvert større funktionsområde med fungerende Python kodeeksempler, der bruger det faktiske biblioteks‑API.

Installation og opsætning

Installer biblioteket fra PyPI med en enkelt kommando:

pip install aspose-3d-foss

Ingen yderligere systempakker, native udvidelser eller kompilator‑værktøjskæder er påkrævet. Biblioteket er ren Python og understøtter Python 3.7 til 3.12 på Windows, macOS og Linux.

For at bekræfte installationen:

from aspose.threed import Scene

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

Funktioner og funktionaliteter

Formatunderstøttelse

Aspose.3D FOSS for Python læser og skriver følgende formater:

FormatFilendelseLæsSkrivNoter
Wavefront OBJ.objJaJa.mtl-materialindlæsning understøttet
STL (binær).stlJaJaRundtur verificeret (39 tests)
STL (ASCII).stlJaJaRundtur verificeret
glTF 2.0.gltfJaJaFuld scenegraf bevaret
GLB (binær glTF).glbJaJaEnkeltfil binær container
COLLADA.daeJaJaScenehierarki og materialer
3MF.3mfJaJaAdditiv fremstillingsformat
FBX.fbxDelvisNejTokenizer fungerer; parser har kendte fejl

Indlæsning af OBJ med indstillinger

ObjLoadOptions styrer hvordan OBJ-filer parses:

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

Gemning til STL

StlSaveOptions styrer binær vs. ASCII-output og andre STL-specifikke indstillinger:

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-indhold er organiseret som et træ af Node objekter. roden af træet er scene.root_node. Hver node kan indeholde undernoder og bære en Entity (mesh, kamera eller lys) plus en Transform.

Gennemløb af scenens hierarki

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)

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

Inspektion af GlobalTransform

GlobalTransform giver nodeens verdensrumstransformation efter at have akkumuleret alle forfædres transformationer:

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 giver adgang til geometridata inklusive kontrolpunkter (vertices), polygoner og vertex-elementer for normaler, UV’er og farver.

Læsning af 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)}")

Adgang til vertex-elementer

Vertex-elementer indeholder data per vertex eller per polygon. De mest almindelige elementer er normaler, UV-koordinater, vertex-farver og udjævningsgrupper:

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

Materialesystem

Aspose.3D FOSS understøtter to materialetyper: LambertMaterial (diffus shading) og PhongMaterial (specular shading). Begge indlæses automatisk fra .mtl-filer, når du bruger ObjLoadOptions med enable_materials = True.

Læsning af 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}")

Tildeling af et 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")

Matematiske værktøjer

Den aspose.threed.utilities modulet leverer alle geometriske matematiktyper, der er nødvendige for scenekonstruktion og inspektion.

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)
QuaternionRotationsrepræsentation uden gimbal lock
Matrix44×4 transformation matrix
BoundingBoxAksialt justeret begrænsningsboks med min/max-hjørner

Arbejde med transformationer

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 af en begrænsningsboks

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

Animation

Aspose.3D FOSS leverer en animationsmodel baseret på AnimationClip, AnimationNode, KeyFrame, og KeyframeSequence. Animationsdata gemt i indlæste filer (glTF, COLLADA) er tilgængelige gennem disse objekter.

Læsning af animationsklip

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

Indlæsnings- og gemmeindstillinger

Hvert understøttet format har en tilsvarende options-klasse, der styrer fortolknings- og serialiseringsadfærd.

KlasseFormatNøgleegenskaber
ObjLoadOptionsOBJenable_materials, flip_coordinate_system, normalize_normal, scale
StlSaveOptionsSTLBinær vs. ASCII-outputtilstand
(glTF bruger standardindstillinger)glTF / GLBScenegraf og materialer bevares automatisk

Brugseksempler

Eksempel 1: OBJ til STL formatkonvertering

Konvertér en OBJ-fil (med materialer) til binær STL, mens du udskriver mesh-statistikker undervejs:

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 pakning

Gem en mappe med separate glTF + teksturfiler som selvstændige GLB-binære filer igen:

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: Inspektion af scenegraph og eksportrapport

Gå igennem en COLLADA-fils scenegraph, indsamle per-mesh-statistikker og udskrive en struktureret 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 bedste praksis

Formatvalg

  • glTF 2.0 / GLB er det anbefalede udvekslingsformat for scener, der indeholder materialer, animationer og komplekse hierarkier. Foretræk GLB (binær) frem for glTF (tekst + eksterne filer) for portabilitet.
  • STL er det rigtige valg, når den efterfølgende forbruger er en slicer, CAD-værktøj eller ethvert værktøj, der kun har brug for geometri. STL indeholder ingen materiale- eller animationsdata.
  • OBJ er bredt understøttet og et godt valg, når materialedata skal udveksles med ældre værktøjer. Sørg altid for at holde .mtl-filen ved siden af .obj-filen.

Koordinatsystemer

  • Forskellige applikationer bruger forskellige håndheds-konventioner. Indstil ObjLoadOptions.flip_coordinate_system = True når du importerer OBJ-filer fra værktøjer, der bruger et højrehåndet koordinatsystem, hvis din pipeline forventer venstrehåndede koordinater, og omvendt.
  • Bekræft aksekonventionen for kilde‑asset’et, før du anvender nogen vending. At vende to gange giver forkert geometri.

Normalisering

  • Indstil altid ObjLoadOptions.normalize_normal = True når den efterfølgende pipeline forventer enhedsnormaler (for eksempel, når du sender normaler til en shader eller udfører dot-produkt belysningsberegninger). Ikke-normaliserede normaler fra dårligt formede OBJ-filer forårsager belysningsartefakter.

Ydeevne

  • Indlæs filer én gang og transformer den in-memory scenegraf i stedet for at genindlæse fra disk for hvert outputformat. En enkelt Scene.from_file() kald efterfulgt af flere scene.save() kald er mere effektivt end gentagne indlæsninger.
  • Når du behandler store batcher, opret en enkelt ObjLoadOptions eller StlSaveOptions instans og genbrug den på tværs af alle filer i stedet for at oprette et nyt options-objekt pr. fil.

Fejlhåndtering

  • Pak scene.open() og scene.save() kald i try/except blokke, når du behandler upålidelige eller brugerleverede filer. Rapporter filnavnet i undtagelsesmeddelelser for at forenkle fejlsøgning i batch pipelines.

Almindelige problemer

ProblemÅrsagLøsning
Mesh vises spejlvendt efter indlæsningKoordinatsystemets håndhed stemmer ikke overensSkift ObjLoadOptions.flip_coordinate_system
Normale har nul længdeKildefilen har ikke-normaliserede normaleSæt ObjLoadOptions.normalize_normal = True
Materialer indlæses ikke fra OBJenable_materials er False (standard)Sæt ObjLoadOptions.enable_materials = True
Scenen indlæses, men alle noder er tommeFilen bruger FBX-formatFBX-parseren er under udvikling; brug i stedet OBJ, STL eller glTF
Modellen er ekstremt lille eller storKildefilen bruger ikke-metriske enhederAnvend ObjLoadOptions.scale for at konvertere til din mål-enhed
AttributeErrormesh.polygonsNode-entitet er ikke et MeshBeskyt med if node.entity is not None før du får adgang til entitetsegenskaber
GLB-fil afvises af fremviserenGemt med .gltf filendelseBrug .glb filendelse når du kalder scene.save() for at udløse binær container

Ofte stillede spørgsmål

Hvilke Python-versioner understøttes? Python 3.7, 3.8, 3.9, 3.10, 3.11 og 3.12 understøttes alle. Biblioteket er ren Python uden native udvidelse, så det fungerer på enhver platform, hvor CPython kører.

Har biblioteket nogen eksterne afhængigheder? Nej. Aspose.3D FOSS for Python bruger kun standardbiblioteket Python. Det installeres som en enkelt pip install aspose-3d-foss kommando uden efterfølgende trin.

Understøttes FBX? FBX-tokenizeren er implementeret og kan parse den binære FBX token stream, men scene-graph builderen oven på tokenizeren har kendte fejl og er ikke klar til produktion. Brug OBJ, STL, glTF, COLLADA eller 3MF til pålidelig produktionsbrug.

Kan jeg bruge Aspose.3D FOSS i et kommercielt produkt? Ja. Biblioteket er udgivet under MIT-licensen, som tillader brug i proprietær og kommerciel software uden royaltybetalinger, forudsat at licensmeddelelsen medtages.

Hvordan rapporterer jeg en fejl eller anmoder om et format? Åbn en issue i repository’en. Medtag en minimal reproducer-fil og Python-versionen, operativsystemet og biblioteksversionen fra pip show aspose-3d-foss.


API-referencens oversigt

Kerneklasser

  • Scene: Topniveau-beholder for en 3D-scene. Indgangspunkt for open(), from_file(), og save().
  • Node: Trænode i scenegrafen. Bærer entity, transform, global_transform, material, child_nodes, og name.
  • Entity: Basisklasse for objekter knyttet til noder (Mesh, Camera, Light).
  • Transform: Lokalrum-position, rotation (Quaternion) og skala for en node.
  • GlobalTransform: Kun læsbar verdensrum-transform beregnet ved at akkumulere alle forældrestransformationer.

Geometri

  • Mesh: Polygonnet med control_points (vertex-liste) og polygons.
  • VertexElementNormal: Per-vertex eller per-polygon normalvektorer.
  • VertexElementUV: Per-vertex UV-teksturkoordinater.
  • VertexElementVertexColor: Per-vertex farvedata.
  • VertexElementSmoothingGroup: Polygon glatningsgruppe-tildelinger.

Materialer

  • LambertMaterial: Diffus skygge-model med diffuse_color og emissive_color.
  • PhongMaterial: Tilføjelse af spejlende skygge-model specular_color og shininess.

Matematikværktøjer (aspose.threed.utilities)

  • Vector2: 2D vektor.
  • Vector3: 3D vektor med dobbeltpræcision.
  • Vector4: 4D vektor med dobbeltpræcision.
  • FVector3: 3D vektor med enkeltpræcision.
  • Quaternion: Rotationskvaternion med from_angle_axis() og to_matrix().
  • Matrix4: 4×4 transformationsmatrix.
  • BoundingBox: Aksialt justeret begrænsningsboks med minimum og maximum : hjørner.

Animation

  • AnimationClip: Navngivet container til et sæt af animationskanaler og deres nøgleframes.
  • AnimationNode: Per-node animationsdata inden for et klip.
  • KeyFrame: Enkelt nøgleframe med tid og værdi.
  • KeyframeSequence: Ordnet sekvens af nøgleframes for en enkelt animeret egenskab.

Indlæsnings- / Gemmeindstillinger

  • ObjLoadOptions: OBJ-specifikke indlæsningsindstillinger: enable_materials, flip_coordinate_system, normalize_normal, scale.
  • StlSaveOptions: STL-specifikke gemmeindstillinger (binær vs. ASCII-tilstand).

Kameraer og lys

  • Camera: Kameraenhed med projektionindstillinger, kan vedhæftes til en Node.
  • Light: Lyskildeenhed, som kan fastgøres til en Node.
 Dansk