Skip to content

Commit 1ca10da

Browse files
committed
feat: add GLTF model loading support
- Implement complete GLTF 2.0 parser with security validation - Add pipeline integration following STL/OBJ patterns - Include 91 comprehensive tests with performance benchmarks - Support cadModel.gltfUrl in circuit-json processing
1 parent ef5ec1f commit 1ca10da

16 files changed

Lines changed: 2837 additions & 9 deletions

lib/converters/circuit-to-3d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
} from "../types"
1414
import { loadSTL } from "../loaders/stl"
1515
import { loadOBJ } from "../loaders/obj"
16+
import { loadGLTF } from "../loaders/gltf"
1617
import { renderBoardTextures } from "./board-renderer"
1718
import { COORDINATE_TRANSFORMS } from "../utils/coordinate-transform"
1819

@@ -94,8 +95,8 @@ export async function convertCircuitJsonTo3D(
9495
const pcbComponentIdsWith3D = new Set<string>()
9596

9697
for (const cad of cadComponents) {
97-
const { model_stl_url, model_obj_url } = cad
98-
if (!model_stl_url && !model_obj_url) continue
98+
const { model_stl_url, model_obj_url, model_gltf_url } = cad
99+
if (!model_stl_url && !model_obj_url && !model_gltf_url) continue
99100

100101
pcbComponentIdsWith3D.add(cad.pcb_component_id)
101102

@@ -122,8 +123,8 @@ export async function convertCircuitJsonTo3D(
122123
center,
123124
size,
124125
color: componentColor,
125-
meshUrl: model_stl_url || model_obj_url,
126-
meshType: model_stl_url ? "stl" : "obj",
126+
meshUrl: model_stl_url || model_obj_url || model_gltf_url,
127+
meshType: model_stl_url ? "stl" : model_obj_url ? "obj" : "gltf",
127128
}
128129

129130
// Add rotation if specified
@@ -139,6 +140,8 @@ export async function convertCircuitJsonTo3D(
139140
box.mesh = await loadSTL(model_stl_url, defaultTransform)
140141
} else if (model_obj_url) {
141142
box.mesh = await loadOBJ(model_obj_url, defaultTransform)
143+
} else if (model_gltf_url) {
144+
box.mesh = await loadGLTF(model_gltf_url, defaultTransform)
142145
}
143146
} catch (error) {
144147
console.warn(`Failed to load 3D model: ${error}`)

lib/gltf/geometry.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Point3, Size3, STLMesh, OBJMesh, Triangle } from "../types"
1+
import type { Point3, Size3, STLMesh, OBJMesh, GLTFMesh, Triangle } from "../types"
22

33
export interface MeshData {
44
positions: number[]
@@ -360,6 +360,31 @@ export function createMeshFromOBJ(
360360
: [{ meshData: createMeshFromSTL(objMesh), materialIndex: -1 }]
361361
}
362362

363+
export function createMeshFromGLTF(gltfMesh: GLTFMesh): MeshData {
364+
const positions: number[] = []
365+
const normals: number[] = []
366+
const texcoords: number[] = []
367+
const indices: number[] = []
368+
369+
let vertexIndex = 0
370+
371+
for (const triangle of gltfMesh.triangles) {
372+
// Add vertices
373+
for (const vertex of triangle.vertices) {
374+
positions.push(vertex.x, vertex.y, vertex.z)
375+
normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z)
376+
// Simple planar UV mapping
377+
texcoords.push(vertex.x, vertex.z)
378+
}
379+
380+
// Add indices (reverse winding for correct face orientation)
381+
indices.push(vertexIndex, vertexIndex + 2, vertexIndex + 1)
382+
vertexIndex += 3
383+
}
384+
385+
return { positions, normals, texcoords, indices }
386+
}
387+
363388
export function transformMesh(
364389
mesh: MeshData,
365390
translation: Point3,

lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type {
4444
BoundingBox,
4545
STLMesh,
4646
OBJMesh,
47+
GLTFMesh,
4748
OBJMaterial,
4849
Color,
4950
Box3D,
@@ -59,6 +60,7 @@ export type {
5960
// Re-export loaders
6061
export { loadSTL, clearSTLCache } from "./loaders/stl"
6162
export { loadOBJ, clearOBJCache } from "./loaders/obj"
63+
export { loadGLTF, clearGLTFCache } from "./loaders/gltf"
6264

6365
// Re-export converters
6466
export { convertCircuitJsonTo3D } from "./converters/circuit-to-3d"

0 commit comments

Comments
 (0)