Kako programatski izgraditi 3D mrežu u TypeScriptu

Kako programatski izgraditi 3D mrežu u TypeScriptu

Aspose.3D FOSS za TypeScript omogućuje izgradnju 3D geometrije u potpunosti u kodu bez učitavanja ikakve datoteke. Definirate položaje vrhova kao kontrolne točke, specificirate poligonalna lica po indeksu i dodajete opcionalne elemente vrhova poput normala, UV‑ova ili boja vrhova. Rezultat se može spremiti u bilo koji zapis koji se može pisati: glTF, GLB, STL, FBX ili COLLADA.

Preduvjeti

  • Node.js 18 ili noviji
  • TypeScript 5.0 ili noviji
  • @aspose/3d instaliran (pogledajte Korak 1)

Vodič korak po korak

Korak 1: Instalirajte @aspose/3d

npm install @aspose/3d

Nisu potrebni nativni dodaci ili sistemske biblioteke. Paket uključuje TypeScript definicije tipova.

Minimum tsconfig.json:

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

Korak 2: Kreiraj scenu i čvor

A Scene je kontejner najviše razine. Sva geometrija mora biti pričvršćena na Node unutar stabla scene:

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

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

createChildNode(name) stvara imenovani čvor i povezuje ga kao dijete trenutnog čvora. Vraćeni Node objekt je mjesto gdje ćete u koraku 7 priložiti mrežu.


Korak 3: Stvori Mesh objekt

Mesh sadrži položaje vrhova i definicije poligona. Izradite jedan s opcionalnim imenom:

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

const mesh = new Mesh('triangle');

Mreža počinje prazna: nema vrhova i nema ploha. Dodajete ih u sljedećim koracima.


Korak 4: Dodaj kontrolne točke (vrhove)

Kontrolne točke su položaji vrhova u lokalnom prostoru. Gurnite Vector4 vrijednosti u mesh.controlPoints. Četvrta komponenta (w) je 1 za položaje:

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

Na ove položaje referencirate pomoću njihovog nultog indeksa prilikom definiranja poligonalnih lica.


Korak 5: Stvaranje poligonalnih lica

createPolygon() definira lice navodeći indekse vrhova redom. Tri indeksa čine trokut:

mesh.createPolygon(0, 1, 2);

Također možete definirati kvadrate (četiri indeksa) ili proizvoljne poligone za formate koji ih podržavaju. Za glTF, biblioteka će automatski triangulirati kvadrate i n‑poligone pri izvozu.


Korak 6: Dodaj normale vrhova

Normalni vektori poboljšavaju kvalitetu renderiranja. Koristite mesh.createElement() za stvaranje VertexElementNormal, prikupite normalne vektore u polje, a zatim pozovite setData() da ih pohranite. Getter data vraća obrambenu kopiju — dodavanje u nju nema učinka. Koristite FVector3 (float jednostruke preciznosti) za normalne podatke, a ne 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 znači jedan normal po vrhu. ReferenceMode.DIRECT znači da je niz podataka indeksiran izravno prema indeksu vrha poligona.


Korak 7: Prikvači mrežu i spremi u glTF

Dodijelite mrežu čvoru putem node.entity, zatim spremite scenu:

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

Za proizvodnju jedne samostalne .glb datoteke umjesto toga, postavite saveOpts.binaryMode = true i promijenite ekstenziju izlazne datoteke u .glb.

Potpuni primjer

Sljedeći je potpuni skript koji kombinira sve prethodne korake:

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

Pokreni s ts-node:

npx ts-node triangle.ts

Uobičajeni problemi

ProblemUzrokRješenje
mesh.controlPoints.length je 0 nakon push-aMreža nije referencirana ni od jednim čvoromPush prije dodjele node.entity; redoslijed nije bitan, ali provjerite referencu
Izvoz generira praznu geometrijunode.entity nije dodijeljenOsigurajte node.entity = mesh prije poziva scene.save()
Neusklađenost broja normalaPolje proslijeđeno setData() je kraće od controlPointsDodajte jedan FVector3 unos po kontrolnoj točki pri korištenju MappingMode.CONTROL_POINT
glTF preglednik prikazuje crnu mrežuNormale usmjerene prema unutraObrnite redoslijed vrhova u createPolygon (npr., 0, 2, 1) ili negirajte vektore normala
TypeScript: svojstvo ’normals.data’ nije pronađenoPogrešna putanja uvozaUvezite VertexElementNormal iz @aspose/3d/entities, a ne iz korijena @aspose/3d

Često postavljana pitanja

Mogu li kreirati četverokute umjesto trokuta? Da. Proslijedite četiri indeksa u createPolygon(0, 1, 2, 3). Biblioteka triangulira četverokute tijekom izvoza u formate koji zahtijevaju trokute (glTF, STL).

Koja je razlika između MappingMode.CONTROL_POINT i MappingMode.POLYGON_VERTEX? CONTROL_POINT pohranjuje jednu vrijednost po jedinstvenom vrhu. POLYGON_VERTEX pohranjuje jednu vrijednost po paru poligon‑vrh, što omogućuje različite normale na istom vrhu kada pripada više poligona (tvrdi rubovi).

Treba li triangulirati mrežu prije spremanja u STL?
Ne. Biblioteka automatski obrađuje triangulaciju prilikom izvoza u formate koji zahtijevaju trokute. Možete definirati kvadrate i n‑poligone u mreži i izravno spremiti u STL.

Kako dodati UV koordinate?
Koristite mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) za stvaranje VertexElementUV, zatim pozovite setData([...]) s nizom vrijednosti FVector2 ili FVector3 — po jednoj po kontrolnoj točki. Getter data vraća kopiju; nemojte ga izravno pushati.

Mogu li izgraditi više mreža u jednoj sceni? Da. Stvorite više čvorova pod scene.rootNode i dodijelite zasebni Mesh svakom čvoru u svojstvu entity.

Vidi također

 Hrvatski