Comment charger des modèles 3D en TypeScript

Comment charger des modèles 3D en TypeScript

Le package @aspose/3d fournit aux applications TypeScript et Node.js une API simple pour ouvrir des fichiers de scène 3D. Scene est l’objet racine : appelez scene.open() avec un chemin de fichier et des options de chargement spécifiques au format, puis parcourez scene.rootNode pour accéder à la géométrie, aux matériaux et aux transformations.

Guide étape par étape

Étape 1 : Installez @aspose/3d via npm

Ajoutez le package à votre projet. Aucun binaire natif ni outil de compilation spécifique à la plateforme n’est requis ; uniquement Node.js 18 ou une version ultérieure.

npm install @aspose/3d

Pour les projets TypeScript, les définitions de type sont incluses dans le package :

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

Étape 2 : Importer la scène et les options spécifiques au format

Chaque format expose sa propre classe de chargeur et son objet d’options sous un sous‑chemin. Importez uniquement ce dont vous avez besoin :

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

Pour les autres formats, le modèle est identique :

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

Étape 3 : Ouvrez un fichier 3D en utilisant scene.open()

Créez une instance Scene, puis appelez scene.open() avec le chemin du fichier et un objet load‑options facultatif. L’appel est synchrone.

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

Pour charger depuis un Buffer déjà en mémoire (utile dans les contextes serverless ou de 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());

Étape 4 : Parcourir les nœuds de la scène

Le graphe de scène est un arbre dont la racine est scene.rootNode. Chaque Node peut contenir des nœuds enfants et un entity optionnel (maillage, caméra, lumière, etc.).

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

Étape 5 : Accéder aux données des sommets du maillage via controlPoints

Lorsque l’entité d’un nœud est un Mesh, vous pouvez lire les points de contrôle bruts (sommets) depuis le tableau controlPoints. Chaque entrée est un Vector4 avec les composants x, y, z et 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)}`);
        }
    }
}

Étape 6 : Configurer ObjLoadOptions pour le chargement des matériaux

ObjLoadOptions expose des propriétés permettant de contrôler la façon dont les fichiers de matériau .mtl et les textures associés sont résolus.

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

Problèmes courants et solutions

Erreur : Impossible de trouver le module ‘@aspose/3d/formats/obj’ Les sous‑chemins de format nécessitent les exportations de package Node.js 12.7+. Assurez‑vous d’utiliser Node.js 18 ou une version ultérieure. Si vous utilisez TypeScript, définissez "moduleResolution": "node16" ou "bundler" dans tsconfig.json.

scene.rootNode.childNodes est vide après open()
Certains fichiers OBJ utilisent des fins de ligne non standard ou n’ont pas de saut de ligne final. Vérifiez que le fichier est un OBJ valide en l’ouvrant dans un éditeur de texte. Confirmez également que vous avez passé ObjLoadOptions et non un LoadOptions générique : les options spécifiques au format sont requises pour un dispatch correct.

controlPoints array has zero length
Le tableau controlPoints a une longueur nulle.

Le maillage a peut‑être été chargé mais ne contient aucune géométrie (par exemple, un groupe vide dans le OBJ). Utilisez mesh.polygonCount pour vérifier avant d’itérer les sommets.

L’utilisation de la mémoire est élevée pour les gros fichiers
Le chargement depuis le tampon avec scene.openFromBuffer() ne réduit pas le pic de mémoire : le fichier complet doit être analysé. Pour les gros fichiers (> 100 Mo), assurez‑vous que votre processus Node.js dispose d’un tas suffisant : node --max-old-space-size=4096 yourScript.js.

Erreurs de type : ’entity’ est de type ‘unknown’ La propriété entity est typée de manière large. Convertissez en any ou en une classe spécifique (Mesh, Camera, etc.) selon ce que vous attendez dans votre scène.

Foire aux questions (FAQ)

Quels formats peuvent être chargés avec scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX et COLLADA (.dae) sont tous pris en charge pour l’importation. Transmettez la classe *LoadOptions correspondante pour chaque format.

Puis-je charger un fichier sans spécifier d’options ?
Oui. scene.open('model.glb') fonctionne sans options pour les formats qui ne nécessitent pas de configuration spéciale. Le passage d’options est recommandé pour OBJ car la résolution des matériaux dépend de enableMaterials.

Le chargement s’exécute-t-il de manière asynchrone ?
Non. scene.open() et scene.openFromBuffer() sont synchrones. Enveloppez‑les dans un thread de travail ou setImmediate si vous devez garder la boucle d’événements réactive.

L’exportation OBJ est-elle prise en charge ?
Oui. L’exportation OBJ est prise en charge via scene.save('output.obj'). Le fichier matériel .mtl est écrit automatiquement à côté du fichier .obj.

Où le fichier .mtl est‑il attendu lors du chargement d’OBJ ?
Par défaut, l’analyseur recherche le fichier .mtl référencé à l’intérieur de l’OBJ (directive mtllib) relatif au répertoire du fichier OBJ. Assurez‑vous que les deux fichiers se trouvent dans le même dossier.

Voir aussi

 Français