brepjs 18.102.0 → 18.104.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.
package/dist/brepjs.cjs CHANGED
@@ -30,7 +30,7 @@ const require_loftFns = require("./loftFns-DaRDYpfB.cjs");
30
30
  const require_cameraFns = require("./cameraFns-S7YbAxfg.cjs");
31
31
  const require_textMetrics = require("./textMetrics-W-H6jUDj.cjs");
32
32
  const require_shapeRefFns = require("./shapeRefFns-Dij41NuC.cjs");
33
- const require_workerHandler = require("./workerHandler-CdlOTwJg.cjs");
33
+ const require_workerPool = require("./workerPool-edtPrfHM.cjs");
34
34
  const require_primitiveFns = require("./primitiveFns-BAWtMd9H.cjs");
35
35
  //#region src/topology/shapeBooleans.ts
36
36
  var BOPAlgo_GlueShift = 1;
@@ -5471,6 +5471,19 @@ function compound$1(children) {
5471
5471
  freeParams: depsOf(...children)
5472
5472
  };
5473
5473
  }
5474
+ function instance$1(source, placements, fuse = false) {
5475
+ const copied = placements.map((m) => m.map((row) => [...row]));
5476
+ let h = fnvMixInt32(fnvMixBool(mix(startHash("Instance"), source), fuse), copied.length);
5477
+ for (const m of copied) for (const v of m.flat()) h = fnvMixNumber(h, v);
5478
+ return {
5479
+ kind: "Instance",
5480
+ source,
5481
+ placements: copied,
5482
+ fuse,
5483
+ structuralHash: h,
5484
+ freeParams: depsOf(source)
5485
+ };
5486
+ }
5474
5487
  //#endregion
5475
5488
  //#region src/csg/types.ts
5476
5489
  function outputKindOf(node) {
@@ -5495,6 +5508,7 @@ function outputKindOf(node) {
5495
5508
  case "Scale":
5496
5509
  case "Mirror": return outputKindOf(node.target);
5497
5510
  case "Compound": return "Compound";
5511
+ case "Instance": return node.fuse ? "Solid" : "Compound";
5498
5512
  }
5499
5513
  }
5500
5514
  //#endregion
@@ -5728,6 +5742,13 @@ function evalEmpty() {
5728
5742
  return require_errors.err(require_errors.computationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, "Empty: cannot materialize an Empty node directly — only valid as boolean/transform operand"));
5729
5743
  }
5730
5744
  //#endregion
5745
+ //#region src/csg/evaluators/instance.ts
5746
+ function evalInstance(node, ctx) {
5747
+ const r = ctx.evalNode(node.source);
5748
+ if (!r.ok) return r;
5749
+ return materialize(instance(r.value, node.placements), { fuse: node.fuse });
5750
+ }
5751
+ //#endregion
5731
5752
  //#region src/csg/evaluate.ts
5732
5753
  function dispatch(node, ctx) {
5733
5754
  switch (node.kind) {
@@ -5751,6 +5772,7 @@ function dispatch(node, ctx) {
5751
5772
  case "Scale": return evalScale(node, ctx);
5752
5773
  case "Mirror": return evalMirror(node, ctx);
5753
5774
  case "Compound": return evalCompound(node, ctx);
5775
+ case "Instance": return evalInstance(node, ctx);
5754
5776
  }
5755
5777
  }
5756
5778
  function hashExprValue(h, v) {
@@ -6085,6 +6107,12 @@ function nodeToJson(n) {
6085
6107
  kind: "Compound",
6086
6108
  children: n.children.map(nodeToJson)
6087
6109
  };
6110
+ if (n.kind === "Instance") return {
6111
+ kind: "Instance",
6112
+ source: nodeToJson(n.source),
6113
+ placements: n.placements,
6114
+ fuse: n.fuse
6115
+ };
6088
6116
  return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
6089
6117
  }
6090
6118
  function bad(msg) {
@@ -6225,6 +6253,7 @@ function readNode(j) {
6225
6253
  case "Scale":
6226
6254
  case "Mirror": return readTransform(kind, j);
6227
6255
  case "Compound": return readCompound(j);
6256
+ case "Instance": return readInstance(j);
6228
6257
  default: return bad(`unknown node kind: ${String(kind)}`);
6229
6258
  }
6230
6259
  }
@@ -6383,6 +6412,16 @@ function readCompound(j) {
6383
6412
  const children = readNodeArray(j["children"], "Compound.children");
6384
6413
  return children.ok ? require_errors.ok(compound$1(children.value)) : children;
6385
6414
  }
6415
+ function isMatrix4x4(v) {
6416
+ return Array.isArray(v) && v.length === 4 && v.every((row) => Array.isArray(row) && row.length === 4 && row.every(isNumber$1));
6417
+ }
6418
+ function readInstance(j) {
6419
+ const source = readNode(j["source"]);
6420
+ if (!source.ok) return source;
6421
+ const placements = j["placements"];
6422
+ if (!Array.isArray(placements) || !placements.every(isMatrix4x4)) return bad("Instance.placements must be an array of 4x4 number matrices");
6423
+ return require_errors.ok(instance$1(source.value, placements, j["fuse"] === true));
6424
+ }
6386
6425
  //#endregion
6387
6426
  //#region src/csg/optimize.ts
6388
6427
  function optimize(node) {
@@ -6479,6 +6518,7 @@ function optimizeNode(n) {
6479
6518
  at: n.at ? foldExpr(n.at) : void 0
6480
6519
  });
6481
6520
  case "Compound": return compound$1(n.children.map(optimizeNode).filter((c) => c.kind !== "Empty"));
6521
+ case "Instance": return instance$1(optimizeNode(n.source), n.placements, n.fuse);
6482
6522
  }
6483
6523
  }
6484
6524
  function optimizeFuse(a, b, tol) {
@@ -6568,6 +6608,7 @@ function rebuildChildren(n, pred, repl) {
6568
6608
  at: n.at
6569
6609
  });
