diff --git a/src/Mod/Part/App/OpenCascadeAll.h b/src/Mod/Part/App/OpenCascadeAll.h index dd6cb34330..869cc38698 100644 --- a/src/Mod/Part/App/OpenCascadeAll.h +++ b/src/Mod/Part/App/OpenCascadeAll.h @@ -150,6 +150,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/Part/App/modelRefine.cpp b/src/Mod/Part/App/modelRefine.cpp index 077a5d5228..c073c13be3 100644 --- a/src/Mod/Part/App/modelRefine.cpp +++ b/src/Mod/Part/App/modelRefine.cpp @@ -1292,6 +1292,13 @@ bool FaceUniter::process() return true; } +void FaceUniter::fixOrientation(const TopoDS_Shell& shell) +{ + if (shell.Orientation() != workShell.Orientation()) { + workShell.Reverse(); + } +} + ///////////////////////////////////////////////////////////////////////////////////////////////////////// // BRepBuilderAPI_RefineModel implement a way to log all modifications on the faces @@ -1358,11 +1365,16 @@ void Part::BRepBuilderAPI_RefineModel::Build() const TopoDS_Solid& solid = TopoDS::Solid(xp.Current()); BRepTools_ReShape reshape; TopExp_Explorer it; + int countShells = 0; for (it.Init(solid, TopAbs_SHELL); it.More(); it.Next()) { + countShells++; const TopoDS_Shell& currentShell = TopoDS::Shell(it.Current()); ModelRefine::FaceUniter uniter(currentShell); if (uniter.process()) { if (uniter.isModified()) { + if (countShells > 1) { + uniter.fixOrientation(currentShell); + } const TopoDS_Shell& newShell = uniter.getShell(); reshape.Replace(currentShell, newShell); LogModifications(uniter); diff --git a/src/Mod/Part/App/modelRefine.h b/src/Mod/Part/App/modelRefine.h index 3a9d404ef0..b89adb0cb3 100644 --- a/src/Mod/Part/App/modelRefine.h +++ b/src/Mod/Part/App/modelRefine.h @@ -198,6 +198,7 @@ public: { return workShell; } + void fixOrientation(const TopoDS_Shell& shell); bool isModified() { return modifiedSignal; diff --git a/src/Mod/PartDesign/App/Feature.cpp b/src/Mod/PartDesign/App/Feature.cpp index c90b1e1a47..8aea9f30ac 100644 --- a/src/Mod/PartDesign/App/Feature.cpp +++ b/src/Mod/PartDesign/App/Feature.cpp @@ -23,11 +23,15 @@ #include #include +#include +#include #include #include +#include #include #include #include +#include #include "App/Datums.h" @@ -241,6 +245,44 @@ int Feature::countSolids(const TopoDS_Shape& shape, TopAbs_ShapeEnum type) return result; } +TopoShape Feature::fixSolids(const TopoShape& solids) +{ + if (solids.isNull()) { + return solids; + } + + std::vector fixSolids; + + TopExp_Explorer xp; + xp.Init(solids.getShape(), TopAbs_SOLID); + for (; xp.More(); xp.Next()) { + TopoDS_Solid solid = TopoDS::Solid(xp.Current()); + BRepCheck_Solid bs(solid); + if (bs.IsStatusOnShape(solid)) { + const auto& listOfStatus = bs.StatusOnShape(solid); + if (listOfStatus.Contains(BRepCheck_EnclosedRegion)) { + fixSolids.emplace_back(solid); + } + } + } + + if (fixSolids.empty()) { + return solids; + } + + TopoDS_Compound comp; + TopoDS_Builder bb; + bb.MakeCompound(comp); + for (const TopoDS_Solid& it : fixSolids) { + ShapeFix_Solid fix(it); + fix.Perform(); + bb.Add(comp, fix.Solid()); + } + + TopoShape fixShape(comp); + return fixShape; +} + bool Feature::isSingleSolidRuleSatisfied(const TopoDS_Shape& shape, TopAbs_ShapeEnum type) { if (singleSolidRuleMode() == Feature::SingleSolidRuleMode::Disabled) { diff --git a/src/Mod/PartDesign/App/Feature.h b/src/Mod/PartDesign/App/Feature.h index bcb5441036..40cb7ce80e 100644 --- a/src/Mod/PartDesign/App/Feature.h +++ b/src/Mod/PartDesign/App/Feature.h @@ -127,6 +127,11 @@ protected: TopoShape getSolid(const TopoShape&) const; static int countSolids(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID); + /** + * Fix solids + */ + TopoShape fixSolids(const TopoShape&); + /** * Checks if the single-solid body rule is fulfilled. */