كيفية إرسال رسالة 3D في TypeScript
الرسم البياني للمشهد في Aspose.3D FOSS for TypeScript هو شجرة من Node الأجسام التي تُدخل في scene.rootNode.المشي هو التكرار: كل عقدة يعرض أ childNodes غير قابلة للاستخدام و اختياري entity هذا الدليل يظهر كيفية المشي على الشجرة بأكملها ، وتحديد أنواع الكيانات ، وجمع إحصاءات القرن.
المعايير
- Node.js 18 أو أحدث
- TypeScript 5.0 أو أحدث
@aspose/3dتثبيت
خطوة بخطوة دليل
الخطوة الأولى: تثبيت وتصدير
قم بتثبيت الحزمة :
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.
استيراد الفصول المستخدمة في هذا الدليل:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { Mesh } from '@aspose/3d/entities';Scene و Mesh هذه هي الفصول الأساسية. ObjLoadOptions يتم استخدامها في نموذج التحميل؛ استبدال فئة الخيارات المقابلة لأشكال أخرى.
الخطوة 2: تحميل المشهد من ملف
خلق أ Scene و اتصلت scene.open() مع مسار الملفات.الشكل الكشف هو تلقائي من الأرقام السحرية الثنائية، لذلك لا تحتاج إلى إدخال تنسيق لملفات GLB أو STL أو 3MF:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());
console.log(`Root node: "${scene.rootNode.name}"`);
console.log(`Top-level children: ${scene.rootNode.childNodes.length}`);يمكنك أيضًا تحميلها من A Buffer في الذاكرة باستخدام scene.openFromBuffer(buffer, options);· مفيد في الأنابيب الخالية من الخادم حيث لا يوجد قرص I/O.
الخطوة الثالثة: إعداد وظيفة تجريبية
التراجع فوق childNodes المعيار القياسي: يزور الوظيفة كل عقدة أولاً عمقاً:
function traverse(node: any, depth = 0): void {
const indent = ' '.repeat(depth);
const entityType = node.entity ? node.entity.constructor.name : '-';
console.log(`${indent}[${entityType}] ${node.name}`);
for (const child of node.childNodes) {
traverse(child, depth + 1);
}
}
traverse(scene.rootNode);لقطة واحدة تسمى Cube,سوف يبدو الإنتاج كما هو الحال:
[-] RootNode
[Mesh] Cube<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”
<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>
node.entity هو null - عنصر العظام، وعنصر المجموعة، ومركز constructor.name فحص الأعمال لأي نوع من الكيانات: Mesh, Camera, Light,وما إلى ذلك.
الخطوة 4: الوصول إلى نوع الكيان على كل عقدة
لتنفيذ الإجراءات القائمة على نوع الكيان، استخدم instanceof فحص بعد الحرس الصفر:
import { Mesh } from '@aspose/3d/entities';
function visitWithTypeCheck(node: any, depth = 0): void {
const indent = ' '.repeat(depth);
if (node.entity instanceof Mesh) {
const mesh = node.entity as Mesh;
console.log(`${indent}MESH "${node.name}": ${mesh.controlPoints.length} vertices`);
} else if (node.entity) {
console.log(`${indent}${node.entity.constructor.name} "${node.name}"`);
} else {
console.log(`${indent}GROUP "${node.name}"`);
}
for (const child of node.childNodes) {
visitWithTypeCheck(child, depth + 1);
}
}
visitWithTypeCheck(scene.rootNode);instanceof Mesh أمنية الطريقة لتأكيد الكيان هو مادة البوليغون قبل الوصول إلى controlPoints, polygonCount,أو العناصر الورقية.
الخطوة 5: تصفية النقاط حسب نوع الكيان
لجمع فقط العقدة التي تحمل الشريط دون طباعة الشجرة الكاملة ، استخدم بطارية متكررة:
import { Mesh } from '@aspose/3d/entities';
function collectMeshes(
node: any,
results: Array<{ name: string; mesh: Mesh }> = []
): Array<{ name: string; mesh: Mesh }> {
if (node.entity instanceof Mesh) {
results.push({ name: node.name, mesh: node.entity as Mesh });
}
for (const child of node.childNodes) {
collectMeshes(child, results);
}
return results;
}
const meshNodes = collectMeshes(scene.rootNode);
console.log(`Found ${meshNodes.length} mesh node(s)`);الوظيفة تقبل إمكانية الاختيار results ترتيب بحيث يمكن للمتصلين مسبقا أن يسبق له لدمج النتائج عبر العديد من الأشجار الفرعية.
الخطوة 6: جمع جميع الأقواس وطباعة أرقام Vertex
توسيع المجموعات للطباعة إحصائيات per-mesh:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { Mesh } from '@aspose/3d/entities';
function collectMeshes(node: any, results: Array<{name: string, mesh: Mesh}> = []) {
if (node.entity instanceof Mesh) {
results.push({ name: node.name, mesh: node.entity as Mesh });
}
for (const child of node.childNodes) {
collectMeshes(child, results);
}
return results;
}
const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());
const meshes = collectMeshes(scene.rootNode);
for (const { name, mesh } of meshes) {
console.log(`${name}: ${mesh.controlPoints.length} vertices, ${mesh.polygonCount} polygons`);
}نموذج النتيجة لمشهد اثنين من المائة:
Cube: 8 vertices, 6 polygons
Sphere: 482 vertices, 480 polygons<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”
<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>
نصائح وأفضل الممارسات
- دائما صفر التحقق
node.entityقبل الوصول إلى الخصائص المحددة للكيان.العديد من العقدة هي عقدات مجموعة نقية لا تحمل أي كيان. - استخدام
instanceofعلىconstructor.name- التحقق من النوع في مسارات المنطق.instanceofهو عودة-أمنة؛ مقارنة الحبل علىconstructor.nameانقطاع مع التخفيضات. - عبر
for...ofعلىchildNodes: يتعامل مع جميع أحجام المجموعة بأمان.تجنب التصنيف الرقمي للتوافق إلى الأمام. - تجنب تحويل الشجرة أثناء التجول:لا تضاف أو تخرج العقد داخل المكالمة التكرارية.جمع النتائج أولا ثم تعديلها.
- إرسال النتائج إلى صفوف المعلمات: هذا يمنع تخصيص سلسلة جديدة على كل مكالمة إعادة التدوير ويسهل دمج النتائج تحت الشجرة.
القضايا المشتركة
| الأعراض | سبب | تصحيح |
|---|---|---|
childNodes يبلغ طولها صفرًا rootNode | نموذج غير مدفوع | ضمان scene.open() إكمال دون خطأ قبل عبور |
node.entity instanceof Mesh لا حقا أبدا | الخطأ Mesh طريق الاستيراد | استيراد Mesh من @aspose/3d/entities,وليس من @aspose/3d الجذور |
| رحلات غائبة عن الملاحة | لا تُدخل في جميع الأطفال | تأكد من أن المكالمة المتكررة تغطي كل عنصر في node.childNodes |
mesh.controlPoints.length 0 هو 0 | ميتش محملة ولكن لا تحتوي على الهندسة الجيولوجية | تحقق من مصدر OBJ للمجموعات الفارغة؛ استخدام mesh.polygonCount كفتحة ثانوية |
| تداول الخيارات الثنائية على العمق الهرمات | شجرة عميقة جدا (مئات المستويات) | استبدال الردع باستخدام قوس صريح Array.push / Array.pop |
الأسئلة المتكررة
يُفعل scene.rootNode هل يحمل نفسه كيانًا؟? لا. العقد الجذر هو حاوية تم إنشاؤها تلقائيًا من قبل المكتبة.لا يوجد لديه كيان.الجيومتر الخاص بك وغيرها من الكائنات المسرحية التي تعيش على عقد الطفل واحد أو أكثر المستويات أدناه rootNode.
ما الفرق بين node.entity و node.entities? node.entity يحتفظ بالكيان الرئيسي الوحيد (الحالة المشتركة).بعض ملفات FBX و COLLADA القديمة قد تنتج عقدة مع العديد من الكيانات المرتبطة؛ في هذه الحالة node.entities (المتعدد) يقدم القائمة الكاملة.
هل يمكنني أن أمر في ترتيب البعد الأول بدلاً من العمق الأول؟? نعم.استخدم قوس بدلاً من مكالمة تجديدية: اضغط على scene.rootNode في صف واحد، ثم تحويل وعمل العقدة أثناء الضغط على كل عقدة من childNodes في كوخ الورق.
هو scene.open() متزامن ؟? نعم . scene.open() و scene.openFromBuffer() كلاهما يمنع شريط الاتصال حتى يتم تثبيت الملف بالكامل.دخلها في شريطة العمال إذا كنت بحاجة إلى الحفاظ على دورة الأحداث استجابة.
كيف يمكنني الحصول على مواقف الفضاء العالمية من عقدة؟? قراءة node.globalTransform;- يعود إلى قراءة واحدة فقط GlobalTransform مع المصفوفة العالمية الفضاء، وتتألف من جميع التحولات الأجداد.للمصففات المطبوعة، اتصل node.evaluateGlobalTransform(false).
ما هي أنواع الكيانات الممكنة بالإضافة إلى Mesh? Camera, Light, و كيانات العظام / الجمجمة المخصصة.تحقق node.entity.constructor.name أو استخدام instanceof مع الفئة المحددة المستوردة من @aspose/3d.