Características y Funcionalidades

Características y Funcionalidades

Aspose.3D FOSS para TypeScript es una biblioteca de Node.js bajo licencia MIT para cargar, construir y exportar escenas 3D. Se entrega con definiciones de tipos completas de TypeScript, una única dependencia en tiempo de ejecución (xmldom), y soporte para seis formatos de archivo 3D principales. Esta página es la referencia principal para todas las áreas de funcionalidad e incluye ejemplos de código TypeScript ejecutables para cada una.

Instalación y configuración

Instala el paquete desde npm usando un solo comando:

npm install @aspose/3d

El paquete está dirigido a CommonJS y requiere Node.js 18 o posterior. Después de la instalación, verifica que tu tsconfig.json incluya las siguientes opciones del compilador para una compatibilidad total:

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

Importa el principal Scene clase desde la raíz del paquete. Las clases de opciones específicas de formato se importan desde sus sub‑rutas respectivas:

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

Características y Funcionalidades

Compatibilidad de formatos

Aspose.3D FOSS for TypeScript lee y escribe seis formatos de archivo 3D principales. La detección de formato es automática a partir de los números mágicos binarios al cargar, por lo que no es necesario especificar el formato de origen explícitamente.

FormatoLeerEscribirNotas
OBJ (Wavefront)Lee/escribe .mtl materiales; usar ObjLoadOptions.enableMaterials para importación
glTF 2.0Formato de texto JSON; materiales PBR
GLBglTF binario; establecido GltfSaveOptions.binaryMode = true
STLBinario y ASCII; verificado el ciclo completo
3MF3D Manufacturing Format with color and material metadata
FBXNo*No*El importador/exportador existe pero la detección automática del formato no está conectada
COLLADA (DAE)Escala de unidades, geometría, materiales y clips de animación

Cargando OBJ con materiales:

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

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

Grafo de escena

Todo el contenido 3D se organiza como un árbol de Node objetos con raíz en scene.rootNode. Cada nodo puede llevar un Entity (un Mesh, Camera, Light, o otro SceneObject) Transform que lo posiciona relativo a su padre.

Clases clave del grafo de escena:

  • Scene: el contenedor de nivel superior; contiene rootNode y animationClips
  • Node: un nodo de árbol con nombre con childNodes, entity, transform, y materials
  • Entity: clase base para objetos adjuntables (Mesh, Camera, Light)
  • SceneObject: clase base compartida por Node y Entity
  • A3DObject: clase base raíz con name y bolsa de propiedades
  • Transform: traslación local, rotación (Euler y Cuaternión), y escala

Recorriendo el grafo de 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);

Crear una jerarquía de escena programáticamente:

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

Geometría y Malla

Mesh es el tipo de geometría principal. Extiende Geometry y expone puntos de control (vértices), índices de polígonos y elementos de vértice para normales, UVs y colores de vértice.

Clases clave de geometría:

  • Mesh: malla de polígonos con controlPoints y polygonCount
  • Geometry: clase base con gestión de elementos de vértice
  • VertexElementNormal: normales por vértice o por vértice de polígono
  • VertexElementUV: coordenadas de textura (uno o más canales UV)
  • VertexElementVertexColor: datos de color por vértice
  • MappingMode: controla cómo se asignan los datos de los elementos a los polígonos (CONTROL_POINT, POLYGON_VERTEX, POLYGON, EDGE, ALL_SAME)
  • ReferenceMode: controla la estrategia de indexado (DIRECT, INDEX, INDEX_TO_DIRECT)
  • VertexElementType: identifica la semántica de un elemento de vértice
  • TextureMapping: enumeración de canales de textura

Lectura de datos de malla de una escena cargada:

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 materiales

Aspose.3D FOSS para TypeScript soporta tres tipos de material que cubren todo el rango, desde el sombreado Phong heredado hasta el renderizado basado en física:

  • LambertMaterial: color difuso y color ambiental; se asigna a materiales simples OBJ/DAE
  • PhongMaterial: añade color especular, brillo y emisivo; el tipo de material OBJ predeterminado
  • PbrMaterial: modelo físico de rugosidad/metallicidad; usado para importación y exportación glTF 2.0

Leyendo materiales de una escena OBJ cargada:

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

Aplicando un material PBR al construir una escena 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);

Utilidades matemáticas

La biblioteca incluye un conjunto completo de tipos matemáticos 3D, todos totalmente tipados:

  • Vector3: vector de 3 componentes; soporta minus(), times(), dot(), cross(), normalize(), length, angleBetween()
  • Vector4: vector de 4 componentes para coordenadas homogéneas
  • Matrix4: matriz de transformación 4×4 con concatenate(), transpose, decompose, setTRS
  • Quaternion: cuaternión de rotación con fromEulerAngle() : (estático, singular), eulerAngles() : (método de instancia), slerp(), normalize()
  • BoundingBox: caja delimitadora alineada a los ejes con minimum, maximum, center, size, merge
  • FVector3: variante de precisión simple de Vector3 : utilizado en datos de elementos de vértice

Calculando una caja delimitadora a partir de los vértices 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);

