Функции и возможности

Aspose.3D FOSS for TypeScript — это библиотека Node.js с лицензией MIT для загрузки, построения и экспорта 3D‑сцен. Она поставляется с полными определениями типов TypeScript и единственной runtime‑зависимостью (xmldom), и поддержкой шести основных форматов 3D‑файлов. Эта страница является основным справочником по всем областям функций и содержит исполняемые примеры кода TypeScript для каждой из них.

Установка и настройка

Установите пакет из 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 (binary 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‑контент организован в виде дерева 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: локальный перенос, вращение (Эйлера и кватерниона), и масштаб

Обход графа сцены:

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);

Геометрия и 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 для TypeScript поддерживает три типа материалов, охватывающих весь спектр от устаревшего Phong shading до физически‑корректного рендеринга:

  • LambertMaterial: диффузный цвет и окружающий цвет; отображается на простые материалы OBJ/DAE
  • PhongMaterial: добавляет specular color, shininess и emissive; тип материала по умолчанию для OBJ
  • PbrMaterial: физически‑основанная модель roughness/metallic; используется для импорта и экспорта 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-component vector; поддерживает minus(), times(), dot(), cross(), normalize(), length, angleBetween()
  • Vector4: 4-component vector для однородных координат
  • 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: класс с 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 свойство возвращает итерируемый объект; избегайте полагаться на числовую индексацию для обеспечения совместимости в будущем.

Распространённые проблемы

СимптомВероятная причинаИсправление
Список материалов пуст после загрузки OBJenableMaterials не заданоУстановлено options.enableMaterials = true
Файл GLB содержит отдельный .bin‑sidecarbinaryMode по умолчанию falseУстановить opts.binaryMode = true
Нормали вершин отсутствуют в выводе STLРежим STL ASCII опускает нормали гранейПереключиться на binaryMode = true или вычислить нормали перед экспортом
node.entity всегда nullТолько обход rootNode, не его дочернихРекурсивно в node.childNodes
Ошибка TypeScript: свойство не существуетСтарый @types кешЗапустить npm install @aspose/3d снова; без отдельного @types требуется пакет
openFromBuffer выбрасывает ошибку форматаФормат не может быть автоматически определён по magicПередайте явный класс опций формата в качестве второго аргумента

Часто задаваемые вопросы

Требует ли библиотека какие‑либо native addons или системные пакеты? Нет. Aspose.3D FOSS for TypeScript имеет единственную зависимость во время выполнения: xmldom, который представляет собой чистый JavaScript и устанавливается автоматически npm. Нет .node нативных аддонов и системных пакетов для установки.

Какие версии 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 создаёт a .gltf JSON‑файл плюс отдельный .bin двоичный буфер‑сайдкар. 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 importer; файл будет обработан резервным путём STL. Используйте классы FBX-specific importer/exporter напрямую, если вам нужен 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 и набор свойств
Transform@aspose/3dЛокальный перенос, вращение и масштаб
Mesh@aspose/3dПолигональная сетка; controlPoints, polygonCount, createPolygon(), элементы вершин
Geometry@aspose/3dБазовый класс для типов геометрии
Camera@aspose/3dСущность камеры с настройками угла обзора и проекции
Light@aspose/3dСветовой объект (point, directional, spot)
LambertMaterial@aspose/3dМодель затенения Diffuse + ambient
PhongMaterial@aspose/3dЗатенение Phong с specular и emissive
PbrMaterial@aspose/3dФизически основанная модель roughness/metallic для 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Нормали, задаваемые на каждую вершину или вершину полигона
VertexElementUV@aspose/3dЭлемент вершины текстурных координат
VertexElementVertexColor@aspose/3dЭлемент вершины цвета
MappingMode@aspose/3dEnum: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME
ReferenceMode@aspose/3dEnum: 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/3dКласс с type: ExtrapolationType и repeatCount: number
ExtrapolationType@aspose/3dEnum: 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
 Русский