Caracteristici și Funcționalități

Caracteristici și Funcționalități

Aspose.3D FOSS pentru TypeScript este o bibliotecă Node.js licențiată MIT pentru încărcarea, construirea și exportarea scenelor 3D. Vine cu definiții complete de tip TypeScript, o singură dependență la runtime (xmldom), și suport pentru șase formate majore de fișiere 3D. Această pagină este referința principală pentru toate zonele de funcționalitate și include exemple de cod TypeScript executabile pentru fiecare.

Instalare și configurare

Instalați pachetul din npm folosind o singură comandă:

npm install @aspose/3d

Pachetul vizează CommonJS și necesită Node.js 18 sau o versiune ulterioară. După instalare, verificați că tsconfig.json include următoarele opțiuni ale compilatorului pentru compatibilitate completă:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true
  }
}

Importați principalul Scene clasă din rădăcina pachetului. Clasele de opțiuni specifice formatului sunt importate din sub-căile lor corespunzătoare:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

Caracteristici și Funcționalități

Suport pentru formate

Aspose.3D FOSS pentru TypeScript citește și scrie șase formate majore de fișiere 3D. Detectarea formatului este automată pe baza numerelor magice binare la încărcare, astfel că nu trebuie să specificați explicit formatul sursă.

FormatCitireScriereNote
OBJ (Wavefront)DaDaCitește/scrie .mtl materiale; utilizare ObjLoadOptions.enableMaterials pentru import
glTF 2.0DaDaformat text JSON; materiale PBR
GLBDaDaBinar glTF; setat GltfSaveOptions.binaryMode = true
STLDaDaBinar și ASCII; roundtrip complet verificat
3MFDaDa3D Manufacturing Format with color and material metadata
FBXNu*Nu*Importator/exportator există, dar detectarea automată a formatului nu este conectată
COLLADA (DAE)DaDaScalarea unității, geometrie, materiale și clipuri de animație

Încărcarea unui fișier OBJ cu materiale:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
options.flipCoordinateSystem = false;
options.scale = 1.0;
options.normalizeNormal = true;
scene.open('model.obj', options);

Salvarea în GLB (glTF binar):

import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
// ... build or load scene content

const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('output.glb', GltfFormat.getInstance(), opts);

Graf de scenă

Tot conținutul 3D este organizat ca un arbore de Node obiecte cu rădăcina la scene.rootNode. Fiecare nod poate conține un Entity (un Mesh, Camera, Light, sau alt SceneObject) și un Transform care îl poziționează relativ la părintele său.

Clase cheie ale graficului de scenă:

  • Scene: containerul de nivel superior; conține rootNode și animationClips
  • Node: un nod de arbore denumit cu childNodes, entity, transform, și materials
  • Entity: clasă de bază pentru obiecte atașabile (Mesh, Camera, Light)
  • SceneObject: clasă de bază partajată de Node și Entity
  • A3DObject: clasă de bază rădăcină cu name și container de proprietăți
  • Transform: translație locală, rotație (Euler și Quaternion) și scară

Traversarea graficului de scenă:

import { Scene, Node, Mesh } from '@aspose/3d';

const scene = new Scene();
scene.open('model.obj');

function visit(node: Node, depth: number = 0): void {
  const indent = '  '.repeat(depth);
  console.log(`${indent}Node: ${node.name}`);
  if (node.entity) {
    console.log(`${indent}  Entity: ${node.entity.constructor.name}`);
  }
  for (const child of node.childNodes) {
    visit(child, depth + 1);
  }
}

visit(scene.rootNode);

Crearea ierarhiei scenei programatic:

import { Scene, Node } from '@aspose/3d';

const scene = new Scene();
const parent = scene.rootNode.createChildNode('chassis');
const wheel = parent.createChildNode('wheel_fl');
wheel.transform.translation.set(0.9, -0.3, 1.4);

Geometrie și Mesh

Mesh este tipul principal de geometrie. Extinde Geometry și expune puncte de control (vârfuri), indici de poligon și elemente de vârf pentru normale, UV-uri și culori de vârf.

Clase cheie de geometrie:

  • Mesh: rețea de poligoane cu controlPoints și polygonCount
  • Geometry: clasă de bază cu gestionarea elementelor de vârf
  • VertexElementNormal: normale per-vârf sau per-vârf-poligon
  • VertexElementUV: coordonate de textură (unul sau mai multe canale UV)
  • VertexElementVertexColor: date de culoare per-vârf
  • MappingMode: controlează modul în care datele elementului se mapă pe poligoane (CONTROL_POINT, POLYGON_VERTEX, POLYGON, EDGE, ALL_SAME)
  • ReferenceMode: controlează strategia de indexare (DIRECT, INDEX, INDEX_TO_DIRECT)
  • VertexElementType: identifică semantica unui element de vârf
  • TextureMapping: enumerarea canalelor de textură

