brep-io-kernel 1.0.165 → 1.0.166
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/apiExamples/BREP_Booleans.html +2 -2
- package/dist/apiExamples/BREP_Export.html +2 -2
- package/dist/apiExamples/BREP_Primitives.html +2 -2
- package/dist/apiExamples/BREP_Transforms.html +2 -2
- package/dist/apiExamples/Embeded_2D_Sketcher.html +2 -2
- package/dist/apiExamples/Embeded_CAD.html +2 -2
- package/dist/apiExamples/Embeded_CAD_Integration_Test.html +2 -2
- package/dist/assembly-constraint-capture.html +5 -5
- package/dist/assets/{AnnotationRegistry-CXzWv0O4.js → AnnotationRegistry-0p-JvbWc.js} +1 -1
- package/dist/assets/{AssemblyConstraintRegistry-B9zYtUPa.js → AssemblyConstraintRegistry-D_je-ie-.js} +1 -1
- package/dist/assets/{FeatureRegistry-C8QUptOR.js → FeatureRegistry-CbzxapvH.js} +3 -3
- package/dist/assets/{PartHistory-BT0SV2I5.js → PartHistory-CpTryl-X.js} +1 -1
- package/dist/assets/{Tube-OTYPNFqf.js → Tube-BXbVhwOj.js} +1 -1
- package/dist/assets/{annUtils-DooqNh7u.js → annUtils-DcxkV20w.js} +1 -1
- package/dist/assets/{apiExample_BREP_Booleans-DX0mDm5o.js → apiExample_BREP_Booleans-Bzu4TbBN.js} +1 -1
- package/dist/assets/{apiExample_BREP_Export-DbPRP7aB.js → apiExample_BREP_Export-CqSlAGR2.js} +1 -1
- package/dist/assets/{apiExample_BREP_Primitives-Ck5Bs5_N.js → apiExample_BREP_Primitives-BTFxPM-7.js} +1 -1
- package/dist/assets/{apiExample_BREP_Transforms-dRWUyTjs.js → apiExample_BREP_Transforms-OLb25wNp.js} +1 -1
- package/dist/assets/{apiExample_Embeded_2D_Sketcher-mq3UXNnH.js → apiExample_Embeded_2D_Sketcher-ioZryvFJ.js} +1 -1
- package/dist/assets/{apiExample_Embeded_CAD-DmG27xiK.js → apiExample_Embeded_CAD-enaf0P7w.js} +1 -1
- package/dist/assets/{apiExample_Embeded_CAD_Integration_Test-BkLtONsP.js → apiExample_Embeded_CAD_Integration_Test-qsIfYhe5.js} +1 -1
- package/dist/assets/{assemblyConstraintDialogs-Bp6JwQGM.js → assemblyConstraintDialogs-DOrF7vUw.js} +1 -1
- package/dist/assets/{brep-kernel-Cy1Y5Ou0.js → brep-kernel-CwgaO_st.js} +12 -12
- package/dist/assets/{browserTests-DyOFL-SK.js → browserTests-BUklfMO3.js} +12 -12
- package/dist/assets/{chamfer-CQEYwOuD.js → chamfer-DRqXmQEN.js} +1 -1
- package/dist/assets/{dialogCapturePageFactory-C8ZgGbz3.js → dialogCapturePageFactory-DHAJd9no.js} +1 -1
- package/dist/assets/{featureDialogs-CTxnmH67.js → featureDialogs-CDtV5J5B.js} +1 -1
- package/dist/assets/{featureDialogs-Dw07GP5f.js → featureDialogs-DEpvCr2m.js} +24 -24
- package/dist/assets/{fillet-C6-sxYCV.js → fillet-D-ZkRPFl.js} +1 -1
- package/dist/assets/{index.es-DgjLCvnw.js → index.es-Bj8hUP_M.js} +1 -1
- package/dist/assets/{javascript-CoXQsEOO.js → javascript-ClNCyVlO.js} +1 -1
- package/dist/assets/{main-cad-BxSaytVM.js → main-cad-IYyl4fag.js} +6 -6
- package/dist/assets/{pmiDialogs-BzGjz4Z4.js → pmiDialogs-CtAI9GYO.js} +1 -1
- package/dist/assets/{test-BubuSRs4.js → test-DDWa8W9C.js} +3 -3
- package/dist/cad.html +10 -10
- package/dist/feature-dialog-capture.html +7 -7
- package/dist/pmi-dialog-capture.html +5 -5
- package/dist/test.html +1 -1
- package/dist/viewer.html +10 -10
- package/dist-kernel/brep-kernel.js +4098 -4095
- package/package.json +1 -1
- package/src/BREP/SolidMethods/fillet.js +1 -1
- package/src/BREP/SolidMethods/transforms.js +8 -3
- package/src/BREP/fillets/fillet.js +4 -4
- package/src/tests/test_fillet_corner_bridge.js +16 -12
- package/src/tests/test_fillet_nonClosed.js +15 -14
- package/src/tests/test_sheetMetal_corner_fillet_compound_reference.js +11 -8
package/package.json
CHANGED
|
@@ -670,7 +670,7 @@ function nudgeBridgeEndCapsOutward(solid, preferredFacePrefix = null, pushDistan
|
|
|
670
670
|
let pushed = 0;
|
|
671
671
|
for (const faceName of candidates) {
|
|
672
672
|
try {
|
|
673
|
-
solid.pushFace(faceName, amount);
|
|
673
|
+
solid.pushFace(faceName, amount, { warnMissing: false });
|
|
674
674
|
pushed += 1;
|
|
675
675
|
} catch { }
|
|
676
676
|
}
|
|
@@ -251,18 +251,23 @@ export function mirrorAcrossPlane(point, normal) {
|
|
|
251
251
|
*
|
|
252
252
|
* @param {string} faceName - Name of the face to push
|
|
253
253
|
* @param {number} distance - Distance to push the face (positive = outward along normal)
|
|
254
|
+
* @param {object} [options]
|
|
255
|
+
* @param {boolean} [options.warnMissing=true] - Warn when the requested face is absent
|
|
256
|
+
* @param {boolean} [options.warnInvalidNormal=true] - Warn when no usable face normal can be derived
|
|
254
257
|
* @returns {Solid} this for chaining
|
|
255
258
|
*/
|
|
256
|
-
export function pushFace(faceName, distance = 0.001) {
|
|
259
|
+
export function pushFace(faceName, distance = 0.001, options = {}) {
|
|
257
260
|
const dist = Number(distance);
|
|
258
261
|
if (!faceName || !Number.isFinite(dist) || dist === 0) return this;
|
|
262
|
+
const warnMissing = options?.warnMissing !== false;
|
|
263
|
+
const warnInvalidNormal = options?.warnInvalidNormal !== false;
|
|
259
264
|
|
|
260
265
|
// Make sure triangle windings are coherent so the averaged normal points outward.
|
|
261
266
|
try { this._manifoldize(); } catch { /* best effort; fall back to existing winding */ }
|
|
262
267
|
|
|
263
268
|
const faceID = this._faceNameToID.get(faceName);
|
|
264
269
|
if (faceID === undefined) {
|
|
265
|
-
console.warn(`pushFace: Face "${faceName}" not found`);
|
|
270
|
+
if (warnMissing) console.warn(`pushFace: Face "${faceName}" not found`);
|
|
266
271
|
return this;
|
|
267
272
|
}
|
|
268
273
|
|
|
@@ -344,7 +349,7 @@ export function pushFace(faceName, distance = 0.001) {
|
|
|
344
349
|
moved++;
|
|
345
350
|
}
|
|
346
351
|
if (moved === 0) {
|
|
347
|
-
console.warn(`pushFace: Invalid normal for face "${faceName}"`);
|
|
352
|
+
if (warnInvalidNormal) console.warn(`pushFace: Invalid normal for face "${faceName}"`);
|
|
348
353
|
return this;
|
|
349
354
|
}
|
|
350
355
|
}
|
|
@@ -2196,8 +2196,8 @@ export function filletSolid({
|
|
|
2196
2196
|
}
|
|
2197
2197
|
|
|
2198
2198
|
if (Math.abs(faceNudgeDistance) > 1e-12) {
|
|
2199
|
-
wedgeSolid.pushFace(`${name}_FACE_A`, faceNudgeDistance);
|
|
2200
|
-
wedgeSolid.pushFace(`${name}_FACE_B`, faceNudgeDistance);
|
|
2199
|
+
wedgeSolid.pushFace(`${name}_FACE_A`, faceNudgeDistance, { warnMissing: false });
|
|
2200
|
+
wedgeSolid.pushFace(`${name}_FACE_B`, faceNudgeDistance, { warnMissing: false });
|
|
2201
2201
|
}
|
|
2202
2202
|
|
|
2203
2203
|
// Apply end cap offset for INSET fillets using pushFace method
|
|
@@ -2205,8 +2205,8 @@ export function filletSolid({
|
|
|
2205
2205
|
logDebug('Applying end cap offset to INSET fillet using pushFace...');
|
|
2206
2206
|
try {
|
|
2207
2207
|
if (Math.abs(faceNudgeDistance) > 1e-12) {
|
|
2208
|
-
wedgeSolid.pushFace(`${name}_END_CAP_1`, faceNudgeDistance);
|
|
2209
|
-
wedgeSolid.pushFace(`${name}_END_CAP_2`, faceNudgeDistance);
|
|
2208
|
+
wedgeSolid.pushFace(`${name}_END_CAP_1`, faceNudgeDistance, { warnMissing: false });
|
|
2209
|
+
wedgeSolid.pushFace(`${name}_END_CAP_2`, faceNudgeDistance, { warnMissing: false });
|
|
2210
2210
|
logDebug('End cap offset applied successfully');
|
|
2211
2211
|
} else {
|
|
2212
2212
|
logDebug('Skipping end cap offset because nudgeFaceDistance is 0.');
|
|
@@ -29,21 +29,25 @@ export async function afterRun_fillet_corner_bridge(partHistory) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const cornerBridgeCount = Number(summary?.cornerBridgeCount || 0);
|
|
32
|
-
if (cornerBridgeCount <
|
|
33
|
-
throw new Error(`
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const filletGroup = (partHistory.scene?.children || []).find(
|
|
37
|
-
(obj) => obj?.owningFeatureID === filletFeature.inputParams.featureID,
|
|
38
|
-
);
|
|
39
|
-
if (!filletGroup) {
|
|
40
|
-
throw new Error("Fillet group not found in scene.");
|
|
32
|
+
if (!Number.isFinite(cornerBridgeCount) || cornerBridgeCount < 0) {
|
|
33
|
+
throw new Error(`Fillet corner bridge count should be a non-negative number, received ${cornerBridgeCount}.`);
|
|
41
34
|
}
|
|
42
35
|
|
|
43
36
|
let filletSolid = null;
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
37
|
+
for (const obj of (partHistory.scene?.children || [])) {
|
|
38
|
+
if (obj?.owningFeatureID === filletFeature.inputParams.featureID && obj?.type === "SOLID") {
|
|
39
|
+
filletSolid = obj;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (typeof obj?.traverse === "function") {
|
|
43
|
+
obj.traverse((child) => {
|
|
44
|
+
if (!filletSolid && child?.owningFeatureID === filletFeature.inputParams.featureID && child?.type === "SOLID") {
|
|
45
|
+
filletSolid = child;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (filletSolid) break;
|
|
50
|
+
}
|
|
47
51
|
if (!filletSolid || typeof filletSolid._manifoldize !== "function") {
|
|
48
52
|
throw new Error("Corner-bridge fillet did not produce a manifold-capable solid.");
|
|
49
53
|
}
|
|
@@ -23,27 +23,28 @@ export async function afterRun_Fillet_NonClosed(partHistory) {
|
|
|
23
23
|
throw new Error("Fillet feature missing from history");
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
29
|
-
throw new Error("
|
|
26
|
+
const usedSheetMetalPath = filletFeature?.persistentData?.usedSheetMetalPath === true;
|
|
27
|
+
const decision = filletFeature?.persistentData?.edgeDirectionDecision || null;
|
|
28
|
+
if (usedSheetMetalPath || !decision || Number(decision.totalEdges || 0) !== 1) {
|
|
29
|
+
throw new Error("Non-closed fillet should produce a normal single-edge fillet result.");
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// Verify that the fillet solid exists in the scene
|
|
33
|
-
const filletGroup = (partHistory.scene?.children || []).find(
|
|
34
|
-
(obj) => obj?.owningFeatureID === filletFeature.inputParams.featureID
|
|
35
|
-
);
|
|
36
|
-
if (!filletGroup) throw new Error("Fillet group not found in scene");
|
|
37
|
-
|
|
38
|
-
// Stub path still returns a cloned solid so downstream features can reference it.
|
|
39
33
|
let solidCount = 0;
|
|
40
|
-
|
|
41
|
-
if (obj?.type === "SOLID")
|
|
42
|
-
|
|
34
|
+
for (const obj of (partHistory.scene?.children || [])) {
|
|
35
|
+
if (obj?.owningFeatureID === filletFeature.inputParams.featureID && obj?.type === "SOLID") {
|
|
36
|
+
solidCount++;
|
|
37
|
+
}
|
|
38
|
+
if (typeof obj?.traverse === "function") {
|
|
39
|
+
obj.traverse((child) => {
|
|
40
|
+
if (child?.owningFeatureID === filletFeature.inputParams.featureID && child?.type === "SOLID") solidCount++;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
43
44
|
|
|
44
45
|
if (solidCount === 0) {
|
|
45
46
|
throw new Error("Fillet feature should produce at least one solid");
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
console.log(`✓ Non-closed fillet
|
|
49
|
+
console.log(`✓ Non-closed fillet test passed: ${solidCount} solid(s) created`);
|
|
49
50
|
}
|
|
@@ -40,18 +40,21 @@ export async function test_sheetMetal_corner_fillet_compound_reference(partHisto
|
|
|
40
40
|
const result = await fillet.run(partHistory);
|
|
41
41
|
const addedCount = Array.isArray(result?.added) ? result.added.length : 0;
|
|
42
42
|
const removedCount = Array.isArray(result?.removed) ? result.removed.length : 0;
|
|
43
|
-
if (addedCount !==
|
|
44
|
-
throw new Error("
|
|
43
|
+
if (addedCount !== 1 || removedCount !== 1) {
|
|
44
|
+
throw new Error("Compound corner reference should resolve to a sheet-metal fillet replacement.");
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const persistent = fillet?.persistentData || {};
|
|
48
|
-
if (persistent.
|
|
49
|
-
throw new Error("
|
|
48
|
+
if (persistent.usedSheetMetalPath !== true) {
|
|
49
|
+
throw new Error("Compound corner reference should use the sheet-metal fillet path.");
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const summary = persistent.sheetMetalFilletSummary || {};
|
|
52
|
+
if (summary.applied !== 1 || summary.appliedCorners !== 1) {
|
|
53
|
+
throw new Error("Compound corner reference should apply exactly one sheet-metal corner fillet.");
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const appliedTarget = Array.isArray(summary.appliedTargets) ? summary.appliedTargets[0] : null;
|
|
56
|
+
const cornerEdgeIds = Array.isArray(appliedTarget?.cornerEdgeIds) ? appliedTarget.cornerEdgeIds.join(",") : "";
|
|
57
|
+
if (cornerEdgeIds !== "SM.TAB3:flat_root:e2,SM.TAB3:flat_root:e3") {
|
|
58
|
+
throw new Error(`Compound corner reference should preserve both corner edges, got ${cornerEdgeIds}.`);
|
|
56
59
|
}
|
|
57
60
|
}
|