brepjs 8.2.0 → 8.3.0

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 (45) hide show
  1. package/dist/2d.cjs +2 -2
  2. package/dist/2d.js +3 -3
  3. package/dist/{Blueprint-D_luVeES.js → Blueprint-CdVaHDSx.js} +3 -2
  4. package/dist/{Blueprint-CTAwjJMN.cjs → Blueprint-a3ukJMG4.cjs} +4 -3
  5. package/dist/{boolean2D-vw76Gayn.js → boolean2D-DzA0STqC.js} +3 -3
  6. package/dist/{boolean2D-B5axNhjN.cjs → boolean2D-pvPIs21j.cjs} +3 -3
  7. package/dist/{booleanFns-BhqXpQoZ.js → booleanFns-BcQUqjUu.js} +42 -5
  8. package/dist/{booleanFns-Yc3EBxdm.cjs → booleanFns-Cd414V3l.cjs} +42 -5
  9. package/dist/brepjs.cjs +189 -100
  10. package/dist/brepjs.js +255 -165
  11. package/dist/{cornerFinder-DuStF5jK.cjs → cornerFinder-BdKtobgb.cjs} +1 -1
  12. package/dist/{cornerFinder-CPm2baSJ.js → cornerFinder-DvPiz-VR.js} +1 -1
  13. package/dist/curveFns-B5EQsSwv.cjs +177 -0
  14. package/dist/curveFns-CyHyk29c.js +178 -0
  15. package/dist/{drawFns-CzBbcoXA.js → drawFns-CAAE4Z88.js} +6 -5
  16. package/dist/{drawFns-CiNxPu6J.cjs → drawFns-Mr2pghU8.cjs} +9 -8
  17. package/dist/{helpers-Dje6wrKi.cjs → helpers-CP2KrBZl.cjs} +4 -4
  18. package/dist/{helpers-BSQfs538.js → helpers-r_e-u1JM.js} +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/io.cjs +2 -2
  22. package/dist/io.js +2 -2
  23. package/dist/{meshFns-BKSPaPXS.js → meshFns-BEvGVcym.js} +4 -1
  24. package/dist/{meshFns-CFVxKBlE.cjs → meshFns-CJV_k_EQ.cjs} +4 -1
  25. package/dist/{operations-CjQHEu1h.js → operations-B314mytX.js} +1 -1
  26. package/dist/{operations-CdGb6IBU.cjs → operations-CYGNxn5D.cjs} +1 -1
  27. package/dist/operations.cjs +1 -1
  28. package/dist/operations.js +1 -1
  29. package/dist/query.cjs +3 -3
  30. package/dist/query.js +4 -4
  31. package/dist/{curveFns-C5gSZ5EY.js → shapeFns-CWd_ASDV.js} +115 -194
  32. package/dist/{curveFns-ByeCqutv.cjs → shapeFns-Z_ScEjmn.cjs} +94 -173
  33. package/dist/sketching.cjs +2 -2
  34. package/dist/sketching.js +2 -2
  35. package/dist/topology/booleanFns.d.ts.map +1 -1
  36. package/dist/topology/meshFns.d.ts +1 -0
  37. package/dist/topology/meshFns.d.ts.map +1 -1
  38. package/dist/topology/modifierFns.d.ts.map +1 -1
  39. package/dist/topology/shapeFns.d.ts +30 -0
  40. package/dist/topology/shapeFns.d.ts.map +1 -1
  41. package/dist/{topology-D8Au8q4i.cjs → topology-A7-jUtHB.cjs} +9 -8
  42. package/dist/{topology-BFB3LI_y.js → topology-BupialMm.js} +4 -3
  43. package/dist/topology.cjs +32 -31
  44. package/dist/topology.js +57 -56
  45. package/package.json +1 -1
package/dist/brepjs.cjs CHANGED
@@ -4,26 +4,27 @@ const occtBoundary = require("./occtBoundary-BFAaUtA7.cjs");
4
4
  const errors = require("./errors-DK1VAdP4.cjs");
5
5
  const shapeTypes = require("./shapeTypes-UqVCIO_T.cjs");
6
6
  const vecOps = require("./vecOps-CjRL1jau.cjs");
7
- const Blueprint = require("./Blueprint-CTAwjJMN.cjs");
8
- const curveFns = require("./curveFns-ByeCqutv.cjs");
7
+ const Blueprint = require("./Blueprint-a3ukJMG4.cjs");
8
+ const curveFns = require("./curveFns-B5EQsSwv.cjs");
9
9
  const loft$2 = require("./loft-PMRx9iMG.cjs");
