Як завантажити 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() з шляхом до файлу та необов’язковим об’єктом load-options. Виклик є синхронним.
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 (mesh, camera, light тощо).
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, ви можете прочитати необроблені контрольні точки (вершини) з controlPoints масиву. Кожен елемент є 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.entity && node.entity.material) {
console.log(`Material on "${node.name}": ${node.entity.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’ The 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() є синхронними. Обгорніть їх у робочий потік або setImmediate якщо вам потрібно, щоб цикл подій залишався чуйним.
Чи підтримується експорт OBJ? Так. Експорт OBJ підтримується через scene.save('output.obj'). Цей .mtl файл матеріалу створюється автоматично разом із .obj файл.
Де очікується файл .mtl під час завантаження OBJ? За замовчуванням парсер шукає .mtl файл, зазначений всередині OBJ (mtllib директива) відносно каталогу файлу OBJ. Переконайтеся, що обидва файли знаходяться в одній теці.