Как да заредим 3D модели в TypeScript
Този @aspose/3d пакетът предоставя на TypeScript и Node.js приложения прост API за отваряне на 3D сценични файлове. Scene е кореновият обект: извикайте scene.open() с път към файл и незадължителни опции за зареждане, специфични за формата, след това обхождайте scene.rootNode за достъп до геометрия, материали и трансформации.
Ръководство стъпка по стъпка
Стъпка 1: Инсталирайте @aspose/3d чрез npm
Добавете пакета към вашия проект. Не са необходими нативни бинарни файлове или специфични за платформата инструменти за компилация; необходим е само Node.js 18 или по-нов.
npm install @aspose/3dЗа TypeScript проекти типови дефиниции са включени в пакета:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}Стъпка 2: Импортирайте Scene и опции, специфични за формата
Всеки формат разкрива свой собствен клас за зареждане и обект с опции под подпът. Импортирайте само това, което ви е необходимо:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';За други формати моделът е идентичен:
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';Стъпка 3: Отворете 3D файл, използвайки scene.open()
Създайте Scene екземпляр, след това извикайте scene.open() с пътя към файла и незадължителен обект с опции за зареждане. Извикването е синхронно.
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');За да заредите от Buffer вече в паметта (полезно в безсървърни или стрийминг контексти):
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());Стъпка 4: Итерирайте през възлите на сцената
Графът на сцената е дърво, коренящо се в scene.rootNode. Всеки Node може да съдържа дъщерни възли и незадължителен entity (мрежа, камера, светлина и др.).
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);Стъпка 5: Достъп до данните за върховете на мрежата чрез controlPoints
Когато ентитетът на възела е Mesh, можете да прочетете суровите контролни точки (върхове) от the controlPoints масив. Всеки елемент е a Vector4 с x, y, z, и 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)}`);
}
}
}Стъпка 6: Конфигурирайте ObjLoadOptions за зареждане на материали
ObjLoadOptions излага свойства за контролиране на начина, по който съпровождащите .mtl материални файлове и текстури се разрешават.
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}`);
}
}Чести проблеми и решения
Грешка: Не може да се намери модулът ‘@aspose/3d/formats/obj’ Подпътеките на формата изискват експорти на пакети от Node.js 12.7+. Уверете се, че използвате Node.js 18 или по-нов. Ако използвате TypeScript, задайте "moduleResolution": "node16" или "bundler" в tsconfig.json.
scene.rootNode.childNodes е празен след open() Някои OBJ файлове използват нестандартни крайни знаци на реда или нямат завършващ нов ред. Проверете дали файлът е валиден OBJ, като го отворите в текстов редактор. Също така се уверете, че сте предали ObjLoadOptions и не общ LoadOptions: специфичните за формата опции са задължителни за правилно разпределяне.
масивът controlPoints има нулева дължина Мрежата може да е заредена, но да не съдържа геометрия (например празна група в OBJ). Използвайте mesh.polygonCount за проверка преди обхождане на върховете.
Използването на памет е високо за големи файлове Зареждане от буфер с scene.openFromBuffer() не намалява пиковото използване на памет: целият файл трябва да бъде анализиран. За големи файлове (> 100 MB) уверете се, че вашият Node.js процес разполага с достатъчен heap: node --max-old-space-size=4096 yourScript.js.
Грешки в типове: ’entity’ е от тип ‘unknown’ Това entity свойството е типизирано широко. Преобразувайте към any или към конкретен клас (Mesh, Camera, и т.н.) в зависимост от това, което очаквате в сцената си.
Често задавани въпроси (FAQ)
Кои формати могат да се заредят с scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX и COLLADA (.dae) са всички поддържани за импортиране. Предайте съответния *LoadOptions клас за всеки формат.
Мога ли да заредя файл без да посочвам опции? Да. scene.open('model.glb') работи без опции за формати, които не изискват специална конфигурация. Предаването на опции се препоръчва за OBJ, тъй като резолюцията на материалите зависи от enableMaterials.
Зареждането се изпълнява асинхронно ли? Не. scene.open() и scene.openFromBuffer() са синхронни. Обвийте ги в worker thread или setImmediate ако трябва да запазите реактивността на event loop.
Поддържа се експортиране в OBJ? Да. Експортирането в OBJ се поддържа чрез scene.save('output.obj'). Този .mtl material file се записва автоматично заедно с the .obj файл.
Къде се очаква .mtl файлът при зареждане на OBJ? По подразбиране, парсерът търси .mtl файл, посочен вътре в OBJ (mtllib директива) спрямо директорията на OBJ файла. Уверете се, че и двата файла са в една и съща папка.