Cara Memuatkan Model 3D dalam TypeScript
Pakej @aspose/3d memberikan aplikasi TypeScript dan Node.js API yang mudah untuk membuka fail adegan 3D. Scene ialah objek akar: panggil scene.open() dengan laluan fail dan pilihan muat format khusus yang bersifat pilihan, kemudian lalui scene.rootNode untuk mengakses geometri, bahan, dan transformasi.
Panduan Langkah demi Langkah
Langkah 1: Pasang @aspose/3d melalui npm
Tambahkan pakej ke projek anda. Tiada binari asli atau alat bina khusus platform diperlukan; hanya Node.js 18 atau lebih baru.
npm install @aspose/3dUntuk projek TypeScript, definisi jenis dibundel bersama pakej:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}Langkah 2: Import Adegan dan pilihan khusus format
Setiap format mendedahkan kelas pemuat dan objek pilihan masing-masing di bawah sub‑laluan. Import hanya apa yang anda perlukan:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';Untuk format lain, pola adalah serupa:
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';Langkah 3: Buka fail 3D menggunakan scene.open()
Cipta satu contoh Scene, kemudian panggil scene.open() dengan laluan fail dan objek pilihan muat‑turun. Panggilan itu bersinkron.
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');Untuk memuat dari Buffer yang sudah berada dalam memori (berguna dalam konteks tanpa pelayan atau penstriman):
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());Langkah 4: Iterasi ke atas nod adegan
Graf adegan ialah sebuah pokok yang berakar pada scene.rootNode. Setiap Node boleh mengandungi nod anak dan entity pilihan (mesh, kamera, cahaya, dll).
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);Langkah 5: Akses data titik verteks mesh melalui controlPoints
Apabila entiti nod adalah Mesh, anda boleh membaca titik kawalan mentah (vertices) daripada tatasusunan controlPoints. Setiap entri adalah Vector4 dengan komponen x, y, z, dan 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)}`);
}
}
}Langkah 6: Konfigurasikan ObjLoadOptions untuk pemuatan bahan
ObjLoadOptions memaparkan sifat untuk mengawal bagaimana fail bahan .mtl yang menyertai dan tekstur diselesaikan.
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}`);
}
}Isu Umum dan Penyelesaian
Ralat: Tidak dapat menemukan modul ‘@aspose/3d/formats/obj’
Sub‑laluan format memerlukan eksport pakej Node.js 12.7+. Pastikan anda menggunakan Node.js 18 atau lebih baru. Jika menggunakan TypeScript, tetapkan "moduleResolution": "node16" atau "bundler" dalam tsconfig.json.
scene.rootNode.childNodes kosong selepas open()
Beberapa fail OBJ menggunakan penamat baris yang tidak standard atau tidak mempunyai baris baru di akhir. Sahkan bahawa fail tersebut adalah OBJ yang sah dengan membukanya dalam penyunting teks. Juga pastikan anda menghantar ObjLoadOptions dan bukan LoadOptions generik: pilihan khusus format diperlukan untuk penghantaran yang betul.
array controlPoints mempunyai panjang sifar
Mesh mungkin telah dimuatkan tetapi tidak mengandungi geometri (contohnya, kumpulan kosong dalam OBJ). Gunakan mesh.polygonCount untuk memeriksa sebelum mengiterasi verteks.
Penggunaan memori tinggi untuk fail besar
Muat-dari-bufer dengan scene.openFromBuffer() tidak mengurangkan memori puncak: keseluruhan fail mesti diparse. Untuk fail besar (> 100 MB), pastikan proses Node.js anda mempunyai heap yang mencukupi: node --max-old-space-size=4096 yourScript.js.
Ralat jenis: ’entity’ adalah jenis ‘unknown’
Sifat entity didefinisikan secara umum. Tukarkan kepada any atau kepada kelas khusus (Mesh, Camera, dll.) bergantung pada apa yang anda jangkakan dalam adegan anda.
Soalan Lazim (FAQ)
Format apa yang boleh dimuatkan dengan scene.open()?
OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX, dan COLLADA (.dae) semuanya disokong untuk import. Hantar kelas *LoadOptions yang sepadan untuk setiap format.
Bolehkah saya memuatkan fail tanpa menentukan pilihan?
Ya. scene.open('model.glb') berfungsi tanpa pilihan untuk format yang tidak memerlukan konfigurasi khas. Menyerahkan pilihan disarankan untuk OBJ kerana resolusi bahan bergantung pada enableMaterials.
Adakah pemuatan dijalankan secara tak segerak?
Tidak. scene.open() dan scene.openFromBuffer() adalah segerak. Balutkan mereka dalam thread pekerja atau setImmediate jika anda perlu mengekalkan gelung acara responsif.
Adakah eksport OBJ disokong?
Ya. Eksport OBJ disokong melalui scene.save('output.obj'). Fail bahan .mtl ditulis secara automatik bersama fail .obj.
Di mana fail .mtl dijangka apabila memuatkan OBJ?
Secara lalai, parser mencari fail .mtl yang dirujuk di dalam OBJ (arahan mtllib) relatif kepada direktori fail OBJ. Pastikan kedua-dua fail berada dalam folder yang sama.