Jak programově vytvořit 3D mesh v TypeScriptu

Jak programově vytvořit 3D mesh v TypeScriptu

Aspose.3D FOSS pro TypeScript vám umožňuje vytvářet 3D geometrii kompletně v kódu bez načítání jakéhokoli souboru. Definujete pozice vrcholů jako kontrolní body, určujete polygonální plochy pomocí indexu a připojujete volitelné prvky vrcholů, jako jsou normály, UV souřadnice nebo barvy vrcholů. Výsledek lze uložit do libovolného zapisovatelného formátu: glTF, GLB, STL, FBX nebo COLLADA.

Požadavky

  • Node.js 18 nebo novější
  • TypeScript 5.0 nebo novější
  • @aspose/3d nainstalován (viz Krok 1)

Průvodce krok za krokem

Krok 1: Nainstalujte @aspose/3d

npm install @aspose/3d

Nejsou vyžadovány žádné nativní doplňky ani systémové knihovny. Balíček obsahuje definice typů TypeScript.

Minimum tsconfig.json:

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

Krok 2: Vytvořte scénu a uzel

Scene je kontejner nejvyšší úrovně. Veškerá geometrie musí být připojena k Node uvnitř stromu scény:

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

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

createChildNode(name) vytvoří pojmenovaný uzel a připojí jej jako podřízený aktuálnímu uzlu. Vrácený objekt Node je místo, kde připojíte síť v kroku 7.


Krok 3: Vytvořte objekt Mesh

Mesh obsahuje pozice vrcholů a definice polygonů. Vytvořte jeden s volitelným názvem:

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

const mesh = new Mesh('triangle');

Síť začíná prázdná: žádné vrcholy a žádné plochy. Přidáte je v následujících krocích.


Krok 4: Přidat řídicí body (vrcholy)

Ovládací body jsou pozice vrcholů v lokálním prostoru. Vložte hodnoty Vector4 do mesh.controlPoints. Čtvrtá složka (w) je 1 pro pozice:

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

Tyto pozice odkazujete pomocí jejich nulového indexu při definování polygonových ploch.


Krok 5: Vytvořit polygonové plochy

createPolygon() definuje plochu výčtem indexů vrcholů v pořadí. Tři indexy tvoří trojúhelník:

mesh.createPolygon(0, 1, 2);

Můžete také definovat čtyřúhelníky (čtyři indexy) nebo libovolné polygonové tvary pro formáty, které je podporují. Pro glTF knihovna automaticky trianguluje čtyřúhelníky a n‑úhelníky při exportu.


Krok 6: Přidat normály vrcholů

Normály zlepšují kvalitu renderování. Použijte mesh.createElement() k vytvoření VertexElementNormal, shromážděte vektory normál do pole a poté zavolejte setData() k jejich uložení. Getter data vrací obrannou kopii — přidávání do ní nemá žádný efekt. Používejte FVector3 (jednopřesnostní float) pro data normál, 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 znamená jeden normál na vrchol. ReferenceMode.DIRECT znamená, že datové pole je indexováno přímo indexem vrcholu polygonu.


Krok 7: Připojte mesh a uložte do glTF

Přiřaďte síť k uzlu pomocí node.entity, pak uložte scénu:

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

Chcete-li místo toho vytvořit jeden samostatný soubor .glb, nastavte saveOpts.binaryMode = true a změňte příponu výstupního souboru na .glb.

Kompletní příklad

Následuje kompletní skript kombinující všechny výše uvedené kroky:

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

Spusťte s ts-node:

npx ts-node triangle.ts

Běžné problémy

IssueCauseFix
mesh.controlPoints.length je 0 po pushSíť není odkazována žádným uzlemPush před přiřazením node.entity; pořadí není podstatné, ale ověřte odkaz
Export vytváří prázdnou geometriinode.entity není přiřazenoZajistěte node.entity = mesh před voláním scene.save()
Neshoda počtu normálPole předané do setData() je kratší než controlPointsPřidejte jeden záznam FVector3 na řídicí bod při použití MappingMode.CONTROL_POINT
glTF prohlížeč zobrazuje černou síťNormály směřují dovnitřObraťte pořadí winding v createPolygon (např. 0, 2, 1) nebo invertujte vektory normál
TypeScript: vlastnost ’normals.data’ nebyla nalezenaŠpatná cesta importuImportujte VertexElementNormal z @aspose/3d/entities, ne z kořene @aspose/3d

Často kladené otázky

Mohu vytvářet čtyřúhelníky místo trojúhelníků? Ano. Předávejte čtyři indexy do createPolygon(0, 1, 2, 3). Knihovna převádí čtyřúhelníky na trojúhelníky během exportu do formátů, které vyžadují trojúhelníky (glTF, STL).

Jaký je rozdíl mezi MappingMode.CONTROL_POINT a MappingMode.POLYGON_VERTEX?
CONTROL_POINT ukládá jednu hodnotu na jedinečný vrchol. POLYGON_VERTEX ukládá jednu hodnotu na pár polygon‑vrchol, což umožňuje různé normály na stejném vrcholu, když patří do více polygonů (tvrdé hrany).

Potřebuji triangulovat síť před uložením do STL?
Ne. Knihovna automaticky provádí triangulaci při exportu do formátů, které vyžadují trojúhelníky. Můžete v síti definovat čtyřúhelníky a n‑úhelníky a uložit přímo do STL.

Jak přidat UV souřadnice?
Použijte mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) k vytvoření VertexElementUV, poté zavolejte setData([...]) s polem hodnot FVector2 nebo FVector3 — jedna na řídicí bod. Getter data vrací kopii; neprovádějte do ní přímé pushování.

Mohu vytvořit více meshů v jedné scéně? Ano. Vytvořte více uzlů pod scene.rootNode a přiřaďte samostatný Mesh k vlastnosti entity každého uzlu.

Viz také

 Čeština