brepjs 12.7.3 → 12.8.1
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/2d/blueprints/boolean2D.d.ts.map +1 -1
- package/dist/2d/blueprints/lib.d.ts.map +1 -1
- package/dist/2d/blueprints/offset.d.ts.map +1 -1
- package/dist/2d.cjs +2 -2
- package/dist/2d.js +3 -3
- package/dist/{Blueprint-CnDVffSX.cjs → Blueprint-CQ28WJhz.cjs} +29 -30
- package/dist/{Blueprint-C3lWY1Jf.js → Blueprint-DbVaf6k7.js} +7 -8
- package/dist/{boolean2D-DyQJt8Na.cjs → boolean2D-0blbVtJ8.cjs} +70 -61
- package/dist/{boolean2D-CwZAIJDS.js → boolean2D-y3E92F0u.js} +37 -28
- package/dist/{booleanFns-CcNUsgI8.js → booleanFns-BCTjYZAg.js} +4 -4
- package/dist/{booleanFns-D7HmkpYt.cjs → booleanFns-gmsX3Cv2.cjs} +59 -59
- package/dist/brepjs.cjs +319 -372
- package/dist/brepjs.js +358 -411
- package/dist/core/errors.d.ts +14 -5
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core.cjs +30 -31
- package/dist/core.js +19 -20
- package/dist/{cornerFinder-BV-l1BCw.js → cornerFinder-Ckz-mPHE.js} +1 -1
- package/dist/{cornerFinder-3zfbQvXg.cjs → cornerFinder-ZmOyOOsh.cjs} +1 -1
- package/dist/{curveFns-Ch87sD5O.cjs → curveFns-BZngcnQ1.cjs} +17 -17
- package/dist/{curveFns-CloOqAQ_.js → curveFns-mROFhiuG.js} +1 -1
- package/dist/{drawFns-5myJTgtX.js → drawFns-Bwakrq7w.js} +24 -25
- package/dist/{drawFns-CDNafQhv.cjs → drawFns-CjRc1NfQ.cjs} +51 -52
- package/dist/{faceFns-B6ebRh5I.js → faceFns-B8GnxjdY.js} +1 -1
- package/dist/{faceFns-BLTEPBKq.cjs → faceFns-DB1Fc5gy.cjs} +20 -20
- package/dist/{helpers-6kn30cSD.cjs → helpers-C8NoT0Wu.cjs} +14 -14
- package/dist/{helpers-C9KvE1RW.js → helpers-X0juxnwj.js} +4 -4
- package/dist/io.cjs +26 -26
- package/dist/io.js +3 -3
- package/dist/kernel/brepkitAdapter.d.ts +8 -8
- package/dist/kernel/brepkitAdapter.d.ts.map +1 -1
- package/dist/kernel/brepkitWasmTypes.d.ts +6 -0
- package/dist/kernel/brepkitWasmTypes.d.ts.map +1 -1
- package/dist/kernel/historyOps.d.ts +3 -3
- package/dist/kernel/historyOps.d.ts.map +1 -1
- package/dist/kernel/types.d.ts +8 -8
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/{loft-BcZUCGKi.js → loft-Bhw-FMoL.js} +4 -4
- package/dist/{loft-DR1UN5uN.cjs → loft-hp3pc1M7.cjs} +43 -43
- package/dist/{measurement-DoYXRaKI.cjs → measurement-BoNTUBAp.cjs} +1 -1
- package/dist/{measurement-oWvhSVZG.js → measurement-D8EJ694A.js} +1 -1
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-3gy0empP.cjs → meshFns-BnV0ZR8w.cjs} +17 -17
- package/dist/{meshFns-DsLRd3tA.js → meshFns-nQjK38EC.js} +2 -2
- package/dist/{operations-Dcz6YlOt.js → operations-BfbkK6DU.js} +5 -5
- package/dist/{operations-DLFzmdFX.cjs → operations-CYpmLSC4.cjs} +75 -75
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/query.cjs +3 -3
- package/dist/query.js +4 -4
- package/dist/{errors-B7kgv0cd.js → result-BaSD1fqR.js} +43 -23
- package/dist/{errors-9fDehDNc.cjs → result-fAX0OZzI.cjs} +20 -0
- package/dist/result.cjs +30 -41
- package/dist/result.js +18 -29
- package/dist/{shapeFns-D-MOoqJd.cjs → shapeFns-C2SnNvdH.cjs} +39 -39
- package/dist/{shapeFns-D2PlLFE6.js → shapeFns-FDuKkrDR.js} +4 -4
- package/dist/sketching.cjs +2 -2
- package/dist/sketching.js +2 -2
- package/dist/{solidBuilders-BzfRBizW.cjs → solidBuilders-994_MQwB.cjs} +12 -12
- package/dist/{solidBuilders-BXhh5hP2.js → solidBuilders-DmwhTCCd.js} +2 -2
- package/dist/{surfaceBuilders-Be_ENWSA.cjs → surfaceBuilders-5VA34a3_.cjs} +27 -27
- package/dist/{surfaceBuilders-D6iDVPIM.js → surfaceBuilders-nQdJ56fe.js} +2 -2
- package/dist/{topology-CKtCGLmb.cjs → topology-ANwCzGL8.cjs} +54 -54
- package/dist/{topology-DxD58iQ6.js → topology-C7x98OVn.js} +8 -8
- package/dist/topology.cjs +6 -6
- package/dist/topology.js +6 -6
- package/dist/{vectors-CESkzEm6.js → vectors-Bx8wkNui.js} +1 -1
- package/dist/{vectors-BafmMf96.cjs → vectors-D_IiZx0q.cjs} +6 -6
- package/dist/vectors.cjs +1 -1
- package/dist/vectors.js +1 -1
- package/package.json +5 -8
package/dist/brepjs.cjs
CHANGED
|
@@ -46,30 +46,29 @@ var __callDispose = (stack, error, hasError) => {
|
|
|
46
46
|
};
|
|
47
47
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
48
48
|
const shapeTypes = require("./shapeTypes-7xEam9Ri.cjs");
|
|
49
|
-
const
|
|
49
|
+
const result = require("./result-fAX0OZzI.cjs");
|
|
50
50
|
const vecOps = require("./vecOps-CjRL1jau.cjs");
|
|
51
|
-
const Blueprint = require("./Blueprint-
|
|
52
|
-
const loft$2 = require("./loft-
|
|
53
|
-
const operations = require("./operations-
|
|
54
|
-
const boolean2D = require("./boolean2D-
|
|
51
|
+
const Blueprint = require("./Blueprint-CQ28WJhz.cjs");
|
|
52
|
+
const loft$2 = require("./loft-hp3pc1M7.cjs");
|
|
53
|
+
const operations = require("./operations-CYpmLSC4.cjs");
|
|
54
|
+
const boolean2D = require("./boolean2D-0blbVtJ8.cjs");
|
|
55
55
|
const _2d = require("./2d.cjs");
|
|
56
|
-
const helpers = require("./helpers-
|
|
56
|
+
const helpers = require("./helpers-C8NoT0Wu.cjs");
|
|
57
57
|
const io = require("./io.cjs");
|
|
58
|
-
const drawFns = require("./drawFns-
|
|
58
|
+
const drawFns = require("./drawFns-CjRc1NfQ.cjs");
|
|
59
59
|
const types = require("./types-CA_xrgDq.cjs");
|
|
60
|
-
const vectors = require("./vectors-
|
|
61
|
-
const shapeFns = require("./shapeFns-
|
|
62
|
-
const booleanFns = require("./booleanFns-
|
|
63
|
-
const topology = require("./topology-
|
|
64
|
-
const curveFns = require("./curveFns-
|
|
65
|
-
const faceFns = require("./faceFns-
|
|
66
|
-
const meshFns = require("./meshFns-
|
|
67
|
-
const measurement = require("./measurement-
|
|
68
|
-
const surfaceBuilders = require("./surfaceBuilders-
|
|
60
|
+
const vectors = require("./vectors-D_IiZx0q.cjs");
|
|
61
|
+
const shapeFns = require("./shapeFns-C2SnNvdH.cjs");
|
|
62
|
+
const booleanFns = require("./booleanFns-gmsX3Cv2.cjs");
|
|
63
|
+
const topology = require("./topology-ANwCzGL8.cjs");
|
|
64
|
+
const curveFns = require("./curveFns-BZngcnQ1.cjs");
|
|
65
|
+
const faceFns = require("./faceFns-DB1Fc5gy.cjs");
|
|
66
|
+
const meshFns = require("./meshFns-BnV0ZR8w.cjs");
|
|
67
|
+
const measurement = require("./measurement-BoNTUBAp.cjs");
|
|
68
|
+
const surfaceBuilders = require("./surfaceBuilders-5VA34a3_.cjs");
|
|
69
69
|
const query = require("./query.cjs");
|
|
70
|
-
const solidBuilders = require("./solidBuilders-
|
|
71
|
-
const
|
|
72
|
-
const cornerFinder = require("./cornerFinder-3zfbQvXg.cjs");
|
|
70
|
+
const solidBuilders = require("./solidBuilders-994_MQwB.cjs");
|
|
71
|
+
const cornerFinder = require("./cornerFinder-ZmOyOOsh.cjs");
|
|
73
72
|
const worker = require("./worker.cjs");
|
|
74
73
|
function supportsProjection(kernel) {
|
|
75
74
|
return "projectShape" in kernel;
|
|
@@ -1257,73 +1256,21 @@ class BrepkitAdapter {
|
|
|
1257
1256
|
return edgeHandle(id);
|
|
1258
1257
|
}
|
|
1259
1258
|
makeTangentArc(startPoint, startTangent, endPoint) {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
ch[1] - chDotT * t[1],
|
|
1276
|
-
ch[2] - chDotT * t[2]
|
|
1277
|
-
];
|
|
1278
|
-
const perpLen = Math.sqrt(perp[0] ** 2 + perp[1] ** 2 + perp[2] ** 2);
|
|
1279
|
-
if (perpLen < 1e-12) return this.makeLineEdge(startPoint, endPoint);
|
|
1280
|
-
const n = [perp[0] / perpLen, perp[1] / perpLen, perp[2] / perpLen];
|
|
1281
|
-
const chord2 = ch[0] ** 2 + ch[1] ** 2 + ch[2] ** 2;
|
|
1282
|
-
const nDotCh = n[0] * ch[0] + n[1] * ch[1] + n[2] * ch[2];
|
|
1283
|
-
const s = -chord2 / (2 * nDotCh);
|
|
1284
|
-
const center = [
|
|
1285
|
-
startPoint[0] + s * n[0],
|
|
1286
|
-
startPoint[1] + s * n[1],
|
|
1287
|
-
startPoint[2] + s * n[2]
|
|
1288
|
-
];
|
|
1289
|
-
const radius = Math.abs(s);
|
|
1290
|
-
const e1 = [
|
|
1291
|
-
(startPoint[0] - center[0]) / radius,
|
|
1292
|
-
(startPoint[1] - center[1]) / radius,
|
|
1293
|
-
(startPoint[2] - center[2]) / radius
|
|
1294
|
-
];
|
|
1295
|
-
const e2 = [
|
|
1296
|
-
(endPoint[0] - center[0]) / radius,
|
|
1297
|
-
(endPoint[1] - center[1]) / radius,
|
|
1298
|
-
(endPoint[2] - center[2]) / radius
|
|
1299
|
-
];
|
|
1300
|
-
let mx = e1[0] + e2[0];
|
|
1301
|
-
let my = e1[1] + e2[1];
|
|
1302
|
-
let mz = e1[2] + e2[2];
|
|
1303
|
-
let mLen = Math.sqrt(mx * mx + my * my + mz * mz);
|
|
1304
|
-
if (mLen < 1e-12) {
|
|
1305
|
-
mx = t[0];
|
|
1306
|
-
my = t[1];
|
|
1307
|
-
mz = t[2];
|
|
1308
|
-
mLen = 1;
|
|
1309
|
-
}
|
|
1310
|
-
const mid = [
|
|
1311
|
-
center[0] + radius * mx / mLen,
|
|
1312
|
-
center[1] + radius * my / mLen,
|
|
1313
|
-
center[2] + radius * mz / mLen
|
|
1314
|
-
];
|
|
1315
|
-
const toMid = [
|
|
1316
|
-
mid[0] - startPoint[0],
|
|
1317
|
-
mid[1] - startPoint[1],
|
|
1318
|
-
mid[2] - startPoint[2]
|
|
1319
|
-
];
|
|
1320
|
-
const dotTM = t[0] * toMid[0] + t[1] * toMid[1] + t[2] * toMid[2];
|
|
1321
|
-
if (dotTM < 0) {
|
|
1322
|
-
mid[0] = center[0] - radius * mx / mLen;
|
|
1323
|
-
mid[1] = center[1] - radius * my / mLen;
|
|
1324
|
-
mid[2] = center[2] - radius * mz / mLen;
|
|
1325
|
-
}
|
|
1326
|
-
return this.makeArcEdge(startPoint, mid, endPoint);
|
|
1259
|
+
if (!this.bk.makeTangentArc3d) {
|
|
1260
|
+
throw new Error("makeTangentArc requires brepkit-wasm >= 1.1.0");
|
|
1261
|
+
}
|
|
1262
|
+
const id = this.bk.makeTangentArc3d(
|
|
1263
|
+
startPoint[0],
|
|
1264
|
+
startPoint[1],
|
|
1265
|
+
startPoint[2],
|
|
1266
|
+
startTangent[0],
|
|
1267
|
+
startTangent[1],
|
|
1268
|
+
startTangent[2],
|
|
1269
|
+
endPoint[0],
|
|
1270
|
+
endPoint[1],
|
|
1271
|
+
endPoint[2]
|
|
1272
|
+
);
|
|
1273
|
+
return edgeHandle(id);
|
|
1327
1274
|
}
|
|
1328
1275
|
makeHelixWire(pitch, height, radius, center, _direction, leftHanded) {
|
|
1329
1276
|
const turns = height / pitch;
|
|
@@ -2686,8 +2633,8 @@ class BrepkitAdapter {
|
|
|
2686
2633
|
if (!isBrepkitHandle(shape2)) return false;
|
|
2687
2634
|
if (shape2.type !== "solid") return true;
|
|
2688
2635
|
try {
|
|
2689
|
-
const
|
|
2690
|
-
return
|
|
2636
|
+
const errors = this.bk.validateSolidRelaxed(shape2.id);
|
|
2637
|
+
return errors === 0;
|
|
2691
2638
|
} catch (e) {
|
|
2692
2639
|
console.warn("brepkit: isValid check failed:", e);
|
|
2693
2640
|
return false;
|
|
@@ -2697,8 +2644,8 @@ class BrepkitAdapter {
|
|
|
2697
2644
|
if (!isBrepkitHandle(shape2)) return false;
|
|
2698
2645
|
if (shape2.type !== "solid") return true;
|
|
2699
2646
|
try {
|
|
2700
|
-
const
|
|
2701
|
-
return
|
|
2647
|
+
const errors = this.bk.validateSolid(shape2.id);
|
|
2648
|
+
return errors === 0;
|
|
2702
2649
|
} catch (e) {
|
|
2703
2650
|
console.warn("brepkit: isValidStrict check failed:", e);
|
|
2704
2651
|
return false;
|
|
@@ -4750,20 +4697,20 @@ const errorFactories = {
|
|
|
4750
4697
|
};
|
|
4751
4698
|
function kernelCall(fn, code, message, kind = "KERNEL_OPERATION") {
|
|
4752
4699
|
try {
|
|
4753
|
-
return
|
|
4700
|
+
return result.ok(shapeTypes.castShape(fn()));
|
|
4754
4701
|
} catch (e) {
|
|
4755
4702
|
const rawMessage = e instanceof Error ? e.message : String(e);
|
|
4756
|
-
const translatedMessage = kind === "KERNEL_OPERATION" ?
|
|
4757
|
-
return
|
|
4703
|
+
const translatedMessage = kind === "KERNEL_OPERATION" ? result.translateKernelError(rawMessage) : rawMessage;
|
|
4704
|
+
return result.err(errorFactories[kind](code, `${message}: ${translatedMessage}`, e));
|
|
4758
4705
|
}
|
|
4759
4706
|
}
|
|
4760
4707
|
function kernelCallRaw(fn, code, message, kind = "KERNEL_OPERATION") {
|
|
4761
4708
|
try {
|
|
4762
|
-
return
|
|
4709
|
+
return result.ok(fn());
|
|
4763
4710
|
} catch (e) {
|
|
4764
4711
|
const rawMessage = e instanceof Error ? e.message : String(e);
|
|
4765
|
-
const translatedMessage = kind === "KERNEL_OPERATION" ?
|
|
4766
|
-
return
|
|
4712
|
+
const translatedMessage = kind === "KERNEL_OPERATION" ? result.translateKernelError(rawMessage) : rawMessage;
|
|
4713
|
+
return result.err(errorFactories[kind](code, `${message}: ${translatedMessage}`, e));
|
|
4767
4714
|
}
|
|
4768
4715
|
}
|
|
4769
4716
|
function kernelCallScoped(fn, code, message, kind = "KERNEL_OPERATION") {
|
|
@@ -4800,8 +4747,8 @@ const CURVE_TYPE_BY_INT = [
|
|
|
4800
4747
|
const findCurveType = (type) => {
|
|
4801
4748
|
const idx = typeof type === "number" ? type : Number(type?.value ?? type);
|
|
4802
4749
|
const curveType = CURVE_TYPE_BY_INT[idx];
|
|
4803
|
-
if (!curveType) return
|
|
4804
|
-
return
|
|
4750
|
+
if (!curveType) return result.err(result.typeCastError("UNKNOWN_CURVE_TYPE", "Unknown curve type"));
|
|
4751
|
+
return result.ok(curveType);
|
|
4805
4752
|
};
|
|
4806
4753
|
const BOPAlgo_GlueShift = 1;
|
|
4807
4754
|
const BOPAlgo_GlueFull = 2;
|
|
@@ -4870,11 +4817,11 @@ function withNearestPostFilter(baseFinder, nearestPoint) {
|
|
|
4870
4817
|
const findUniqueNearest = (shape2) => {
|
|
4871
4818
|
const nearest = findAllNearest(shape2);
|
|
4872
4819
|
if (nearest.length === 0) {
|
|
4873
|
-
return
|
|
4874
|
-
|
|
4820
|
+
return result.err(
|
|
4821
|
+
result.queryError("FINDER_NOT_UNIQUE", "Finder expected a unique match but found 0 element(s)")
|
|
4875
4822
|
);
|
|
4876
4823
|
}
|
|
4877
|
-
return
|
|
4824
|
+
return result.ok(nearest[0]);
|
|
4878
4825
|
};
|
|
4879
4826
|
return {
|
|
4880
4827
|
...baseFinder,
|
|
@@ -4951,9 +4898,9 @@ const REC601_G = 0.587;
|
|
|
4951
4898
|
const REC601_B = 0.114;
|
|
4952
4899
|
function surfaceFromGrid(heights, options = {}) {
|
|
4953
4900
|
if (heights.length < 2) {
|
|
4954
|
-
return
|
|
4955
|
-
|
|
4956
|
-
|
|
4901
|
+
return result.err(
|
|
4902
|
+
result.validationError(
|
|
4903
|
+
result.BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
4957
4904
|
`surfaceFromGrid: need at least 2 rows, got ${heights.length}`
|
|
4958
4905
|
)
|
|
4959
4906
|
);
|
|
@@ -4961,9 +4908,9 @@ function surfaceFromGrid(heights, options = {}) {
|
|
|
4961
4908
|
const rows = heights.length;
|
|
4962
4909
|
const cols = heights[0]?.length ?? 0;
|
|
4963
4910
|
if (cols < 2) {
|
|
4964
|
-
return
|
|
4965
|
-
|
|
4966
|
-
|
|
4911
|
+
return result.err(
|
|
4912
|
+
result.validationError(
|
|
4913
|
+
result.BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
4967
4914
|
`surfaceFromGrid: need at least 2 columns, got ${cols}`
|
|
4968
4915
|
)
|
|
4969
4916
|
);
|
|
@@ -4971,9 +4918,9 @@ function surfaceFromGrid(heights, options = {}) {
|
|
|
4971
4918
|
for (let r = 0; r < rows; r++) {
|
|
4972
4919
|
const row = heights[r];
|
|
4973
4920
|
if (!row || row.length !== cols) {
|
|
4974
|
-
return
|
|
4975
|
-
|
|
4976
|
-
|
|
4921
|
+
return result.err(
|
|
4922
|
+
result.validationError(
|
|
4923
|
+
result.BrepErrorCode.SURFACE_GRID_JAGGED,
|
|
4977
4924
|
`surfaceFromGrid: row ${r} has ${row?.length ?? 0} columns, expected ${cols}`
|
|
4978
4925
|
)
|
|
4979
4926
|
);
|
|
@@ -4990,7 +4937,7 @@ function surfaceFromGrid(heights, options = {}) {
|
|
|
4990
4937
|
return buildTriangulatedSurface(heights, rows, cols, dx, dy, scaleZ);
|
|
4991
4938
|
} catch (e) {
|
|
4992
4939
|
const raw = e instanceof Error ? e.message : String(e);
|
|
4993
|
-
return
|
|
4940
|
+
return result.err(result.kernelError(result.BrepErrorCode.SURFACE_FAILED, `surfaceFromGrid failed: ${raw}`, e));
|
|
4994
4941
|
}
|
|
4995
4942
|
}
|
|
4996
4943
|
function buildBSplineSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
@@ -5005,10 +4952,10 @@ function buildBSplineSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
|
5005
4952
|
const faceShape = shapeTypes.getKernel().bsplineSurface(points, rows, cols);
|
|
5006
4953
|
const shape2 = shapeTypes.castShape(faceShape);
|
|
5007
4954
|
if (shapeTypes.isFace(shape2)) {
|
|
5008
|
-
return
|
|
4955
|
+
return result.ok(shape2);
|
|
5009
4956
|
}
|
|
5010
4957
|
shape2[Symbol.dispose]();
|
|
5011
|
-
return
|
|
4958
|
+
return result.err(result.kernelError(result.BrepErrorCode.SURFACE_FAILED, "B-spline surface did not produce a face"));
|
|
5012
4959
|
}
|
|
5013
4960
|
function buildTriangulatedSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
5014
4961
|
const points = [];
|
|
@@ -5022,23 +4969,23 @@ function buildTriangulatedSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
|
5022
4969
|
const resultShape = shapeTypes.getKernel().triangulatedSurface(points, rows, cols);
|
|
5023
4970
|
const shape2 = shapeTypes.castShape(resultShape);
|
|
5024
4971
|
if (shapeTypes.isFace(shape2)) {
|
|
5025
|
-
return
|
|
4972
|
+
return result.ok(shape2);
|
|
5026
4973
|
}
|
|
5027
4974
|
if (shapeTypes.isShell(shape2)) {
|
|
5028
|
-
return
|
|
4975
|
+
return result.ok(shape2);
|
|
5029
4976
|
}
|
|
5030
4977
|
shape2[Symbol.dispose]();
|
|
5031
|
-
return
|
|
5032
|
-
|
|
4978
|
+
return result.err(
|
|
4979
|
+
result.kernelError(result.BrepErrorCode.SURFACE_FAILED, "surfaceFromGrid: unexpected shape type from sewing")
|
|
5033
4980
|
);
|
|
5034
4981
|
}
|
|
5035
4982
|
async function surfaceFromImage(blob, options = {}) {
|
|
5036
4983
|
const channel = options.channel ?? "luminance";
|
|
5037
4984
|
const downsample = Math.max(1, Math.round(options.downsample ?? 1));
|
|
5038
4985
|
if (typeof createImageBitmap !== "function") {
|
|
5039
|
-
return
|
|
5040
|
-
|
|
5041
|
-
|
|
4986
|
+
return result.err(
|
|
4987
|
+
result.ioError(
|
|
4988
|
+
result.BrepErrorCode.SURFACE_FAILED,
|
|
5042
4989
|
"surfaceFromImage requires createImageBitmap (not available in this environment)"
|
|
5043
4990
|
)
|
|
5044
4991
|
);
|
|
@@ -5047,9 +4994,9 @@ async function surfaceFromImage(blob, options = {}) {
|
|
|
5047
4994
|
try {
|
|
5048
4995
|
bitmap = await createImageBitmap(blob);
|
|
5049
4996
|
} catch (e) {
|
|
5050
|
-
return
|
|
5051
|
-
|
|
5052
|
-
|
|
4997
|
+
return result.err(
|
|
4998
|
+
result.ioError(
|
|
4999
|
+
result.BrepErrorCode.SURFACE_FAILED,
|
|
5053
5000
|
`surfaceFromImage: failed to decode image — ${e instanceof Error ? e.message : String(e)}`
|
|
5054
5001
|
)
|
|
5055
5002
|
);
|
|
@@ -5058,18 +5005,18 @@ async function surfaceFromImage(blob, options = {}) {
|
|
|
5058
5005
|
const h = bitmap.height;
|
|
5059
5006
|
if (w < 2 || h < 2) {
|
|
5060
5007
|
bitmap.close();
|
|
5061
|
-
return
|
|
5062
|
-
|
|
5063
|
-
|
|
5008
|
+
return result.err(
|
|
5009
|
+
result.validationError(
|
|
5010
|
+
result.BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
5064
5011
|
`surfaceFromImage: image too small (${w}x${h}), need at least 2x2`
|
|
5065
5012
|
)
|
|
5066
5013
|
);
|
|
5067
5014
|
}
|
|
5068
5015
|
if (typeof OffscreenCanvas !== "function") {
|
|
5069
5016
|
bitmap.close();
|
|
5070
|
-
return
|
|
5071
|
-
|
|
5072
|
-
|
|
5017
|
+
return result.err(
|
|
5018
|
+
result.ioError(
|
|
5019
|
+
result.BrepErrorCode.SURFACE_FAILED,
|
|
5073
5020
|
"surfaceFromImage requires OffscreenCanvas (not available in this environment)"
|
|
5074
5021
|
)
|
|
5075
5022
|
);
|
|
@@ -5078,8 +5025,8 @@ async function surfaceFromImage(blob, options = {}) {
|
|
|
5078
5025
|
const ctx = canvas.getContext("2d");
|
|
5079
5026
|
if (!ctx) {
|
|
5080
5027
|
bitmap.close();
|
|
5081
|
-
return
|
|
5082
|
-
|
|
5028
|
+
return result.err(
|
|
5029
|
+
result.ioError(result.BrepErrorCode.SURFACE_FAILED, "surfaceFromImage: could not get 2D canvas context")
|
|
5083
5030
|
);
|
|
5084
5031
|
}
|
|
5085
5032
|
ctx.drawImage(bitmap, 0, 0);
|
|
@@ -5121,15 +5068,15 @@ async function surfaceFromImage(blob, options = {}) {
|
|
|
5121
5068
|
}
|
|
5122
5069
|
function validateNotNull$1(shape2, label) {
|
|
5123
5070
|
if (shapeTypes.getKernel().isNull(shape2.wrapped)) {
|
|
5124
|
-
return
|
|
5071
|
+
return result.err(result.validationError(result.BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
|
|
5125
5072
|
}
|
|
5126
|
-
return
|
|
5073
|
+
return result.ok(void 0);
|
|
5127
5074
|
}
|
|
5128
5075
|
function hull(shapes, options = {}) {
|
|
5129
5076
|
if (shapes.length === 0) {
|
|
5130
|
-
return
|
|
5131
|
-
|
|
5132
|
-
|
|
5077
|
+
return result.err(
|
|
5078
|
+
result.validationError(
|
|
5079
|
+
result.BrepErrorCode.HULL_EMPTY_INPUT,
|
|
5133
5080
|
"hull: at least one shape is required",
|
|
5134
5081
|
void 0,
|
|
5135
5082
|
void 0,
|
|
@@ -5139,7 +5086,7 @@ function hull(shapes, options = {}) {
|
|
|
5139
5086
|
}
|
|
5140
5087
|
for (const [i, shape2] of shapes.entries()) {
|
|
5141
5088
|
const check = validateNotNull$1(shape2, `hull: shapes[${i}]`);
|
|
5142
|
-
if (
|
|
5089
|
+
if (result.isErr(check)) return check;
|
|
5143
5090
|
}
|
|
5144
5091
|
const tolerance = options.tolerance ?? 0.1;
|
|
5145
5092
|
try {
|
|
@@ -5148,20 +5095,20 @@ function hull(shapes, options = {}) {
|
|
|
5148
5095
|
const resultOc = kernel.hull(ocShapes, tolerance);
|
|
5149
5096
|
const cast = shapeTypes.castShape(resultOc);
|
|
5150
5097
|
if (!shapeTypes.isSolid(cast)) {
|
|
5151
|
-
return
|
|
5152
|
-
|
|
5153
|
-
|
|
5098
|
+
return result.err(
|
|
5099
|
+
result.kernelError(
|
|
5100
|
+
result.BrepErrorCode.HULL_NOT_3D,
|
|
5154
5101
|
"Hull result is not a solid; input may be degenerate"
|
|
5155
5102
|
)
|
|
5156
5103
|
);
|
|
5157
5104
|
}
|
|
5158
|
-
return
|
|
5105
|
+
return result.ok(cast);
|
|
5159
5106
|
} catch (e) {
|
|
5160
5107
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5161
5108
|
if (raw.includes("coplanar") || raw.includes("fewer than") || raw.includes("degenerate")) {
|
|
5162
|
-
return
|
|
5109
|
+
return result.err(result.kernelError(result.BrepErrorCode.HULL_DEGENERATE, `Hull degenerate: ${raw}`, e));
|
|
5163
5110
|
}
|
|
5164
|
-
return
|
|
5111
|
+
return result.err(result.kernelError(result.BrepErrorCode.HULL_FAILED, `Hull operation failed: ${raw}`, e));
|
|
5165
5112
|
}
|
|
5166
5113
|
}
|
|
5167
5114
|
function detectSphere(shape2) {
|
|
@@ -5180,18 +5127,18 @@ function minkowskiSphere(shape2, radius, tolerance) {
|
|
|
5180
5127
|
const wrapped = shapeTypes.castShape(resultShape);
|
|
5181
5128
|
if (!shapeTypes.isShape3D(wrapped)) {
|
|
5182
5129
|
wrapped[Symbol.dispose]();
|
|
5183
|
-
return
|
|
5184
|
-
|
|
5185
|
-
|
|
5130
|
+
return result.err(
|
|
5131
|
+
result.typeCastError(
|
|
5132
|
+
result.BrepErrorCode.MINKOWSKI_NOT_3D,
|
|
5186
5133
|
"Minkowski sphere offset did not produce a 3D shape"
|
|
5187
5134
|
)
|
|
5188
5135
|
);
|
|
5189
5136
|
}
|
|
5190
|
-
return
|
|
5137
|
+
return result.ok(wrapped);
|
|
5191
5138
|
} catch (e) {
|
|
5192
5139
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5193
|
-
return
|
|
5194
|
-
|
|
5140
|
+
return result.err(
|
|
5141
|
+
result.kernelError(result.BrepErrorCode.MINKOWSKI_FAILED, `Minkowski sphere offset failed: ${raw}`, e, {
|
|
5195
5142
|
operation: "minkowski",
|
|
5196
5143
|
fastPath: "sphere"
|
|
5197
5144
|
})
|
|
@@ -5204,9 +5151,9 @@ function minkowskiGeneral(shape2, tool, tolerance) {
|
|
|
5204
5151
|
const shapeVerts = shapeFns.getVertices(shape2);
|
|
5205
5152
|
const toolVerts = shapeFns.getVertices(tool);
|
|
5206
5153
|
if (shapeVerts.length === 0 || toolVerts.length === 0) {
|
|
5207
|
-
return
|
|
5208
|
-
|
|
5209
|
-
|
|
5154
|
+
return result.err(
|
|
5155
|
+
result.kernelError(
|
|
5156
|
+
result.BrepErrorCode.MINKOWSKI_FAILED,
|
|
5210
5157
|
"Minkowski sum: one or both shapes have no vertices",
|
|
5211
5158
|
void 0,
|
|
5212
5159
|
{
|
|
@@ -5227,15 +5174,15 @@ function minkowskiGeneral(shape2, tool, tolerance) {
|
|
|
5227
5174
|
const wrapped = shapeTypes.castShape(hullShape);
|
|
5228
5175
|
if (!shapeTypes.isShape3D(wrapped)) {
|
|
5229
5176
|
wrapped[Symbol.dispose]();
|
|
5230
|
-
return
|
|
5231
|
-
|
|
5177
|
+
return result.err(
|
|
5178
|
+
result.typeCastError(result.BrepErrorCode.MINKOWSKI_NOT_3D, "Minkowski hull did not produce a 3D shape")
|
|
5232
5179
|
);
|
|
5233
5180
|
}
|
|
5234
|
-
return
|
|
5181
|
+
return result.ok(wrapped);
|
|
5235
5182
|
} catch (e) {
|
|
5236
5183
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5237
|
-
return
|
|
5238
|
-
|
|
5184
|
+
return result.err(
|
|
5185
|
+
result.kernelError(result.BrepErrorCode.MINKOWSKI_FAILED, `Minkowski general path failed: ${raw}`, e, {
|
|
5239
5186
|
operation: "minkowski"
|
|
5240
5187
|
})
|
|
5241
5188
|
);
|
|
@@ -5244,16 +5191,16 @@ function minkowskiGeneral(shape2, tool, tolerance) {
|
|
|
5244
5191
|
function minkowski(shape2, tool, options = {}) {
|
|
5245
5192
|
const { tolerance = 1e-6 } = options;
|
|
5246
5193
|
if (shapeTypes.getKernel().isNull(shape2.wrapped)) {
|
|
5247
|
-
return
|
|
5194
|
+
return result.err(result.validationError(result.BrepErrorCode.NULL_SHAPE_INPUT, "minkowski: shape is a null shape"));
|
|
5248
5195
|
}
|
|
5249
5196
|
if (shapeTypes.getKernel().isNull(tool.wrapped)) {
|
|
5250
|
-
return
|
|
5251
|
-
|
|
5197
|
+
return result.err(
|
|
5198
|
+
result.validationError(result.BrepErrorCode.MINKOWSKI_NULL_TOOL, "minkowski: tool is a null shape")
|
|
5252
5199
|
);
|
|
5253
5200
|
}
|
|
5254
5201
|
if (!shapeTypes.isShape3D(shape2) || !shapeTypes.isShape3D(tool)) {
|
|
5255
|
-
return
|
|
5256
|
-
|
|
5202
|
+
return result.err(
|
|
5203
|
+
result.validationError(result.BrepErrorCode.MINKOWSKI_NOT_3D, "minkowski: both shape and tool must be 3D")
|
|
5257
5204
|
);
|
|
5258
5205
|
}
|
|
5259
5206
|
const sphereRadius = detectSphere(tool);
|
|
@@ -5265,17 +5212,17 @@ function minkowski(shape2, tool, options = {}) {
|
|
|
5265
5212
|
function polyhedron(points, faces, options = {}) {
|
|
5266
5213
|
const { tolerance = 1e-6 } = options;
|
|
5267
5214
|
if (points.length < 4) {
|
|
5268
|
-
return
|
|
5269
|
-
|
|
5270
|
-
|
|
5215
|
+
return result.err(
|
|
5216
|
+
result.validationError(
|
|
5217
|
+
result.BrepErrorCode.POLYHEDRON_INSUFFICIENT_POINTS,
|
|
5271
5218
|
`polyhedron: need at least 4 points, got ${points.length}`
|
|
5272
5219
|
)
|
|
5273
5220
|
);
|
|
5274
5221
|
}
|
|
5275
5222
|
if (faces.length < 4) {
|
|
5276
|
-
return
|
|
5277
|
-
|
|
5278
|
-
|
|
5223
|
+
return result.err(
|
|
5224
|
+
result.validationError(
|
|
5225
|
+
result.BrepErrorCode.POLYHEDRON_INSUFFICIENT_FACES,
|
|
5279
5226
|
`polyhedron: need at least 4 faces, got ${faces.length}`
|
|
5280
5227
|
)
|
|
5281
5228
|
);
|
|
@@ -5284,9 +5231,9 @@ function polyhedron(points, faces, options = {}) {
|
|
|
5284
5231
|
for (const [fi, face] of faces.entries()) {
|
|
5285
5232
|
for (const idx of face) {
|
|
5286
5233
|
if (idx < 0 || idx >= points.length) {
|
|
5287
|
-
return
|
|
5288
|
-
|
|
5289
|
-
|
|
5234
|
+
return result.err(
|
|
5235
|
+
result.validationError(
|
|
5236
|
+
result.BrepErrorCode.POLYHEDRON_INVALID_INDEX,
|
|
5290
5237
|
`polyhedron: face ${fi} has out-of-range index ${idx} (${points.length} points)`
|
|
5291
5238
|
)
|
|
5292
5239
|
);
|
|
@@ -5305,21 +5252,21 @@ function polyhedron(points, faces, options = {}) {
|
|
|
5305
5252
|
const cast = shapeTypes.castShape(resultOc);
|
|
5306
5253
|
if (!shapeTypes.isSolid(cast)) {
|
|
5307
5254
|
cast[Symbol.dispose]();
|
|
5308
|
-
return
|
|
5309
|
-
|
|
5255
|
+
return result.err(
|
|
5256
|
+
result.kernelError(result.BrepErrorCode.POLYHEDRON_FAILED, "Polyhedron did not produce a solid")
|
|
5310
5257
|
);
|
|
5311
5258
|
}
|
|
5312
|
-
return
|
|
5259
|
+
return result.ok(cast);
|
|
5313
5260
|
} catch (e) {
|
|
5314
5261
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5315
|
-
return
|
|
5262
|
+
return result.err(result.kernelError(result.BrepErrorCode.POLYHEDRON_FAILED, `Polyhedron failed: ${raw}`, e));
|
|
5316
5263
|
}
|
|
5317
5264
|
}
|
|
5318
5265
|
function multiSectionSweep(sections, spine, options) {
|
|
5319
5266
|
if (sections.length < 2) {
|
|
5320
|
-
return
|
|
5321
|
-
|
|
5322
|
-
|
|
5267
|
+
return result.err(
|
|
5268
|
+
result.validationError(
|
|
5269
|
+
result.BrepErrorCode.MULTI_SWEEP_INSUFFICIENT_SECTIONS,
|
|
5323
5270
|
`Multi-section sweep requires at least 2 sections, got ${sections.length}`
|
|
5324
5271
|
)
|
|
5325
5272
|
);
|
|
@@ -5329,9 +5276,9 @@ function multiSectionSweep(sections, spine, options) {
|
|
|
5329
5276
|
for (let i = 0; i < explicitLocations.length; i++) {
|
|
5330
5277
|
const loc = explicitLocations[i];
|
|
5331
5278
|
if (loc !== void 0 && (loc < 0 || loc > 1)) {
|
|
5332
|
-
return
|
|
5333
|
-
|
|
5334
|
-
|
|
5279
|
+
return result.err(
|
|
5280
|
+
result.validationError(
|
|
5281
|
+
result.BrepErrorCode.MULTI_SWEEP_FAILED,
|
|
5335
5282
|
`Section ${i} location ${loc} is out of range [0, 1]`
|
|
5336
5283
|
)
|
|
5337
5284
|
);
|
|
@@ -5340,9 +5287,9 @@ function multiSectionSweep(sections, spine, options) {
|
|
|
5340
5287
|
const definedLocs = explicitLocations.filter((l) => l !== void 0);
|
|
5341
5288
|
for (let i = 1; i < definedLocs.length; i++) {
|
|
5342
5289
|
if ((definedLocs[i] ?? 0) <= (definedLocs[i - 1] ?? 0)) {
|
|
5343
|
-
return
|
|
5344
|
-
|
|
5345
|
-
|
|
5290
|
+
return result.err(
|
|
5291
|
+
result.validationError(
|
|
5292
|
+
result.BrepErrorCode.MULTI_SWEEP_FAILED,
|
|
5346
5293
|
"Section locations must be strictly increasing"
|
|
5347
5294
|
)
|
|
5348
5295
|
);
|
|
@@ -5367,17 +5314,17 @@ function multiSectionSweep(sections, spine, options) {
|
|
|
5367
5314
|
positionedWires.push(kernel.downcast(positioned, "wire"));
|
|
5368
5315
|
}
|
|
5369
5316
|
const loftResult = kernel.loftAdvanced(positionedWires, { solid, ruled, tolerance });
|
|
5370
|
-
const
|
|
5371
|
-
if (!shapeTypes.isShape3D(
|
|
5372
|
-
return
|
|
5373
|
-
|
|
5317
|
+
const result$1 = shapeTypes.castShape(loftResult);
|
|
5318
|
+
if (!shapeTypes.isShape3D(result$1)) {
|
|
5319
|
+
return result.err(
|
|
5320
|
+
result.typeCastError("MULTI_SWEEP_NOT_3D", "Multi-section sweep did not produce a 3D shape")
|
|
5374
5321
|
);
|
|
5375
5322
|
}
|
|
5376
|
-
return
|
|
5323
|
+
return result.ok(result$1);
|
|
5377
5324
|
} catch (e) {
|
|
5378
5325
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5379
|
-
return
|
|
5380
|
-
|
|
5326
|
+
return result.err(
|
|
5327
|
+
result.kernelError(result.BrepErrorCode.MULTI_SWEEP_FAILED, `Multi-section sweep failed: ${raw}`, e)
|
|
5381
5328
|
);
|
|
5382
5329
|
}
|
|
5383
5330
|
}
|
|
@@ -5394,14 +5341,14 @@ function guidedSweep(profile, spine, guides, options = {}) {
|
|
|
5394
5341
|
...tolerance !== void 0 ? { tolerance, boundTolerance: tolerance } : {}
|
|
5395
5342
|
});
|
|
5396
5343
|
const ocShape = typeof sweepResult === "object" && "shape" in sweepResult ? sweepResult.shape : sweepResult;
|
|
5397
|
-
const
|
|
5398
|
-
if (!shapeTypes.isShape3D(
|
|
5399
|
-
return
|
|
5344
|
+
const result$1 = shapeTypes.castShape(ocShape);
|
|
5345
|
+
if (!shapeTypes.isShape3D(result$1)) {
|
|
5346
|
+
return result.err(result.typeCastError("GUIDED_SWEEP_NOT_3D", "Guided sweep did not produce a 3D shape"));
|
|
5400
5347
|
}
|
|
5401
|
-
return
|
|
5348
|
+
return result.ok(result$1);
|
|
5402
5349
|
} catch (e) {
|
|
5403
5350
|
const raw = e instanceof Error ? e.message : String(e);
|
|
5404
|
-
return
|
|
5351
|
+
return result.err(result.kernelError(result.BrepErrorCode.GUIDED_SWEEP_FAILED, `Guided sweep failed: ${raw}`, e));
|
|
5405
5352
|
}
|
|
5406
5353
|
}
|
|
5407
5354
|
const EPS = 1e-10;
|
|
@@ -5836,17 +5783,17 @@ function roof(w, options) {
|
|
|
5836
5783
|
try {
|
|
5837
5784
|
const polygon = extractPolygon(w);
|
|
5838
5785
|
if (polygon.length < 3) {
|
|
5839
|
-
return
|
|
5840
|
-
|
|
5841
|
-
|
|
5786
|
+
return result.err(
|
|
5787
|
+
result.kernelError(
|
|
5788
|
+
result.BrepErrorCode.ROOF_FAILED,
|
|
5842
5789
|
"Wire must have at least 3 edges for roof generation"
|
|
5843
5790
|
)
|
|
5844
5791
|
);
|
|
5845
5792
|
}
|
|
5846
5793
|
const skeleton = computeStraightSkeleton(polygon);
|
|
5847
5794
|
if (skeleton.faces.length === 0) {
|
|
5848
|
-
return
|
|
5849
|
-
|
|
5795
|
+
return result.err(
|
|
5796
|
+
result.kernelError(result.BrepErrorCode.ROOF_FAILED, "Straight skeleton computation produced no faces")
|
|
5850
5797
|
);
|
|
5851
5798
|
}
|
|
5852
5799
|
const kernel = shapeTypes.getKernel();
|
|
@@ -5896,24 +5843,24 @@ function roof(w, options) {
|
|
|
5896
5843
|
}
|
|
5897
5844
|
}
|
|
5898
5845
|
if (triFaces.length === 0) {
|
|
5899
|
-
return
|
|
5900
|
-
|
|
5846
|
+
return result.err(
|
|
5847
|
+
result.kernelError(result.BrepErrorCode.ROOF_FAILED, "No valid triangular faces could be built")
|
|
5901
5848
|
);
|
|
5902
5849
|
}
|
|
5903
5850
|
try {
|
|
5904
5851
|
const solid = kernel.sewAndSolidify(triFaces, 1e-6);
|
|
5905
5852
|
const fixed = kernel.fixShape(solid);
|
|
5906
|
-
return
|
|
5853
|
+
return result.ok(shapeTypes.createSolid(fixed));
|
|
5907
5854
|
} catch {
|
|
5908
5855
|
try {
|
|
5909
|
-
return
|
|
5856
|
+
return result.ok(shapeTypes.createSolid(kernel.sew(triFaces, 1e-6)));
|
|
5910
5857
|
} catch {
|
|
5911
|
-
return
|
|
5858
|
+
return result.err(result.kernelError(result.BrepErrorCode.ROOF_FAILED, "Failed to sew roof faces"));
|
|
5912
5859
|
}
|
|
5913
5860
|
}
|
|
5914
5861
|
} catch (e) {
|
|
5915
5862
|
const msg = e instanceof Error ? e.message : String(e);
|
|
5916
|
-
return
|
|
5863
|
+
return result.err(result.kernelError(result.BrepErrorCode.ROOF_FAILED, `Roof generation failed: ${msg}`, e));
|
|
5917
5864
|
}
|
|
5918
5865
|
}
|
|
5919
5866
|
const UNSUPPORTED_DOF = {
|
|
@@ -5984,14 +5931,14 @@ function extractPair(a, b) {
|
|
|
5984
5931
|
const entA = extractEntity(a);
|
|
5985
5932
|
const entB = extractEntity(b);
|
|
5986
5933
|
if (!entA || !entB) {
|
|
5987
|
-
return
|
|
5988
|
-
|
|
5989
|
-
|
|
5934
|
+
return result.err(
|
|
5935
|
+
result.validationError(
|
|
5936
|
+
result.BrepErrorCode.ASSEMBLY_MATE_INVALID,
|
|
5990
5937
|
"solveAssembly: could not extract geometry from mate entities"
|
|
5991
5938
|
)
|
|
5992
5939
|
);
|
|
5993
5940
|
}
|
|
5994
|
-
return
|
|
5941
|
+
return result.ok({
|
|
5995
5942
|
entityA: { node: a.node, entity: entA },
|
|
5996
5943
|
entityB: { node: b.node, entity: entB }
|
|
5997
5944
|
});
|
|
@@ -6003,8 +5950,8 @@ function addMate(assembly, constraint) {
|
|
|
6003
5950
|
function solveAssembly(assembly) {
|
|
6004
5951
|
const mates = assembly.mates;
|
|
6005
5952
|
if (!mates || mates.length === 0) {
|
|
6006
|
-
return
|
|
6007
|
-
|
|
5953
|
+
return result.err(
|
|
5954
|
+
result.validationError(result.BrepErrorCode.ASSEMBLY_MATE_INVALID, "solveAssembly: no mates defined")
|
|
6008
5955
|
);
|
|
6009
5956
|
}
|
|
6010
5957
|
try {
|
|
@@ -6039,42 +5986,42 @@ function solveAssembly(assembly) {
|
|
|
6039
5986
|
solverConstraints.push({ type: "concentric", ...pair.value });
|
|
6040
5987
|
}
|
|
6041
5988
|
}
|
|
6042
|
-
const
|
|
6043
|
-
if (!
|
|
6044
|
-
const detail =
|
|
6045
|
-
return
|
|
5989
|
+
const result$1 = solveConstraints(nodes, solverConstraints);
|
|
5990
|
+
if (!result$1.converged) {
|
|
5991
|
+
const detail = result$1.unsupported.length > 0 ? `Unsupported constraint types: ${result$1.unsupported.join(", ")} (${result$1.dof} DOF unresolved)` : "Assembly constraint solver did not converge";
|
|
5992
|
+
return result.err(result.kernelError(result.BrepErrorCode.ASSEMBLY_NOT_CONVERGED, detail));
|
|
6046
5993
|
}
|
|
6047
|
-
return
|
|
6048
|
-
transforms:
|
|
6049
|
-
dof:
|
|
6050
|
-
converged:
|
|
5994
|
+
return result.ok({
|
|
5995
|
+
transforms: result$1.transforms,
|
|
5996
|
+
dof: result$1.dof,
|
|
5997
|
+
converged: result$1.converged
|
|
6051
5998
|
});
|
|
6052
5999
|
} catch (e) {
|
|
6053
6000
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6054
|
-
return
|
|
6055
|
-
|
|
6001
|
+
return result.err(
|
|
6002
|
+
result.kernelError(result.BrepErrorCode.ASSEMBLY_SOLVE_FAILED, `Assembly solve failed: ${raw}`, e)
|
|
6056
6003
|
);
|
|
6057
6004
|
}
|
|
6058
6005
|
}
|
|
6059
6006
|
function checkInterference(shape1, shape2, tolerance = 1e-6) {
|
|
6060
6007
|
if (shapeTypes.getKernel().isNull(shape1.wrapped)) {
|
|
6061
|
-
return
|
|
6062
|
-
|
|
6063
|
-
|
|
6008
|
+
return result.err(
|
|
6009
|
+
result.validationError(
|
|
6010
|
+
result.BrepErrorCode.NULL_SHAPE_INPUT,
|
|
6064
6011
|
"checkInterference: first shape is a null shape"
|
|
6065
6012
|
)
|
|
6066
6013
|
);
|
|
6067
6014
|
}
|
|
6068
6015
|
if (shapeTypes.getKernel().isNull(shape2.wrapped)) {
|
|
6069
|
-
return
|
|
6070
|
-
|
|
6071
|
-
|
|
6016
|
+
return result.err(
|
|
6017
|
+
result.validationError(
|
|
6018
|
+
result.BrepErrorCode.NULL_SHAPE_INPUT,
|
|
6072
6019
|
"checkInterference: second shape is a null shape"
|
|
6073
6020
|
)
|
|
6074
6021
|
);
|
|
6075
6022
|
}
|
|
6076
6023
|
const dist = shapeTypes.getKernel().distance(shape1.wrapped, shape2.wrapped);
|
|
6077
|
-
return
|
|
6024
|
+
return result.ok({
|
|
6078
6025
|
hasInterference: dist.value <= tolerance,
|
|
6079
6026
|
minDistance: dist.value,
|
|
6080
6027
|
pointOnShape1: dist.point1,
|
|
@@ -6087,9 +6034,9 @@ function checkAllInterferences(shapes, tolerance = 1e-6) {
|
|
|
6087
6034
|
shapes.forEach((si, i) => {
|
|
6088
6035
|
for (let j = i + 1; j < shapes.length; j++) {
|
|
6089
6036
|
if (aabbDisjoint(boxes[i], boxes[j], tolerance)) continue;
|
|
6090
|
-
const
|
|
6091
|
-
if (
|
|
6092
|
-
pairs.push({ i, j, result:
|
|
6037
|
+
const result$1 = result.unwrap(checkInterference(si, shapes[j], tolerance));
|
|
6038
|
+
if (result$1.hasInterference) {
|
|
6039
|
+
pairs.push({ i, j, result: result$1 });
|
|
6093
6040
|
}
|
|
6094
6041
|
}
|
|
6095
6042
|
});
|
|
@@ -6174,12 +6121,12 @@ async function importDXF(blob, options) {
|
|
|
6174
6121
|
try {
|
|
6175
6122
|
text = await blob.text();
|
|
6176
6123
|
} catch (cause) {
|
|
6177
|
-
return
|
|
6124
|
+
return result.err(result.ioError(result.BrepErrorCode.DXF_IMPORT_FAILED, "Failed to read DXF blob", cause));
|
|
6178
6125
|
}
|
|
6179
6126
|
const allEntities = parseEntities(text);
|
|
6180
6127
|
const entities = options?.layer !== void 0 ? allEntities.filter((e) => e.layer === options.layer) : allEntities;
|
|
6181
6128
|
if (entities.length === 0) {
|
|
6182
|
-
return
|
|
6129
|
+
return result.ok([]);
|
|
6183
6130
|
}
|
|
6184
6131
|
const edges = [];
|
|
6185
6132
|
try {
|
|
@@ -6190,13 +6137,13 @@ async function importDXF(blob, options) {
|
|
|
6190
6137
|
}
|
|
6191
6138
|
}
|
|
6192
6139
|
if (edges.length === 0) {
|
|
6193
|
-
return
|
|
6140
|
+
return result.ok([]);
|
|
6194
6141
|
}
|
|
6195
6142
|
const wire = shapeTypes.getKernel().makeWire(edges);
|
|
6196
|
-
return
|
|
6143
|
+
return result.ok([shapeTypes.createWire(wire)]);
|
|
6197
6144
|
} catch (cause) {
|
|
6198
|
-
return
|
|
6199
|
-
|
|
6145
|
+
return result.err(
|
|
6146
|
+
result.ioError(result.BrepErrorCode.DXF_IMPORT_FAILED, "Failed to convert DXF entities to geometry", cause)
|
|
6200
6147
|
);
|
|
6201
6148
|
} finally {
|
|
6202
6149
|
for (const edge of edges) {
|
|
@@ -6229,13 +6176,13 @@ async function importOBJ(blob) {
|
|
|
6229
6176
|
}
|
|
6230
6177
|
}
|
|
6231
6178
|
if (vertices.length === 0 || faces.length === 0) {
|
|
6232
|
-
return
|
|
6179
|
+
return result.err(result.ioError(result.BrepErrorCode.OBJ_IMPORT_FAILED, "OBJ file contains no valid geometry"));
|
|
6233
6180
|
}
|
|
6234
6181
|
try {
|
|
6235
6182
|
return buildSolidFromMesh$1(vertices, faces);
|
|
6236
6183
|
} catch (e) {
|
|
6237
6184
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6238
|
-
return
|
|
6185
|
+
return result.err(result.ioError(result.BrepErrorCode.OBJ_IMPORT_FAILED, `OBJ import failed: ${msg}`, e));
|
|
6239
6186
|
}
|
|
6240
6187
|
}
|
|
6241
6188
|
function buildSolidFromMesh$1(vertices, faces) {
|
|
@@ -6260,17 +6207,17 @@ function buildSolidFromMesh$1(vertices, faces) {
|
|
|
6260
6207
|
}
|
|
6261
6208
|
}
|
|
6262
6209
|
if (triFaces.length === 0) {
|
|
6263
|
-
return
|
|
6264
|
-
|
|
6210
|
+
return result.err(
|
|
6211
|
+
result.ioError(result.BrepErrorCode.OBJ_IMPORT_FAILED, "No valid triangular faces could be built")
|
|
6265
6212
|
);
|
|
6266
6213
|
}
|
|
6267
6214
|
try {
|
|
6268
|
-
return
|
|
6215
|
+
return result.ok(shapeTypes.castShape(kernel.sewAndSolidify(triFaces, 1e-6)));
|
|
6269
6216
|
} catch {
|
|
6270
6217
|
try {
|
|
6271
|
-
return
|
|
6218
|
+
return result.ok(shapeTypes.castShape(kernel.sew(triFaces, 1e-6)));
|
|
6272
6219
|
} catch {
|
|
6273
|
-
return
|
|
6220
|
+
return result.err(result.ioError(result.BrepErrorCode.OBJ_IMPORT_FAILED, "Failed to sew triangular faces"));
|
|
6274
6221
|
}
|
|
6275
6222
|
}
|
|
6276
6223
|
}
|
|
@@ -6376,7 +6323,7 @@ function buildSolidFromMesh(mesh2) {
|
|
|
6376
6323
|
const faces = mesh2.triangles;
|
|
6377
6324
|
try {
|
|
6378
6325
|
const solid = kernel.buildSolidFromFaces(points, faces, 1e-6);
|
|
6379
|
-
return
|
|
6326
|
+
return result.ok(shapeTypes.castShape(solid));
|
|
6380
6327
|
} catch {
|
|
6381
6328
|
const triFaces = [];
|
|
6382
6329
|
for (const [v1, v2, v3] of mesh2.triangles) {
|
|
@@ -6390,17 +6337,17 @@ function buildSolidFromMesh(mesh2) {
|
|
|
6390
6337
|
}
|
|
6391
6338
|
}
|
|
6392
6339
|
if (triFaces.length === 0) {
|
|
6393
|
-
return
|
|
6394
|
-
|
|
6340
|
+
return result.err(
|
|
6341
|
+
result.ioError(result.BrepErrorCode.THREEMF_IMPORT_FAILED, "No valid triangular faces could be built")
|
|
6395
6342
|
);
|
|
6396
6343
|
}
|
|
6397
6344
|
try {
|
|
6398
|
-
return
|
|
6345
|
+
return result.ok(shapeTypes.castShape(kernel.sewAndSolidify(triFaces, 1e-6)));
|
|
6399
6346
|
} catch {
|
|
6400
6347
|
try {
|
|
6401
|
-
return
|
|
6348
|
+
return result.ok(shapeTypes.castShape(kernel.sew(triFaces, 1e-6)));
|
|
6402
6349
|
} catch {
|
|
6403
|
-
return
|
|
6350
|
+
return result.err(result.ioError(result.BrepErrorCode.THREEMF_IMPORT_FAILED, "Failed to sew triangular faces"));
|
|
6404
6351
|
}
|
|
6405
6352
|
}
|
|
6406
6353
|
}
|
|
@@ -6411,9 +6358,9 @@ async function importThreeMF(blob) {
|
|
|
6411
6358
|
const data = new Uint8Array(arrayBuf);
|
|
6412
6359
|
const modelData = extractFromZip(data, "3D/3dmodel.model");
|
|
6413
6360
|
if (!modelData) {
|
|
6414
|
-
return
|
|
6415
|
-
|
|
6416
|
-
|
|
6361
|
+
return result.err(
|
|
6362
|
+
result.ioError(
|
|
6363
|
+
result.BrepErrorCode.THREEMF_IMPORT_FAILED,
|
|
6417
6364
|
"3MF archive does not contain 3D/3dmodel.model (or uses unsupported compression)"
|
|
6418
6365
|
)
|
|
6419
6366
|
);
|
|
@@ -6421,14 +6368,14 @@ async function importThreeMF(blob) {
|
|
|
6421
6368
|
const xml = new TextDecoder().decode(modelData);
|
|
6422
6369
|
const parsed = parseModelXml(xml);
|
|
6423
6370
|
if (parsed.vertices.length === 0 || parsed.triangles.length === 0) {
|
|
6424
|
-
return
|
|
6425
|
-
|
|
6371
|
+
return result.err(
|
|
6372
|
+
result.ioError(result.BrepErrorCode.THREEMF_IMPORT_FAILED, "3MF model contains no valid geometry")
|
|
6426
6373
|
);
|
|
6427
6374
|
}
|
|
6428
6375
|
return buildSolidFromMesh(parsed);
|
|
6429
6376
|
} catch (e) {
|
|
6430
6377
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6431
|
-
return
|
|
6378
|
+
return result.err(result.ioError(result.BrepErrorCode.THREEMF_IMPORT_FAILED, `3MF import failed: ${msg}`, e));
|
|
6432
6379
|
}
|
|
6433
6380
|
}
|
|
6434
6381
|
function resolve(s) {
|
|
@@ -6442,9 +6389,9 @@ function resolve3D(s) {
|
|
|
6442
6389
|
}
|
|
6443
6390
|
function validateNotNull(shape2, label) {
|
|
6444
6391
|
if (shapeTypes.getKernel().isNull(shape2.wrapped)) {
|
|
6445
|
-
return
|
|
6392
|
+
return result.err(result.validationError(result.BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
|
|
6446
6393
|
}
|
|
6447
|
-
return
|
|
6394
|
+
return result.ok(void 0);
|
|
6448
6395
|
}
|
|
6449
6396
|
function collectInputFaceHashes(inputs) {
|
|
6450
6397
|
const hasMetadata = inputs.some((s) => {
|
|
@@ -6462,7 +6409,7 @@ function collectInputFaceHashes(inputs) {
|
|
|
6462
6409
|
}
|
|
6463
6410
|
function thicken$1(shape2, thickness) {
|
|
6464
6411
|
const check = validateNotNull(shape2, "thicken: shape");
|
|
6465
|
-
if (
|
|
6412
|
+
if (result.isErr(check)) return check;
|
|
6466
6413
|
try {
|
|
6467
6414
|
const inputFaceHashes = collectInputFaceHashes([shape2]);
|
|
6468
6415
|
const { shape: resultShape, evolution } = shapeTypes.getKernel().thickenWithHistory(
|
|
@@ -6475,18 +6422,18 @@ function thicken$1(shape2, thickness) {
|
|
|
6475
6422
|
shapeFns.propagateOriginsFromEvolution(evolution, [shape2], cast);
|
|
6476
6423
|
booleanFns.propagateFaceTagsFromEvolution(evolution, [shape2], cast);
|
|
6477
6424
|
booleanFns.propagateColorsFromEvolution(evolution, [shape2], cast);
|
|
6478
|
-
return
|
|
6425
|
+
return result.ok(cast);
|
|
6479
6426
|
} catch (e) {
|
|
6480
6427
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6481
|
-
return
|
|
6428
|
+
return result.err(result.kernelError("THICKEN_FAILED", `Thicken operation failed: ${raw}`, e));
|
|
6482
6429
|
}
|
|
6483
6430
|
}
|
|
6484
6431
|
function fillet$1(shape2, edges, radius) {
|
|
6485
6432
|
const check = validateNotNull(shape2, "fillet: shape");
|
|
6486
|
-
if (
|
|
6433
|
+
if (result.isErr(check)) return check;
|
|
6487
6434
|
if (typeof radius === "number" && radius <= 0) {
|
|
6488
|
-
return
|
|
6489
|
-
|
|
6435
|
+
return result.err(
|
|
6436
|
+
result.validationError(
|
|
6490
6437
|
"INVALID_FILLET_RADIUS",
|
|
6491
6438
|
"Fillet radius must be positive",
|
|
6492
6439
|
void 0,
|
|
@@ -6496,8 +6443,8 @@ function fillet$1(shape2, edges, radius) {
|
|
|
6496
6443
|
);
|
|
6497
6444
|
}
|
|
6498
6445
|
if (Array.isArray(radius) && (radius[0] <= 0 || radius[1] <= 0)) {
|
|
6499
|
-
return
|
|
6500
|
-
|
|
6446
|
+
return result.err(
|
|
6447
|
+
result.validationError(
|
|
6501
6448
|
"INVALID_FILLET_RADIUS",
|
|
6502
6449
|
"Fillet radii must both be positive",
|
|
6503
6450
|
void 0,
|
|
@@ -6508,9 +6455,9 @@ function fillet$1(shape2, edges, radius) {
|
|
|
6508
6455
|
}
|
|
6509
6456
|
const selectedEdges = edges ?? shapeFns.getEdges(shape2);
|
|
6510
6457
|
if (selectedEdges.length === 0) {
|
|
6511
|
-
return
|
|
6512
|
-
|
|
6513
|
-
|
|
6458
|
+
return result.err(
|
|
6459
|
+
result.validationError(
|
|
6460
|
+
result.BrepErrorCode.FILLET_NO_EDGES,
|
|
6514
6461
|
"No edges found for fillet",
|
|
6515
6462
|
void 0,
|
|
6516
6463
|
void 0,
|
|
@@ -6544,9 +6491,9 @@ function fillet$1(shape2, edges, radius) {
|
|
|
6544
6491
|
kernelRadius = radius;
|
|
6545
6492
|
}
|
|
6546
6493
|
if (filteredEdges.length === 0) {
|
|
6547
|
-
return
|
|
6548
|
-
|
|
6549
|
-
|
|
6494
|
+
return result.err(
|
|
6495
|
+
result.validationError(
|
|
6496
|
+
result.BrepErrorCode.FILLET_NO_EDGES,
|
|
6550
6497
|
"No edges with positive radius for fillet",
|
|
6551
6498
|
void 0,
|
|
6552
6499
|
void 0,
|
|
@@ -6564,16 +6511,16 @@ function fillet$1(shape2, edges, radius) {
|
|
|
6564
6511
|
);
|
|
6565
6512
|
const cast = shapeTypes.castShape(resultShape);
|
|
6566
6513
|
if (!shapeTypes.isShape3D(cast)) {
|
|
6567
|
-
return
|
|
6514
|
+
return result.err(result.kernelError(result.BrepErrorCode.FILLET_NOT_3D, "Fillet result is not a 3D shape"));
|
|
6568
6515
|
}
|
|
6569
6516
|
shapeFns.propagateOriginsFromEvolution(evolution, [shape2], cast);
|
|
6570
6517
|
booleanFns.propagateFaceTagsFromEvolution(evolution, [shape2], cast);
|
|
6571
6518
|
booleanFns.propagateColorsFromEvolution(evolution, [shape2], cast);
|
|
6572
|
-
return
|
|
6519
|
+
return result.ok(cast);
|
|
6573
6520
|
} catch (e) {
|
|
6574
6521
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6575
|
-
return
|
|
6576
|
-
|
|
6522
|
+
return result.err(
|
|
6523
|
+
result.kernelError("FILLET_FAILED", `Fillet operation failed: ${raw}`, e, {
|
|
6577
6524
|
operation: "fillet",
|
|
6578
6525
|
edgeCount: selectedEdges.length,
|
|
6579
6526
|
radius
|
|
@@ -6583,10 +6530,10 @@ function fillet$1(shape2, edges, radius) {
|
|
|
6583
6530
|
}
|
|
6584
6531
|
function chamfer$1(shape2, edges, distance) {
|
|
6585
6532
|
const check = validateNotNull(shape2, "chamfer: shape");
|
|
6586
|
-
if (
|
|
6533
|
+
if (result.isErr(check)) return check;
|
|
6587
6534
|
if (typeof distance === "number" && distance <= 0) {
|
|
6588
|
-
return
|
|
6589
|
-
|
|
6535
|
+
return result.err(
|
|
6536
|
+
result.validationError(
|
|
6590
6537
|
"INVALID_CHAMFER_DISTANCE",
|
|
6591
6538
|
"Chamfer distance must be positive",
|
|
6592
6539
|
void 0,
|
|
@@ -6596,8 +6543,8 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
6596
6543
|
);
|
|
6597
6544
|
}
|
|
6598
6545
|
if (Array.isArray(distance) && (distance[0] <= 0 || distance[1] <= 0)) {
|
|
6599
|
-
return
|
|
6600
|
-
|
|
6546
|
+
return result.err(
|
|
6547
|
+
result.validationError(
|
|
6601
6548
|
"INVALID_CHAMFER_DISTANCE",
|
|
6602
6549
|
"Chamfer distances must both be positive",
|
|
6603
6550
|
void 0,
|
|
@@ -6608,7 +6555,7 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
6608
6555
|
}
|
|
6609
6556
|
const selectedEdges = edges ?? shapeFns.getEdges(shape2);
|
|
6610
6557
|
if (selectedEdges.length === 0) {
|
|
6611
|
-
return
|
|
6558
|
+
return result.err(result.validationError(result.BrepErrorCode.CHAMFER_NO_EDGES, "No edges found for chamfer"));
|
|
6612
6559
|
}
|
|
6613
6560
|
try {
|
|
6614
6561
|
let filteredEdges;
|
|
@@ -6636,9 +6583,9 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
6636
6583
|
kernelDistance = distance;
|
|
6637
6584
|
}
|
|
6638
6585
|
if (filteredEdges.length === 0) {
|
|
6639
|
-
return
|
|
6640
|
-
|
|
6641
|
-
|
|
6586
|
+
return result.err(
|
|
6587
|
+
result.validationError(
|
|
6588
|
+
result.BrepErrorCode.CHAMFER_NO_EDGES,
|
|
6642
6589
|
"No edges with positive distance for chamfer"
|
|
6643
6590
|
)
|
|
6644
6591
|
);
|
|
@@ -6653,16 +6600,16 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
6653
6600
|
);
|
|
6654
6601
|
const cast = shapeTypes.castShape(resultShape);
|
|
6655
6602
|
if (!shapeTypes.isShape3D(cast)) {
|
|
6656
|
-
return
|
|
6603
|
+
return result.err(result.kernelError(result.BrepErrorCode.CHAMFER_NOT_3D, "Chamfer result is not a 3D shape"));
|
|
6657
6604
|
}
|
|
6658
6605
|
shapeFns.propagateOriginsFromEvolution(evolution, [shape2], cast);
|
|
6659
6606
|
booleanFns.propagateFaceTagsFromEvolution(evolution, [shape2], cast);
|
|
6660
6607
|
booleanFns.propagateColorsFromEvolution(evolution, [shape2], cast);
|
|
6661
|
-
return
|
|
6608
|
+
return result.ok(cast);
|
|
6662
6609
|
} catch (e) {
|
|
6663
6610
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6664
|
-
return
|
|
6665
|
-
|
|
6611
|
+
return result.err(
|
|
6612
|
+
result.kernelError("CHAMFER_FAILED", `Chamfer operation failed: ${raw}`, e, {
|
|
6666
6613
|
operation: "chamfer",
|
|
6667
6614
|
edgeCount: selectedEdges.length,
|
|
6668
6615
|
distance
|
|
@@ -6672,12 +6619,12 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
6672
6619
|
}
|
|
6673
6620
|
function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
6674
6621
|
const check = validateNotNull(shape2, "shell: shape");
|
|
6675
|
-
if (
|
|
6622
|
+
if (result.isErr(check)) return check;
|
|
6676
6623
|
if (thickness <= 0) {
|
|
6677
|
-
return
|
|
6624
|
+
return result.err(result.validationError("INVALID_THICKNESS", "Shell thickness must be positive"));
|
|
6678
6625
|
}
|
|
6679
6626
|
if (faces.length === 0) {
|
|
6680
|
-
return
|
|
6627
|
+
return result.err(result.validationError("NO_FACES", "At least one face must be specified for shell"));
|
|
6681
6628
|
}
|
|
6682
6629
|
try {
|
|
6683
6630
|
const inputFaceHashes = collectInputFaceHashes([shape2]);
|
|
@@ -6691,16 +6638,16 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
6691
6638
|
);
|
|
6692
6639
|
const cast = shapeTypes.castShape(resultShape);
|
|
6693
6640
|
if (!shapeTypes.isShape3D(cast)) {
|
|
6694
|
-
return
|
|
6641
|
+
return result.err(result.kernelError("SHELL_RESULT_NOT_3D", "Shell result is not a 3D shape"));
|
|
6695
6642
|
}
|
|
6696
6643
|
shapeFns.propagateOriginsFromEvolution(evolution, [shape2], cast);
|
|
6697
6644
|
booleanFns.propagateFaceTagsFromEvolution(evolution, [shape2], cast);
|
|
6698
6645
|
booleanFns.propagateColorsFromEvolution(evolution, [shape2], cast);
|
|
6699
|
-
return
|
|
6646
|
+
return result.ok(cast);
|
|
6700
6647
|
} catch (e) {
|
|
6701
6648
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6702
|
-
return
|
|
6703
|
-
|
|
6649
|
+
return result.err(
|
|
6650
|
+
result.kernelError("SHELL_FAILED", `Shell operation failed: ${raw}`, e, {
|
|
6704
6651
|
operation: "shell",
|
|
6705
6652
|
faceCount: faces.length,
|
|
6706
6653
|
thickness
|
|
@@ -6710,9 +6657,9 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
6710
6657
|
}
|
|
6711
6658
|
function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
6712
6659
|
const check = validateNotNull(shape2, "offset: shape");
|
|
6713
|
-
if (
|
|
6660
|
+
if (result.isErr(check)) return check;
|
|
6714
6661
|
if (distance === 0) {
|
|
6715
|
-
return
|
|
6662
|
+
return result.err(result.validationError("ZERO_OFFSET", "Offset distance cannot be zero"));
|
|
6716
6663
|
}
|
|
6717
6664
|
try {
|
|
6718
6665
|
const inputFaceHashes = collectInputFaceHashes([shape2]);
|
|
@@ -6725,15 +6672,15 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
|
6725
6672
|
);
|
|
6726
6673
|
const cast = shapeTypes.castShape(resultShape);
|
|
6727
6674
|
if (!shapeTypes.isShape3D(cast)) {
|
|
6728
|
-
return
|
|
6675
|
+
return result.err(result.kernelError("OFFSET_RESULT_NOT_3D", "Offset result is not a 3D shape"));
|
|
6729
6676
|
}
|
|
6730
6677
|
shapeFns.propagateOriginsFromEvolution(evolution, [shape2], cast);
|
|
6731
6678
|
booleanFns.propagateFaceTagsFromEvolution(evolution, [shape2], cast);
|
|
6732
6679
|
booleanFns.propagateColorsFromEvolution(evolution, [shape2], cast);
|
|
6733
|
-
return
|
|
6680
|
+
return result.ok(cast);
|
|
6734
6681
|
} catch (e) {
|
|
6735
6682
|
const raw = e instanceof Error ? e.message : String(e);
|
|
6736
|
-
return
|
|
6683
|
+
return result.err(result.kernelError("OFFSET_FAILED", `Offset operation failed: ${raw}`, e));
|
|
6737
6684
|
}
|
|
6738
6685
|
}
|
|
6739
6686
|
function translate(shape2, v) {
|
|
@@ -6890,7 +6837,7 @@ function isEmpty(shape2) {
|
|
|
6890
6837
|
}
|
|
6891
6838
|
function loft$1(wires, { ruled = true, startPoint, endPoint, tolerance = 1e-6 } = {}, returnShell = false) {
|
|
6892
6839
|
if (wires.length === 0 && !startPoint && !endPoint) {
|
|
6893
|
-
return
|
|
6840
|
+
return result.err(result.validationError("LOFT_EMPTY", "Loft requires at least one wire or start/end point"));
|
|
6894
6841
|
}
|
|
6895
6842
|
const kernel = shapeTypes.getKernel();
|
|
6896
6843
|
const startVertex = startPoint ? kernel.makeVertex(...types.toVec3(startPoint)) : void 0;
|
|
@@ -6906,13 +6853,13 @@ function loft$1(wires, { ruled = true, startPoint, endPoint, tolerance = 1e-6 }
|
|
|
6906
6853
|
...endVertex ? { endVertex } : {}
|
|
6907
6854
|
}
|
|
6908
6855
|
);
|
|
6909
|
-
const
|
|
6910
|
-
if (!shapeTypes.isShape3D(
|
|
6911
|
-
return
|
|
6856
|
+
const result$1 = shapeTypes.castShape(shape2);
|
|
6857
|
+
if (!shapeTypes.isShape3D(result$1)) {
|
|
6858
|
+
return result.err(result.typeCastError("LOFT_NOT_3D", "Loft did not produce a 3D shape"));
|
|
6912
6859
|
}
|
|
6913
|
-
return
|
|
6860
|
+
return result.ok(result$1);
|
|
6914
6861
|
} catch {
|
|
6915
|
-
return
|
|
6862
|
+
return result.err(result.kernelError("LOFT_FAILED", "Loft operation failed"));
|
|
6916
6863
|
}
|
|
6917
6864
|
}
|
|
6918
6865
|
function extrude(face, height) {
|
|
@@ -6937,8 +6884,8 @@ function resolveTargetFace(shape2, faceSpec) {
|
|
|
6937
6884
|
if (faceSpec === void 0) {
|
|
6938
6885
|
const faces = shapeFns.getFaces(shape2);
|
|
6939
6886
|
if (faces.length === 0) {
|
|
6940
|
-
return
|
|
6941
|
-
|
|
6887
|
+
return result.err(
|
|
6888
|
+
result.validationError(result.BrepErrorCode.COMPOUND_NO_FACES, "compoundOps: shape has no faces")
|
|
6942
6889
|
);
|
|
6943
6890
|
}
|
|
6944
6891
|
let best = faces[0];
|
|
@@ -6951,22 +6898,22 @@ function resolveTargetFace(shape2, faceSpec) {
|
|
|
6951
6898
|
bestZ = z;
|
|
6952
6899
|
}
|
|
6953
6900
|
}
|
|
6954
|
-
return
|
|
6901
|
+
return result.ok(best);
|
|
6955
6902
|
}
|
|
6956
6903
|
if (typeof faceSpec === "function") {
|
|
6957
6904
|
const finder = faceSpec(helpers.faceFinder());
|
|
6958
6905
|
const found = finder.findAll(shape2);
|
|
6959
6906
|
if (found.length === 0) {
|
|
6960
|
-
return
|
|
6961
|
-
|
|
6962
|
-
|
|
6907
|
+
return result.err(
|
|
6908
|
+
result.queryError(
|
|
6909
|
+
result.BrepErrorCode.COMPOUND_FACE_NOT_FOUND,
|
|
6963
6910
|
"compoundOps: face finder matched no faces"
|
|
6964
6911
|
)
|
|
6965
6912
|
);
|
|
6966
6913
|
}
|
|
6967
|
-
return
|
|
6914
|
+
return result.ok(found[0]);
|
|
6968
6915
|
}
|
|
6969
|
-
return
|
|
6916
|
+
return result.ok(faceSpec);
|
|
6970
6917
|
}
|
|
6971
6918
|
function toWire(profile) {
|
|
6972
6919
|
if ("sketchOnPlane" in profile && typeof profile.sketchOnPlane === "function") {
|
|
@@ -6979,10 +6926,10 @@ function drill(shape2, options) {
|
|
|
6979
6926
|
const { at, radius, axis: rawAxis } = options;
|
|
6980
6927
|
const axis = rawAxis ?? [0, 0, 1];
|
|
6981
6928
|
if (radius <= 0) {
|
|
6982
|
-
return
|
|
6929
|
+
return result.err(result.validationError("DRILL_INVALID_RADIUS", "Drill radius must be positive"));
|
|
6983
6930
|
}
|
|
6984
6931
|
if (vecOps.vecIsZero(axis)) {
|
|
6985
|
-
return
|
|
6932
|
+
return result.err(result.validationError("DRILL_ZERO_AXIS", "Drill axis cannot be zero"));
|
|
6986
6933
|
}
|
|
6987
6934
|
const dir = vecOps.vecNormalize(axis);
|
|
6988
6935
|
const pos = at.length === 2 ? [at[0], at[1], 0] : [at[0], at[1], at[2]];
|
|
@@ -7021,36 +6968,36 @@ function pocket(shape2, options) {
|
|
|
7021
6968
|
const s = resolve(shape2);
|
|
7022
6969
|
const { profile, depth } = options;
|
|
7023
6970
|
if (depth <= 0) {
|
|
7024
|
-
return
|
|
6971
|
+
return result.err(result.validationError("POCKET_INVALID_DEPTH", "Pocket depth must be positive"));
|
|
7025
6972
|
}
|
|
7026
6973
|
const targetResult = resolveTargetFace(s, options.face);
|
|
7027
|
-
if (
|
|
6974
|
+
if (result.isErr(targetResult)) return targetResult;
|
|
7028
6975
|
const targetFace = targetResult.value;
|
|
7029
6976
|
const normal = faceFns.normalAt(targetFace);
|
|
7030
6977
|
const w = toWire(profile);
|
|
7031
6978
|
const faceResult = surfaceBuilders.makeFace(w);
|
|
7032
|
-
if (
|
|
6979
|
+
if (result.isErr(faceResult)) return faceResult;
|
|
7033
6980
|
const extDir = vecOps.vecScale(vecOps.vecNormalize(normal), -depth);
|
|
7034
6981
|
const toolResult = operations.extrude(faceResult.value, extDir);
|
|
7035
|
-
if (
|
|
6982
|
+
if (result.isErr(toolResult)) return toolResult;
|
|
7036
6983
|
return booleanFns.cut(s, toolResult.value);
|
|
7037
6984
|
}
|
|
7038
6985
|
function boss(shape2, options) {
|
|
7039
6986
|
const s = resolve(shape2);
|
|
7040
6987
|
const { profile, height } = options;
|
|
7041
6988
|
if (height <= 0) {
|
|
7042
|
-
return
|
|
6989
|
+
return result.err(result.validationError("BOSS_INVALID_HEIGHT", "Boss height must be positive"));
|
|
7043
6990
|
}
|
|
7044
6991
|
const targetResult = resolveTargetFace(s, options.face);
|
|
7045
|
-
if (
|
|
6992
|
+
if (result.isErr(targetResult)) return targetResult;
|
|
7046
6993
|
const targetFace = targetResult.value;
|
|
7047
6994
|
const normal = faceFns.normalAt(targetFace);
|
|
7048
6995
|
const w = toWire(profile);
|
|
7049
6996
|
const faceResult = surfaceBuilders.makeFace(w);
|
|
7050
|
-
if (
|
|
6997
|
+
if (result.isErr(faceResult)) return faceResult;
|
|
7051
6998
|
const extDir = vecOps.vecScale(vecOps.vecNormalize(normal), height);
|
|
7052
6999
|
const toolResult = operations.extrude(faceResult.value, extDir);
|
|
7053
|
-
if (
|
|
7000
|
+
if (result.isErr(toolResult)) return toolResult;
|
|
7054
7001
|
return booleanFns.fuse(s, toolResult.value);
|
|
7055
7002
|
}
|
|
7056
7003
|
function mirrorJoin(shape2, options) {
|
|
@@ -7064,15 +7011,15 @@ function rectangularPattern(shape2, options) {
|
|
|
7064
7011
|
const s = resolve(shape2);
|
|
7065
7012
|
const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options;
|
|
7066
7013
|
if (xCount < 1 || yCount < 1) {
|
|
7067
|
-
return
|
|
7014
|
+
return result.err(result.validationError("PATTERN_INVALID_COUNT", "Pattern counts must be at least 1"));
|
|
7068
7015
|
}
|
|
7069
7016
|
if (vecOps.vecIsZero(xDir)) {
|
|
7070
|
-
return
|
|
7017
|
+
return result.err(result.validationError("PATTERN_ZERO_DIRECTION", "X direction cannot be zero"));
|
|
7071
7018
|
}
|
|
7072
7019
|
if (vecOps.vecIsZero(yDir)) {
|
|
7073
|
-
return
|
|
7020
|
+
return result.err(result.validationError("PATTERN_ZERO_DIRECTION", "Y direction cannot be zero"));
|
|
7074
7021
|
}
|
|
7075
|
-
if (xCount === 1 && yCount === 1) return
|
|
7022
|
+
if (xCount === 1 && yCount === 1) return result.ok(s);
|
|
7076
7023
|
const xNorm = vecOps.vecNormalize(xDir);
|
|
7077
7024
|
const yNorm = vecOps.vecNormalize(yDir);
|
|
7078
7025
|
const copies = [s];
|
|
@@ -7110,11 +7057,11 @@ Suggestion: ${brepError.suggestion}` : brepError.message;
|
|
|
7110
7057
|
}
|
|
7111
7058
|
}
|
|
7112
7059
|
}
|
|
7113
|
-
function unwrapOrThrow(
|
|
7114
|
-
if (
|
|
7115
|
-
throw new BrepWrapperError(
|
|
7060
|
+
function unwrapOrThrow(result$1) {
|
|
7061
|
+
if (result.isErr(result$1)) {
|
|
7062
|
+
throw new BrepWrapperError(result$1.error);
|
|
7116
7063
|
}
|
|
7117
|
-
return
|
|
7064
|
+
return result$1.value;
|
|
7118
7065
|
}
|
|
7119
7066
|
function createWrappedBase(val) {
|
|
7120
7067
|
const self = {
|
|
@@ -7299,41 +7246,43 @@ exports.withKernel = shapeTypes.withKernel;
|
|
|
7299
7246
|
exports.withScope = shapeTypes.withScope;
|
|
7300
7247
|
exports.withScopeResult = shapeTypes.withScopeResult;
|
|
7301
7248
|
exports.withScopeResultAsync = shapeTypes.withScopeResultAsync;
|
|
7302
|
-
exports.
|
|
7303
|
-
exports.
|
|
7304
|
-
exports.
|
|
7305
|
-
exports.
|
|
7306
|
-
exports.
|
|
7307
|
-
exports.
|
|
7308
|
-
exports.
|
|
7309
|
-
exports.
|
|
7310
|
-
exports.
|
|
7311
|
-
exports.
|
|
7312
|
-
exports.
|
|
7313
|
-
exports.
|
|
7314
|
-
exports.
|
|
7315
|
-
exports.
|
|
7316
|
-
exports.
|
|
7317
|
-
exports.
|
|
7318
|
-
exports.
|
|
7319
|
-
exports.
|
|
7320
|
-
exports.
|
|
7321
|
-
exports.
|
|
7322
|
-
exports.
|
|
7323
|
-
exports.
|
|
7324
|
-
exports.
|
|
7325
|
-
exports.
|
|
7326
|
-
exports.
|
|
7327
|
-
exports.
|
|
7328
|
-
exports.
|
|
7329
|
-
exports.
|
|
7330
|
-
exports.
|
|
7331
|
-
exports.
|
|
7332
|
-
exports.
|
|
7333
|
-
exports.
|
|
7334
|
-
exports.
|
|
7335
|
-
exports.
|
|
7336
|
-
exports.
|
|
7249
|
+
exports.BrepBugError = result.BrepBugError;
|
|
7250
|
+
exports.BrepErrorCode = result.BrepErrorCode;
|
|
7251
|
+
exports.OK = result.OK;
|
|
7252
|
+
exports.all = result.all;
|
|
7253
|
+
exports.andThen = result.andThen;
|
|
7254
|
+
exports.bug = result.bug;
|
|
7255
|
+
exports.collect = result.collect;
|
|
7256
|
+
exports.computationError = result.computationError;
|
|
7257
|
+
exports.err = result.err;
|
|
7258
|
+
exports.flatMap = result.flatMap;
|
|
7259
|
+
exports.fromNullable = result.fromNullable;
|
|
7260
|
+
exports.ioError = result.ioError;
|
|
7261
|
+
exports.isErr = result.isErr;
|
|
7262
|
+
exports.isOk = result.isOk;
|
|
7263
|
+
exports.kernelError = result.kernelError;
|
|
7264
|
+
exports.map = result.map;
|
|
7265
|
+
exports.mapErr = result.mapErr;
|
|
7266
|
+
exports.match = result.match;
|
|
7267
|
+
exports.moduleInitError = result.moduleInitError;
|
|
7268
|
+
exports.ok = result.ok;
|
|
7269
|
+
exports.or = result.or;
|
|
7270
|
+
exports.orElse = result.orElse;
|
|
7271
|
+
exports.pipeline = result.pipeline;
|
|
7272
|
+
exports.queryError = result.queryError;
|
|
7273
|
+
exports.sketcherStateError = result.sketcherStateError;
|
|
7274
|
+
exports.tap = result.tap;
|
|
7275
|
+
exports.tapErr = result.tapErr;
|
|
7276
|
+
exports.tryCatch = result.tryCatch;
|
|
7277
|
+
exports.tryCatchAsync = result.tryCatchAsync;
|
|
7278
|
+
exports.typeCastError = result.typeCastError;
|
|
7279
|
+
exports.unsupportedError = result.unsupportedError;
|
|
7280
|
+
exports.unwrap = result.unwrap;
|
|
7281
|
+
exports.unwrapErr = result.unwrapErr;
|
|
7282
|
+
exports.unwrapOr = result.unwrapOr;
|
|
7283
|
+
exports.unwrapOrElse = result.unwrapOrElse;
|
|
7284
|
+
exports.validationError = result.validationError;
|
|
7285
|
+
exports.zipResults = result.zip;
|
|
7337
7286
|
exports.DEG2RAD = vecOps.DEG2RAD;
|
|
7338
7287
|
exports.HASH_CODE_MAX = vecOps.HASH_CODE_MAX;
|
|
7339
7288
|
exports.RAD2DEG = vecOps.RAD2DEG;
|
|
@@ -7631,8 +7580,6 @@ exports.measureVolume = measurement.measureVolume;
|
|
|
7631
7580
|
exports.measureVolumeProps = measurement.measureVolumeProps;
|
|
7632
7581
|
exports.fill = surfaceBuilders.fill;
|
|
7633
7582
|
exports.edgeFinder = query.edgeFinder;
|
|
7634
|
-
exports.BrepBugError = result.BrepBugError;
|
|
7635
|
-
exports.bug = result.bug;
|
|
7636
7583
|
exports.cornerFinder = cornerFinder.cornerFinder;
|
|
7637
7584
|
exports.createOperationRegistry = worker.createOperationRegistry;
|
|
7638
7585
|
exports.createTaskQueue = worker.createTaskQueue;
|