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/3dTypeScript 프로젝트의 경우, 타입 정의가 패키지에 포함되어 있습니다:
##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 배열. 각 항목은 Vector4 와 x, 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 파일 디렉터리를 기준으로 상대 경로입니다. 두 파일이 같은 폴더에 있는지 확인하세요.