How to Optimize 3D Models in TypeScript

How to Optimize 3D Models in TypeScript

Aspose.3D FOSS for TypeScript provides several strategies for reducing output file size and improving processing throughput. This guide covers format selection, binary embedding, in-memory pipelines, and Node.js-level optimizations.

Step-by-Step Guide

Step 1: Choose the Right Output Format

GLB (binary glTF) produces the most compact output with good tooling support. OBJ is text-based and larger. STL is compact for geometry-only workflows.

FormatSizeIncludes MaterialsIncludes AnimationBest Use
GLBSmallYes (embedded)YesWeb, games, general exchange
glTFMediumYes (separate)YesDevelopment, inspection
STLSmallNoNo3D printing, geometry-only
OBJLargeSeparate .mtlNoLegacy tools, wide compatibility
FBXMediumYesYesDCC tools (Maya, Blender)
3MFSmallYesNoModern 3D printing

Step 2: Export to Binary GLB

When saving to GLB, set GltfSaveOptions.binaryMode = true to produce a single self-contained binary file. This avoids the separate .bin sidecar and is required for many 3D viewers:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';

const scene = new Scene();
scene.open('complex-model.obj', new ObjLoadOptions());

const opts = new GltfSaveOptions();
opts.binaryMode = true;

scene.save('optimized.glb', opts);
console.log('Saved compact binary GLB');

Step 3: Use Buffer I/O for In-Memory Pipelines

When processing files in a web service, use openFromBuffer and saveToBuffer to avoid writing to the file system:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

async function convertInMemory(inputBuffer: Buffer): Promise<Buffer> {
    const scene = new Scene();
    scene.openFromBuffer(inputBuffer, new ObjLoadOptions());
    return scene.saveToBuffer('output.glb');
}

Step 4: Batch-Process Files with Worker Threads

For large conversion jobs, distribute work across Node.js worker threads to use multiple CPU cores:

// worker.ts
import { workerData, parentPort } from 'worker_threads';
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

const { inputPath, outputPath } = workerData;

const scene = new Scene();
scene.open(inputPath, new ObjLoadOptions());
scene.save(outputPath);

parentPort?.postMessage({ done: true, output: outputPath });
// main.ts: dispatch files to workers
import { Worker } from 'worker_threads';
import * as fs from 'fs';
import * as path from 'path';

const files = fs.readdirSync('./input').filter(f => f.endsWith('.obj'));

for (const file of files) {
    const inputPath = path.join('./input', file);
    const outputPath = path.join('./output', file.replace('.obj', '.glb'));

    const worker = new Worker('./dist/worker.js', {
        workerData: { inputPath, outputPath }
    });

    worker.on('message', msg => console.log(`Converted: ${msg.output}`));
    worker.on('error', err => console.error(`Error: ${err}`));
}

Step 5: Monitor Memory for Large Models

For files over 50 MB, monitor heap usage and process files sequentially if memory is constrained:

function logMemory(label: string) {
    const used = process.memoryUsage();
    console.log(`[${label}] heapUsed: ${Math.round(used.heapUsed / 1024 / 1024)} MB`);
}

logMemory('before load');
const scene = new Scene();
scene.open('large-model.obj');
logMemory('after load');
scene.save('output.glb');
logMemory('after save');

Increase the Node.js heap for very large models:

node --max-old-space-size=8192 convert.js

Frequently Asked Questions

What is the most compact output format?

GLB (binary glTF) with embedded assets produces the most compact single-file output for scenes with materials and textures. STL is more compact for geometry-only content.

Does @aspose/3d apply mesh simplification or LOD?

No. The library reads and writes the source geometry without modifying the mesh topology. Mesh simplification (vertex reduction, LOD generation) is not supported.

Can I strip materials to reduce file size?

Set ObjSaveOptions.enableMaterials = false when saving to OBJ. For glTF, all material data is always included; use STL for geometry-only output.


See Also