Jak načíst 3D modely v TypeScript

Jak načíst 3D modely v TypeScript

Balíček @aspose/3d poskytuje aplikacím v TypeScript a Node.js jednoduché API pro otevírání 3D souborů scén. Scene je kořenový objekt: zavolejte scene.open() s cestou k souboru a volitelnými možnostmi načítání specifickými pro formát, poté procházejte scene.rootNode pro přístup k geometrii, materiálům a transformacím.

Průvodce krok za krokem

Krok 1: Nainstalujte @aspose/3d pomocí npm

Přidejte balíček do svého projektu. Není potřeba žádné nativní binární soubory ani nástroje specifické pro platformu; stačí Node.js 18 nebo novější.

npm install @aspose/3d

Pro projekty TypeScript jsou definice typů součástí balíčku:

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

Krok 2: Importovat scénu a možnosti specifické pro formát

Každý formát poskytuje svou vlastní třídu načítače a objekt možností pod podcestou. Importujte jen to, co potřebujete:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

Pro jiné formáty je vzor identický:

import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';

Krok 3: Otevřete 3D soubor pomocí scene.open()

Vytvořte instanci Scene, poté zavolejte scene.open() s cestou k souboru a volitelným objektem load‑options. Volání je synchronní.

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');

Pro načtení z Buffer již v paměti (užitečné v serverless nebo streamovacích kontextech):

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());

Krok 4: Procházet uzly scény

Graf scény je strom s kořenem v scene.rootNode. Každý Node může obsahovat podřízené uzly a volitelný entity (mesh, kamera, světlo atd.).

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);

Krok 5: Přístup k datům vrcholů sítě pomocí controlPoints

Když je entita uzlu Mesh, můžete načíst surové řídicí body (vrcholy) z pole controlPoints. Každý záznam je Vector4 s komponentami x, y, z a 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)}`);
        }
    }
}

Krok 6: Nakonfigurujte ObjLoadOptions pro načítání materiálů

ObjLoadOptions poskytuje vlastnosti pro řízení toho, jak jsou řešeny přidružené .mtl soubory materiálu a textury.

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}`);
    }
}

Časté problémy a opravy

Chyba: Nelze najít modul ‘@aspose/3d/formats/obj’ Formátové podcesty vyžadují exporty balíčků Node.js 12.7+. Ujistěte se, že používáte Node.js 18 nebo novější. Pokud používáte TypeScript, nastavte "moduleResolution": "node16" nebo "bundler" v tsconfig.json.

scene.rootNode.childNodes je prázdný po open() Některé soubory OBJ používají nestandardní konce řádků nebo postrádají koncový nový řádek. Ověřte, že soubor je platný OBJ otevřením v textovém editoru. Také potvrďte, že jste předali ObjLoadOptions a ne obecný LoadOptions: formátově specifické možnosti jsou vyžadovány pro správné směrování.

pole controlPoints má nulovou délku
Mesh mohl být načten, ale neobsahuje žádnou geometrii (např. prázdná skupina v souboru OBJ). Použijte mesh.polygonCount k ověření před iterací vrcholů.

Využití paměti je vysoké u velkých souborů
Load-from-buffer with scene.openFromBuffer() nesnižuje špičkové využití paměti: celý soubor musí být parsován. Pro velké soubory (> 100 MB) zajistěte, aby váš proces Node.js měl dostatečnou haldu: node --max-old-space-size=4096 yourScript.js.

Typové chyby: ’entity’ je typu ‘unknown’
Vlastnost entity je typována obecně. Přetypujte na any nebo na konkrétní třídu (Mesh, Camera, atd.) podle toho, co očekáváte ve své scéně.

Často kladené otázky (FAQ)

Které formáty lze načíst pomocí scene.open()?
OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX a COLLADA (.dae) jsou všechny podporovány pro import. Použijte odpovídající třídu *LoadOptions pro každý formát.

Mohu načíst soubor bez zadání možností?
Ano. scene.open('model.glb') funguje bez možností pro formáty, které nevyžadují speciální konfiguraci. Použití možností se doporučuje pro OBJ, protože rozlišení materiálu závisí na enableMaterials.

Běží načítání asynchronně?
Ne. scene.open() a scene.openFromBuffer() jsou synchronní. Zabalte je do pracovního vlákna nebo setImmediate, pokud potřebujete udržet smyčku událostí responzivní.

Je export OBJ podporován? Ano. Export OBJ je podporován prostřednictvím scene.save('output.obj'). Soubor materiálu .mtl je automaticky vytvořen vedle souboru .obj.

Kde se očekává soubor .mtl při načítání OBJ? Ve výchozím nastavení parser hledá soubor .mtl uvedený uvnitř OBJ (mtllib direktiva) relativně k adresáři souboru OBJ. Ujistěte se, že oba soubory jsou ve stejné složce.

Viz také

 Čeština