6570
6610
  case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl)));
6611
+ case "Instance": return instance$1(walk(n.source, pred, repl), n.placements, n.fuse);
6571
6612
  }
6572
6613
  }
6573
6614
  function forEachNode(root, fn) {
@@ -6596,6 +6637,7 @@ function childrenOf(n) {
6596
6637
  case "Scale":
6597
6638
  case "Mirror": return [n.target];
6598
6639
  case "Compound": return n.children;
6640
+ case "Instance": return [n.source];
6599
6641
  }
6600
6642
  }
6601
6643
  function nodeCount(root) {
@@ -6632,6 +6674,7 @@ var csg_exports = /* @__PURE__ */ require_textBlueprints.__exportAll({
6632
6674
  fromJSON: () => fromJSON,
6633
6675
  fuse: () => fuse$1,
6634
6676
  fuseAll: () => fuseAll$1,
6677
+ instance: () => instance$1,
6635
6678
  intersect: () => intersect$1,
6636
6679
  line: () => line$1,
6637
6680
  mirror: () => mirror$1,
@@ -6759,17 +6802,18 @@ exports.createHistory = require_threadFns.createHistory;
6759
6802
  exports.createKernelHandle = require_shapeTypes.createKernelHandle;
6760
6803
  exports.createMeshCache = require_meshFns.createMeshCache;
6761
6804
  exports.createNamedPlane = require_planeOps.createNamedPlane;
6762
- exports.createOperationRegistry = require_workerHandler.createOperationRegistry;
6805
+ exports.createOperationRegistry = require_workerPool.createOperationRegistry;
6763
6806
  exports.createPlane = require_planeOps.createPlane;
6764
6807
  exports.createRef = require_shapeRefFns.createRef;
6765
6808
  exports.createRegistry = require_threadFns.createRegistry;
6766
6809
  exports.createShell = require_shapeTypes.createShell;
6767
6810
  exports.createSolid = require_shapeTypes.createSolid;
6768
- exports.createTaskQueue = require_workerHandler.createTaskQueue;
6811
+ exports.createTaskQueue = require_workerPool.createTaskQueue;
6769
6812
  exports.createVertex = require_shapeTypes.createVertex;
6770
6813
  exports.createWire = require_shapeTypes.createWire;
6771
- exports.createWorkerClient = require_workerHandler.createWorkerClient;
6772
- exports.createWorkerHandler = require_workerHandler.createWorkerHandler;
6814
+ exports.createWorkerClient = require_workerPool.createWorkerClient;
6815
+ exports.createWorkerHandler = require_workerPool.createWorkerHandler;
6816
+ exports.createWorkerPool = require_workerPool.createWorkerPool;
6773
6817
  Object.defineProperty(exports, "csg", {
6774
6818
  enumerable: true,
6775
6819
  get: function() {
@@ -6803,7 +6847,7 @@ exports.cutWithEvolution = require_healingFns.cutWithEvolution;
6803
6847
  exports.cylinder = require_primitiveFns.cylinder;
6804
6848
  exports.cylindricalJoint = require_threadFns.cylindricalJoint;
6805
6849
  exports.defaultScorer = require_shapeRefFns.defaultScorer;
6806
- exports.dequeueTask = require_workerHandler.dequeueTask;
6850
+ exports.dequeueTask = require_workerPool.dequeueTask;
6807
6851
  exports.describe = describe;
6808
6852
  exports.deserializeDrawing = require_drawFns.deserializeDrawing;
6809
6853
  exports.deserializeHistory = require_threadFns.deserializeHistory;
@@ -6835,7 +6879,7 @@ exports.edgesOfFace = require_healingFns.edgesOfFace;
6835
6879
  exports.ellipse = require_primitiveFns.ellipse;
6836
6880
  exports.ellipseArc = require_primitiveFns.ellipseArc;
6837
6881
  exports.ellipsoid = require_primitiveFns.ellipsoid;
6838
- exports.enqueueTask = require_workerHandler.enqueueTask;
6882
+ exports.enqueueTask = require_workerPool.enqueueTask;
6839
6883
  exports.err = require_errors.err;
6840
6884
  exports.exportAssemblySTEP = require_threadFns.exportAssemblySTEP;
6841
6885
  exports.exportDXF = require_importFns.exportDXF;
@@ -6968,33 +7012,33 @@ exports.isChamferRadius = isChamferRadius;
6968
7012
  exports.isClosedWire = require_shapeTypes.isClosedWire;
6969
7013
  exports.isCompSolid = require_faceFns.isCompSolid;
6970
7014
  exports.isCompound = require_shapeTypes.isCompound;
6971
- exports.isDisposeRequest = require_workerHandler.isDisposeRequest;
7015
+ exports.isDisposeRequest = require_workerPool.isDisposeRequest;
6972
7016
  exports.isEdge = require_shapeTypes.isEdge;
6973
7017
  exports.isEmpty = isEmpty;
6974
7018
  exports.isEqualShape = require_shapeFns.isEqualShape;
6975
7019
  exports.isErr = require_errors.isErr;
6976
- exports.isErrorResponse = require_workerHandler.isErrorResponse;
7020
+ exports.isErrorResponse = require_workerPool.isErrorResponse;
6977
7021
  exports.isFace = require_shapeTypes.isFace;
6978
7022
  exports.isFilletRadius = isFilletRadius;
6979
- exports.isInitRequest = require_workerHandler.isInitRequest;
7023
+ exports.isInitRequest = require_workerPool.isInitRequest;
6980
7024
  exports.isInside2D = require_blueprintFns.isInside2D;
6981
7025
  exports.isInstanced = isInstanced;
6982
7026
  exports.isLive = require_shapeTypes.isLive;
6983
7027
  exports.isManifoldShell = require_shapeTypes.isManifoldShell;
6984
7028
  exports.isNumber = isNumber;
6985
7029
  exports.isOk = require_errors.isOk;
6986
- exports.isOperationRequest = require_workerHandler.isOperationRequest;
7030
+ exports.isOperationRequest = require_workerPool.isOperationRequest;
6987
7031
  exports.isOrientedFace = require_shapeTypes.isOrientedFace;
6988
7032
  exports.isPlanarFace = require_shapeTypes.isPlanarFace;
6989
7033
  exports.isPlanarWire = require_shapeTypes.isPlanarWire;
6990
7034
  exports.isProjectionPlane = require_cameraFns.isProjectionPlane;
6991
- exports.isQueueEmpty = require_workerHandler.isEmpty;
7035
+ exports.isQueueEmpty = require_workerPool.isEmpty;
6992
7036
  exports.isSameShape = require_shapeFns.isSameShape;
6993
7037
  exports.isShape1D = require_shapeTypes.isShape1D;
6994
7038
  exports.isShape3D = require_shapeTypes.isShape3D;
6995
7039
  exports.isShell = require_shapeTypes.isShell;
6996
7040
  exports.isSolid = require_shapeTypes.isSolid;
6997
- exports.isSuccessResponse = require_workerHandler.isSuccessResponse;
7041
+ exports.isSuccessResponse = require_workerPool.isSuccessResponse;
6998
7042
  exports.isValid = isValid;
6999
7043
  exports.isValidSolid = require_shapeTypes.isValidSolid;
7000
7044
  exports.isVertex = require_shapeTypes.isVertex;
@@ -7085,7 +7129,7 @@ Object.defineProperty(exports, "patterns", {
7085
7129
  return patterns_exports;
7086
7130
  }
7087
7131
  });
7088
- exports.pendingCount = require_workerHandler.pendingCount;
7132
+ exports.pendingCount = require_workerPool.pendingCount;
7089
7133
  exports.pipeline = require_errors.pipeline;
7090
7134
  exports.pivotPlane = require_planeOps.pivotPlane;
7091
7135
  exports.planarFace = require_shapeTypes.planarFace;
@@ -7118,13 +7162,13 @@ Object.defineProperty(exports, "query", {
7118
7162
  });
7119
7163
  exports.queryError = require_errors.queryError;
7120
7164
  exports.rectangularPattern = rectangularPattern;
7121
- exports.registerHandler = require_workerHandler.registerHandler;
7165
+ exports.registerHandler = require_workerPool.registerHandler;
7122
7166
  exports.registerKernel = require_shapeTypes.registerKernel;
7123
7167
  exports.registerKernelTier = require_shapeTypes.registerKernelTier;
7124
7168
  exports.registerOperation = require_threadFns.registerOperation;
7125
7169
  exports.registerShape = require_threadFns.registerShape;
7126
7170
  exports.registerVoxel = registerVoxel;
7127
- exports.rejectAll = require_workerHandler.rejectAll;
7171
+ exports.rejectAll = require_workerPool.rejectAll;
7128
7172
  exports.removeChild = require_threadFns.removeChild;
7129
7173
  exports.removeHolesFromFace = require_faceFns.removeHolesFromFace;
7130
7174
  exports.repairMesh = repairMesh;
package/dist/brepjs.js CHANGED
@@ -29,7 +29,7 @@ import { a as Sketch, c as compoundSketchLoft, d as sketchFace, f as sketchLoft,
29
29
  import { a as makeProjectedEdges, i as projectEdges, n as cameraLookAt, r as createCamera, s as isProjectionPlane, t as cameraFromPlane } from "./cameraFns-Bu6jgTKc.js";
30
30
  import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-CBbDQ5QW.js";
31
31
  import { a as updateRoles, i as resolveRef, n as captureHint, o as defaultScorer, r as createRef, t as assignRoles } from "./shapeRefFns-Cn4WNb3q.js";
32
- import { a as createTaskQueue, c as isEmpty$1, d as isDisposeRequest, f as isErrorResponse, h as isSuccessResponse, i as createWorkerClient, l as pendingCount, m as isOperationRequest, n as createWorkerHandler, o as dequeueTask, p as isInitRequest, r as registerHandler, s as enqueueTask, t as createOperationRegistry, u as rejectAll } from "./workerHandler-CFetYgIm.js";
32
+ import { a as createWorkerClient, c as enqueueTask, d as rejectAll, f as isDisposeRequest, g as isSuccessResponse, h as isOperationRequest, i as registerHandler, l as isEmpty$1, m as isInitRequest, n as createOperationRegistry, o as createTaskQueue, p as isErrorResponse, r as createWorkerHandler, s as dequeueTask, t as createWorkerPool, u as pendingCount } from "./workerPool-BxBKpKeI.js";
33
33
  import { C as threePointArc, D as wireLoop, E as wire, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere$1, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus$1, x as subFace, y as solid } from "./primitiveFns-62SO4ti5.js";
34
34
  //#region \0rolldown/runtime.js
35
35
  var __defProp = Object.defineProperty;
@@ -5474,6 +5474,19 @@ function compound$1(children) {
5474
5474
  freeParams: depsOf(...children)
5475
5475
  };
5476
5476
  }
5477
+ function instance$1(source, placements, fuse = false) {
5478
+ const copied = placements.map((m) => m.map((row) => [...row]));
5479
+ let h = fnvMixInt32(fnvMixBool(mix(startHash("Instance"), source), fuse), copied.length);
5480
+ for (const m of copied) for (const v of m.flat()) h = fnvMixNumber(h, v);
5481
+ return {
5482
+ kind: "Instance",
5483
+ source,
5484
+ placements: copied,
5485
+ fuse,
5486
+ structuralHash: h,
5487
+ freeParams: depsOf(source)
5488
+ };
5489
+ }
5477
5490
  //#endregion
5478
5491
  //#region src/csg/types.ts
5479
5492
  function outputKindOf(node) {
@@ -5498,6 +5511,7 @@ function outputKindOf(node) {
5498
5511
  case "Scale":
5499
5512
  case "Mirror": return outputKindOf(node.target);
5500
5513
  case "Compound": return "Compound";
5514
+ case "Instance": return node.fuse ? "Solid" : "Compound";
5501
5515
  }
5502
5516
  }
5503
5517
  //#endregion
@@ -5731,6 +5745,13 @@ function evalEmpty() {
5731
5745
  return err(computationError(BrepErrorCode.NULL_SHAPE_INPUT, "Empty: cannot materialize an Empty node directly — only valid as boolean/transform operand"));
5732
5746
  }
5733
5747
  //#endregion
5748
+ //#region src/csg/evaluators/instance.ts
5749
+ function evalInstance(node, ctx) {
5750
+ const r = ctx.evalNode(node.source);
5751
+ if (!r.ok) return r;
5752
+ return materialize(instance(r.value, node.placements), { fuse: node.fuse });
5753
+ }
5754
+ //#endregion
5734
5755
  //#region src/csg/evaluate.ts
5735
5756
  function dispatch(node, ctx) {
5736
5757
  switch (node.kind) {
@@ -5754,6 +5775,7 @@ function dispatch(node, ctx) {
5754
5775
  case "Scale": return evalScale(node, ctx);
5755
5776
  case "Mirror": return evalMirror(node, ctx);
5756
5777
  case "Compound": return evalCompound(node, ctx);
5778
+ case "Instance": return evalInstance(node, ctx);
5757
5779
  }
5758
5780
  }
5759
5781
  function hashExprValue(h, v) {
@@ -6088,6 +6110,12 @@ function nodeToJson(n) {
6088
6110
  kind: "Compound",
6089
6111
  children: n.children.map(nodeToJson)
6090
6112
  };
6113
+ if (n.kind === "Instance") return {
6114
+ kind: "Instance",
6115
+ source: nodeToJson(n.source),
6116
+ placements: n.placements,
6117
+ fuse: n.fuse
6118
+ };
6091
6119
  return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
6092
6120
  }
6093
6121
  function bad(msg) {
@@ -6228,6 +6256,7 @@ function readNode(j) {
6228
6256
  case "Scale":
6229
6257
  case "Mirror": return readTransform(kind, j);
6230
6258
  case "Compound": return readCompound(j);
6259
+ case "Instance": return readInstance(j);
6231
6260
  default: return bad(`unknown node kind: ${String(kind)}`);
6232
6261
  }
6233
6262
  }
@@ -6386,6 +6415,16 @@ function readCompound(j) {
6386
6415
  const children = readNodeArray(j["children"], "Compound.children");
6387
6416
  return children.ok ? ok(compound$1(children.value)) : children;
6388
6417
  }
6418
+ function isMatrix4x4(v) {
6419
+ return Array.isArray(v) && v.length === 4 && v.every((row) => Array.isArray(row) && row.length === 4 && row.every(isNumber$1));
6420
+ }
6421
+ function readInstance(j) {
6422
+ const source = readNode(j["source"]);
6423
+ if (!source.ok) return source;
6424
+ const placements = j["placements"];
6425
+ if (!Array.isArray(placements) || !placements.every(isMatrix4x4)) return bad("Instance.placements must be an array of 4x4 number matrices");
6426
+ return ok(instance$1(source.value, placements, j["fuse"] === true));
6427
+ }
6389
6428
  //#endregion
6390
6429
  //#region src/csg/optimize.ts
6391
6430
  function optimize(node) {
@@ -6482,6 +6521,7 @@ function optimizeNode(n) {
6482
6521
  at: n.at ? foldExpr(n.at) : void 0
6483
6522
  });
6484
6523
  case "Compound": return compound$1(n.children.map(optimizeNode).filter((c) => c.kind !== "Empty"));
6524
+ case "Instance": return instance$1(optimizeNode(n.source), n.placements, n.fuse);
6485
6525
  }
6486
6526
  }
6487
6527
  function optimizeFuse(a, b, tol) {
@@ -6571,6 +6611,7 @@ function rebuildChildren(n, pred, repl) {
6571
6611
  at: n.at
6572
6612
  });
6573
6613
  case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl)));
6614
+ case "Instance": return instance$1(walk(n.source, pred, repl), n.placements, n.fuse);
6574
6615
  }
