circuit-json-to-gltf 0.0.72 → 0.0.73

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 +76 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -11459,7 +11459,7 @@ var require_unionGeom3 = __commonJS({
11459
11459
  var flatten = require_flatten();
11460
11460
  var retessellate = require_retessellate();
11461
11461
  var unionSub = require_unionGeom3Sub();
11462
- var union = (...geometries) => {
11462
+ var union3 = (...geometries) => {
11463
11463
  geometries = flatten(geometries);
11464
11464
  let i;
11465
11465
  for (i = 1; i < geometries.length; i += 2) {
@@ -11469,7 +11469,7 @@ var require_unionGeom3 = __commonJS({
11469
11469
  newgeometry = retessellate(newgeometry);
11470
11470
  return newgeometry;
11471
11471
  };
11472
- module.exports = union;
11472
+ module.exports = union3;
11473
11473
  }
11474
11474
  });
11475
11475
 
@@ -11483,14 +11483,14 @@ var require_unionGeom2 = __commonJS({
11483
11483
  var fromFakePolygons = require_fromFakePolygons();
11484
11484
  var to3DWalls = require_to3DWalls();
11485
11485
  var unionGeom3 = require_unionGeom3();
11486
- var union = (...geometries) => {
11486
+ var union3 = (...geometries) => {
11487
11487
  geometries = flatten(geometries);
11488
11488
  const newgeometries = geometries.map((geometry) => to3DWalls({ z0: -1, z1: 1 }, geometry));
11489
11489
  const newgeom3 = unionGeom3(newgeometries);
11490
11490
  const epsilon = measureEpsilon(newgeom3);
11491
11491
  return fromFakePolygons(epsilon, geom33.toPolygons(newgeom3));
11492
11492
  };
11493
- module.exports = union;
11493
+ module.exports = union3;
11494
11494
  }
11495
11495
  });
11496
11496
 
@@ -11504,7 +11504,7 @@ var require_union = __commonJS({
11504
11504
  var geom33 = require_geom3();
11505
11505
  var unionGeom2 = require_unionGeom2();
11506
11506
  var unionGeom3 = require_unionGeom3();
11507
- var union = (...geometries) => {
11507
+ var union3 = (...geometries) => {
11508
11508
  geometries = flatten(geometries);
11509
11509
  if (geometries.length === 0) throw new Error("wrong number of arguments");
11510
11510
  if (!areAllShapesTheSameType(geometries)) {
@@ -11515,7 +11515,7 @@ var require_union = __commonJS({
11515
11515
  if (geom33.isA(geometry)) return unionGeom3(geometries);
11516
11516
  return geometry;
11517
11517
  };
11518
- module.exports = union;
11518
+ module.exports = union3;
11519
11519
  }
11520
11520
  });
11521
11521
 
@@ -11905,7 +11905,7 @@ var require_expandGeom3 = __commonJS({
11905
11905
  "node_modules/@jscad/modeling/src/operations/expansions/expandGeom3.js"(exports, module) {
11906
11906
  "use strict";
11907
11907
  var geom33 = require_geom3();
11908
- var union = require_union();
11908
+ var union3 = require_union();
11909
11909
  var expandShell = require_expandShell();
11910
11910
  var expandGeom3 = (options, geometry) => {
11911
11911
  const defaults = {
@@ -11921,7 +11921,7 @@ var require_expandGeom3 = __commonJS({
11921
11921
  if (polygons.length === 0) throw new Error("the given geometry cannot be empty");
11922
11922
  options = { delta, corners, segments };
11923
11923
  const expanded = expandShell(options, geometry);
11924
- return union(geometry, expanded);
11924
+ return union3(geometry, expanded);
11925
11925
  };
11926
11926
  module.exports = expandGeom3;
11927
11927
  }
@@ -12633,7 +12633,7 @@ var require_hullChain = __commonJS({
12633
12633
  "node_modules/@jscad/modeling/src/operations/hulls/hullChain.js"(exports, module) {
12634
12634
  "use strict";
12635
12635
  var flatten = require_flatten();
12636
- var union = require_union();
12636
+ var union3 = require_union();
12637
12637
  var hull = require_hull();
12638
12638
  var hullChain = (...geometries) => {
12639
12639
  geometries = flatten(geometries);
@@ -12642,7 +12642,7 @@ var require_hullChain = __commonJS({
12642
12642
  for (let i = 1; i < geometries.length; i++) {
12643
12643
  hulls.push(hull(geometries[i - 1], geometries[i]));
12644
12644
  }
12645
- return union(hulls);
12645
+ return union3(hulls);
12646
12646
  };
12647
12647
  module.exports = hullChain;
12648
12648
  }
@@ -15001,6 +15001,8 @@ var import_extrusions = __toESM(require_extrusions(), 1);
15001
15001
  var import_primitives = __toESM(require_primitives(), 1);
15002
15002
  var import_transforms = __toESM(require_transforms(), 1);
15003
15003
  var DEFAULT_SEGMENTS = 64;
15004
+ var REDUCED_SEGMENTS = 16;
15005
+ var HOLE_COUNT_THRESHOLD = 50;
15004
15006
  var toBoardSpaceVec2 = (point, center) => [point.x - center.x, -(point.y - center.y)];
15005
15007
  var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
15006
15008
  var arePointsClockwise = (points) => {
@@ -15013,11 +15015,11 @@ var arePointsClockwise = (points) => {
15013
15015
  const signedArea = area / 2;
15014
15016
  return signedArea <= 0;
15015
15017
  };
15016
- var createCircularHole = (x, y, radius, thickness) => (0, import_primitives.cylinder)({
15018
+ var createCircularHole = (x, y, radius, thickness, segments = DEFAULT_SEGMENTS) => (0, import_primitives.cylinder)({
15017
15019
  center: [x, y, 0],
15018
15020
  height: thickness + 1,
15019
15021
  radius,
15020
- segments: DEFAULT_SEGMENTS
15022
+ segments
15021
15023
  });
15022
15024
  var createCutoutGeoms = (boardCenter, thickness, cutouts = []) => {
15023
15025
  const geoms = [];
@@ -15129,9 +15131,36 @@ var filterCutoutsForBoard = (cutouts, board) => {
15129
15131
  var import_extrusions2 = __toESM(require_extrusions(), 1);
15130
15132
  var import_primitives2 = __toESM(require_primitives(), 1);
15131
15133
  var import_transforms2 = __toESM(require_transforms(), 1);
15132
- var import_booleans = __toESM(require_booleans(), 1);
15134
+ var import_booleans2 = __toESM(require_booleans(), 1);
15133
15135
  var geom3 = __toESM(require_geom3(), 1);
15134
15136
  var import_measureBoundingBox = __toESM(require_measureBoundingBox2(), 1);
15137
+
15138
+ // lib/utils/batched-union.ts
15139
+ var import_booleans = __toESM(require_booleans(), 1);
15140
+ var batchedUnion = (geoms, batchSize = 50) => {
15141
+ if (geoms.length === 0) {
15142
+ throw new Error("Cannot union empty array");
15143
+ }
15144
+ if (geoms.length === 1) {
15145
+ return geoms[0];
15146
+ }
15147
+ let results = [...geoms];
15148
+ while (results.length > 1) {
15149
+ const newResults = [];
15150
+ for (let i = 0; i < results.length; i += batchSize) {
15151
+ const batch = results.slice(i, i + batchSize);
15152
+ if (batch.length === 1) {
15153
+ newResults.push(batch[0]);
15154
+ } else {
15155
+ newResults.push((0, import_booleans.union)(...batch));
15156
+ }
15157
+ }
15158
+ results = newResults;
15159
+ }
15160
+ return results[0];
15161
+ };
15162
+
15163
+ // lib/utils/pcb-board-geometry.ts
15135
15164
  var RADIUS_EPSILON = 1e-4;
15136
15165
  var getNumberProperty = (obj, key) => {
15137
15166
  const value = obj[key];
@@ -15157,14 +15186,14 @@ var createBoardOutlineGeom = (board, center, thickness) => {
15157
15186
  geom = (0, import_transforms2.translate)([0, 0, -thickness / 2], geom);
15158
15187
  return geom;
15159
15188
  };
15160
- var createPillHole = (x, y, width, height, thickness, rotate) => {
15189
+ var createPillHoleWithSegments = (x, y, width, height, thickness, rotate, segments = DEFAULT_SEGMENTS) => {
15161
15190
  const minDimension = Math.min(width, height);
15162
15191
  const maxAllowedRadius = Math.max(0, minDimension / 2 - RADIUS_EPSILON);
15163
15192
  const roundRadius = maxAllowedRadius <= 0 ? 0 : Math.min(height / 2, maxAllowedRadius);
15164
15193
  const hole2d = (0, import_primitives2.roundedRectangle)({
15165
15194
  size: [width, height],
15166
15195
  roundRadius,
15167
- segments: DEFAULT_SEGMENTS
15196
+ segments
15168
15197
  });
15169
15198
  let hole3d = (0, import_extrusions2.extrudeLinear)({ height: thickness + 1 }, hole2d);
15170
15199
  hole3d = (0, import_transforms2.translate)([0, 0, -(thickness + 1) / 2], hole3d);
@@ -15173,7 +15202,7 @@ var createPillHole = (x, y, width, height, thickness, rotate) => {
15173
15202
  }
15174
15203
  return (0, import_transforms2.translate)([x, y, 0], hole3d);
15175
15204
  };
15176
- var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) => {
15205
+ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = [], segments = DEFAULT_SEGMENTS) => {
15177
15206
  const holeGeoms = [];
15178
15207
  for (const hole of holes) {
15179
15208
  const holeRecord = hole;
@@ -15187,13 +15216,14 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
15187
15216
  const rotate = holeHeight > holeWidth;
15188
15217
  const width = rotate ? holeHeight : holeWidth;
15189
15218
  const height = rotate ? holeWidth : holeHeight;
15190
- const pillHole = createPillHole(
15219
+ const pillHole = createPillHoleWithSegments(
15191
15220
  relX,
15192
15221
  relY,
15193
15222
  width,
15194
15223
  height,
15195
15224
  thickness,
15196
- rotate
15225
+ rotate,
15226
+ segments
15197
15227
  );
15198
15228
  holeGeoms.push(pillHole);
15199
15229
  continue;
@@ -15210,7 +15240,7 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
15210
15240
  const hole2d = (0, import_primitives2.roundedRectangle)({
15211
15241
  size: [holeWidth, holeHeight],
15212
15242
  roundRadius,
15213
- segments: DEFAULT_SEGMENTS
15243
+ segments
15214
15244
  });
15215
15245
  let hole3d = (0, import_extrusions2.extrudeLinear)({ height: thickness + 1 }, hole2d);
15216
15246
  hole3d = (0, import_transforms2.translate)([0, 0, -(thickness + 1) / 2], hole3d);
@@ -15224,7 +15254,7 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
15224
15254
  const diameter = getNumberProperty(holeRecord, "hole_diameter") ?? getNumberProperty(holeRecord, "diameter");
15225
15255
  if (!diameter) continue;
15226
15256
  const radius = diameter / 2;
15227
- holeGeoms.push(createCircularHole(relX, relY, radius, thickness));
15257
+ holeGeoms.push(createCircularHole(relX, relY, radius, thickness, segments));
15228
15258
  }
15229
15259
  for (const plated of platedHoles) {
15230
15260
  const platedRecord = plated;
@@ -15240,13 +15270,23 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
15240
15270
  const width = rotate ? holeHeight : holeWidth;
15241
15271
  const height = rotate ? holeWidth : holeHeight;
15242
15272
  holeGeoms.push(
15243
- createPillHole(relX, relY, width, height, thickness, rotate)
15273
+ createPillHoleWithSegments(
15274
+ relX,
15275
+ relY,
15276
+ width,
15277
+ height,
15278
+ thickness,
15279
+ rotate,
15280
+ segments
15281
+ )
15244
15282
  );
15245
15283
  continue;
15246
15284
  }
15247
15285
  const diameter = getNumberProperty(platedRecord, "hole_diameter") ?? getNumberProperty(platedRecord, "outer_diameter");
15248
15286
  if (!diameter) continue;
15249
- holeGeoms.push(createCircularHole(relX, relY, diameter / 2, thickness));
15287
+ holeGeoms.push(
15288
+ createCircularHole(relX, relY, diameter / 2, thickness, segments)
15289
+ );
15250
15290
  }
15251
15291
  return holeGeoms;
15252
15292
  };
@@ -15302,11 +15342,21 @@ var createBoardMesh = (board, options) => {
15302
15342
  const { thickness, holes = [], platedHoles = [], cutouts = [] } = options;
15303
15343
  const center = board.center ?? { x: 0, y: 0 };
15304
15344
  let boardGeom = createBoardOutlineGeom(board, center, thickness);
15305
- const holeGeoms = createHoleGeoms(center, thickness, holes, platedHoles);
15345
+ const totalHoleCount = holes.length + platedHoles.length;
15346
+ const useReducedSegments = totalHoleCount > HOLE_COUNT_THRESHOLD;
15347
+ const segments = useReducedSegments ? REDUCED_SEGMENTS : DEFAULT_SEGMENTS;
15348
+ const holeGeoms = createHoleGeoms(
15349
+ center,
15350
+ thickness,
15351
+ holes,
15352
+ platedHoles,
15353
+ segments
15354
+ );
15306
15355
  const cutoutGeoms = createCutoutGeoms(center, thickness, cutouts);
15307
15356
  const subtractGeoms = [...holeGeoms, ...cutoutGeoms];
15308
15357
  if (subtractGeoms.length > 0) {
15309
- boardGeom = (0, import_booleans.subtract)(boardGeom, ...subtractGeoms);
15358
+ const unifiedHoles = batchedUnion(subtractGeoms);
15359
+ boardGeom = (0, import_booleans2.subtract)(boardGeom, unifiedHoles);
15310
15360
  }
15311
15361
  boardGeom = (0, import_transforms2.rotateX)(-Math.PI / 2, boardGeom);
15312
15362
  const polygons = geom3.toPolygons(boardGeom);
@@ -15321,7 +15371,7 @@ var createBoardMesh = (board, options) => {
15321
15371
 
15322
15372
  // lib/utils/pcb-panel-geometry.ts
15323
15373
  var import_transforms3 = __toESM(require_transforms(), 1);
15324
- var import_booleans2 = __toESM(require_booleans(), 1);
15374
+ var import_booleans3 = __toESM(require_booleans(), 1);
15325
15375
  var geom32 = __toESM(require_geom3(), 1);
15326
15376
  var import_measureBoundingBox2 = __toESM(require_measureBoundingBox2(), 1);
15327
15377
  var createPanelMesh = (panel, options) => {
@@ -15332,7 +15382,7 @@ var createPanelMesh = (panel, options) => {
15332
15382
  const cutoutGeoms = createCutoutGeoms(center, thickness, cutouts);
15333
15383
  const subtractGeoms = [...holeGeoms, ...cutoutGeoms];
15334
15384
  if (subtractGeoms.length > 0) {
15335
- panelGeom = (0, import_booleans2.subtract)(panelGeom, ...subtractGeoms);
15385
+ panelGeom = (0, import_booleans3.subtract)(panelGeom, ...subtractGeoms);
15336
15386
  }
15337
15387
  panelGeom = (0, import_transforms3.rotateX)(-Math.PI / 2, panelGeom);
15338
15388
  const polygons = geom32.toPolygons(panelGeom);
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.72",
5
+ "version": "0.0.73",
6
6
  "scripts": {
7
7
  "test": "bun test tests/",
8
8
  "format": "biome format --write .",