brepjs 20.13.0 → 20.13.2
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.cjs +6 -6
- package/dist/2d.js +6 -6
- package/dist/{adjacencyFns-BXzEHSC5.cjs → adjacencyFns-BBugwmvl.cjs} +3 -3
- package/dist/{adjacencyFns-BYjzMejn.js → adjacencyFns-V29Gvfs9.js} +3 -3
- package/dist/{blueprint-464KGkzc.cjs → blueprint-BO8zuqoy.cjs} +5 -5
- package/dist/{blueprint-D-4-uTkr.js → blueprint-CDmOJybf.js} +5 -5
- package/dist/{blueprintFns-CE5RdX-E.js → blueprintFns-CEKZsu4N.js} +2 -2
- package/dist/{blueprintFns-BdyFiuiC.cjs → blueprintFns-Cki-iwEl.cjs} +2 -2
- package/dist/{blueprintSketcher-C4XHzqTw.cjs → blueprintSketcher-Bxkp-vjK.cjs} +3 -3
- package/dist/{blueprintSketcher-CQ9LxcIl.js → blueprintSketcher-DG_2zJg7.js} +3 -3
- package/dist/{boolean2D-CKE32vHV.cjs → boolean2D-C_sEMz0u.cjs} +4 -4
- package/dist/{boolean2D-DwJvQ4p_.js → boolean2D-DqCcYA2X.js} +4 -4
- package/dist/{booleanFns-MkzdfjDv.cjs → booleanFns-CA9tvtqr.cjs} +5 -5
- package/dist/{booleanFns-CsTz48A3.js → booleanFns-CopMFBLS.js} +5 -5
- package/dist/brepjs.cjs +33 -31
- package/dist/brepjs.js +33 -31
- package/dist/{cameraFns-BDl_D28X.js → cameraFns-BIIpsfds.js} +3 -3
- package/dist/{cameraFns-vHpapIZG.cjs → cameraFns-BJ35ht2H.cjs} +3 -3
- package/dist/core.cjs +2 -2
- package/dist/core.js +2 -2
- package/dist/{cornerFinder-Dyk5sKEN.js → cornerFinder-C8VCstc3.js} +1 -1
- package/dist/{cornerFinder-adDN0_C4.cjs → cornerFinder-D83OLL_I.cjs} +1 -1
- package/dist/{curveFns-RjNVzxNc.js → curveFns--TqXOi8f.js} +1 -1
- package/dist/{curveFns-HtjEh2W-.cjs → curveFns-B29Eot3K.cjs} +1 -1
- package/dist/{drawFns-B5gZtD_P.cjs → drawFns-Bqs4HPzo.cjs} +12 -12
- package/dist/{drawFns-stc8-Gma.js → drawFns-g9FrZ_P4.js} +12 -12
- package/dist/{faceFns-C7wBHMPv.cjs → faceFns-BeSpw0Dz.cjs} +2 -2
- package/dist/{faceFns-DaPoCzd-.js → faceFns-BzHfvPea.js} +2 -2
- package/dist/{healingFns-zYCbT8vR.cjs → healingFns-BtZg6i3J.cjs} +31 -14
- package/dist/{healingFns-C3Wq_hN3.js → healingFns-DtefNa-x.js} +31 -14
- package/dist/{helpers-BdtYVyP5.cjs → helpers-CFEuQ0ok.cjs} +6 -6
- package/dist/{helpers-CDzSlBi_.js → helpers-CHUowMmV.js} +6 -6
- package/dist/{importFns-DR7Adv-W.js → importFns-BLaneR8r.js} +34 -20
- package/dist/{importFns-CotbQ9l7.cjs → importFns-BX0866c6.cjs} +34 -20
- package/dist/io/importFns.d.ts +12 -5
- package/dist/io.cjs +2 -2
- package/dist/io.js +2 -2
- package/dist/kernel/brepkit/brepkitWasmTypes.d.ts +0 -4
- package/dist/kernel/brepkit/helpers.d.ts +15 -0
- package/dist/kernel/brepkit/igesMerge.d.ts +13 -0
- package/dist/kernel/brepkit/measureOps.d.ts +7 -0
- package/dist/kernel/brepkit/modifierOps.d.ts +11 -1
- package/dist/kernel/brepkit/stepMerge.d.ts +14 -0
- package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
- package/dist/{loftFns-C9k9UAKh.cjs → loftFns-Byjbneme.cjs} +31 -16
- package/dist/{loftFns-Cbnrz3p8.js → loftFns-Cth8Le9X.js} +32 -17
- package/dist/{measureFns-Bi62maOJ.cjs → measureFns-BlS2xJcn.cjs} +53 -9
- package/dist/{measureFns-DivR02Xb.js → measureFns-CLsSuByu.js} +49 -11
- package/dist/measurement/measureFns.d.ts +16 -1
- package/dist/measurement.cjs +2 -2
- package/dist/measurement.js +2 -2
- package/dist/{meshFns-CcuY52tt.js → meshFns-CzpP9SBf.js} +4 -4
- package/dist/{meshFns-8MTf0Lo_.cjs → meshFns-ECQqx-8Q.cjs} +4 -4
- package/dist/{occtWasmAdapter-BNOuP9DA.cjs → occtWasmAdapter-4YnvqZOW.cjs} +72 -3
- package/dist/{occtWasmAdapter-1k4udeb3.js → occtWasmAdapter-CGsnjMOe.js} +72 -3
- package/dist/operations/sweepFns.d.ts +7 -3
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/{primitiveFns-BifV4IGL.cjs → primitiveFns-CzhQz02F.cjs} +5 -5
- package/dist/{primitiveFns-uDvN1FH6.js → primitiveFns-Kph3YP3A.js} +5 -5
- package/dist/{principalBoxFns-ez0xXLyK.js → principalBoxFns-C8ZmZNxJ.js} +3 -3
- package/dist/{principalBoxFns-DjxE8Rym.cjs → principalBoxFns-Ck9rR3Op.cjs} +3 -3
- package/dist/projection.cjs +1 -1
- package/dist/projection.js +1 -1
- package/dist/query.cjs +2 -2
- package/dist/query.js +2 -2
- package/dist/{refResolveFns-CTkAPUwM.cjs → refResolveFns-CVUSuVee.cjs} +6 -6
- package/dist/{refResolveFns-CuaYXFya.js → refResolveFns-Cf16q6AH.js} +6 -6
- package/dist/{shapeFns-Rmgd4x9I.cjs → shapeFns-BEwoFgq2.cjs} +2 -2
- package/dist/{shapeFns-DgpWLKra.js → shapeFns-Bepwarf3.js} +2 -2
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeTypes-BjitsJRQ.cjs → shapeTypes-CIw6-GFy.cjs} +899 -198
- package/dist/{shapeTypes-DbPghQD3.js → shapeTypes-hLHmANUz.js} +899 -198
- package/dist/sketching.cjs +3 -3
- package/dist/sketching.js +3 -3
- package/dist/{solidBuilders-Bs2NA3xl.cjs → solidBuilders-BVHK-era.cjs} +3 -3
- package/dist/{solidBuilders-BUI_fGzR.js → solidBuilders-IA8xNuxJ.js} +3 -3
- package/dist/{surfaceBuilders-CO_DKhWA.js → surfaceBuilders-BYwkPzfM.js} +3 -3
- package/dist/{surfaceBuilders-Cn1mkQ3j.cjs → surfaceBuilders-DIM5GSAT.cjs} +3 -3
- package/dist/text.cjs +2 -2
- package/dist/text.js +2 -2
- package/dist/{textBlueprints-CT0Kbw1f.js → textBlueprints-B4w-_4_D.js} +8 -8
- package/dist/{textBlueprints-P_D0KUVx.cjs → textBlueprints-CPJ6sBZZ.cjs} +8 -8
- package/dist/{textMetrics-CVyX8GyL.cjs → textMetrics-Dfr_9G6g.cjs} +1 -1
- package/dist/{textMetrics-CXKdzefS.js → textMetrics-na1BYw65.js} +1 -1
- package/dist/{threadFns-COs6jmaf.js → threadFns-BEO0-PP6.js} +7 -7
- package/dist/{threadFns-BV4HLdPE.cjs → threadFns-CAsRIX6c.cjs} +7 -7
- package/dist/topology/apiTypes.d.ts +7 -3
- package/dist/topology/chamferAngleFns.d.ts +2 -2
- package/dist/topology/evolutionFns.d.ts +1 -1
- package/dist/topology/modifierFns.d.ts +11 -4
- package/dist/topology.cjs +9 -9
- package/dist/topology.js +9 -9
- package/dist/{topologyQueryFns-s0LddGkF.cjs → topologyQueryFns-BNDmjz7x.cjs} +1 -1
- package/dist/{topologyQueryFns-J2ae_Gvc.js → topologyQueryFns-BYqsNs6q.js} +1 -1
- package/dist/{validityTypes-CD_Xz0vZ.js → validityTypes-BYhzdgTM.js} +1 -1
- package/dist/{validityTypes-BVZ0lSNi.cjs → validityTypes-Gd5B_HcL.cjs} +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_occtWasmAdapter = require("./occtWasmAdapter-
|
|
1
|
+
const require_occtWasmAdapter = require("./occtWasmAdapter-4YnvqZOW.cjs");
|
|
2
2
|
const require_bug = require("./bug-CBcpIPuf.cjs");
|
|
3
3
|
// src/kernel/quality.ts
|
|
4
4
|
/**
|
|
@@ -5397,6 +5397,124 @@ function dist3(x1, y1, z1, x2, y2, z2) {
|
|
|
5397
5397
|
const dx = x1 - x2, dy = y1 - y2, dz = z1 - z2;
|
|
5398
5398
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
5399
5399
|
}
|
|
5400
|
+
var TAU$1 = 2 * Math.PI;
|
|
5401
|
+
/**
|
|
5402
|
+
* The frame of an analytic circle or ellipse edge, evaluated at t as
|
|
5403
|
+
* center + U·cos t + V·sin t, recovered from its points at 0, π/2 and π.
|
|
5404
|
+
* brepkit reports such an edge's domain as exactly [0, 2π]; a NURBS edge that
|
|
5405
|
+
* happens to be a circle reports its knot domain and gets no frame.
|
|
5406
|
+
*/
|
|
5407
|
+
function conicFrame(bk, edgeId) {
|
|
5408
|
+
const params = bk.getEdgeCurveParameters(edgeId);
|
|
5409
|
+
if (require_bug.wasmIndex(params, 0) !== 0 || require_bug.wasmIndex(params, 1) !== TAU$1) return void 0;
|
|
5410
|
+
const curveType = bk.getEdgeCurveType(edgeId);
|
|
5411
|
+
if (curveType !== "CIRCLE" && curveType !== "ELLIPSE") return void 0;
|
|
5412
|
+
const at = (t) => {
|
|
5413
|
+
const p = bk.evaluateEdgeCurve(edgeId, t);
|
|
5414
|
+
return [
|
|
5415
|
+
require_bug.wasmIndex(p, 0),
|
|
5416
|
+
require_bug.wasmIndex(p, 1),
|
|
5417
|
+
require_bug.wasmIndex(p, 2)
|
|
5418
|
+
];
|
|
5419
|
+
};
|
|
5420
|
+
const p0 = at(0);
|
|
5421
|
+
const pHalf = at(Math.PI / 2);
|
|
5422
|
+
const pPi = at(Math.PI);
|
|
5423
|
+
const center = [
|
|
5424
|
+
(p0[0] + pPi[0]) / 2,
|
|
5425
|
+
(p0[1] + pPi[1]) / 2,
|
|
5426
|
+
(p0[2] + pPi[2]) / 2
|
|
5427
|
+
];
|
|
5428
|
+
return {
|
|
5429
|
+
center,
|
|
5430
|
+
u: [
|
|
5431
|
+
p0[0] - center[0],
|
|
5432
|
+
p0[1] - center[1],
|
|
5433
|
+
p0[2] - center[2]
|
|
5434
|
+
],
|
|
5435
|
+
v: [
|
|
5436
|
+
pHalf[0] - center[0],
|
|
5437
|
+
pHalf[1] - center[1],
|
|
5438
|
+
pHalf[2] - center[2]
|
|
5439
|
+
]
|
|
5440
|
+
};
|
|
5441
|
+
}
|
|
5442
|
+
function edgeEnds(bk, edgeId) {
|
|
5443
|
+
const verts = bk.getEdgeVertices(edgeId);
|
|
5444
|
+
return [[
|
|
5445
|
+
require_bug.wasmIndex(verts, 0),
|
|
5446
|
+
require_bug.wasmIndex(verts, 1),
|
|
5447
|
+
require_bug.wasmIndex(verts, 2)
|
|
5448
|
+
], [
|
|
5449
|
+
require_bug.wasmIndex(verts, 3),
|
|
5450
|
+
require_bug.wasmIndex(verts, 4),
|
|
5451
|
+
require_bug.wasmIndex(verts, 5)
|
|
5452
|
+
]];
|
|
5453
|
+
}
|
|
5454
|
+
/**
|
|
5455
|
+
* The curve parameters an edge spans. brepkit reports a circle or ellipse edge's
|
|
5456
|
+
* domain as the whole [0, 2π] even for an arc; the arc runs counterclockwise
|
|
5457
|
+
* about the curve's axis from the angle of its start vertex to that of its end
|
|
5458
|
+
* vertex (brepkit's own `circle_param_range`), angles read off the curve's frame.
|
|
5459
|
+
*/
|
|
5460
|
+
function edgeParamRange(bk, edgeId) {
|
|
5461
|
+
const params = bk.getEdgeCurveParameters(edgeId);
|
|
5462
|
+
const t0 = require_bug.wasmIndex(params, 0);
|
|
5463
|
+
const t1 = require_bug.wasmIndex(params, 1);
|
|
5464
|
+
const frame = conicFrame(bk, edgeId);
|
|
5465
|
+
if (!frame) return [t0, t1];
|
|
5466
|
+
const [start, end] = edgeEnds(bk, edgeId);
|
|
5467
|
+
if (dist3(...start, ...end) < 1e-7) return [t0, t1];
|
|
5468
|
+
const { center, u, v } = frame;
|
|
5469
|
+
const uu = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
|
|
5470
|
+
const vv = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
|
5471
|
+
const angleOf = (p) => {
|
|
5472
|
+
const d = [
|
|
5473
|
+
p[0] - center[0],
|
|
5474
|
+
p[1] - center[1],
|
|
5475
|
+
p[2] - center[2]
|
|
5476
|
+
];
|
|
5477
|
+
const cos = (d[0] * u[0] + d[1] * u[1] + d[2] * u[2]) / uu;
|
|
5478
|
+
const sin = (d[0] * v[0] + d[1] * v[1] + d[2] * v[2]) / vv;
|
|
5479
|
+
return Math.atan2(sin, cos);
|
|
5480
|
+
};
|
|
5481
|
+
const ts = angleOf(start);
|
|
5482
|
+
let te = angleOf(end);
|
|
5483
|
+
if (te <= ts) te += TAU$1;
|
|
5484
|
+
return [ts, te];
|
|
5485
|
+
}
|
|
5486
|
+
var CURVE_BOX_SAMPLES = 32;
|
|
5487
|
+
/**
|
|
5488
|
+
* Points whose bounding box is the edge's: its ends, plus for a circle or
|
|
5489
|
+
* ellipse the points where each coordinate peaks within the arc (exact), and
|
|
5490
|
+
* for any other curve samples along its parameter range.
|
|
5491
|
+
*/
|
|
5492
|
+
function edgeBoxPoints(bk, edgeId) {
|
|
5493
|
+
const points = [...edgeEnds(bk, edgeId)];
|
|
5494
|
+
if (bk.getEdgeCurveType(edgeId) === "LINE") return points;
|
|
5495
|
+
const [t0, t1] = edgeParamRange(bk, edgeId);
|
|
5496
|
+
const at = (t) => {
|
|
5497
|
+
const p = bk.evaluateEdgeCurve(edgeId, t);
|
|
5498
|
+
return [
|
|
5499
|
+
require_bug.wasmIndex(p, 0),
|
|
5500
|
+
require_bug.wasmIndex(p, 1),
|
|
5501
|
+
require_bug.wasmIndex(p, 2)
|
|
5502
|
+
];
|
|
5503
|
+
};
|
|
5504
|
+
const frame = conicFrame(bk, edgeId);
|
|
5505
|
+
if (frame) {
|
|
5506
|
+
for (let k = 0; k < 3; k++) {
|
|
5507
|
+
const peak = Math.atan2(require_bug.wasmIndex(frame.v, k), require_bug.wasmIndex(frame.u, k));
|
|
5508
|
+
for (const base of [peak, peak + Math.PI]) {
|
|
5509
|
+
const t = base + TAU$1 * Math.ceil((t0 - base) / TAU$1);
|
|
5510
|
+
if (t <= t1) points.push(at(t));
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5513
|
+
return points;
|
|
5514
|
+
}
|
|
5515
|
+
for (let i = 1; i < CURVE_BOX_SAMPLES; i++) points.push(at(t0 + (t1 - t0) * i / CURVE_BOX_SAMPLES));
|
|
5516
|
+
return points;
|
|
5517
|
+
}
|
|
5400
5518
|
/** Copy a WASM-backed Uint8Array into an independent ArrayBuffer. */
|
|
5401
5519
|
function copyWasmBytes(bytes) {
|
|
5402
5520
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
@@ -5866,7 +5984,7 @@ function curveTangent(bk, shape, param) {
|
|
|
5866
5984
|
edgeId = require_bug.wasmIndex(edgeIds, edgeIds.length - 1);
|
|
5867
5985
|
let cumulative = 0;
|
|
5868
5986
|
for (const eid of edgeIds) {
|
|
5869
|
-
const p = bk
|
|
5987
|
+
const p = edgeParamRange(bk, eid);
|
|
5870
5988
|
const span = require_bug.wasmIndex(p, 1) - require_bug.wasmIndex(p, 0);
|
|
5871
5989
|
if (param <= cumulative + span || eid === edgeId) {
|
|
5872
5990
|
edgeId = eid;
|
|
@@ -5889,13 +6007,12 @@ function curveParameters(bk, shape) {
|
|
|
5889
6007
|
if (edgeIds.length === 0) return [0, 0];
|
|
5890
6008
|
let total = 0;
|
|
5891
6009
|
for (const eid of edgeIds) {
|
|
5892
|
-
const p = bk
|
|
6010
|
+
const p = edgeParamRange(bk, eid);
|
|
5893
6011
|
total += require_bug.wasmIndex(p, 1) - require_bug.wasmIndex(p, 0);
|
|
5894
6012
|
}
|
|
5895
6013
|
return [0, total];
|
|
5896
6014
|
}
|
|
5897
|
-
|
|
5898
|
-
return [require_bug.wasmIndex(params, 0), require_bug.wasmIndex(params, 1)];
|
|
6015
|
+
return edgeParamRange(bk, unwrap$1(shape, "edge"));
|
|
5899
6016
|
}
|
|
5900
6017
|
function curvePointAtParam(bk, shape, param) {
|
|
5901
6018
|
const h = shape;
|
|
@@ -5903,7 +6020,7 @@ function curvePointAtParam(bk, shape, param) {
|
|
|
5903
6020
|
const edgeIds = toArray(bk.getWireEdges(h.id));
|
|
5904
6021
|
let cumulative = 0;
|
|
5905
6022
|
for (const eid of edgeIds) {
|
|
5906
|
-
const p = bk
|
|
6023
|
+
const p = edgeParamRange(bk, eid);
|
|
5907
6024
|
const span = require_bug.wasmIndex(p, 1) - require_bug.wasmIndex(p, 0);
|
|
5908
6025
|
if (param <= cumulative + span || eid === edgeIds[edgeIds.length - 1]) {
|
|
5909
6026
|
const localParam = require_bug.wasmIndex(p, 0) + (param - cumulative);
|
|
@@ -7080,7 +7197,16 @@ function makeWireFromMixed(bk, items) {
|
|
|
7080
7197
|
else if (h.type === "wire") for (const childEdgeId of toArray(bk.getWireEdges(h.id))) edgeIds.push(childEdgeId);
|
|
7081
7198
|
}
|
|
7082
7199
|
if (edgeIds.length === 0) throw new Error("brepkit: makeWireFromMixed requires at least one edge");
|
|
7083
|
-
return wireHandle(bk.makeWire(edgeIds,
|
|
7200
|
+
return wireHandle(bk.makeWire(edgeIds, chainCloses(bk, edgeIds)));
|
|
7201
|
+
}
|
|
7202
|
+
/** Matches the 1e-7 linear tolerance brepkit's makeWire welds vertices within. */
|
|
7203
|
+
var WIRE_CLOSE_TOLERANCE = 1e-7;
|
|
7204
|
+
function chainCloses(bk, edgeIds) {
|
|
7205
|
+
const first = bk.getEdgeVertices(require_bug.wasmIndex(edgeIds, 0));
|
|
7206
|
+
const last = bk.getEdgeVertices(require_bug.wasmIndex(edgeIds, edgeIds.length - 1));
|
|
7207
|
+
const [sx, sy, sz] = require_bug.vec3At(first, 0);
|
|
7208
|
+
const [ex, ey, ez] = require_bug.vec3At(last, 3);
|
|
7209
|
+
return Math.hypot(ex - sx, ey - sy, ez - sz) < WIRE_CLOSE_TOLERANCE;
|
|
7084
7210
|
}
|
|
7085
7211
|
function makeCompound(bk, shapes) {
|
|
7086
7212
|
const handles = shapes.filter(isBrepkitHandle);
|
|
@@ -7188,6 +7314,7 @@ function sewAndSolidify(bk, faces, tolerance) {
|
|
|
7188
7314
|
function interpolatePoints(bk, points, options) {
|
|
7189
7315
|
if (options?.tolerance !== void 0) warnOnce("interpolate-tolerance", "interpolatePoints() tolerance parameter is not supported; brepkit uses chord-length parameterisation.");
|
|
7190
7316
|
if (points.length < 2) throw new Error("brepkit: need at least 2 points");
|
|
7317
|
+
if (options?.periodic) return interpolateClosed(bk, points);
|
|
7191
7318
|
if (points.length === 2) return makeLineEdge(bk, require_bug.wasmIndex(points, 0), require_bug.wasmIndex(points, 1));
|
|
7192
7319
|
const degree = Math.min(3, points.length - 1);
|
|
7193
7320
|
const coords = points.flatMap(([x, y, z]) => [
|
|
@@ -7197,6 +7324,132 @@ function interpolatePoints(bk, points, options) {
|
|
|
7197
7324
|
]);
|
|
7198
7325
|
return edgeHandle(bk.interpolatePoints(coords, degree));
|
|
7199
7326
|
}
|
|
7327
|
+
/**
|
|
7328
|
+
* The closed cubic through `points` that OCCT's periodic GeomAPI_Interpolate
|
|
7329
|
+
* builds, which brepkit-wasm has no binding for. The points are parameterised
|
|
7330
|
+
* by chord length, the closing chord included; the spline is C2 at every point
|
|
7331
|
+
* but the first, where it closes C1 with the tangent of the Lagrange
|
|
7332
|
+
* polynomial through the first four points (three when there are only three).
|
|
7333
|
+
* It is built as one cubic Bezier segment per chord: a clamped NURBS whose
|
|
7334
|
+
* interior knots have multiplicity 3.
|
|
7335
|
+
*/
|
|
7336
|
+
function interpolateClosed(bk, points) {
|
|
7337
|
+
if (points.length < 3) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: a periodic interpolation needs at least 3 points");
|
|
7338
|
+
const loop = [...points, require_bug.wasmIndex(points, 0)];
|
|
7339
|
+
const h = loop.slice(1).map((p, i) => {
|
|
7340
|
+
const q = require_bug.wasmIndex(loop, i);
|
|
7341
|
+
return Math.hypot(p[0] - q[0], p[1] - q[1], p[2] - q[2]);
|
|
7342
|
+
});
|
|
7343
|
+
if (h.some((len) => len === 0)) throw new Error("brepkit: periodic interpolation through repeated points");
|
|
7344
|
+
const t = [0];
|
|
7345
|
+
for (const len of h) t.push(require_bug.wasmIndex(t, t.length - 1) + len);
|
|
7346
|
+
const tangent = lagrangeStartTangent(loop, t, points.length === 3 ? 2 : 3);
|
|
7347
|
+
const derivatives = [
|
|
7348
|
+
tangent,
|
|
7349
|
+
...interiorDerivatives(loop, h, tangent),
|
|
7350
|
+
tangent
|
|
7351
|
+
];
|
|
7352
|
+
const controlPoints = [...require_bug.wasmIndex(loop, 0)];
|
|
7353
|
+
const knots = [
|
|
7354
|
+
0,
|
|
7355
|
+
0,
|
|
7356
|
+
0,
|
|
7357
|
+
0
|
|
7358
|
+
];
|
|
7359
|
+
for (let i = 0; i < h.length; i++) {
|
|
7360
|
+
const third = require_bug.wasmIndex(h, i) / 3;
|
|
7361
|
+
const p0 = require_bug.wasmIndex(loop, i);
|
|
7362
|
+
const p1 = require_bug.wasmIndex(loop, i + 1);
|
|
7363
|
+
const d0 = require_bug.wasmIndex(derivatives, i);
|
|
7364
|
+
const d1 = require_bug.wasmIndex(derivatives, i + 1);
|
|
7365
|
+
controlPoints.push(...p0.map((c, k) => c + third * require_bug.wasmIndex(d0, k)));
|
|
7366
|
+
controlPoints.push(...p1.map((c, k) => c - third * require_bug.wasmIndex(d1, k)));
|
|
7367
|
+
controlPoints.push(...p1);
|
|
7368
|
+
const ti = require_bug.wasmIndex(t, i + 1);
|
|
7369
|
+
knots.push(ti, ti, ti);
|
|
7370
|
+
}
|
|
7371
|
+
knots.push(require_bug.wasmIndex(t, t.length - 1));
|
|
7372
|
+
const [x, y, z] = require_bug.wasmIndex(loop, 0);
|
|
7373
|
+
const weights = Array(controlPoints.length / 3).fill(1);
|
|
7374
|
+
return edgeHandle(bk.makeNurbsEdge(x, y, z, x, y, z, 3, knots, controlPoints, weights));
|
|
7375
|
+
}
|
|
7376
|
+
/** Derivative at t[0] of the Lagrange polynomial through the first degree + 1 points. */
|
|
7377
|
+
function lagrangeStartTangent(pts, t, degree) {
|
|
7378
|
+
const t0 = require_bug.wasmIndex(t, 0);
|
|
7379
|
+
const tangent = [
|
|
7380
|
+
0,
|
|
7381
|
+
0,
|
|
7382
|
+
0
|
|
7383
|
+
];
|
|
7384
|
+
for (let j = 0; j <= degree; j++) {
|
|
7385
|
+
let weight = j === 0 ? 0 : 1;
|
|
7386
|
+
let den = 1;
|
|
7387
|
+
for (let m = 0; m <= degree; m++) {
|
|
7388
|
+
if (m === j) continue;
|
|
7389
|
+
if (j === 0) weight += 1 / (t0 - require_bug.wasmIndex(t, m));
|
|
7390
|
+
else if (m !== 0) weight *= t0 - require_bug.wasmIndex(t, m);
|
|
7391
|
+
den *= require_bug.wasmIndex(t, j) - require_bug.wasmIndex(t, m);
|
|
7392
|
+
}
|
|
7393
|
+
if (j !== 0) weight /= den;
|
|
7394
|
+
const p = require_bug.wasmIndex(pts, j);
|
|
7395
|
+
for (let k = 0; k < 3; k++) tangent[k] = require_bug.wasmIndex(tangent, k) + weight * require_bug.wasmIndex(p, k);
|
|
7396
|
+
}
|
|
7397
|
+
return tangent;
|
|
7398
|
+
}
|
|
7399
|
+
/**
|
|
7400
|
+
* Derivatives at the interior points of a cubic spline through `pts` (the first
|
|
7401
|
+
* point repeated at the end), from C2 continuity at each, with `tangent` at
|
|
7402
|
+
* both ends: one tridiagonal system per coordinate.
|
|
7403
|
+
*/
|
|
7404
|
+
function interiorDerivatives(pts, h, tangent) {
|
|
7405
|
+
const sub = [];
|
|
7406
|
+
const diag = [];
|
|
7407
|
+
const sup = [];
|
|
7408
|
+
const rhs = [
|
|
7409
|
+
[],
|
|
7410
|
+
[],
|
|
7411
|
+
[]
|
|
7412
|
+
];
|
|
7413
|
+
const last = h.length - 1;
|
|
7414
|
+
for (let i = 1; i <= last; i++) {
|
|
7415
|
+
const hp = require_bug.wasmIndex(h, i - 1);
|
|
7416
|
+
const hn = require_bug.wasmIndex(h, i);
|
|
7417
|
+
sub.push(hn);
|
|
7418
|
+
diag.push(2 * (hp + hn));
|
|
7419
|
+
sup.push(hp);
|
|
7420
|
+
const prev = require_bug.wasmIndex(pts, i - 1);
|
|
7421
|
+
const cur = require_bug.wasmIndex(pts, i);
|
|
7422
|
+
const next = require_bug.wasmIndex(pts, i + 1);
|
|
7423
|
+
for (let k = 0; k < 3; k++) {
|
|
7424
|
+
const into = require_bug.wasmIndex(cur, k) - require_bug.wasmIndex(prev, k);
|
|
7425
|
+
const out = require_bug.wasmIndex(next, k) - require_bug.wasmIndex(cur, k);
|
|
7426
|
+
let r = 3 * (hn / hp * into + hp / hn * out);
|
|
7427
|
+
if (i === 1) r -= hn * require_bug.wasmIndex(tangent, k);
|
|
7428
|
+
if (i === last) r -= hp * require_bug.wasmIndex(tangent, k);
|
|
7429
|
+
require_bug.wasmIndex(rhs, k).push(r);
|
|
7430
|
+
}
|
|
7431
|
+
}
|
|
7432
|
+
const [xs, ys, zs] = rhs.map((r) => solveTridiagonal(sub, diag, sup, r));
|
|
7433
|
+
return xs.map((x, i) => [
|
|
7434
|
+
x,
|
|
7435
|
+
require_bug.wasmIndex(ys, i),
|
|
7436
|
+
require_bug.wasmIndex(zs, i)
|
|
7437
|
+
]);
|
|
7438
|
+
}
|
|
7439
|
+
/** Solve a tridiagonal system (sub-, main and super-diagonal) by the Thomas algorithm. */
|
|
7440
|
+
function solveTridiagonal(sub, diag, sup, rhs) {
|
|
7441
|
+
const n = diag.length;
|
|
7442
|
+
const c = [];
|
|
7443
|
+
const d = [];
|
|
7444
|
+
for (let i = 0; i < n; i++) {
|
|
7445
|
+
const den = require_bug.wasmIndex(diag, i) - (i > 0 ? require_bug.wasmIndex(sub, i) * require_bug.wasmIndex(c, i - 1) : 0);
|
|
7446
|
+
c.push(require_bug.wasmIndex(sup, i) / den);
|
|
7447
|
+
d.push((require_bug.wasmIndex(rhs, i) - (i > 0 ? require_bug.wasmIndex(sub, i) * require_bug.wasmIndex(d, i - 1) : 0)) / den);
|
|
7448
|
+
}
|
|
7449
|
+
const x = Array(n).fill(0);
|
|
7450
|
+
for (let i = n - 1; i >= 0; i--) x[i] = require_bug.wasmIndex(d, i) - (i < n - 1 ? require_bug.wasmIndex(c, i) * require_bug.wasmIndex(x, i + 1) : 0);
|
|
7451
|
+
return x;
|
|
7452
|
+
}
|
|
7200
7453
|
function approximatePoints(bk, points, options) {
|
|
7201
7454
|
const degree = options?.degMax ?? 3;
|
|
7202
7455
|
const tol = options?.tolerance ?? 1e-6;
|
|
@@ -7481,59 +7734,96 @@ function fillet(bk, shape, edges, radius) {
|
|
|
7481
7734
|
const solidId = unwrapSolidOrThrow(shape, "fillet");
|
|
7482
7735
|
const edgeIds = edges.map((e) => unwrap$1(e, "edge"));
|
|
7483
7736
|
if (typeof radius === "number") return solidHandle(bk.fillet(solidId, edgeIds, radius));
|
|
7484
|
-
const
|
|
7485
|
-
for (const
|
|
7486
|
-
const
|
|
7487
|
-
|
|
7488
|
-
if (
|
|
7489
|
-
|
|
7490
|
-
const [startR, endR] = Array.isArray(r) ? r : [r, r];
|
|
7491
|
-
spec.push({
|
|
7492
|
-
edge: edgeId,
|
|
7493
|
-
startRadius: startR,
|
|
7494
|
-
endRadius: endR
|
|
7495
|
-
});
|
|
7737
|
+
const radii = /* @__PURE__ */ new Set();
|
|
7738
|
+
for (const edge of edges) {
|
|
7739
|
+
const r = typeof radius === "function" ? radius(edge) : radius;
|
|
7740
|
+
const [start, end] = Array.isArray(r) ? r : [r, r];
|
|
7741
|
+
if (start !== end) throw varyingFilletUnsupported();
|
|
7742
|
+
radii.add(start);
|
|
7496
7743
|
}
|
|
7497
|
-
|
|
7744
|
+
if (radii.size > 1) throw perEdgeUnsupported("fillet radii");
|
|
7745
|
+
const [only] = radii;
|
|
7746
|
+
if (only === void 0) throw new Error("brepkit: fillet needs at least one edge");
|
|
7747
|
+
return solidHandle(bk.fillet(solidId, edgeIds, only));
|
|
7748
|
+
}
|
|
7749
|
+
/**
|
|
7750
|
+
* brepkit takes one value for every edge of a fillet or chamfer call, and a
|
|
7751
|
+
* second call on the first one's result cannot name the input's other edges:
|
|
7752
|
+
* a chamfer fails on them ("no manifold edges to chamfer"), and a fillet builds
|
|
7753
|
+
* the right body but leaves the input solid corrupt, so that filleting the
|
|
7754
|
+
* input's four vertical cube edges at 2 mm afterwards cuts a flat chamfer.
|
|
7755
|
+
*/
|
|
7756
|
+
function perEdgeUnsupported(what) {
|
|
7757
|
+
return new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: different ${what} on different edges in one call is not supported`);
|
|
7758
|
+
}
|
|
7759
|
+
/**
|
|
7760
|
+
* brepkit-wasm's filletVariable does not build a rolling-ball blend: on the
|
|
7761
|
+
* 40 mm top edge of a 40 x 30 x 20 box, a radius running 2 to 5 removes 260 mm3
|
|
7762
|
+
* where the blend removes about 113, and even a constant law of 3 removes 180
|
|
7763
|
+
* (the flat chamfer) where fillet removes 77.26. A radius that varies along an
|
|
7764
|
+
* edge is refused rather than built that way.
|
|
7765
|
+
*/
|
|
7766
|
+
function varyingFilletUnsupported() {
|
|
7767
|
+
return new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: a fillet radius that varies along an edge is not supported");
|
|
7498
7768
|
}
|
|
7499
|
-
/**
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7769
|
+
/** occt's hashCode upper bound, which the kernel-agnostic filletVariable spec hashes edges with. */
|
|
7770
|
+
var HASH_UPPER_BOUND = 2147483647;
|
|
7771
|
+
/**
|
|
7772
|
+
* A variable fillet spec on one edge: `{ edge: hashCode, radii: [{ param, radius }] }`
|
|
7773
|
+
* from variableFillet, or `{ edgeId, startRadius, endRadius }`. A constant radius is
|
|
7774
|
+
* an ordinary fillet; a radius that varies is unsupported (see
|
|
7775
|
+
* {@link varyingFilletUnsupported}).
|
|
7776
|
+
*/
|
|
7777
|
+
function filletVariable$1(bk, shape, spec) {
|
|
7778
|
+
const solidId = unwrapSolidOrThrow(shape, "filletVariable");
|
|
7779
|
+
const parsed = JSON.parse(spec);
|
|
7780
|
+
let edgeId;
|
|
7781
|
+
let radii;
|
|
7782
|
+
if (parsed.edge !== void 0 && parsed.radii !== void 0 && parsed.radii.length > 0) {
|
|
7783
|
+
const hash = parsed.edge;
|
|
7784
|
+
edgeId = toArray(bk.getSolidEdges(solidId)).find((id) => id % HASH_UPPER_BOUND === hash);
|
|
7785
|
+
radii = parsed.radii.map((r) => r.radius);
|
|
7786
|
+
} else if (parsed.edgeId !== void 0 && parsed.startRadius !== void 0 && parsed.endRadius !== void 0) {
|
|
7787
|
+
edgeId = parsed.edgeId;
|
|
7788
|
+
radii = [parsed.startRadius, parsed.endRadius];
|
|
7789
|
+
} else throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: filletVariable: unrecognized spec");
|
|
7790
|
+
if (edgeId === void 0) throw new Error("brepkit: filletVariable: the edge is not an edge of the shape");
|
|
7791
|
+
const [first = 0] = radii;
|
|
7792
|
+
if (radii.some((r) => r !== first)) throw varyingFilletUnsupported();
|
|
7793
|
+
return solidHandle(bk.fillet(solidId, [edgeId], first));
|
|
7794
|
+
}
|
|
7795
|
+
/**
|
|
7796
|
+
* A symmetric chamfer for two equal distances, brepkit's two-distance chamfer
|
|
7797
|
+
* otherwise. brepkit sets `d1` back on the edge's first face in its own face
|
|
7798
|
+
* order, which need not be the face occt-wasm picks for the same edge.
|
|
7799
|
+
*/
|
|
7800
|
+
function chamferTwoDistances(bk, solidId, edgeIds, d1, d2) {
|
|
7801
|
+
return d1 === d2 ? bk.chamfer(solidId, edgeIds, d1) : bk.chamferV2(solidId, edgeIds, d1, d2);
|
|
7503
7802
|
}
|
|
7504
7803
|
function chamfer(bk, shape, edges, distance) {
|
|
7505
7804
|
const solidId = unwrapSolidOrThrow(shape, "chamfer");
|
|
7506
7805
|
const edgeIds = edges.map((e) => unwrap$1(e, "edge"));
|
|
7507
7806
|
if (typeof distance === "number") return solidHandle(bk.chamfer(solidId, edgeIds, distance));
|
|
7508
|
-
if (Array.isArray(distance))
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
return solidHandle(requireChamferAsymmetric(bk, "an asymmetric chamfer")(solidId, edgeIds, d1, d2));
|
|
7512
|
-
}
|
|
7513
|
-
const groups = /* @__PURE__ */ new Map();
|
|
7514
|
-
for (const [i, edge] of edges.entries()) {
|
|
7807
|
+
if (Array.isArray(distance)) return solidHandle(chamferTwoDistances(bk, solidId, edgeIds, distance[0], distance[1]));
|
|
7808
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
7809
|
+
for (const edge of edges) {
|
|
7515
7810
|
const r = distance(edge);
|
|
7516
|
-
const eid = edgeIds[i];
|
|
7517
|
-
if (eid === void 0) continue;
|
|
7518
7811
|
const [d1, d2] = Array.isArray(r) ? r : [r, r];
|
|
7519
|
-
|
|
7520
|
-
const group = groups.get(key);
|
|
7521
|
-
if (group) group.ids.push(eid);
|
|
7522
|
-
else groups.set(key, {
|
|
7523
|
-
ids: [eid],
|
|
7524
|
-
d1,
|
|
7525
|
-
d2
|
|
7526
|
-
});
|
|
7812
|
+
pairs.set(`${d1},${d2}`, [d1, d2]);
|
|
7527
7813
|
}
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
return solidHandle(
|
|
7814
|
+
if (pairs.size > 1) throw perEdgeUnsupported("chamfer distances");
|
|
7815
|
+
const [only] = pairs.values();
|
|
7816
|
+
if (only === void 0) throw new Error("brepkit: chamfer needs at least one edge");
|
|
7817
|
+
return solidHandle(chamferTwoDistances(bk, solidId, edgeIds, only[0], only[1]));
|
|
7532
7818
|
}
|
|
7819
|
+
/**
|
|
7820
|
+
* brepkit sets `distance` back on the edge's first face in its own face order
|
|
7821
|
+
* and the other face back by distance·tan(angle).
|
|
7822
|
+
*/
|
|
7533
7823
|
function chamferDistAngle$1(bk, shape, edges, distance, angleDeg) {
|
|
7534
|
-
const
|
|
7535
|
-
const
|
|
7536
|
-
return solidHandle(
|
|
7824
|
+
const solidId = unwrapSolidOrThrow(shape, "chamferDistAngle");
|
|
7825
|
+
const edgeIds = edges.map((e) => unwrap$1(e, "edge"));
|
|
7826
|
+
return solidHandle(bk.chamferDistanceAngle(solidId, edgeIds, distance, angleDeg * Math.PI / 180));
|
|
7537
7827
|
}
|
|
7538
7828
|
function faceCentroid(bk, faceId) {
|
|
7539
7829
|
const verts = toArray(bk.getFaceVertices(faceId));
|
|
@@ -7616,10 +7906,6 @@ function offset$1(bk, shape, distance, tolerance) {
|
|
|
7616
7906
|
const solidId = unwrapSolidOrThrow(shape, "offset");
|
|
7617
7907
|
return solidHandle(bk.offsetSolidV2(solidId, distance));
|
|
7618
7908
|
}
|
|
7619
|
-
function filletVariable$1(bk, shape, spec) {
|
|
7620
|
-
const solidId = unwrapSolidOrThrow(shape, "filletVariable");
|
|
7621
|
-
return solidHandle(bk.filletVariable(solidId, spec));
|
|
7622
|
-
}
|
|
7623
7909
|
function draft$1(bk, shape, faces, pullDirection, neutralPlane, angleDeg) {
|
|
7624
7910
|
const solidId = unwrapSolidOrThrow(shape, "draft");
|
|
7625
7911
|
const faceIds = faces.map((f) => unwrap$1(f, "face"));
|
|
@@ -8016,22 +8302,151 @@ function fuseToolWithHistory(bk, toolSolidIds, accum, hashUpperBound) {
|
|
|
8016
8302
|
}
|
|
8017
8303
|
return union;
|
|
8018
8304
|
}
|
|
8305
|
+
/** Whether this kernel can merge co-surface faces after `op` (brepkit-wasm >= 3.2). */
|
|
8306
|
+
function canSimplify(bk, op) {
|
|
8307
|
+
if (op === "fuse") return typeof bk.fuseWithOptions === "function";
|
|
8308
|
+
if (op === "cut") return typeof bk.cutWithOptions === "function";
|
|
8309
|
+
return typeof bk.intersectWithOptions === "function";
|
|
8310
|
+
}
|
|
8311
|
+
/** A point inside a face: the centroid of its largest tessellation triangle. */
|
|
8312
|
+
var FACE_POINT_DEFLECTION = .1;
|
|
8313
|
+
function interiorPoint(bk, faceId) {
|
|
8314
|
+
const mesh = bk.tessellateFace(faceId, FACE_POINT_DEFLECTION);
|
|
8315
|
+
const at = (t) => require_bug.vec3At(mesh.positions, require_bug.wasmIndex(mesh.indices, t) * 3);
|
|
8316
|
+
let best;
|
|
8317
|
+
let bestArea = -1;
|
|
8318
|
+
for (let t = 0; t + 2 < mesh.indices.length; t += 3) {
|
|
8319
|
+
const [ax, ay, az] = at(t);
|
|
8320
|
+
const [bx, by, bz] = at(t + 1);
|
|
8321
|
+
const [cx, cy, cz] = at(t + 2);
|
|
8322
|
+
const [ux, uy, uz] = [
|
|
8323
|
+
bx - ax,
|
|
8324
|
+
by - ay,
|
|
8325
|
+
bz - az
|
|
8326
|
+
];
|
|
8327
|
+
const [vx, vy, vz] = [
|
|
8328
|
+
cx - ax,
|
|
8329
|
+
cy - ay,
|
|
8330
|
+
cz - az
|
|
8331
|
+
];
|
|
8332
|
+
const area = Math.hypot(uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx);
|
|
8333
|
+
if (area > bestArea) {
|
|
8334
|
+
bestArea = area;
|
|
8335
|
+
best = [
|
|
8336
|
+
(ax + bx + cx) / 3,
|
|
8337
|
+
(ay + by + cy) / 3,
|
|
8338
|
+
(az + bz + cz) / 3
|
|
8339
|
+
];
|
|
8340
|
+
}
|
|
8341
|
+
}
|
|
8342
|
+
return best;
|
|
8343
|
+
}
|
|
8344
|
+
/**
|
|
8345
|
+
* The box of a face's tessellation, grown by twice the deflection: the face
|
|
8346
|
+
* lies within one deflection of its mesh, and an `interiorPoint` within one
|
|
8347
|
+
* deflection of the face, so the box holds every interior point of the face.
|
|
8348
|
+
*/
|
|
8349
|
+
function faceMeshBox(bk, faceId) {
|
|
8350
|
+
const { positions } = bk.tessellateFace(faceId, FACE_POINT_DEFLECTION);
|
|
8351
|
+
if (positions.length < 3) return void 0;
|
|
8352
|
+
const min = require_bug.vec3At(positions, 0);
|
|
8353
|
+
const max = [...min];
|
|
8354
|
+
for (let i = 3; i + 2 < positions.length; i += 3) for (let k = 0; k < 3; k++) {
|
|
8355
|
+
const v = require_bug.wasmIndex(positions, i + k);
|
|
8356
|
+
min[k] = Math.min(require_bug.wasmIndex(min, k), v);
|
|
8357
|
+
max[k] = Math.max(require_bug.wasmIndex(max, k), v);
|
|
8358
|
+
}
|
|
8359
|
+
const pad = 2 * FACE_POINT_DEFLECTION;
|
|
8360
|
+
for (let k = 0; k < 3; k++) {
|
|
8361
|
+
min[k] = require_bug.wasmIndex(min, k) - pad;
|
|
8362
|
+
max[k] = require_bug.wasmIndex(max, k) + pad;
|
|
8363
|
+
}
|
|
8364
|
+
return {
|
|
8365
|
+
min,
|
|
8366
|
+
max
|
|
8367
|
+
};
|
|
8368
|
+
}
|
|
8369
|
+
function boxHolds(box, p) {
|
|
8370
|
+
return p.every((v, k) => v >= require_bug.wasmIndex(box.min, k) && v <= require_bug.wasmIndex(box.max, k));
|
|
8371
|
+
}
|
|
8372
|
+
/**
|
|
8373
|
+
* Carry a boolean's face evolution over to the simplified result of the same
|
|
8374
|
+
* boolean. brepkit tracks face provenance only through its unsimplified
|
|
8375
|
+
* boolean, and merging co-surface faces makes new faces, so the boolean runs
|
|
8376
|
+
* twice: once with evolution, once simplified. Each face of the first result
|
|
8377
|
+
* lies inside one face of the second; a point inside it names that face.
|
|
8378
|
+
*/
|
|
8379
|
+
function simplifiedWithHistory(bk, tracked, simplified, hashUpperBound) {
|
|
8380
|
+
const from = tracked.shape;
|
|
8381
|
+
const to = simplified;
|
|
8382
|
+
if (from.type !== "solid" || to.type !== "solid") return {
|
|
8383
|
+
shape: simplified,
|
|
8384
|
+
evolution: tracked.evolution
|
|
8385
|
+
};
|
|
8386
|
+
const targets = toArray(bk.getSolidFaces(to.id)).map((id) => ({
|
|
8387
|
+
id,
|
|
8388
|
+
box: faceMeshBox(bk, id)
|
|
8389
|
+
}));
|
|
8390
|
+
const into = /* @__PURE__ */ new Map();
|
|
8391
|
+
for (const faceId of toArray(bk.getSolidFaces(from.id))) {
|
|
8392
|
+
const p = interiorPoint(bk, faceId);
|
|
8393
|
+
if (!p) continue;
|
|
8394
|
+
const near = targets.filter(({ box }) => !box || boxHolds(box, p));
|
|
8395
|
+
let nearest;
|
|
8396
|
+
let nearestDistance = Infinity;
|
|
8397
|
+
for (const { id } of near.length > 0 ? near : targets) {
|
|
8398
|
+
const d = require_bug.wasmIndex(bk.pointToFaceDistance(p[0], p[1], p[2], id), 0);
|
|
8399
|
+
if (d < nearestDistance) {
|
|
8400
|
+
nearestDistance = d;
|
|
8401
|
+
nearest = id;
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
if (nearest !== void 0) into.set(faceId % hashUpperBound, nearest % hashUpperBound);
|
|
8405
|
+
}
|
|
8406
|
+
const remap = (m) => new Map([...m].map(([k, outs]) => [k, [...new Set(outs.map((o) => into.get(o) ?? o))]]));
|
|
8407
|
+
return {
|
|
8408
|
+
shape: simplified,
|
|
8409
|
+
evolution: {
|
|
8410
|
+
modified: remap(tracked.evolution.modified),
|
|
8411
|
+
generated: remap(tracked.evolution.generated),
|
|
8412
|
+
deleted: tracked.evolution.deleted
|
|
8413
|
+
}
|
|
8414
|
+
};
|
|
8415
|
+
}
|
|
8019
8416
|
/**
|
|
8020
8417
|
* Shared implementation for boolean-with-history operations (fuse, cut, intersect).
|
|
8418
|
+
* With `simplify`, the evolution comes from the unsimplified boolean and is
|
|
8419
|
+
* carried over to the simplified one (see {@link simplifiedWithHistory}).
|
|
8021
8420
|
*/
|
|
8022
8421
|
function booleanWithHistoryImpl(bk, shape, tool, inputFaceHashes, hashUpperBound, options, nativeFn, fallbackFn, op) {
|
|
8422
|
+
const tracked = trackedBoolean(bk, shape, tool, inputFaceHashes, hashUpperBound, options, nativeFn, fallbackFn, op);
|
|
8023
8423
|
const noDiagnostics = {
|
|
8024
8424
|
hasErrors: false,
|
|
8025
8425
|
hasWarnings: false,
|
|
8026
8426
|
messages: []
|
|
8027
8427
|
};
|
|
8428
|
+
if (!tracked.native || !options?.simplify || !canSimplify(bk, op)) return {
|
|
8429
|
+
...tracked.result,
|
|
8430
|
+
diagnostics: noDiagnostics
|
|
8431
|
+
};
|
|
8432
|
+
return {
|
|
8433
|
+
...simplifiedWithHistory(bk, tracked.result, fallbackFn(shape, tool, options), hashUpperBound),
|
|
8434
|
+
diagnostics: noDiagnostics
|
|
8435
|
+
};
|
|
8436
|
+
}
|
|
8437
|
+
/**
|
|
8438
|
+
* The boolean with its face evolution: brepkit's native evolution for a solid
|
|
8439
|
+
* base (`native: true`), geometric matching otherwise. The native path ignores
|
|
8440
|
+
* `simplify`; the fallback applies it.
|
|
8441
|
+
*/
|
|
8442
|
+
function trackedBoolean(bk, shape, tool, inputFaceHashes, hashUpperBound, options, nativeFn, fallbackFn, op) {
|
|
8028
8443
|
const sh = shape;
|
|
8029
8444
|
const th = tool;
|
|
8030
8445
|
if (inputFaceHashes.length > 0 && sh.type === "solid") {
|
|
8031
8446
|
if (th.type === "solid") try {
|
|
8032
8447
|
return {
|
|
8033
|
-
|
|
8034
|
-
|
|
8448
|
+
result: parseNativeEvolution(nativeFn(sh.id, th.id), hashUpperBound),
|
|
8449
|
+
native: true
|
|
8035
8450
|
};
|
|
8036
8451
|
} catch (e) {
|
|
8037
8452
|
if (!isEmptyBooleanError(e)) throw e;
|
|
@@ -8047,19 +8462,21 @@ function booleanWithHistoryImpl(bk, shape, tool, inputFaceHashes, hashUpperBound
|
|
|
8047
8462
|
let steps = toolSolidIds;
|
|
8048
8463
|
if (op === "intersect" && toolSolidIds.length > 1) steps = [fuseToolWithHistory(bk, toolSolidIds, accum, hashUpperBound) ?? bk.fuseAll(toolSolidIds)];
|
|
8049
8464
|
return {
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8465
|
+
result: {
|
|
8466
|
+
shape: applyCompoundBooleanWithHistory(shape, steps, accum, hashUpperBound, nativeFn),
|
|
8467
|
+
evolution: {
|
|
8468
|
+
modified: accum.combinedModified,
|
|
8469
|
+
generated: accum.combinedGenerated,
|
|
8470
|
+
deleted: accum.combinedDeleted
|
|
8471
|
+
}
|
|
8055
8472
|
},
|
|
8056
|
-
|
|
8473
|
+
native: true
|
|
8057
8474
|
};
|
|
8058
8475
|
}
|
|
8059
8476
|
}
|
|
8060
8477
|
return {
|
|
8061
|
-
|
|
8062
|
-
|
|
8478
|
+
result: buildEvolution(bk, fallbackFn(shape, tool, options), inputFaceHashes, hashUpperBound, false, shape),
|
|
8479
|
+
native: false
|
|
8063
8480
|
};
|
|
8064
8481
|
}
|
|
8065
8482
|
function translateWithHistory(bk, shape, x, y, z, inputFaceHashes, hashUpperBound) {
|
|
@@ -8161,36 +8578,45 @@ function mesh$1(bk, shape, options) {
|
|
|
8161
8578
|
const angularTol = options.angularTolerance > 0 ? options.angularTolerance : void 0;
|
|
8162
8579
|
let result;
|
|
8163
8580
|
if (bkHandle.type === "solid") result = meshSolid(bk, h, deflection, !!options.includeUVs, angularTol);
|
|
8164
|
-
else if (bkHandle.type === "face") result = meshSingleFace(bk, h, deflection,
|
|
8165
|
-
else if (bkHandle.type === "compound") result =
|
|
8581
|
+
else if (bkHandle.type === "face") result = meshSingleFace(bk, h, deflection, angularTol);
|
|
8582
|
+
else if (bkHandle.type === "compound" || bkHandle.type === "shell") result = concatMeshes(meshParts(bk, bkHandle, deflection, !!options.includeUVs, angularTol));
|
|
8166
8583
|
else throw new Error(`brepkit: cannot mesh shape of type '${bkHandle.type}'`);
|
|
8167
8584
|
if (options.skipNormals) result.normals = /* @__PURE__ */ new Float32Array(0);
|
|
8168
8585
|
if (!options.includeUVs) result.uvs = /* @__PURE__ */ new Float32Array(0);
|
|
8169
8586
|
return result;
|
|
8170
8587
|
}
|
|
8171
8588
|
/**
|
|
8172
|
-
* Mesh
|
|
8589
|
+
* Mesh each solid and face inside a compound or shell, one part apiece.
|
|
8173
8590
|
*
|
|
8174
|
-
* Text solids are compounds
|
|
8175
|
-
*
|
|
8176
|
-
*
|
|
8591
|
+
* Text solids are compounds (one solid per glyph), and a sheet of loose faces
|
|
8592
|
+
* is a compound of faces or a sewn shell, so each child is meshed by what it
|
|
8593
|
+
* is: a solid as a solid, a shell as its faces, a face as itself.
|
|
8594
|
+
*
|
|
8595
|
+
* Compounds come in two flavours and only one is arena-backed. A synthetic
|
|
8596
|
+
* compound (non-solid children, id from `nextSyntheticId`) exists JS-side only,
|
|
8597
|
+
* so asking the kernel to resolve it raises an invalid-handle error; its
|
|
8598
|
+
* children are read from `syntheticCompounds` instead. Wires, edges and
|
|
8599
|
+
* vertices contribute no triangles and are skipped rather than throwing.
|
|
8600
|
+
*/
|
|
8601
|
+
function meshParts(bk, h, deflection, includeUVs, angularTolerance) {
|
|
8602
|
+
switch (h.type) {
|
|
8603
|
+
case "solid": return [meshSolid(bk, h.id, deflection, includeUVs, angularTolerance)];
|
|
8604
|
+
case "face": return [meshSingleFace(bk, h.id, deflection, angularTolerance)];
|
|
8605
|
+
case "shell": return toArray(bk.getShellFaces(h.id)).map((faceId) => meshSingleFace(bk, faceId, deflection, angularTolerance));
|
|
8606
|
+
case "compound": return (syntheticCompounds.get(h.id) ?? toArray(bk.getCompoundSolids(h.id)).map(solidHandle)).flatMap((child) => meshParts(bk, child, deflection, includeUVs, angularTolerance));
|
|
8607
|
+
default: return [];
|
|
8608
|
+
}
|
|
8609
|
+
}
|
|
8610
|
+
/**
|
|
8611
|
+
* Concatenate meshes into one.
|
|
8177
8612
|
*
|
|
8178
8613
|
* Triangle indices are vertex-relative, so each part's are rebased by the
|
|
8179
8614
|
* running vertex count; `faceGroups` index into the triangle list, so their
|
|
8180
8615
|
* `start` is rebased by the running triangle count. `uvs` are only carried
|
|
8181
8616
|
* when every part supplied them, since a partial UV array would misalign
|
|
8182
8617
|
* against the concatenated vertices.
|
|
8183
|
-
*
|
|
8184
|
-
* Compounds come in two flavours and only one is arena-backed. A synthetic
|
|
8185
|
-
* compound (non-solid children, id from `nextSyntheticId`) exists JS-side only,
|
|
8186
|
-
* so asking the kernel to resolve it raises an invalid-handle error; its
|
|
8187
|
-
* children are read from `syntheticCompounds` instead. Non-solid children
|
|
8188
|
-
* contribute no triangles and are skipped rather than throwing, matching how a
|
|
8189
|
-
* wire or edge meshes to nothing elsewhere in this adapter.
|
|
8190
8618
|
*/
|
|
8191
|
-
function
|
|
8192
|
-
const synthetic = syntheticCompounds.get(compoundId);
|
|
8193
|
-
const parts = (synthetic ? synthetic.filter((c) => c.type === "solid").map((c) => c.id) : toArray(bk.getCompoundSolids(compoundId))).map((id) => meshSolid(bk, id, deflection, includeUVs, angularTolerance));
|
|
8619
|
+
function concatMeshes(parts) {
|
|
8194
8620
|
if (parts.length === 1) return require_bug.wasmIndex(parts, 0);
|
|
8195
8621
|
if (parts.length === 0) return {
|
|
8196
8622
|
vertices: /* @__PURE__ */ new Float32Array(0),
|
|
@@ -8237,12 +8663,21 @@ function meshCompound(bk, compoundId, deflection, includeUVs, angularTolerance)
|
|
|
8237
8663
|
}
|
|
8238
8664
|
function meshEdges$1(bk, shape, tolerance, angularTolerance) {
|
|
8239
8665
|
const bkHandle = shape;
|
|
8240
|
-
if (bkHandle.type !== "solid") return {
|
|
8241
|
-
lines: /* @__PURE__ */ new Float32Array(0),
|
|
8242
|
-
edgeGroups: []
|
|
8243
|
-
};
|
|
8244
8666
|
const angularTol = angularTolerance > 0 ? angularTolerance : void 0;
|
|
8667
|
+
if (bkHandle.type !== "solid") {
|
|
8668
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8669
|
+
const edgeIds = [];
|
|
8670
|
+
for (const edge of iterShapes$1(bk, shape, "edge")) {
|
|
8671
|
+
const id = unwrap$1(edge);
|
|
8672
|
+
if (seen.has(id)) continue;
|
|
8673
|
+
seen.add(id);
|
|
8674
|
+
edgeIds.push(id);
|
|
8675
|
+
}
|
|
8676
|
+
return sampleEdges(bk, edgeIds, tolerance, angularTol ?? DEFAULT_ANGULAR_TOLERANCE);
|
|
8677
|
+
}
|
|
8678
|
+
const edgeIds = toArray(bk.getSolidEdges(bkHandle.id));
|
|
8245
8679
|
const edgeLines = bk.meshEdgesAll(bkHandle.id, tolerance, angularTol);
|
|
8680
|
+
if (edgeLines.edgeCount !== edgeIds.length) return sampleEdges(bk, edgeIds, tolerance, angularTol ?? DEFAULT_ANGULAR_TOLERANCE);
|
|
8246
8681
|
const positions = edgeLines.positions;
|
|
8247
8682
|
const offsets = edgeLines.offsets;
|
|
8248
8683
|
const edgeCount = edgeLines.edgeCount;
|
|
@@ -8262,7 +8697,7 @@ function meshEdges$1(bk, shape, tolerance, angularTolerance) {
|
|
|
8262
8697
|
edgeGroups.push({
|
|
8263
8698
|
start: segStart,
|
|
8264
8699
|
count: segments.length / 3 - segStart,
|
|
8265
|
-
edgeHash: i
|
|
8700
|
+
edgeHash: require_bug.wasmIndex(edgeIds, i)
|
|
8266
8701
|
});
|
|
8267
8702
|
}
|
|
8268
8703
|
return {
|
|
@@ -8270,6 +8705,78 @@ function meshEdges$1(bk, shape, tolerance, angularTolerance) {
|
|
|
8270
8705
|
edgeGroups
|
|
8271
8706
|
};
|
|
8272
8707
|
}
|
|
8708
|
+
/** brepkit's own default angular deflection (`DEFAULT_ANGULAR_TOL`, ~20°). */
|
|
8709
|
+
var DEFAULT_ANGULAR_TOLERANCE = .35;
|
|
8710
|
+
var EDGE_SAMPLE_START_SEGMENTS = 4;
|
|
8711
|
+
var EDGE_SAMPLE_MAX_DEPTH = 8;
|
|
8712
|
+
/**
|
|
8713
|
+
* Sample edges one at a time into line-segment pairs labelled with each edge's
|
|
8714
|
+
* id. Edges outside a solid have no batch sampler, so each curve is split until
|
|
8715
|
+
* a segment's midpoint sits within `tolerance` of its chord and its end
|
|
8716
|
+
* tangents turn by no more than `angularTolerance`.
|
|
8717
|
+
*/
|
|
8718
|
+
function sampleEdges(bk, edgeIds, tolerance, angularTolerance) {
|
|
8719
|
+
const segments = [];
|
|
8720
|
+
const edgeGroups = [];
|
|
8721
|
+
for (const edgeId of edgeIds) {
|
|
8722
|
+
const points = sampleEdgePoints(bk, edgeId, tolerance, angularTolerance);
|
|
8723
|
+
const segStart = segments.length / 3;
|
|
8724
|
+
for (let i = 0; i + 1 < points.length; i++) segments.push(...require_bug.wasmIndex(points, i), ...require_bug.wasmIndex(points, i + 1));
|
|
8725
|
+
edgeGroups.push({
|
|
8726
|
+
start: segStart,
|
|
8727
|
+
count: segments.length / 3 - segStart,
|
|
8728
|
+
edgeHash: edgeId
|
|
8729
|
+
});
|
|
8730
|
+
}
|
|
8731
|
+
return {
|
|
8732
|
+
lines: new Float32Array(segments),
|
|
8733
|
+
edgeGroups
|
|
8734
|
+
};
|
|
8735
|
+
}
|
|
8736
|
+
function sampleEdgePoints(bk, edgeId, tolerance, angularTolerance) {
|
|
8737
|
+
if (bk.getEdgeCurveType(edgeId) === "LINE") {
|
|
8738
|
+
const v = bk.getEdgeVertices(edgeId);
|
|
8739
|
+
return [require_bug.vec3At(v, 0), require_bug.vec3At(v, 3)];
|
|
8740
|
+
}
|
|
8741
|
+
const [t0, t1] = edgeParamRange(bk, edgeId);
|
|
8742
|
+
const at = (t) => {
|
|
8743
|
+
const r = bk.evaluateEdgeCurveD1(edgeId, t);
|
|
8744
|
+
return {
|
|
8745
|
+
p: require_bug.vec3At(r, 0),
|
|
8746
|
+
d: require_bug.vec3At(r, 3)
|
|
8747
|
+
};
|
|
8748
|
+
};
|
|
8749
|
+
const points = [];
|
|
8750
|
+
const refine = (a, pa, b, pb, depth) => {
|
|
8751
|
+
const m = (a + b) / 2;
|
|
8752
|
+
const pm = at(m);
|
|
8753
|
+
const sag = Math.hypot(pm.p[0] - (pa.p[0] + pb.p[0]) / 2, pm.p[1] - (pa.p[1] + pb.p[1]) / 2, pm.p[2] - (pa.p[2] + pb.p[2]) / 2);
|
|
8754
|
+
if (depth < EDGE_SAMPLE_MAX_DEPTH && (sag > tolerance || turnAngle(pa.d, pb.d) > angularTolerance)) {
|
|
8755
|
+
refine(a, pa, m, pm, depth + 1);
|
|
8756
|
+
refine(m, pm, b, pb, depth + 1);
|
|
8757
|
+
return;
|
|
8758
|
+
}
|
|
8759
|
+
points.push(pb.p);
|
|
8760
|
+
};
|
|
8761
|
+
let prevT = t0;
|
|
8762
|
+
let prev = at(t0);
|
|
8763
|
+
points.push(prev.p);
|
|
8764
|
+
for (let i = 1; i <= EDGE_SAMPLE_START_SEGMENTS; i++) {
|
|
8765
|
+
const t = t0 + (t1 - t0) * i / EDGE_SAMPLE_START_SEGMENTS;
|
|
8766
|
+
const next = at(t);
|
|
8767
|
+
refine(prevT, prev, t, next, 0);
|
|
8768
|
+
prevT = t;
|
|
8769
|
+
prev = next;
|
|
8770
|
+
}
|
|
8771
|
+
return points;
|
|
8772
|
+
}
|
|
8773
|
+
function turnAngle(a, b) {
|
|
8774
|
+
const la = Math.hypot(a[0], a[1], a[2]);
|
|
8775
|
+
const lb = Math.hypot(b[0], b[1], b[2]);
|
|
8776
|
+
if (la === 0 || lb === 0) return 0;
|
|
8777
|
+
const cos = (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) / (la * lb);
|
|
8778
|
+
return Math.acos(Math.min(1, Math.max(-1, cos)));
|
|
8779
|
+
}
|
|
8273
8780
|
function hasTriangulation$1(_bk, _shape) {
|
|
8274
8781
|
return false;
|
|
8275
8782
|
}
|
|
@@ -8416,8 +8923,8 @@ function meshSolidPerFace(bk, solidId, deflection, angularTolerance) {
|
|
|
8416
8923
|
faceGroups
|
|
8417
8924
|
};
|
|
8418
8925
|
}
|
|
8419
|
-
/** Tessellate a single face
|
|
8420
|
-
function meshSingleFace(bk, faceId, deflection,
|
|
8926
|
+
/** Tessellate a single face, its triangles grouped under the face's own hash. */
|
|
8927
|
+
function meshSingleFace(bk, faceId, deflection, angularTolerance) {
|
|
8421
8928
|
const faceMesh = bk.tessellateFace(faceId, deflection, angularTolerance);
|
|
8422
8929
|
const positions = faceMesh.positions;
|
|
8423
8930
|
const normals = faceMesh.normals;
|
|
@@ -8433,7 +8940,7 @@ function meshSingleFace(bk, faceId, deflection, faceHash, angularTolerance) {
|
|
|
8433
8940
|
faceGroups: [{
|
|
8434
8941
|
start: 0,
|
|
8435
8942
|
count: indices.length,
|
|
8436
|
-
faceHash
|
|
8943
|
+
faceHash: faceId
|
|
8437
8944
|
}]
|
|
8438
8945
|
};
|
|
8439
8946
|
}
|
|
@@ -8446,22 +8953,219 @@ function makeMeshOps$1(bk) {
|
|
|
8446
8953
|
meshShape: (shape, tolerance, angularTolerance) => {}
|
|
8447
8954
|
};
|
|
8448
8955
|
}
|
|
8956
|
+
// src/kernel/brepkit/igesMerge.ts
|
|
8957
|
+
/**
|
|
8958
|
+
* Merge single-solid brepkit IGES documents into one.
|
|
8959
|
+
*
|
|
8960
|
+
* brepkit-wasm's `exportIges` takes one solid, but an IGES file holds one
|
|
8961
|
+
* document. brepkit's writer emits only standalone entities that point at no
|
|
8962
|
+
* other entity, so the merge appends each later document's directory and
|
|
8963
|
+
* parameter entries, renumbering only the fixed-column fields that number or
|
|
8964
|
+
* link them, and keeps the first document's start and global sections.
|
|
8965
|
+
*
|
|
8966
|
+
* @module
|
|
8967
|
+
*/
|
|
8968
|
+
/** Plane, line, B-spline curve and B-spline surface: the entities brepkit writes. */
|
|
8969
|
+
var POINTER_FREE = /* @__PURE__ */ new Set([
|
|
8970
|
+
108,
|
|
8971
|
+
110,
|
|
8972
|
+
126,
|
|
8973
|
+
128
|
|
8974
|
+
]);
|
|
8975
|
+
var PLANE = 108;
|
|
8976
|
+
/** A plane's sixth parameter points at its bounding curve; brepkit writes none. */
|
|
8977
|
+
var PLANE_BOUND = 5;
|
|
8978
|
+
/** Each line by the section letter in column 73. */
|
|
8979
|
+
function sections(doc) {
|
|
8980
|
+
const bySection = /* @__PURE__ */ new Map();
|
|
8981
|
+
for (const line of doc.split("\n")) {
|
|
8982
|
+
if (line.length < 73) continue;
|
|
8983
|
+
const letter = line.charAt(72);
|
|
8984
|
+
const lines = bySection.get(letter) ?? [];
|
|
8985
|
+
lines.push(line.slice(0, 80));
|
|
8986
|
+
bySection.set(letter, lines);
|
|
8987
|
+
}
|
|
8988
|
+
return {
|
|
8989
|
+
start: bySection.get("S") ?? [],
|
|
8990
|
+
global: bySection.get("G") ?? [],
|
|
8991
|
+
directory: bySection.get("D") ?? [],
|
|
8992
|
+
parameter: bySection.get("P") ?? []
|
|
8993
|
+
};
|
|
8994
|
+
}
|
|
8995
|
+
/** The `index`th 8-column field of a directory line. */
|
|
8996
|
+
function field(line, index) {
|
|
8997
|
+
return Number(line.slice(index * 8, index * 8 + 8).trim() || "0");
|
|
8998
|
+
}
|
|
8999
|
+
function withField(line, index, value) {
|
|
9000
|
+
return line.slice(0, index * 8) + String(value).padStart(8) + line.slice(index * 8 + 8);
|
|
9001
|
+
}
|
|
9002
|
+
/** `line` with its section letter and sequence number in columns 73-80. */
|
|
9003
|
+
function withSequence(line, letter, sequence) {
|
|
9004
|
+
return line.slice(0, 72).padEnd(72) + letter + String(sequence).padStart(7);
|
|
9005
|
+
}
|
|
9006
|
+
/** Throw unless the entity a directory entry describes points at nothing. */
|
|
9007
|
+
function assertPointerFree(line1, line2, parameter) {
|
|
9008
|
+
const type = field(line1, 0);
|
|
9009
|
+
const linked = [
|
|
9010
|
+
2,
|
|
9011
|
+
3,
|
|
9012
|
+
4,
|
|
9013
|
+
5,
|
|
9014
|
+
6,
|
|
9015
|
+
7
|
|
9016
|
+
].some((i) => field(line1, i) !== 0) || field(line2, 2) !== 0;
|
|
9017
|
+
let bounded = false;
|
|
9018
|
+
if (type === PLANE) {
|
|
9019
|
+
const first = field(line1, 1) - 1;
|
|
9020
|
+
bounded = (parameter.slice(first, first + field(line2, 3)).map((l) => l.slice(0, 64)).join("").split(/[,;]/)[PLANE_BOUND]?.trim() ?? "0") !== "0";
|
|
9021
|
+
}
|
|
9022
|
+
if (!POINTER_FREE.has(type) || linked || bounded) throw new Error(`brepkit: cannot merge IGES documents holding a linked entity (type ${type})`);
|
|
9023
|
+
}
|
|
9024
|
+
/** One IGES document holding the entities of every brepkit IGES document in `docs`. */
|
|
9025
|
+
function mergeIgesDocuments(docs) {
|
|
9026
|
+
const [first, ...rest] = docs;
|
|
9027
|
+
if (first === void 0) return "";
|
|
9028
|
+
if (rest.length === 0) return first;
|
|
9029
|
+
const base = sections(first);
|
|
9030
|
+
const directory = [];
|
|
9031
|
+
const parameter = [];
|
|
9032
|
+
for (const doc of docs) {
|
|
9033
|
+
const { directory: d, parameter: p } = sections(doc);
|
|
9034
|
+
const dOffset = directory.length;
|
|
9035
|
+
const pOffset = parameter.length;
|
|
9036
|
+
for (let i = 0; i + 1 < d.length; i += 2) {
|
|
9037
|
+
const line1 = d[i] ?? "";
|
|
9038
|
+
const line2 = d[i + 1] ?? "";
|
|
9039
|
+
assertPointerFree(line1, line2, p);
|
|
9040
|
+
const renumbered = withField(line1, 1, field(line1, 1) + pOffset);
|
|
9041
|
+
directory.push(withSequence(renumbered, "D", dOffset + i + 1));
|
|
9042
|
+
directory.push(withSequence(line2, "D", dOffset + i + 2));
|
|
9043
|
+
}
|
|
9044
|
+
p.forEach((line, j) => {
|
|
9045
|
+
const owner = Number(line.slice(64, 72).trim()) + dOffset;
|
|
9046
|
+
parameter.push(withSequence(line.slice(0, 64) + String(owner).padStart(8), "P", pOffset + j + 1));
|
|
9047
|
+
});
|
|
9048
|
+
}
|
|
9049
|
+
const count = (letter, n) => letter + String(n).padStart(7);
|
|
9050
|
+
const terminate = count("S", base.start.length) + count("G", base.global.length) + count("D", directory.length) + count("P", parameter.length);
|
|
9051
|
+
return [
|
|
9052
|
+
...base.start,
|
|
9053
|
+
...base.global,
|
|
9054
|
+
...directory,
|
|
9055
|
+
...parameter,
|
|
9056
|
+
withSequence(terminate, "T", 1),
|
|
9057
|
+
""
|
|
9058
|
+
].join("\n");
|
|
9059
|
+
}
|
|
9060
|
+
// src/kernel/brepkit/stepMerge.ts
|
|
9061
|
+
var REPRESENTATION = /^(ADVANCED_BREP_SHAPE_REPRESENTATION\s*\(\s*'(?:[^']|'')*'\s*,\s*\()([^)]*)\)/;
|
|
9062
|
+
/** A string literal, kept as is, or a `#n` entity reference. */
|
|
9063
|
+
var TOKEN = /'(?:[^']|'')*'|#(\d+)/g;
|
|
9064
|
+
/** Rewrite every `#n` reference outside a string literal to `#map(n)`. */
|
|
9065
|
+
function mapRefs(body, map) {
|
|
9066
|
+
return body.replace(TOKEN, (token, id) => id === void 0 ? token : `#${map(Number(id))}`);
|
|
9067
|
+
}
|
|
9068
|
+
function refsOf(body) {
|
|
9069
|
+
const refs = [];
|
|
9070
|
+
mapRefs(body, (id) => {
|
|
9071
|
+
refs.push(id);
|
|
9072
|
+
return id;
|
|
9073
|
+
});
|
|
9074
|
+
return refs;
|
|
9075
|
+
}
|
|
9076
|
+
/** Split the data section into records at semicolons outside string literals. */
|
|
9077
|
+
function parseStep(doc) {
|
|
9078
|
+
const dataStart = doc.indexOf("DATA;");
|
|
9079
|
+
if (dataStart < 0) throw new Error("brepkit: STEP document has no DATA section");
|
|
9080
|
+
const bodyStart = dataStart + 5;
|
|
9081
|
+
const records = [];
|
|
9082
|
+
let inString = false;
|
|
9083
|
+
let start = bodyStart;
|
|
9084
|
+
for (let i = bodyStart; i < doc.length; i++) {
|
|
9085
|
+
const ch = doc.charAt(i);
|
|
9086
|
+
if (ch === "'") inString = !inString;
|
|
9087
|
+
if (inString || ch !== ";") continue;
|
|
9088
|
+
const statement = doc.slice(start, i).trim();
|
|
9089
|
+
if (statement === "ENDSEC") return {
|
|
9090
|
+
head: doc.slice(0, bodyStart),
|
|
9091
|
+
tail: doc.slice(start).trimStart(),
|
|
9092
|
+
records
|
|
9093
|
+
};
|
|
9094
|
+
const match = /^#(\d+)\s*=\s*([\s\S]*)$/.exec(statement);
|
|
9095
|
+
if (!match) throw new Error(`brepkit: unreadable STEP record '${statement.slice(0, 40)}'`);
|
|
9096
|
+
records.push({
|
|
9097
|
+
id: Number(match[1]),
|
|
9098
|
+
body: match[2] ?? ""
|
|
9099
|
+
});
|
|
9100
|
+
start = i + 1;
|
|
9101
|
+
}
|
|
9102
|
+
throw new Error("brepkit: STEP document has an unterminated DATA section");
|
|
9103
|
+
}
|
|
9104
|
+
function representationIndex(records) {
|
|
9105
|
+
const index = records.findIndex((r) => REPRESENTATION.test(r.body));
|
|
9106
|
+
if (index < 0) throw new Error("brepkit: STEP document has no shape representation");
|
|
9107
|
+
return index;
|
|
9108
|
+
}
|
|
9109
|
+
/** The ids of the solids a document's shape representation lists. */
|
|
9110
|
+
function solidIds(records) {
|
|
9111
|
+
const rep = records[representationIndex(records)];
|
|
9112
|
+
return refsOf(REPRESENTATION.exec(rep?.body ?? "")?.[2] ?? "");
|
|
9113
|
+
}
|
|
9114
|
+
/** The records `roots` reach, in file order, renumbered consecutively from `firstId`. */
|
|
9115
|
+
function takeReachable(records, roots, firstId) {
|
|
9116
|
+
const byId = new Map(records.map((r) => [r.id, r.body]));
|
|
9117
|
+
const reached = /* @__PURE__ */ new Set();
|
|
9118
|
+
const pending = [...roots];
|
|
9119
|
+
while (pending.length > 0) {
|
|
9120
|
+
const id = pending.pop() ?? 0;
|
|
9121
|
+
if (reached.has(id)) continue;
|
|
9122
|
+
reached.add(id);
|
|
9123
|
+
for (const ref of refsOf(byId.get(id) ?? "")) pending.push(ref);
|
|
9124
|
+
}
|
|
9125
|
+
const kept = records.filter((r) => reached.has(r.id));
|
|
9126
|
+
const renumber = new Map(kept.map((r, i) => [r.id, firstId + i]));
|
|
9127
|
+
const remap = (id) => renumber.get(id) ?? id;
|
|
9128
|
+
return {
|
|
9129
|
+
lines: kept.map((r) => `#${remap(r.id)} = ${mapRefs(r.body, remap)};`),
|
|
9130
|
+
renumber
|
|
9131
|
+
};
|
|
9132
|
+
}
|
|
9133
|
+
/** One STEP document holding the solids of every brepkit STEP document in `docs`. */
|
|
9134
|
+
function mergeStepDocuments(docs) {
|
|
9135
|
+
const [first, ...rest] = docs;
|
|
9136
|
+
if (first === void 0) return "";
|
|
9137
|
+
if (rest.length === 0) return first;
|
|
9138
|
+
const base = parseStep(first);
|
|
9139
|
+
let nextId = base.records.reduce((max, r) => Math.max(max, r.id), 0) + 1;
|
|
9140
|
+
const added = [];
|
|
9141
|
+
const solids = [];
|
|
9142
|
+
for (const doc of rest) {
|
|
9143
|
+
const { records } = parseStep(doc);
|
|
9144
|
+
const roots = solidIds(records);
|
|
9145
|
+
const { lines, renumber } = takeReachable(records, roots, nextId);
|
|
9146
|
+
for (const line of lines) added.push(line);
|
|
9147
|
+
for (const id of roots) solids.push(renumber.get(id) ?? id);
|
|
9148
|
+
nextId += lines.length;
|
|
9149
|
+
}
|
|
9150
|
+
const repIndex = representationIndex(base.records);
|
|
9151
|
+
const extraItems = solids.map((id) => `, #${id}`).join("");
|
|
9152
|
+
const addItems = (_match, open, items) => `${open}${items}${extraItems})`;
|
|
9153
|
+
const lines = base.records.map(({ id, body }, i) => `#${id} = ${i === repIndex ? body.replace(REPRESENTATION, addItems) : body};`);
|
|
9154
|
+
const merged = [
|
|
9155
|
+
...lines.slice(0, repIndex),
|
|
9156
|
+
...added,
|
|
9157
|
+
...lines.slice(repIndex)
|
|
9158
|
+
];
|
|
9159
|
+
return `${base.head}\n${merged.join("\n")}\n${base.tail}`;
|
|
9160
|
+
}
|
|
8449
9161
|
// src/kernel/brepkit/ioOps.ts
|
|
8450
9162
|
function exportSTEP(bk, shapes) {
|
|
8451
9163
|
if (shapes.length === 0) return "";
|
|
8452
|
-
|
|
8453
|
-
for (const shape of shapes) {
|
|
8454
|
-
const solidIds = unwrapSolidsForExport(bk, shape, "exportSTEP");
|
|
8455
|
-
for (const sid of solidIds) {
|
|
8456
|
-
const bytes = bk.exportStep(sid);
|
|
8457
|
-
parts.push(new TextDecoder().decode(bytes));
|
|
8458
|
-
}
|
|
8459
|
-
}
|
|
8460
|
-
return parts.join("\n");
|
|
9164
|
+
return mergeStepDocuments(shapes.flatMap((shape) => unwrapSolidsForExport(bk, shape, "exportSTEP")).map((sid) => new TextDecoder().decode(bk.exportStep(sid))));
|
|
8461
9165
|
}
|
|
8462
9166
|
function exportSTL$1(bk, shape, binary, tolerance = require_occtWasmAdapter.DEFAULT_STL_TOLERANCE, angularTolerance = require_occtWasmAdapter.DEFAULT_STL_ANGULAR_TOLERANCE) {
|
|
8463
|
-
|
|
8464
|
-
const { vertices, triangles } = mesh$1(bk,
|
|
9167
|
+
unwrapSolidsForExport(bk, shape, "exportSTL");
|
|
9168
|
+
const { vertices, triangles } = mesh$1(bk, shape, {
|
|
8465
9169
|
tolerance,
|
|
8466
9170
|
angularTolerance,
|
|
8467
9171
|
skipNormals: true
|
|
@@ -8478,15 +9182,7 @@ function importSTL(bk, data) {
|
|
|
8478
9182
|
}
|
|
8479
9183
|
function exportIGES(bk, shapes) {
|
|
8480
9184
|
if (shapes.length === 0) return "";
|
|
8481
|
-
|
|
8482
|
-
for (const shape of shapes) {
|
|
8483
|
-
const solidIds = unwrapSolidsForExport(bk, shape, "exportIGES");
|
|
8484
|
-
for (const sid of solidIds) {
|
|
8485
|
-
const bytes = bk.exportIges(sid);
|
|
8486
|
-
parts.push(new TextDecoder().decode(bytes));
|
|
8487
|
-
}
|
|
8488
|
-
}
|
|
8489
|
-
return parts.join("\n");
|
|
9185
|
+
return mergeIgesDocuments(shapes.flatMap((shape) => unwrapSolidsForExport(bk, shape, "exportIGES")).map((sid) => new TextDecoder().decode(bk.exportIges(sid))));
|
|
8490
9186
|
}
|
|
8491
9187
|
function importIGES(bk, data) {
|
|
8492
9188
|
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
|
|
@@ -8529,9 +9225,11 @@ function toBREP(bk, shape) {
|
|
|
8529
9225
|
}
|
|
8530
9226
|
function fromBREP(bk, data) {
|
|
8531
9227
|
if (typeof bk.fromBREP === "function" && data.trimStart().startsWith("{")) return solidHandle(bk.fromBREP(data));
|
|
8532
|
-
const
|
|
9228
|
+
const shapes = importSTEP(bk, data);
|
|
9229
|
+
const [first] = shapes;
|
|
8533
9230
|
if (!first) throw new Error("brepkit: fromBREP produced no shapes");
|
|
8534
|
-
return first;
|
|
9231
|
+
if (shapes.length === 1) return first;
|
|
9232
|
+
return compoundHandle(bk.makeCompound(shapes.map((s) => unwrap$1(s, "solid"))));
|
|
8535
9233
|
}
|
|
8536
9234
|
function createXCAFDocument(_bk, shapes) {
|
|
8537
9235
|
return {
|
|
@@ -9222,19 +9920,9 @@ function liftCurve2dToPlane(bk, curve, origin, planeZ, planeX) {
|
|
|
9222
9920
|
-planeZ[2]
|
|
9223
9921
|
];
|
|
9224
9922
|
const bounds = require_occtWasmAdapter.curveBounds(c);
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
const nSegments = angularSpan > Math.PI ? 4 : angularSpan > Math.PI / 2 ? 2 : 1;
|
|
9229
|
-
const segmentSpan = (bounds.last - bounds.first) / nSegments;
|
|
9230
|
-
const edgeIds = [];
|
|
9231
|
-
for (let seg = 0; seg < nSegments; seg++) {
|
|
9232
|
-
const [su, sv] = require_occtWasmAdapter.evaluateCurve2d(c, bounds.first + seg * segmentSpan);
|
|
9233
|
-
const [eu, ev] = require_occtWasmAdapter.evaluateCurve2d(c, bounds.first + (seg + 1) * segmentSpan);
|
|
9234
|
-
edgeIds.push(bk.makeCircleArc3d(...lift(su, sv), ...lift(eu, ev), ...center3d, ...axis));
|
|
9235
|
-
}
|
|
9236
|
-
if (edgeIds.length === 1) return edgeHandle(require_bug.wasmIndex(edgeIds, 0));
|
|
9237
|
-
return wireHandle(bk.makeWire(edgeIds, false));
|
|
9923
|
+
const [su, sv] = require_occtWasmAdapter.evaluateCurve2d(c, bounds.first);
|
|
9924
|
+
const [eu, ev] = require_occtWasmAdapter.evaluateCurve2d(c, bounds.last);
|
|
9925
|
+
return edgeHandle(bk.makeCircleArc3d(...lift(su, sv), ...lift(eu, ev), ...center3d, ...axis));
|
|
9238
9926
|
}
|
|
9239
9927
|
if (basis.__bk2d === "ellipse") {
|
|
9240
9928
|
const ell = basis;
|
|
@@ -9349,9 +10037,7 @@ function refineUVSamples(uvSamples, evaluateUV, maxSamples, threshold) {
|
|
|
9349
10037
|
function extractCurve2dFromEdge(bk, edge, face) {
|
|
9350
10038
|
const eid = unwrap$1(edge, "edge");
|
|
9351
10039
|
const fid = unwrap$1(face, "face");
|
|
9352
|
-
const
|
|
9353
|
-
const tMin = params[0] ?? 0;
|
|
9354
|
-
const tMax = params[1] ?? 1;
|
|
10040
|
+
const [tMin, tMax] = edgeParamRange(bk, eid);
|
|
9355
10041
|
const BASE_N = 20;
|
|
9356
10042
|
const MAX_N = 80;
|
|
9357
10043
|
const REFINE_THRESHOLD = .05;
|
|
@@ -9388,9 +10074,7 @@ function fillSurface(bk, wires, _options) {
|
|
|
9388
10074
|
const curveLengths = [];
|
|
9389
10075
|
for (const edge of wireEdges) {
|
|
9390
10076
|
const edgeId = unwrap$1(edge, "edge");
|
|
9391
|
-
const
|
|
9392
|
-
const tMin = require_bug.wasmIndex(params, 0);
|
|
9393
|
-
const tMax = require_bug.wasmIndex(params, 1);
|
|
10077
|
+
const [tMin, tMax] = edgeParamRange(bk, edgeId);
|
|
9394
10078
|
const N = 10;
|
|
9395
10079
|
const pts = [];
|
|
9396
10080
|
for (let i = 0; i <= N; i++) {
|
|
@@ -9565,23 +10249,9 @@ function linearCenterOfMass(bk, shape) {
|
|
|
9565
10249
|
return centerOfMass$1(bk, shape);
|
|
9566
10250
|
}
|
|
9567
10251
|
function boundingBox$1(bk, shape) {
|
|
9568
|
-
const
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
return {
|
|
9572
|
-
min: require_bug.vec3At(bb, 0),
|
|
9573
|
-
max: require_bug.vec3At(bb, 3)
|
|
9574
|
-
};
|
|
9575
|
-
}
|
|
9576
|
-
if (h.type === "vertex") {
|
|
9577
|
-
const pos = vertexPosition(bk, shape);
|
|
9578
|
-
return {
|
|
9579
|
-
min: [...pos],
|
|
9580
|
-
max: [...pos]
|
|
9581
|
-
};
|
|
9582
|
-
}
|
|
9583
|
-
const vertices = iterShapes$1(bk, shape, "vertex");
|
|
9584
|
-
if (vertices.length === 0) return {
|
|
10252
|
+
const points = boxPoints(bk, shape);
|
|
10253
|
+
const [first] = points;
|
|
10254
|
+
if (!first) return {
|
|
9585
10255
|
min: [
|
|
9586
10256
|
0,
|
|
9587
10257
|
0,
|
|
@@ -9593,76 +10263,105 @@ function boundingBox$1(bk, shape) {
|
|
|
9593
10263
|
0
|
|
9594
10264
|
]
|
|
9595
10265
|
};
|
|
9596
|
-
const
|
|
9597
|
-
|
|
9598
|
-
let
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
if (p[0] < minX) minX = p[0];
|
|
9602
|
-
if (p[0] > maxX) maxX = p[0];
|
|
9603
|
-
if (p[1] < minY) minY = p[1];
|
|
9604
|
-
if (p[1] > maxY) maxY = p[1];
|
|
9605
|
-
if (p[2] < minZ) minZ = p[2];
|
|
9606
|
-
if (p[2] > maxZ) maxZ = p[2];
|
|
10266
|
+
const min = [...first];
|
|
10267
|
+
const max = [...first];
|
|
10268
|
+
for (const p of points) for (let k = 0; k < 3; k++) {
|
|
10269
|
+
min[k] = Math.min(require_bug.wasmIndex(min, k), require_bug.wasmIndex(p, k));
|
|
10270
|
+
max[k] = Math.max(require_bug.wasmIndex(max, k), require_bug.wasmIndex(p, k));
|
|
9607
10271
|
}
|
|
9608
10272
|
return {
|
|
9609
|
-
min
|
|
9610
|
-
|
|
9611
|
-
minY,
|
|
9612
|
-
minZ
|
|
9613
|
-
],
|
|
9614
|
-
max: [
|
|
9615
|
-
maxX,
|
|
9616
|
-
maxY,
|
|
9617
|
-
maxZ
|
|
9618
|
-
]
|
|
10273
|
+
min,
|
|
10274
|
+
max
|
|
9619
10275
|
};
|
|
9620
10276
|
}
|
|
10277
|
+
/**
|
|
10278
|
+
* Points whose bounding box is the shape's: a solid's own box corners, and for
|
|
10279
|
+
* anything else the box points of its edges (see `edgeBoxPoints`), so an arc's
|
|
10280
|
+
* bulge counts and not just its end vertices.
|
|
10281
|
+
*/
|
|
10282
|
+
function boxPoints(bk, h) {
|
|
10283
|
+
switch (h.type) {
|
|
10284
|
+
case "solid": {
|
|
10285
|
+
const bb = bk.boundingBox(h.id);
|
|
10286
|
+
return [require_bug.vec3At(bb, 0), require_bug.vec3At(bb, 3)];
|
|
10287
|
+
}
|
|
10288
|
+
case "vertex": return [require_bug.vec3At(bk.getVertexPosition(h.id))];
|
|
10289
|
+
case "edge": return edgeBoxPoints(bk, h.id);
|
|
10290
|
+
case "compound": return (syntheticCompounds.get(h.id) ?? compoundSolidIds(bk, h.id).map(solidHandle)).flatMap((child) => boxPoints(bk, child));
|
|
10291
|
+
default: {
|
|
10292
|
+
const edges = iterShapes$1(bk, h, "edge");
|
|
10293
|
+
if (edges.length > 0) return edges.flatMap((e) => edgeBoxPoints(bk, unwrap$1(e)));
|
|
10294
|
+
return iterShapes$1(bk, h, "vertex").map((v) => vertexPosition(bk, v));
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10297
|
+
}
|
|
10298
|
+
/**
|
|
10299
|
+
* Minimum distance between two shapes. brepkit-wasm measures from a point to a
|
|
10300
|
+
* solid, face or edge, and between two solids; a wire, shell or compound is
|
|
10301
|
+
* measured through its edges, faces or children, taking the closest pair. Any
|
|
10302
|
+
* other pairing (face to face, edge to edge, face to solid, ...) has no exact
|
|
10303
|
+
* brepkit measure and throws {@link UnsupportedKernelOperationError}.
|
|
10304
|
+
*/
|
|
9621
10305
|
function distance$1(bk, shape1, shape2) {
|
|
9622
|
-
const
|
|
9623
|
-
const
|
|
9624
|
-
|
|
9625
|
-
|
|
10306
|
+
const parts1 = distanceParts(bk, shape1);
|
|
10307
|
+
const parts2 = distanceParts(bk, shape2);
|
|
10308
|
+
let best;
|
|
10309
|
+
for (const a of parts1) for (const b of parts2) {
|
|
10310
|
+
const d = partDistance(bk, a, b);
|
|
10311
|
+
if (best === void 0 || d.value < best.value) best = d;
|
|
10312
|
+
}
|
|
10313
|
+
if (best === void 0) throw new Error("brepkit: distance needs two non-empty shapes");
|
|
10314
|
+
return best;
|
|
10315
|
+
}
|
|
10316
|
+
/** The solids, faces, edges and vertices a shape is measured through. */
|
|
10317
|
+
function distanceParts(bk, h) {
|
|
10318
|
+
switch (h.type) {
|
|
10319
|
+
case "wire": return toArray(bk.getWireEdges(h.id)).map(edgeHandle);
|
|
10320
|
+
case "shell": return toArray(bk.getShellFaces(h.id)).map(faceHandle);
|
|
10321
|
+
case "compound": return (syntheticCompounds.get(h.id) ?? compoundSolidIds(bk, h.id).map(solidHandle)).flatMap((child) => distanceParts(bk, child));
|
|
10322
|
+
default: return [h];
|
|
10323
|
+
}
|
|
10324
|
+
}
|
|
10325
|
+
function partDistance(bk, a, b) {
|
|
10326
|
+
if (a.type === "solid" && b.type === "solid") {
|
|
10327
|
+
const buf = bk.solidToSolidDistance(a.id, b.id);
|
|
9626
10328
|
return {
|
|
9627
10329
|
value: require_bug.wasmIndex(buf, 0),
|
|
9628
10330
|
point1: require_bug.vec3At(buf, 1),
|
|
9629
10331
|
point2: require_bug.vec3At(buf, 4)
|
|
9630
10332
|
};
|
|
9631
10333
|
}
|
|
9632
|
-
if (
|
|
9633
|
-
|
|
9634
|
-
const
|
|
10334
|
+
if (a.type === "vertex") return pointDistance(bk, a, b);
|
|
10335
|
+
if (b.type === "vertex") {
|
|
10336
|
+
const d = pointDistance(bk, b, a);
|
|
10337
|
+
return {
|
|
10338
|
+
value: d.value,
|
|
10339
|
+
point1: d.point2,
|
|
10340
|
+
point2: d.point1
|
|
10341
|
+
};
|
|
10342
|
+
}
|
|
10343
|
+
throw new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: no distance between a ${a.type} and a ${b.type}; brepkit-wasm measures from a point to a solid, face or edge, and between two solids`);
|
|
10344
|
+
}
|
|
10345
|
+
function pointDistance(bk, v, to) {
|
|
10346
|
+
const point1 = require_bug.vec3At(bk.getVertexPosition(v.id));
|
|
10347
|
+
if (to.type === "vertex") {
|
|
10348
|
+
const point2 = require_bug.vec3At(bk.getVertexPosition(to.id));
|
|
9635
10349
|
return {
|
|
9636
|
-
value:
|
|
10350
|
+
value: Math.hypot(point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]),
|
|
9637
10351
|
point1,
|
|
9638
|
-
point2
|
|
10352
|
+
point2
|
|
9639
10353
|
};
|
|
9640
10354
|
}
|
|
9641
|
-
const
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
(require_bug.wasmIndex(bb, 1) + require_bug.wasmIndex(bb, 4)) / 2,
|
|
9648
|
-
(require_bug.wasmIndex(bb, 2) + require_bug.wasmIndex(bb, 5)) / 2
|
|
9649
|
-
];
|
|
9650
|
-
}
|
|
9651
|
-
return [
|
|
9652
|
-
0,
|
|
9653
|
-
0,
|
|
9654
|
-
0
|
|
9655
|
-
];
|
|
9656
|
-
};
|
|
9657
|
-
const p1 = getPos(h1);
|
|
9658
|
-
const p2 = getPos(h2);
|
|
9659
|
-
const dx = p2[0] - p1[0];
|
|
9660
|
-
const dy = p2[1] - p1[1];
|
|
9661
|
-
const dz = p2[2] - p1[2];
|
|
10355
|
+
const [x, y, z] = point1;
|
|
10356
|
+
let result;
|
|
10357
|
+
if (to.type === "solid") result = bk.pointToSolidDistance(x, y, z, to.id);
|
|
10358
|
+
else if (to.type === "face") result = bk.pointToFaceDistance(x, y, z, to.id);
|
|
10359
|
+
else if (to.type === "edge") result = bk.pointToEdgeDistance(x, y, z, to.id);
|
|
10360
|
+
else throw new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: no distance from a vertex to a ${to.type}`);
|
|
9662
10361
|
return {
|
|
9663
|
-
value:
|
|
9664
|
-
point1
|
|
9665
|
-
point2:
|
|
10362
|
+
value: require_bug.wasmIndex(result, 0),
|
|
10363
|
+
point1,
|
|
10364
|
+
point2: require_bug.vec3At(result, 1)
|
|
9666
10365
|
};
|
|
9667
10366
|
}
|
|
9668
10367
|
function surfaceCurvature$1(bk, face, u, v) {
|
|
@@ -9937,6 +10636,8 @@ function trySmoothPipeShell(bk, faceId, spine) {
|
|
|
9937
10636
|
}
|
|
9938
10637
|
}
|
|
9939
10638
|
function sweepPipeShell(bk, profile, spine, options) {
|
|
10639
|
+
if (options?.["auxiliary"] !== void 0) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: sweepPipeShell has no auxiliary spine (twist or guided sweep)");
|
|
10640
|
+
if (options?.["law"] !== void 0) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: sweepPipeShell has no scaling law");
|
|
9940
10641
|
const profileHandle = profile;
|
|
9941
10642
|
const faceId = profileHandle.type === "wire" ? bk.makeFaceFromWire(profileHandle.id) : unwrap$1(profile, "face");
|
|
9942
10643
|
const shellMode = !!(options && options["shellMode"]);
|