6575
6616
  }
6576
6617
  function forEachNode(root, fn) {
@@ -6599,6 +6640,7 @@ function childrenOf(n) {
6599
6640
  case "Scale":
6600
6641
  case "Mirror": return [n.target];
6601
6642
  case "Compound": return n.children;
6643
+ case "Instance": return [n.source];
6602
6644
  }
6603
6645
  }
6604
6646
  function nodeCount(root) {
@@ -6635,6 +6677,7 @@ var csg_exports = /* @__PURE__ */ __exportAll({
6635
6677
  fromJSON: () => fromJSON,
6636
6678
  fuse: () => fuse$1,
6637
6679
  fuseAll: () => fuseAll$1,
6680
+ instance: () => instance$1,
6638
6681
  intersect: () => intersect$1,
6639
6682
  line: () => line$1,
6640
6683
  mirror: () => mirror$1,
@@ -6659,4 +6702,4 @@ var csg_exports = /* @__PURE__ */ __exportAll({
6659
6702
  withEvaluator: () => withEvaluator
6660
6703
  });
6661
6704
  //#endregion
6662
- export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, exportURDF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, forwardKinematics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, gridPattern, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, importURDF, init, initFromManifold, initFromOC, initVoxel, innerWires, instance, instanceCount, instanceGrid, instancedMesh, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, inverseKinematics, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isInstanced, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTrajectory, jointTransform, jointsFromDH, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, materialize, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mechanismDOF, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarJoint, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setJointValues, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
6705
+ export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, createWorkerPool, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, exportURDF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, forwardKinematics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, gridPattern, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, importURDF, init, initFromManifold, initFromOC, initVoxel, innerWires, instance, instanceCount, instanceGrid, instancedMesh, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, inverseKinematics, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isInstanced, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTrajectory, jointTransform, jointsFromDH, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, materialize, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mechanismDOF, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarJoint, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setJointValues, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
@@ -1,5 +1,6 @@
1
1
  import { ScalarInput, Vec3Input } from './expressions.js';
2
- import { BoxNode, SphereNode, CylinderNode, ConeNode, TorusNode, PolygonNode, CircleNode, LineNode, VertexLitNode, EmptyNode, FuseNode, CutNode, IntersectNode, FuseAllNode, CutAllNode, TranslateNode, RotateNode, ScaleNode, MirrorNode, CompoundNode, IRNode, SolidNode, FaceNode, EdgeNode, VertexNode } from './types.js';
2
+ import { Matrix4x4 } from '../core/types.js';
3
+ import { BoxNode, SphereNode, CylinderNode, ConeNode, TorusNode, PolygonNode, CircleNode, LineNode, VertexLitNode, EmptyNode, FuseNode, CutNode, IntersectNode, FuseAllNode, CutAllNode, TranslateNode, RotateNode, ScaleNode, MirrorNode, CompoundNode, InstanceNode, IRNode, SolidNode, FaceNode, EdgeNode, VertexNode } from './types.js';
3
4
  export declare function box(x: ScalarInput, y: ScalarInput, z: ScalarInput): BoxNode;
4
5
  export declare function sphere(radius: ScalarInput): SphereNode;
5
6
  export declare function cylinder(radius: ScalarInput, height: ScalarInput): CylinderNode;
@@ -33,4 +34,5 @@ export interface MirrorOptions {
33
34
  }
34
35
  export declare function mirror(target: IRNode, options?: MirrorOptions): MirrorNode;
35
36
  export declare function compound(children: ReadonlyArray<IRNode>): CompoundNode;
37
+ export declare function instance(source: IRNode, placements: ReadonlyArray<Matrix4x4>, fuse?: boolean): InstanceNode;
36
38
  export type { FaceNode, EdgeNode, VertexNode, SolidNode };
@@ -0,0 +1,5 @@
1
+ import { Result } from '../../core/result.js';
2
+ import { AnyShape, Dimension } from '../../core/shapeTypes.js';
3
+ import { InstanceNode } from '../types.js';
4
+ import { EvalContext } from './context.js';
5
+ export declare function evalInstance(node: InstanceNode, ctx: EvalContext): Result<AnyShape<Dimension>>;
@@ -5,9 +5,9 @@
5
5
  * parameterize via named expression bindings; evaluate against the active
6
6
  * kernel with subtree-level cache reuse for incremental parametric edits.
7
7
  */
8
- export { box, sphere, cylinder, cone, torus, polygon, circle, line, vertex, emptySolid, emptyFace, emptyWire, fuse, cut, intersect, fuseAll, cutAll, translate, rotate, scale, mirror, compound, type RotateOptions, type ScaleOptions, type MirrorOptions, } from './builders.js';
8
+ export { box, sphere, cylinder, cone, torus, polygon, circle, line, vertex, emptySolid, emptyFace, emptyWire, fuse, cut, intersect, fuseAll, cutAll, translate, rotate, scale, mirror, compound, instance, type RotateOptions, type ScaleOptions, type MirrorOptions, } from './builders.js';
9
9
  export { numLit, vec3Lit, vec2Lit, param, binOp, unaryOp, component, buildVec, add, mul, asScalarExpr, asVec3Expr, asVec2Expr, type Expr, type ExprValue, type Env, type ScalarInput, type Vec3Input, type Vec2Input, type BinaryOp, type UnaryOp, } from './expressions.js';
10
- export type { IRNode, NodeKind, OutputKind, PrimitiveNode, BooleanNode, TransformIRNode, SolidNode, FaceNode, EdgeNode, VertexNode, AnyNode, } from './types.js';
10
+ export type { IRNode, NodeKind, OutputKind, PrimitiveNode, BooleanNode, TransformIRNode, InstanceNode, SolidNode, FaceNode, EdgeNode, VertexNode, AnyNode, } from './types.js';
11
11
  export { outputKindOf } from './types.js';
12
12
  export { Evaluator, withEvaluator, type EvaluatorOptions, type StepInfo, type CacheStats, } from './evaluate.js';
13
13
  export { toJSON, fromJSON, CSG_VERSION, type CsgEnvelope } from './serialize.js';
@@ -1,4 +1,5 @@
1
1
  import { Expr } from './expressions.js';
2
+ import { Matrix4x4 } from '../core/types.js';
2
3
  export type OutputKind = 'Solid' | 'Face' | 'Wire' | 'Edge' | 'Vertex' | 'Compound';
3
4
  /** Output kinds that have a corresponding empty-shape builder + serializer. */
4
5
  export type EmptyOutputKind = 'Solid' | 'Face' | 'Wire';
@@ -111,10 +112,18 @@ export interface CompoundNode extends IRNodeBase {
111
112
  readonly kind: 'Compound';
112
113
  readonly children: readonly IRNode[];
113
114
  }
115
+ export interface InstanceNode extends IRNodeBase {
116
+ readonly kind: 'Instance';
117
+ readonly source: IRNode;
118
+ /** Per-instance world transforms (row-major 4x4 literals). */
119
+ readonly placements: readonly Matrix4x4[];
120
+ /** Fuse the placed copies into one solid; otherwise a Compound. */
121
+ readonly fuse: boolean;
122
+ }
114
123
  export type PrimitiveNode = BoxNode | SphereNode | CylinderNode | ConeNode | TorusNode | PolygonNode | CircleNode | LineNode | VertexLitNode | EmptyNode;
115
124
  export type BooleanNode = FuseNode | CutNode | IntersectNode | FuseAllNode | CutAllNode;
116
125
  export type TransformIRNode = TranslateNode | RotateNode | ScaleNode | MirrorNode;
117
- export type IRNode = PrimitiveNode | BooleanNode | TransformIRNode | CompoundNode;
126
+ export type IRNode = PrimitiveNode | BooleanNode | TransformIRNode | CompoundNode | InstanceNode;
118
127
  export type NodeKind = IRNode['kind'];
119
128
  export type AnyNode = IRNode;
120
129
  /** Nodes that produce a 3D solid. */
package/dist/index.d.ts CHANGED
@@ -137,7 +137,7 @@ export { importGLB } from './io/gltfImportFns.js';
137
137
  export type { DXFImportOptions } from './io/dxfImportFns.js';
138
138
  export { edgeFinder, faceFinder, wireFinder, vertexFinder, cornerFinder, type EdgeFinderFn, type FaceFinderFn, type WireFinderFn, type VertexFinderFn, type CornerFinderFn, type CornerFilter, type ShapeFinder, } from './query/finderFns.js';
139
139
  export { createCamera, cameraLookAt, cameraFromPlane, projectEdges, type Camera, } from './projection/cameraFns.js';
140
- export { type WorkerRequest, type InitRequest, type OperationRequest, type DisposeRequest, type WorkerResponse, type SuccessResponse, type ErrorResponse, isInitRequest, isOperationRequest, isDisposeRequest, isSuccessResponse, isErrorResponse, type PendingTask, type TaskQueue, createTaskQueue, enqueueTask, dequeueTask, pendingCount, isQueueEmpty, rejectAll, createWorkerClient, createOperationRegistry, registerHandler, createWorkerHandler, type WorkerClient, type WorkerClientOptions, type WorkerResult, type OperationHandler, type OperationRegistry, } from './worker/index.js';
140
+ export { type WorkerRequest, type InitRequest, type OperationRequest, type DisposeRequest, type WorkerResponse, type SuccessResponse, type ErrorResponse, isInitRequest, isOperationRequest, isDisposeRequest, isSuccessResponse, isErrorResponse, type PendingTask, type TaskQueue, createTaskQueue, enqueueTask, dequeueTask, pendingCount, isQueueEmpty, rejectAll, createWorkerClient, createOperationRegistry, registerHandler, createWorkerHandler, createWorkerPool, type WorkerClient, type WorkerClientOptions, type WorkerResult, type OperationHandler, type OperationRegistry, type WorkerPool, type WorkerPoolOptions, type WorkerOperation, } from './worker/index.js';
141
141
  export type { Shapeable, WrappedMarker, FinderFn, FilletRadius, ChamferDistance, DraftAngle, DraftOptions, DrawingLike, DrillOptions, PocketOptions, BossOptions, MirrorJoinOptions, RectangularPatternOptions, } from './topology/apiTypes.js';
142
142
  export { resolve, resolve3D } from './topology/apiTypes.js';
143
143
  export { box, cylinder, sphere, cone, torus, ellipsoid, line, circle, ellipse, helix, threePointArc, ellipseArc, bsplineApprox, bezier, tangentArc, wire, wireLoop, face, filledFace, subFace, polygon, vertex, compound, solid, offsetFace, sewShells, addHoles, type BoxOptions, type CylinderOptions, type SphereOptions, type ConeOptions, type TorusOptions, type EllipsoidOptions, type CircleOptions, type EllipseOptions, type HelixOptions, type EllipseArcOptions, } from './topology/primitiveFns.js';
@@ -8,3 +8,4 @@ export { type WorkerRequest, type InitRequest, type OperationRequest, type Dispo
8
8
  export { type PendingTask, type TaskQueue, createTaskQueue, enqueueTask, dequeueTask, pendingCount, isEmpty as isQueueEmpty, rejectAll, } from './taskQueue.js';
9
9
  export { createWorkerClient, type WorkerClient, type WorkerClientOptions, type WorkerResult, } from './workerClient.js';
10
10
  export { createOperationRegistry, registerHandler, createWorkerHandler, type OperationHandler, type OperationRegistry, } from './workerHandler.js';
11
+ export { createWorkerPool, type WorkerPool, type WorkerPoolOptions, type WorkerOperation, } from './workerPool.js';
@@ -0,0 +1,46 @@
1
+ import { WorkerResult } from './workerClient.js';
2
+ export interface WorkerPoolOptions {
3
+ /** The Worker instances to pool over; each is wrapped in a WorkerClient. */
4
+ workers: Worker[];
5
+ /** Optional URL for the WASM binary, forwarded to every worker on init. */
6
+ wasmUrl?: string;
7
+ }
8
+ /** A single operation for {@link WorkerPool.executeBatch}. */
9
+ export interface WorkerOperation {
10
+ /** Name of the registered operation to invoke. */
11
+ operation: string;
12
+ /** BREP-serialized input shapes. */
13
+ shapesBrep: string[];
14
+ /** Parameters forwarded to the operation handler. */
15
+ params: Record<string, unknown>;
16
+ }
17
+ export interface WorkerPool {
18
+ /** Number of workers in the pool. */
19
+ readonly size: number;
20
+ /**
21
+ * Initialize every worker (load WASM) in parallel. Atomic: if any worker
22
+ * fails, the pool disposes every worker and rejects with the original error,
23
+ * leaving the pool in a terminal disposed state.
24
+ */
25
+ init(): Promise<void>;
26
+ /** Run one operation on the least-loaded worker. */
27
+ execute(operation: string, shapesBrep: string[], params: Record<string, unknown>): Promise<WorkerResult>;
28
+ /**
29
+ * Run a batch of independent operations, fanned across the pool concurrently.
30
+ * Resolves with results in the same order as `operations`.
31
+ */
32
+ executeBatch(operations: ReadonlyArray<WorkerOperation>): Promise<WorkerResult[]>;
33
+ /** In-flight task count per worker, indexed as the pool was constructed. */
34
+ inFlight(): readonly number[];
35
+ /** Dispose every worker, rejecting all pending and future operations. Idempotent. */
36
+ dispose(): void;
37
+ }
38
+ /**
39
+ * Create a worker pool over the given Worker instances.
40
+ *
41
+ * Dispatch is least-loaded: each operation goes to the worker with the fewest
42
+ * in-flight tasks (ties resolve to the first). The count is bumped synchronously
43
+ * at dispatch, so a burst of calls spreads across workers rather than piling
44
+ * onto one. Under uniform op cost this degrades to round-robin.
45
+ */
46
+ export declare function createWorkerPool(options: WorkerPoolOptions): WorkerPool;
package/dist/worker.cjs CHANGED
@@ -1,17 +1,18 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_workerHandler = require("./workerHandler-CdlOTwJg.cjs");
3
- exports.createOperationRegistry = require_workerHandler.createOperationRegistry;
4
- exports.createTaskQueue = require_workerHandler.createTaskQueue;
5
- exports.createWorkerClient = require_workerHandler.createWorkerClient;
6
- exports.createWorkerHandler = require_workerHandler.createWorkerHandler;
7
- exports.dequeueTask = require_workerHandler.dequeueTask;
8
- exports.enqueueTask = require_workerHandler.enqueueTask;
9
- exports.isDisposeRequest = require_workerHandler.isDisposeRequest;
10
- exports.isErrorResponse = require_workerHandler.isErrorResponse;
11
- exports.isInitRequest = require_workerHandler.isInitRequest;
12
- exports.isOperationRequest = require_workerHandler.isOperationRequest;
13
- exports.isQueueEmpty = require_workerHandler.isEmpty;
14
- exports.isSuccessResponse = require_workerHandler.isSuccessResponse;
15
- exports.pendingCount = require_workerHandler.pendingCount;
16
- exports.registerHandler = require_workerHandler.registerHandler;
17
- exports.rejectAll = require_workerHandler.rejectAll;
2
+ const require_workerPool = require("./workerPool-edtPrfHM.cjs");
3
+ exports.createOperationRegistry = require_workerPool.createOperationRegistry;
4
+ exports.createTaskQueue = require_workerPool.createTaskQueue;
5
+ exports.createWorkerClient = require_workerPool.createWorkerClient;
6
+ exports.createWorkerHandler = require_workerPool.createWorkerHandler;
7
+ exports.createWorkerPool = require_workerPool.createWorkerPool;
8
+ exports.dequeueTask = require_workerPool.dequeueTask;
9
+ exports.enqueueTask = require_workerPool.enqueueTask;
10
+ exports.isDisposeRequest = require_workerPool.isDisposeRequest;
11
+ exports.isErrorResponse = require_workerPool.isErrorResponse;
12
+ exports.isInitRequest = require_workerPool.isInitRequest;
13
+ exports.isOperationRequest = require_workerPool.isOperationRequest;
14
+ exports.isQueueEmpty = require_workerPool.isEmpty;
15
+ exports.isSuccessResponse = require_workerPool.isSuccessResponse;
16
+ exports.pendingCount = require_workerPool.pendingCount;
17
+ exports.registerHandler = require_workerPool.registerHandler;
18
+ exports.rejectAll = require_workerPool.rejectAll;
package/dist/worker.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as createTaskQueue, c as isEmpty, d as isDisposeRequest, f as isErrorResponse, h as isSuccessResponse, i as createWorkerClient, l as pendingCount, m as isOperationRequest, n as createWorkerHandler, o as dequeueTask, p as isInitRequest, r as registerHandler, s as enqueueTask, t as createOperationRegistry, u as rejectAll } from "./workerHandler-CFetYgIm.js";
2
- export { createOperationRegistry, createTaskQueue, createWorkerClient, createWorkerHandler, dequeueTask, enqueueTask, isDisposeRequest, isErrorResponse, isInitRequest, isOperationRequest, isEmpty as isQueueEmpty, isSuccessResponse, pendingCount, registerHandler, rejectAll };
1
+ import { a as createWorkerClient, c as enqueueTask, d as rejectAll, f as isDisposeRequest, g as isSuccessResponse, h as isOperationRequest, i as registerHandler, l as isEmpty, m as isInitRequest, n as createOperationRegistry, o as createTaskQueue, p as isErrorResponse, r as createWorkerHandler, s as dequeueTask, t as createWorkerPool, u as pendingCount } from "./workerPool-BxBKpKeI.js";
2
+ export { createOperationRegistry, createTaskQueue, createWorkerClient, createWorkerHandler, createWorkerPool, dequeueTask, enqueueTask, isDisposeRequest, isErrorResponse, isInitRequest, isOperationRequest, isEmpty as isQueueEmpty, isSuccessResponse, pendingCount, registerHandler, rejectAll };
@@ -205,4 +205,68 @@ function createWorkerHandler(registry, initFn) {
205
205
  };
206
206
  }
207
207
  //#endregion
208
- export { createTaskQueue as a, isEmpty as c, isDisposeRequest as d, isErrorResponse as f, isSuccessResponse as h, createWorkerClient as i, pendingCount as l, isOperationRequest as m, createWorkerHandler as n, dequeueTask as o, isInitRequest as p, registerHandler as r, enqueueTask as s, createOperationRegistry as t, rejectAll as u };
208
+ //#region src/worker/workerPool.ts
209
+ /**
210
+ * Worker pool for spreading CAD operations across several Web Workers.
211
+ *
212
+ * Wraps N {@link WorkerClient}s behind the same promise API and dispatches each
213
+ * operation to the least-loaded worker, so independent work can span cores
214
+ * instead of serializing through a single worker.
215
+ */
216
+ /**
217
+ * Create a worker pool over the given Worker instances.
218
+ *
219
+ * Dispatch is least-loaded: each operation goes to the worker with the fewest
220
+ * in-flight tasks (ties resolve to the first). The count is bumped synchronously
221
+ * at dispatch, so a burst of calls spreads across workers rather than piling
222
+ * onto one. Under uniform op cost this degrades to round-robin.
223
+ */
224
+ function createWorkerPool(options) {
225
+ const { workers, wasmUrl } = options;
226
+ if (workers.length === 0) throw new Error("createWorkerPool requires at least one worker");
227
+ const slots = workers.map((worker) => ({
228
+ client: createWorkerClient({
229
+ worker,
230
+ ...wasmUrl !== void 0 ? { wasmUrl } : {}
231
+ }),
232
+ inFlight: 0
233
+ }));
234
+ let disposed = false;
235
+ function leastLoaded() {
236
+ return slots.reduce((best, slot) => slot.inFlight < best.inFlight ? slot : best);
237
+ }
238
+ function execute(operation, shapesBrep, params) {
239
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("WorkerPool has been disposed"));
240
+ const slot = leastLoaded();
241
+ slot.inFlight += 1;
242
+ return slot.client.execute(operation, shapesBrep, params).finally(() => {
243
+ slot.inFlight -= 1;
244
+ });
245
+ }
246
+ function dispose() {
247
+ if (disposed) return;
248
+ disposed = true;
249
+ for (const slot of slots) slot.client.dispose();
250
+ }
251
+ return {
252
+ size: slots.length,
253
+ async init() {
254
+ try {
255
+ await Promise.all(slots.map((slot) => slot.client.init()));
256
+ } catch (err) {
257
+ dispose();
258
+ throw err;
259
+ }
260
+ },
261
+ execute,
262
+ executeBatch(operations) {
263
+ return Promise.all(operations.map((op) => execute(op.operation, op.shapesBrep, op.params)));
264
+ },
265
+ inFlight() {
266
+ return slots.map((slot) => slot.inFlight);
267
+ },
268
+ dispose
269
+ };
270
+ }
271
+ //#endregion
272
+ export { createWorkerClient as a, enqueueTask as c, rejectAll as d, isDisposeRequest as f, isSuccessResponse as g, isOperationRequest as h, registerHandler as i, isEmpty as l, isInitRequest as m, createOperationRegistry as n, createTaskQueue as o, isErrorResponse as p, createWorkerHandler as r, dequeueTask as s, createWorkerPool as t, pendingCount as u };
@@ -205,6 +205,70 @@ function createWorkerHandler(registry, initFn) {
205
205
  };
206
206
  }
