Как загрузить 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 массив. Каждый элемент является 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’ Эта 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. Убедитесь, что оба файла находятся в одной папке.