Caratteristiche e funzionalità

Caratteristiche e funzionalità

Aspose.3D FOSS per TypeScript è una libreria Node.js rilasciata sotto licenza MIT per caricare, costruire ed esportare scene 3D. Viene fornita con definizioni di tipo TypeScript complete, una singola dipendenza runtime (xmldom), e supporto per sei principali formati di file 3D. Questa pagina è il riferimento principale per tutte le aree funzionali e include esempi di codice TypeScript eseguibili per ciascuna.

Installazione e configurazione

Installa il pacchetto da npm usando un unico comando:

npm install @aspose/3d

Il pacchetto mira a CommonJS e richiede Node.js 18 o versioni successive. Dopo l’installazione, verifica il tuo tsconfig.json includono le seguenti opzioni del compilatore per una piena compatibilità:

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

Importa il principale Scene classe dalla radice del pacchetto. Le classi di opzioni specifiche per formato vengono importate dai rispettivi sotto‑percorsi:

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

Caratteristiche e funzionalità

Supporto dei formati

Aspose.3D FOSS per TypeScript legge e scrive sei principali formati di file 3D. Il rilevamento del formato è automatico tramite i numeri magici binari durante il caricamento, quindi non è necessario specificare esplicitamente il formato di origine.

FormatoLeggiScriviNote
OBJ (Wavefront)Legge/scrive .mtl materiali; usa ObjLoadOptions.enableMaterials per l’importazione
glTF 2.0Formato di testo JSON; materiali PBR
GLBglTF binario; impostato GltfSaveOptions.binaryMode = true
STLBinario e ASCII; roundtrip completo verificato
3MF3D Manufacturing Format with color and material metadata
FBXNo*No*Importatore/esportatore esistono ma il rilevamento automatico del formato non è collegato
COLLADA (DAE)Scalatura delle unità, geometria, materiali e clip di animazione

Caricamento di OBJ con materiali:

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

Salvataggio in GLB (glTF binario):

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

Scene Graph

Tutti i contenuti 3D sono organizzati come un albero di Node oggetti radicati in scene.rootNode. Ogni nodo può trasportare un Entity (un Mesh, Camera, Light, o altro SceneObject) e un Transform che lo posiziona rispetto al suo genitore.

Classi chiave del grafo della scena:

  • Scene: il contenitore di livello superiore; contiene rootNode e animationClips
  • Node: un nodo ad albero denominato con childNodes, entity, transform, e materials
  • Entity: classe base per oggetti collegabili (Mesh, Camera, Light)
  • SceneObject: classe base condivisa da Node e Entity
  • A3DObject: classe base radice con name e sacchetto di proprietà
  • Transform: traslazione locale, rotazione (Euler e Quaternion) e scala

Attraversamento del grafo della scena:

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

Creare una gerarchia di scena programmaticamente:

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

Geometria e Mesh

Mesh è il tipo di geometria principale. Estende Geometry e espone punti di controllo (vertici), indici dei poligoni e elementi dei vertici per normali, UV e colori dei vertici.

Classi chiave di geometria:

  • Mesh: mesh poligonale con controlPoints e polygonCount
  • Geometry: classe base con gestione degli elementi dei vertici
  • VertexElementNormal: normali per vertice o per vertice di poligono
  • VertexElementUV: coordinate di texture (uno o più canali UV)
  • VertexElementVertexColor: dati di colore per vertice
  • MappingMode: controlla come i dati degli elementi vengono mappati sui poligoniCONTROL_POINT, POLYGON_VERTEX, POLYGON, EDGE, ALL_SAME)
  • ReferenceMode:controlla la strategia di indicizzazione (DIRECT, INDEX, INDEX_TO_DIRECT)
  • VertexElementType:identifica la semantica di un elemento vertice
  • TextureMapping:enumerazione dei canali texture

