Πώς να περάσετε ένα 3D σκηνικό γραφικά σε TypeScript

Πώς να περάσετε ένα 3D σκηνικό γραφικά σε TypeScript

Το γραφικό σκηνής στο Aspose.3D FOSS για το TypeScript είναι ένα δέντρο Node αντικείμενα που ριζώνουν σε scene.rootNode.Ο ταξιδιωτικός είναι επαναλαμβανόμενος: κάθε κόμβος εκθέτει ένα childNodes Ανεκτίμητο και ελεγχόμενο entity Ο οδηγός αυτός δείχνει πώς να περπατάτε ολόκληρο το δέντρο, εντοπίζοντας τύπους οντοτήτων και συλλέγοντας στατιστικά στοιχεία για τα μασά.

Προϋποθέσεις

  • Node.js 18 ή αργότερα
  • TypeScript 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}`);

Μπορείτε επίσης να φορτώσετε από το A 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: Συλλέξτε όλες τις μάζες και εκτυπώστε τα κέρματα 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 είναιΤο Mesh φορτίζεται αλλά δεν περιέχει γεωμετρίαΕλέγξτε την πηγή OBJ για κενές ομάδες. χρησιμοποιήστε mesh.polygonCount ως δευτερογενής έλεγχος
Στενάει το πέρασμα σε βαθιές ιεραρχίεςΠολύ βαθιά σκηνή δέντρο (σε εκατοντάδες επίπεδα)Αντικαταστήστε την αναδρομή με μια ρητή σκάκι χρησιμοποιώντας Array.push / Array.pop

Συχνές ερωτήσεις

Η ΚΕ scene.rootNode Εχει μια οντότητα;? Ο κόμβος ρίζας είναι ένα δοχείο που δημιουργείται αυτόματα από τη βιβλιοθήκη. δεν έχει οντότητα. η γεωμετρία σας και άλλα αντικείμενα σκηνής ζουν σε παιδικά κόμπια ενός ή περισσότερων επιπέδων κάτω από το rootNode.

Ποια είναι η διαφορά μεταξύ node.entity και node.entities? node.entity Κάποια παλαιότερα αρχεία FBX και COLLADA μπορεί να παράγουν κόμβους με πολλαπλές συνδεδεμένες οντότητες. node.entities (Πολύ) παρέχει την πλήρη λίστα.

Μπορώ να περάσω με ευρύτατη πρώτη σειρά αντί για βάθος πρώτος;? Χρησιμοποιήστε ένα κουτί αντί για μια επανεκκλητική κλήση: push 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.

Δείτε επίσης

 Ελληνικά