Πώς να δημιουργήσετε ένα 3D Mesh προγραμματιστικά σε TypeScript
Aspose.3D FOSS for TypeScript σας επιτρέπει να δημιουργήσετε 3D γεωμετρία εντελώς σε κώδικα χωρίς να φορτώνετε κανένα αρχείο. Ορίζετε τις θέσεις των κορυφών ως σημεία ελέγχου, καθορίζετε τα πολύγωνα με δείκτη και συνδέετε προαιρετικά στοιχεία κορυφής όπως normals, UVs ή χρώματα κορυφής. Το αποτέλεσμα μπορεί να αποθηκευτεί σε οποιαδήποτε εγγράψιμη μορφή: glTF, GLB, STL, FBX ή COLLADA.
Προαπαιτούμενα
- Node.js 18 ή νεότερο
- TypeScript 5.0 ή νεότερο
@aspose/3dεγκατεστημένο (δείτε το Βήμα 1)
Οδηγός βήμα-βήμα
Βήμα 1: Εγκατάσταση @aspose/3d
npm install @aspose/3dΔεν απαιτούνται εγγενείς πρόσθετα ή βιβλιοθήκες συστήματος. Το πακέτο περιλαμβάνει ορισμούς τύπων TypeScript.
Ελάχιστο tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Βήμα 2: Δημιουργία Σκηνής και Κόμβου
Ένα Scene είναι το κοντέινερ υψηλότερου επιπέδου. Όλη η γεωμετρία πρέπει να προσαρμοστεί σε ένα Node μέσα στο δέντρο σκηνής:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) δημιουργεί έναν ονομασμένο κόμβο και τον συνδέει ως παιδί του τρέχοντος κόμβου. Το επιστρεφόμενο αντικείμενο Node είναι το σημείο όπου θα συνδέσετε το πλέγμα στο Βήμα 7.
Βήμα 3: Δημιουργία αντικειμένου Mesh
Mesh περιέχει θέσεις κορυφών και ορισμούς πολυγώνων. Δημιουργήστε ένα με προαιρετικό όνομα:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');Το πλέγμα ξεκινά κενό: χωρίς κορυφές και χωρίς πρόσωπα. Τα προσθέτετε στα επόμενα βήματα.
Βήμα 4: Προσθήκη σημείων ελέγχου (Κορυφές)
Τα σημεία ελέγχου είναι οι θέσεις των κορυφών σε τοπικό χώρο. Σπρώξτε τις τιμές Vector4 στο mesh.controlPoints. Το τέταρτο συστατικό (w) είναι 1 για τις θέσεις:
import { Vector4 } from '@aspose/3d/utilities';
mesh.controlPoints.push(new Vector4(0.0, 0.0, 0.0, 1.0)); // index 0
mesh.controlPoints.push(new Vector4(1.0, 0.0, 0.0, 1.0)); // index 1
mesh.controlPoints.push(new Vector4(0.5, 1.0, 0.0, 1.0)); // index 2
Αναφέρεστε σε αυτές τις θέσεις με τον μηδενικό δείκτη τους όταν ορίζετε τις όψεις του πολύγωνου.
Βήμα 5: Δημιουργία Πολυγωνικών Πλευρών
createPolygon() ορίζει μια όψη καταγράφοντας τις δείκτες κορυφών με τη σειρά. Τρεις δείκτες σχηματίζουν ένα τρίγωνο:
mesh.createPolygon(0, 1, 2);Μπορείτε επίσης να ορίσετε τετράπλευρα (τέσσερις δείκτες) ή αυθαίρετα πολύγωνα για μορφές που τα υποστηρίζουν. Για το glTF, η βιβλιοθήκη θα τριγωνοποιήσει αυτόματα τα τετράπλευρα και τα n‑γωνά κατά την εξαγωγή.
Βήμα 6: Προσθήκη Κανονικών Κορυφών
Τα κανονικά βελτιώνουν την ποιότητα απόδοσης. Χρησιμοποιήστε mesh.createElement() για να δημιουργήσετε ένα VertexElementNormal, συλλέξτε τα διανύσματα κανονικών σε έναν πίνακα, στη συνέχεια καλέστε setData() για να τα αποθηκεύσετε. Η μέθοδος λήψης data επιστρέφει ένα αμυντικό αντίγραφο — η προσθήκη σε αυτό δεν έχει καμία επίδραση. Χρησιμοποιήστε FVector3 (μονής ακρίβειας float) για δεδομένα κανονικών, όχι Vector4.
import { VertexElementNormal } from '@aspose/3d/entities';
import { VertexElementType, MappingMode, ReferenceMode } from '@aspose/3d/entities';
import { FVector3 } from '@aspose/3d/utilities';
const normals = mesh.createElement(
VertexElementType.NORMAL,
MappingMode.CONTROL_POINT,
ReferenceMode.DIRECT
) as VertexElementNormal;
// Build the normal array, then call setData() — do NOT push to normals.data
normals.setData([
new FVector3(0, 0, 1), // normal for vertex 0 (pointing +Z)
new FVector3(0, 0, 1), // normal for vertex 1
new FVector3(0, 0, 1), // normal for vertex 2
]);MappingMode.CONTROL_POINT σημαίνει ένα κανονικό ανά κορυφή. ReferenceMode.DIRECT σημαίνει ότι ο πίνακας δεδομένων ευρετηριάζεται άμεσα από το δείκτη κορυφής του πολυγώνου.
Βήμα 7: Συνδέστε το πλέγμα και αποθηκεύστε σε glTF
Αναθέστε το πλέγμα στον κόμβο μέσω node.entity, στη συνέχεια αποθηκεύστε τη σκηνή:
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
node.entity = mesh;
const saveOpts = new GltfSaveOptions();
scene.save('triangle.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Triangle mesh saved to triangle.gltf');Για να δημιουργήσετε ένα ενιαίο αυτόνομο αρχείο .glb αντί αυτού, ορίστε saveOpts.binaryMode = true και αλλάξτε την επέκταση του αρχείου εξόδου σε .glb.
Πλήρες Παράδειγμα
Το παρακάτω είναι το πλήρες σενάριο που συνδυάζει όλα τα παραπάνω βήματα:
import { Scene } from '@aspose/3d';
import { Mesh, VertexElementNormal } from '@aspose/3d/entities';
import { VertexElementType, MappingMode, ReferenceMode } from '@aspose/3d/entities';
import { Vector4, FVector3 } from '@aspose/3d/utilities';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');
const mesh = new Mesh('triangle');
mesh.controlPoints.push(new Vector4(0.0, 0.0, 0.0, 1.0));
mesh.controlPoints.push(new Vector4(1.0, 0.0, 0.0, 1.0));
mesh.controlPoints.push(new Vector4(0.5, 1.0, 0.0, 1.0));
mesh.createPolygon(0, 1, 2);
const normals = mesh.createElement(
VertexElementType.NORMAL,
MappingMode.CONTROL_POINT,
ReferenceMode.DIRECT
) as VertexElementNormal;
// setData() is the correct API — normals.data returns a defensive copy; pushing to it has no effect
normals.setData([
new FVector3(0, 0, 1),
new FVector3(0, 0, 1),
new FVector3(0, 0, 1),
]);
node.entity = mesh;
const saveOpts = new GltfSaveOptions();
scene.save('triangle.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Triangle mesh saved to triangle.gltf');Εκτέλεση με ts-node:
npx ts-node triangle.tsΚοινά προβλήματα
| Issue | Cause | Fix |
|---|---|---|
mesh.controlPoints.length είναι 0 μετά την ώθηση | Το πλέγμα δεν αναφέρεται από κανέναν κόμβο | Κάντε ώθηση πριν την ανάθεση του node.entity· η σειρά δεν έχει σημασία, αλλά επαληθεύστε την αναφορά |
| Η εξαγωγή παράγει κενή γεωμετρία | node.entity δεν έχει εκχωρηθεί | Βεβαιωθείτε ότι node.entity = mesh πριν καλέσετε το scene.save() |
| Ασυμφωνία αριθμού κανονικών | Ο πίνακας που περνιέται στο setData() είναι μικρότερος από το controlPoints | Προσθέστε μία καταχώρηση FVector3 ανά σημείο ελέγχου όταν χρησιμοποιείτε το MappingMode.CONTROL_POINT |
| Ο προβολέας glTF εμφανίζει μαύρο πλέγμα | Οι κανονικές κατευθύνσεις δείχνουν προς το εσωτερικό | Αντιστρέψτε τη σειρά περιδίασης στο createPolygon (π.χ., 0, 2, 1) ή αναιρέστε τα διανύσματα κανονικών |
| TypeScript: η ιδιότητα ’normals.data’ δεν βρέθηκε | Λάθος διαδρομή εισαγωγής | Εισάγετε το VertexElementNormal από το @aspose/3d/entities, όχι από τη ρίζα @aspose/3d |
Συχνές Ερωτήσεις
Μπορώ να δημιουργήσω τετράπλευρα αντί για τρίγωνα;
Ναι. Περνάτε τέσσερις δείκτες στο createPolygon(0, 1, 2, 3). Η βιβλιοθήκη τριγωνοποιεί τα τετράπλευρα κατά την εξαγωγή σε μορφές που απαιτούν τρίγωνα (glTF, STL).
Ποια είναι η διαφορά μεταξύ MappingMode.CONTROL_POINT και MappingMode.POLYGON_VERTEX;CONTROL_POINT αποθηκεύει μία τιμή ανά μοναδική κορυφή. POLYGON_VERTEX αποθηκεύει μία τιμή ανά ζεύγος πολύγωνο‑κορυφή, το οποίο επιτρέπει διαφορετικούς κανονικούς στην ίδια κορυφή όταν ανήκει σε πολλαπλά πολύγωνα (σκληρές άκρες).
Πρέπει να τριγωνοποιήσω το πλέγμα πριν το αποθηκεύσω σε STL;
Όχι. Η βιβλιοθήκη διαχειρίζεται την τριγωνοποίηση αυτόματα κατά την εξαγωγή σε μορφές που απαιτούν τρίγωνα. Μπορείτε να ορίσετε τετράπλευρα και n‑γωνικά στο πλέγμα και να αποθηκεύσετε απευθείας σε STL.
Πώς να προσθέσω συντεταγμένες UV;
Χρησιμοποιήστε mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) για να δημιουργήσετε ένα VertexElementUV, στη συνέχεια καλέστε setData([...]) με έναν πίνακα τιμών FVector2 ή FVector3 — μία ανά σημείο ελέγχου. Ο getter data επιστρέφει ένα αντίγραφο· μην το τροποποιείτε απευθείας.
Μπορώ να δημιουργήσω πολλαπλά πλέγματα σε μία σκηνή;
Ναι. Δημιουργήστε πολλαπλούς κόμβους κάτω από scene.rootNode και εκχωρήστε ένα ξεχωριστό Mesh στην ιδιότητα entity του κάθε κόμβου.