Lettura dei dati mesh da una scena caricata:

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}`);
    }
  }
}

Sistema dei materiali

Aspose.3D FOSS per TypeScript supporta tre tipi di materiale che coprono l’intera gamma, dallo shading Phong legacy al rendering basato sulla fisica:

  • LambertMaterial:colore diffuso e colore ambientale; mappa a materiali OBJ/DAE semplici
  • PhongMaterial:aggiunge colore speculare, lucentezza e emissivo; il tipo di materiale OBJ predefinito
  • PbrMaterial:modello fisicamente basato di rugosità/metallicità; usato per l’importazione ed esportazione glTF 2.0

Lettura dei materiali da una scena OBJ caricata:

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)}`);
    }
  }
}

Applicazione di un materiale PBR durante la costruzione di una scena 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);

Utility matematiche

La libreria include un set completo di tipi matematici 3D, tutti completamente tipizzati:

  • Vector3:vettore a 3 componenti; supporta minus(), times(), dot(), cross(), normalize(), length, angleBetween()
  • Vector4:vettore a 4 componenti per coordinate omogenee
  • Matrix4:matrice di trasformazione 4×4 con concatenate(), transpose, decompose, setTRS
  • Quaternion:quaternione di rotazione con fromEulerAngle() (statico, singolare), eulerAngles() (metodo di istanza), slerp(), normalize()
  • BoundingBox:box di delimitazione allineato agli assi con minimum, maximum, center, size, merge
  • FVector3:variante a precisione singola di Vector3 usato nei dati degli elementi vertice

Calcolo di un bounding box dai vertici della mesh:

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

Costruzione di una trasformazione da angoli di Eulero:

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

Sistema di animazione

L’API di animazione modella clip, nodi, canali e sequenze di fotogrammi chiave:

  • AnimationClip:collezione denominata di nodi di animazione; accessibile tramite scene.animationClips; espone animations: AnimationNode[]
  • AnimationNode: gruppo denominato di BindPoints; creato tramite clip.createAnimationNode(name), accessibile tramite clip.animations
  • BindPoint: associa un AnimationNode a una proprietà specifica su un oggetto della scena; espone property e channelsCount
  • AnimationChannel: estende KeyframeSequence; contiene un separato keyframeSequence; accessibile tramite bindPoint.getChannel(name)
  • KeyFrame: una singola coppia tempo/valore; trasporta per-keyframe interpolation: Interpolation
  • KeyframeSequence: elenco ordinato di KeyFrame oggetti tramite keyFrames; ha preBehavior e postBehavior (Extrapolation)
  • Interpolation: enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
  • Extrapolation: classe con type: ExtrapolationType e repeatCount: number
  • ExtrapolationType: enum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE

