3D 콘텐츠를 다루는 Node.js 개발자는 종종 형식 간 변환이 필요합니다: 디자인 툴은 OBJ를 내보내고, 웹 렌더러는 GLB를 기대하며, 3D 프린터는 STL을 요구하고, 제조 파이프라인은 3MF를 사용합니다. 이러한 변환을 단일하고 일관된 API로 처리하면 파이프라인에서 외부 도구의 수를 줄이고, 변환 로직을 애플리케이션 코드 내부에 유지하여 테스트 및 버전 관리를 할 수 있습니다.

@aspose/3d 패키지 (v24.12.0, MIT 라이선스)는 Node.js에서 주요 3D 포맷을 모두 읽고 쓸 수 있는 TypeScript 우선 API를 제공합니다. 이 가이드는 가장 일반적인 변환 워크플로우를 단계별로 안내합니다.

설치

npm install @aspose/3d

요구 사항: Node.js 18, 20, 또는 22; TypeScript 5.0 이상. 유일한 런타임 종속성은 xmldom.

지원되는 형식

아래 표는 이 가이드에서 다루는 형식과 해당 형식의 읽기/쓰기 지원 여부를 나열합니다.

포맷확장자읽기쓰기참고
Wavefront OBJ.obj읽기/쓰기 .mtl material 파일
glTF 2.0 (JSON).gltf표준 웹 전달 형식
glTF 2.0 (바이너리).glb독립형, 웹에 선호됨
STL (ASCII/Binary).stl표준 3D 프린팅 포맷
3MF.3mf풍부한 메타데이터를 갖춘 제조 형식
FBX.fbx아니오*아니오*Importer/exporter는 존재하지만 형식 자동 감지는 연결되어 있지 않아; via로는 사용할 수 없습니다. scene.open()
COLLADA.daeXML 기반 교환 형식

OBJ는 가져오기와 내보내기를 모두 지원합니다. 로드할 때는 scene.open() 그리고 저장할 때는 scene.save('output.obj'), 또는 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 제조 형식(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 예제에서 사용된 클래스는 이 문서의 클래스 참조 페이지를 참조하십시오.