circuit-json-to-gltf 0.0.57 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +119 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14109,6 +14109,75 @@ function clearOBJCache() {
14109
14109
  objCache.clear();
14110
14110
  }
14111
14111
 
14112
+ // lib/utils/gltf-node-transforms.ts
14113
+ function applyQuaternion(p, q) {
14114
+ const [qx, qy, qz, qw] = q;
14115
+ const { x, y, z } = p;
14116
+ const ix = qw * x + qy * z - qz * y;
14117
+ const iy = qw * y + qz * x - qx * z;
14118
+ const iz = qw * z + qx * y - qy * x;
14119
+ const iw = -qx * x - qy * y - qz * z;
14120
+ return {
14121
+ x: ix * qw + iw * -qx + iy * -qz - iz * -qy,
14122
+ y: iy * qw + iw * -qy + iz * -qx - ix * -qz,
14123
+ z: iz * qw + iw * -qz + ix * -qy - iy * -qx
14124
+ };
14125
+ }
14126
+ function applyNodeTransform(p, node) {
14127
+ let result = { ...p };
14128
+ if (node.scale) {
14129
+ result = {
14130
+ x: result.x * node.scale[0],
14131
+ y: result.y * node.scale[1],
14132
+ z: result.z * node.scale[2]
14133
+ };
14134
+ }
14135
+ if (node.rotation) {
14136
+ result = applyQuaternion(
14137
+ result,
14138
+ node.rotation
14139
+ );
14140
+ }
14141
+ if (node.translation) {
14142
+ result = {
14143
+ x: result.x + node.translation[0],
14144
+ y: result.y + node.translation[1],
14145
+ z: result.z + node.translation[2]
14146
+ };
14147
+ }
14148
+ return result;
14149
+ }
14150
+ function buildMeshTransforms(gltf) {
14151
+ const meshTransforms = /* @__PURE__ */ new Map();
14152
+ if (!gltf.nodes) return meshTransforms;
14153
+ function processNode(nodeIndex, parentTransforms) {
14154
+ const node = gltf.nodes[nodeIndex];
14155
+ if (!node) return;
14156
+ const currentTransforms = [...parentTransforms];
14157
+ if (node.translation || node.rotation || node.scale) {
14158
+ currentTransforms.push({
14159
+ translation: node.translation,
14160
+ rotation: node.rotation,
14161
+ scale: node.scale
14162
+ });
14163
+ }
14164
+ if (node.mesh !== void 0) {
14165
+ meshTransforms.set(node.mesh, currentTransforms);
14166
+ }
14167
+ if (node.children) {
14168
+ for (const childIndex of node.children) {
14169
+ processNode(childIndex, currentTransforms);
14170
+ }
14171
+ }
14172
+ }
14173
+ if (gltf.scenes && gltf.scenes[0]?.nodes) {
14174
+ for (const rootNodeIndex of gltf.scenes[0].nodes) {
14175
+ processNode(rootNodeIndex, []);
14176
+ }
14177
+ }
14178
+ return meshTransforms;
14179
+ }
14180
+
14112
14181
  // lib/loaders/glb.ts
14113
14182
  var glbCache = /* @__PURE__ */ new Map();
