Hur man laddar 3D-modeller i TypeScript
Den @aspose/3d paketet ger TypeScript- och Node.js-applikationer ett enkelt API för att öppna 3D-scenfiler. Scene är rotobjektet: anropa scene.open() med en filsökväg och valfria format‑specifika laddningsalternativ, och sedan traversera scene.rootNode för att komma åt geometri, material och transformationer.
Steg-för-steg-guide
Steg 1: Installera @aspose/3d via npm
Lägg till paketet i ditt projekt. Inga inhemska binärer eller plattforms‑specifika byggverktyg krävs; endast Node.js 18 eller senare.
npm install @aspose/3dFör TypeScript‑projekt är typdefinitionerna medföljande i paketet:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}Steg 2: Importera Scene och format‑specifika alternativ
Varje format exponerar sin egen laddarklass och options‑objekt under en under‑sökväg. Importera bara det du behöver:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';För andra format är mönstret identiskt:
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';Steg 3: Öppna en 3D‑fil med scene.open()
Skapa en Scene instans, och sedan anropa scene.open() med filsökvägen och ett valfritt laddningsalternativ‑objekt. Anropet är synkront.
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');För att ladda från en Buffer redan i minnet (användbart i serverlösa eller strömningssammanhang):
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());Steg 4: Iterera över scen‑noder
Scengrafen är ett träd med rot i scene.rootNode. Varje Node kan innehålla barnnoder och ett valfritt entity (mesh, kamera, ljus osv.).
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);Steg 5: Åtkomst till mesh‑vertex‑data via controlPoints
När en nods entitet är en Mesh,kan du läsa de råa kontrollpunkterna (vertices) från the controlPoints array. Varje post är en Vector4 med x, y, z, och w komponenter.
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)}`);
}
}
}Steg 6: Konfigurera ObjLoadOptions för materialinläsning
ObjLoadOptions exponerar egenskaper för att styra hur medföljande .mtl materialfiler och texturer löses upp.
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}`);
}
}Vanliga problem och lösningar
Fel: Kan inte hitta modulen ‘@aspose/3d/formats/obj’ Formatets under‑sökvägar kräver Node.js 12.7+ paketexport. Se till att du använder Node.js 18 eller senare. Om du använder TypeScript, ange "moduleResolution": "node16" eller "bundler" i tsconfig.json.
scene.rootNode.childNodes är tom efter open() Vissa OBJ-filer använder icke‑standard radslut eller saknar en avslutande ny rad. Verifiera att filen är en giltig OBJ genom att öppna den i en textredigerare. Bekräfta också att du har skickat ObjLoadOptions och inte en generisk LoadOptions: format‑specifika alternativ krävs för korrekt dispatch.
controlPoints‑arrayen har noll längd Nätet kan ha lästs in men innehåller ingen geometri (t.ex. en tom grupp i OBJ). Använd mesh.polygonCount för att kontrollera innan du itererar över vertexar.
Minnesanvändningen är hög för stora filer Läs‑från‑buffer med scene.openFromBuffer() minskar inte toppminnet: hela filen måste parsas. För stora filer (> 100 MB), se till att din Node.js‑process har tillräckligt heap‑utrymme: node --max-old-space-size=4096 yourScript.js.
Typfel: ’entity’ är av typen ‘unknown’ Den entity egenskapen är typad brett. Kasta till any eller till en specifik klass (Mesh, Camera, etc.) beroende på vad du förväntar dig i din scen.
Vanliga frågor (FAQ)
Vilka format kan laddas med scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX och COLLADA (.dae) stöds alla för import. Skicka den motsvarande *LoadOptions klassen för varje format.
Kan jag ladda en fil utan att ange alternativ? Ja. scene.open('model.glb') fungerar utan alternativ för format som inte kräver speciell konfiguration. Att skicka alternativ rekommenderas för OBJ eftersom materialupplösning beror på enableMaterials.
Kör laddning asynkront? Nej. scene.open() och scene.openFromBuffer() är synkrona. Packa in dem i en worker-tråd eller setImmediate om du behöver hålla en händelseslinga responsiv.
Stöds OBJ-export? Ja. OBJ-export stöds via scene.save('output.obj'). Den .mtl materialfilen skrivs automatiskt bredvid den .obj fil.
Var förväntas .mtl-filen vara när OBJ laddas? Som standard letar parsern efter .mtl fil som refereras inuti OBJ (mtllib direktiv) relativt till OBJ-filens katalog. Se till att båda filerna är i samma mapp.