Kaip programiškai sukurti 3D tinklelį TypeScript
Aspose.3D FOSS for TypeScript leidžia kurti 3D geometriją visiškai kode be jokio failo įkėlimo. Jūs apibrėžiate viršūnių pozicijas kaip valdymo taškus, nurodote daugiakampių veidus pagal indeksą ir pridedate pasirenkamus viršūnių elementus, tokius kaip normalių vektoriai, UV koordinatės arba viršūnių spalvos. Rezultatas gali būti išsaugotas bet kuriame įrašomame formate: glTF, GLB, STL, FBX arba COLLADA.
Būtinosios sąlygos
- Node.js 18 arba vėlesnė
- TypeScript 5.0 arba vėlesnė
@aspose/3dįdiegta (žr. 1 žingsnį)
Žingsnis po žingsnio vadovas
Žingsnis 1: Įdiekite @aspose/3d
npm install @aspose/3dNereikia jokių natūralių papildinių ar sistemos bibliotekų. Paketas apima TypeScript tipų apibrėžimus.
Minimumas tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Žingsnis 2: Sukurkite sceną ir mazgą
Scene yra aukščiausio lygio konteineris. Visa geometrija turi būti prijungta prie Node scenos medyje:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) sukuria pavadintą mazgą ir prijungia jį kaip esamo mazgo vaiką. Grąžintas Node objektas yra vieta, kurioje 7 žingsnyje prijungsite tinklą.
3 žingsnis: sukurti tinklelio objektą
Mesh saugo viršūnių pozicijas ir daugiakampių apibrėžimus. Sukurkite vieną su pasirenkamu pavadinimu:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');Tinklas pradžioje tuščias: nėra viršūnių ir nėra veidų. Jūs juos pridėsite tolesniuose žingsniuose.
Žingsnis 4: Pridėti kontrolinius taškus (viršūnes)
Kontroliniai taškai yra viršūnių pozicijos vietinėje erdvėje. Įdėkite Vector4 reikšmes į mesh.controlPoints. Ketvirta komponentė (w) yra 1 pozicijoms:
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
Jūs šias pozicijas nurodote pagal jų nulio pagrindo indeksą, kai apibrėžiate daugiakampio veidus.
Žingsnis 5: Sukurti daugiakampio paviršius
createPolygon() apibrėžia veidą išvardindama viršūnių indeksus tvarka. Trys indeksai sudaro trikampį:
mesh.createPolygon(0, 1, 2);Taip pat galite apibrėžti kvadratus (keturis indeksus) arba bet kokius daugiakampius formatams, kurie juos palaiko. glTF atveju biblioteka automatiškai sueksportuodama suskaidys kvadratus ir n‑kampus į trikampius.
Žingsnis 6: Pridėti viršūnių normalės
Normalės pagerina atvaizdavimo kokybę. Naudokite mesh.createElement(), kad sukurtumėte VertexElementNormal, surinktumėte normalės vektorius į masyvą, tada iškvieskite setData(), kad juos išsaugotumėte. data gaunamasis metodas grąžina apsauginę kopiją — į ją įdėti (push) neturi jokio poveikio. Naudokite FVector3 (viengubo tikslumo slankiojo kablelio) normalės duomenims, o 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 reiškia vieną normalią per viršūnę. ReferenceMode.DIRECT reiškia, kad duomenų masyvas indeksuojamas tiesiogiai pagal daugiakampio viršūnės indeksą.
Žingsnis 7: Prisegti tinklelį ir išsaugoti į glTF
Priskirkite tinklelį mazgui per node.entity, tada išsaugokite sceną:
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');Norėdami vietoj to sukurti vieną savarankišką .glb failą, nustatykite saveOpts.binaryMode = true ir pakeiskite išvesties failo plėtinį į .glb.
Pilnas pavyzdys
Toliau pateikiamas visas scenarijus, apjungiantis visus aukščiau nurodytus žingsnius:
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');Paleisti su ts-node:
npx ts-node triangle.tsDažnos problemos
| Problema | Priežastis | Sprendimas |
|---|---|---|
mesh.controlPoints.length yra 0 po push | Tinklas nėra susietas su jokių mazgu | Push prieš priskiriant node.entity; tvarka nesvarbi, bet patikrinkite nuorodą |
| Eksportas sukuria tuščią geometriją | node.entity nepriskirta | Užtikrinkite node.entity = mesh prieš iškviečiant scene.save() |
| Normalų skaičiaus neatitikimas | Masyvas, perduotas setData(), trumpesnis nei controlPoints | Pridėkite po vieną FVector3 įrašą kiekvienam valdymo taškui naudojant MappingMode.CONTROL_POINT |
| glTF peržiūros programa rodo juodą tinklą | Normalės rodo į vidų | Apverskite vėjimo tvarką createPolygon (pvz., 0, 2, 1) arba neigti normalų vektorius |
| TypeScript: savybės ’normals.data’ nerasta | Neteisingas importo kelias | Importuokite VertexElementNormal iš @aspose/3d/entities, o ne iš @aspose/3d šaknies |
Dažnai užduodami klausimai
Ar galiu kurti kvadratus vietoje trikampių?
Taip. Perduokite keturis indeksus createPolygon(0, 1, 2, 3). Biblioteka kvadratus trianguliuoja eksportuojant į formatus, kuriems reikalingi trikampiai (glTF, STL).
Kuo skiriasi MappingMode.CONTROL_POINT ir MappingMode.POLYGON_VERTEX?CONTROL_POINT saugo vieną reikšmę kiekvienam unikaliam viršūnei. POLYGON_VERTEX saugo vieną reikšmę kiekvienam daugiakampio‑viršūnės porai, leidžiant skirtingus normalus toje pačioje viršūnėje, kai ji priklauso keliems daugiakampiams (kieti kraštai).
Ar reikia trikampuoti tinklelį prieš išsaugant į STL?
Ne. Biblioteka automatiškai tvarko trikampavimą eksportuojant į formatus, kuriems reikalingi trikampiai. Galite tinklelyje apibrėžti keturkampius ir n‑kampius ir tiesiogiai išsaugoti į STL.
Kaip pridėti UV koordinates?
Naudokite mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT), kad sukurtumėte VertexElementUV, tada iškvieskite setData([...]) su FVector2 arba FVector3 reikšmių masyvu — po vieną kiekvienam valdymo taškui. data gaunamasis metodas grąžina kopiją; neįdėkite į ją tiesiogiai.
Ar galiu sukurti kelis meshes vienoje scenoje?
Taip. Sukurkite kelis mazgus po scene.rootNode ir priskirkite atskirą Mesh kiekvieno mazgo entity savybei.