14114
14183
  async function loadGLB(url, transform) {
@@ -14167,7 +14236,7 @@ function parseGLB(buffer, transform) {
14167
14236
  const finalConfig = transform ?? {
14168
14237
  axisMapping: { x: "x", y: "z", z: "y" }
14169
14238
  };
14170
- const transformedTriangles = transformTriangles(triangles, finalConfig);
14239
+ let transformedTriangles = transformTriangles(triangles, finalConfig);
14171
14240
  const hasColors = transformedTriangles.some((t) => t.color !== void 0);
14172
14241
  if (hasColors) {
14173
14242
  return convertToOBJMesh(transformedTriangles);
@@ -14226,7 +14295,10 @@ function extractTrianglesFromGLTF(gltf, binaryBuffer) {
14226
14295
  if (!gltf.meshes || !gltf.accessors || !gltf.bufferViews) {
14227
14296
  return triangles;
14228
14297
  }
14229
- for (const mesh of gltf.meshes) {
14298
+ const meshTransforms = buildMeshTransforms(gltf);
14299
+ for (let meshIndex = 0; meshIndex < gltf.meshes.length; meshIndex++) {
14300
+ const mesh = gltf.meshes[meshIndex];
14301
+ const transforms = meshTransforms.get(meshIndex) || [];
14230
14302
  for (const primitive of mesh.primitives) {
14231
14303
  const mode = primitive.mode ?? 4;
14232
14304
  if (mode !== 4) {
@@ -14286,28 +14358,42 @@ function extractTrianglesFromGLTF(gltf, binaryBuffer) {
14286
14358
  const i0 = indices[i];
14287
14359
  const i1 = indices[i + 1];
14288
14360
  const i2 = indices[i + 2];
14289
- const v0 = {
14361
+ let v0 = {
14290
14362
  x: positions[i0 * 3],
14291
14363
  y: positions[i0 * 3 + 1],
14292
14364
  z: positions[i0 * 3 + 2]
14293
14365
  };
14294
- const v1 = {
14366
+ let v1 = {
14295
14367
  x: positions[i1 * 3],
14296
14368
  y: positions[i1 * 3 + 1],
14297
14369
  z: positions[i1 * 3 + 2]
14298
14370
  };
14299
- const v2 = {
14371
+ let v2 = {
14300
14372
  x: positions[i2 * 3],
14301
14373
  y: positions[i2 * 3 + 1],
14302
14374
  z: positions[i2 * 3 + 2]
14303
14375
  };
14376
+ for (const transform of transforms) {
14377
+ v0 = applyNodeTransform(v0, transform);
14378
+ v1 = applyNodeTransform(v1, transform);
14379
+ v2 = applyNodeTransform(v2, transform);
14380
+ }
14304
14381
  let normal;
14305
14382
  if (normals) {
14306
- normal = {
14383
+ let n = {
14307
14384
  x: (normals[i0 * 3] + normals[i1 * 3] + normals[i2 * 3]) / 3,
14308
14385
  y: (normals[i0 * 3 + 1] + normals[i1 * 3 + 1] + normals[i2 * 3 + 1]) / 3,
14309
14386
  z: (normals[i0 * 3 + 2] + normals[i1 * 3 + 2] + normals[i2 * 3 + 2]) / 3
14310
14387
  };
14388
+ for (const transform of transforms) {
14389
+ if (transform.rotation) {
14390
+ n = applyQuaternion(
14391
+ n,
14392
+ transform.rotation
14393
+ );
14394
+ }
14395
+ }
14396
+ normal = n;
14311
14397
  } else {
14312
14398
  normal = computeNormal(v0, v1, v2);
14313
14399
  }
@@ -14352,28 +14438,42 @@ function extractTrianglesFromGLTF(gltf, binaryBuffer) {
14352
14438
  }
14353
14439
  } else {
14354
14440
  for (let i = 0; i < vertexCount; i += 3) {
14355
- const v0 = {
14441
+ let v0 = {
14356
14442
  x: positions[i * 3],
14357
14443
  y: positions[i * 3 + 1],
14358
14444
  z: positions[i * 3 + 2]
14359
14445
  };
14360
- const v1 = {
14446
+ let v1 = {
14361
14447
  x: positions[(i + 1) * 3],
14362
14448
  y: positions[(i + 1) * 3 + 1],
14363
14449
  z: positions[(i + 1) * 3 + 2]
14364
14450
  };
14365
- const v2 = {
14451
+ let v2 = {
14366
14452
  x: positions[(i + 2) * 3],
14367
14453
  y: positions[(i + 2) * 3 + 1],
14368
14454
  z: positions[(i + 2) * 3 + 2]
14369
14455
  };
14456
+ for (const transform of transforms) {
14457
+ v0 = applyNodeTransform(v0, transform);
14458
+ v1 = applyNodeTransform(v1, transform);
14459
+ v2 = applyNodeTransform(v2, transform);
14460
+ }
14370
14461
  let normal;
14371
14462
  if (normals) {
14372
- normal = {
14463
+ let n = {
14373
14464
  x: (normals[i * 3] + normals[(i + 1) * 3] + normals[(i + 2) * 3]) / 3,
14374
14465
  y: (normals[i * 3 + 1] + normals[(i + 1) * 3 + 1] + normals[(i + 2) * 3 + 1]) / 3,
14375
14466
  z: (normals[i * 3 + 2] + normals[(i + 1) * 3 + 2] + normals[(i + 2) * 3 + 2]) / 3
14376
14467
  };
14468
+ for (const transform of transforms) {
14469
+ if (transform.rotation) {
14470
+ n = applyQuaternion(
14471
+ n,
14472
+ transform.rotation
14473
+ );
14474
+ }
14475
+ }
14476
+ normal = n;
14377
14477
  } else {
14378
14478
  normal = computeNormal(v0, v1, v2);
14379
14479
  }
@@ -14964,12 +15064,14 @@ var import_booleans2 = __toESM(require_booleans(), 1);
14964
15064
  var geom32 = __toESM(require_geom3(), 1);
14965
15065
  var import_measureBoundingBox2 = __toESM(require_measureBoundingBox2(), 1);
14966
15066
  var createPanelMesh = (panel, options) => {
14967
- const { thickness, holes = [], platedHoles = [] } = options;
15067
+ const { thickness, holes = [], platedHoles = [], cutouts = [] } = options;
14968
15068
  const center = panel.center ?? { x: 0, y: 0 };
14969
15069
  let panelGeom = createBoardOutlineGeom(panel, center, thickness);
14970
15070
  const holeGeoms = createHoleGeoms(center, thickness, holes, platedHoles);
14971
- if (holeGeoms.length > 0) {
14972
- panelGeom = (0, import_booleans2.subtract)(panelGeom, ...holeGeoms);
15071
+ const cutoutGeoms = createCutoutGeoms(center, thickness, cutouts);
15072
+ const subtractGeoms = [...holeGeoms, ...cutoutGeoms];
15073
+ if (subtractGeoms.length > 0) {
15074
+ panelGeom = (0, import_booleans2.subtract)(panelGeom, ...subtractGeoms);
14973
15075
  }
14974
15076
  panelGeom = (0, import_transforms3.rotateX)(-Math.PI / 2, panelGeom);
14975
15077
  const polygons = geom32.toPolygons(panelGeom);
@@ -15017,10 +15119,13 @@ async function convertCircuitJsonTo3D(circuitJson, options = {}) {
15017
15119
  if (pcbPanel) {
15018
15120
  const pcbHoles = db.pcb_hole?.list?.() ?? [];
15019
15121
  const pcbPlatedHoles = db.pcb_plated_hole?.list?.() ?? [];
15122
+ const pcbCutouts = db.pcb_cutout?.list?.() ?? [];
15123
+ const panelCutouts = pcbCutouts.filter((cutout) => !cutout.pcb_board_id);
15020
15124
  const panelMesh = createPanelMesh(pcbPanel, {
15021
15125
  thickness: effectiveBoardThickness,
15022
15126
  holes: pcbHoles,
15023
- platedHoles: pcbPlatedHoles
15127
+ platedHoles: pcbPlatedHoles,
15128
+ cutouts: panelCutouts
15024
15129
  });
15025
15130
  const meshWidth = panelMesh.boundingBox.max.x - panelMesh.boundingBox.min.x;
15026
15131
  const meshHeight = panelMesh.boundingBox.max.z - panelMesh.boundingBox.min.z;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "circuit-json-to-gltf",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.57",
5
+ "version": "0.0.59",
6
6
  "scripts": {
7
7
  "test": "bun test tests/",
8
8
  "format": "biome format --write .",