From 36ddfdc7b959f7fc4000f6c3ff50aca65fbe3b2e Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 12 Feb 2026 16:29:09 -0500 Subject: [PATCH 1/2] [TD]fix crash on failed cut - wrong result and warning on first time through. Fixes itself after next execute(). - https://github.com/FreeCAD/FreeCAD/issues/27414 --- src/Mod/TechDraw/App/DrawBrokenView.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawBrokenView.cpp b/src/Mod/TechDraw/App/DrawBrokenView.cpp index b6e540381c..6b5fb01dc5 100644 --- a/src/Mod/TechDraw/App/DrawBrokenView.cpp +++ b/src/Mod/TechDraw/App/DrawBrokenView.cpp @@ -173,7 +173,12 @@ TopoDS_Shape DrawBrokenView::breakShape(const TopoDS_Shape& shapeToBreak) const auto breaksAll = Breaks.getValues(); TopoDS_Shape updatedShape = shapeToBreak; for (auto& item : breaksAll) { + TopoDS_Shape previousShape = updatedShape; updatedShape = apply1Break(*item, updatedShape); + if (updatedShape.IsNull()) { + Base::Console().warning("Failed to apply break %s\n", item->Label.getValue()); + updatedShape = previousShape; + } } return updatedShape; } @@ -198,20 +203,26 @@ TopoDS_Shape DrawBrokenView::apply1Break(const App::DocumentObject& breakObj, co moveDir0.Normalize(); moveDir0 = DU::closestBasisOriented(moveDir0); auto halfSpace0 = makeHalfSpace(breakPoints.first, moveDir0, breakPoints.second); + FCBRepAlgoAPI_Cut mkCut0(inShape, halfSpace0); - if (!mkCut0.IsDone()) { - Base::Console().message("DBV::apply1Break - cut0 failed\n"); + if (!mkCut0.IsDone() || mkCut0.Shape().IsNull()) { + Base::Console().warning("Failed to make first cut for break %s.\n", breakObj.Label.getValue()); + return {}; } + TopoDS_Shape cut0 = mkCut0.Shape(); + // make a halfspace that is positioned at the second breakpoint and extends // in the direction of the first point Base::Vector3d moveDir1 = breakPoints.first - breakPoints.second; moveDir1.Normalize(); moveDir1 = DU::closestBasisOriented(moveDir1); auto halfSpace1 = makeHalfSpace(breakPoints.second, moveDir1, breakPoints.first); + FCBRepAlgoAPI_Cut mkCut1(inShape, halfSpace1); - if (!mkCut1.IsDone()) { - Base::Console().message("DBV::apply1Break - cut1 failed\n"); + if (!mkCut1.IsDone()|| mkCut1.Shape().IsNull()) { + Base::Console().warning("Failed to make second cut for break %s.\n", breakObj.Label.getValue()); + return {}; } TopoDS_Shape cut1 = mkCut1.Shape(); From 6d73f9173ccfeb2b840cda9b3f95b26cfbb57c17 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 12 Feb 2026 16:46:19 -0500 Subject: [PATCH 2/2] [TD]use BRepAlgoAPI_Cut instead of FCBRepAlgoAPI_Cut --- src/Mod/TechDraw/App/DrawBrokenView.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawBrokenView.cpp b/src/Mod/TechDraw/App/DrawBrokenView.cpp index 6b5fb01dc5..dc2c4b9549 100644 --- a/src/Mod/TechDraw/App/DrawBrokenView.cpp +++ b/src/Mod/TechDraw/App/DrawBrokenView.cpp @@ -204,7 +204,10 @@ TopoDS_Shape DrawBrokenView::apply1Break(const App::DocumentObject& breakObj, co moveDir0 = DU::closestBasisOriented(moveDir0); auto halfSpace0 = makeHalfSpace(breakPoints.first, moveDir0, breakPoints.second); - FCBRepAlgoAPI_Cut mkCut0(inShape, halfSpace0); + // FCBRepAlgoAPI_Cut gets upset about cutting non-solids?? "XXX is not a solid" from Boolean::execute(). + // We are cutting Compounds and that is valid in BRepAlgoAPI_Cut, but maybe not in FCBRepAlgoAPI_Cut? + // See sample file here: https://github.com/FreeCAD/FreeCAD/issues/27414 + BRepAlgoAPI_Cut mkCut0(inShape, halfSpace0); if (!mkCut0.IsDone() || mkCut0.Shape().IsNull()) { Base::Console().warning("Failed to make first cut for break %s.\n", breakObj.Label.getValue()); return {}; @@ -219,7 +222,8 @@ TopoDS_Shape DrawBrokenView::apply1Break(const App::DocumentObject& breakObj, co moveDir1 = DU::closestBasisOriented(moveDir1); auto halfSpace1 = makeHalfSpace(breakPoints.second, moveDir1, breakPoints.first); - FCBRepAlgoAPI_Cut mkCut1(inShape, halfSpace1); + // see mkCut0 above + BRepAlgoAPI_Cut mkCut1(inShape, halfSpace1); if (!mkCut1.IsDone()|| mkCut1.Shape().IsNull()) { Base::Console().warning("Failed to make second cut for break %s.\n", breakObj.Label.getValue()); return {};