چگونه مدل‌های سه‌بعدی را در TypeScript بارگذاری کنیم

چگونه مدل‌های سه‌بعدی را در TypeScript بارگذاری کنیم

بسته @aspose/3d یک API ساده برای برنامه‌های TypeScript و Node.js جهت باز کردن فایل‌های صحنه 3D فراهم می‌کند. 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
  }
}

مرحله ۲: وارد کردن صحنه و گزینه‌های مخصوص فرمت

هر فرمت کلاس بارگذار و شیء گزینه‌های خود را تحت یک مسیر فرعی نمایش می‌دهد. فقط آنچه نیاز دارید را وارد کنید:

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';

مرحله ۳: یک فایل 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 که قبلاً در حافظه است (مفید در زمینه‌های سرورلس یا استریمینگ):

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());

مرحله ۴: مرور گره‌های صحنه

گراف صحنه یک درخت است که ریشه آن 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);

مرحله 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 از پایان خطوط غیر استاندارد استفاده می‌کنند یا newline پایانی ندارند. با باز کردن فایل در یک ویرایشگر متن، صحت یک فایل OBJ معتبر را تأیید کنید. همچنین تأیید کنید که ObjLoadOptions را ارسال کرده‌اید و نه LoadOptions عمومی: گزینه‌های مخصوص فرمت برای توزیع صحیح لازم هستند.

آرایه controlPoints طول صفر دارد
ممکن است مش بارگذاری شده باشد اما شامل هندسه‌ای نباشد (مثلاً یک گروه خالی در OBJ). از mesh.polygonCount برای بررسی قبل از تکرار رئوس استفاده کنید.

مصرف حافظه برای فایل‌های بزرگ زیاد است
بارگذاری از بافر با scene.openFromBuffer() باعث کاهش حافظه اوج نمی‌شود: کل فایل باید تجزیه شود. برای فایل‌های بزرگ (> 100 مگابایت)، اطمینان حاصل کنید که فرآیند Node.js شما حافظه heap کافی دارد: 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') پشتیبانی می‌شود. فایل مواد .mtl به‌صورت خودکار در کنار فایل .obj نوشته می‌شود.

فایل .mtl در هنگام بارگذاری OBJ کجا انتظار می‌رود؟
به‌صورت پیش‌فرض، تجزیه‌کننده به دنبال فایل .mtl که در داخل OBJ (دستور mtllib) ارجاع داده شده است، نسبت به پوشهٔ فایل OBJ می‌گردد. مطمئن شوید هر دو فایل در یک پوشه قرار دارند.

همچنین ببینید

 فارسی