Característiques i funcionalitats
Aspose.3D FOSS per TypeScript és una biblioteca Node.js amb llicència MIT per carregar, construir i exportar escenes 3D. Ve amb definicions de tipus TypeScript completes, una única dependència d’execució (xmldom), i suport per a sis formats de fitxer 3D principals. Aquesta pàgina és la referència principal per a totes les àrees de funcionalitat i inclou exemples de codi TypeScript executables per a cadascuna d’elles.
Instal·lació i configuració
Instal·leu el paquet des de npm amb una sola comanda:
npm install @aspose/3dEl paquet apunta a CommonJS i requereix Node.js 18 o posterior. Després de la instal·lació, verifica que el teu tsconfig.json inclogui les següents opcions del compilador per a una compatibilitat completa:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Importa el principal Scene classe des de l’arrel del paquet. Les classes d’opcions específiques de format s’importen des dels seus subcamins corresponents:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';Característiques i funcionalitats
Suport de formats
Aspose.3D FOSS for TypeScript llegeix i escriu sis formats de fitxer 3D principals. La detecció del format és automàtica a partir dels números màgics binaris en carregar, de manera que no cal especificar explícitament el format d’origen.
| Format | Read | Write | Notes |
|---|---|---|---|
| OBJ (Wavefront) | Sí | Sí | Llegeix/escriu .mtl materials; ús ObjLoadOptions.enableMaterials per a la importació |
| glTF 2.0 | Sí | Sí | format de text JSON; materials PBR |
| GLB | Sí | Sí | glTF binari; establert GltfSaveOptions.binaryMode = true |
| STL | Sí | Sí | Binari i ASCII; verificat el recorregut complet |
| 3MF | Sí | Sí | 3D Manufacturing Format with color and material metadata |
| FBX | No* | No* | Existeixen importador/exportador però la detecció automàtica del format no està connectada |
| COLLADA (DAE) | Sí | Sí | Escala d’unitats, geometria, materials i clips d’animació |
Carregant OBJ amb materials:
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);Desant a GLB (glTF binari):
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 d’Escena
Tot el contingut 3D s’organitza com un arbre de Node objectes arrelats a scene.rootNode. Cada node pot portar un Entity (un Mesh, Camera, Light, o altre SceneObject) Transform que el posiciona respecte al seu pare.
Classes clau del gràfic d’escena:
Scene: el contenidor de nivell superior; contérootNodeianimationClipsNode: un node d’arbre amb nomchildNodes,entity,transform, imaterialsEntity: classe base per a objectes adjuntables (Mesh,Camera,Light)SceneObject: classe base compartida perNodeiEntityA3DObject: classe base arrel ambnamei bossa de propietatsTransform: translació local, rotació (Euler i Quaternió), i escala
Recórrer el graf d’escena:
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);Creació d’una jerarquia d’escena programàticament:
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 i Malla
Mesh és el tipus de geometria principal. Extén Geometry i exposa punts de control (vèrtexs), índexs de polígons i elements de vèrtex per a normals, UVs i colors de vèrtex.
Classes de geometria clau:
Mesh: malla de polígons ambcontrolPointsipolygonCountGeometry: classe base amb gestió d’elements de vèrtexVertexElementNormal: normals per vèrtex o per vèrtex de polígonVertexElementUV: coordenades de textura (un o més canals UV)VertexElementVertexColor: dades de color per vèrtexMappingMode: controla com les dades d’elements es mapegen a polígons (ByControlPoint,ByPolygonVertex, etc.)ReferenceMode: controla l’estratègia d’indexació (Direct,IndexToDirect)VertexElementType: identifica la semàntica d’un element de vèrtexTextureMapping: enumeració de canals de textura
Lectura de dades de malla d’una escena carregada:
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 de materials
Aspose.3D FOSS for TypeScript admet tres tipus de material que cobreixen tot el rang des de l’ombrejat Phong llegat fins al renderitzat basat en la física:
LambertMaterial: color difús i color ambient; es mapeja a materials simples OBJ/DAEPhongMaterial: afegeix color especular, lluentor i emissiu; el tipus de material OBJ per defectePbrMaterial: model basat en la física de rugositat/metàl·lic; utilitzat per a la importació i exportació de glTF 2.0
Lectura de materials d’una escena OBJ carregada:
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)}`);
}
}
}Aplicació d’un material PBR en construir una escena glTF:
import { Scene, Node, PbrMaterial } 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); // 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);Utilitats matemàtiques
La biblioteca ve amb un conjunt complet de tipus matemàtics 3D, tots completament tipats:
Vector3: vector de 3 components; admetadd,subtract,scale,dot,cross,normalize,lengthVector4: vector de 4 components per a coordenades homogèniesMatrix4: matriu de transformació 4×4 ambmultiply,invert,transpose,decomposeQuaternion: quaternió de rotació ambfromEulerAngles,toEulerAngles,slerp,normalizeBoundingBox: caixa delimitadora alineada amb els eixos ambmin,max,center,size,mergeFVector3: variant de precisió simple deVector3: utilitzat en dades d’elements de vèrtex
Calculant una caixa delimitadora a partir dels vèrtexs de la malla:
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);Construint una transformació a partir d’angles d’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));Sistema d’animació
L’API d’animació modela clips, nodes, canals i seqüències de fotogrames:
AnimationClip: col·lecció anomenada de nodes d’animació; accedida viascene.animationClipsAnimationNode: enllaça un clip a un node d’escena per nomAnimationChannel: apunta a una propietat específica (p. ex., translació X) dins d’un node d’animacióKeyFrame: una única parella temps/valorKeyframeSequence: llista ordenada deKeyFrameobjectes ambInterpolationiExtrapolationparàmetresInterpolation: mode d’interpolació de fotogrames clau:Linear,Constant,CubicExtrapolation: comportament abans/després del rang de fotogrames clau:Constant,Cycle,Mirror
Llegint dades d’animació d’una escena carregada:
import { Scene, AnimationClip, KeyframeSequence } from '@aspose/3d';
const scene = new Scene();
scene.open('animated.fbx');
for (const clip of scene.animationClips) {
console.log(`Clip: "${clip.name}"`);
for (const animNode of clip.nodes) {
console.log(` Node: ${animNode.name}`);
for (const channel of animNode.channels) {
const seq: KeyframeSequence = channel.keyframeSequence;
console.log(` Channel "${channel.name}": ${seq.keyFrames.length} keyframes`);
console.log(` Interpolation: ${seq.interpolation}`);
}
}
}Suport per a fluxos i buffers
Utilitza scene.openFromBuffer() per carregar una escena 3D directament des d’una memòria Buffer. Aquest és el patró recomanat per a funcions sense servidor, canals de transmissió i processament d’actius recuperats per HTTP sense escriure al 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);
}
}La detecció automàtica del format a partir de números màgics binaris s’aplica en carregar des d’un buffer, de manera que els fitxers GLB, STL binari i 3MF es reconeixen sense especificar un paràmetre de format.
Exemples d’ús
Exemple 1: Carrega OBJ i Exporta a GLB
Aquest exemple carrega un fitxer Wavefront OBJ amb materials i, a continuació, reexporta l’escena com a fitxer binari glTF (GLB) adequat per a ús web i en motors 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');Exemple 2: Viatge d’anada i tornada STL amb Validació de Normals
Aquest exemple carrega un fitxer STL binari, imprimeix la informació de normals per vèrtex i, a continuació, reexporta l’escena com a STL ASCII i verifica el viatge d’anada i tornada.
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);Exemple 3: Construir una Escena Programàticament i Desar com a glTF
Aquest exemple construeix una escena amb un material PBR des de zero i la desa com a fitxer JSON glTF.
import { Scene, Mesh, PbrMaterial, Vector4 } 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');Consells i bones pràctiques
- Utilitza
ObjLoadOptions.enableMaterials = truequan necessiteu dades de material dels fitxers .mtl. Sense això, la llista de materials a cada node quedarà buida. - Preferiu
binaryMode = trueper a GLB quan es produeixen actius per a la web o motors de jocs. El GLB binari és un únic fitxer autònom i es carrega més ràpidament en navegadors i motors que la separació JSON + .bin. - Utilitzeu
openFromBuffer()en entorns sense servidor per evitar I/O de fitxers temporals. Obteniu l’actiu, passeu elBufferdirectament i escriviu la sortida a un flux o a un altre buffer. - Comproveu
node.entityabans de fer el casting: no tots els nodes contenen una entitat. Sempre protegeix amb uninstanceofcomprova abans d’accedirMesh-propietats específiques com aracontrolPoints. - Conjunt
normalizeNormal = trueaObjLoadOptionsquan els teus fitxers OBJ d’origen provenen de fonts no fiables. Això impedeix que les normals degenerades es propagin cap a les etapes de renderització o validació posteriors. - Mantén
strict: truea tsconfig.json: la biblioteca està escrita ambnoImplicitAnyistrictNullChecks. Desactivarstrictamaga errors de tipus reals i nega el valor de l’API tipada. - Recorre via
childNodes, no un bucle d’índex: elchildNodesla propietat retorna un iterable; evita confiar en l’indexació numèrica per a una compatibilitat futura.
Problemes comuns
| Símptoma | Causa probable | Solució |
|---|---|---|
| Llista de materials buida després de carregar OBJ | enableMaterials no establert | Establir options.enableMaterials = true |
| El fitxer GLB conté un sidecar .bin separat | binaryMode per defecte a false | Establir opts.binaryMode = true |
| Falten les normals de vèrtex a la sortida STL | El mode STL ASCII omet les normals per cara | Canvia a binaryMode = true o calcula les normals abans d’exportar |
node.entity és sempre null | Només recorrent rootNode, no els seus fills | Recórrer a node.childNodes |
| Error de TypeScript: la propietat no existeix | Antic @types memòria cau | Executa npm install @aspose/3d de nou; sense separació @types es necessita el paquet |
openFromBuffer llança un error de format | El format no es pot detectar automàticament a partir del magic | Passa la classe d’opció de format explícita com a segon argument |
Preguntes Freqüents
Requereix la biblioteca algun complement natiu o paquets del sistema? No. Aspose.3D FOSS per a TypeScript té una única dependència d’execució: xmldom, que és JavaScript pur i s’instal·la automàticament amb npm. No hi ha .node extensions natives i cap paquet del sistema per instal·lar.
Quines versions de Node.js són compatibles? Node.js 18, 20 i 22 LTS. La biblioteca apunta a una sortida CommonJS i utilitza característiques del llenguatge ES2020 internament.
Puc utilitzar la biblioteca en un paquet per al navegador (webpack/esbuild)? La biblioteca apunta a Node.js i utilitza el Node.js fs i Buffer API. L’empaquetat per al navegador no està oficialment suportat. Per a ús en navegador, carrega l’escena al servidor i transmet el resultat (p. ex., com a GLB) al client.
Quina és la diferència entre GltfSaveOptions.binaryMode = true i false? binaryMode = false genera un .gltf fitxer JSON més un separat .bin sidecar de buffer binari. binaryMode = true produeix un únic auto‑contingut .glb fitxer. Utilitzeu true per a la distribució d’actius en producció.
Puc carregar un fitxer des d’una resposta HTTP sense desar‑lo al disc? Sí. Recupera la resposta com a Buffer (p. ex., amb node-fetch o la integrada fetch a Node 18+), i després crida scene.openFromBuffer(buffer, options).
El suport per a FBX és complet? La lectura i escriptura de FBX són compatibles per a la jerarquia d’escena, les malles i les dades geomètriques, els clips d’animació i els materials. Els fitxers FBX altament complexos amb mitjans incrustats poden produir resultats parcials; proveu amb el vostre corpus d’actius específic.
La biblioteca admet TypeScript 4.x? Es recomana TypeScript 5.0+. TypeScript 4.7+ hauria de funcionar en la pràctica, però la biblioteca es prova i es desenvolupa contra 5.0+.
Resum de la referència de l’API
| Classe | Mòdul | Propòsit |
|---|---|---|
Scene | @aspose/3d | Contenidor d’escena de nivell superior; open(), openFromBuffer(), save(), rootNode, animationClips |
Node | @aspose/3d | Node del graf d’escena; childNodes, entity, transform, materials, createChildNode() |
Entity | @aspose/3d | Classe base per a objectes que es poden adjuntar a l’escena |
SceneObject | @aspose/3d | Classe base compartida per Node i Entity |
A3DObject | @aspose/3d | Base arrel amb name i bossa de propietats |
Transform | @aspose/3d | Traslació, rotació i escala locals |
Mesh | @aspose/3d | Malla de polígons; controlPoints, polygonCount, createPolygon(), elements de vèrtex |
Geometry | @aspose/3d | Classe base per a tipus de geometria |
Camera | @aspose/3d | Entitat de càmera amb camp de visió i configuracions de projecció |
Light | @aspose/3d | Entitat de llum (puntual, direccional, spot) |
LambertMaterial | @aspose/3d | Model d’ombrejat difús + ambient |
PhongMaterial | @aspose/3d | Ombrejat Phong amb especular i emissiu |
PbrMaterial | @aspose/3d | Model físicament basat en rugositat/metàl·lic per a glTF |
Vector3 | @aspose/3d | 3-component double-precision vector |
Vector4 | @aspose/3d | 4-component vector for homogeneous math |
Matrix4 | @aspose/3d | 4×4 transformation matrix |
Quaternion | @aspose/3d | Quaternió de rotació |
BoundingBox | @aspose/3d | Caixa delimitadora alineada a l’eix |
FVector3 | @aspose/3d | Variant de precisió simple de Vector3 |
VertexElementNormal | @aspose/3d | Normals per vèrtex o per vèrtex de polígon |
VertexElementUV | @aspose/3d | Element de vèrtex de coordenada de textura |
VertexElementVertexColor | @aspose/3d | Element de vèrtex de color per vèrtex |
MappingMode | @aspose/3d | Enumeració: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME |
ReferenceMode | @aspose/3d | Enumeració: Direct, IndexToDirect |
AnimationClip | @aspose/3d | Animació anomenada; conté AnimationNode llista |
AnimationNode | @aspose/3d | Enllaça el clip al node d’escena; conté AnimationChannel llista |
AnimationChannel | @aspose/3d | Apunta a una propietat; conté KeyframeSequence |
KeyFrame | @aspose/3d | Parella única de fotograma clau temps/valor |
KeyframeSequence | @aspose/3d | Llista ordenada de fotogrames clau amb interpolació i extrapolació |
Interpolation | @aspose/3d | Enumeració: Linear, Constant, Cubic |
Extrapolation | @aspose/3d | Enumeració: Constant, Cycle, Mirror |
ObjLoadOptions | @aspose/3d/formats/obj | Opcions d’importació OBJ: enableMaterials, flipCoordinateSystem, scale, normalizeNormal |
GltfSaveOptions | @aspose/3d/formats/gltf | Opcions d’exportació glTF/GLB: binaryMode |
GltfFormat | @aspose/3d/formats/gltf | Instància de format per a glTF/GLB; passa a scene.save() |
StlLoadOptions | @aspose/3d/formats/stl | Opcions d’importació STL |
StlSaveOptions | @aspose/3d/formats/stl | Opcions d’exportació STL: binaryMode |
StlImporter | @aspose/3d/formats/stl | Lector STL de baix nivell |
StlExporter | @aspose/3d/formats/stl | Escriptor STL de baix nivell |