Com carregar models 3D a TypeScript

Com carregar models 3D a TypeScript

El paquet @aspose/3d ofereix a les aplicacions TypeScript i Node.js una API senzilla per obrir fitxers d’escena 3D. Scene és l’objecte arrel: crideu scene.open() amb una ruta de fitxer i opcions de càrrega específiques del format, i després recorreu scene.rootNode per accedir a la geometria, els materials i les transformacions.

Guia pas a pas

Pas 1: Instal·la @aspose/3d via npm

Afegeix el paquet al teu projecte. No es necessiten binaris natius ni eines de construcció específiques de la plataforma; només Node.js 18 o posterior.

npm install @aspose/3d

Per als projectes TypeScript, les definicions de tipus s’inclouen amb el paquet:

##tsconfig.json: minimum required settings
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true
  }
}

Pas 2: Importa l’Escena i les opcions específiques del format

Cada format exposa la seva pròpia classe de carregador i l’objecte d’opcions sota un subcamí. Importa només el que necessites:

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

Per a altres formats, el patró és idèntic:

import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';

Pas 3: Obre un fitxer 3D utilitzant scene.open()

Creeu una instància Scene, després crideu scene.open() amb el camí del fitxer i un objecte d’opcions de càrrega opcional. La crida és sincrònica.

import { Scene } 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);
console.log('Scene loaded successfully');

Per carregar des d’un Buffer ja a la memòria (útil en entorns sense servidor o de streaming):

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

const buffer = fs.readFileSync('model.obj');
const scene = new Scene();
scene.openFromBuffer(buffer, new ObjLoadOptions());

Pas 4: Iterar sobre els nodes de l’escena

El graf de escena és un arbre arrelat a scene.rootNode. Cada Node pot contenir nodes fills i un entity opcional (malla, càmera, llum, etc.).

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

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

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

visitNode(scene.rootNode);

Pas 5: Accedir a les dades de vèrtex de la malla via controlPoints

Quan l’entitat d’un node és un Mesh, podeu llegir els punts de control en brut (vèrtexs) de la matriu controlPoints. Cada entrada és un Vector4 amb components x, y, z i w.

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

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

for (const node of scene.rootNode.childNodes) {
    if (!node.entity) continue;
    const entity = node.entity;
    // Check if the entity is a Mesh by duck-typing controlPoints
    if ('controlPoints' in entity) {
        const mesh = entity as any;
        console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices`);
        // Print first three vertices
        for (let i = 0; i < Math.min(3, mesh.controlPoints.length); i++) {
            const v = mesh.controlPoints[i];
            console.log(`  v[${i}]: x=${v.x.toFixed(4)}, y=${v.y.toFixed(4)}, z=${v.z.toFixed(4)}`);
        }
    }
}

Pas 6: Configura ObjLoadOptions per a la càrrega de materials

ObjLoadOptions exposa propietats per controlar com es resolen els fitxers de material .mtl i les textures adjuntes.

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

const options = new ObjLoadOptions();
options.enableMaterials = true;   // parse .mtl file if present

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

// Inspect materials attached to nodes
for (const node of scene.rootNode.childNodes) {
    if (node.material) {
        console.log(`Material on "${node.name}": ${node.material.constructor.name}`);
    }
}

Problemes comuns i solucions

Error: No es pot trobar el mòdul ‘@aspose/3d/formats/obj’ Els subcamins de format requereixen exportacions de paquets de Node.js 12.7+. Assegureu-vos que esteu a Node.js 18 o posterior. Si utilitzeu TypeScript, establiu "moduleResolution": "node16" o "bundler" a tsconfig.json.

scene.rootNode.childNodes està buit després de open()
Alguns fitxers OBJ utilitzen salts de línia no estàndard o no tenen una nova línia final. Verifiqueu que el fitxer sigui un OBJ vàlid obrint-lo en un editor de text. També confirmeu que heu passat ObjLoadOptions i no un genèric LoadOptions: les opcions específiques del format són necessàries per al correcte encaminament.

La matriu controlPoints té longitud zero
La malla pot haver estat carregada però no conté geometria (p. ex., un grup buit a l’OBJ). Utilitzeu mesh.polygonCount per comprovar abans d’iterar els vèrtexs.

L’ús de memòria és alt per a fitxers grans
Load-from-buffer amb scene.openFromBuffer() no redueix la memòria màxima: s’ha d’analitzar tot el fitxer. Per a fitxers grans (> 100 MB), assegureu-vos que el vostre procés Node.js disposi de prou heap: node --max-old-space-size=4096 yourScript.js.

Errors de tipus: ’entity’ és de tipus ‘unknown’ La propietat entity està tipada de manera àmplia. Fes un cast a any o a una classe específica (Mesh, Camera, etc.) segons el que esperes a la teva escena.

Preguntes freqüents (FAQ)

Quins formats es poden carregar amb scene.open()?
OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX i COLLADA (.dae) són tots compatibles per a la importació. Passeu la classe *LoadOptions corresponent per a cada format.

Puc carregar un fitxer sense especificar opcions?
Sí. scene.open('model.glb') funciona sense opcions per a formats que no requereixen configuració especial. Passar opcions es recomana per a OBJ perquè la resolució del material depèn de enableMaterials.

La càrrega s’executa de manera asíncrona?
No. scene.open() i scene.openFromBuffer() són sincrònics. Envolta’ls en un fil de treball o setImmediate si necessites mantenir un bucle d’esdeveniments responsiu.

L’exportació OBJ està suportada?
Sí. L’exportació OBJ està suportada a través de scene.save('output.obj'). El fitxer de material .mtl s’escriu automàticament al costat del fitxer .obj.

On es espera el fitxer .mtl quan es carrega OBJ?
Per defecte, l’analitzador busca el fitxer .mtl referenciat dins de l’OBJ (directiva mtllib) relatiu al directori del fitxer OBJ. Assegureu-vos que ambdós fitxers estiguin a la mateixa carpeta.

Vegeu també

 Català