207
207
  //#endregion
208
+ //#region src/worker/workerPool.ts
209
+ /**
210
+ * Worker pool for spreading CAD operations across several Web Workers.
211
+ *
212
+ * Wraps N {@link WorkerClient}s behind the same promise API and dispatches each
213
+ * operation to the least-loaded worker, so independent work can span cores
214
+ * instead of serializing through a single worker.
215
+ */
216
+ /**
217
+ * Create a worker pool over the given Worker instances.
218
+ *
219
+ * Dispatch is least-loaded: each operation goes to the worker with the fewest
220
+ * in-flight tasks (ties resolve to the first). The count is bumped synchronously
221
+ * at dispatch, so a burst of calls spreads across workers rather than piling
222
+ * onto one. Under uniform op cost this degrades to round-robin.
223
+ */
224
+ function createWorkerPool(options) {
225
+ const { workers, wasmUrl } = options;
226
+ if (workers.length === 0) throw new Error("createWorkerPool requires at least one worker");
227
+ const slots = workers.map((worker) => ({
228
+ client: createWorkerClient({
229
+ worker,
230
+ ...wasmUrl !== void 0 ? { wasmUrl } : {}
231
+ }),
232
+ inFlight: 0
233
+ }));
234
+ let disposed = false;
235
+ function leastLoaded() {
236
+ return slots.reduce((best, slot) => slot.inFlight < best.inFlight ? slot : best);
237
+ }
238
+ function execute(operation, shapesBrep, params) {
239
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("WorkerPool has been disposed"));
240
+ const slot = leastLoaded();
241
+ slot.inFlight += 1;
242
+ return slot.client.execute(operation, shapesBrep, params).finally(() => {
243
+ slot.inFlight -= 1;
244
+ });
245
+ }
246
+ function dispose() {
247
+ if (disposed) return;
248
+ disposed = true;
249
+ for (const slot of slots) slot.client.dispose();
250
+ }
251
+ return {
252
+ size: slots.length,
253
+ async init() {
254
+ try {
255
+ await Promise.all(slots.map((slot) => slot.client.init()));
256
+ } catch (err) {
257
+ dispose();
258
+ throw err;
259
+ }
260
+ },
261
+ execute,
262
+ executeBatch(operations) {
263
+ return Promise.all(operations.map((op) => execute(op.operation, op.shapesBrep, op.params)));
264
+ },
265
+ inFlight() {
266
+ return slots.map((slot) => slot.inFlight);
267
+ },
268
+ dispose
269
+ };
270
+ }
271
+ //#endregion
208
272
  Object.defineProperty(exports, "createOperationRegistry", {
209
273
  enumerable: true,
210
274
  get: function() {
@@ -229,6 +293,12 @@ Object.defineProperty(exports, "createWorkerHandler", {
229
293
  return createWorkerHandler;
230
294
  }
231
295
  });
296
+ Object.defineProperty(exports, "createWorkerPool", {
297
+ enumerable: true,
298
+ get: function() {
299
+ return createWorkerPool;
300
+ }
301
+ });
232
302
  Object.defineProperty(exports, "dequeueTask", {
233
303
  enumerable: true,
234
304
  get: function() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brepjs",
3
- "version": "18.102.0",
3
+ "version": "18.104.0",
4
4
  "description": "Web CAD library with pluggable geometry kernel",
5
5
  "keywords": [
6
6
  "cad",