Hoe een 3D-mesh programmatisch te bouwen in TypeScript
Aspose.3D FOSS for TypeScript stelt je in staat om 3D‑geometrie volledig in code te bouwen zonder een bestand te laden. Je definieert vertexposities als controlepunten, specificeert polygonvlakken door index en voeg je optionele vertexelementen toe, zoals normalen, UV’s of vertexkleuren. Het resultaat kan worden opgeslagen in elk schrijfbaar formaat: glTF, GLB, STL, FBX of COLLADA.
Vereisten
- Node.js 18 of hoger
- TypeScript 5.0 of hoger
@aspose/3dgeïnstalleerd (zie Stap 1)
Stapsgewijze gids
Stap 1: Installeer @aspose/3d
npm install @aspose/3dGeen native add‑ons of systeembibliotheken zijn vereist. Het pakket bevat TypeScript‑typedefinities.
Minimum tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Stap 2: Maak een Scene en Node
Een Scene is de bovenste container. Alle geometrie moet worden gekoppeld aan een Node binnen de sceneboom:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) maakt een benoemde node aan en koppelt deze als kind van de huidige node. Het geretourneerde Node‑object is waar je het mesh in Stap 7 aanhecht.
Stap 3: Maak een Mesh Object
Mesh bevat vertexposities en polygoondefinities. Construeer er één met een optionele naam:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');De mesh start leeg: geen vertices en geen faces. Je voegt ze toe in de volgende stappen.
Stap 4: Controlepunten toevoegen (Vertices)
Controlepunten zijn de vertexposities in lokale ruimte. Duw Vector4-waarden in mesh.controlPoints. Het vierde component (w) is 1 voor posities:
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
U verwijst naar deze posities met hun nulgebaseerde index bij het definiëren van polygonvlakken.
Stap 5: Polygonvlakken maken
createPolygon() definieert een vlak door de vertex-indexen in volgorde te vermelden. Drie indexen vormen een driehoek:
mesh.createPolygon(0, 1, 2);U kunt ook quads (vier indexen) of willekeurige polygonen definiëren voor formaten die deze ondersteunen. Voor glTF zal de bibliotheek bij export automatisch quads en n-gons trianguleren.
Stap 6: Vertexnormals toevoegen
Normaalvectoren verbeteren de renderkwaliteit. Gebruik mesh.createElement() om een VertexElementNormal te maken, verzamel normaalvectoren in een array en roep vervolgens setData() aan om ze op te slaan. De data getter retourneert een defensieve kopie — er iets aan toevoegen heeft geen effect. Gebruik FVector3 (single-precision float) voor normaaldata, niet 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 betekent één normaal per vertex. ReferenceMode.DIRECT betekent dat de gegevensarray direct wordt geïndexeerd door de polygon-vertex-index.
Stap 7: Mesh koppelen en opslaan als glTF
Wijs het mesh toe aan de node via node.entity, sla vervolgens de scène op:
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');Om in plaats daarvan een enkel zelfvoorzienend .glb-bestand te produceren, stel saveOpts.binaryMode = true in en wijzig de extensie van het uitvoerbestand naar .glb.
Volledig voorbeeld
Het volgende is het volledige script dat alle bovenstaande stappen combineert:
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');Uitvoeren met ts-node:
npx ts-node triangle.tsVeelvoorkomende problemen
| Issue | Cause | Fix |
|---|---|---|
mesh.controlPoints.length is 0 na push | Mesh niet door een node gerefereerd | Push vóór het toewijzen van node.entity; volgorde maakt niet uit, maar controleer de referentie |
| Export genereert lege geometrie | node.entity niet toegewezen | Zorg ervoor dat node.entity = mesh vóór het aanroepen van scene.save() |
| Aantal normalen komt niet overeen | Array die aan setData() wordt doorgegeven is korter dan controlPoints | Voeg één FVector3-item toe per controlepunt bij gebruik van MappingMode.CONTROL_POINT |
| glTF-viewer toont zwart mesh | Normalen wijzen naar binnen | Keer windingvolgorde om in createPolygon (bijv. 0, 2, 1) of negeer de normaalvectoren |
| TypeScript: eigenschap ’normals.data’ niet gevonden | Verkeerd importpad | Importeer VertexElementNormal vanuit @aspose/3d/entities, niet vanuit de @aspose/3d-root |
Veelgestelde vragen
Kan ik quads maken in plaats van driehoeken?
Ja. Geef vier indexen door aan createPolygon(0, 1, 2, 3). De bibliotheek trianguleert quads tijdens het exporteren naar formaten die driehoeken vereisen (glTF, STL).
Wat is het verschil tussen MappingMode.CONTROL_POINT en MappingMode.POLYGON_VERTEX?CONTROL_POINT slaat één waarde per unieke vertex op. POLYGON_VERTEX slaat één waarde per polygon-vertex-paar op, waardoor verschillende normals op dezelfde vertex mogelijk zijn wanneer deze tot meerdere polygonen behoort (hard edges).
Moet ik het mesh trianguleren voordat ik het opsla naar STL?
Nee. De bibliotheek handelt triangulatie automatisch af bij het exporteren naar formaten die driehoeken vereisen. Je kunt quads en n-gons definiëren in het mesh en direct naar STL opslaan.
Hoe voeg ik UV-coördinaten toe?
Gebruik mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) om een VertexElementUV te maken, roep vervolgens setData([...]) aan met een array van FVector2 of FVector3 waarden — één per controlepunt. De data getter geeft een kopie terug; duw er niet direct op.
Kan ik meerdere meshes in één scène bouwen?
Ja. Maak meerdere knooppunten onder scene.rootNode en wijs een aparte Mesh toe aan de entity‑eigenschap van elk knooppunt.