Функції та можливості

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 і animationClips
  • Node: іменований вузол дерева з childNodes, entity, transform, і materials
  • Entity: базовий клас для приєднуваних об’єктів (Mesh, Camera, Light)
  • SceneObject: базовий клас, спільний для Node і Entity
  • A3DObject: кореневий базовий клас з 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 і polygonCount
  • Geometry: базовий клас з управлінням вершинними елементами
  • VertexElementNormal: нормалі per-vertex або per-polygon-vertex
  • VertexElementUV: текстурні координати (один або кілька UV-каналів)
  • VertexElementVertexColor: дані кольору per-vertex
  • MappingMode: керує тим, як дані елементів відображаються на полігони (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/DAE
  • PhongMaterial: додає спекулярний колір, блиск і емісивність; тип матеріалу за замовчуванням OBJ
  • PbrMaterial: фізично‑обґрунтована модель шорсткості/металевості; використовується для імпорту та експорту 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, setTRS
  • Quaternion: кватерніон обертання з fromEulerAngle() (статичний, одиничний), eulerAngles() (метод екземпляра), slerp(), normalize()
  • BoundingBox: прямокутна обмежувальна коробка, орієнтована за осями, з minimum, maximum, center, size, merge
  • FVector3: варіант одиночної точності 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.animations
  • BindPoint: прив’язує AnimationNode до конкретної властивості об’єкта сцени; відкриває property і channelsCount
  • AnimationChannel: розширює KeyframeSequence; містить окремий keyframeSequence; доступний через bindPoint.getChannel(name)
  • KeyFrame: одинарна пара час/значення; несе per-keyframe interpolation: Interpolation
  • KeyframeSequence: впорядкований список KeyFrame об’єкти через keyFrames; має preBehavior і postBehavior (Extrapolation)
  • Interpolation: enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
  • Extrapolation: class з type: ExtrapolationType і repeatCount: number
  • ExtrapolationType: 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; уникайте покладання на числове індексування для майбутньої сумісності.

Поширені проблеми

СимптомЙмовірна причинаВиправлення
Список матеріалів порожній після завантаження OBJenableMaterials не встановленоВстановити options.enableMaterials = true
Файл GLB містить окремий .bin sidecarbinaryMode за замовчуванням falseВстановити opts.binaryMode = true
Вершинні нормалі відсутні у виводі STLSTL 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/3d3-component double-precision vector
Vector4@aspose/3d4-component vector for homogeneous math
Matrix4@aspose/3d4×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/3dEnum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
Extrapolation@aspose/3dClass з 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
 Українська