TypeScript में 3D दृश्य ग्राफ कैसे पार करें
Aspose.3D FOSS में दृश्य ग्राफ TypeScript के लिए एक पेड़ है Node वस्तुओं में जड़ें scene.rootNode.यात्रा पुनरावृत्ति है: प्रत्येक नोड एक को उजागर करता है childNodes अविश्वसनीय और वैकल्पिक entity यह गाइड दिखाता है कि पूरे पेड़ को कैसे चलना है, वस्तुओं के प्रकारों की पहचान करना और मस्जिद सांख्यिकी इकट्ठा करना।.
आवश्यकताएँ
- Node.js 18 या बाद में
- टाइपस्क्रिप्ट 5.0 या बाद में
@aspose/3dस्थापित
कदम-दर-चरण गाइड
चरण 1: स्थापना और आयात
पैकेज को स्थापित करें:
npm install @aspose/3dइस गाइड में उपयोग किए जाने वाले कक्षाओं का आयात करें:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { Mesh } from '@aspose/3d/entities';Scene और Mesh ये ही मुख्य वर्ग हैं।. ObjLoadOptions लोड उदाहरण में इस्तेमाल किया जाता है; अन्य प्रारूपों के लिए फिट करने के विकल्प वर्ग को प्रतिस्थापित करें।.
चरण 2: एक फ़ाइल से एक दृश्य लोड करें
बनाए A 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}`);आप एक से भी लोड कर सकते हैं। Buffer स्मृति में उपयोग scene.openFromBuffer(buffer, options);सर्वर-मुक्त पाइपलाइनों में उपयोगी जहां डिस्क I/O उपलब्ध नहीं है।.
चरण 3: एक पुनरावृत्ति यात्रा कार्य लिखें
रिकॉर्डिंग के बारे में 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,और Vertex के तत्वों का।.
चरण 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: सभी मेश और प्रिंट वर्टेक्स गिनती इकट्ठा करें
संग्रहक का विस्तार करें ताकि 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 0 लंबाई के साथ rootNode | मॉडल नहीं लोड किया गया | सुनिश्चित करें scene.open() बिना किसी गलती के पारित किए जाने से पहले |
node.entity instanceof Mesh कभी सच नहीं | गलत Mesh आयात मार्ग | आयात Mesh से @aspose/3d/entities,नहीं, से @aspose/3d रूट |
| यात्रा के लिए नकली मिट्टी खो जाती है | सभी बच्चों को नहीं छोड़ना | यह सुनिश्चित करें कि पुनरावृत्ति कॉल में प्रत्येक तत्व को कवर किया जाता है node.childNodes |
mesh.controlPoints.length 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.