Cara Memuat Model 3D di TypeScript
The @aspose/3d paket memberikan aplikasi TypeScript dan Node.js API yang sederhana untuk membuka file adegan 3D. Scene adalah objek akar: panggil scene.open() dengan jalur file dan opsi muat spesifik format yang opsional, lalu telusuri scene.rootNode untuk mengakses geometri, material, dan transformasi.
Panduan Langkah-demi-Langkah
Langkah 1: Instal @aspose/3d via npm
Tambahkan paket ke proyek Anda. Tidak diperlukan binari native atau alat build khusus platform; hanya Node.js 18 atau yang lebih baru.
npm install @aspose/3dUntuk proyek TypeScript, definisi tipe disertakan dalam paket:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}Langkah 2: Impor Scene dan opsi khusus format
Setiap format menyediakan kelas pemuat dan objek opsi masing‑masing di bawah sub‑path. Impor hanya apa yang Anda butuhkan:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';Untuk format lain pola ini identik:
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';Langkah 3: Buka file 3D menggunakan scene.open()
Buat sebuah Scene instansi, lalu panggil scene.open() dengan jalur file dan objek opsi-muat yang opsional. Panggilan ini bersifat sinkron.
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 sebuah Buffer yang sudah berada di memori (berguna dalam konteks serverless atau 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());Langkah 4: Iterasi node adegan
Graf adegan adalah pohon yang berakar di scene.rootNode. Setiap Node dapat berisi node anak dan opsional entity (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 vertex mesh melalui controlPoints
Ketika entitas node adalah sebuah Mesh, Anda dapat membaca titik kontrol mentah (vertex) dari the controlPoints array. Setiap entri adalah sebuah Vector4 dengan x, y, z, dan w komponen.
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 material
ObjLoadOptions menyajikan properti untuk mengontrol bagaimana yang menyertai .mtl file material 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}`);
}
}Masalah Umum dan Solusinya
Kesalahan: Tidak dapat menemukan modul ‘@aspose/3d/formats/obj’ Sub‑path format memerlukan ekspor paket Node.js 12.7+. Pastikan Anda menggunakan Node.js 18 atau yang lebih baru. Jika menggunakan TypeScript, atur "moduleResolution": "node16" atau "bundler" di tsconfig.json.
scene.rootNode.childNodes kosong setelah open() Beberapa file OBJ menggunakan akhir baris non‑standar atau tidak memiliki newline di akhir. Verifikasi bahwa file tersebut adalah OBJ yang valid dengan membukanya di editor teks. Juga pastikan Anda telah memberikan ObjLoadOptions dan bukan generic LoadOptions: opsi khusus format diperlukan untuk pengiriman yang tepat.
array controlPoints memiliki panjang nol Mesh mungkin telah dimuat tetapi tidak berisi geometri (misalnya, grup kosong dalam OBJ). Gunakan mesh.polygonCount untuk memeriksa sebelum mengiterasi vertex.
Penggunaan memori tinggi untuk file besar Muat-dari-buffer dengan scene.openFromBuffer() tidak mengurangi memori puncak: seluruh file harus diparsing. Untuk file besar (> 100 MB), pastikan proses Node.js Anda memiliki heap yang cukup: node --max-old-space-size=4096 yourScript.js.
Kesalahan tipe: ’entity’ berjenis ‘unknown’ The entity properti bertipe secara luas. Cast ke any atau ke kelas spesifik (Mesh, Camera, dll.) tergantung pada apa yang Anda harapkan dalam scene Anda.
Pertanyaan yang Sering Diajukan (FAQ)
Format apa yang dapat dimuat dengan scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX, dan COLLADA (.dae) semuanya didukung untuk impor. Berikan kelas yang sesuai *LoadOptions untuk setiap format.
Apakah saya dapat memuat file tanpa menentukan opsi? Ya. scene.open('model.glb') berfungsi tanpa opsi untuk format yang tidak memerlukan konfigurasi khusus. Menyertakan opsi disarankan untuk OBJ karena resolusi material bergantung pada enableMaterials.
Apakah pemuatan berjalan secara asynchronous? Tidak. scene.open() dan scene.openFromBuffer() bersifat sinkron. Bungkus mereka dalam thread pekerja atau setImmediate jika Anda perlu menjaga event loop tetap responsif.
Apakah ekspor OBJ didukung? Ya. Ekspor OBJ didukung melalui scene.save('output.obj'). The .mtl file material ditulis secara otomatis di samping the .obj file.
Di mana file .mtl diharapkan berada saat memuat OBJ? Secara default, parser mencari .mtl file yang direferensikan di dalam OBJ (mtllib directive) relatif terhadap direktori file OBJ. Pastikan kedua file berada dalam folder yang sama.