Node.js 개발자들은 3D 콘텐츠를 다룰 때 형식 간 변환이 자주 필요합니다. 디자인 툴은 OBJ를 내보내고, 웹 렌더러는 GLB를 기대하며, 3D 프린터는 STL을 요구하고, 제조 파이프라인은 3MF를 사용합니다. 이러한 변환을 단일하고 일관된 API로 처리하면 파이프라인에서 외부 도구의 수를 줄이고, 변환 로직을 애플리케이션 코드 내부에 유지하여 테스트 및 버전 관리를 할 수 있습니다.
그 @aspose/3d 패키지(v24.12.0, MIT 라이선스)는 Node.js에서 주요 3D 포맷을 모두 읽고 쓸 수 있는 TypeScript‑first API를 제공합니다. 이 가이드는 가장 일반적인 변환 워크플로를 단계별로 안내합니다.
설치
npm install @aspose/3d
요구 사항: Node.js 18, 20 또는 22; TypeScript 5.0 이상. 런타임 의존성은 단 하나뿐이며 xmldom.
지원되는 포맷
아래 표는 이 가이드에서 다루는 포맷과 해당 포맷의 읽기/쓰기 지원 여부를 나열합니다.
| 형식 | 확장자 | 읽기 | 쓰기 | 참고 |
|---|---|---|---|---|
| Wavefront OBJ | .obj | 예 | 아니오 | 가져오기 전용; 읽기 .mtl 재질 파일 |
| glTF 2.0 (JSON) | .gltf | 예 | 예 | 표준 웹 전달 형식 |
| glTF 2.0 (Binary) | .glb | 예 | 예 | 독립형, 웹에 선호됨 |
| STL (ASCII/Binary) | .stl | 예 | 예 | 표준 3D 프린팅 포맷 |
| 3MF | .3mf | 예 | 예 | 풍부한 메타데이터를 갖춘 제조 형식 |
| FBX | .fbx | 아니오* | 아니오* | Importer/exporter는 존재하지만 형식 자동 감지는 연결되어 있지 않으며, 통해 사용할 수 없습니다. scene.open() |
| COLLADA | .dae | 예 | 예 | XML 기반 교환 형식 |
참고: OBJ는 가져오기 전용 (canExport: false). 다른 형식으로 OBJ 콘텐츠를 변환하려면, 다음을 사용하여 로드하십시오 scene.open() 그리고 glTF, STL, 3MF와 같은 지원되는 내보내기 형식으로 저장하십시오.
OBJ → GLB (웹 전달)
OBJ를 바이너리 glTF(GLB)로 변환하는 것은 가장 일반적인 웹 워크플로우입니다. GLB는 텍스처, 기하학, 메타데이터가 하나의 파일에 포함된 자체 포함 바이너리 번들로, HTTP 전달에 효율적이며 Three.js, Babylon.js, model-viewer에서 직접 로드할 수 있습니다.
import { Scene } from '@aspose/3d';
function convertObjToGlb(inputPath: string, outputPath: string): void {
const scene = new Scene();
scene.open(inputPath);
scene.save(outputPath); // extension '.glb' selects binary GLB format
console.log(`Converted ${inputPath} -> ${outputPath}`);
}
convertObjToGlb('model.obj', 'model.glb');
출력 형식은 파일 확장자를 기반으로 추론됩니다. 다음을 사용하십시오 .glb 바이너리 GLB 또는 .gltf 별도의 JSON + .bin 레이아웃.
OBJ → STL: 3D 프린팅을 위한 모델 준비
STL은 FDM 및 SLA 3D 프린팅의 공통 언어입니다. PrusaSlicer, Bambu Studio, Chitubox와 같은 슬라이서 모두 STL을 지원합니다. OBJ를 STL로 변환하는 것은 두 포맷 모두 삼각형 메쉬를 저장하므로 간단합니다.
import { Scene } from '@aspose/3d';
function convertObjToStl(inputPath: string, outputPath: string): void {
const scene = new Scene();
scene.open(inputPath);
scene.save(outputPath); // extension '.stl' selects STL format
console.log(`STL written to ${outputPath}`);
}
convertObjToStl('part.obj', 'part.stl');
STL은 색상, 재질, UV 데이터를 저장하지 않습니다. OBJ 파일에 재질 그룹이 포함되어 있다면 해당 정보는 내보내기 시 사라집니다. 색상을 보존하는 출력 포맷이 필요하다면 대신 3MF를 고려하십시오(아래 참고).
STL → glTF: 스캐너 또는 CAD 출력에서 웹으로
구조광 스캐너와 파라메트릭 CAD 익스포터는 일반적으로 STL을 출력합니다. glTF로 변환하면 서버‑사이드 렌더링 단계 없이도 웹 기반 뷰어와 AR 플랫폼에서 기하학을 활용할 수 있습니다.
import { Scene } from '@aspose/3d';
function convertStlToGltf(inputPath: string, outputPath: string): void {
const scene = new Scene();
scene.open(inputPath);
// extension '.gltf' saves as JSON + .bin sidecar
scene.save(outputPath);
console.log(`glTF written to ${outputPath}`);
}
convertStlToGltf('scan_output.stl', 'scan_output.gltf');
STL은 재질이나 텍스처 정보를 포함하지 않으므로, 생성된 glTF 파일에는 기하학 정보만 들어갑니다. 필요하다면 로드 후 프로그램적으로 재질을 씬 노드에 연결할 수 있습니다.
3MF to glTF (Manufacturing to Visualization)
3D Manufacturing Format(3MF)은 색상, 재료, 컴포넌트 트리, 프린트 메타데이터를 기하학과 함께 저장하기 때문에 적층 제조 워크플로우에서 점점 더 많이 사용됩니다. 3MF를 glTF로 변환하면 씬 구조를 유지하면서 웹 도구에서의 하위 시각화를 가능하게 합니다.
import { Scene } from '@aspose/3d';
function convert3mfToGlb(inputPath: string, outputPath: string): void {
const scene = new Scene();
scene.open(inputPath);
scene.save(outputPath); // extension '.glb' selects binary GLB format
console.log(`3MF -> GLB: ${outputPath}`);
}
convert3mfToGlb('assembly.3mf', 'assembly.glb');
3MF files often contain multi-component assemblies. The scene graph produced by scene.open() 구성 요소 계층 구조를 보존합니다 scene.rootNode.childNodes, 따라서 저장하기 전에 개별 파트를 검사하거나 조작할 수 있습니다.
배치 변환
파일 디렉터리를 처리할 때, 각 변환을 try/catch 단일 손상된 파일이 전체 배치를 중단하지 않도록 합니다.
import { Scene } from '@aspose/3d';
import { readdirSync } from 'fs';
import { join, basename, extname } from 'path';
interface ConversionResult {
input: string;
output: string;
success: boolean;
error?: string;
}
function batchConvertToGlb(
inputDir: string,
outputDir: string,
extensions: string[] = ['.obj', '.stl', '.3mf', '.dae'] // .fbx excluded: format auto-detection not wired
): ConversionResult[] {
const results: ConversionResult[] = [];
const files = readdirSync(inputDir).filter((f) =>
extensions.includes(extname(f).toLowerCase())
);
for (const file of files) {
const inputPath = join(inputDir, file);
const outputPath = join(outputDir, basename(file, extname(file)) + '.glb');
try {
const scene = new Scene();
scene.open(inputPath);
scene.save(outputPath); // extension '.glb' infers GLB format
results.push({ input: inputPath, output: outputPath, success: true });
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
results.push({ input: inputPath, output: outputPath, success: false, error: message });
console.error(`Failed to convert ${file}: ${message}`);
}
}
const succeeded = results.filter((r) => r.success).length;
console.log(`Batch complete: ${succeeded}/${results.length} files converted.`);
return results;
}
// Usage
batchConvertToGlb('./input', './output');
위 패턴은 입력 디렉터리에서 지원되는 각 파일 확장자를 읽고, GLB로 변환하며, 루프를 중단하지 않고 실패를 기록합니다. 반환된 배열은 ConversionResult 객체는 보고 또는 재시도 로직에 사용할 수 있습니다.
결론
@aspose/3d Node.js TypeScript 애플리케이션에서 일관된 두 단계 API로 형식 변환 요구 사항 전체를 포괄합니다: scene.open() 로드하기 위해, scene.save() 쓰기 위해. 기억해야 할 핵심 제약은 FBX 임포터 및 익스포터 클래스가 존재하지만 형식 자동 감지는 아직 연결되지 않아 FBX 파일을 통해 로드할 수 없다는 점입니다 scene.open().
다음에 대한 자세한 내용은 Scene, Node, 및 Mesh 예제에서 사용된 클래스는 이 문서의 클래스 참조 페이지를 참조하십시오.