10
- const operations = require("./operations-CdGb6IBU.cjs");
11
- const boolean2D = require("./boolean2D-B5axNhjN.cjs");
10
+ const operations = require("./operations-CYGNxn5D.cjs");
11
+ const boolean2D = require("./boolean2D-pvPIs21j.cjs");
12
12
  const _2d = require("./2d.cjs");
13
- const helpers = require("./helpers-Dje6wrKi.cjs");
13
+ const helpers = require("./helpers-CP2KrBZl.cjs");
14
14
  const io = require("./io.cjs");
15
- const drawFns = require("./drawFns-CiNxPu6J.cjs");
15
+ const drawFns = require("./drawFns-Mr2pghU8.cjs");
16
16
  const vectors = require("./vectors-t1XG4LpL.cjs");
17
- const topology = require("./topology-D8Au8q4i.cjs");
17
+ const shapeFns = require("./shapeFns-Z_ScEjmn.cjs");
18
+ const topology = require("./topology-A7-jUtHB.cjs");
18
19
  const faceFns = require("./faceFns-D1Sqnlu6.cjs");
19
- const meshFns = require("./meshFns-CFVxKBlE.cjs");
20
- const booleanFns = require("./booleanFns-Yc3EBxdm.cjs");
20
+ const meshFns = require("./meshFns-CJV_k_EQ.cjs");
21
+ const booleanFns = require("./booleanFns-Cd414V3l.cjs");
21
22
  const measurement = require("./measurement-B06hNs89.cjs");
22
23
  const curveBuilders = require("./curveBuilders-Du03_Yyf.cjs");
23
24
  const cast = require("./cast-C107o5ow.cjs");
24
25
  const query = require("./query.cjs");
25
26
  const result = require("./result.cjs");
26
- const cornerFinder = require("./cornerFinder-DuStF5jK.cjs");
27
+ const cornerFinder = require("./cornerFinder-BdKtobgb.cjs");
27
28
  const worker = require("./worker.cjs");
