Cara Memuatkan Model 3D dalam TypeScript

Cara Memuatkan Model 3D dalam TypeScript

The @aspose/3d pakej 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 yang khusus kepada format secara opsional, kemudian lalui scene.rootNode untuk mengakses geometri, bahan, dan transformasi.

Panduan Langkah demi Langkah

Langkah 1: Pasang @aspose/3d melalui npm

Tambah pakej ke projek anda. Tiada binari asli atau alat bina khusus platform diperlukan; hanya Node.js 18 atau lebih baru.

npm install @aspose/3d

Untuk projek TypeScript, definisi jenis disertakan bersama pakej:

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

Langkah 2: Import Scene 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 coraknya 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 Scene instans, kemudian panggil scene.open() dengan laluan fail dan objek pilihan muat-opsi secara opsional. Panggilan ini bersifat segerak.

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 satu 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: Ulangi ke atas nod adegan

Graf adegan ialah pokok yang berakar pada scene.rootNode. Setiap Node boleh mengandungi nod anak dan pilihan 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

Apabila entiti nod ialah Mesh, anda boleh membaca titik kawalan mentah (vertices) daripada the controlPoints array. Setiap entri adalah satu 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 bahan

ObjLoadOptions mendedahkan sifat untuk mengawal bagaimana fail pendamping .mtl fail bahan 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.entity && node.entity.material) {
        console.log(`Material on "${node.name}": ${node.entity.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() Sesetengah fail OBJ menggunakan penghujung baris bukan piawai atau tidak mempunyai baris baru di akhir. Sahkan fail tersebut adalah OBJ yang sah dengan membukanya dalam penyunting teks. Juga pastikan anda telah menghantar ObjLoadOptions dan bukan generik LoadOptions: pilihan khusus format diperlukan untuk penghantaran yang betul.

array controlPoints mempunyai panjang sifar Mesh mungkin telah dimuatkan tetapi tidak mengandungi geometri (contoh, 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’ Yang entity ciri ini ditetapkan secara luas. Cast 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 yang sepadan *LoadOptions 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 asynchronous? Tidak. scene.open() dan scene.openFromBuffer() adalah serentak. Balutkan mereka dalam worker thread atau setImmediate jika anda perlu mengekalkan event loop responsif.

Adakah OBJ export disokong? Ya. OBJ export disokong melalui scene.save('output.obj'). The .mtl fail material ditulis secara automatik di sebelah .obj fail.

Di manakah fail .mtl dijangka apabila memuatkan OBJ? Secara lalai, parser mencari .mtl fail yang dirujuk di dalam OBJ (mtllib arahan) relatif kepada direktori fail OBJ. Pastikan kedua-dua fail berada dalam folder yang sama.

Lihat Juga

 Bahasa Melayu