brepjs 18.112.0 → 18.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brepjs.cjs +139 -23
- package/dist/brepjs.js +138 -24
- package/dist/index.d.ts +2 -2
- package/dist/topology/shapeRef/derivedFaceRefFns.d.ts +16 -0
- package/dist/topology/shapeRef/index.d.ts +2 -1
- package/dist/topology/shapeRef/roleLookup.d.ts +3 -1
- package/dist/topology/shapeRef/shapeRefTypes.d.ts +42 -0
- package/package.json +1 -1
package/dist/brepjs.cjs
CHANGED
|
@@ -1183,23 +1183,8 @@ function distance(a, b) {
|
|
|
1183
1183
|
const dz = a[2] - b[2];
|
|
1184
1184
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
1185
1185
|
}
|
|
1186
|
-
/**
|
|
1187
|
-
function
|
|
1188
|
-
const originRoles = roles.get(origin);
|
|
1189
|
-
if (!originRoles) return void 0;
|
|
1190
|
-
const hash = require_shapeFns.getHashCode(face);
|
|
1191
|
-
for (const [role, hashes] of originRoles) if (hashes.includes(hash)) return role;
|
|
1192
|
-
}
|
|
1193
|
-
/** Current faces a role resolves to — its tracked successors present in `shape`. */
|
|
1194
|
-
function facesForRole(shape, origin, role, roles) {
|
|
1195
|
-
const hashes = roles.get(origin)?.get(role);
|
|
1196
|
-
if (hashes === void 0 || hashes.length === 0) return [];
|
|
1197
|
-
return require_topologyQueryFns.getFaces(shape).filter((f) => hashes.includes(require_shapeFns.getHashCode(f)));
|
|
1198
|
-
}
|
|
1199
|
-
//#endregion
|
|
1200
|
-
//#region src/topology/shapeRef/edgeRefFns.ts
|
|
1201
|
-
/** Midpoint of an edge's endpoint vertices (a closed edge collapses to one). */
|
|
1202
|
-
function endpointMidpoint(verts) {
|
|
1186
|
+
/** Mean of a set of vertices' positions (e.g. an edge's endpoints). */
|
|
1187
|
+
function vertexCentroid(verts) {
|
|
1203
1188
|
if (verts.length === 0) return void 0;
|
|
1204
1189
|
let x = 0;
|
|
1205
1190
|
let y = 0;
|
|
@@ -1217,12 +1202,27 @@ function endpointMidpoint(verts) {
|
|
|
1217
1202
|
z / n
|
|
1218
1203
|
];
|
|
1219
1204
|
}
|
|
1205
|
+
/** The role whose tracked hashes include this face (reverse lookup). */
|
|
1206
|
+
function roleOfFace(face, origin, roles) {
|
|
1207
|
+
const originRoles = roles.get(origin);
|
|
1208
|
+
if (!originRoles) return void 0;
|
|
1209
|
+
const hash = require_shapeFns.getHashCode(face);
|
|
1210
|
+
for (const [role, hashes] of originRoles) if (hashes.includes(hash)) return role;
|
|
1211
|
+
}
|
|
1212
|
+
/** Current faces a role resolves to — its tracked successors present in `shape`. */
|
|
1213
|
+
function facesForRole(shape, origin, role, roles) {
|
|
1214
|
+
const hashes = roles.get(origin)?.get(role);
|
|
1215
|
+
if (hashes === void 0 || hashes.length === 0) return [];
|
|
1216
|
+
return require_topologyQueryFns.getFaces(shape).filter((f) => hashes.includes(require_shapeFns.getHashCode(f)));
|
|
1217
|
+
}
|
|
1218
|
+
//#endregion
|
|
1219
|
+
//#region src/topology/shapeRef/edgeRefFns.ts
|
|
1220
1220
|
function captureEdgeHint(edge) {
|
|
1221
1221
|
const lengthResult = require_measureFns.measureLength(edge);
|
|
1222
1222
|
return {
|
|
1223
1223
|
entityType: "edge",
|
|
1224
1224
|
length: lengthResult.ok ? lengthResult.value : void 0,
|
|
1225
|
-
midpoint:
|
|
1225
|
+
midpoint: vertexCentroid(require_healingFns.verticesOfEdge(edge))
|
|
1226
1226
|
};
|
|
1227
1227
|
}
|
|
1228
1228
|
function dedupeEdges(edges) {
|
|
@@ -1238,7 +1238,7 @@ function dedupeEdges(edges) {
|
|
|
1238
1238
|
return out;
|
|
1239
1239
|
}
|
|
1240
1240
|
/** Hint scores closer than this are treated as indistinguishable (→ ambiguous). */
|
|
1241
|
-
var HINT_MARGIN$
|
|
1241
|
+
var HINT_MARGIN$2 = 1e-6;
|
|
1242
1242
|
/**
|
|
1243
1243
|
* Pick the candidate edge closest to the hint (length + endpoint midpoint).
|
|
1244
1244
|
* Returns undefined when it genuinely can't discriminate — the hint carries no
|
|
@@ -1257,7 +1257,7 @@ function bestByHint(candidates, hint) {
|
|
|
1257
1257
|
if (len.ok) score += Math.abs(len.value - hint.length);
|
|
1258
1258
|
}
|
|
1259
1259
|
if (hint.midpoint !== void 0) {
|
|
1260
|
-
const mid =
|
|
1260
|
+
const mid = vertexCentroid(require_healingFns.verticesOfEdge(edge));
|
|
1261
1261
|
if (mid !== void 0) score += distance(hint.midpoint, mid);
|
|
1262
1262
|
}
|
|
1263
1263
|
if (score < bestScore) {
|
|
@@ -1266,7 +1266,7 @@ function bestByHint(candidates, hint) {
|
|
|
1266
1266
|
best = edge;
|
|
1267
1267
|
} else if (score < secondScore) secondScore = score;
|
|
1268
1268
|
}
|
|
1269
|
-
if (best === void 0 || secondScore - bestScore < HINT_MARGIN$
|
|
1269
|
+
if (best === void 0 || secondScore - bestScore < HINT_MARGIN$2) return void 0;
|
|
1270
1270
|
return best;
|
|
1271
1271
|
}
|
|
1272
1272
|
/**
|
|
@@ -1332,7 +1332,7 @@ function resolveEdgeRef(ref, roles, shape) {
|
|
|
1332
1332
|
/** A corner needs at least this many faces to pin a unique point. */
|
|
1333
1333
|
var MIN_VERTEX_FACES = 3;
|
|
1334
1334
|
/** Hint distances closer than this are indistinguishable (→ ambiguous). */
|
|
1335
|
-
var HINT_MARGIN = 1e-6;
|
|
1335
|
+
var HINT_MARGIN$1 = 1e-6;
|
|
1336
1336
|
/** Hashes of all vertices across `faces`, recording one handle per hash. */
|
|
1337
1337
|
function vertexHashes(faces, handles) {
|
|
1338
1338
|
const hashes = /* @__PURE__ */ new Set();
|
|
@@ -1378,7 +1378,7 @@ function nearestToHint(vertices, hint) {
|
|
|
1378
1378
|
best = v;
|
|
1379
1379
|
} else if (d < secondDist) secondDist = d;
|
|
1380
1380
|
}
|
|
1381
|
-
if (best === void 0 || secondDist - bestDist < HINT_MARGIN) return void 0;
|
|
1381
|
+
if (best === void 0 || secondDist - bestDist < HINT_MARGIN$1) return void 0;
|
|
1382
1382
|
return best;
|
|
1383
1383
|
}
|
|
1384
1384
|
/**
|
|
@@ -1445,6 +1445,120 @@ function resolveVertexRef(ref, roles, shape) {
|
|
|
1445
1445
|
};
|
|
1446
1446
|
}
|
|
1447
1447
|
//#endregion
|
|
1448
|
+
//#region src/topology/shapeRef/derivedFaceRefFns.ts
|
|
1449
|
+
/** A face re-derives a bridged face when its normal is nearly identical. */
|
|
1450
|
+
var NORMAL_MATCH = .99;
|
|
1451
|
+
/** A generated face's normal has a positive component along BOTH bridged normals. */
|
|
1452
|
+
var BLEND_THRESHOLD = .1;
|
|
1453
|
+
/** Tiebreak distances closer than this are indistinguishable (→ ambiguous). */
|
|
1454
|
+
var HINT_MARGIN = 1e-6;
|
|
1455
|
+
function normalDot(a, b) {
|
|
1456
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
1457
|
+
}
|
|
1458
|
+
/** Faces whose outward normal nearly matches `normal` (re-derives a bridged face). */
|
|
1459
|
+
function facesByNormal(shape, normal) {
|
|
1460
|
+
return require_topologyQueryFns.getFaces(shape).filter((f) => normalDot(require_faceFns.normalAt(f), normal) > NORMAL_MATCH);
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Faces adjacent to BOTH face sets, excluding the sets themselves. Uses the
|
|
1464
|
+
* cached edge→faces adjacency (`adjacentFaces`) rather than an O(F·N) per-pair
|
|
1465
|
+
* `sharedEdges` scan.
|
|
1466
|
+
*/
|
|
1467
|
+
function betweenFaces(shape, aFaces, bFaces) {
|
|
1468
|
+
const exclude = new Set([...aFaces, ...bFaces].map(require_shapeFns.getHashCode));
|
|
1469
|
+
const adjacentToA = /* @__PURE__ */ new Set();
|
|
1470
|
+
for (const a of aFaces) for (const f of require_healingFns.adjacentFaces(shape, a)) adjacentToA.add(require_shapeFns.getHashCode(f));
|
|
1471
|
+
const result = [];
|
|
1472
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1473
|
+
for (const b of bFaces) for (const f of require_healingFns.adjacentFaces(shape, b)) {
|
|
1474
|
+
const h = require_shapeFns.getHashCode(f);
|
|
1475
|
+
if (exclude.has(h) || seen.has(h) || !adjacentToA.has(h)) continue;
|
|
1476
|
+
seen.add(h);
|
|
1477
|
+
result.push(f);
|
|
1478
|
+
}
|
|
1479
|
+
return result;
|
|
1480
|
+
}
|
|
1481
|
+
/** Face whose center is nearest `point`; undefined on a tie (→ ambiguous). */
|
|
1482
|
+
function nearestFace(faces, point) {
|
|
1483
|
+
let best;
|
|
1484
|
+
let bestDist = Infinity;
|
|
1485
|
+
let secondDist = Infinity;
|
|
1486
|
+
for (const f of faces) {
|
|
1487
|
+
const d = distance(require_faceFns.faceCenter(f), point);
|
|
1488
|
+
if (d < bestDist) {
|
|
1489
|
+
secondDist = bestDist;
|
|
1490
|
+
bestDist = d;
|
|
1491
|
+
best = f;
|
|
1492
|
+
} else if (d < secondDist) secondDist = d;
|
|
1493
|
+
}
|
|
1494
|
+
if (best === void 0 || secondDist - bestDist < HINT_MARGIN) return void 0;
|
|
1495
|
+
return best;
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Capture a reference to the face an `op` (fillet/chamfer) will generate across
|
|
1499
|
+
* `edge`: the roles of the edge's two faces, their outward normals, and the edge
|
|
1500
|
+
* midpoint. Call this on the PRE-op shape. Returns undefined when the edge
|
|
1501
|
+
* doesn't bound two named faces.
|
|
1502
|
+
*/
|
|
1503
|
+
function createDerivedFaceRef(origin, op, edge, preShape, roles) {
|
|
1504
|
+
const [faceA, faceB] = require_healingFns.facesOfEdge(preShape, edge);
|
|
1505
|
+
if (faceA === void 0 || faceB === void 0) return void 0;
|
|
1506
|
+
const roleA = roleOfFace(faceA, origin, roles);
|
|
1507
|
+
const roleB = roleOfFace(faceB, origin, roles);
|
|
1508
|
+
if (roleA === void 0 || roleB === void 0) return void 0;
|
|
1509
|
+
return {
|
|
1510
|
+
origin,
|
|
1511
|
+
op,
|
|
1512
|
+
betweenRoles: [roleA, roleB],
|
|
1513
|
+
hint: {
|
|
1514
|
+
entityType: "derived-face",
|
|
1515
|
+
normalA: require_faceFns.normalAt(faceA),
|
|
1516
|
+
normalB: require_faceFns.normalAt(faceB),
|
|
1517
|
+
edgeMidpoint: vertexCentroid(require_healingFns.verticesOfEdge(edge))
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Resolve a DerivedFaceRef in the post-op `shape`: re-derive the two bridged
|
|
1523
|
+
* faces (role table, else by captured normal), then return the face adjacent to
|
|
1524
|
+
* both whose normal blends both. One survivor → resolved; several →
|
|
1525
|
+
* nearest-to-edge-midpoint; none → broken.
|
|
1526
|
+
*/
|
|
1527
|
+
function resolveDerivedFaceRef(ref, roles, shape) {
|
|
1528
|
+
let aFaces = facesForRole(shape, ref.origin, ref.betweenRoles[0], roles);
|
|
1529
|
+
if (aFaces.length === 0) aFaces = facesByNormal(shape, ref.hint.normalA);
|
|
1530
|
+
let bFaces = facesForRole(shape, ref.origin, ref.betweenRoles[1], roles);
|
|
1531
|
+
if (bFaces.length === 0) bFaces = facesByNormal(shape, ref.hint.normalB);
|
|
1532
|
+
if (aFaces.length === 0 || bFaces.length === 0) return {
|
|
1533
|
+
ref,
|
|
1534
|
+
reason: "not-found"
|
|
1535
|
+
};
|
|
1536
|
+
const blended = betweenFaces(shape, aFaces, bFaces).filter((f) => normalDot(require_faceFns.normalAt(f), ref.hint.normalA) > BLEND_THRESHOLD && normalDot(require_faceFns.normalAt(f), ref.hint.normalB) > BLEND_THRESHOLD);
|
|
1537
|
+
if (blended.length === 1) {
|
|
1538
|
+
const [only] = blended;
|
|
1539
|
+
if (only !== void 0) return {
|
|
1540
|
+
face: only,
|
|
1541
|
+
confidence: "geometric-fallback"
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
if (blended.length > 1) {
|
|
1545
|
+
const best = ref.hint.edgeMidpoint && nearestFace(blended, ref.hint.edgeMidpoint);
|
|
1546
|
+
if (best) return {
|
|
1547
|
+
face: best,
|
|
1548
|
+
confidence: "geometric-fallback"
|
|
1549
|
+
};
|
|
1550
|
+
return {
|
|
1551
|
+
ref,
|
|
1552
|
+
reason: "ambiguous",
|
|
1553
|
+
candidates: blended
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
return {
|
|
1557
|
+
ref,
|
|
1558
|
+
reason: "not-found"
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1561
|
+
//#endregion
|
|
1448
1562
|
//#region src/topology/surfaceFns.ts
|
|
1449
1563
|
/**
|
|
1450
1564
|
* Surface creation functions — generate faces from height-map grids.
|
|
@@ -7148,6 +7262,7 @@ exports.createBlueprint = require_blueprintFns.createBlueprint;
|
|
|
7148
7262
|
exports.createCamera = require_cameraFns.createCamera;
|
|
7149
7263
|
exports.createCompound = require_shapeTypes.createCompound;
|
|
7150
7264
|
exports.createCompoundBlueprint = require_blueprintFns.createCompoundBlueprint;
|
|
7265
|
+
exports.createDerivedFaceRef = createDerivedFaceRef;
|
|
7151
7266
|
exports.createDistanceQuery = require_measureFns.createDistanceQuery;
|
|
7152
7267
|
exports.createEdge = require_shapeTypes.createEdge;
|
|
7153
7268
|
exports.createEdgeRef = createEdgeRef;
|
|
@@ -7539,6 +7654,7 @@ exports.resetPerformanceStats = require_shapeTypes.resetPerformanceStats;
|
|
|
7539
7654
|
exports.resize = require_shapeFns.resize;
|
|
7540
7655
|
exports.resolve = resolve;
|
|
7541
7656
|
exports.resolve3D = resolve3D;
|
|
7657
|
+
exports.resolveDerivedFaceRef = resolveDerivedFaceRef;
|
|
7542
7658
|
exports.resolveDirection = require_types.resolveDirection;
|
|
7543
7659
|
exports.resolveEdgeRef = resolveEdgeRef;
|
|
7544
7660
|
exports.resolvePlane = require_planeOps.resolvePlane;
|
package/dist/brepjs.js
CHANGED
|
@@ -1194,23 +1194,8 @@ function distance(a, b) {
|
|
|
1194
1194
|
const dz = a[2] - b[2];
|
|
1195
1195
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
1196
1196
|
}
|
|
1197
|
-
/**
|
|
1198
|
-
function
|
|
1199
|
-
const originRoles = roles.get(origin);
|
|
1200
|
-
if (!originRoles) return void 0;
|
|
1201
|
-
const hash = getHashCode(face);
|
|
1202
|
-
for (const [role, hashes] of originRoles) if (hashes.includes(hash)) return role;
|
|
1203
|
-
}
|
|
1204
|
-
/** Current faces a role resolves to — its tracked successors present in `shape`. */
|
|
1205
|
-
function facesForRole(shape, origin, role, roles) {
|
|
1206
|
-
const hashes = roles.get(origin)?.get(role);
|
|
1207
|
-
if (hashes === void 0 || hashes.length === 0) return [];
|
|
1208
|
-
return getFaces(shape).filter((f) => hashes.includes(getHashCode(f)));
|
|
1209
|
-
}
|
|
1210
|
-
//#endregion
|
|
1211
|
-
//#region src/topology/shapeRef/edgeRefFns.ts
|
|
1212
|
-
/** Midpoint of an edge's endpoint vertices (a closed edge collapses to one). */
|
|
1213
|
-
function endpointMidpoint(verts) {
|
|
1197
|
+
/** Mean of a set of vertices' positions (e.g. an edge's endpoints). */
|
|
1198
|
+
function vertexCentroid(verts) {
|
|
1214
1199
|
if (verts.length === 0) return void 0;
|
|
1215
1200
|
let x = 0;
|
|
1216
1201
|
let y = 0;
|
|
@@ -1228,12 +1213,27 @@ function endpointMidpoint(verts) {
|
|
|
1228
1213
|
z / n
|
|
1229
1214
|
];
|
|
1230
1215
|
}
|
|
1216
|
+
/** The role whose tracked hashes include this face (reverse lookup). */
|
|
1217
|
+
function roleOfFace(face, origin, roles) {
|
|
1218
|
+
const originRoles = roles.get(origin);
|
|
1219
|
+
if (!originRoles) return void 0;
|
|
1220
|
+
const hash = getHashCode(face);
|
|
1221
|
+
for (const [role, hashes] of originRoles) if (hashes.includes(hash)) return role;
|
|
1222
|
+
}
|
|
1223
|
+
/** Current faces a role resolves to — its tracked successors present in `shape`. */
|
|
1224
|
+
function facesForRole(shape, origin, role, roles) {
|
|
1225
|
+
const hashes = roles.get(origin)?.get(role);
|
|
1226
|
+
if (hashes === void 0 || hashes.length === 0) return [];
|
|
1227
|
+
return getFaces(shape).filter((f) => hashes.includes(getHashCode(f)));
|
|
1228
|
+
}
|
|
1229
|
+
//#endregion
|
|
1230
|
+
//#region src/topology/shapeRef/edgeRefFns.ts
|
|
1231
1231
|
function captureEdgeHint(edge) {
|
|
1232
1232
|
const lengthResult = measureLength(edge);
|
|
1233
1233
|
return {
|
|
1234
1234
|
entityType: "edge",
|
|
1235
1235
|
length: lengthResult.ok ? lengthResult.value : void 0,
|
|
1236
|
-
midpoint:
|
|
1236
|
+
midpoint: vertexCentroid(verticesOfEdge(edge))
|
|
1237
1237
|
};
|
|
1238
1238
|
}
|
|
1239
1239
|
function dedupeEdges(edges) {
|
|
@@ -1249,7 +1249,7 @@ function dedupeEdges(edges) {
|
|
|
1249
1249
|
return out;
|
|
1250
1250
|
}
|
|
1251
1251
|
/** Hint scores closer than this are treated as indistinguishable (→ ambiguous). */
|
|
1252
|
-
var HINT_MARGIN$
|
|
1252
|
+
var HINT_MARGIN$2 = 1e-6;
|
|
1253
1253
|
/**
|
|
1254
1254
|
* Pick the candidate edge closest to the hint (length + endpoint midpoint).
|
|
1255
1255
|
* Returns undefined when it genuinely can't discriminate — the hint carries no
|
|
@@ -1268,7 +1268,7 @@ function bestByHint(candidates, hint) {
|
|
|
1268
1268
|
if (len.ok) score += Math.abs(len.value - hint.length);
|
|
1269
1269
|
}
|
|
1270
1270
|
if (hint.midpoint !== void 0) {
|
|
1271
|
-
const mid =
|
|
1271
|
+
const mid = vertexCentroid(verticesOfEdge(edge));
|
|
1272
1272
|
if (mid !== void 0) score += distance(hint.midpoint, mid);
|
|
1273
1273
|
}
|
|
1274
1274
|
if (score < bestScore) {
|
|
@@ -1277,7 +1277,7 @@ function bestByHint(candidates, hint) {
|
|
|
1277
1277
|
best = edge;
|
|
1278
1278
|
} else if (score < secondScore) secondScore = score;
|
|
1279
1279
|
}
|
|
1280
|
-
if (best === void 0 || secondScore - bestScore < HINT_MARGIN$
|
|
1280
|
+
if (best === void 0 || secondScore - bestScore < HINT_MARGIN$2) return void 0;
|
|
1281
1281
|
return best;
|
|
1282
1282
|
}
|
|
1283
1283
|
/**
|
|
@@ -1343,7 +1343,7 @@ function resolveEdgeRef(ref, roles, shape) {
|
|
|
1343
1343
|
/** A corner needs at least this many faces to pin a unique point. */
|
|
1344
1344
|
var MIN_VERTEX_FACES = 3;
|
|
1345
1345
|
/** Hint distances closer than this are indistinguishable (→ ambiguous). */
|
|
1346
|
-
var HINT_MARGIN = 1e-6;
|
|
1346
|
+
var HINT_MARGIN$1 = 1e-6;
|
|
1347
1347
|
/** Hashes of all vertices across `faces`, recording one handle per hash. */
|
|
1348
1348
|
function vertexHashes(faces, handles) {
|
|
1349
1349
|
const hashes = /* @__PURE__ */ new Set();
|
|
@@ -1389,7 +1389,7 @@ function nearestToHint(vertices, hint) {
|
|
|
1389
1389
|
best = v;
|
|
1390
1390
|
} else if (d < secondDist) secondDist = d;
|
|
1391
1391
|
}
|
|
1392
|
-
if (best === void 0 || secondDist - bestDist < HINT_MARGIN) return void 0;
|
|
1392
|
+
if (best === void 0 || secondDist - bestDist < HINT_MARGIN$1) return void 0;
|
|
1393
1393
|
return best;
|
|
1394
1394
|
}
|
|
1395
1395
|
/**
|
|
@@ -1456,6 +1456,120 @@ function resolveVertexRef(ref, roles, shape) {
|
|
|
1456
1456
|
};
|
|
1457
1457
|
}
|
|
1458
1458
|
//#endregion
|
|
1459
|
+
//#region src/topology/shapeRef/derivedFaceRefFns.ts
|
|
1460
|
+
/** A face re-derives a bridged face when its normal is nearly identical. */
|
|
1461
|
+
var NORMAL_MATCH = .99;
|
|
1462
|
+
/** A generated face's normal has a positive component along BOTH bridged normals. */
|
|
1463
|
+
var BLEND_THRESHOLD = .1;
|
|
1464
|
+
/** Tiebreak distances closer than this are indistinguishable (→ ambiguous). */
|
|
1465
|
+
var HINT_MARGIN = 1e-6;
|
|
1466
|
+
function normalDot(a, b) {
|
|
1467
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
1468
|
+
}
|
|
1469
|
+
/** Faces whose outward normal nearly matches `normal` (re-derives a bridged face). */
|
|
1470
|
+
function facesByNormal(shape, normal) {
|
|
1471
|
+
return getFaces(shape).filter((f) => normalDot(normalAt(f), normal) > NORMAL_MATCH);
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Faces adjacent to BOTH face sets, excluding the sets themselves. Uses the
|
|
1475
|
+
* cached edge→faces adjacency (`adjacentFaces`) rather than an O(F·N) per-pair
|
|
1476
|
+
* `sharedEdges` scan.
|
|
1477
|
+
*/
|
|
1478
|
+
function betweenFaces(shape, aFaces, bFaces) {
|
|
1479
|
+
const exclude = new Set([...aFaces, ...bFaces].map(getHashCode));
|
|
1480
|
+
const adjacentToA = /* @__PURE__ */ new Set();
|
|
1481
|
+
for (const a of aFaces) for (const f of adjacentFaces(shape, a)) adjacentToA.add(getHashCode(f));
|
|
1482
|
+
const result = [];
|
|
1483
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1484
|
+
for (const b of bFaces) for (const f of adjacentFaces(shape, b)) {
|
|
1485
|
+
const h = getHashCode(f);
|
|
1486
|
+
if (exclude.has(h) || seen.has(h) || !adjacentToA.has(h)) continue;
|
|
1487
|
+
seen.add(h);
|
|
1488
|
+
result.push(f);
|
|
1489
|
+
}
|
|
1490
|
+
return result;
|
|
1491
|
+
}
|
|
1492
|
+
/** Face whose center is nearest `point`; undefined on a tie (→ ambiguous). */
|
|
1493
|
+
function nearestFace(faces, point) {
|
|
1494
|
+
let best;
|
|
1495
|
+
let bestDist = Infinity;
|
|
1496
|
+
let secondDist = Infinity;
|
|
1497
|
+
for (const f of faces) {
|
|
1498
|
+
const d = distance(faceCenter(f), point);
|
|
1499
|
+
if (d < bestDist) {
|
|
1500
|
+
secondDist = bestDist;
|
|
1501
|
+
bestDist = d;
|
|
1502
|
+
best = f;
|
|
1503
|
+
} else if (d < secondDist) secondDist = d;
|
|
1504
|
+
}
|
|
1505
|
+
if (best === void 0 || secondDist - bestDist < HINT_MARGIN) return void 0;
|
|
1506
|
+
return best;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Capture a reference to the face an `op` (fillet/chamfer) will generate across
|
|
1510
|
+
* `edge`: the roles of the edge's two faces, their outward normals, and the edge
|
|
1511
|
+
* midpoint. Call this on the PRE-op shape. Returns undefined when the edge
|
|
1512
|
+
* doesn't bound two named faces.
|
|
1513
|
+
*/
|
|
1514
|
+
function createDerivedFaceRef(origin, op, edge, preShape, roles) {
|
|
1515
|
+
const [faceA, faceB] = facesOfEdge(preShape, edge);
|
|
1516
|
+
if (faceA === void 0 || faceB === void 0) return void 0;
|
|
1517
|
+
const roleA = roleOfFace(faceA, origin, roles);
|
|
1518
|
+
const roleB = roleOfFace(faceB, origin, roles);
|
|
1519
|
+
if (roleA === void 0 || roleB === void 0) return void 0;
|
|
1520
|
+
return {
|
|
1521
|
+
origin,
|
|
1522
|
+
op,
|
|
1523
|
+
betweenRoles: [roleA, roleB],
|
|
1524
|
+
hint: {
|
|
1525
|
+
entityType: "derived-face",
|
|
1526
|
+
normalA: normalAt(faceA),
|
|
1527
|
+
normalB: normalAt(faceB),
|
|
1528
|
+
edgeMidpoint: vertexCentroid(verticesOfEdge(edge))
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Resolve a DerivedFaceRef in the post-op `shape`: re-derive the two bridged
|
|
1534
|
+
* faces (role table, else by captured normal), then return the face adjacent to
|
|
1535
|
+
* both whose normal blends both. One survivor → resolved; several →
|
|
1536
|
+
* nearest-to-edge-midpoint; none → broken.
|
|
1537
|
+
*/
|
|
1538
|
+
function resolveDerivedFaceRef(ref, roles, shape) {
|
|
1539
|
+
let aFaces = facesForRole(shape, ref.origin, ref.betweenRoles[0], roles);
|
|
1540
|
+
if (aFaces.length === 0) aFaces = facesByNormal(shape, ref.hint.normalA);
|
|
1541
|
+
let bFaces = facesForRole(shape, ref.origin, ref.betweenRoles[1], roles);
|
|
1542
|
+
if (bFaces.length === 0) bFaces = facesByNormal(shape, ref.hint.normalB);
|
|
1543
|
+
if (aFaces.length === 0 || bFaces.length === 0) return {
|
|
1544
|
+
ref,
|
|
1545
|
+
reason: "not-found"
|
|
1546
|
+
};
|
|
1547
|
+
const blended = betweenFaces(shape, aFaces, bFaces).filter((f) => normalDot(normalAt(f), ref.hint.normalA) > BLEND_THRESHOLD && normalDot(normalAt(f), ref.hint.normalB) > BLEND_THRESHOLD);
|
|
1548
|
+
if (blended.length === 1) {
|
|
1549
|
+
const [only] = blended;
|
|
1550
|
+
if (only !== void 0) return {
|
|
1551
|
+
face: only,
|
|
1552
|
+
confidence: "geometric-fallback"
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
if (blended.length > 1) {
|
|
1556
|
+
const best = ref.hint.edgeMidpoint && nearestFace(blended, ref.hint.edgeMidpoint);
|
|
1557
|
+
if (best) return {
|
|
1558
|
+
face: best,
|
|
1559
|
+
confidence: "geometric-fallback"
|
|
1560
|
+
};
|
|
1561
|
+
return {
|
|
1562
|
+
ref,
|
|
1563
|
+
reason: "ambiguous",
|
|
1564
|
+
candidates: blended
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
return {
|
|
1568
|
+
ref,
|
|
1569
|
+
reason: "not-found"
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
//#endregion
|
|
1459
1573
|
//#region src/topology/surfaceFns.ts
|
|
1460
1574
|
/**
|
|
1461
1575
|
* Surface creation functions — generate faces from height-map grids.
|
|
@@ -7056,4 +7170,4 @@ var csg_exports = /* @__PURE__ */ __exportAll({
|
|
|
7056
7170
|
withEvaluator: () => withEvaluator
|
|
7057
7171
|
});
|
|
7058
7172
|
//#endregion
|
|
7059
|
-
export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createEdgeRef, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createVertexRef, createWire, createWorkerClient, createWorkerHandler, createWorkerPool, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, exportURDF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, facesOfVertex, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, forwardKinematics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, gridPattern, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, importURDF, init, initFromManifold, initFromOC, initVoxel, innerWires, instance, instanceCount, instanceGrid, instancedMesh, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, inverseKinematics, ioNs_exports as io, ioError, is2D, is3D, isBatchRequest, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isInstanced, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTrajectory, jointTransform, jointsFromDH, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, materialize, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mechanismDOF, mesh, meshEdges, meshLODs, meshLODsProgressive, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarJoint, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolveEdgeRef, resolvePlane, resolveRef, resolveVertexRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setJointValues, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLODGeometryLevels, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, verticesOfFace, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
|
|
7173
|
+
export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addJoint, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDerivedFaceRef, createDistanceQuery, createEdge, createEdgeRef, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createVertexRef, createWire, createWorkerClient, createWorkerHandler, createWorkerPool, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, cylindricalJoint, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, exportURDF, extrude, extrudeAll, face, faceAxis, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, facesOfVertex, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, forwardKinematics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, gridPattern, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, importURDF, init, initFromManifold, initFromOC, initVoxel, innerWires, instance, instanceCount, instanceGrid, instancedMesh, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, inverseKinematics, ioNs_exports as io, ioError, is2D, is3D, isBatchRequest, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isInstanced, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, jointTrajectory, jointTransform, jointsFromDH, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, materialize, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mechanismDOF, mesh, meshEdges, meshLODs, meshLODsProgressive, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarJoint, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, prismaticJoint, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDerivedFaceRef, resolveDirection, resolveEdgeRef, resolvePlane, resolveRef, resolveVertexRef, reverseCurve, revoluteJoint, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, fieldAxialRamp as sdfFieldAxialRamp, fieldClamp as sdfFieldClamp, fieldConst as sdfFieldConst, fieldFromSdf as sdfFieldFromSdf, fieldRadialRamp as sdfFieldRadialRamp, lattice as sdfLattice, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, strutLattice as sdfStrutLattice, sweep as sdfSweep, torus as sdfTorus, section, sectionToFace, serializeHistory, setJointValue, setJointValues, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, sphericalJoint, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep$1 as sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, thread, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLODGeometryLevels, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, verticesOfFace, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
|
package/dist/index.d.ts
CHANGED
|
@@ -102,8 +102,8 @@ export { checkBoolean } from './topology/booleanDiagnosticFns.js';
|
|
|
102
102
|
export type { CheckBooleanResult, BooleanIssue, BooleanOpType, BooleanDiagnostics, } from './kernel/types.js';
|
|
103
103
|
export { fuseWithEvolution, cutWithEvolution, intersectWithEvolution, filletWithEvolution, chamferWithEvolution, shellWithEvolution, type EvolutionResult, } from './topology/evolutionFns.js';
|
|
104
104
|
export type { ShapeEvolution } from './kernel/types.js';
|
|
105
|
-
export { captureHint, assignRoles, createRef, updateRoles, resolveRef, defaultScorer, createEdgeRef, resolveEdgeRef, createVertexRef, resolveVertexRef, } from './topology/shapeRef/index.js';
|
|
106
|
-
export type { GeometricHint, ShapeRef, RoleTable, ResolvedRef, BrokenRef, FaceScorer, EdgeHint, EdgeRef, ResolvedEdgeRef, BrokenEdgeRef, VertexHint, VertexRef, ResolvedVertexRef, BrokenVertexRef, } from './topology/shapeRef/index.js';
|
|
105
|
+
export { captureHint, assignRoles, createRef, updateRoles, resolveRef, defaultScorer, createEdgeRef, resolveEdgeRef, createVertexRef, resolveVertexRef, createDerivedFaceRef, resolveDerivedFaceRef, } from './topology/shapeRef/index.js';
|
|
106
|
+
export type { GeometricHint, ShapeRef, RoleTable, ResolvedRef, BrokenRef, FaceScorer, EdgeHint, EdgeRef, ResolvedEdgeRef, BrokenEdgeRef, VertexHint, VertexRef, ResolvedVertexRef, BrokenVertexRef, DerivedFaceHint, DerivedFaceRef, ResolvedDerivedFaceRef, BrokenDerivedFaceRef, } from './topology/shapeRef/index.js';
|
|
107
107
|
export { surfaceFromGrid, surfaceFromImage, type SurfaceFromGridOptions, type SurfaceFromImageOptions, } from './topology/surfaceFns.js';
|
|
108
108
|
export { hull, type HullOptions } from './topology/hullFns.js';
|
|
109
109
|
export { convexHull } from './operations/convexHullFns.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Edge, Shape3D } from '../../core/shapeTypes.js';
|
|
2
|
+
import { DerivedFaceRef, ResolvedDerivedFaceRef, BrokenDerivedFaceRef, RoleTable } from './shapeRefTypes.js';
|
|
3
|
+
/**
|
|
4
|
+
* Capture a reference to the face an `op` (fillet/chamfer) will generate across
|
|
5
|
+
* `edge`: the roles of the edge's two faces, their outward normals, and the edge
|
|
6
|
+
* midpoint. Call this on the PRE-op shape. Returns undefined when the edge
|
|
7
|
+
* doesn't bound two named faces.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createDerivedFaceRef(origin: string, op: 'fillet' | 'chamfer', edge: Edge, preShape: Shape3D, roles: RoleTable): DerivedFaceRef | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a DerivedFaceRef in the post-op `shape`: re-derive the two bridged
|
|
12
|
+
* faces (role table, else by captured normal), then return the face adjacent to
|
|
13
|
+
* both whose normal blends both. One survivor → resolved; several →
|
|
14
|
+
* nearest-to-edge-midpoint; none → broken.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveDerivedFaceRef(ref: DerivedFaceRef, roles: RoleTable, shape: Shape3D): ResolvedDerivedFaceRef | BrokenDerivedFaceRef;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ShapeRef — stable, serializable face references for parametric replay.
|
|
3
3
|
*/
|
|
4
|
-
export type { GeometricHint, ShapeRef, RoleTable, ResolvedRef, BrokenRef, EdgeHint, EdgeRef, ResolvedEdgeRef, BrokenEdgeRef, VertexHint, VertexRef, ResolvedVertexRef, BrokenVertexRef, } from './shapeRefTypes.js';
|
|
4
|
+
export type { GeometricHint, ShapeRef, RoleTable, ResolvedRef, BrokenRef, EdgeHint, EdgeRef, ResolvedEdgeRef, BrokenEdgeRef, VertexHint, VertexRef, ResolvedVertexRef, BrokenVertexRef, DerivedFaceHint, DerivedFaceRef, ResolvedDerivedFaceRef, BrokenDerivedFaceRef, } from './shapeRefTypes.js';
|
|
5
5
|
export { type FaceScorer, defaultScorer } from './scoring.js';
|
|
6
6
|
export { captureHint, assignRoles, createRef, updateRoles, resolveRef } from './shapeRefFns.js';
|
|
7
7
|
export { createEdgeRef, resolveEdgeRef } from './edgeRefFns.js';
|
|
8
8
|
export { createVertexRef, resolveVertexRef } from './vertexRefFns.js';
|
|
9
|
+
export { createDerivedFaceRef, resolveDerivedFaceRef } from './derivedFaceRefFns.js';
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { Face, Shape3D } from '../../core/shapeTypes.js';
|
|
1
|
+
import { Face, Shape3D, Vertex } from '../../core/shapeTypes.js';
|
|
2
2
|
import { Vec3 } from '../../core/types.js';
|
|
3
3
|
import { RoleTable } from './shapeRefTypes.js';
|
|
4
4
|
/** Euclidean distance between two points. */
|
|
5
5
|
export declare function distance(a: Vec3, b: Vec3): number;
|
|
6
|
+
/** Mean of a set of vertices' positions (e.g. an edge's endpoints). */
|
|
7
|
+
export declare function vertexCentroid(verts: readonly Vertex[]): Vec3 | undefined;
|
|
6
8
|
/** The role whose tracked hashes include this face (reverse lookup). */
|
|
7
9
|
export declare function roleOfFace(face: Face, origin: string, roles: RoleTable): string | undefined;
|
|
8
10
|
/** Current faces a role resolves to — its tracked successors present in `shape`. */
|
|
@@ -104,3 +104,45 @@ export interface BrokenVertexRef {
|
|
|
104
104
|
readonly reason: 'ambiguous' | 'not-found';
|
|
105
105
|
readonly candidates?: readonly Vertex[];
|
|
106
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Snapshot for re-deriving a generated face. fillet/chamfer evolution is empty
|
|
109
|
+
* on the OCCT kernels, so the role table can't track the bridged faces — they
|
|
110
|
+
* are re-found by their captured outward normals; the edge midpoint breaks ties.
|
|
111
|
+
*/
|
|
112
|
+
export interface DerivedFaceHint {
|
|
113
|
+
readonly entityType: 'derived-face';
|
|
114
|
+
readonly normalA: Vec3;
|
|
115
|
+
readonly normalB: Vec3;
|
|
116
|
+
readonly edgeMidpoint?: Vec3 | undefined;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A reference to a *generated* face — a fillet round or chamfer bevel — named by
|
|
120
|
+
* the two faces it bridges. The generated face has no stable hash (it didn't
|
|
121
|
+
* exist at capture time, and fillet evolution is empty), so it's resolved as the
|
|
122
|
+
* face adjacent to both bridged faces whose normal blends both — the orthogonal
|
|
123
|
+
* flanking faces are rejected. Lineage-by-neighbors for geometry created by the
|
|
124
|
+
* very edit being referenced across.
|
|
125
|
+
*/
|
|
126
|
+
export interface DerivedFaceRef {
|
|
127
|
+
readonly origin: string;
|
|
128
|
+
/**
|
|
129
|
+
* Which op generated the face — descriptive metadata for consumers. Resolution
|
|
130
|
+
* is op-agnostic (the normal-blend isolates both a fillet round and a chamfer
|
|
131
|
+
* bevel), so the resolver doesn't consult it.
|
|
132
|
+
*/
|
|
133
|
+
readonly op: 'fillet' | 'chamfer';
|
|
134
|
+
/** Roles of the two faces the generated face bridges. */
|
|
135
|
+
readonly betweenRoles: readonly [string, string];
|
|
136
|
+
readonly hint: DerivedFaceHint;
|
|
137
|
+
}
|
|
138
|
+
/** A successfully resolved derived-face reference (always geometric). */
|
|
139
|
+
export interface ResolvedDerivedFaceRef {
|
|
140
|
+
readonly face: Face;
|
|
141
|
+
readonly confidence: 'geometric-fallback';
|
|
142
|
+
}
|
|
143
|
+
/** A derived-face reference that could not be resolved. */
|
|
144
|
+
export interface BrokenDerivedFaceRef {
|
|
145
|
+
readonly ref: DerivedFaceRef;
|
|
146
|
+
readonly reason: 'ambiguous' | 'not-found';
|
|
147
|
+
readonly candidates?: readonly Face[];
|
|
148
|
+
}
|