Construyendo una transformación a partir de ángulos de 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 de Animación

La API de animación modela clips, nodos, canales y secuencias de fotogramas clave:

  • AnimationClip: colección nombrada de nodos de animación; accedida a través de scene.animationClips;: ; expone animations: AnimationNode[]
  • AnimationNode: grupo nombrado de BindPoint: s; creado mediante clip.createAnimationNode(name), accedido a través de clip.animations
  • BindPoint: enlaza un AnimationNode : a una propiedad específica en un objeto de escena; expone property : y channelsCount
  • AnimationChannel: extiende KeyframeSequence; contiene un separado keyframeSequence; accedido a través de bindPoint.getChannel(name)
  • KeyFrame: un único par tiempo/valor; lleva por fotograma clave interpolation: Interpolation
  • KeyframeSequence: lista ordenada de KeyFrame objetos a través de keyFrames; tiene preBehavior y postBehavior (Extrapolation)
  • Interpolation: enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
  • Extrapolation: clase con type: ExtrapolationType y repeatCount: number
  • ExtrapolationType: enum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE

Leyendo datos de animación de una escena cargada:

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

Soporte de Stream y Buffer

Usar scene.openFromBuffer() para cargar una escena 3D directamente desde una memoria Buffer. Este es el patrón recomendado para funciones sin servidor, canalizaciones de transmisión y procesamiento de recursos obtenidos mediante HTTP sin escribir en 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);
  }
}

La detección automática de formato a partir de los números mágicos binarios se aplica al cargar desde un buffer, por lo que los archivos GLB, STL binario y 3MF se reconocen sin especificar un parámetro de formato.

Ejemplos de uso

Ejemplo 1: Cargar OBJ y Exportar a GLB

Este ejemplo carga un archivo Wavefront OBJ con materiales, y luego vuelve a exportar la escena como un archivo glTF binario (GLB) adecuado para uso web y en motores de juego.

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

Ejemplo 2: Recorrido completo STL con Validación de Normales

Este ejemplo carga un archivo STL binario, muestra la información de normales por vértice, y luego vuelve a exportar la escena como STL ASCII y verifica el recorrido completo.

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

Ejemplo 3: Construir una escena programáticamente y guardarla como glTF

Este ejemplo construye una escena con un material PBR desde cero y la guarda como un archivo glTF JSON.

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

Consejos y mejores prácticas

  • Usar ObjLoadOptions.enableMaterials = true cuando necesites datos de material de archivos .mtl. Sin ello, la lista de materiales en cada nodo estará vacía.
  • Preferir binaryMode = true para GLB al producir activos para web o motores de juego. El GLB binario es un único archivo autónomo y se carga más rápido en navegadores y motores que la división JSON + .bin.
  • Usar openFromBuffer() en entornos sin servidor para evitar E/S de archivos temporales. Obtén el activo, pasa el Buffer directamente, y escribe la salida a un flujo o a otro búfer.
  • Verificar node.entity antes de convertir: no todos los nodos llevan una entidad. Siempre protege con un instanceof verifique antes de acceder Mesh-propiedades específicas como controlPoints.
  • Establecer normalizeNormal = true en ObjLoadOptions cuando sus archivos OBJ de origen provienen de fuentes no confiables. Esto evita que normales degeneradas se propaguen a los pasos posteriores de renderizado o validación.
  • Mantenga strict: true en tsconfig.json: la biblioteca está escrita con noImplicitAny y strictNullChecks. Desactivar strict oculta errores de tipo reales y anula el valor de la API tipada.
  • Recorrer vía childNodes, no un bucle de índice: el childNodes la propiedad devuelve un iterable; evite depender del indexado numérico para mantener la compatibilidad futura.

Problemas comunes

SíntomaCausa probableSolución
Lista de materiales vacía después de cargar OBJenableMaterials no establecidoEstablecer options.enableMaterials = true
El archivo GLB contiene un sidecar .bin separadobinaryMode predeterminando a falseEstablecer opts.binaryMode = true
Faltan normales de vértice en la salida STLEl modo ASCII de STL omite las normales por caraCambiar a binaryMode = true o calcular normales antes de exportar
node.entity es siempre nullRecorriendo solo rootNode, no sus hijosRecursar en node.childNodes
Error de TypeScript: la propiedad no existeAntiguo @types cachéEjecutar npm install @aspose/3d de nuevo; sin separado @types se necesita el paquete
openFromBuffer lanza error de formatoFormato no detectable automáticamente a partir del magicPase la clase de opción de formato explícita como segundo argumento

Preguntas Frecuentes

¿Requiere la biblioteca algún complemento nativo o paquetes del sistema? No. Aspose.3D FOSS para TypeScript tiene una única dependencia en tiempo de ejecución: xmldom, que es JavaScript puro y se instala automáticamente mediante npm. No hay .node complementos nativos y sin paquetes del sistema que instalar.

¿Qué versiones de Node.js son compatibles? Node.js 18, 20 y 22 LTS. La biblioteca tiene como objetivo una salida CommonJS y utiliza características del lenguaje ES2020 internamente.