Citirea datelor de plasă dintr-o scenă încărcată:

import { Scene, Mesh, VertexElementType } from '@aspose/3d';

const scene = new Scene();
scene.open('model.stl');

for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    const mesh = node.entity as Mesh;
    console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices, ${mesh.polygonCount} polygons`);

    const normals = mesh.getElement(VertexElementType.NORMAL);
    if (normals) {
      console.log(`  Normal mapping: ${normals.mappingMode}`);
    }
  }
}

Sistem de materiale

Aspose.3D FOSS pentru TypeScript suportă trei tipuri de materiale care acoperă întreaga gamă, de la umbrire Phong moștenită la redare bazată pe fizică:

  • LambertMaterial: culoare difuză și culoare ambientală; se mapă la materiale simple OBJ/DAE
  • PhongMaterial: adaugă culoare speculară, luciu și emisivă; tipul de material implicit OBJ
  • PbrMaterial: model fizic de rugozitate/metalic; utilizat pentru importul și exportul glTF 2.0

Citirea materialelor dintr-o scenă OBJ încărcată:

import { Scene, PhongMaterial, LambertMaterial } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
scene.open('model.obj', options);

for (const node of scene.rootNode.childNodes) {
  for (const mat of node.materials) {
    if (mat instanceof PhongMaterial) {
      const phong = mat as PhongMaterial;
      console.log(`  Phong: diffuse=${JSON.stringify(phong.diffuseColor)}, shininess=${phong.shininess}`);
    } else if (mat instanceof LambertMaterial) {
      console.log(`  Lambert: diffuse=${JSON.stringify((mat as LambertMaterial).diffuseColor)}`);
    }
  }
}

Aplicarea unui material PBR la construirea unei scene glTF:

import { Scene, Node, PbrMaterial } from '@aspose/3d';
import { Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const node = scene.rootNode.createChildNode('sphere');
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.8, 0.2, 0.2);   // red-tinted albedo; albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.5;
node.material = mat;

const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), opts);

Utilitare matematice

Biblioteca este livrată cu un set complet de tipuri matematice 3D, toate complet tipizate:

  • Vector3: vector cu 3 componente; suportă minus(), times(), dot(), cross(), normalize(), length, angleBetween()
  • Vector4: vector cu 4 componente pentru coordonate omogene
  • Matrix4: matrice de transformare 4×4 cu concatenate(), transpose, decompose, setTRS
  • Quaternion: cuaternion de rotație cu fromEulerAngle() (static, singular), eulerAngles() (instance method), slerp(), normalize()
  • BoundingBox: cutie de delimitare aliniată pe axe cu minimum, maximum, center, size, merge
  • FVector3: variantă cu precizie simplă a Vector3 utilizat în datele elementelor de vârf

Calcularea unei cutii delimitatoare din vârfurile rețelei:

import { Scene, Mesh, Vector3, BoundingBox } from '@aspose/3d';

const scene = new Scene();
scene.open('model.obj');

let box = new BoundingBox();
for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    for (const pt of (node.entity as Mesh).controlPoints) {
      box.merge(new Vector3(pt.x, pt.y, pt.z));
    }
  }
}
console.log('Center:', box.center);
console.log('Extents:', box.size);

Construirea unei transformări din unghiuri Euler:

import { Quaternion, Vector3, Matrix4 } from '@aspose/3d';

const rot = Quaternion.fromEulerAngle(0, Math.PI / 4, 0); // 45° around Y
const mat = new Matrix4();
mat.setTRS(new Vector3(0, 0, 0), rot, new Vector3(1, 1, 1));

Sistem de animație

API-ul de animație modelează clipuri, noduri, canale și secvențe de cadre cheie:

  • AnimationClip: colecție numită de noduri de animație; accesată prin scene.animationClips; expune animations: AnimationNode[]
  • AnimationNode: grup denumit BindPoint: s; creat prin clip.createAnimationNode(name), accesat prin clip.animations
  • BindPoint: leagă un AnimationNode : la o proprietate specifică a unui obiect de scenă; expune property : și channelsCount
  • AnimationChannel: extinde KeyframeSequence; deține un separat keyframeSequence; accesat prin bindPoint.getChannel(name)
  • KeyFrame: o singură pereche timp/valoare; transportă per-keyframe interpolation: Interpolation
  • KeyframeSequence: listă ordonată de KeyFrame obiecte prin keyFrames; are preBehavior și postBehavior (Extrapolation)
  • Interpolation: enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
  • Extrapolation: class cu type: ExtrapolationType și repeatCount: number
  • ExtrapolationType: enum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE

Citirea datelor de animație dintr-o scenă încărcată:

import { Scene, AnimationNode, BindPoint } from '@aspose/3d';

const scene = new Scene();
scene.open('animated.dae');   // COLLADA animation import is supported

for (const clip of scene.animationClips) {
  console.log(`Clip: "${clip.name}"`);
  for (const animNode of clip.animations) {          // clip.animations, not clip.nodes
    console.log(`  AnimationNode: ${animNode.name}`);
    for (const bp of animNode.bindPoints) {           // animNode.bindPoints, not animNode.channels
      console.log(`  BindPoint: property="${bp.property.name}", channels=${bp.channelsCount}`);
    }
  }
}

Suport pentru fluxuri și buffer-e

Utilizați scene.openFromBuffer() pentru a încărca o scenă 3D direct din memorie Buffer. Acesta este modelul recomandat pentru funcții serverless, conducte de streaming și procesarea activelor preluate prin HTTP fără a scrie pe disc.

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import * as fs from 'fs';

// Load file into memory, then parse from buffer
const buffer: Buffer = fs.readFileSync('model.obj');
const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
scene.openFromBuffer(buffer, options);

for (const node of scene.rootNode.childNodes) {
  if (node.entity) {
    console.log(node.name, node.entity.constructor.name);
  }
}

Detectarea automată a formatului pe baza numerelor magice binare se aplică la încărcarea din buffer, astfel încât fișierele GLB, STL binare și 3MF sunt recunoscute fără a specifica un parametru de format.

Exemple de utilizare

Exemplul 1: Încărcare OBJ și export în GLB

Acest exemplu încarcă un fișier Wavefront OBJ cu materiale, apoi reexportă scena ca fișier binar glTF (GLB) potrivit pentru utilizarea pe web și în motoare de joc.

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

function convertObjToGlb(inputPath: string, outputPath: string): void {
  const scene = new Scene();

  const loadOpts = new ObjLoadOptions();
  loadOpts.enableMaterials = true;
  loadOpts.flipCoordinateSystem = false;
  loadOpts.normalizeNormal = true;
  scene.open(inputPath, loadOpts);

  // Report what was loaded
  for (const node of scene.rootNode.childNodes) {
    if (node.entity) {
      console.log(`Loaded: ${node.name} (${node.entity.constructor.name})`);
    }
  }

  const saveOpts = new GltfSaveOptions();
  saveOpts.binaryMode = true; // write .glb instead of .gltf + .bin
  scene.save(outputPath, GltfFormat.getInstance(), saveOpts);

  console.log(`Exported GLB to: ${outputPath}`);
}

convertObjToGlb('input.obj', 'output.glb');

Exemplul 2: Tur complet STL cu validare a normalelor

Acest exemplu încarcă un fișier STL binar, afișează informațiile de normală per vertex, apoi reexportă scena ca STL ASCII și verifică turul complet.

import { Scene, Mesh, VertexElementNormal, VertexElementType } from '@aspose/3d';
import { StlLoadOptions, StlSaveOptions } from '@aspose/3d/formats/stl';

const scene = new Scene();
const loadOpts = new StlLoadOptions();
scene.open('model.stl', loadOpts);

let totalPolygons = 0;
for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    const mesh = node.entity as Mesh;
    totalPolygons += mesh.polygonCount;

    const normElem = mesh.getElement(VertexElementType.NORMAL) as VertexElementNormal | null;
    if (normElem) {
      console.log(`  Normals: ${normElem.data.length} entries, mapping=${normElem.mappingMode}`);
    }
  }
}
console.log(`Total polygons: ${totalPolygons}`);

// Re-export as ASCII STL
const saveOpts = new StlSaveOptions();
saveOpts.binaryMode = false; // ASCII output
scene.save('output_ascii.stl', saveOpts);

Exemplul 3: Construiește o scenă programatic și salveaz-o ca glTF

Acest exemplu construiește o scenă cu un material PBR de la zero și o salvează ca un fișier JSON glTF.

import { Scene, Mesh, PbrMaterial, Vector4, Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const node = scene.rootNode.createChildNode('floor');

// Build a simple quad mesh (two triangles)
// controlPoints are Vector4 (x, y, z, w) where w=1 for positions
const mesh = new Mesh();
mesh.controlPoints.push(
  new Vector4(-1, 0, -1, 1),
  new Vector4( 1, 0, -1, 1),
  new Vector4( 1, 0,  1, 1),
  new Vector4(-1, 0,  1, 1),
);
mesh.createPolygon([0, 1, 2]);
mesh.createPolygon([0, 2, 3]);
node.entity = mesh;

// Apply a PBR material
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.6, 0.6, 0.6);   // albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.8;
node.material = mat;

// Save as JSON glTF
const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('floor.gltf', GltfFormat.getInstance(), opts);
console.log('Scene written to floor.gltf');

Sfaturi și bune practici

  • Utilizați ObjLoadOptions.enableMaterials = true de fiecare dată când aveți nevoie de date de material din fișierele .mtl. Fără ele, lista de materiale de pe fiecare nod va fi goală.
  • Preferă binaryMode = true pentru GLB când produceți active pentru web sau motoare de jocuri. GLB binar este un singur fișier auto‑conținut și se încarcă mai repede în browsere și motoare decât versiunea JSON + .bin.
  • Utilizați openFromBuffer() în medii serverless pentru a evita I/O‑ul fișierelor temporare. Preluați activul, transmiteți Buffer direct, și scrieți ieșirea într-un flux sau alt buffer.
  • Verificați node.entity înainte de a face casting: nu toate nodurile conțin o entitate. Întotdeauna protejați cu un instanceof verifică înainte de a accesa Mesh-proprietăți specifice, cum ar fi controlPoints.
  • Setare normalizeNormal = true în ObjLoadOptions când fișierele tale OBJ sursă provin din surse neîncredere. Acest lucru împiedică propagarea normalelor degenerate în etapele ulterioare de redare sau validare.
  • Păstrează strict: true în tsconfig.json: biblioteca este scrisă cu noImplicitAny și strictNullChecks. Dezactivarea strict maschează erorile reale de tip și diminuează valoarea API-ului tipizat.
  • Parcurge prin childNodes, nu o buclă de index: the childNodes proprietatea returnează un iterabil; evită să te bazezi pe indexarea numerică pentru compatibilitate viitoare.

Probleme comune

SimptomCauză ProbabilăRemediere
Lista de materiale este goală după încărcarea OBJenableMaterials nu este setatSetează options.enableMaterials = true
Fișierul GLB conține un fișier .bin separatbinaryMode se setează implicit la falseSetează opts.binaryMode = true
Normalele vârfurilor lipsesc în ieșirea STLModului STL ASCII omite normalele pe fiecare fațăComută la binaryMode = true sau calculează normalele înainte de export
node.entity este întotdeauna nullSe parcurge doar rootNode, nu copiii săiRecursiv în node.childNodes
Eroare TypeScript: proprietatea nu existăVechi @types cacheRulează npm install @aspose/3d din nou; fără separare @types pachetul este necesar
openFromBuffer aruncă eroare de formatFormatul nu poate fi detectat automat din magicTransmite clasa de opțiune de format explicită ca al doilea argument

Întrebări frecvente

Necesită biblioteca vreun add-on nativ sau pachete de sistem? Nu. Aspose.3D FOSS pentru TypeScript are o singură dependență la runtime: xmldom, care este JavaScript pur și este instalat automat prin npm. Nu există .node native addons și fără pachete de sistem de instalat.

Ce versiuni de Node.js sunt suportate? Node.js 18, 20 și 22 LTS. Biblioteca vizează ieșire CommonJS și folosește caracteristici de limbaj ES2020 în interior.

Pot folosi biblioteca într-un pachet pentru browser (webpack/esbuild)? Biblioteca vizează Node.js și folosește Node.js fs și Buffer API-uri. Crearea de pachete pentru browser nu este suportată oficial. Pentru utilizarea în browser, încarcă scena pe server și transmite rezultatul (de ex., ca GLB) clientului.

Care este diferența dintre GltfSaveOptions.binaryMode = true și false? binaryMode = false produce un .gltf fișier JSON plus un separat .bin sidecar de buffer binar. binaryMode = true produce un singur element auto-conținut .glb fișier. Utilizați true pentru livrarea activelor în producție.

Pot încărca un fișier dintr-un răspuns HTTP fără să îl salvez pe disc? Da. Preiați răspunsul ca un Buffer (de exemplu, utilizând node-fetch sau încorporată fetch în Node 18+), apoi apelați scene.openFromBuffer(buffer, options).

Este suportul FBX complet? Nu. Clasele de import și export FBX există în bibliotecă, dar FBX nu este integrat în Scene.open() sau Scene.save() detectare automată. Apelarea scene.open('file.fbx') nu va invoca importatorul FBX; fișierul va fi gestionat prin calea de rezervă STL. Folosiți direct clasele de import/export specifice FBX dacă aveți nevoie de I/O FBX. Consultați tabelul de suport al formatelor de mai sus care marchează FBX ca No*.

Suportă biblioteca TypeScript 4.x? Se recomandă TypeScript 5.0+. TypeScript 4.7+ ar trebui să funcționeze în practică, dar biblioteca este testată și dezvoltată pentru 5.0+.

Rezumat al referinței API

ClasăModulScop
Scene@aspose/3dContainer de scenă la nivel superior; open(), openFromBuffer(), save(), rootNode, animationClips
Node@aspose/3dNod al graficului de scenă; childNodes, entity, transform, materials, createChildNode()
Entity@aspose/3dClasă de bază pentru obiecte atașabile la scenă
SceneObject@aspose/3dClasa de bază partajată de Node și Entity
A3DObject@aspose/3dBaza rădăcină cu name și pungă de proprietăți
Transform@aspose/3dTranslație, rotație și scară locale
Mesh@aspose/3dPlasă poligonală; controlPoints, polygonCount, createPolygon(), elemente de vârf
Geometry@aspose/3dClasă de bază pentru tipuri de geometrie
Camera@aspose/3dEntitate cameră cu unghi de vizualizare și setări de proiecție
Light@aspose/3dEntitate lumină (punct, direcțional, spot)
LambertMaterial@aspose/3dModel de umbrire difuz + ambiental
PhongMaterial@aspose/3dUmbrire Phong cu componentă speculară și emisivă
PbrMaterial@aspose/3dModel fizic bazat pe rugozitate/metalic pentru glTF
Vector3@aspose/3d3-component double-precision vector
Vector4@aspose/3d4-component vector for homogeneous math
Matrix4@aspose/3d4×4 transformation matrix
Quaternion@aspose/3dCuaternion de rotație
BoundingBox@aspose/3dCutie de delimitare aliniată pe axe
FVector3@aspose/3dVariantă cu precizie simplă a Vector3
VertexElementNormal@aspose/3dNormale per-vertex sau per-polygon-vertex
VertexElementUV@aspose/3dElement de vertex pentru coordonatele texturii
VertexElementVertexColor@aspose/3dElement de vertex pentru culoarea per-vertex
MappingMode@aspose/3dEnum: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME
ReferenceMode@aspose/3dEnum: DIRECT, INDEX, INDEX_TO_DIRECT
AnimationClip@aspose/3dAnimație numită; expune animations: AnimationNode[]; creat prin scene.createAnimationClip(name)
AnimationNode@aspose/3dGrup denumit de BindPoints; creat prin clip.createAnimationNode(name)
BindPoint@aspose/3dLeagă un AnimationNode la o proprietate a obiectului de scenă; expune property și channelsCount
AnimationChannel@aspose/3dExtinde KeyframeSequence; conține un keyframeSequence; accesat prin bindPoint.getChannel(name)
KeyFrame@aspose/3dPereche unică de cadru cheie timp/valoare; conține interpolation: Interpolation
KeyframeSequence@aspose/3dOrdinate keyFrames listă; preBehavior/postBehavior sunt Extrapolation obiecte
Interpolation@aspose/3dEnum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
Extrapolation@aspose/3dClasă cu type: ExtrapolationType și repeatCount: number
ExtrapolationType@aspose/3dEnum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE
ObjLoadOptions@aspose/3d/formats/objOpțiuni de import OBJ: enableMaterials, flipCoordinateSystem, scale, normalizeNormal
GltfSaveOptions@aspose/3d/formats/gltfOpțiuni de export glTF/GLB: binaryMode
GltfFormat@aspose/3d/formats/gltfInstanță de format pentru glTF/GLB; transmite la scene.save()
StlLoadOptions@aspose/3d/formats/stlOpțiuni de import STL
StlSaveOptions@aspose/3d/formats/stlOpțiuni de export STL: binaryMode
StlImporter@aspose/3d/formats/stlCititor STL de nivel scăzut
StlExporter@aspose/3d/formats/stlScriitor STL de nivel scăzut
 Română