Kako programatski izgraditi 3D mrežu u TypeScript‑u
Aspose.3D FOSS za TypeScript omogućava izgradnju 3D geometrije u potpunosti putem koda, bez učitavanja bilo koje datoteke. Definišete pozicije vrhova kao kontrolne tačke, specificirate poligonalna lica po indeksu i prikačite opcione elemente vrhova kao što su normale, UV‑koordinate ili boje vrhova. Rezultat se može sačuvati u bilo koji zapis koji se može pisati: glTF, GLB, STL, FBX ili COLLADA.
Preduslovi
- Node.js 18 ili noviji
- TypeScript 5.0 ili noviji
@aspose/3dinstaliran (pogledajte Korak 1)
Vodič korak po korak
Korak 1: Instalirajte @aspose/3d
npm install @aspose/3dNisu 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: Kreirajte scenu i čvor
Scene је контејнер највишег нивоа.
Сва геометрија мора бити прикључена на Node унутар стабла сцене:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) kreira imenovani čvor i povezuje ga kao dete trenutnog čvora. Vraćeni Node objekat je mesto gde ćete prikačiti mesh u korak 7.
Korak 3: Kreirajte Mesh objekat
Mesh sadrži pozicije vrhova i definicije poligona. Napravite jedan sa opcionim imenom:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');Mreža počinje prazna: nema temena i nema lica. Dodajete ih u narednim koracima.
Korak 4: Dodajte kontrolne tačke (vrhove)
Kontrolne tačke su položaji vrhova u lokalnom prostoru. Ubaci Vector4 vrednosti 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 pozicije se referišete po njihovom nultom indeksu prilikom definisanja poligonskih lica.
Korak 5: Kreiraj poligonalna lica
createPolygon() definiše površ tako što navodi indekse vrhova redom. Tri indeksa čine trougao:
mesh.createPolygon(0, 1, 2);Možete takođe definisati kvadrate (četiri indeksa) ili proizvoljne poligone za formate koji ih podržavaju. Za glTF, biblioteka će automatski triangulisati kvadrate i n‑gone prilikom izvoza.
Korak 6: Dodajte normale vrha
Normalni vektori poboljšavaju kvalitet renderovanja. Koristite mesh.createElement() da kreirate VertexElementNormal, sakupite normalne vektore u niz, zatim pozovite setData() da ih sačuvate. Getter data vraća odbrambenu kopiju — dodavanje u nju nema efekta. Koristite FVector3 (float jedne preciznosti) za normalne podatke, 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 direktno prema indeksu vrha poligona.
Korak 7: Prikači mrežu i sačuvaj u glTF
Dodelite mrežu čvoru putem node.entity, zatim sačuvajte 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');Da biste umesto toga proizveli jedinstvenu samostalnu .glb datoteku, postavite saveOpts.binaryMode = true i promenite ekstenziju izlazne datoteke u .glb.
Kompletan primer
Sledeći je kompletan skript koji kombinuje 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 sa ts-node:
npx ts-node triangle.tsУобичајени проблеми
| Issue | Cause | Fix |
|---|---|---|
mesh.controlPoints.length је 0 након push‑а | Мрежа није референцирана ни у једном чвору | Гурните пре доделе 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 |
Često postavljana pitanja
Могу ли да правим четвороуглове уместо троуглова?
Да. Проследите четири индекса у createPolygon(0, 1, 2, 3). Библиотека триангулира четвороуглове приликом извоза у формате који захтевају троуглове (glTF, STL).
Koja je razlika između MappingMode.CONTROL_POINT i MappingMode.POLYGON_VERTEX?CONTROL_POINT čuva jednu vrednost po jedinstvenom vrhu. POLYGON_VERTEX čuva jednu vrednost po paru poligon‑vrh, što omogućava različite normale na istom vrhu kada pripada više poligona (tvrde ivice).
Da li je potrebno triangulisati mrežu pre čuvanja u STL?
Ne. Biblioteka automatski obavlja triangulaciju prilikom izvoza u formate koji zahtevaju trouglove. Možete definisati kvadrate i n‑poligone u mreži i direktno sačuvati u STL.
Kako da dodam UV koordinate?
Koristite mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) da kreirate VertexElementUV, zatim pozovite setData([...]) sa nizom FVector2 ili FVector3 vrednosti — po jedan po kontrolnoj tački. data getter vraća kopiju; nemojte direktno da ubacujete u nju.
Могу ли да изградим више мрежа у једној сцени?
Да. Креирајте више чворова под scene.rootNode и доделите одвојени Mesh својству entity сваког чвора.