Hur man bygger ett 3D‑mesh programatiskt i TypeScript

Hur man bygger ett 3D‑mesh programatiskt i TypeScript

Aspose.3D FOSS för TypeScript låter dig bygga 3D-geometri helt i kod utan att ladda någon fil. Du definierar vertexpositioner som kontrollpunkter, specificerar polygonytor med index och bifogar valfria vertexelement såsom normaler, UV:er eller vertexfärger. Resultatet kan sparas till vilket skrivbart format som helst: glTF, GLB, STL, FBX eller COLLADA.

Förutsättningar

  • Node.js 18 eller senare
  • TypeScript 5.0 eller senare
  • @aspose/3d installerad (se Steg 1)

Steg-för-steg-guide

Steg 1: Installera @aspose/3d

npm install @aspose/3d

Inga inbyggda tillägg eller systembibliotek krävs. Paketet inkluderar TypeScript-typdefinitioner.

Minimum tsconfig.json:

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

Steg 2: Skapa en Scene och Node

En Scene är den översta behållaren. All geometri måste fästas vid en Node i scenträdet:

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

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

createChildNode(name) skapar en namngiven nod och kopplar den som ett barn till den aktuella noden. Det returnerade Node‑objektet är där du kommer att fästa meshen i steg 7.


Steg 3: Skapa ett Mesh-objekt

Mesh innehåller vertexpositioner och polygondefinitioner. Skapa en med ett valfritt namn:

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

const mesh = new Mesh('triangle');

Meshen börjar tom: inga hörn och inga ytor. Du lägger till dem i nästa steg.


Steg 4: Lägg till kontrollpunkter (Vertices)

Kontrollpunkter är vertexpositionerna i lokalt utrymme. Skjut Vector4-värdena in i mesh.controlPoints. Den fjärde komponenten (w) är 1 för positioner:

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

Du refererar till dessa positioner med deras nollbaserade index när du definierar polygonytor.


Steg 5: Skapa polygonytor

createPolygon() definierar en yta genom att lista vertexindexen i ordning. Tre index bildar en triangel:

mesh.createPolygon(0, 1, 2);

Du kan också definiera fyrkanter (fyra index) eller godtyckliga polygoner för format som stödjer dem. För glTF kommer biblioteket automatiskt att triangulera fyrkanter och n‑goner vid export.


Steg 6: Lägg till vertexnormaler

Normaler förbättrar renderingskvaliteten. Använd mesh.createElement() för att skapa en VertexElementNormal, samla normalvektorer i en array och anropa sedan setData() för att lagra dem. data‑getter returnerar en defensiv kopia — att pusha till den har ingen effekt. Använd FVector3 (single-precision float) för normaldata, inte 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 betyder en normal per vertex. ReferenceMode.DIRECT betyder att dataarrayen indexeras direkt av polygonens vertex‑index.


Steg 7: Fäst Mesh och spara till glTF

Tilldela meshen till noden via node.entity, spara sedan scenen:

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

För att producera en enda självständig .glb‑fil istället, ange saveOpts.binaryMode = true och ändra filens utdata‑filändelse till .glb.

Fullständigt exempel

Följande är det fullständiga skriptet som kombinerar alla steg ovan:

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

Kör med ts-node:

npx ts-node triangle.ts

Vanliga problem

ProblemOrsakLösning
mesh.controlPoints.length är 0 efter pushMesh refereras inte av någon nodPush innan node.entity tilldelas; ordningen spelar ingen roll, men verifiera referensen
Export genererar tom geometrinode.entity är inte tilldeladSäkerställ node.entity = mesh innan du anropar scene.save()
Normalantal matchar inteArray som skickas till setData() är kortare än controlPointsLägg till en FVector3 post per kontrollpunkt när du använder MappingMode.CONTROL_POINT
glTF-visaren visar svart meshNormaler pekar inåtVänd på winding-ordningen i createPolygon (t.ex. 0, 2, 1) eller negera normalvektorer
TypeScript: egenskapen ’normals.data’ hittades inteFel importvägImportera VertexElementNormal från @aspose/3d/entities, inte från roten @aspose/3d

Vanliga frågor

Kan jag skapa fyrkanter istället för trianglar? Ja. Skicka fyra index till createPolygon(0, 1, 2, 3). Biblioteket triangulerar fyrkanter vid export till format som kräver trianglar (glTF, STL).

Vad är skillnaden mellan MappingMode.CONTROL_POINT och MappingMode.POLYGON_VERTEX?
CONTROL_POINT lagrar ett värde per unik vertex. POLYGON_VERTEX lagrar ett värde per polygon-vertex pair, vilket möjliggör olika normals vid samma vertex när den tillhör flera polygoner (hard edges).

Behöver jag triangulera meshen innan jag sparar till STL?
Nej. Biblioteket hanterar triangulering automatiskt när du exporterar till format som kräver trianglar. Du kan definiera quads och n‑gons i meshen och spara till STL direkt.

Hur lägger jag till UV-koordinater?
Använd mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) för att skapa en VertexElementUV, anropa sedan setData([...]) med en array av FVector2‑ eller FVector3‑värden — ett per kontrollpunkt. data‑hämtaren returnerar en kopia; tryck inte på den direkt.

Kan jag bygga flera meshar i en scen?
Ja. Skapa flera noder under scene.rootNode och tilldela ett separat Mesh till varje nodes entity‑egenskap.

Se även

 Svenska