Lettura dei dati di animazione da una scena caricata:

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}`);
    }
  }
}

Supporto per Stream e Buffer

Usa scene.openFromBuffer() per caricare una scena 3D direttamente da una memoria in-memory Buffer. Questo è lo schema consigliato per le funzioni serverless, le pipeline di streaming e l’elaborazione di risorse recuperate via HTTP senza scrivere su disco.

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

Il rilevamento automatico del formato tramite i numeri magici binari si applica durante il caricamento da buffer, quindi i file GLB, STL binari e 3MF vengono riconosciuti senza dover specificare un parametro di formato.

Esempi di utilizzo

Esempio 1: Carica OBJ ed esporta in GLB

Questo esempio carica un file Wavefront OBJ con i materiali, quindi riesporta la scena come file glTF binario (GLB) adatto per l’uso sul web e nei motori di gioco.

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');

Esempio 2: Round-Trip STL con convalida delle normali

Questo esempio carica un file STL binario, stampa le informazioni delle normali per vertice, quindi riesporta la scena come STL ASCII e verifica il round‑trip.

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

Esempio 3: Costruire una scena programmaticamente e salvarla come glTF

Questo esempio costruisce una scena con un materiale PBR da zero e la salva come file 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');

Suggerimenti e migliori pratiche

  • Usa ObjLoadOptions.enableMaterials = true ogni volta che hai bisogno dei dati dei materiali dai file .mtl. Senza di esso, l’elenco dei materiali su ogni nodo sarà vuoto.
  • Preferisci binaryMode = true per GLB quando si producono asset per il web o per motori di gioco. Il GLB binario è un unico file autonomo e si carica più velocemente nei browser e nei motori rispetto alla divisione JSON + .bin.
  • Usa openFromBuffer() in ambienti serverless per evitare I/O di file temporanei. Recupera l’asset, passa il Buffer direttamente, e scrivi l’output su uno stream o su un altro buffer.
  • Verifica node.entity prima del casting: non tutti i nodi contengono un’entità. Proteggi sempre con un instanceof controllo prima di accedere Mesh-specifiche proprietà come controlPoints.
  • Imposta normalizeNormal = true in ObjLoadOptions quando i tuoi file OBJ di origine provengono da fonti non attendibili. Questo impedisce che normali degeneri si propaghino nei passaggi di rendering o di validazione a valle.
  • Mantieni strict: true in tsconfig.json: la libreria è stata creata con noImplicitAny e strictNullChecks. Disabilitando strict nasconde i veri errori di tipo e nega il valore dell’API tipizzata.
  • Attraversa tramite childNodes, non un ciclo di indice: il childNodes la proprietà restituisce un iterabile; evita di fare affidamento sull’indicizzazione numerica per la compatibilità futura.

Problemi comuni

SintomoCausa probabileCorrezione
Elenco dei materiali vuoto dopo il caricamento OBJenableMaterials non impostatoImposta options.enableMaterials = true
Il file GLB contiene un file .bin separatobinaryMode impostazione predefinita su falseImposta opts.binaryMode = true
Normali dei vertici mancanti nell’output STLLa modalità STL ASCII omette le normali per facciaPassa a binaryMode = true oppure calcola le normali prima dell’esportazione
node.entity è sempre nullSolo attraversando rootNode, non i suoi figliRicorsione in node.childNodes
Errore TypeScript: la proprietà non esisteVecchio @types cacheEsegui npm install @aspose/3d di nuovo; nessun separato @types pacchetto è necessario
openFromBuffer genera errore di formatoFormato non rilevabile automaticamente dal magicPassa la classe di opzione di formato esplicita come secondo argomento

Domande frequenti

La libreria richiede addon nativi o pacchetti di sistema? No. Aspose.3D FOSS per TypeScript ha una singola dipendenza runtime: xmldom, che è puro JavaScript e viene installato automaticamente da npm. Non ci sono .node addon nativi e nessun pacchetto di sistema da installare.

Quali versioni di Node.js sono supportate? Node.js 18, 20 e 22 LTS. La libreria genera output CommonJS e utilizza funzionalità del linguaggio ES2020 internamente.

Posso usare la libreria in un bundle per browser (webpack/esbuild)? La libreria è destinata a Node.js e utilizza Node.js fs e Buffer API. Il bundling per browser non è ufficialmente supportato. Per l’uso in browser, carica la scena sul server e trasmetti il risultato (ad es., come GLB) al client.

Qual è la differenza tra GltfSaveOptions.binaryMode = true e false? binaryMode = false produce un .gltf file JSON più un separato .bin sidecar di buffer binario. binaryMode = true produce un unico file autonomo .glb file. Usa true per la consegna di asset in produzione.

Posso caricare un file da una risposta HTTP senza salvarlo su disco? Sì. Recupera la risposta come un Buffer (ad es., usando node-fetch o il built-in fetch in Node 18+), quindi chiama scene.openFromBuffer(buffer, options).

Il supporto FBX è completo? No. Le classi di importazione ed esportazione FBX esistono nella libreria, ma FBX non è integrato in Scene.open() oppure Scene.save() rilevamento automatico. Chiamare scene.open('file.fbx') non invocherà l’importatore FBX; il file verrà gestito dal percorso di fallback STL. Usa direttamente le classi importatore/esportatore specifiche per FBX se hai bisogno di I/O FBX. Vedi la tabella di supporto dei formati sopra, che indica FBX come No*.

La libreria supporta TypeScript 4.x? Si consiglia TypeScript 5.0+. TypeScript 4.7+ dovrebbe funzionare in pratica, ma la libreria è testata e sviluppata contro 5.0+.

Sommario del Riferimento API

ClasseModuloScopo
Scene@aspose/3dContenitore della scena di livello superiore; open(), openFromBuffer(), save(), rootNode, animationClips
Node@aspose/3dNodo del grafo della scena; childNodes, entity, transform, materials, createChildNode()
Entity@aspose/3dClasse base per oggetti collegabili alla scena
SceneObject@aspose/3dClasse base condivisa da Node e Entity
A3DObject@aspose/3dBase radice con name e contenitore di proprietà
Transform@aspose/3dTraslazione, rotazione e scala locali
Mesh@aspose/3dMesh poligonale; controlPoints, polygonCount, createPolygon(), elementi dei vertici
Geometry@aspose/3dClasse base per tipi di geometria
Camera@aspose/3dEntità fotocamera con campo visivo e impostazioni di proiezione
Light@aspose/3dEntità luminosa (puntiforme, direzionale, spot)
LambertMaterial@aspose/3dModello di shading diffuso + ambientale
PhongMaterial@aspose/3dPhong shading con speculare ed emissivo
PbrMaterial@aspose/3dModello basato sulla fisica di roughness/metallic per glTF
Vector3@aspose/3d3-component double-precision vector
Vector4@aspose/3d4-component vector for homogeneous math
Matrix4@aspose/3d4×4 transformation matrix
Quaternion@aspose/3dQuaternione di rotazione
BoundingBox@aspose/3dBounding box allineata agli assi
FVector3@aspose/3dVariante a precisione singola di Vector3
VertexElementNormal@aspose/3dNormali per vertice o per vertice di poligono
VertexElementUV@aspose/3dElemento vertice di coordinate texture
VertexElementVertexColor@aspose/3dElemento vertice di colore per vertice
MappingMode@aspose/3dEnum: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME
ReferenceMode@aspose/3dEnum: DIRECT, INDEX, INDEX_TO_DIRECT
AnimationClip@aspose/3dAnimazione nominata; espone animations: AnimationNode[]; creata tramite scene.createAnimationClip(name)
AnimationNode@aspose/3dGruppo nominato di BindPoints; creata tramite clip.createAnimationNode(name)
BindPoint@aspose/3dAssocia un AnimationNode a una proprietà di oggetto scena; espone property e channelsCount
AnimationChannel@aspose/3dEstende KeyframeSequence; contiene un keyframeSequence; accesso tramite bindPoint.getChannel(name)
KeyFrame@aspose/3dSingola coppia di fotogrammi chiave tempo/valore; trasporta interpolation: Interpolation
KeyframeSequence@aspose/3dOrdinato keyFrames elenco; preBehavior/postBehavior sono Extrapolation oggetti
Interpolation@aspose/3dEnum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
Extrapolation@aspose/3dClasse con type: ExtrapolationType e repeatCount: number
ExtrapolationType@aspose/3dEnum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE
ObjLoadOptions@aspose/3d/formats/objOpzioni di importazione OBJ: enableMaterials, flipCoordinateSystem, scale, normalizeNormal
GltfSaveOptions@aspose/3d/formats/gltfOpzioni di esportazione glTF/GLB: binaryMode
GltfFormat@aspose/3d/formats/gltfIstanza di formato per glTF/GLB; passa a scene.save()
StlLoadOptions@aspose/3d/formats/stlOpzioni di importazione STL
StlSaveOptions@aspose/3d/formats/stlOpzioni di esportazione STL: binaryMode
StlImporter@aspose/3d/formats/stlLettore STL a basso livello
StlExporter@aspose/3d/formats/stlScrittore STL a basso livello
 Italiano