Функції та можливості
Aspose.3D FOSS for TypeScript — це бібліотека Node.js з ліцензією MIT для завантаження, створення та експорту 3D‑сцен. Вона постачається з повними визначеннями типів TypeScript, однією залежністю під час виконання (xmldom), і підтримкою шести основних форматів 3D‑файлів.
Встановлення та налаштування
Встановіть пакет з npm за допомогою однієї команди:
npm install @aspose/3dПакет орієнтований на CommonJS і вимагає Node.js 18 або новішої версії. Після встановлення перевірте, чи ваш tsconfig.json містить такі параметри компілятора для повної сумісності:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Імпортуйте головний Scene клас з кореня пакету. Класи параметрів, специфічних для формату, імпортуються з їх відповідних підшляхів:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';Функції та можливості
Підтримка форматів
Aspose.3D FOSS for TypeScript читає та записує шість основних 3D‑форматів файлів. Визначення формату виконується автоматично за допомогою бінарних магічних чисел під час завантаження, тому вам не потрібно явно вказувати вихідний формат.
| Формат | Читання | Запис | Примітки |
|---|---|---|---|
| OBJ (Wavefront) | Так | Так | Читає/записує .mtl матеріали; використовуйте ObjLoadOptions.enableMaterials для імпорту |
| glTF 2.0 | Так | Так | текстовий формат JSON; матеріали PBR |
| GLB | Так | Так | Бінарний glTF; встановлено GltfSaveOptions.binaryMode = true |
| STL | Так | Так | Бінарний і ASCII; повний раундтрип підтверджено |
| 3MF | Так | Так | 3D Manufacturing Format with color and material metadata |
| FBX | Ні* | Ні* | Імпортер/експортер існує, але автоматичне визначення формату не підключено |
| COLLADA (DAE) | Так | Так | Масштаб одиниці, геометрія, матеріали та анімаційні кліпи |
Завантаження OBJ з матеріалами:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
options.flipCoordinateSystem = false;
options.scale = 1.0;
options.normalizeNormal = true;
scene.open('model.obj', options);Збереження у GLB (бінарний glTF):
import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
// ... build or load scene content
const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('output.glb', GltfFormat.getInstance(), opts);Граф сцени
Весь 3D‑контент організовано у вигляді дерева of Node об’єкти, що мають корінь у scene.rootNode. Кожен вузол може містити Entity (a Mesh, Camera, Light, або інший SceneObject) і Transform яка позиціонує його відносно батька.
Ключові класи графа сцени:
Scene: контейнер верхнього рівня; міститьrootNodeіanimationClipsNode: іменований вузол дерева зchildNodes,entity,transform, іmaterialsEntity: базовий клас для приєднуваних об’єктів (Mesh,Camera,Light)SceneObject: базовий клас, спільний дляNodeіEntityA3DObject: кореневий базовий клас зnameі контейнером властивостейTransform:локальний зсув, обертання (Euler і Quaternion) та масштаб
Обхід графа сцени:
import { Scene, Node, Mesh } from '@aspose/3d';
const scene = new Scene();
scene.open('model.obj');
function visit(node: Node, depth: number = 0): void {
const indent = ' '.repeat(depth);
console.log(`${indent}Node: ${node.name}`);
if (node.entity) {
console.log(`${indent} Entity: ${node.entity.constructor.name}`);
}
for (const child of node.childNodes) {
visit(child, depth + 1);
}
}
visit(scene.rootNode);Створення ієрархії сцени програмно:
import { Scene, Node } from '@aspose/3d';
const scene = new Scene();
const parent = scene.rootNode.createChildNode('chassis');
const wheel = parent.createChildNode('wheel_fl');
wheel.transform.translation.set(0.9, -0.3, 1.4);Geometry та Mesh
Mesh є основним типом геометрії. Він розширює Geometry і надає контрольні точки (вершини), індекси полігонів та елементи вершин для нормалей, UVs, та кольорів вершин.
Ключові класи геометрії:
Mesh: полігональна сітка зcontrolPointsіpolygonCountGeometry: базовий клас з управлінням вершинними елементамиVertexElementNormal: нормалі per-vertex або per-polygon-vertexVertexElementUV: текстурні координати (один або кілька UV-каналів)VertexElementVertexColor: дані кольору per-vertexMappingMode: керує тим, як дані елементів відображаються на полігони (CONTROL_POINT,POLYGON_VERTEX,POLYGON,EDGE,ALL_SAME)ReferenceMode: керує стратегією індексування (DIRECT,INDEX,INDEX_TO_DIRECT)VertexElementType: визначає семантику елементу вершиниTextureMapping: перерахування каналів текстури
Читання даних сітки з завантаженої сцени:
import { Scene, Mesh, VertexElementType } from '@aspose/3d';
const scene = new Scene();
scene.open('model.stl');
for (const node of scene.rootNode.childNodes) {
if (node.entity instanceof Mesh) {
const mesh = node.entity as Mesh;
console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices, ${mesh.polygonCount} polygons`);
const normals = mesh.getElement(VertexElementType.NORMAL);
if (normals) {
console.log(` Normal mapping: ${normals.mappingMode}`);
}
}
}Система матеріалів
Aspose.3D FOSS for TypeScript підтримує три типи матеріалів, що охоплюють повний діапазон від застарілого Phong-освітлення до фізично‑коректного рендерингу:
LambertMaterial: дифузний колір і амбієнтний колір; відображається у прості матеріали OBJ/DAEPhongMaterial: додає спекулярний колір, блиск і емісивність; тип матеріалу за замовчуванням OBJPbrMaterial: фізично‑обґрунтована модель шорсткості/металевості; використовується для імпорту та експорту glTF 2.0
Читання матеріалів із завантаженої сцени OBJ:
import { Scene, PhongMaterial, LambertMaterial } 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);
for (const node of scene.rootNode.childNodes) {
for (const mat of node.materials) {
if (mat instanceof PhongMaterial) {
const phong = mat as PhongMaterial;
console.log(` Phong: diffuse=${JSON.stringify(phong.diffuseColor)}, shininess=${phong.shininess}`);
} else if (mat instanceof LambertMaterial) {
console.log(` Lambert: diffuse=${JSON.stringify((mat as LambertMaterial).diffuseColor)}`);
}
}
}Застосування PBR‑матеріалу під час побудови сцени glTF:
import { Scene, Node, PbrMaterial } from '@aspose/3d';
import { Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
const node = scene.rootNode.createChildNode('sphere');
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.8, 0.2, 0.2); // red-tinted albedo; albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.5;
node.material = mat;
const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), opts);Математичні утиліти
Бібліотека постачається з повним набором 3D‑математичних типів, усі повністю типізовані:
Vector3: вектор з 3 компонентами; підтримуєminus(),times(),dot(),cross(),normalize(),length,angleBetween()Vector4: вектор з 4 компонентами для однорідних координатMatrix4: матриця перетворення 4×4 зconcatenate(),transpose,decompose,setTRSQuaternion: кватерніон обертання зfromEulerAngle()(статичний, одиничний),eulerAngles()(метод екземпляра),slerp(),normalize()BoundingBox: прямокутна обмежувальна коробка, орієнтована за осями, зminimum,maximum,center,size,mergeFVector3: варіант одиночної точностіVector3використовується у даних елементів вершини
Обчислення обмежувальної коробки з вершин сітки:
import { Scene, Mesh, Vector3, BoundingBox } from '@aspose/3d';
const scene = new Scene();
scene.open('model.obj');
let box = new BoundingBox();
for (const node of scene.rootNode.childNodes) {
if (node.entity instanceof Mesh) {
for (const pt of (node.entity as Mesh).controlPoints) {
box.merge(new Vector3(pt.x, pt.y, pt.z));
}
}
}
console.log('Center:', box.center);
console.log('Extents:', box.size);Створення трансформації з кутів Ейлера:
import { Quaternion, Vector3, Matrix4 } from '@aspose/3d';
const rot = Quaternion.fromEulerAngle(0, Math.PI / 4, 0); // 45° around Y
const mat = new Matrix4();
mat.setTRS(new Vector3(0, 0, 0), rot, new Vector3(1, 1, 1));Система анімації
API анімації моделює кліпи, вузли, канали та послідовності ключових кадрів:
AnimationClip:іменована колекція анімаційних вузлів; доступна черезscene.animationClips;надаєanimations: AnimationNode[]AnimationNode:іменована групаBindPoints; створена за допомогоюclip.createAnimationNode(name), доступна черезclip.animationsBindPoint: прив’язуєAnimationNodeдо конкретної властивості об’єкта сцени; відкриваєpropertyіchannelsCountAnimationChannel: розширюєKeyframeSequence; містить окремийkeyframeSequence; доступний черезbindPoint.getChannel(name)KeyFrame: одинарна пара час/значення; несе per-keyframeinterpolation: InterpolationKeyframeSequence: впорядкований списокKeyFrameоб’єкти черезkeyFrames; маєpreBehaviorіpostBehavior(Extrapolation)Interpolation: enum:LINEAR,CONSTANT,BEZIER,B_SPLINE,CARDINAL_SPLINE,TCB_SPLINEExtrapolation: class зtype: ExtrapolationTypeіrepeatCount: numberExtrapolationType: enum:CONSTANT,GRADIENT,CYCLE,CYCLE_RELATIVE,OSCILLATE
Читання даних анімації з завантаженої сцени:
import { Scene, AnimationNode, BindPoint } from '@aspose/3d';
const scene = new Scene();
scene.open('animated.dae'); // COLLADA animation import is supported
for (const clip of scene.animationClips) {
console.log(`Clip: "${clip.name}"`);
for (const animNode of clip.animations) { // clip.animations, not clip.nodes
console.log(` AnimationNode: ${animNode.name}`);
for (const bp of animNode.bindPoints) { // animNode.bindPoints, not animNode.channels
console.log(` BindPoint: property="${bp.property.name}", channels=${bp.channelsCount}`);
}
}
}Підтримка потоків та буферів
Використовуйте scene.openFromBuffer() для завантаження 3D‑сцени безпосередньо з пам’яті Buffer. Це рекомендований підхід для безсерверних функцій, потокових конвеєрів та обробки ресурсів, отриманих через HTTP, без запису на диск.
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import * as fs from 'fs';
// Load file into memory, then parse from buffer
const buffer: Buffer = fs.readFileSync('model.obj');
const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
scene.openFromBuffer(buffer, options);
for (const node of scene.rootNode.childNodes) {
if (node.entity) {
console.log(node.name, node.entity.constructor.name);
}
}Автоматичне визначення формату за бінарними магічними числами застосовується при завантаженні з буфера, тому файли GLB, бінарний STL та 3MF розпізнаються без вказання параметра формату.
Приклади використання
Приклад 1: Завантаження OBJ та експорт у GLB
У цьому прикладі завантажується файл Wavefront OBJ з матеріалами, після чого сцена повторно експортується у бінарний glTF (GLB) файл, придатний для використання в інтернеті та ігрових рушіях.
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
function convertObjToGlb(inputPath: string, outputPath: string): void {
const scene = new Scene();
const loadOpts = new ObjLoadOptions();
loadOpts.enableMaterials = true;
loadOpts.flipCoordinateSystem = false;
loadOpts.normalizeNormal = true;
scene.open(inputPath, loadOpts);
// Report what was loaded
for (const node of scene.rootNode.childNodes) {
if (node.entity) {
console.log(`Loaded: ${node.name} (${node.entity.constructor.name})`);
}
}
const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true; // write .glb instead of .gltf + .bin
scene.save(outputPath, GltfFormat.getInstance(), saveOpts);
console.log(`Exported GLB to: ${outputPath}`);
}
convertObjToGlb('input.obj', 'output.glb');Приклад 2: Круговий процес STL з перевіркою нормалей
У цьому прикладі завантажується бінарний STL файл, виводиться інформація про нормалі для кожної вершини, після чого сцена повторно експортується у ASCII STL і перевіряється коректність кругового процесу.
import { Scene, Mesh, VertexElementNormal, VertexElementType } from '@aspose/3d';
import { StlLoadOptions, StlSaveOptions } from '@aspose/3d/formats/stl';
const scene = new Scene();
const loadOpts = new StlLoadOptions();
scene.open('model.stl', loadOpts);
let totalPolygons = 0;
for (const node of scene.rootNode.childNodes) {
if (node.entity instanceof Mesh) {
const mesh = node.entity as Mesh;
totalPolygons += mesh.polygonCount;
const normElem = mesh.getElement(VertexElementType.NORMAL) as VertexElementNormal | null;
if (normElem) {
console.log(` Normals: ${normElem.data.length} entries, mapping=${normElem.mappingMode}`);
}
}
}
console.log(`Total polygons: ${totalPolygons}`);
// Re-export as ASCII STL
const saveOpts = new StlSaveOptions();
saveOpts.binaryMode = false; // ASCII output
scene.save('output_ascii.stl', saveOpts);Приклад 3: Створити сцену програмно та зберегти як glTF
Цей приклад створює сцену з PBR‑матеріалом з нуля та зберігає її як JSON‑файл glTF.
import { Scene, Mesh, PbrMaterial, Vector4, Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
const node = scene.rootNode.createChildNode('floor');
// Build a simple quad mesh (two triangles)
// controlPoints are Vector4 (x, y, z, w) where w=1 for positions
const mesh = new Mesh();
mesh.controlPoints.push(
new Vector4(-1, 0, -1, 1),
new Vector4( 1, 0, -1, 1),
new Vector4( 1, 0, 1, 1),
new Vector4(-1, 0, 1, 1),
);
mesh.createPolygon([0, 1, 2]);
mesh.createPolygon([0, 2, 3]);
node.entity = mesh;
// Apply a PBR material
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.6, 0.6, 0.6); // albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.8;
node.material = mat;
// Save as JSON glTF
const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('floor.gltf', GltfFormat.getInstance(), opts);
console.log('Scene written to floor.gltf');Поради та кращі практики
- Використовуйте
ObjLoadOptions.enableMaterials = trueколи вам потрібні дані матеріалів з .mtl‑файлів. Без цього список матеріалів у кожному вузлі буде порожнім. - Віддавайте перевагу
binaryMode = trueдля GLB при створенні ресурсів для веб‑або ігрових движків. Бінарний GLB — це один самодостатній файл, який завантажується швидше в браузерах та движках, ніж розділення JSON + .bin. - Використовуйте
openFromBuffer()у безсерверних середовищах щоб уникнути тимчасового вводу/виводу файлів. Отримайте ресурс, передайтеBufferбезпосередньо і запишіть результат у потік або інший буфер. - Перевірте
node.entityперед приведенням типу: не всі вузли містять сутність. Завжди захищайтесяinstanceofперевірте перед доступомMesh-специфічні властивості, такі якcontrolPoints. - Встановити
normalizeNormal = trueуObjLoadOptionsколи ваші вихідні OBJ‑файли надходять з ненадійних джерел. Це запобігає поширенню деґенерованих нормалей у подальших етапах рендерингу або валідації. - Зберегти
strict: trueу tsconfig.json: бібліотека створена за допомогоюnoImplicitAnyіstrictNullChecks. Вимкненняstrictмаскує реальні помилки типу і позбавляє цінності типізованого API. - Перебирати за допомогою
childNodes, а не індексний цикл: цеchildNodesвластивість повертає iterable; уникайте покладання на числове індексування для майбутньої сумісності.
Поширені проблеми
| Симптом | Ймовірна причина | Виправлення |
|---|---|---|
| Список матеріалів порожній після завантаження OBJ | enableMaterials не встановлено | Встановити options.enableMaterials = true |
| Файл GLB містить окремий .bin sidecar | binaryMode за замовчуванням false | Встановити opts.binaryMode = true |
| Вершинні нормалі відсутні у виводі STL | STL ASCII режим пропускає нормалі для кожної грані | Переключитися на binaryMode = true або обчислити нормалі перед експортом |
node.entity завжди null | Лише обхід rootNode, не його дочірні елементи | Рекурсивно у node.childNodes |
| Помилка TypeScript: властивість не існує | Старий @types кеш | Запустити npm install @aspose/3d знову; без окремого @types пакет потрібен |
openFromBuffer викидає помилку формату | Формат не може бути автоматично визначений за магічними даними | Передайте явний клас параметра формату як другий аргумент |
Часті запитання
Чи потребує бібліотека будь‑яких native addons або system packages? Ні. Aspose.3D FOSS for TypeScript має одну runtime dependency: xmldom, який є чистим JavaScript і встановлюється автоматично через npm. Немає .node native addons та жодних system packages для встановлення.
Які версії Node.js підтримуються? Node.js 18, 20 і 22 LTS. Бібліотека орієнтується на вивід CommonJS і використовує внутрішньо функції мови ES2020.
Чи можу я використовувати бібліотеку у браузерному бандлі (webpack/esbuild)? Бібліотека орієнтується на Node.js і використовує Node.js fs і Buffer API. Пакування для браузера офіційно не підтримується. Для використання в браузері завантажуйте сцену на сервері та передавайте результат (наприклад, у форматі GLB) клієнту.
У чому різниця між GltfSaveOptions.binaryMode = true і false? binaryMode = false створює .gltf файл JSON плюс окремий .bin бінарний буфер sidecar. binaryMode = true створює один самодостатній .glb файл. Використовуйте true для доставки активів у продакшн.
Чи можу я завантажити файл з HTTP‑відповіді, не зберігаючи його на диск? Так. Отримайте відповідь як Buffer (наприклад, використовуючи node-fetch або вбудований fetch у Node 18+), потім викличте scene.openFromBuffer(buffer, options).
Чи повна підтримка FBX? Ні. Класи імпортера та експортера FBX існують у бібліотеці, але FBX не підключений до Scene.open() або Scene.save() автоматичного визначення. Виклик scene.open('file.fbx') не викличе імпортер FBX; файл буде оброблений шляхом резервного STL. Використовуйте специфічні для FBX класи імпортера/експортера безпосередньо, якщо вам потрібен FBX I/O. Дивіться таблицю підтримки форматів вище, яка позначає FBX як No*.
Чи підтримує бібліотека TypeScript 4.x? Рекомендується TypeScript 5.0+. TypeScript 4.7+ має працювати на практиці, проте бібліотека тестується та розробляється під 5.0+.
Огляд довідки API
| Клас | Модуль | Призначення |
|---|---|---|
Scene | @aspose/3d | Контейнер сцени верхнього рівня; open(), openFromBuffer(), save(), rootNode, animationClips |
Node | @aspose/3d | Вузол графа сцени; childNodes, entity, transform, materials, createChildNode() |
Entity | @aspose/3d | Базовий клас для об’єктів, які можна прив’язати до сцени |
SceneObject | @aspose/3d | Базовий клас, спільний для Node і Entity |
A3DObject | @aspose/3d | Кореневий базовий з name і property bag |
Transform | @aspose/3d | Локальний зсув, обертання та масштаб |
Mesh | @aspose/3d | Полігональна сітка; controlPoints, polygonCount, createPolygon(), елементи вершини |
Geometry | @aspose/3d | Базовий клас для типів геометрії |
Camera | @aspose/3d | Об’єкт камери з полем зору та налаштуваннями проекції |
Light | @aspose/3d | Об’єкт світла (точкове, напрямкове, прожекторне) |
LambertMaterial | @aspose/3d | Модель дифузного + амбієнтного затінення |
PhongMaterial | @aspose/3d | Затінення Phong зі спекулярним та емісивним |
PbrMaterial | @aspose/3d | Фізично‑основана модель шорсткості/металевості для glTF |
Vector3 | @aspose/3d | 3-component double-precision vector |
Vector4 | @aspose/3d | 4-component vector for homogeneous math |
Matrix4 | @aspose/3d | 4×4 transformation matrix |
Quaternion | @aspose/3d | Кватерніон обертання |
BoundingBox | @aspose/3d | Осьово-орієнтована обмежувальна коробка |
FVector3 | @aspose/3d | Варіант одинарної точності Vector3 |
VertexElementNormal | @aspose/3d | Нормалі per-vertex або per-polygon-vertex |
VertexElementUV | @aspose/3d | Елемент вершини текстурних координат |
VertexElementVertexColor | @aspose/3d | Елемент вершини з per-vertex кольором |
MappingMode | @aspose/3d | Перелічення: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME |
ReferenceMode | @aspose/3d | Перелічення: DIRECT, INDEX, INDEX_TO_DIRECT |
AnimationClip | @aspose/3d | Названа анімація; надає animations: AnimationNode[]; створено за допомогою scene.createAnimationClip(name) |
AnimationNode | @aspose/3d | Названа група BindPoints; створено за допомогою clip.createAnimationNode(name) |
BindPoint | @aspose/3d | Прив’язує AnimationNode до властивості об’єкта сцени; відкриває property і channelsCount |
AnimationChannel | @aspose/3d | Розширює KeyframeSequence; містить keyframeSequence; доступний через bindPoint.getChannel(name) |
KeyFrame | @aspose/3d | Одинарна пара час/значення ключового кадру; несе interpolation: Interpolation |
KeyframeSequence | @aspose/3d | Упорядковано keyFrames список; preBehavior/postBehavior є Extrapolation об’єкти |
Interpolation | @aspose/3d | Enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE |
Extrapolation | @aspose/3d | Class з type: ExtrapolationType і repeatCount: number |
ExtrapolationType | @aspose/3d | Перелічення: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE |
ObjLoadOptions | @aspose/3d/formats/obj | Параметри імпорту OBJ: enableMaterials, flipCoordinateSystem, scale, normalizeNormal |
GltfSaveOptions | @aspose/3d/formats/gltf | Параметри експорту glTF/GLB: binaryMode |
GltfFormat | @aspose/3d/formats/gltf | Екземпляр формату для glTF/GLB; передайте до scene.save() |
StlLoadOptions | @aspose/3d/formats/stl | Параметри імпорту STL |
StlSaveOptions | @aspose/3d/formats/stl | Параметри експорту STL: binaryMode |
StlImporter | @aspose/3d/formats/stl | Низькорівневий читач STL |
StlExporter | @aspose/3d/formats/stl | Низькорівневий записувач STL |