Wie man 3D-Modelle in TypeScript lädt
Das @aspose/3d-Paket bietet TypeScript- und Node.js-Anwendungen eine unkomplizierte API zum Öffnen von 3D‑Szenendateien. Scene ist das Root‑Objekt: Rufen Sie scene.open() mit einem Dateipfad und optionalen format‑spezifischen Ladeoptionen auf, und traversieren Sie dann scene.rootNode, um auf Geometrie, Materialien und Transformationen zuzugreifen.
Schritt-für-Schritt-Anleitung
Schritt 1: Installieren Sie @aspose/3d über npm
Fügen Sie das Paket zu Ihrem Projekt hinzu. Keine nativen Binärdateien oder plattformspezifischen Build‑Tools sind erforderlich; nur Node.js 18 oder höher.
npm install @aspose/3dFür TypeScript-Projekte werden die Typdefinitionen mit dem Paket gebündelt:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}Schritt 2: Szene importieren und formatbezogene Optionen
Jedes Format stellt seine eigene Loader‑Klasse und Options‑Objekt unter einem Unterpfad bereit. Importieren Sie nur das, was Sie benötigen:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';Für andere Formate ist das Muster identisch:
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';Schritt 3: Öffnen Sie eine 3D-Datei mit scene.open()
Erstellen Sie eine Scene‑Instanz und rufen Sie dann scene.open() mit dem Dateipfad und einem optionalen load‑options‑Objekt auf. Der Aufruf ist synchron.
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');Um aus einem Buffer, das bereits im Speicher ist, zu laden (nützlich in serverlosen oder Streaming‑Kontexten):
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());Schritt 4: Durchlaufen von Szenenknoten
Der Szenengraph ist ein Baum, dessen Wurzel scene.rootNode ist. Jeder Node kann Kindknoten und optional ein entity (Mesh, Kamera, Licht usw.) enthalten.
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);Schritt 5: Zugriff auf Mesh‑Vertex‑Daten über controlPoints
Wenn die Entität eines Knotens ein Mesh ist, können Sie die rohen Kontrollpunkte (Scheitelpunkte) aus dem controlPoints‑Array lesen. Jeder Eintrag ist ein Vector4 mit x, y, z und w‑Komponenten.
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)}`);
}
}
}Schritt 6: ObjLoadOptions für das Laden von Materialien konfigurieren
ObjLoadOptions stellt Eigenschaften bereit, um zu steuern, wie begleitende .mtl‑Materialdateien und Texturen aufgelöst werden.
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}`);
}
}Häufige Probleme und Lösungen
Fehler: Modul ‘@aspose/3d/formats/obj’ nicht gefunden
Die Format‑Unterpfade erfordern Node.js 12.7+ Paket‑Exports. Stellen Sie sicher, dass Sie Node.js 18 oder höher verwenden. Wenn Sie TypeScript verwenden, setzen Sie "moduleResolution": "node16" oder "bundler" in tsconfig.json.
scene.rootNode.childNodes ist nach open() leer
Einige OBJ-Dateien verwenden nicht standardmäßige Zeilenenden oder haben kein abschließendes Newline‑Zeichen. Überprüfen Sie, ob die Datei ein gültiges OBJ ist, indem Sie sie in einem Texteditor öffnen. Stellen Sie außerdem sicher, dass Sie ObjLoadOptions übergeben haben und nicht ein generisches LoadOptions: Die format‑spezifischen Optionen sind für die korrekte Weiterleitung erforderlich.
controlPoints-Array hat Länge Null
Das Mesh wurde möglicherweise geladen, enthält jedoch keine Geometrie (z. B. eine leere Gruppe im OBJ). Verwenden Sie mesh.polygonCount, um vor dem Durchlaufen der Vertices zu prüfen.
Speicherverbrauch ist bei großen Dateien hoch
Load-from-buffer mit scene.openFromBuffer() reduziert den Spitzenverbrauch nicht: Die gesamte Datei muss geparst werden. Für große Dateien (> 100 MB) stellen Sie sicher, dass Ihr Node.js‑Prozess über ausreichend Heap verfügt: node --max-old-space-size=4096 yourScript.js.
Typfehler: ’entity’ ist vom Typ ‘unknown’
Die entity-Eigenschaft ist breit typisiert. Casten Sie zu any oder zu einer spezifischen Klasse (Mesh, Camera usw.), je nachdem, was Sie in Ihrer Szene erwarten.
Häufig gestellte Fragen (FAQ)
Welche Formate können mit scene.open() geladen werden?
OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX und COLLADA (.dae) werden alle für den Import unterstützt. Verwenden Sie die entsprechende *LoadOptions‑Klasse für jedes Format.
Kann ich eine Datei laden, ohne Optionen anzugeben?
Ja. scene.open('model.glb') funktioniert ohne Optionen für Formate, die keine spezielle Konfiguration benötigen. Das Übergeben von Optionen wird für OBJ empfohlen, da die Materialauflösung von enableMaterials abhängt.
Läuft das Laden asynchron?
Nein. scene.open() und scene.openFromBuffer() sind synchron. Wickeln Sie sie in einen Worker‑Thread ein oder setImmediate, wenn Sie die Ereignisschleife reaktionsfähig halten müssen.
Wird der OBJ-Export unterstützt?
Ja. Der OBJ-Export wird über scene.save('output.obj') unterstützt. Die .mtl-Materialdatei wird automatisch zusammen mit der .obj-Datei geschrieben.
Wo wird die .mtl-Datei beim Laden von OBJ erwartet?
Standardmäßig sucht der Parser nach der .mtl‑Datei, die im OBJ (mtllib‑Direktive) referenziert wird, relativ zum Verzeichnis der OBJ‑Datei. Stellen Sie sicher, dass beide Dateien im selben Ordner liegen.