¿Puedo usar la biblioteca en un paquete para navegador (webpack/esbuild)? La biblioteca tiene como objetivo Node.js y utiliza el Node.js fs y Buffer APIs. El empaquetado para navegador no está oficialmente soportado. Para uso en navegador, cargue la escena del lado del servidor y transmita el resultado (p. ej., como GLB) al cliente.

¿Cuál es la diferencia entre GltfSaveOptions.binaryMode = true y false? binaryMode = false produce un .gltf archivo JSON más un separado .bin sidecar de búfer binario. binaryMode = true produce un único auto‑contenible .glb archivo. Use true para la entrega de activos en producción.

¿Puedo cargar un archivo desde una respuesta HTTP sin guardarlo en disco? Sí. Obtenga la respuesta como una Buffer (p. ej., usando node-fetch o la incorporada fetch en Node 18+), luego llame scene.openFromBuffer(buffer, options).

¿Está completo el soporte de FBX? No. Existen clases de importador y exportador de FBX en la biblioteca, pero FBX no está integrado en Scene.open() o Scene.save() detección automática. Llamar scene.open('file.fbx') no invocará el importador FBX; el archivo será manejado por la ruta de respaldo STL. Use directamente las clases importador/exportador específicas de FBX si necesita I/O de FBX. Consulte la tabla de soporte de formatos arriba que marca FBX como No*.

¿La biblioteca admite TypeScript 4.x? Se recomienda TypeScript 5.0+. TypeScript 4.7+ debería funcionar en la práctica, pero la biblioteca se prueba y se desarrolla contra 5.0+.

Resumen de la Referencia de API

ClaseMóduloPropósito
Scene@aspose/3dContenedor de escena de nivel superior; open(), openFromBuffer(), save(), rootNode, animationClips
Node@aspose/3dNodo del grafo de escena; childNodes, entity, transform, materials, createChildNode()
Entity@aspose/3dClase base para objetos que se pueden adjuntar a la escena
SceneObject@aspose/3dClase base compartida por Node y Entity
A3DObject@aspose/3dBase raíz con name y bolsa de propiedades
Transform@aspose/3dTraslación, rotación y escala locales
Mesh@aspose/3dMalla poligonal; controlPoints, polygonCount, createPolygon(), elementos de vértice
Geometry@aspose/3dClase base para tipos de geometría
Camera@aspose/3dentidad de cámara con campo de visión y configuraciones de proyección
Light@aspose/3dentidad de luz (puntual, direccional, foco)
LambertMaterial@aspose/3dModelo de sombreado difuso + ambiental
PhongMaterial@aspose/3dPhong shading con specular y emissive
PbrMaterial@aspose/3dModelo basado en la física de rugosidad/metallic para glTF
Vector3@aspose/3d3-component double-precision vector
Vector4@aspose/3d4-component vector for homogeneous math
Matrix4@aspose/3d4×4 transformation matrix
Quaternion@aspose/3dCuaternión de rotación
BoundingBox@aspose/3dCaja delimitadora alineada a los ejes
FVector3@aspose/3dVariante de precisión simple de Vector3
VertexElementNormal@aspose/3dNormales por vértice o por vértice de polígono
VertexElementUV@aspose/3dElemento de vértice de coordenada de textura
VertexElementVertexColor@aspose/3dElemento de vértice de color por vértice
MappingMode@aspose/3dEnum: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME
ReferenceMode@aspose/3dEnum: DIRECT, INDEX, INDEX_TO_DIRECT
AnimationClip@aspose/3dAnimación nombrada; expone animations: AnimationNode[]; creado mediante scene.createAnimationClip(name)
AnimationNode@aspose/3dGrupo nombrado de BindPoints; creado mediante clip.createAnimationNode(name)
BindPoint@aspose/3dVincula un AnimationNode a una propiedad de objeto de escena; expone property y channelsCount
AnimationChannel@aspose/3dAmplía KeyframeSequence; contiene un keyframeSequence; accedido a través de bindPoint.getChannel(name)
KeyFrame@aspose/3dPar de fotogramas clave de tiempo/valor único; lleva interpolation: Interpolation
KeyframeSequence@aspose/3dOrdenado keyFrames lista; preBehavior/postBehavior son Extrapolation objetos
Interpolation@aspose/3dEnum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
Extrapolation@aspose/3dClase con type: ExtrapolationType y repeatCount: number
ExtrapolationType@aspose/3dEnum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE
ObjLoadOptions@aspose/3d/formats/objOpciones de importación OBJ: enableMaterials, flipCoordinateSystem, scale, normalizeNormal
GltfSaveOptions@aspose/3d/formats/gltfOpciones de exportación glTF/GLB: binaryMode
GltfFormat@aspose/3d/formats/gltfInstancia de formato para glTF/GLB; pasar a scene.save()
StlLoadOptions@aspose/3d/formats/stlOpciones de importación STL
StlSaveOptions@aspose/3d/formats/stlOpciones de exportación STL: binaryMode
StlImporter@aspose/3d/formats/stlLector STL de bajo nivel
StlExporter@aspose/3d/formats/stlEscritor STL de bajo nivel
 Español