Wie man ein 3D‑Mesh programmgesteuert in TypeScript erstellt

Wie man ein 3D‑Mesh programmgesteuert in TypeScript erstellt

Aspose.3D FOSS für TypeScript ermöglicht es Ihnen, 3D-Geometrie vollständig im Code zu erstellen, ohne eine Datei zu laden. Sie definieren Scheitelpunktpositionen als Kontrollpunkte, geben Polygonflächen über Indizes an und fügen optionale Scheitel-Elemente wie Normalen, UVs oder Scheitel-Farben hinzu. Das Ergebnis kann in jedes beschreibbare Format gespeichert werden: glTF, GLB, STL, FBX oder COLLADA.

Voraussetzungen

  • Node.js 18 oder neuer
  • TypeScript 5.0 oder neuer
  • @aspose/3d installiert (siehe Schritt 1)

Schritt-für-Schritt-Anleitung

Schritt 1: Installieren @aspose/3d

npm install @aspose/3d

Keine nativen Add‑ons oder Systembibliotheken sind erforderlich. Das Paket enthält TypeScript‑Typdefinitionen.

Minimum tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true
  }
}

Schritt 2: Erstelle eine Szene und einen Knoten

Ein Scene ist der oberste Container. Alle Geometrie muss an einem Node innerhalb des Szenenbaums angehängt werden:

import { Scene } from '@aspose/3d';

const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');

createChildNode(name) erstellt einen benannten Knoten und verbindet ihn als Kind des aktuellen Knotens. Das zurückgegebene Node‑Objekt ist der Ort, an dem Sie das Mesh in Schritt 7 anhängen.


Schritt 3: Mesh-Objekt erstellen

Mesh enthält Scheitelpunktpositionen und Polygon‑Definitionen. Erstelle ein solches mit einem optionalen Namen:

import { Mesh } from '@aspose/3d/entities';

const mesh = new Mesh('triangle');

Das Mesh beginnt leer: keine Scheitelpunkte und keine Flächen. Sie fügen sie in den nächsten Schritten hinzu.


Schritt 4: Kontrollpunkte hinzufügen (Scheitelpunkte)

Kontrollpunkte sind die Scheitelpunktpositionen im lokalen Raum. Schieben Sie Vector4 Werte in mesh.controlPoints. Die vierte Komponente (w) ist 1 für Positionen:

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

Sie referenzieren diese Positionen über deren nullbasierten Index, wenn Sie Polygonflächen definieren.


Schritt 5: Polygonflächen erstellen

createPolygon() definiert ein Face, indem die Scheitelpunktindizes in Reihenfolge aufgelistet werden. Drei Indizes ergeben ein Dreieck:

mesh.createPolygon(0, 1, 2);

Sie können auch Quads (vier Indizes) oder beliebige Polygone für Formate definieren, die sie unterstützen. Für glTF trianguliert die Bibliothek beim Export automatisch Quads und N‑Gons.


Schritt 6: Vertex‑Normalen hinzufügen

Normalen verbessern die Rendering‑Qualität. Verwenden Sie mesh.createElement(), um ein VertexElementNormal zu erstellen, sammeln Sie Normalenvektoren in einem Array und rufen Sie dann setData() auf, um sie zu speichern. Der data‑Getter gibt eine defensive Kopie zurück – das Hinzufügen zu ihr hat keine Wirkung. Verwenden Sie FVector3 (Single‑Precision‑Float) für Normaldaten, nicht 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 bedeutet ein Normal pro Scheitelpunkt. ReferenceMode.DIRECT bedeutet, dass das Datenarray direkt über den Polygon‑Scheitelpunkt‑Index indiziert wird.


Schritt 7: Mesh anhängen und als glTF speichern

Weisen Sie das Mesh dem Knoten über node.entity zu, dann speichern Sie die Szene:

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');

Um stattdessen eine einzelne eigenständige .glb‑Datei zu erzeugen, setzen Sie saveOpts.binaryMode = true und ändern Sie die Ausgabedateierweiterung zu .glb.

Vollständiges Beispiel

Das Folgende ist das vollständige Skript, das alle oben genannten Schritte kombiniert:

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');

Ausführen mit ts-node:

npx ts-node triangle.ts

Häufige Probleme

IssueCauseFix
mesh.controlPoints.length ist nach dem Push 0Mesh wird von keinem Knoten referenziertPush vor der Zuweisung von node.entity; die Reihenfolge ist egal, aber die Referenz überprüfen
Export erzeugt leere Geometrienode.entity nicht zugewiesenStellen Sie sicher, dass node.entity = mesh vor dem Aufruf von scene.save() vorhanden ist
Normalenanzahl stimmt nicht übereinArray, das an setData() übergeben wird, ist kürzer als controlPointsFügen Sie pro Kontrollpunkt einen FVector3‑Eintrag hinzu, wenn Sie MappingMode.CONTROL_POINT verwenden
glTF‑Viewer zeigt schwarzes MeshNormalen zeigen nach innenKehr die Windungsreihenfolge in createPolygon um (z. B. 0, 2, 1) oder negiere die Normalenvektoren
TypeScript: Eigenschaft ’normals.data’ nicht gefundenFalscher ImportpfadImportieren Sie VertexElementNormal aus @aspose/3d/entities, nicht aus dem Wurzelverzeichnis @aspose/3d

Häufig gestellte Fragen

Kann ich Quads anstelle von Dreiecken erstellen? Ja. Übergeben Sie vier Indizes an createPolygon(0, 1, 2, 3). Die Bibliothek trianguliert Quads beim Export in Formate, die Dreiecke erfordern (glTF, STL).

Was ist der Unterschied zwischen MappingMode.CONTROL_POINT und MappingMode.POLYGON_VERTEX?
CONTROL_POINT speichert einen Wert pro eindeutigen Scheitelpunkt. POLYGON_VERTEX speichert einen Wert pro Polygon‑Scheitelpunkt‑Paar, was unterschiedliche Normalen am selben Scheitelpunkt ermöglicht, wenn er zu mehreren Polygonen gehört (harte Kanten).

Muss ich das Mesh vor dem Speichern als STL triangulieren?
Nein. Die Bibliothek übernimmt die Triangulation automatisch beim Export in Formate, die Dreiecke erfordern. Sie können Quads und N‑Gons im Mesh definieren und direkt als STL speichern.

Wie füge ich UV-Koordinaten hinzu?
Verwenden Sie mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT), um ein VertexElementUV zu erstellen, und rufen Sie dann setData([...]) mit einem Array von FVector2‑ oder FVector3‑Werten auf — je einer pro Kontrollpunkt. Der data‑Getter gibt eine Kopie zurück; fügen Sie nicht direkt Elemente hinzu.

Kann ich mehrere Meshes in einer Szene erstellen?
Ja. Erstellen Sie mehrere Knoten unter scene.rootNode und weisen Sie jedem Knoten eine separate Mesh seiner entity‑Eigenschaft zu.

Siehe auch

 Deutsch