From 76517f849279926f4d259129ecc94058dd1d701a Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sun, 20 Jul 2025 11:50:59 -0400 Subject: [PATCH] [TD]fix BrokenView does not handle shells - or faces, wires, edges that are not part of another shape --- src/Mod/TechDraw/App/DrawBrokenView.cpp | 44 ++++++++++++++++++------- src/Mod/TechDraw/App/DrawBrokenView.h | 4 +++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawBrokenView.cpp b/src/Mod/TechDraw/App/DrawBrokenView.cpp index 0e7fb2c86f..a709bbc74e 100644 --- a/src/Mod/TechDraw/App/DrawBrokenView.cpp +++ b/src/Mod/TechDraw/App/DrawBrokenView.cpp @@ -39,6 +39,9 @@ //! for sketch based breaks, the break direction is perpendicular to the edges //! in the sketch. +// ??? is option 1 actually working? Not used in practice? + + #include "PreCompiled.h" // NOLINT #ifndef _PreComp_ @@ -157,7 +160,6 @@ App::DocumentObjectExecReturn* DrawBrokenView::execute() BRepBuilderAPI_Copy BuilderCopy(shape); TopoDS_Shape safeShape = BuilderCopy.Shape(); - m_unbrokenCenter = SU::findCentroidVec(safeShape, getProjectionCS()); TopoDS_Shape brokenShape = breakShape(safeShape); @@ -206,7 +208,6 @@ TopoDS_Shape DrawBrokenView::apply1Break(const App::DocumentObject& breakObj, co Base::Console().message("DBV::apply1Break - cut0 failed\n"); } 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; @@ -242,12 +243,13 @@ TopoDS_Shape DrawBrokenView::compressShape(const TopoDS_Shape& shapeToCompress) //! a piece: PppppP no need to move TopoDS_Shape DrawBrokenView::compressHorizontal(const TopoDS_Shape& shapeToCompress)const { - auto pieces = getPieces(shapeToCompress); - auto breaksAll = Breaks.getValues(); - auto moveDirection = DU::closestBasisOriented(Base::convertTo(getProjectionCS().XDirection())); + std::vector pieces = getPieces(shapeToCompress); + std::vector breaksAll = Breaks.getValues(); + Base::Vector3d moveDirection = DU::closestBasisOriented(Base::convertTo(getProjectionCS().XDirection())); bool descend = false; - auto sortedBreaks = makeSortedBreakList(breaksAll, moveDirection, descend); - auto limits = getPieceLimits(pieces, moveDirection); + BreakList sortedBreaks = makeSortedBreakList(breaksAll, moveDirection, descend); + PieceLimitList limits = getPieceLimits(pieces, moveDirection); + // for each break, move all the pieces left of the break to the right by the removed amount // for the break for (auto& breakItem : sortedBreaks) { @@ -262,6 +264,7 @@ TopoDS_Shape DrawBrokenView::compressHorizontal(const TopoDS_Shape& shapeToComp TopoDS_Shape temp = ShapeUtils::moveShape(pieces.at(iPiece), netBreakDisplace); pieces.at(iPiece) = temp; } + iPiece++; } } @@ -281,6 +284,7 @@ TopoDS_Shape DrawBrokenView::compressHorizontal(const TopoDS_Shape& shapeToComp TopoDS_Shape DrawBrokenView::compressVertical(const TopoDS_Shape& shapeToCompress)const { auto pieces = getPieces(shapeToCompress); + auto breaksAll = Breaks.getValues(); // not sure about using closestBasis here. may prevent oblique breaks later. auto moveDirection = DU::closestBasisOriented(Base::convertTo(getProjectionCS().YDirection())); @@ -750,16 +754,32 @@ PieceLimitList DrawBrokenView::getPieceLimits(const std::vector& p return limits; } +//! get the pieces of the broken shape. std::vector DrawBrokenView::getPieces(const TopoDS_Shape& brokenShape) +{ + std::vector result = getPiecesByType(brokenShape, TopAbs_SOLID); + std::vector temp = getPiecesByType(brokenShape, TopAbs_SHELL, TopAbs_SOLID); + result.insert(result.end(), temp.begin(), temp.end()); + temp = getPiecesByType(brokenShape, TopAbs_FACE, TopAbs_SHELL); + result.insert(result.end(), temp.begin(), temp.end()); + temp = getPiecesByType(brokenShape, TopAbs_WIRE, TopAbs_FACE); + result.insert(result.end(), temp.begin(), temp.end()); + temp = getPiecesByType(brokenShape, TopAbs_EDGE, TopAbs_WIRE); + result.insert(result.end(), temp.begin(), temp.end()); + return result; +} + +//! retrieve the subelements of a shape that are of type desiredShapeType, but that do not +//! belong to a shape of type avoidShapeType. +std::vector DrawBrokenView::getPiecesByType(const TopoDS_Shape& shapeToSearch, + TopAbs_ShapeEnum desiredShapeType, + TopAbs_ShapeEnum avoidShapeType) { std::vector result; - // ?? is it reasonable to expect that we only want the solids? do we need to - // pick based on ShapeType <= TopAbs_SHELL? to get shells, compounds etc? - TopExp_Explorer expl(brokenShape, TopAbs_SOLID); + TopExp_Explorer expl(shapeToSearch, desiredShapeType, avoidShapeType); for (; expl.More(); expl.Next()) { - const TopoDS_Solid& solid = TopoDS::Solid(expl.Current()); - result.push_back(solid); + result.push_back(expl.Current()); } return result; diff --git a/src/Mod/TechDraw/App/DrawBrokenView.h b/src/Mod/TechDraw/App/DrawBrokenView.h index bcaa8c985c..560e805f5b 100644 --- a/src/Mod/TechDraw/App/DrawBrokenView.h +++ b/src/Mod/TechDraw/App/DrawBrokenView.h @@ -149,6 +149,10 @@ private: const bool descend = false) const; static std::vector getPieces(const TopoDS_Shape& brokenShape); + static std::vector getPiecesByType(const TopoDS_Shape& shapeToSearch, + TopAbs_ShapeEnum desiredShapeType, + TopAbs_ShapeEnum avoidShapeType = TopAbs_SHAPE); + static BreakList sortBreaks(BreakList& inList, bool descend = false); static bool breakLess(const BreakListEntry& entry0, const BreakListEntry& entry1);