TypeScript에서 3D 모델을 로드하는 방법

TypeScript에서 3D 모델을 로드하는 방법

@aspose/3d 패키지는 TypeScript 및 Node.js 애플리케이션에 3D 씬 파일을 여는 간단한 API를 제공합니다. Scene 은(는) 루트 객체입니다: 호출 scene.open() 파일 경로와 선택적인 포맷별 로드 옵션을 제공하고, 그 다음 탐색합니다 scene.rootNode 기하학, 재질 및 변환에 접근합니다.

단계별 가이드

Step 1: npm을 통해 @aspose/3d 설치

패키지를 프로젝트에 추가합니다. 네이티브 바이너리나 플랫폼별 빌드 도구가 필요하지 않으며, Node.js 18 이상만 있으면 됩니다.

npm install @aspose/3d

TypeScript 프로젝트의 경우, 타입 정의가 패키지에 포함되어 있습니다:

##tsconfig.json: minimum required settings
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true
  }
}

Step 2: Scene 및 포맷별 옵션 가져오기

각 포맷은 하위 경로에 자체 로더 클래스와 옵션 객체를 노출합니다. 필요한 것만 가져오세요:

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

다른 포맷도 동일한 패턴을 따릅니다:

import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';

Step 3: scene.open()을 사용해 3D 파일 열기

생성합니다 Scene 인스턴스, 그 다음 호출 scene.open() 파일 경로와 선택적 로드 옵션 객체를 사용합니다. 호출은 동기식입니다.

import { Scene } 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);
console.log('Scene loaded successfully');

다음으로부터 로드하려면 Buffer 이미 메모리에 있는 (서버리스 또는 스트리밍 상황에서 유용함):

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

const buffer = fs.readFileSync('model.obj');
const scene = new Scene();
scene.openFromBuffer(buffer, new ObjLoadOptions());

Step 4: 씬 노드 순회

씬 그래프는 다음을 루트로 하는 트리입니다 scene.rootNode. 각 Node 자식 노드와 선택적인 요소를 포함할 수 있습니다 entity (메시, 카메라, 라이트 등).

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

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

function visitNode(node: any, depth: number = 0): void {
    const indent = '  '.repeat(depth);
    console.log(`${indent}Node: ${node.name}`);
    if (node.entity) {
        console.log(`${indent}  Entity type: ${node.entity.constructor.name}`);
    }
    for (const child of node.childNodes) {
        visitNode(child, depth + 1);
    }
}

visitNode(scene.rootNode);

Step 5: controlPoints를 통해 메쉬 정점 데이터에 접근하기

노드의 엔티티가 … 일 경우 Mesh, 원시 제어점(버텍스)을 다음에서 읽을 수 있습니다 controlPoints 배열. 각 항목은 Vector4x, y, z, 및 w 구성 요소들.

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

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

for (const node of scene.rootNode.childNodes) {
    if (!node.entity) continue;
    const entity = node.entity;
    // Check if the entity is a Mesh by duck-typing controlPoints
    if ('controlPoints' in entity) {
        const mesh = entity as any;
        console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices`);
        // Print first three vertices
        for (let i = 0; i < Math.min(3, mesh.controlPoints.length); i++) {
            const v = mesh.controlPoints[i];
            console.log(`  v[${i}]: x=${v.x.toFixed(4)}, y=${v.y.toFixed(4)}, z=${v.z.toFixed(4)}`);
        }
    }
}

Step 6: 재질 로드를 위한 ObjLoadOptions 설정

ObjLoadOptions 동반되는 방식을 제어하는 속성을 노출합니다 .mtl 재질 파일 및 텍스처가 해결되는 방식을 제어하는 속성을 노출합니다.

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

const options = new ObjLoadOptions();
options.enableMaterials = true;   // parse .mtl file if present

const scene = new Scene();
scene.open('model.obj', options);

// Inspect materials attached to nodes
for (const node of scene.rootNode.childNodes) {
    if (node.entity && node.entity.material) {
        console.log(`Material on "${node.name}": ${node.entity.material.constructor.name}`);
    }
}

일반적인 문제 및 해결 방법

오류: 모듈 ‘@aspose/3d/formats/obj’을(를) 찾을 수 없습니다 포맷 하위 경로는 Node.js 12.7+ 패키지 내보내기가 필요합니다. Node.js 18 이상을 사용하고 있는지 확인하십시오. TypeScript를 사용하는 경우, 설정하십시오 "moduleResolution": "node16" 또는 "bundler" 에서 tsconfig.json.

scene.rootNode.childNodes가 open() 후에 비어 있습니다 일부 OBJ 파일은 비표준 줄 끝을 사용하거나 마지막 줄바꿈이 없을 수 있습니다. 텍스트 편집기로 열어 파일이 유효한 OBJ인지 확인하십시오. 또한 전달한 것이 ObjLoadOptions 이고 일반적인 것이 아니라 LoadOptions: 형식별 옵션이 올바른 디스패치를 위해 필요합니다.

controlPoints 배열의 길이가 0입니다 메시가 로드되었지만 기하학이 없을 수 있습니다(예: OBJ의 빈 그룹). 사용하십시오 mesh.polygonCount 정점을 반복하기 전에 확인하십시오.

대용량 파일의 메모리 사용량이 높습니다 버퍼에서 로드하기와 함께 scene.openFromBuffer() 피크 메모리를 줄이지 않습니다: 전체 파일을 파싱해야 합니다. 대용량 파일(> 100 MB)의 경우 Node.js 프로세스에 충분한 힙이 있는지 확인하십시오: node --max-old-space-size=4096 yourScript.js.

타입 오류: ’entity’는 ‘unknown’ 타입입니다entity 속성은 넓게 타입이 지정되었습니다. 캐스트 대상 any 또는 특정 클래스로 (Mesh, Camera, 등) 당신이 장면에서 기대하는 것에 따라.

자주 묻는 질문 (FAQ)

scene.open()으로 로드할 수 있는 포맷은 무엇인가요? OBJ, glTF 2.0(.gltf + .bin), GLB, STL, 3MF, FBX, 그리고 COLLADA(.dae)는 모두 가져오기를 지원합니다. 해당 *LoadOptions 각 포맷에 대한 클래스를 전달합니다.

옵션을 지정하지 않고 파일을 로드할 수 있나요? 예. scene.open('model.glb') 특별한 구성이 필요하지 않은 포맷은 옵션 없이도 작동합니다. OBJ의 경우 재질 해상도가 재질 파일에 따라 달라지기 때문에 옵션을 전달하는 것이 권장됩니다. enableMaterials.

로드가 비동기적으로 실행되나요? 아니요. scene.open()scene.openFromBuffer() 는 동기식입니다. 워커 스레드에 감싸거나 setImmediate 이벤트 루프를 응답 상태로 유지해야 할 경우.

OBJ 내보내기가 지원되나요? 예. OBJ 내보내기는 다음을 통해 지원됩니다. scene.save('output.obj'). The .mtl material file은 자동으로 해당 파일과 함께 작성됩니다. .obj 파일.

OBJ를 로드할 때 .mtl 파일은 어디에 있어야 합니까? 기본적으로 파서는 다음을 찾습니다. .mtl OBJ 내부에 참조된 파일 (mtllib directive) OBJ 파일 디렉터리를 기준으로 상대 경로입니다. 두 파일이 같은 폴더에 있는지 확인하세요.

참고

 한국어