문제 해결 가이드

문제 해결 가이드

이 페이지에서는 TypeScript 및 Node.js 프로젝트에서 @aspose/3d을 사용할 때 가장 흔히 발생하는 오류와 그 근본 원인 설명 및 검증된 해결 방법을 다룹니다.


모듈 해석 오류

Error: Cannot find module '@aspose/3d/formats/obj'

Root cause: TypeScript의 모듈 해석 전략은 moduleResolutionnode 또는 node16로 설정되지 않는 한 package.json의 Node.js‑style 서브‑path 내보내기(exports)를 지원하지 않습니다.

수정: 귀하의 tsconfig.json에서 moduleResolution"node"로 설정하십시오:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true
  }
}

TypeScript 5.x와 "module": "node16" 또는 "module": "nodenext"를 사용 중이라면, "moduleResolution": "node16"을 사용하여 일치시킵니다.


SyntaxError: Cannot use import statement in a module

Root cause: 컴파일된 JavaScript가 require() 의미 체계로 실행되고 있지만 출력에 ES 모듈 import 구문이 포함됩니다; 이는 modulees2020 또는 esnext로 설정된 경우에 발생하지만 Node.js 런타임은 CommonJS를 기대합니다.

Fix: "module": "commonjs"tsconfig.json에 사용하고 컴파일된 .js 파일을 node으로 직접 실행하십시오:

{
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "./dist"
  }
}

그런 다음 컴파일하고 실행하십시오:

npx tsc
node dist/main.js

Error: Cannot find module '@aspose/3d'

Root cause: 패키지가 설치되지 않았거나 node_modules가 오래되었습니다.

수정:

npm install @aspose/3d

설치 확인:

node -e "const { Scene } = require('@aspose/3d'); console.log('OK', new Scene().constructor.name);"

로드 후 빈 씬

장면이 로드되지만 rootNode.childNodes은 비어 있습니다

Root cause (1): 파일 형식이 모든 기하학을 자식 노드가 아니라 rootNode.entity에 직접 배치합니다. 이는 단일 메쉬 STL 파일에서 일반적입니다.

진단:

import { Scene, Mesh } from '@aspose/3d';

const scene = new Scene();
scene.open('model.stl');

// Check rootNode directly
if (scene.rootNode.entity) {
    console.log(`Root entity: ${scene.rootNode.entity.constructor.name}`);
}
console.log(`Child count: ${scene.rootNode.childNodes.length}`);

수정: scene.rootNode 자체부터 시작하여 자식만이 아니라 전체를 순회합니다:

function visit(node: any): void {
    if (node.entity instanceof Mesh) {
        const m = node.entity as Mesh;
        console.log(`Mesh: ${m.controlPoints.length} vertices`);
    }
    for (const child of node.childNodes) {
        visit(child);
    }
}
visit(scene.rootNode);

Root cause (2): 파일 경로가 잘못되었거나 파일이 0바이트입니다. open()을 호출하기 전에 파일이 존재하고 비어 있지 않은지 확인하십시오.

import * as fs from 'fs';

const path = 'model.obj';
if (!fs.existsSync(path)) throw new Error(`File not found: ${path}`);
const stat = fs.statSync(path);
if (stat.size === 0) throw new Error(`File is empty: ${path}`);

OBJ 로드 후 재질 목록이 비어 있습니다

Root cause: 재질 로딩은 기본적으로 ObjLoadOptions에서 비활성화됩니다. 라이브러리는 .mtl 사이드카 파일을 읽지 않고 기하학을 로드합니다.

Fix: enableMaterials = true 설정:

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

const scene = new Scene();
const opts = new ObjLoadOptions();
opts.enableMaterials = true;
scene.open('model.obj', opts);

또한 .mtl 파일을 .obj 파일과 같은 디렉터리에 두세요, 라이브러리가 .obj 경로를 기준으로 해결하기 때문입니다.


포맷 및 I/O 오류

openFromBuffer이 인식되지 않는 형식 오류를 발생시킵니다

Root cause: 버퍼 내용이 인식 가능한 바이너리 형식이 아니거나, 버퍼가 손상되었습니다(잘려 있거나, 인코딩이 잘못되었거나, 원시 바이트 대신 base64인 경우).

진단:

const buffer = fs.readFileSync('model.glb');
console.log('Buffer size:', buffer.length, 'bytes');
console.log('First 4 bytes (hex):', buffer.slice(0, 4).toString('hex'));
// GLB magic: 676c5446 ("glTF")
// STL binary starts with 80 bytes of header; no fixed magic
// OBJ is text: openFromBuffer may not detect format

Fix: 텍스트 기반 포맷 (OBJ, COLLADA)의 경우, 형식을 힌트하기 위해 적절한 옵션 클래스를 전달하십시오:

import { ObjLoadOptions } from '@aspose/3d/formats/obj';
scene.openFromBuffer(buffer, new ObjLoadOptions());

출력 GLB가 3D 뷰어에서 JSON 형식으로 열립니다

Root cause: GltfSaveOptions.binaryModefalse를 기본값으로 설정되어, 출력 파일 이름이 .glb인 경우에도 .gltf JSON 출력을 생성합니다.

Fix: 명시적으로 binaryMode = true를 설정합니다:

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

const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('output.glb', opts);

STL 출력에 색상 또는 재료 데이터가 슬라이서에 없습니다.

Root cause: STL 형식은 표준 사양에서 재료나 색상을 지원하지 않습니다. 색상을 지원하는 슬라이서는 @aspose/3d에서 지원하지 않는 독점 확장을 사용합니다.

수정: 대신 3MF로 내보내면 색상 및 재료 메타데이터를 지원합니다:

scene.save('output.3mf');

TypeScript 컴파일 오류

Property 'controlPoints' does not exist on type 'Entity'

Root cause: Entity은 기본 클래스이며; Mesh은 기하학 속성을 가진 구체 타입입니다. 메시 전용 멤버에 접근하기 전에 instanceof 가드를 사용해야 합니다.

수정:

import { Mesh } from '@aspose/3d';

if (node.entity instanceof Mesh) {
    const mesh = node.entity as Mesh;
    console.log(mesh.controlPoints.length);
}

Type 'null' is not assignable to type 'Node'

Root cause: getChildNode()Node | null를 반환합니다. TypeScript 엄격 모드에서는 null 경우를 처리하도록 요구합니다.

수정:

const child = node.getChildNode('wheel');
if (!child) throw new Error('Node "wheel" not found');
// child is now Node, not null

Cannot find name 'GltfSaveOptions'

Root cause: GltfSaveOptions은 서브 경로 모듈 @aspose/3d/formats/gltf에 있으며, 패키지 루트에 있지 않습니다.

Fix: 하위 경로에서 가져오기:

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

메모리 및 성능 문제

프로세스가 대형 FBX 파일에서 메모리 부족 현상이 발생합니다

Root cause: 매우 큰 FBX 파일(>200 MB)은 상당한 힙을 할당합니다. Node.js 기본 힙은 64비트 시스템에서 약 1.5 GB이지만 다중 씬 파일에는 충분하지 않을 수 있습니다.

Fix: Node.js 힙 크기 늘리기:

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

메모리가 제한된 경우 파일을 병렬이 아닌 순차적으로 처리하십시오:

for (const file of files) {
    const scene = new Scene();
    scene.open(file);
    scene.save(file.replace('.fbx', '.glb'));
    // scene goes out of scope; GC can reclaim
}

관련 항목

 한국어