Cum să încarci modele 3D în TypeScript

Cum să încarci modele 3D în TypeScript

The @aspose/3d pachetul oferă aplicațiilor TypeScript și Node.js o API simplă pentru deschiderea fișierelor de scenă 3D. Scene este obiectul rădăcină: apelați scene.open() cu o cale de fișier și opțiuni de încărcare opționale specifice formatului, apoi parcurgeți scene.rootNode pentru a accesa geometria, materialele și transformările.

Ghid pas cu pas

Pasul 1: Instalați @aspose/3d prin npm

Adăugați pachetul în proiectul dumneavoastră. Nu sunt necesare binare native sau unelte de compilare specifice platformei; este nevoie doar de Node.js 18 sau o versiune ulterioară.

npm install @aspose/3d

Pentru proiectele TypeScript, definițiile de tip sunt incluse în pachet:

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

Pasul 2: Importați Scene și opțiunile specifice formatului

Fiecare format expune propria clasă de încărcare și obiectul de opțiuni sub un sub‑path. Importați doar ceea ce aveți nevoie:

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

Pentru alte formate modelul este identic:

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

Pasul 3: Deschideți un fișier 3D utilizând scene.open()

Creați un Scene instanță, apoi apelați scene.open() cu calea fișierului și un obiect de opțiuni de încărcare opțional. Apelul este sincron.

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

Pentru a încărca dintr-un Buffer deja în memorie (util în contexte serverless sau 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());

Pasul 4: Iterați peste nodurile scenei

Graful de scenă este un arbore cu rădăcina la scene.rootNode. Fiecare Node poate conține noduri copil și un opțional entity (mesh, cameră, lumină, 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);

Pasul 5: Accesați datele vârfurilor mesh-ului prin controlPoints

Când entitatea unui nod este un Mesh, poți citi punctele de control brute (vârfuri) din controlPoints array. Fiecare intrare este un Vector4 cu x, y, z, și w componente.

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

Pasul 6: Configurați ObjLoadOptions pentru încărcarea materialelor

ObjLoadOptions expune proprietăți pentru a controla modul în care însoțitor .mtl fișierele de material și texturile sunt rezolvate.

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.entity && node.entity.material) {
        console.log(`Material on "${node.name}": ${node.entity.material.constructor.name}`);
    }
}

Probleme comune și soluții

Eroare: Nu se poate găsi modulul ‘@aspose/3d/formats/obj’ Sub-căile de format necesită exporturi de pachete Node.js 12.7+. Asigurați-vă că utilizați Node.js 18 sau o versiune ulterioară. Dacă folosiți TypeScript, setați "moduleResolution": "node16" sau "bundler" în tsconfig.json.

scene.rootNode.childNodes este gol după open() Unele fișiere OBJ folosesc sfârșite de linie ne-standard sau nu au un newline la final. Verificați că fișierul este un OBJ valid deschizându-l într-un editor de text. De asemenea, confirmați că ați transmis ObjLoadOptions și nu un generic LoadOptions: opțiunile specifice formatului sunt necesare pentru o distribuție corectă.

array-ul controlPoints are lungime zero Mesh-ul ar fi putut fi încărcat, dar nu conține geometrie (de ex., un grup gol în OBJ). Folosiți mesh.polygonCount pentru a verifica înainte de a itera vârfurile.

Utilizarea memoriei este ridicată pentru fișiere mari Încărcare-din-buffer cu scene.openFromBuffer() nu reduce memoria maximă: întregul fișier trebuie analizat. Pentru fișiere mari (> 100 MB), asigură-te că procesul tău Node.js are suficient heap: node --max-old-space-size=4096 yourScript.js.

Erori de tip: ’entity’ este de tip ‘unknown’ Proprietatea entity este tipizată larg. Conversia la any sau la o clasă specifică (Mesh, Camera, etc.) în funcție de ce aștepți în scenă.

Întrebări frecvente (FAQ)

Ce formate pot fi încărcate cu scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX și COLLADA (.dae) sunt toate suportate pentru import. Transmite *LoadOptions clasa pentru fiecare format.

Pot să încarc un fișier fără a specifica opțiuni? Da. scene.open('model.glb') funcționează fără opțiuni pentru formatele care nu necesită configurare specială. Transmiterea opțiunilor este recomandată pentru OBJ deoarece rezoluția materialului depinde de enableMaterials.

Se execută încărcarea asincron? Nu. scene.open() și scene.openFromBuffer() sunt sincrone. Împachetează-le într-un fir de lucru sau setImmediate dacă trebuie să menții un buclă de evenimente receptivă.

Este suportat exportul OBJ? Da. Exportul OBJ este suportat prin scene.save('output.obj'). The .mtl fișierul material este scris automat alături de .obj fișierul.

Unde se așteaptă fișierul .mtl la încărcarea unui OBJ? În mod implicit, parserul caută .mtl fișierul referențiat în interiorul OBJ-ului (mtllib directivă) relativ la directorul fișierului OBJ. Asigurați-vă că ambele fișiere se află în același folder.

Vezi și

 Română