איך לטעון מודלים תלת‑ממדיים ב-TypeScript
ה @aspose/3d החבילה מספקת ליישומי TypeScript ו‑Node.js API פשוט לפתיחת קבצי סצנות תלת‑ממד. Scene הוא האובייקט השורש: קרא scene.open() עם נתיב קובץ ואפשרויות טעינה ספציפיות לפורמט באופן רשות, ואז לעבור scene.rootNode כדי לגשת לגאומטריה, חומרים והמרות.
מדריך שלב אחר שלב
שלב 1: התקנת @aspose/3d באמצעות npm
הוסף את החבילה לפרויקט שלך. אין צורך בבינריים מקומיים או בכלי בנייה ספציפיים לפלטפורמה; רק Node.js 18 או גרסה מאוחרת יותר.
npm install @aspose/3dלפרויקטים ב‑TypeScript, הגדרות הטיפוסים מובאות יחד עם החבילה:
##tsconfig.json: minimum required settings
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true
}
}שלב 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';שלב 3: פתיחת קובץ 3D באמצעות scene.open()
צור 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 כבר בזיכרון (שימושי במצבי serverless או זרימה):
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());שלב 4: איטרציה על צמתים בסצנה
גרף הסצנה הוא עץ שמקודש ב scene.rootNode. כל Node יכול להכיל צמתים צאצאים ו- entity (mesh, camera, light, וכו’).
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);שלב 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)}`);
}
}
}שלב 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.material) {
console.log(`Material on "${node.name}": ${node.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 הוא באורך אפס ייתכן שה‑mesh נטען אך אינו מכיל גאומטריה (למשל, קבוצה ריקה ב‑OBJ). השתמש mesh.polygonCount כדי לבדוק לפני איטרציה על הקודקודים.
שימוש בזיכרון גבוה עבור קבצים גדולים טעינה‑מ‑buffer עם scene.openFromBuffer() אינה מפחיתה את השיא בזיכרון: יש לנתח את כל הקובץ. עבור קבצים גדולים (> 100 MB), ודא שתהליך ה‑Node.js שלך מכיל ערמת זיכרון מספקת: node --max-old-space-size=4096 yourScript.js.
שגיאות סוג: ’entity’ הוא מסוג ‘unknown’ ה entity ה‑property מתויג באופן רחב. המר ל any או למחלקה ספציפית (Mesh, Camera, וכו’) בהתאם למה שאתה מצפה בסצנה שלך.
שאלות נפוצות (FAQ)
אילו פורמטים ניתן לטעון עם scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX, ו‑COLLADA (.dae) נתמכים כולם לייבוא. העבר את ה‑class המתאים *LoadOptions class לכל פורמט.
האם אפשר לטעון קובץ בלי לציין אפשרויות? כן. scene.open('model.glb') פועל ללא אפשרויות עבור פורמטים שאינם דורשים קונפיגורציה מיוחדת. העברת אפשרויות מומלצת עבור OBJ מכיוון שהרזולוציה של החומר תלויה ב‑ enableMaterials.
האם הטעינה מתבצעת באופן אסינכרוני? לא. scene.open() ו‑ scene.openFromBuffer() הם סינכרוניים. עטוף אותם בחוט עובד או setImmediate אם אתה צריך לשמור על לולאת אירועים מגיבה.
האם ייצוא OBJ נתמך? כן. ייצוא OBJ נתמך דרך scene.save('output.obj'). ה .mtl קובץ החומר נכתב אוטומטית לצד ה‑ .obj קובץ.
היכן מצופה קובץ .mtl בעת טעינת OBJ? בברירת מחדל, הפארסר מחפש את .mtl קובץ שמופיע בתוך ה-OBJ (mtllib הוראה) יחסית לתיקיית הקובץ OBJ. ודא ששני הקבצים באותה תיקייה.