Jak zbudować siatkę 3D programowo w TypeScript
Aspose.3D FOSS for TypeScript pozwala tworzyć geometrię 3D całkowicie w kodzie, bez ładowania jakiegokolwiek pliku. Definiujesz pozycje wierzchołków jako punkty kontrolne, określasz ściany wielokątów za pomocą indeksów i dołączasz opcjonalne elementy wierzchołków, takie jak normalne, UV lub kolory wierzchołków. Wynik można zapisać w dowolnym zapisywalnym formacie: glTF, GLB, STL, FBX lub COLLADA.
Wymagania wstępne
- Node.js 18 lub nowszy
- TypeScript 5.0 lub nowszy
@aspose/3dzainstalowany (zobacz Krok 1)
Przewodnik krok po kroku
Krok 1: Zainstaluj @aspose/3d
npm install @aspose/3dNie są wymagane żadne natywne dodatki ani biblioteki systemowe. Pakiet zawiera definicje typów TypeScript.
Minimum tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Krok 2: Utwórz scenę i węzeł
Scene jest kontenerem najwyższego poziomu. Cała geometria musi być dołączona do Node wewnątrz drzewa sceny:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) tworzy nazwany węzeł i podłącza go jako dziecko bieżącego węzła. Zwrócony obiekt Node to miejsce, w którym w kroku 7 podłączysz siatkę.
Krok 3: Utwórz Mesh Object
Mesh przechowuje pozycje wierzchołków i definicje wielokątów. Utwórz jeden z opcjonalną nazwą:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');Siatka zaczyna się pustą: brak wierzchołków i brak ścian. Dodajesz je w kolejnych krokach.
Krok 4: Dodaj punkty kontrolne (wierzchołki)
Punkty kontrolne to pozycje wierzchołków w przestrzeni lokalnej. Przenieś wartości Vector4 do mesh.controlPoints. Czwarty składnik (w) jest 1 dla pozycji:
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
Odwołujesz się do tych pozycji za pomocą ich indeksu zerowego przy definiowaniu ścian wielokątów.
Krok 5: Utwórz ściany wielokąta
createPolygon() definiuje twarz, wymieniając indeksy wierzchołków w kolejności. Trzy indeksy tworzą trójkąt:
mesh.createPolygon(0, 1, 2);Możesz także definiować czworokąty (cztery indeksy) lub dowolne wielokąty dla formatów, które je obsługują. Dla glTF biblioteka automatycznie trianguluje czworokąty i n‑kąty podczas eksportu.
Krok 6: Dodaj normale wierzchołków
Normalne poprawiają jakość renderowania. Użyj mesh.createElement(), aby utworzyć VertexElementNormal, zbierz wektory normalnych do tablicy, a następnie wywołaj setData(), aby je zapisać. Getter data zwraca kopię obronną — dodawanie do niej nie ma wpływu. Używaj FVector3 (liczba zmiennoprzecinkowa pojedynczej precyzji) dla danych normalnych, nie 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 oznacza jedną normalną na wierzchołek. ReferenceMode.DIRECT oznacza, że tablica danych jest indeksowana bezpośrednio przez indeks wierzchołka wielokąta.
Krok 7: Dołącz siatkę i zapisz jako glTF
Przypisz siatkę do węzła za pomocą node.entity, a następnie zapisz 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');Aby zamiast tego wygenerować pojedynczy, samodzielny plik .glb, ustaw saveOpts.binaryMode = true i zmień rozszerzenie pliku wyjściowego na .glb.
Pełny przykład
Poniżej znajduje się pełny skrypt łączący wszystkie powyższe kroki:
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');Uruchom z ts-node:
npx ts-node triangle.tsTypowe problemy
| Issue | Cause | Fix |
|---|---|---|
mesh.controlPoints.length wynosi 0 po push | Siatka nie jest referencjonowana przez żaden węzeł | Wypchnij przed przypisaniem node.entity; kolejność nie ma znaczenia, ale zweryfikuj odwołanie |
| Eksport generuje pustą geometrię | node.entity nie przypisano | Upewnij się, że node.entity = mesh jest ustawione przed wywołaniem scene.save() |
| Niezgodność liczby wektorów normalnych | Tablica przekazana do setData() jest krótsza niż controlPoints | Dodaj jeden wpis FVector3 na każdy punkt kontrolny przy użyciu MappingMode.CONTROL_POINT |
| Podgląd glTF wyświetla czarną siatkę | Wektory normalne skierowane do wewnątrz | Odwróć kolejność wierzchołków w createPolygon (np. 0, 2, 1) lub zaneguj wektory normalne |
| TypeScript: nie znaleziono właściwości ’normals.data' | Nieprawidłowa ścieżka importu | Importuj VertexElementNormal z @aspose/3d/entities, a nie z katalogu głównego @aspose/3d |
Najczęściej zadawane pytania
Czy mogę tworzyć czworokąty zamiast trójkątów?
Tak. Przekaż cztery indeksy do createPolygon(0, 1, 2, 3). Biblioteka trianguluje czworokąty podczas eksportu do formatów wymagających trójkątów (glTF, STL).
Jaka jest różnica między MappingMode.CONTROL_POINT a MappingMode.POLYGON_VERTEX?CONTROL_POINT przechowuje jedną wartość na unikalny wierzchołek. POLYGON_VERTEX przechowuje jedną wartość na parę wielokąt‑wierzchołek, co pozwala na różne wektory normalne w tym samym wierzchołku, gdy należy on do wielu wielokątów (twarde krawędzie).
Czy muszę triangulować siatkę przed zapisaniem do STL?
Nie. Biblioteka automatycznie obsługuje triangulację podczas eksportu do formatów wymagających trójkątów. Możesz definiować czworokąty i n‑kąty w siatce i zapisać bezpośrednio do STL.
Jak dodać współrzędne UV?
Użyj mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT), aby utworzyć VertexElementUV, a następnie wywołaj setData([...]) z tablicą wartości FVector2 lub FVector3 — po jednej na punkt kontrolny. Getter data zwraca kopię; nie dodawaj do niej bezpośrednio.
Czy mogę zbudować wiele siatek w jednej scenie?
Tak. Utwórz wiele węzłów pod scene.rootNode i przypisz oddzielny Mesh do właściwości entity każdego węzła.