Cara Membina Mesh 3D Secara Program dalam TypeScript
Aspose.3D FOSS untuk TypeScript membolehkan anda membina geometri 3D sepenuhnya dalam kod tanpa memuatkan sebarang fail. Anda menentukan kedudukan vertex sebagai titik kawalan, menentukan muka poligon mengikut indeks, dan melampirkan elemen vertex pilihan seperti normal, UV, atau warna vertex. Hasilnya boleh disimpan ke mana-mana format yang boleh ditulis: glTF, GLB, STL, FBX, atau COLLADA.
Prasyarat
- Node.js 18 atau lebih baru
- TypeScript 5.0 atau lebih baru
@aspose/3ddipasang (lihat Langkah 1)
Panduan Langkah demi Langkah
Langkah 1: Pasang @aspose/3d
npm install @aspose/3dTiada add‑on asli atau perpustakaan sistem diperlukan. Pakej ini termasuk definisi jenis TypeScript.
Minimum tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}Langkah 2: Buat Adegan dan Node
Sebuah Scene ialah kontena peringkat atas. Semua geometri mesti dilampirkan kepada sebuah Node di dalam pokok adegan:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const node = scene.rootNode.createChildNode('triangle');createChildNode(name) membuat nod bernama dan menyambungkannya sebagai anak nod semasa. Objek Node yang dikembalikan ialah tempat anda akan melekatkan mesh pada Langkah 7.
Langkah 3: Cipta Objek Mesh
Mesh menyimpan kedudukan vertex dan definisi poligon. Bina satu dengan nama pilihan:
import { Mesh } from '@aspose/3d/entities';
const mesh = new Mesh('triangle');Mesh bermula kosong: tiada simpul dan tiada muka. Anda menambahnya dalam langkah seterusnya.
Langkah 4: Tambah Titik Kawalan (Vertices)
Titik kawalan adalah kedudukan verteks dalam ruang tempatan. Tolak nilai Vector4 ke dalam mesh.controlPoints. Komponen keempat (w) ialah 1 untuk kedudukan:
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
Anda merujuk kedudukan ini dengan indeks berasaskan sifar apabila mentakrifkan muka polygon.
Langkah 5: Cipta Muka Poligon
createPolygon() mendefinisikan satu muka dengan menyenaraikan indeks‑vertex dalam susunan. Tiga indeks membentuk satu segitiga:
mesh.createPolygon(0, 1, 2);Anda juga boleh menentukan quads (empat indeks) atau poligon sewenang‑wenanya untuk format yang menyokongnya. Untuk glTF, perpustakaan akan secara automatik melakukan triangulasi quads dan n‑gon semasa eksport.
Langkah 6: Tambah Normal Vertex
Normal meningkatkan kualiti rendering. Gunakan mesh.createElement() untuk membuat VertexElementNormal, kumpulkan vektor normal ke dalam satu array, kemudian panggil setData() untuk menyimpannya. Getter data mengembalikan salinan defensif — menolak ke dalamnya tidak memberi kesan. Gunakan FVector3 (float tepat tunggal) untuk data normal, bukan 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 bermaksud satu normal per vertex. ReferenceMode.DIRECT bermaksud susunan data diindeks secara langsung oleh indeks vertex poligon.
Langkah 7: Lampirkan Mesh dan Simpan ke glTF
Tetapkan mesh kepada nod melalui node.entity, kemudian simpan adegan:
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');Untuk menghasilkan satu fail .glb yang berdiri sendiri, tetapkan saveOpts.binaryMode = true dan ubah sambungan fail output kepada .glb.
Contoh Lengkap
Berikut ialah skrip penuh yang menggabungkan semua langkah di atas:
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');Jalankan dengan ts-node:
npx ts-node triangle.tsIsu Umum
| Isu | Punca | Penyelesaian |
|---|---|---|
mesh.controlPoints.length ialah 0 selepas tolak | Mesh tidak dirujuk oleh mana-mana nod | Tolak sebelum menetapkan node.entity; susunan tidak penting, tetapi sahkan rujukan |
| Eksport menghasilkan geometri kosong | node.entity tidak ditetapkan | Pastikan node.entity = mesh sebelum memanggil scene.save() |
| Bilangan normal tidak sepadan | Array yang dihantar ke setData() lebih pendek daripada controlPoints | Tambah satu entri FVector3 per titik kawalan apabila menggunakan MappingMode.CONTROL_POINT |
| Penonton glTF menunjukkan mesh hitam | Normal mengarah ke dalam | Balikkan susunan winding dalam createPolygon (contoh, 0, 2, 1) atau negasikan vektor normal |
| TypeScript: sifat ’normals.data’ tidak ditemui | Laluan import salah | Import VertexElementNormal dari @aspose/3d/entities, bukan dari akar @aspose/3d |
Soalan Lazim
Bolehkah saya membuat quads dan bukannya segitiga?
Ya. Hantar empat indeks kepada createPolygon(0, 1, 2, 3). Perpustakaan menukarkan quads menjadi segitiga semasa eksport ke format yang memerlukan segitiga (glTF, STL).
Apakah perbezaan antara MappingMode.CONTROL_POINT dan MappingMode.POLYGON_VERTEX?CONTROL_POINT menyimpan satu nilai bagi setiap simpul unik. POLYGON_VERTEX menyimpan satu nilai bagi setiap pasangan poligon‑simpul, yang membolehkan normal yang berbeza pada simpul yang sama apabila ia tergolong dalam pelbagai poligon (tepi keras).
Perlukah saya melakukan triangulasi pada mesh sebelum menyimpan ke STL?
Tidak. Perpustakaan mengendalikan triangulasi secara automatik apabila mengeksport ke format yang memerlukan segi tiga. Anda boleh menentukan kuad dan n‑gon dalam mesh dan menyimpan terus ke STL.
Bagaimana saya menambah koordinat UV?
Gunakan mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) untuk membuat VertexElementUV, kemudian panggil setData([...]) dengan satu tatasusunan nilai FVector2 atau FVector3 — satu bagi setiap titik kawalan. Pemanggil data mengembalikan salinan; jangan push secara langsung kepadanya.
Bolehkah saya membina berbilang mesh dalam satu adegan?
Ya. Cipta berbilang nod di bawah scene.rootNode dan tetapkan Mesh yang berasingan kepada sifat entity setiap nod.