fix: Boolean difference silently does nothing on near-coplanar/step cuts (#11410) - #11411
fix: Boolean difference silently does nothing on near-coplanar/step cuts (#11410)#11411BenJule wants to merge 1 commit into
Conversation
7f0962c to
56c65f4
Compare
ArthurBambulab
left a comment
There was a problem hiding this comment.
Please address the cancel-vs-failure ambiguity before merge, and ideally verify the CGAL path on the reporter's model (Manifold offline success ≠ CGAL in-tree).
Must fix
Cancel is conflated with mcut failure (MeshBoolean.cpp, do_boolean A_NOT_B branch)
do_boolean_single() also returns false when cancel_cb() fires mid-loop (around the connected-component traversal). This PR treats every !ok as a geometric mcut failure and runs CGAL fallback, so a user cancel can:
- still run an expensive
cgal::minus, and/or - complete successfully via CGAL, contradicting cancel semantics.
Suggested minimal guard:
bool ok = do_boolean_single(*src_part, *cut_part, boolean_opts, cancel_cb, temp_progress_cb);
if (cancel_cb && cancel_cb())
return false;
if (boolean_opts == "A_NOT_B") {
// existing fallback...
}…ambulab#11410) The interactive Boolean tool runs on mcut. For a difference (A_NOT_B) the result of do_boolean_single() was ignored: when mcut's LOCATION_ABOVE fragment filter returns zero connected components (typical for near-coplanar / deep-step cuts, and for the model in bambulab#11410), src_part was left untouched and merged back unchanged, so the subtraction silently did nothing while the UI reported success. Capture the return value and, when mcut yields nothing for a difference, fall back to the existing CGAL corefinement path (cgal::minus) on a TriangleMesh accumulator instead of dropping the operation. The fallback only runs when mcut already failed, so it cannot regress cases that work today. Union and intersection paths are unchanged. Closes bambulab#11410
56c65f4 to
0c972fd
Compare
|
Thanks for catching this. I added an explicit cancel check immediately after I also built the updated commit successfully with the Linux PR pipeline and tested the resulting Bambu Studio artifact against the reporter's original 3MF from #11410. The subtraction now completes successfully and produces the expected deeper cut, confirming the in-tree CGAL fallback on the actual model. I attempted to exercise cancellation manually as well, but this particular operation completes too quickly to reliably hit the Cancel button. I therefore cannot claim a manual cancellation test, but the cancel/failure ambiguity identified in the review is now explicitly guarded in the code. |
What
Fixes #11410. The interactive Boolean Difference tool silently does nothing for certain geometries (deep step or near-coplanar cuts). The model stays unchanged while the UI reports success. Setting the cutter as a negative part works because that path is unrelated (CSG at slice time), which is why it looked inconsistent.
Root cause
MeshBoolean::mcut::do_booleansplits multi-component meshes and subtracts each cutter viado_boolean_single(mcut,A_NOT_BwithMC_DISPATCH_FILTER_FRAGMENT_LOCATION_ABOVE). For near-coplanar or step cuts mcut returns zero connected components, sodo_boolean_singlereturnsfalseand leavessrc_partuntouched.The bug: for
A_NOT_BandUNIONthe return value was ignored and the unchangedsrc_partwas merged back, so the subtraction was silently dropped. TheINTERSECTIONbranch already checkssuccess.Fix
Capture the return value; when mcut yields nothing for a difference, fall back to the CGAL corefinement path that already exists in this file (
cgal::minuson anindexed_triangle_setaccumulator) instead of dropping the op. The fallback only runs when mcut already failed, so it cannot regress anything that works today. Union and intersection paths are unchanged.Validation
I could not run a full GUI build here, so I validated the approach offline against the reporter's exact model. The object contains the body (26,346 faces, 3 solids) and the cutter cylinder (1,440 faces) as two separate, still overlapping solids, i.e. the difference genuinely never got baked in. Running the subtraction with an independent robust engine (Manifold) succeeds cleanly:
So the geometry is booleanable by a robust backend, mcut is the weak link. CGAL corefinement (used by this fix) is that kind of robust backend and is already linked and used in the codebase.
Note
Not yet exercised in a full BambuStudio GUI build on my side, CI will cover compilation. The change is deliberately low-risk (fallback only triggers on an existing mcut failure). Happy to adjust if you would prefer surfacing an error instead of the fallback, or gating it behind a flag.