كيفية تحميل نماذج ثلاثية الأبعاد في TypeScript
ال @aspose/3d الحزمة توفر لتطبيقات TypeScript وNode.js واجهة برمجة تطبيقات بسيطة لفتح ملفات المشاهد ثلاثية الأبعاد. 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: فتح ملف ثلاثي الأبعاد باستخدام 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());الخطوة 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);الخطوة 5: الوصول إلى بيانات رؤوس الشبكة عبر controlPoints
عندما يكون كيان العقدة Mesh,، يمكنك قراءة نقاط التحكم الخام (الرؤوس) من the 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 للتحقق قبل تكرار الرؤوس.
استخدام الذاكرة مرتفع للملفات الكبيرة تحميل من الذاكرة المؤقتة باستخدام scene.openFromBuffer() لا يقلل من الذاكرة القصوى: يجب تحليل الملف بالكامل. للملفات الكبيرة (> 100 ميغابايت)، تأكد من أن عملية 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'). الـ .mtl يتم كتابة ملف المادة تلقائيًا بجانب الـ .obj ملف.
أين يُتوقع وجود ملف .mtl عند تحميل OBJ؟? بشكل افتراضي، يبحث المحلل عن .mtl الملف المشار إليه داخل OBJ (mtllib التوجيه) نسبةً إلى دليل ملف OBJ. تأكد من أن كلا الملفين في نفس المجلد.