28
29
  const errorFactories = {
29
30
  OCCT_OPERATION: (code, message, cause) => ({ kind: "OCCT_OPERATION", code, message, cause }),
@@ -97,9 +98,9 @@ function withNearestPostFilter(baseFinder, nearestPoint) {
97
98
  const candidates = baseFinder.findAll(shape2);
98
99
  if (candidates.length === 0) return [];
99
100
  let bestIdx = 0;
100
- let bestDist = vecOps.vecDistance(curveFns.vertexPosition(candidates[0]), nearestPoint);
101
+ let bestDist = vecOps.vecDistance(shapeFns.vertexPosition(candidates[0]), nearestPoint);
101
102
  for (let i = 1; i < candidates.length; i++) {
102
- const d = vecOps.vecDistance(curveFns.vertexPosition(candidates[i]), nearestPoint);
103
+ const d = vecOps.vecDistance(shapeFns.vertexPosition(candidates[i]), nearestPoint);
103
104
  if (d < bestDist) {
104
105
  bestDist = d;
105
106
  bestIdx = i;
@@ -129,13 +130,13 @@ function buildVertexFinder(filters) {
129
130
  buildVertexFinder,
130
131
  (_base, withFilter) => ({
131
132
  nearestTo: (point) => withNearestPostFilter(buildVertexFinder(filters), point),
132
- atPosition: (point, tolerance = 1e-4) => withFilter((vertex2) => vecOps.vecDistance(curveFns.vertexPosition(vertex2), point) < tolerance),
133
+ atPosition: (point, tolerance = 1e-4) => withFilter((vertex2) => vecOps.vecDistance(shapeFns.vertexPosition(vertex2), point) < tolerance),
133
134
  withinBox: (min, max) => withFilter((vertex2) => {
134
- const pos = curveFns.vertexPosition(vertex2);
135
+ const pos = shapeFns.vertexPosition(vertex2);
135
136
  return pos[0] >= min[0] - 1e-6 && pos[0] <= max[0] + 1e-6 && pos[1] >= min[1] - 1e-6 && pos[1] <= max[1] + 1e-6 && pos[2] >= min[2] - 1e-6 && pos[2] <= max[2] + 1e-6;
136
137
  }),
137
138
  atDistance: (distance, point = [0, 0, 0], tolerance = 1e-4) => withFilter((vertex2) => {
138
- const pos = curveFns.vertexPosition(vertex2);
139
+ const pos = shapeFns.vertexPosition(vertex2);
139
140
  return Math.abs(vecOps.vecDistance(pos, point) - distance) < tolerance;
140
141
  })
141
142
  })
@@ -197,7 +198,7 @@ function box(width, depth, height, options) {
197
198
  const solid2 = shapeTypes.createSolid(maker.Solid());
198
199
  const center = options?.at ?? (options?.centered ? [0, 0, 0] : void 0);
199
200
  if (center) {
200
- return curveFns.translate(solid2, [center[0] - width / 2, center[1] - depth / 2, center[2] - height / 2]);
201
+ return shapeFns.translate(solid2, [center[0] - width / 2, center[1] - depth / 2, center[2] - height / 2]);
201
202
  }
202
203
  return solid2;
203
204
  }
@@ -211,14 +212,14 @@ function cylinder(radius, height, options) {
211
212
  -axis[1] * height * 0.5,
212
213
  -axis[2] * height * 0.5
213
214
  ];
214
- solid2 = curveFns.translate(solid2, halfShift);
215
+ solid2 = shapeFns.translate(solid2, halfShift);
215
216
  }
216
217
  return solid2;
217
218
  }
218
219
  function sphere(radius, options) {
219
220
  let solid2 = loft$2.makeSphere(radius);
220
221
  if (options?.at) {
221
- solid2 = curveFns.translate(solid2, options.at);
222
+ solid2 = shapeFns.translate(solid2, options.at);
222
223
  }
223
224
  return solid2;
224
225
  }
@@ -232,7 +233,7 @@ function cone(bottomRadius, topRadius, height, options) {
232
233
  -axis[1] * height * 0.5,
233
234
  -axis[2] * height * 0.5
234
235
  ];
235
- solid2 = curveFns.translate(solid2, halfShift);
236
+ solid2 = shapeFns.translate(solid2, halfShift);
236
237
  }
237
238
  return solid2;
238
239
  }
@@ -242,7 +243,7 @@ function torus(majorRadius, minorRadius, options) {
242
243
  function ellipsoid(rx, ry, rz, options) {
243
244
  let solid2 = loft$2.makeEllipsoid(rx, ry, rz);
244
245
  if (options?.at) {
245
- solid2 = curveFns.translate(solid2, options.at);
246
+ solid2 = shapeFns.translate(solid2, options.at);
246
247
  }
247
248
  return solid2;
248
249
  }
@@ -333,11 +334,21 @@ function validateNotNull(shape2, label) {
333
334
  function thicken$1(shape2, thickness) {
334
335
  const check = validateNotNull(shape2, "thicken: shape");
335
336
  if (errors.isErr(check)) return check;
336
- return kernelCall(
337
- () => occtBoundary.getKernel().thicken(shape2.wrapped, thickness),
338
- "THICKEN_FAILED",
339
- "Thicken operation failed"
340
- );
337
+ try {
338
+ const oc = occtBoundary.getKernel().oc;
339
+ const r = shapeTypes.gcWithScope();
340
+ const builder = r(new oc.BRepOffsetAPI_MakeThickSolid());
341
+ builder.MakeThickSolidBySimple(shape2.wrapped, thickness);
342
+ const progress = r(new oc.Message_ProgressRange_1());
343
+ builder.Build(progress);
344
+ const resultOc = builder.Shape();
345
+ const cast2 = shapeTypes.castShape(resultOc);
346
+ shapeFns.propagateOrigins(builder, [shape2], cast2);
347
+ return errors.ok(cast2);
348
+ } catch (e) {
349
+ const raw = e instanceof Error ? e.message : String(e);
350
+ return errors.err(errors.occtError("THICKEN_FAILED", `Thicken operation failed: ${raw}`, e));
351
+ }
341
352
  }
342
353
  function fillet$1(shape2, edges, radius) {
343
354
  const check = validateNotNull(shape2, "fillet: shape");
@@ -364,7 +375,7 @@ function fillet$1(shape2, edges, radius) {
364
375
  )
365
376
  );
366
377
  }
367
- const selectedEdges = edges ?? curveFns.getEdges(shape2);
378
+ const selectedEdges = edges ?? shapeFns.getEdges(shape2);
368
379
  if (selectedEdges.length === 0) {
369
380
  return errors.err(
370
381
  errors.validationError(
@@ -377,23 +388,26 @@ function fillet$1(shape2, edges, radius) {
377
388
  );
378
389
  }
379
390
  try {
380
- const kernel = occtBoundary.getKernel();
381
- const kernelRadius = typeof radius === "function" ? (
382
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- kernel expects OcShape callback
383
- ((ocEdge) => {
384
- const edgeWrapped = shapeTypes.castShape(ocEdge);
385
- return radius(edgeWrapped) ?? 0;
386
- })
387
- ) : radius;
388
- const result2 = kernel.fillet(
389
- shape2.wrapped,
390
- selectedEdges.map((e) => e.wrapped),
391
- kernelRadius
391
+ const oc = occtBoundary.getKernel().oc;
392
+ const r = shapeTypes.gcWithScope();
393
+ const builder = r(
394
+ new oc.BRepFilletAPI_MakeFillet(shape2.wrapped, oc.ChFi3d_FilletShape.ChFi3d_Rational)
392
395
  );
393
- const cast2 = shapeTypes.castShape(result2);
396
+ for (const edge of selectedEdges) {
397
+ const rad = typeof radius === "function" ? radius(edge) ?? 0 : radius;
398
+ if (typeof rad === "number") {
399
+ if (rad > 0) builder.Add_2(rad, edge.wrapped);
400
+ } else {
401
+ const [r1, r2] = rad;
402
+ if (r1 > 0 && r2 > 0) builder.Add_3(r1, r2, edge.wrapped);
403
+ }
404
+ }
405
+ const resultOc = builder.Shape();
406
+ const cast2 = shapeTypes.castShape(resultOc);
394
407
  if (!shapeTypes.isShape3D(cast2)) {
395
408
  return errors.err(errors.occtError("FILLET_RESULT_NOT_3D", "Fillet result is not a 3D shape"));
396
409
  }
410
+ shapeFns.propagateOrigins(builder, [shape2], cast2);
397
411
  return errors.ok(cast2);
398
412
  } catch (e) {
399
413
  const raw = e instanceof Error ? e.message : String(e);
@@ -431,28 +445,63 @@ function chamfer$1(shape2, edges, distance) {
431
445
  )
432
446
  );
433
447
  }
434
- const selectedEdges = edges ?? curveFns.getEdges(shape2);
448
+ const selectedEdges = edges ?? shapeFns.getEdges(shape2);
435
449
  if (selectedEdges.length === 0) {
436
450
  return errors.err(errors.validationError("NO_EDGES", "No edges found for chamfer"));
437
451
  }
438
452
  try {
439
- const kernel = occtBoundary.getKernel();
440
- const kernelDistance = typeof distance === "function" ? (
441
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- kernel expects OcShape callback
442
- ((ocEdge) => {
443
- const edgeWrapped = shapeTypes.castShape(ocEdge);
444
- return distance(edgeWrapped) ?? 0;
445
- })
446
- ) : distance;
447
- const result2 = kernel.chamfer(
448
- shape2.wrapped,
449
- selectedEdges.map((e) => e.wrapped),
450
- kernelDistance
451
- );
452
- const cast2 = shapeTypes.castShape(result2);
453
+ let getEdgeFaceMap = function() {
454
+ if (edgeFaceMap) return edgeFaceMap;
455
+ edgeFaceMap = /* @__PURE__ */ new Map();
456
+ const faceExp = new oc.TopExp_Explorer_2(
457
+ shape2.wrapped,
458
+ oc.TopAbs_ShapeEnum.TopAbs_FACE,
459
+ oc.TopAbs_ShapeEnum.TopAbs_SHAPE
460
+ );
461
+ while (faceExp.More()) {
462
+ const face2 = oc.TopoDS.Face_1(faceExp.Current());
463
+ const edgeExp = new oc.TopExp_Explorer_2(
464
+ face2,
465
+ oc.TopAbs_ShapeEnum.TopAbs_EDGE,
466
+ oc.TopAbs_ShapeEnum.TopAbs_SHAPE
467
+ );
468
+ while (edgeExp.More()) {
469
+ const hash = edgeExp.Current().HashCode(2147483647);
470
+ if (!edgeFaceMap.has(hash)) {
471
+ edgeFaceMap.set(hash, face2);
472
+ }
473
+ edgeExp.Next();
474
+ }
475
+ edgeExp.delete();
476
+ faceExp.Next();
477
+ }
478
+ faceExp.delete();
479
+ return edgeFaceMap;
480
+ };
481
+ const oc = occtBoundary.getKernel().oc;
482
+ const r = shapeTypes.gcWithScope();
483
+ const builder = r(new oc.BRepFilletAPI_MakeChamfer(shape2.wrapped));
484
+ let edgeFaceMap = null;
485
+ for (const edge of selectedEdges) {
486
+ const d = typeof distance === "function" ? distance(edge) ?? 0 : distance;
487
+ if (typeof d === "number") {
488
+ if (d > 0) builder.Add_2(d, edge.wrapped);
489
+ } else {
490
+ const [d1, d2] = d;
491
+ if (d1 > 0 && d2 > 0) {
492
+ const face2 = getEdgeFaceMap().get(edge.wrapped.HashCode(2147483647));
493
+ if (face2) {
494
+ builder.Add_3(d1, d2, oc.TopoDS.Edge_1(edge.wrapped), face2);
495
+ }
496
+ }
497
+ }
498
+ }
499
+ const resultOc = builder.Shape();
500
+ const cast2 = shapeTypes.castShape(resultOc);
453
501
  if (!shapeTypes.isShape3D(cast2)) {
454
502
  return errors.err(errors.occtError("CHAMFER_RESULT_NOT_3D", "Chamfer result is not a 3D shape"));
455
503
  }
504
+ shapeFns.propagateOrigins(builder, [shape2], cast2);
456
505
  return errors.ok(cast2);
457
506
  } catch (e) {
458
507
  const raw = e instanceof Error ? e.message : String(e);
@@ -475,16 +524,32 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
475
524
  return errors.err(errors.validationError("NO_FACES", "At least one face must be specified for shell"));
476
525
  }
477
526
  try {
478
- const result2 = occtBoundary.getKernel().shell(
527
+ const oc = occtBoundary.getKernel().oc;
528
+ const r = shapeTypes.gcWithScope();
529
+ const facesToRemove = r(new oc.TopTools_ListOfShape_1());
530
+ for (const face2 of faces) {
531
+ facesToRemove.Append_1(face2.wrapped);
532
+ }
533
+ const progress = r(new oc.Message_ProgressRange_1());
534
+ const builder = r(new oc.BRepOffsetAPI_MakeThickSolid());
535
+ builder.MakeThickSolidByJoin(
479
536
  shape2.wrapped,
480
- faces.map((f) => f.wrapped),
481
- thickness,
482
- tolerance
537
+ facesToRemove,
538
+ -thickness,
539
+ tolerance,
540
+ oc.BRepOffset_Mode.BRepOffset_Skin,
541
+ false,
542
+ false,
543
+ oc.GeomAbs_JoinType.GeomAbs_Arc,
544
+ false,
545
+ progress
483
546
  );
484
- const cast2 = shapeTypes.castShape(result2);
547
+ const resultOc = builder.Shape();
548
+ const cast2 = shapeTypes.castShape(resultOc);
485
549
  if (!shapeTypes.isShape3D(cast2)) {
486
550
  return errors.err(errors.occtError("SHELL_RESULT_NOT_3D", "Shell result is not a 3D shape"));
487
551
  }
552
+ shapeFns.propagateOrigins(builder, [shape2], cast2);
488
553
  return errors.ok(cast2);
489
554
  } catch (e) {
490
555
  const raw = e instanceof Error ? e.message : String(e);
@@ -503,34 +568,56 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
503
568
  if (distance === 0) {
504
569
  return errors.err(errors.validationError("ZERO_OFFSET", "Offset distance cannot be zero"));
505
570
  }
506
- return kernelCall(
507
- () => occtBoundary.getKernel().offset(shape2.wrapped, distance, tolerance),
508
- "OFFSET_FAILED",
509
- "Offset operation failed"
510
- );
571
+ try {
572
+ const oc = occtBoundary.getKernel().oc;
573
+ const r = shapeTypes.gcWithScope();
574
+ const progress = r(new oc.Message_ProgressRange_1());
575
+ const builder = r(new oc.BRepOffsetAPI_MakeOffsetShape());
576
+ builder.PerformByJoin(
577
+ shape2.wrapped,
578
+ distance,
579
+ tolerance,
580
+ oc.BRepOffset_Mode.BRepOffset_Skin,
581
+ false,
582
+ false,
583
+ oc.GeomAbs_JoinType.GeomAbs_Arc,
584
+ false,
585
+ progress
586
+ );
587
+ const resultOc = builder.Shape();
588
+ const cast2 = shapeTypes.castShape(resultOc);
589
+ if (!shapeTypes.isShape3D(cast2)) {
590
+ return errors.err(errors.occtError("OFFSET_RESULT_NOT_3D", "Offset result is not a 3D shape"));
591
+ }
592
+ shapeFns.propagateOrigins(builder, [shape2], cast2);
593
+ return errors.ok(cast2);
594
+ } catch (e) {
595
+ const raw = e instanceof Error ? e.message : String(e);
596
+ return errors.err(errors.occtError("OFFSET_FAILED", `Offset operation failed: ${raw}`, e));
597
+ }
511
598
  }
512
599
  function translate(shape2, v) {
513
- return curveFns.translate(resolve(shape2), v);
600
+ return shapeFns.translate(resolve(shape2), v);
514
601
  }
515
602
  function rotate(shape2, angle, options) {
516
603
  const pivotPoint = options?.at;
517
- return curveFns.rotate(resolve(shape2), angle, pivotPoint, options?.axis);
604
+ return shapeFns.rotate(resolve(shape2), angle, pivotPoint, options?.axis);
518
605
  }
519
606
  function mirror(shape2, options) {
520
607
  const planeOrigin = options?.at;
521
- return curveFns.mirror(resolve(shape2), options?.normal ?? [1, 0, 0], planeOrigin);
608
+ return shapeFns.mirror(resolve(shape2), options?.normal ?? [1, 0, 0], planeOrigin);
522
609
  }
523
610
  function scale(shape2, factor, options) {
524
- return curveFns.scale(resolve(shape2), factor, options?.center);
611
+ return shapeFns.scale(resolve(shape2), factor, options?.center);
525
612
  }
526
613
  function clone(shape2) {
527
- return curveFns.clone(resolve(shape2));
614
+ return shapeFns.clone(resolve(shape2));
528
615
  }
529
616
  function applyMatrix(shape2, matrix) {
530
- return curveFns.applyMatrix(resolve(shape2), matrix);
617
+ return shapeFns.applyMatrix(resolve(shape2), matrix);
531
618
  }
532
619
  function transformCopy(shape2, composed) {
533
- return curveFns.transformCopy(resolve(shape2), composed);
620
+ return shapeFns.transformCopy(resolve(shape2), composed);
534
621
  }
535
622
  function fuse(a, b, options) {
536
623
  return booleanFns.fuse(resolve(a), resolve(b), options);
@@ -613,7 +700,7 @@ function chamfer(shape2, edgesOrDistance, maybeDistance) {
613
700
  }
614
701
  const normalized = normalizeChamferDistance(distance);
615
702
  if (normalized.mode === "distAngle") {
616
- const selectedEdges = edges ?? curveFns.getEdges(s);
703
+ const selectedEdges = edges ?? shapeFns.getEdges(s);
617
704
  return topology.chamferDistAngle(
618
705
  s,
619
706
  [...selectedEdges],
@@ -638,7 +725,7 @@ function heal(shape2) {
638
725
  return topology.heal(resolve(shape2));
639
726
  }
640
727
  function simplify(shape2) {
641
- return curveFns.simplify(resolve(shape2));
728
+ return shapeFns.simplify(resolve(shape2));
642
729
  }
643
730
  function mesh(shape2, options) {
644
731
  return meshFns.mesh(resolve(shape2), options);
@@ -647,10 +734,10 @@ function meshEdges(shape2, options) {
647
734
  return meshFns.meshEdges(resolve(shape2), options);
648
735
  }
649
736
  function describe(shape2) {
650
- return curveFns.describe(resolve(shape2));
737
+ return shapeFns.describe(resolve(shape2));
651
738
  }
652
739
  function toBREP(shape2) {
653
- return curveFns.toBREP(resolve(shape2));
740
+ return shapeFns.toBREP(resolve(shape2));
654
741
  }
655
742
  function fromBREP(data) {
656
743
  return cast.fromBREP(data);
@@ -659,7 +746,7 @@ function isValid(shape2) {
659
746
  return topology.isValid(resolve(shape2));
660
747
  }
661
748
  function isEmpty(shape2) {
662
- return curveFns.isEmpty(resolve(shape2));
749
+ return shapeFns.isEmpty(resolve(shape2));
663
750
  }
664
751
  function loft$1(wires, { ruled = true, startPoint, endPoint } = {}, returnShell = false) {
665
752
  if (wires.length === 0 && !startPoint && !endPoint) {
@@ -712,7 +799,7 @@ function loft(wires, options) {
712
799
  }
713
800
  function resolveTargetFace(shape2, faceSpec) {
714
801
  if (faceSpec === void 0) {
715
- const faces = curveFns.getFaces(shape2);
802
+ const faces = shapeFns.getFaces(shape2);
716
803
  if (faces.length === 0) {
717
804
  throw new Error("compoundOps: shape has no faces");
718
805
  }
@@ -758,7 +845,7 @@ function drill(shape2, options) {
758
845
  const pos = at.length === 2 ? [at[0], at[1], 0] : [at[0], at[1], at[2]];
759
846
  let depth = options.depth;
760
847
  if (depth === void 0) {
761
- const b = curveFns.getBounds(s);
848
+ const b = shapeFns.getBounds(s);
762
849
  const dx = b.xMax - b.xMin;
763
850
  const dy = b.yMax - b.yMin;
764
851
  const dz = b.zMax - b.zMin;
@@ -766,7 +853,7 @@ function drill(shape2, options) {
766
853
  }
767
854
  const cyl = loft$2.makeCylinder(radius, depth, pos, dir);
768
855
  const startOffset = options.depth === void 0 ? vecOps.vecScale(dir, -depth / 2) : [0, 0, 0];
769
- const tool = startOffset[0] !== 0 || startOffset[1] !== 0 || startOffset[2] !== 0 ? curveFns.translate(cyl, startOffset) : cyl;
856
+ const tool = startOffset[0] !== 0 || startOffset[1] !== 0 || startOffset[2] !== 0 ? shapeFns.translate(cyl, startOffset) : cyl;
770
857
  return booleanFns.cut(s, tool);
771
858
  }
772
859
  function pocket(shape2, options) {
@@ -805,7 +892,7 @@ function mirrorJoin(shape2, options) {
805
892
  const s = resolve(shape2);
806
893
  const normal = options?.normal ?? [1, 0, 0];
807
894
  const planeOrigin = options?.at;
808
- const mirrored = curveFns.mirror(s, normal, planeOrigin);
895
+ const mirrored = shapeFns.mirror(s, normal, planeOrigin);
809
896
  return booleanFns.fuse(s, mirrored);
810
897
  }
811
898
  function rectangularPattern(shape2, options) {
@@ -832,7 +919,7 @@ function rectangularPattern(shape2, options) {
832
919
  xNorm[1] * xSpacing * xi + yNorm[1] * ySpacing * yi,
833
920
  xNorm[2] * xSpacing * xi + yNorm[2] * ySpacing * yi
834
921
  ];
835
- copies.push(curveFns.translate(s, offset2));
922
+ copies.push(shapeFns.translate(s, offset2));
836
923
  }
837
924
  }
838
925
  return booleanFns.fuseAll(copies);
@@ -879,7 +966,7 @@ function createWrappedBase(val) {
879
966
  rotateX: (a) => wrapAny(rotate(val, a, { axis: [1, 0, 0] })),
880
967
  rotateY: (a) => wrapAny(rotate(val, a, { axis: [0, 1, 0] })),
881
968
  rotateZ: (a) => wrapAny(rotate(val, a, { axis: [0, 0, 1] })),
882
- bounds: () => curveFns.getBounds(val),
969
+ bounds: () => shapeFns.getBounds(val),
883
970
  describe: () => describe(val),
884
971
  clone: () => wrapAny(clone(val)),
885
972
  // Meshing & Rendering
@@ -940,10 +1027,10 @@ function createWrapped3D(val) {
940
1027
  volumeProps: () => measurement.measureVolumeProps(val),
941
1028
  surfaceProps: () => measurement.measureSurfaceProps(val),
942
1029
  // Queries
943
- edges: () => curveFns.getEdges(val),
944
- faces: () => curveFns.getFaces(val),
945
- wires: () => curveFns.getWires(val),
946
- vertices: () => curveFns.getVertices(val),
1030
+ edges: () => shapeFns.getEdges(val),
1031
+ faces: () => shapeFns.getFaces(val),
1032
+ wires: () => shapeFns.getWires(val),
1033
+ vertices: () => shapeFns.getVertices(val),
947
1034
  // Patterns
948
1035
  linearPattern: (dir, count, spacing) => wrap3D(unwrapOrThrow(operations.linearPattern(val, dir, count, spacing))),
949
1036
  circularPattern: (axis, count, angle) => wrap3D(unwrapOrThrow(operations.circularPattern(val, axis, count, angle)))
@@ -1093,7 +1180,6 @@ exports.Curve2D = Blueprint.Curve2D;
1093
1180
  exports.axis2d = Blueprint.axis2d;
1094
1181
  exports.makePlane = Blueprint.makePlane;
1095
1182
  exports.approximateCurve = curveFns.approximateCurve;
1096
- exports.composeTransforms = curveFns.composeTransforms;
1097
1183
  exports.curveEndPoint = curveFns.curveEndPoint;
1098
1184
  exports.curveIsClosed = curveFns.curveIsClosed;
1099
1185
  exports.curveIsPeriodic = curveFns.curveIsPeriodic;
@@ -1104,23 +1190,10 @@ exports.curveStartPoint = curveFns.curveStartPoint;
1104
1190
  exports.curveTangentAt = curveFns.curveTangentAt;
1105
1191
  exports.findCurveType = curveFns.findCurveType;
1106
1192
  exports.flipOrientation = curveFns.flipOrientation;
1107
- exports.getBounds = curveFns.getBounds;
1108
1193
  exports.getCurveType = curveFns.getCurveType;
1109
- exports.getEdges = curveFns.getEdges;
1110
- exports.getFaces = curveFns.getFaces;
1111
- exports.getHashCode = curveFns.getHashCode;
1112
1194
  exports.getOrientation = curveFns.getOrientation;
1113
- exports.getVertices = curveFns.getVertices;
1114
- exports.getWires = curveFns.getWires;
1115
1195
  exports.interpolateCurve = curveFns.interpolateCurve;
1116
- exports.isEqualShape = curveFns.isEqualShape;
1117
- exports.isSameShape = curveFns.isSameShape;
1118
- exports.iterEdges = curveFns.iterEdges;
1119
- exports.iterFaces = curveFns.iterFaces;
1120
- exports.iterVertices = curveFns.iterVertices;
1121
- exports.iterWires = curveFns.iterWires;
1122
1196
  exports.offsetWire2D = curveFns.offsetWire2D;
1123
- exports.vertexPosition = curveFns.vertexPosition;
1124
1197
  exports.basicFaceExtrusion = loft$2.basicFaceExtrusion;
1125
1198
  exports.genericSweep = loft$2.genericSweep;
1126
1199
  exports.revolution = loft$2.revolution;
@@ -1266,6 +1339,22 @@ exports.createPlane = vectors.createPlane;
1266
1339
  exports.pivotPlane = vectors.pivotPlane;
1267
1340
  exports.resolvePlane = vectors.resolvePlane;
1268
1341
  exports.translatePlane = vectors.translatePlane;
1342
+ exports.composeTransforms = shapeFns.composeTransforms;
1343
+ exports.getBounds = shapeFns.getBounds;
1344
+ exports.getEdges = shapeFns.getEdges;
1345
+ exports.getFaceOrigins = shapeFns.getFaceOrigins;
1346
+ exports.getFaces = shapeFns.getFaces;
1347
+ exports.getHashCode = shapeFns.getHashCode;
1348
+ exports.getVertices = shapeFns.getVertices;
1349
+ exports.getWires = shapeFns.getWires;
1350
+ exports.isEqualShape = shapeFns.isEqualShape;
1351
+ exports.isSameShape = shapeFns.isSameShape;
1352
+ exports.iterEdges = shapeFns.iterEdges;
1353
+ exports.iterFaces = shapeFns.iterFaces;
1354
+ exports.iterVertices = shapeFns.iterVertices;
1355
+ exports.iterWires = shapeFns.iterWires;
1356
+ exports.setShapeOrigin = shapeFns.setShapeOrigin;
1357
+ exports.vertexPosition = shapeFns.vertexPosition;
1269
1358
  exports.adjacentFaces = topology.adjacentFaces;
1270
1359
  exports.autoHeal = topology.autoHeal;
1271
1360
  exports.chamferDistAngleShape = topology.chamferDistAngle;