circuit-json-to-gltf 0.0.72 → 0.0.74
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.
- package/dist/index.js +348 -97
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -4378,6 +4378,52 @@ var require_isA3 = __commonJS({
|
|
|
4378
4378
|
}
|
|
4379
4379
|
});
|
|
4380
4380
|
|
|
4381
|
+
// node_modules/@jscad/modeling/src/geometries/geom3/isConvex.js
|
|
4382
|
+
var require_isConvex2 = __commonJS({
|
|
4383
|
+
"node_modules/@jscad/modeling/src/geometries/geom3/isConvex.js"(exports, module) {
|
|
4384
|
+
"use strict";
|
|
4385
|
+
var { EPS } = require_constants();
|
|
4386
|
+
var vec3 = require_vec3();
|
|
4387
|
+
var geom33 = require_isA3();
|
|
4388
|
+
var toPolygons3 = require_toPolygons();
|
|
4389
|
+
var poly3 = require_poly3();
|
|
4390
|
+
var isConvex = (geometry) => {
|
|
4391
|
+
if (!geom33(geometry)) {
|
|
4392
|
+
throw new Error("isConvex requires a geom3 geometry");
|
|
4393
|
+
}
|
|
4394
|
+
const polygons = toPolygons3(geometry);
|
|
4395
|
+
if (polygons.length === 0) {
|
|
4396
|
+
return true;
|
|
4397
|
+
}
|
|
4398
|
+
const vertices = [];
|
|
4399
|
+
const found = /* @__PURE__ */ new Set();
|
|
4400
|
+
for (let i = 0; i < polygons.length; i++) {
|
|
4401
|
+
const verts = polygons[i].vertices;
|
|
4402
|
+
for (let j = 0; j < verts.length; j++) {
|
|
4403
|
+
const v = verts[j];
|
|
4404
|
+
const key = `${v[0]},${v[1]},${v[2]}`;
|
|
4405
|
+
if (!found.has(key)) {
|
|
4406
|
+
found.add(key);
|
|
4407
|
+
vertices.push(v);
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4411
|
+
for (let i = 0; i < polygons.length; i++) {
|
|
4412
|
+
const plane = poly3.plane(polygons[i]);
|
|
4413
|
+
for (let j = 0; j < vertices.length; j++) {
|
|
4414
|
+
const v = vertices[j];
|
|
4415
|
+
const distance = vec3.dot(plane, v) - plane[3];
|
|
4416
|
+
if (distance > EPS) {
|
|
4417
|
+
return false;
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
return true;
|
|
4422
|
+
};
|
|
4423
|
+
module.exports = isConvex;
|
|
4424
|
+
}
|
|
4425
|
+
});
|
|
4426
|
+
|
|
4381
4427
|
// node_modules/@jscad/modeling/src/geometries/geom3/toPoints.js
|
|
4382
4428
|
var require_toPoints3 = __commonJS({
|
|
4383
4429
|
"node_modules/@jscad/modeling/src/geometries/geom3/toPoints.js"(exports, module) {
|
|
@@ -4535,6 +4581,7 @@ var require_geom3 = __commonJS({
|
|
|
4535
4581
|
fromCompactBinary: require_fromCompactBinary2(),
|
|
4536
4582
|
invert: require_invert3(),
|
|
4537
4583
|
isA: require_isA3(),
|
|
4584
|
+
isConvex: require_isConvex2(),
|
|
4538
4585
|
toPoints: require_toPoints3(),
|
|
4539
4586
|
toPolygons: require_toPolygons(),
|
|
4540
4587
|
toString: require_toString7(),
|
|
@@ -4731,7 +4778,7 @@ var require_appendArc = __commonJS({
|
|
|
4731
4778
|
} else if (sweepFlag && deltatheta < 0) {
|
|
4732
4779
|
deltatheta += TAU;
|
|
4733
4780
|
}
|
|
4734
|
-
let numsteps = Math.
|
|
4781
|
+
let numsteps = Math.floor(segments * (Math.abs(deltatheta) / TAU));
|
|
4735
4782
|
if (numsteps < 1) numsteps = 1;
|
|
4736
4783
|
for (let step = 1; step < numsteps; step++) {
|
|
4737
4784
|
const theta = theta1 + step / numsteps * deltatheta;
|
|
@@ -7200,7 +7247,7 @@ var require_arc = __commonJS({
|
|
|
7200
7247
|
vec2.add(point, point, centerv);
|
|
7201
7248
|
pointArray.push(point);
|
|
7202
7249
|
} else {
|
|
7203
|
-
const numsteps = Math.
|
|
7250
|
+
const numsteps = Math.floor(segments * (Math.abs(rotation) / TAU));
|
|
7204
7251
|
let edgestepsize = numsteps * 0.5 / rotation;
|
|
7205
7252
|
if (edgestepsize > 0.25) edgestepsize = 0.25;
|
|
7206
7253
|
const totalsteps = makeTangent ? numsteps + 2 : numsteps;
|
|
@@ -11233,6 +11280,205 @@ var require_intersect2 = __commonJS({
|
|
|
11233
11280
|
}
|
|
11234
11281
|
});
|
|
11235
11282
|
|
|
11283
|
+
// node_modules/@jscad/modeling/src/operations/hulls/hullPoints3.js
|
|
11284
|
+
var require_hullPoints3 = __commonJS({
|
|
11285
|
+
"node_modules/@jscad/modeling/src/operations/hulls/hullPoints3.js"(exports, module) {
|
|
11286
|
+
"use strict";
|
|
11287
|
+
var poly3 = require_poly3();
|
|
11288
|
+
var quickhull = require_quickhull();
|
|
11289
|
+
var hullPoints3 = (uniquePoints) => {
|
|
11290
|
+
const faces = quickhull(uniquePoints, { skipTriangulation: true });
|
|
11291
|
+
const polygons = faces.map((face) => {
|
|
11292
|
+
const vertices = face.map((index) => uniquePoints[index]);
|
|
11293
|
+
return poly3.create(vertices);
|
|
11294
|
+
});
|
|
11295
|
+
return polygons;
|
|
11296
|
+
};
|
|
11297
|
+
module.exports = hullPoints3;
|
|
11298
|
+
}
|
|
11299
|
+
});
|
|
11300
|
+
|
|
11301
|
+
// node_modules/@jscad/modeling/src/operations/booleans/unionGeom3Sub.js
|
|
11302
|
+
var require_unionGeom3Sub = __commonJS({
|
|
11303
|
+
"node_modules/@jscad/modeling/src/operations/booleans/unionGeom3Sub.js"(exports, module) {
|
|
11304
|
+
"use strict";
|
|
11305
|
+
var geom33 = require_geom3();
|
|
11306
|
+
var mayOverlap = require_mayOverlap();
|
|
11307
|
+
var { Tree } = require_trees();
|
|
11308
|
+
var unionSub = (geometry1, geometry2) => {
|
|
11309
|
+
if (!mayOverlap(geometry1, geometry2)) {
|
|
11310
|
+
return unionForNonIntersecting(geometry1, geometry2);
|
|
11311
|
+
}
|
|
11312
|
+
const a = new Tree(geom33.toPolygons(geometry1));
|
|
11313
|
+
const b = new Tree(geom33.toPolygons(geometry2));
|
|
11314
|
+
a.clipTo(b, false);
|
|
11315
|
+
b.clipTo(a);
|
|
11316
|
+
b.invert();
|
|
11317
|
+
b.clipTo(a);
|
|
11318
|
+
b.invert();
|
|
11319
|
+
const newpolygons = a.allPolygons().concat(b.allPolygons());
|
|
11320
|
+
const result = geom33.create(newpolygons);
|
|
11321
|
+
return result;
|
|
11322
|
+
};
|
|
11323
|
+
var unionForNonIntersecting = (geometry1, geometry2) => {
|
|
11324
|
+
let newpolygons = geom33.toPolygons(geometry1);
|
|
11325
|
+
newpolygons = newpolygons.concat(geom33.toPolygons(geometry2));
|
|
11326
|
+
return geom33.create(newpolygons);
|
|
11327
|
+
};
|
|
11328
|
+
module.exports = unionSub;
|
|
11329
|
+
}
|
|
11330
|
+
});
|
|
11331
|
+
|
|
11332
|
+
// node_modules/@jscad/modeling/src/operations/booleans/unionGeom3.js
|
|
11333
|
+
var require_unionGeom3 = __commonJS({
|
|
11334
|
+
"node_modules/@jscad/modeling/src/operations/booleans/unionGeom3.js"(exports, module) {
|
|
11335
|
+
"use strict";
|
|
11336
|
+
var flatten = require_flatten();
|
|
11337
|
+
var retessellate = require_retessellate();
|
|
11338
|
+
var unionSub = require_unionGeom3Sub();
|
|
11339
|
+
var union3 = (...geometries) => {
|
|
11340
|
+
geometries = flatten(geometries);
|
|
11341
|
+
let i;
|
|
11342
|
+
for (i = 1; i < geometries.length; i += 2) {
|
|
11343
|
+
geometries.push(unionSub(geometries[i - 1], geometries[i]));
|
|
11344
|
+
}
|
|
11345
|
+
let newgeometry = geometries[i - 1];
|
|
11346
|
+
newgeometry = retessellate(newgeometry);
|
|
11347
|
+
return newgeometry;
|
|
11348
|
+
};
|
|
11349
|
+
module.exports = union3;
|
|
11350
|
+
}
|
|
11351
|
+
});
|
|
11352
|
+
|
|
11353
|
+
// node_modules/@jscad/modeling/src/operations/minkowski/minkowskiSum.js
|
|
11354
|
+
var require_minkowskiSum = __commonJS({
|
|
11355
|
+
"node_modules/@jscad/modeling/src/operations/minkowski/minkowskiSum.js"(exports, module) {
|
|
11356
|
+
"use strict";
|
|
11357
|
+
var flatten = require_flatten();
|
|
11358
|
+
var geom33 = require_geom3();
|
|
11359
|
+
var poly3 = require_poly3();
|
|
11360
|
+
var hullPoints3 = require_hullPoints3();
|
|
11361
|
+
var unionGeom3 = require_unionGeom3();
|
|
11362
|
+
var minkowskiSum = (...geometries) => {
|
|
11363
|
+
geometries = flatten(geometries);
|
|
11364
|
+
if (geometries.length !== 2) {
|
|
11365
|
+
throw new Error("minkowskiSum requires exactly two geometries");
|
|
11366
|
+
}
|
|
11367
|
+
const [geomA, geomB] = geometries;
|
|
11368
|
+
if (!geom33.isA(geomA) || !geom33.isA(geomB)) {
|
|
11369
|
+
throw new Error("minkowskiSum requires geom3 geometries");
|
|
11370
|
+
}
|
|
11371
|
+
const aConvex = geom33.isConvex(geomA);
|
|
11372
|
+
const bConvex = geom33.isConvex(geomB);
|
|
11373
|
+
if (aConvex && bConvex) {
|
|
11374
|
+
return minkowskiSumConvex(geomA, geomB);
|
|
11375
|
+
}
|
|
11376
|
+
if (!aConvex && bConvex) {
|
|
11377
|
+
return minkowskiSumNonConvexConvex(geomA, geomB);
|
|
11378
|
+
}
|
|
11379
|
+
if (aConvex && !bConvex) {
|
|
11380
|
+
return minkowskiSumNonConvexConvex(geomB, geomA);
|
|
11381
|
+
}
|
|
11382
|
+
throw new Error("minkowskiSum of two non-convex geometries is not yet supported");
|
|
11383
|
+
};
|
|
11384
|
+
var minkowskiSumNonConvexConvex = (geomA, geomB) => {
|
|
11385
|
+
const tetrahedra = decomposeIntoTetrahedra(geomA);
|
|
11386
|
+
if (tetrahedra.length === 0) {
|
|
11387
|
+
return geom33.create();
|
|
11388
|
+
}
|
|
11389
|
+
const parts = tetrahedra.map((tet) => minkowskiSumConvex(tet, geomB));
|
|
11390
|
+
if (parts.length === 1) {
|
|
11391
|
+
return parts[0];
|
|
11392
|
+
}
|
|
11393
|
+
return unionGeom3(parts);
|
|
11394
|
+
};
|
|
11395
|
+
var decomposeIntoTetrahedra = (geometry) => {
|
|
11396
|
+
const polygons = geom33.toPolygons(geometry);
|
|
11397
|
+
if (polygons.length === 0) {
|
|
11398
|
+
return [];
|
|
11399
|
+
}
|
|
11400
|
+
const tetrahedra = [];
|
|
11401
|
+
for (let i = 0; i < polygons.length; i++) {
|
|
11402
|
+
const polygon3 = polygons[i];
|
|
11403
|
+
const vertices = polygon3.vertices;
|
|
11404
|
+
let cx = 0, cy = 0, cz = 0;
|
|
11405
|
+
for (let k = 0; k < vertices.length; k++) {
|
|
11406
|
+
cx += vertices[k][0];
|
|
11407
|
+
cy += vertices[k][1];
|
|
11408
|
+
cz += vertices[k][2];
|
|
11409
|
+
}
|
|
11410
|
+
cx /= vertices.length;
|
|
11411
|
+
cy /= vertices.length;
|
|
11412
|
+
cz /= vertices.length;
|
|
11413
|
+
const plane = poly3.plane(polygon3);
|
|
11414
|
+
const nx = plane[0], ny = plane[1], nz = plane[2];
|
|
11415
|
+
const offset = 0.1;
|
|
11416
|
+
const apex = [
|
|
11417
|
+
// Vertex used as apex in tetrahedron polygons below
|
|
11418
|
+
cx - nx * offset,
|
|
11419
|
+
cy - ny * offset,
|
|
11420
|
+
cz - nz * offset
|
|
11421
|
+
];
|
|
11422
|
+
for (let j = 1; j < vertices.length - 1; j++) {
|
|
11423
|
+
const v0 = vertices[0];
|
|
11424
|
+
const v1 = vertices[j];
|
|
11425
|
+
const v2 = vertices[j + 1];
|
|
11426
|
+
const tetPolygons = createTetrahedronPolygons(apex, v0, v1, v2);
|
|
11427
|
+
tetrahedra.push(geom33.create(tetPolygons));
|
|
11428
|
+
}
|
|
11429
|
+
}
|
|
11430
|
+
return tetrahedra;
|
|
11431
|
+
};
|
|
11432
|
+
var createTetrahedronPolygons = (p0, p1, p2, p3) => {
|
|
11433
|
+
return [
|
|
11434
|
+
poly3.create([p0, p2, p1]),
|
|
11435
|
+
// base seen from p3
|
|
11436
|
+
poly3.create([p0, p1, p3]),
|
|
11437
|
+
// face opposite p2
|
|
11438
|
+
poly3.create([p1, p2, p3]),
|
|
11439
|
+
// face opposite p0
|
|
11440
|
+
poly3.create([p2, p0, p3])
|
|
11441
|
+
// face opposite p1
|
|
11442
|
+
];
|
|
11443
|
+
};
|
|
11444
|
+
var minkowskiSumConvex = (geomA, geomB) => {
|
|
11445
|
+
const pointsA = extractUniqueVertices(geomA);
|
|
11446
|
+
const pointsB = extractUniqueVertices(geomB);
|
|
11447
|
+
if (pointsA.length === 0 || pointsB.length === 0) {
|
|
11448
|
+
return geom33.create();
|
|
11449
|
+
}
|
|
11450
|
+
const summedPoints = [];
|
|
11451
|
+
for (let i = 0; i < pointsA.length; i++) {
|
|
11452
|
+
const a = pointsA[i];
|
|
11453
|
+
for (let j = 0; j < pointsB.length; j++) {
|
|
11454
|
+
const b = pointsB[j];
|
|
11455
|
+
summedPoints.push([a[0] + b[0], a[1] + b[1], a[2] + b[2]]);
|
|
11456
|
+
}
|
|
11457
|
+
}
|
|
11458
|
+
const hullPolygons = hullPoints3(summedPoints);
|
|
11459
|
+
return geom33.create(hullPolygons);
|
|
11460
|
+
};
|
|
11461
|
+
var extractUniqueVertices = (geometry) => {
|
|
11462
|
+
const found = /* @__PURE__ */ new Set();
|
|
11463
|
+
const unique = [];
|
|
11464
|
+
const polygons = geom33.toPolygons(geometry);
|
|
11465
|
+
for (let i = 0; i < polygons.length; i++) {
|
|
11466
|
+
const vertices = polygons[i].vertices;
|
|
11467
|
+
for (let j = 0; j < vertices.length; j++) {
|
|
11468
|
+
const v = vertices[j];
|
|
11469
|
+
const key = `${v[0]},${v[1]},${v[2]}`;
|
|
11470
|
+
if (!found.has(key)) {
|
|
11471
|
+
found.add(key);
|
|
11472
|
+
unique.push(v);
|
|
11473
|
+
}
|
|
11474
|
+
}
|
|
11475
|
+
}
|
|
11476
|
+
return unique;
|
|
11477
|
+
};
|
|
11478
|
+
module.exports = minkowskiSum;
|
|
11479
|
+
}
|
|
11480
|
+
});
|
|
11481
|
+
|
|
11236
11482
|
// node_modules/@jscad/modeling/src/operations/booleans/scissionGeom3.js
|
|
11237
11483
|
var require_scissionGeom3 = __commonJS({
|
|
11238
11484
|
"node_modules/@jscad/modeling/src/operations/booleans/scissionGeom3.js"(exports, module) {
|
|
@@ -11421,58 +11667,6 @@ var require_subtract4 = __commonJS({
|
|
|
11421
11667
|
}
|
|
11422
11668
|
});
|
|
11423
11669
|
|
|
11424
|
-
// node_modules/@jscad/modeling/src/operations/booleans/unionGeom3Sub.js
|
|
11425
|
-
var require_unionGeom3Sub = __commonJS({
|
|
11426
|
-
"node_modules/@jscad/modeling/src/operations/booleans/unionGeom3Sub.js"(exports, module) {
|
|
11427
|
-
"use strict";
|
|
11428
|
-
var geom33 = require_geom3();
|
|
11429
|
-
var mayOverlap = require_mayOverlap();
|
|
11430
|
-
var { Tree } = require_trees();
|
|
11431
|
-
var unionSub = (geometry1, geometry2) => {
|
|
11432
|
-
if (!mayOverlap(geometry1, geometry2)) {
|
|
11433
|
-
return unionForNonIntersecting(geometry1, geometry2);
|
|
11434
|
-
}
|
|
11435
|
-
const a = new Tree(geom33.toPolygons(geometry1));
|
|
11436
|
-
const b = new Tree(geom33.toPolygons(geometry2));
|
|
11437
|
-
a.clipTo(b, false);
|
|
11438
|
-
b.clipTo(a);
|
|
11439
|
-
b.invert();
|
|
11440
|
-
b.clipTo(a);
|
|
11441
|
-
b.invert();
|
|
11442
|
-
const newpolygons = a.allPolygons().concat(b.allPolygons());
|
|
11443
|
-
const result = geom33.create(newpolygons);
|
|
11444
|
-
return result;
|
|
11445
|
-
};
|
|
11446
|
-
var unionForNonIntersecting = (geometry1, geometry2) => {
|
|
11447
|
-
let newpolygons = geom33.toPolygons(geometry1);
|
|
11448
|
-
newpolygons = newpolygons.concat(geom33.toPolygons(geometry2));
|
|
11449
|
-
return geom33.create(newpolygons);
|
|
11450
|
-
};
|
|
11451
|
-
module.exports = unionSub;
|
|
11452
|
-
}
|
|
11453
|
-
});
|
|
11454
|
-
|
|
11455
|
-
// node_modules/@jscad/modeling/src/operations/booleans/unionGeom3.js
|
|
11456
|
-
var require_unionGeom3 = __commonJS({
|
|
11457
|
-
"node_modules/@jscad/modeling/src/operations/booleans/unionGeom3.js"(exports, module) {
|
|
11458
|
-
"use strict";
|
|
11459
|
-
var flatten = require_flatten();
|
|
11460
|
-
var retessellate = require_retessellate();
|
|
11461
|
-
var unionSub = require_unionGeom3Sub();
|
|
11462
|
-
var union = (...geometries) => {
|
|
11463
|
-
geometries = flatten(geometries);
|
|
11464
|
-
let i;
|
|
11465
|
-
for (i = 1; i < geometries.length; i += 2) {
|
|
11466
|
-
geometries.push(unionSub(geometries[i - 1], geometries[i]));
|
|
11467
|
-
}
|
|
11468
|
-
let newgeometry = geometries[i - 1];
|
|
11469
|
-
newgeometry = retessellate(newgeometry);
|
|
11470
|
-
return newgeometry;
|
|
11471
|
-
};
|
|
11472
|
-
module.exports = union;
|
|
11473
|
-
}
|
|
11474
|
-
});
|
|
11475
|
-
|
|
11476
11670
|
// node_modules/@jscad/modeling/src/operations/booleans/unionGeom2.js
|
|
11477
11671
|
var require_unionGeom2 = __commonJS({
|
|
11478
11672
|
"node_modules/@jscad/modeling/src/operations/booleans/unionGeom2.js"(exports, module) {
|
|
@@ -11483,14 +11677,14 @@ var require_unionGeom2 = __commonJS({
|
|
|
11483
11677
|
var fromFakePolygons = require_fromFakePolygons();
|
|
11484
11678
|
var to3DWalls = require_to3DWalls();
|
|
11485
11679
|
var unionGeom3 = require_unionGeom3();
|
|
11486
|
-
var
|
|
11680
|
+
var union3 = (...geometries) => {
|
|
11487
11681
|
geometries = flatten(geometries);
|
|
11488
11682
|
const newgeometries = geometries.map((geometry) => to3DWalls({ z0: -1, z1: 1 }, geometry));
|
|
11489
11683
|
const newgeom3 = unionGeom3(newgeometries);
|
|
11490
11684
|
const epsilon = measureEpsilon(newgeom3);
|
|
11491
11685
|
return fromFakePolygons(epsilon, geom33.toPolygons(newgeom3));
|
|
11492
11686
|
};
|
|
11493
|
-
module.exports =
|
|
11687
|
+
module.exports = union3;
|
|
11494
11688
|
}
|
|
11495
11689
|
});
|
|
11496
11690
|
|
|
@@ -11504,7 +11698,7 @@ var require_union = __commonJS({
|
|
|
11504
11698
|
var geom33 = require_geom3();
|
|
11505
11699
|
var unionGeom2 = require_unionGeom2();
|
|
11506
11700
|
var unionGeom3 = require_unionGeom3();
|
|
11507
|
-
var
|
|
11701
|
+
var union3 = (...geometries) => {
|
|
11508
11702
|
geometries = flatten(geometries);
|
|
11509
11703
|
if (geometries.length === 0) throw new Error("wrong number of arguments");
|
|
11510
11704
|
if (!areAllShapesTheSameType(geometries)) {
|
|
@@ -11515,7 +11709,7 @@ var require_union = __commonJS({
|
|
|
11515
11709
|
if (geom33.isA(geometry)) return unionGeom3(geometries);
|
|
11516
11710
|
return geometry;
|
|
11517
11711
|
};
|
|
11518
|
-
module.exports =
|
|
11712
|
+
module.exports = union3;
|
|
11519
11713
|
}
|
|
11520
11714
|
});
|
|
11521
11715
|
|
|
@@ -11525,6 +11719,7 @@ var require_booleans = __commonJS({
|
|
|
11525
11719
|
"use strict";
|
|
11526
11720
|
module.exports = {
|
|
11527
11721
|
intersect: require_intersect2(),
|
|
11722
|
+
minkowski: require_minkowskiSum(),
|
|
11528
11723
|
scission: require_scission(),
|
|
11529
11724
|
subtract: require_subtract4(),
|
|
11530
11725
|
union: require_union()
|
|
@@ -11905,7 +12100,7 @@ var require_expandGeom3 = __commonJS({
|
|
|
11905
12100
|
"node_modules/@jscad/modeling/src/operations/expansions/expandGeom3.js"(exports, module) {
|
|
11906
12101
|
"use strict";
|
|
11907
12102
|
var geom33 = require_geom3();
|
|
11908
|
-
var
|
|
12103
|
+
var union3 = require_union();
|
|
11909
12104
|
var expandShell = require_expandShell();
|
|
11910
12105
|
var expandGeom3 = (options, geometry) => {
|
|
11911
12106
|
const defaults = {
|
|
@@ -11921,7 +12116,7 @@ var require_expandGeom3 = __commonJS({
|
|
|
11921
12116
|
if (polygons.length === 0) throw new Error("the given geometry cannot be empty");
|
|
11922
12117
|
options = { delta, corners, segments };
|
|
11923
12118
|
const expanded = expandShell(options, geometry);
|
|
11924
|
-
return
|
|
12119
|
+
return union3(geometry, expanded);
|
|
11925
12120
|
};
|
|
11926
12121
|
module.exports = expandGeom3;
|
|
11927
12122
|
}
|
|
@@ -12564,24 +12759,6 @@ var require_hullGeom2 = __commonJS({
|
|
|
12564
12759
|
}
|
|
12565
12760
|
});
|
|
12566
12761
|
|
|
12567
|
-
// node_modules/@jscad/modeling/src/operations/hulls/hullPoints3.js
|
|
12568
|
-
var require_hullPoints3 = __commonJS({
|
|
12569
|
-
"node_modules/@jscad/modeling/src/operations/hulls/hullPoints3.js"(exports, module) {
|
|
12570
|
-
"use strict";
|
|
12571
|
-
var poly3 = require_poly3();
|
|
12572
|
-
var quickhull = require_quickhull();
|
|
12573
|
-
var hullPoints3 = (uniquePoints) => {
|
|
12574
|
-
const faces = quickhull(uniquePoints, { skipTriangulation: true });
|
|
12575
|
-
const polygons = faces.map((face) => {
|
|
12576
|
-
const vertices = face.map((index) => uniquePoints[index]);
|
|
12577
|
-
return poly3.create(vertices);
|
|
12578
|
-
});
|
|
12579
|
-
return polygons;
|
|
12580
|
-
};
|
|
12581
|
-
module.exports = hullPoints3;
|
|
12582
|
-
}
|
|
12583
|
-
});
|
|
12584
|
-
|
|
12585
12762
|
// node_modules/@jscad/modeling/src/operations/hulls/hullGeom3.js
|
|
12586
12763
|
var require_hullGeom3 = __commonJS({
|
|
12587
12764
|
"node_modules/@jscad/modeling/src/operations/hulls/hullGeom3.js"(exports, module) {
|
|
@@ -12633,7 +12810,7 @@ var require_hullChain = __commonJS({
|
|
|
12633
12810
|
"node_modules/@jscad/modeling/src/operations/hulls/hullChain.js"(exports, module) {
|
|
12634
12811
|
"use strict";
|
|
12635
12812
|
var flatten = require_flatten();
|
|
12636
|
-
var
|
|
12813
|
+
var union3 = require_union();
|
|
12637
12814
|
var hull = require_hull();
|
|
12638
12815
|
var hullChain = (...geometries) => {
|
|
12639
12816
|
geometries = flatten(geometries);
|
|
@@ -12642,7 +12819,7 @@ var require_hullChain = __commonJS({
|
|
|
12642
12819
|
for (let i = 1; i < geometries.length; i++) {
|
|
12643
12820
|
hulls.push(hull(geometries[i - 1], geometries[i]));
|
|
12644
12821
|
}
|
|
12645
|
-
return
|
|
12822
|
+
return union3(hulls);
|
|
12646
12823
|
};
|
|
12647
12824
|
module.exports = hullChain;
|
|
12648
12825
|
}
|
|
@@ -12661,6 +12838,16 @@ var require_hulls = __commonJS({
|
|
|
12661
12838
|
}
|
|
12662
12839
|
});
|
|
12663
12840
|
|
|
12841
|
+
// node_modules/@jscad/modeling/src/operations/minkowski/index.js
|
|
12842
|
+
var require_minkowski = __commonJS({
|
|
12843
|
+
"node_modules/@jscad/modeling/src/operations/minkowski/index.js"(exports, module) {
|
|
12844
|
+
"use strict";
|
|
12845
|
+
module.exports = {
|
|
12846
|
+
minkowskiSum: require_minkowskiSum()
|
|
12847
|
+
};
|
|
12848
|
+
}
|
|
12849
|
+
});
|
|
12850
|
+
|
|
12664
12851
|
// node_modules/@jscad/modeling/src/operations/modifiers/snapPolygons.js
|
|
12665
12852
|
var require_snapPolygons = __commonJS({
|
|
12666
12853
|
"node_modules/@jscad/modeling/src/operations/modifiers/snapPolygons.js"(exports, module) {
|
|
@@ -13502,6 +13689,7 @@ var require_src = __commonJS({
|
|
|
13502
13689
|
expansions: require_expansions(),
|
|
13503
13690
|
extrusions: require_extrusions(),
|
|
13504
13691
|
hulls: require_hulls(),
|
|
13692
|
+
minkowski: require_minkowski(),
|
|
13505
13693
|
modifiers: require_modifiers(),
|
|
13506
13694
|
transforms: require_transforms()
|
|
13507
13695
|
};
|
|
@@ -14613,7 +14801,20 @@ var occtModulePromise = null;
|
|
|
14613
14801
|
async function getOcctModule() {
|
|
14614
14802
|
if (!occtModulePromise) {
|
|
14615
14803
|
const occtimportjs = (await import("occt-import-js")).default;
|
|
14616
|
-
|
|
14804
|
+
const isBrowser = typeof window !== "undefined" || typeof self !== "undefined";
|
|
14805
|
+
if (isBrowser) {
|
|
14806
|
+
let wasmUrl;
|
|
14807
|
+
try {
|
|
14808
|
+
wasmUrl = (await import("occt-import-js/dist/occt-import-js.wasm?url")).default;
|
|
14809
|
+
} catch {
|
|
14810
|
+
wasmUrl = void 0;
|
|
14811
|
+
}
|
|
14812
|
+
occtModulePromise = occtimportjs({
|
|
14813
|
+
locateFile: (path) => path.endsWith(".wasm") && wasmUrl ? wasmUrl : path
|
|
14814
|
+
});
|
|
14815
|
+
} else {
|
|
14816
|
+
occtModulePromise = occtimportjs();
|
|
14817
|
+
}
|
|
14617
14818
|
}
|
|
14618
14819
|
return occtModulePromise;
|
|
14619
14820
|
}
|
|
@@ -15001,6 +15202,8 @@ var import_extrusions = __toESM(require_extrusions(), 1);
|
|
|
15001
15202
|
var import_primitives = __toESM(require_primitives(), 1);
|
|
15002
15203
|
var import_transforms = __toESM(require_transforms(), 1);
|
|
15003
15204
|
var DEFAULT_SEGMENTS = 64;
|
|
15205
|
+
var REDUCED_SEGMENTS = 16;
|
|
15206
|
+
var HOLE_COUNT_THRESHOLD = 50;
|
|
15004
15207
|
var toBoardSpaceVec2 = (point, center) => [point.x - center.x, -(point.y - center.y)];
|
|
15005
15208
|
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
15006
15209
|
var arePointsClockwise = (points) => {
|
|
@@ -15013,11 +15216,11 @@ var arePointsClockwise = (points) => {
|
|
|
15013
15216
|
const signedArea = area / 2;
|
|
15014
15217
|
return signedArea <= 0;
|
|
15015
15218
|
};
|
|
15016
|
-
var createCircularHole = (x, y, radius, thickness) => (0, import_primitives.cylinder)({
|
|
15219
|
+
var createCircularHole = (x, y, radius, thickness, segments = DEFAULT_SEGMENTS) => (0, import_primitives.cylinder)({
|
|
15017
15220
|
center: [x, y, 0],
|
|
15018
15221
|
height: thickness + 1,
|
|
15019
15222
|
radius,
|
|
15020
|
-
segments
|
|
15223
|
+
segments
|
|
15021
15224
|
});
|
|
15022
15225
|
var createCutoutGeoms = (boardCenter, thickness, cutouts = []) => {
|
|
15023
15226
|
const geoms = [];
|
|
@@ -15129,9 +15332,36 @@ var filterCutoutsForBoard = (cutouts, board) => {
|
|
|
15129
15332
|
var import_extrusions2 = __toESM(require_extrusions(), 1);
|
|
15130
15333
|
var import_primitives2 = __toESM(require_primitives(), 1);
|
|
15131
15334
|
var import_transforms2 = __toESM(require_transforms(), 1);
|
|
15132
|
-
var
|
|
15335
|
+
var import_booleans2 = __toESM(require_booleans(), 1);
|
|
15133
15336
|
var geom3 = __toESM(require_geom3(), 1);
|
|
15134
15337
|
var import_measureBoundingBox = __toESM(require_measureBoundingBox2(), 1);
|
|
15338
|
+
|
|
15339
|
+
// lib/utils/batched-union.ts
|
|
15340
|
+
var import_booleans = __toESM(require_booleans(), 1);
|
|
15341
|
+
var batchedUnion = (geoms, batchSize = 50) => {
|
|
15342
|
+
if (geoms.length === 0) {
|
|
15343
|
+
throw new Error("Cannot union empty array");
|
|
15344
|
+
}
|
|
15345
|
+
if (geoms.length === 1) {
|
|
15346
|
+
return geoms[0];
|
|
15347
|
+
}
|
|
15348
|
+
let results = [...geoms];
|
|
15349
|
+
while (results.length > 1) {
|
|
15350
|
+
const newResults = [];
|
|
15351
|
+
for (let i = 0; i < results.length; i += batchSize) {
|
|
15352
|
+
const batch = results.slice(i, i + batchSize);
|
|
15353
|
+
if (batch.length === 1) {
|
|
15354
|
+
newResults.push(batch[0]);
|
|
15355
|
+
} else {
|
|
15356
|
+
newResults.push((0, import_booleans.union)(...batch));
|
|
15357
|
+
}
|
|
15358
|
+
}
|
|
15359
|
+
results = newResults;
|
|
15360
|
+
}
|
|
15361
|
+
return results[0];
|
|
15362
|
+
};
|
|
15363
|
+
|
|
15364
|
+
// lib/utils/pcb-board-geometry.ts
|
|
15135
15365
|
var RADIUS_EPSILON = 1e-4;
|
|
15136
15366
|
var getNumberProperty = (obj, key) => {
|
|
15137
15367
|
const value = obj[key];
|
|
@@ -15157,14 +15387,14 @@ var createBoardOutlineGeom = (board, center, thickness) => {
|
|
|
15157
15387
|
geom = (0, import_transforms2.translate)([0, 0, -thickness / 2], geom);
|
|
15158
15388
|
return geom;
|
|
15159
15389
|
};
|
|
15160
|
-
var
|
|
15390
|
+
var createPillHoleWithSegments = (x, y, width, height, thickness, rotate, segments = DEFAULT_SEGMENTS) => {
|
|
15161
15391
|
const minDimension = Math.min(width, height);
|
|
15162
15392
|
const maxAllowedRadius = Math.max(0, minDimension / 2 - RADIUS_EPSILON);
|
|
15163
15393
|
const roundRadius = maxAllowedRadius <= 0 ? 0 : Math.min(height / 2, maxAllowedRadius);
|
|
15164
15394
|
const hole2d = (0, import_primitives2.roundedRectangle)({
|
|
15165
15395
|
size: [width, height],
|
|
15166
15396
|
roundRadius,
|
|
15167
|
-
segments
|
|
15397
|
+
segments
|
|
15168
15398
|
});
|
|
15169
15399
|
let hole3d = (0, import_extrusions2.extrudeLinear)({ height: thickness + 1 }, hole2d);
|
|
15170
15400
|
hole3d = (0, import_transforms2.translate)([0, 0, -(thickness + 1) / 2], hole3d);
|
|
@@ -15173,7 +15403,7 @@ var createPillHole = (x, y, width, height, thickness, rotate) => {
|
|
|
15173
15403
|
}
|
|
15174
15404
|
return (0, import_transforms2.translate)([x, y, 0], hole3d);
|
|
15175
15405
|
};
|
|
15176
|
-
var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) => {
|
|
15406
|
+
var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = [], segments = DEFAULT_SEGMENTS) => {
|
|
15177
15407
|
const holeGeoms = [];
|
|
15178
15408
|
for (const hole of holes) {
|
|
15179
15409
|
const holeRecord = hole;
|
|
@@ -15187,13 +15417,14 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
|
|
|
15187
15417
|
const rotate = holeHeight > holeWidth;
|
|
15188
15418
|
const width = rotate ? holeHeight : holeWidth;
|
|
15189
15419
|
const height = rotate ? holeWidth : holeHeight;
|
|
15190
|
-
const pillHole =
|
|
15420
|
+
const pillHole = createPillHoleWithSegments(
|
|
15191
15421
|
relX,
|
|
15192
15422
|
relY,
|
|
15193
15423
|
width,
|
|
15194
15424
|
height,
|
|
15195
15425
|
thickness,
|
|
15196
|
-
rotate
|
|
15426
|
+
rotate,
|
|
15427
|
+
segments
|
|
15197
15428
|
);
|
|
15198
15429
|
holeGeoms.push(pillHole);
|
|
15199
15430
|
continue;
|
|
@@ -15210,7 +15441,7 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
|
|
|
15210
15441
|
const hole2d = (0, import_primitives2.roundedRectangle)({
|
|
15211
15442
|
size: [holeWidth, holeHeight],
|
|
15212
15443
|
roundRadius,
|
|
15213
|
-
segments
|
|
15444
|
+
segments
|
|
15214
15445
|
});
|
|
15215
15446
|
let hole3d = (0, import_extrusions2.extrudeLinear)({ height: thickness + 1 }, hole2d);
|
|
15216
15447
|
hole3d = (0, import_transforms2.translate)([0, 0, -(thickness + 1) / 2], hole3d);
|
|
@@ -15224,7 +15455,7 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
|
|
|
15224
15455
|
const diameter = getNumberProperty(holeRecord, "hole_diameter") ?? getNumberProperty(holeRecord, "diameter");
|
|
15225
15456
|
if (!diameter) continue;
|
|
15226
15457
|
const radius = diameter / 2;
|
|
15227
|
-
holeGeoms.push(createCircularHole(relX, relY, radius, thickness));
|
|
15458
|
+
holeGeoms.push(createCircularHole(relX, relY, radius, thickness, segments));
|
|
15228
15459
|
}
|
|
15229
15460
|
for (const plated of platedHoles) {
|
|
15230
15461
|
const platedRecord = plated;
|
|
@@ -15240,13 +15471,23 @@ var createHoleGeoms = (boardCenter, thickness, holes = [], platedHoles = []) =>
|
|
|
15240
15471
|
const width = rotate ? holeHeight : holeWidth;
|
|
15241
15472
|
const height = rotate ? holeWidth : holeHeight;
|
|
15242
15473
|
holeGeoms.push(
|
|
15243
|
-
|
|
15474
|
+
createPillHoleWithSegments(
|
|
15475
|
+
relX,
|
|
15476
|
+
relY,
|
|
15477
|
+
width,
|
|
15478
|
+
height,
|
|
15479
|
+
thickness,
|
|
15480
|
+
rotate,
|
|
15481
|
+
segments
|
|
15482
|
+
)
|
|
15244
15483
|
);
|
|
15245
15484
|
continue;
|
|
15246
15485
|
}
|
|
15247
15486
|
const diameter = getNumberProperty(platedRecord, "hole_diameter") ?? getNumberProperty(platedRecord, "outer_diameter");
|
|
15248
15487
|
if (!diameter) continue;
|
|
15249
|
-
holeGeoms.push(
|
|
15488
|
+
holeGeoms.push(
|
|
15489
|
+
createCircularHole(relX, relY, diameter / 2, thickness, segments)
|
|
15490
|
+
);
|
|
15250
15491
|
}
|
|
15251
15492
|
return holeGeoms;
|
|
15252
15493
|
};
|
|
@@ -15302,11 +15543,21 @@ var createBoardMesh = (board, options) => {
|
|
|
15302
15543
|
const { thickness, holes = [], platedHoles = [], cutouts = [] } = options;
|
|
15303
15544
|
const center = board.center ?? { x: 0, y: 0 };
|
|
15304
15545
|
let boardGeom = createBoardOutlineGeom(board, center, thickness);
|
|
15305
|
-
const
|
|
15546
|
+
const totalHoleCount = holes.length + platedHoles.length;
|
|
15547
|
+
const useReducedSegments = totalHoleCount > HOLE_COUNT_THRESHOLD;
|
|
15548
|
+
const segments = useReducedSegments ? REDUCED_SEGMENTS : DEFAULT_SEGMENTS;
|
|
15549
|
+
const holeGeoms = createHoleGeoms(
|
|
15550
|
+
center,
|
|
15551
|
+
thickness,
|
|
15552
|
+
holes,
|
|
15553
|
+
platedHoles,
|
|
15554
|
+
segments
|
|
15555
|
+
);
|
|
15306
15556
|
const cutoutGeoms = createCutoutGeoms(center, thickness, cutouts);
|
|
15307
15557
|
const subtractGeoms = [...holeGeoms, ...cutoutGeoms];
|
|
15308
15558
|
if (subtractGeoms.length > 0) {
|
|
15309
|
-
|
|
15559
|
+
const unifiedHoles = batchedUnion(subtractGeoms);
|
|
15560
|
+
boardGeom = (0, import_booleans2.subtract)(boardGeom, unifiedHoles);
|
|
15310
15561
|
}
|
|
15311
15562
|
boardGeom = (0, import_transforms2.rotateX)(-Math.PI / 2, boardGeom);
|
|
15312
15563
|
const polygons = geom3.toPolygons(boardGeom);
|
|
@@ -15321,7 +15572,7 @@ var createBoardMesh = (board, options) => {
|
|
|
15321
15572
|
|
|
15322
15573
|
// lib/utils/pcb-panel-geometry.ts
|
|
15323
15574
|
var import_transforms3 = __toESM(require_transforms(), 1);
|
|
15324
|
-
var
|
|
15575
|
+
var import_booleans3 = __toESM(require_booleans(), 1);
|
|
15325
15576
|
var geom32 = __toESM(require_geom3(), 1);
|
|
15326
15577
|
var import_measureBoundingBox2 = __toESM(require_measureBoundingBox2(), 1);
|
|
15327
15578
|
var createPanelMesh = (panel, options) => {
|
|
@@ -15332,7 +15583,7 @@ var createPanelMesh = (panel, options) => {
|
|
|
15332
15583
|
const cutoutGeoms = createCutoutGeoms(center, thickness, cutouts);
|
|
15333
15584
|
const subtractGeoms = [...holeGeoms, ...cutoutGeoms];
|
|
15334
15585
|
if (subtractGeoms.length > 0) {
|
|
15335
|
-
panelGeom = (0,
|
|
15586
|
+
panelGeom = (0, import_booleans3.subtract)(panelGeom, ...subtractGeoms);
|
|
15336
15587
|
}
|
|
15337
15588
|
panelGeom = (0, import_transforms3.rotateX)(-Math.PI / 2, panelGeom);
|
|
15338
15589
|
const polygons = geom32.toPolygons(panelGeom);
|
package/package.json
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
"name": "circuit-json-to-gltf",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.74",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "bun test tests/",
|
|
8
|
+
"test:playwright": "playwright test",
|
|
8
9
|
"format": "biome format --write .",
|
|
9
10
|
"format:check": "biome format .",
|
|
10
11
|
"build:site": "cosmos-export",
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@biomejs/biome": "^2.1.4",
|
|
27
|
+
"@playwright/test": "^1.58.2",
|
|
26
28
|
"@google/model-viewer": "^4.1.0",
|
|
27
29
|
"@resvg/resvg-js": "^2.6.2",
|
|
28
30
|
"@resvg/resvg-wasm": "^2.6.2",
|