From afbfdd0ed2bc2a67280a4638345de8a28811c32e Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 30 Dec 2014 19:19:58 +0300 Subject: [PATCH] 1) Fix for issue 0022706 with MakePipeTShape (workaround for Fillet problem) 2) Clean-up code: - Remove redundant includes - Move oftenly used functions to GEOMUtils - Add documentation, indentation, etc. --- .../AdvancedEngine_IOperations.cxx | 26 ++++ .../AdvancedEngine_PipeTShapeDriver.cxx | 25 +++- src/GEOMImpl/GEOMImpl_BooleanDriver.cxx | 81 +++-------- src/GEOMImpl/GEOMImpl_ChamferDriver.cxx | 18 +-- src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx | 13 +- src/GEOMImpl/GEOMImpl_FilletDriver.cxx | 49 ++----- src/GEOMImpl/GEOMImpl_HealingDriver.cxx | 22 +-- src/GEOMImpl/GEOMImpl_OffsetDriver.cxx | 32 +---- src/GEOMImpl/GEOMImpl_PartitionDriver.cxx | 33 +---- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 18 +-- src/GEOMImpl/GEOMImpl_PipePathDriver.cxx | 67 --------- src/GEOMImpl/GEOMImpl_ScaleDriver.cxx | 24 +--- src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx | 22 +-- src/GEOMImpl/GEOMImpl_TranslateDriver.cxx | 27 +--- src/GEOMUtils/CMakeLists.txt | 1 + src/GEOMUtils/GEOMUtils.cxx | 129 +++++++++++++++--- src/GEOMUtils/GEOMUtils.hxx | 76 ++++++++++- 17 files changed, 288 insertions(+), 375 deletions(-) diff --git a/src/AdvancedEngine/AdvancedEngine_IOperations.cxx b/src/AdvancedEngine/AdvancedEngine_IOperations.cxx index e713e003a..5d1b96999 100644 --- a/src/AdvancedEngine/AdvancedEngine_IOperations.cxx +++ b/src/AdvancedEngine/AdvancedEngine_IOperations.cxx @@ -109,6 +109,10 @@ #define FIND_GROUPS_BY_POINTS 1 +// Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet +// VSR 30/12/2014: macro enabled +#define FILLET_FIX_TOLERANCE + //============================================================================= /*! * Constructor @@ -2842,6 +2846,17 @@ AdvancedEngine_IOperations::MakePipeTShapeFillet aFillet->GetLastFunction()->SetDescription(""); TopoDS_Shape aFilletShape = aFillet->GetValue(); + +#ifdef FILLET_FIX_TOLERANCE + // VSR: 30/12/2014: temporary workaround about Fillet problem + if (theHexMesh) { + GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE); + } + else { + GEOMUtils::FixShapeCurves(aFilletShape); + } +#endif + aFunction->SetValue(aFilletShape); // END of fillet @@ -3087,6 +3102,17 @@ AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition aFillet->GetLastFunction()->SetDescription(""); TopoDS_Shape aFilletShape = aFillet->GetValue(); + +#ifdef FILLET_FIX_TOLERANCE + // VSR: 30/12/2014: temporary workaround about Fillet problem + if (theHexMesh) { + GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE); + } + else { + GEOMUtils::FixShapeCurves(aFilletShape); + } +#endif + aFunction->SetValue(aFilletShape); // END of fillet diff --git a/src/AdvancedEngine/AdvancedEngine_PipeTShapeDriver.cxx b/src/AdvancedEngine/AdvancedEngine_PipeTShapeDriver.cxx index 7551b43f7..25d0edade 100644 --- a/src/AdvancedEngine/AdvancedEngine_PipeTShapeDriver.cxx +++ b/src/AdvancedEngine/AdvancedEngine_PipeTShapeDriver.cxx @@ -63,6 +63,11 @@ #include +// Undefine below macro to enable workaround about problem with wrong +// tolerances of intersection curves in MakePipeTShape and MakeQuarterPipeTShape +// VSR 30/12/2014: macro enabled +#define FIX_CURVES_TOLERANCES + //======================================================================= //function : GetID //purpose : @@ -299,7 +304,7 @@ void AdvancedEngine_PipeTShapeDriver::GetCommonShapesOnCylinders(const TopoDS_Sh //purpose : //======================================================================= TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakePipeTShape (const double r1, const double w1, const double l1, - const double r2, const double w2, const double l2) const + const double r2, const double w2, const double l2) const { double r1Ext = r1 + w1; double r2Ext = r2 + w2; @@ -341,7 +346,14 @@ TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakePipeTShape (const double r1, c StdFail_NotDone::Raise("Coudn't cut cylinders"); } - return Te.Shape(); + TopoDS_Shape aShape = Te.Shape(); + + // VSR: 30/12/2014: temporary workaround about intersection curves problem +#ifdef FIX_CURVES_TOLERANCES + GEOMUtils::FixShapeCurves(aShape); +#endif + + return aShape; } //======================================================================= @@ -349,7 +361,7 @@ TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakePipeTShape (const double r1, c //purpose : //======================================================================= TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakeQuarterPipeTShape (const double r1, const double w1, const double l1, - const double r2, const double w2, const double l2) const + const double r2, const double w2, const double l2) const { TopoDS_Shape Te = MakePipeTShape(r1, w1, l1, r2, w2, l2); if (Te.IsNull()) @@ -373,6 +385,13 @@ TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakeQuarterPipeTShape (const doubl StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box"); } + TopoDS_Shape aShape = Te4.Shape(); + + // VSR: 30/12/2014: temporary workaround about intersection curves problem +#ifdef FIX_CURVES_TOLERANCES + GEOMUtils::FixShapeCurves(aShape); +#endif + return Te4.Shape(); } diff --git a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx index 32b0b04fa..389ca6f5e 100644 --- a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx @@ -31,16 +31,11 @@ #include -#include -#include - #include -#include #include #include #include #include -#include #include #include @@ -73,33 +68,23 @@ static TopoDS_Shape RemoveExtraEdges(const TopoDS_Shape &theShape) { TopoDS_Shape aResult; - if (theShape.IsNull() == Standard_False) { + if (!theShape.IsNull()) { BlockFix_BlockFixAPI aTool; aTool.OptimumNbFaces() = 0; aTool.SetShape(theShape); aTool.Perform(); - aResult = aTool.Shape(); - - // Repair result - BRepCheck_Analyzer anAna (aResult, false); - Standard_Boolean isValid = anAna.IsValid(); + TopoDS_Shape aShape = aTool.Shape(); - if (!isValid) { + if (GEOMUtils::CheckShape(aShape)) { + aResult = aShape; + } + else { TopoDS_Shape aFixed; ShHealOper_ShapeProcess aHealer; - aHealer.Perform(aResult, aFixed); - - if (aHealer.isDone()) { + if (aHealer.isDone() && GEOMUtils::CheckShape(aFixed)) aResult = aFixed; - anAna.Init(aResult, false); - isValid = anAna.IsValid(); - } - } - - if (!isValid) { - aResult.Nullify(); } } @@ -153,11 +138,7 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const if (!aShape1.IsNull() && !aShape2.IsNull()) { // check arguments for Mantis issue 0021019 - BRepCheck_Analyzer ana (aShape1, Standard_True); - if (!ana.IsValid()) - StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); - ana.Init(aShape2); - if (!ana.IsValid()) + if (!GEOMUtils::CheckShape(aShape1, true) || !GEOMUtils::CheckShape(aShape2, true)) StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); if (isCheckSelfInte) { @@ -211,10 +192,9 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const aShape = aRefShape->GetValue(); if (!aShape.IsNull()) { - BRepCheck_Analyzer anAna (aShape, Standard_True); - if (!anAna.IsValid()) { + // check arguments for Mantis issue 0021019 + if (!GEOMUtils::CheckShape(aShape, true)) StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); - } BOPAlgo_CheckerSI aCSI; // checker of self-interferences @@ -239,11 +219,9 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const for (i = 2; i <= nbShapes; i++) { aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(i)); aShape2 = aRefShape->GetValue(); - anAna.Init(aShape2); - - if (!anAna.IsValid()) { + + if (!GEOMUtils::CheckShape(aShape2, true)) StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); - } if (isCheckSelfInte) { BOPCol_ListOfShape aList2; @@ -280,11 +258,8 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const if (!aShape.IsNull()) { // check arguments for Mantis issue 0021019 - BRepCheck_Analyzer anAna (aShape, Standard_True); - - if (!anAna.IsValid()) { + if (!GEOMUtils::CheckShape(aShape, true)) StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); - } BOPAlgo_CheckerSI aCSI; // checker of self-interferences @@ -315,11 +290,9 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const for (i = 1; i <= nbShapes; i++) { aRefTool = Handle(GEOM_Function)::DownCast(aTools->Value(i)); aTool = aRefTool->GetValue(); - anAna.Init(aTool); - if (!anAna.IsValid()) { + if (!GEOMUtils::CheckShape(aTool, true)) StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid"); - } if (isCheckSelfInte) { BOPCol_ListOfShape aList2; @@ -572,19 +545,8 @@ TopoDS_Shape GEOMImpl_BooleanDriver::performOperation } // 08.07.2008 skl for bug 19761 from Mantis - BRepCheck_Analyzer ana (aShape, Standard_True); - ana.Init(aShape); - if (!ana.IsValid()) { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape, Precision::Confusion(), - Precision::Confusion(), TopAbs_SHAPE); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->Perform(); - aShape = aSfs->Shape(); - ana.Init(aShape); - if (!ana.IsValid()) - Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result"); // BEGIN: Mantis issue 0021060: always limit tolerance of BOP result // 1. Get shape parameters for comparison @@ -616,15 +578,8 @@ TopoDS_Shape GEOMImpl_BooleanDriver::performOperation TopoDS_Shape aShapeCopy; TColStd_IndexedDataMapOfTransientTransient aMapTShapes; TNaming_CopyShape::CopyTool(aShape, aMapTShapes, aShapeCopy); - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShapeCopy, Precision::Confusion(), Precision::Confusion(), TopAbs_SHAPE); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape (aShapeCopy); - aSfs->Perform(); - aShapeCopy = aSfs->Shape(); - - // 3. Check parameters - ana.Init(aShapeCopy); - if (ana.IsValid()) { + + if ( GEOMUtils::FixShapeTolerance(aShapeCopy) ) { int iType, nbTypesCopy [TopAbs_SHAPE]; for (iType = 0; iType < TopAbs_SHAPE; ++iType) diff --git a/src/GEOMImpl/GEOMImpl_ChamferDriver.cxx b/src/GEOMImpl/GEOMImpl_ChamferDriver.cxx index e845c72a7..f7582ecfd 100644 --- a/src/GEOMImpl/GEOMImpl_ChamferDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ChamferDriver.cxx @@ -20,14 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include #include #include - +#include #include #include @@ -35,22 +33,16 @@ #include #include -#include -#include - #include #include #include #include #include #include -#include #include #include #include -#include -#include #include //======================================================================= @@ -63,7 +55,6 @@ const Standard_GUID& GEOMImpl_ChamferDriver::GetID() return aChamferDriver; } - //======================================================================= //function : GEOMImpl_ChamferDriver //purpose : @@ -269,12 +260,7 @@ Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const if (aShape.IsNull()) return 0; // reduce tolerances - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape, Precision::Confusion(), - Precision::Confusion(), TopAbs_SHAPE); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->Perform(); - aShape = aSfs->Shape(); + GEOMUtils::FixShapeTolerance( aShape ); // fix SameParameter flag BRepLib::SameParameter(aShape, 1.E-5, Standard_True); diff --git a/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx b/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx index ad3fb2d12..808d79253 100755 --- a/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx @@ -17,34 +17,25 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include #include #include #include +#include #include -#include -#include #include #include #include -#include #include #include -#include #include #include +#include -#include -#include - -#include -#include #include //======================================================================= diff --git a/src/GEOMImpl/GEOMImpl_FilletDriver.cxx b/src/GEOMImpl/GEOMImpl_FilletDriver.cxx index f8b6756a0..bdffdb03a 100644 --- a/src/GEOMImpl/GEOMImpl_FilletDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_FilletDriver.cxx @@ -20,50 +20,29 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include #include +#include #include #include -#include -#include - #include #include #include #include #include - -#include -#include - -#include -#include #include -// VSR 08/12/2014: debug PipeTShape function -// Uncomment the macro below to correct tolerance of resulting face after creating fillet -#define FIX_FACE_TOLERANCE - -namespace -{ - bool FixShape( TopoDS_Shape& shape, - TopAbs_ShapeEnum type = TopAbs_SHAPE, - Standard_Real tolerance = Precision::Confusion() ) - { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance( shape, tolerance, tolerance, type ); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape( shape ); - aSfs->Perform(); - shape = aSfs->Shape(); - BRepCheck_Analyzer ana( shape, false ); - return ana.IsValid(); - } -} +// Debug PipeTShape function: uncomment the macro below to correct tolerance +// of resulting face after fillet creation +// VSR 30/12/2014: macro disabled +//#define FIX_FACE_TOLERANCE +// Debug PipeTShape function: uncomment the macro below to correct tolerance +// of resulting curves after fillet creation +// VSR 30/12/2014: macro disabled +//#define FIX_CURVES_TOLERANCES //======================================================================= //function : GetID @@ -155,13 +134,13 @@ Standard_Integer GEOMImpl_FilletDriver::Execute(TFunction_Logbook& log) const if (aShape.IsNull()) return 0; -#ifdef FIX_FACE_TOLERANCE - bool isOk = FixShape(aShape, TopAbs_FACE); +#if defined(FIX_CURVES_TOLERANCES) + bool isOk = GEOMUtils::FixShapeCurves(aShape); +#elif defined(FIX_FACE_TOLERANCE) + bool isOk = GEOMUtils::FixShapeTolerance(aShape, TopAbs_FACE); #else - // Check shape validity - BRepCheck_Analyzer ana(aShape, false); // 08.07.2008 added by skl during fixing bug 19761 from Mantis - bool isOk = ana.IsValid() || FixShape(aShape); + bool isOk = GEOMUtils::CheckShape(aShape) || GEOMUtils::FixShapeTolerance(aShape); #endif if ( !isOk ) StdFail_NotDone::Raise("Fillet algorithm have produced an invalid shape result"); diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx index 89decb61c..966cd0334 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx @@ -20,8 +20,6 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include @@ -44,12 +42,8 @@ #include -#include -#include - #include #include -#include #include #include @@ -552,17 +546,10 @@ void GEOMImpl_HealingDriver::LimitTolerance (GEOMImpl_IHealing* theHI, TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy); // 2. Limit tolerance. - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShapeCopy, aTol, aTol, aType); - - // 3. Fix obtained shape. - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape (aShapeCopy); - aSfs->Perform(); - theOutShape = aSfs->Shape(); - - BRepCheck_Analyzer ana (theOutShape, Standard_True); - if (!ana.IsValid()) + if (!GEOMUtils::FixShapeTolerance(aShapeCopy, aType, aTol)) StdFail_NotDone::Raise("Non valid shape result"); + + theOutShape = aShapeCopy; } //======================================================================= @@ -737,8 +724,7 @@ void GEOMImpl_HealingDriver::FuseCollinearEdges (const TopoDS_Shape& theOriginal } theOutShape = aFinalWire; - BRepCheck_Analyzer ana (theOutShape, Standard_True); - if (!ana.IsValid()) + if (!GEOMUtils::CheckShape(theOutShape, true)) StdFail_NotDone::Raise("Non valid shape result"); } diff --git a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx index fe5bb0580..7475b4a34 100644 --- a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx @@ -26,29 +26,16 @@ #include #include #include +#include #include -#include -#include #include -#include #include -#include - #include - #include -#include - -#include -#include -#include - #include #include -#include "utilities.h" - //======================================================================= //function : GetID //purpose : @@ -59,7 +46,6 @@ const Standard_GUID& GEOMImpl_OffsetDriver::GetID() return aOffsetDriver; } - //======================================================================= //function : GEOMImpl_OffsetDriver //purpose : @@ -100,20 +86,8 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const aTol); if (MO.IsDone()) { aShape = MO.Shape(); - // 23.04.2010 skl for bug 21699 from Mantis - BRepCheck_Analyzer ana (aShape, Standard_True); - ana.Init(aShape); - if (!ana.IsValid()) { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape, Precision::Confusion(), - Precision::Confusion(), TopAbs_SHAPE); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->Perform(); - aShape = aSfs->Shape(); - ana.Init(aShape); - if (!ana.IsValid()) - Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result"); } else { StdFail_NotDone::Raise("Offset construction failed"); diff --git a/src/GEOMImpl/GEOMImpl_PartitionDriver.cxx b/src/GEOMImpl/GEOMImpl_PartitionDriver.cxx index c50b0a86a..9b49bfeaf 100644 --- a/src/GEOMImpl/GEOMImpl_PartitionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PartitionDriver.cxx @@ -20,47 +20,29 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include - +#include #include #include - #include #include #include -//#include -#include -#include -#include - #include #include -#include #include -#include -#include #include #include #include #include #include -#include -#include - #include -#include -#include #include #include -#include -#include #include #include #include @@ -444,17 +426,8 @@ Standard_Integer GEOMImpl_PartitionDriver::Execute(TFunction_Logbook& log) const Standard_ConstructionError::Raise("Partition aborted : non valid shape result"); //end of IPAL21418 - if (!BRepAlgo::IsValid(aShape)) { - // 08.07.2008 added by skl during fixing bug 19761 from Mantis - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape, Precision::Confusion(), - Precision::Confusion(), TopAbs_SHAPE); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->Perform(); - aShape = aSfs->Shape(); - if (!BRepAlgo::IsValid(aShape)) - Standard_ConstructionError::Raise("Partition aborted : non valid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Partition aborted : non valid shape result"); aFunction->SetValue(aShape); diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index 5f580ddb9..a3f4c388a 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include @@ -47,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -2573,19 +2570,8 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const if (aShape.IsNull()) return 0; - BRepCheck_Analyzer ana (aShape, Standard_False); - if (!ana.IsValid()) { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion()); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->SetPrecision(Precision::Confusion()); - aSfs->Perform(); - aShape = aSfs->Shape(); - - ana.Init(aShape, Standard_False); - if (!ana.IsValid()) - Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); if (aType != PIPE_BASE_PATH && aType != PIPE_SHELLS_WITHOUT_PATH) { diff --git a/src/GEOMImpl/GEOMImpl_PipePathDriver.cxx b/src/GEOMImpl/GEOMImpl_PipePathDriver.cxx index 25bf5cdff..f52d340f2 100644 --- a/src/GEOMImpl/GEOMImpl_PipePathDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipePathDriver.cxx @@ -20,83 +20,16 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - -#include - #include - -#include #include #include #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include #include - #include - #include -#include -#include - -#include "utilities.h" //======================================================================= //function : GetID diff --git a/src/GEOMImpl/GEOMImpl_ScaleDriver.cxx b/src/GEOMImpl/GEOMImpl_ScaleDriver.cxx index 3525ed57b..9cc1d6265 100644 --- a/src/GEOMImpl/GEOMImpl_ScaleDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ScaleDriver.cxx @@ -20,27 +20,20 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include +#include #include -#include -#include - #include #include #include -#include -#include #include #include #include #include -#include #include #include @@ -175,19 +168,8 @@ Standard_Integer GEOMImpl_ScaleDriver::Execute(TFunction_Logbook& log) const if (aShape.IsNull()) return 0; - BRepCheck_Analyzer ana (aShape, Standard_False); - if (!ana.IsValid()) { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion()); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->SetPrecision(Precision::Confusion()); - aSfs->Perform(); - aShape = aSfs->Shape(); - - ana.Init(aShape, Standard_False); - if (!ana.IsValid()) - Standard_ConstructionError::Raise("Scaling aborted : algorithm has produced an invalid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Scaling aborted : algorithm has produced an invalid shape result"); aFunction->SetValue(aShape); diff --git a/src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx b/src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx index d4df6a4b6..367587691 100644 --- a/src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ThruSectionsDriver.cxx @@ -20,19 +20,16 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include #include #include +#include #include #include -#include #include #include -#include #include #include @@ -41,12 +38,9 @@ #include #include -#include #include #include -#include -#include -#include + //======================================================================= //function : GetID //purpose : @@ -132,21 +126,11 @@ Standard_Integer GEOMImpl_ThruSectionsDriver::Execute(TFunction_Logbook& log) co return 0; } - BRepCheck_Analyzer ana (aShape, Standard_False); - if (!ana.IsValid()) { + if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) ) { //algoritm thru section creats on the arcs invalid shapes gka - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion()); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->SetPrecision(Precision::Confusion()); - aSfs->Perform(); - aShape = aSfs->Shape(); - //ana.Init(aShape, Standard_False); - //if (!ana.IsValid()) // Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); } - aFunction->SetValue(aShape); log.SetTouched(Label()); diff --git a/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx b/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx index 0fab3342e..cb67a9ec0 100644 --- a/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx @@ -20,22 +20,14 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include #include -#include #include #include #include -#include -#include - #include #include -#include -#include #include #include @@ -43,8 +35,6 @@ #include #include #include -#include -#include #include #include @@ -197,7 +187,6 @@ Standard_Integer GEOMImpl_TranslateDriver::Execute(TFunction_Logbook& log) const B.Add(aCompound, anOriginal.Located(aLocRes)); } aShape = aCompound; - //aShape = GEOMImpl_ITransformOperations::TranslateShape1D(anOriginal, &TI); } else if (aType == TRANSLATE_2D) { Standard_Integer nbtimes1 = TI.GetNbIter1(), nbtimes2 = TI.GetNbIter2(); @@ -242,25 +231,13 @@ Standard_Integer GEOMImpl_TranslateDriver::Execute(TFunction_Logbook& log) const } } aShape = aCompound; - //aShape = GEOMImpl_ITransformOperations::TranslateShape2D(anOriginal, &TI); } else return 0; if (aShape.IsNull()) return 0; - BRepCheck_Analyzer ana (aShape, Standard_True); - if (!ana.IsValid()) { - ShapeFix_ShapeTolerance aSFT; - aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion()); - Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); - aSfs->SetPrecision(Precision::Confusion()); - aSfs->Perform(); - aShape = aSfs->Shape(); - - ana.Init(aShape, Standard_False); - if (!ana.IsValid()) - Standard_ConstructionError::Raise("Scaling aborted : algorithm has produced an invalid shape result"); - } + if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) ) + Standard_ConstructionError::Raise("Scaling aborted : algorithm has produced an invalid shape result"); aFunction->SetValue(aShape); diff --git a/src/GEOMUtils/CMakeLists.txt b/src/GEOMUtils/CMakeLists.txt index fdd98a686..db3037eac 100755 --- a/src/GEOMUtils/CMakeLists.txt +++ b/src/GEOMUtils/CMakeLists.txt @@ -42,6 +42,7 @@ SET(_link_LIBRARIES ${CAS_TKG3d} ${CAS_TKV3d} ${CAS_TKGeomBase} + ${CAS_TKBO} ${LIBXML2_LIBRARIES} ${KERNEL_SALOMELocalTrace} ) diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx index 0b12033aa..3773646b8 100644 --- a/src/GEOMUtils/GEOMUtils.cxx +++ b/src/GEOMUtils/GEOMUtils.cxx @@ -26,7 +26,6 @@ #include -#include #include #include @@ -46,8 +45,12 @@ #include #include +#include + #include +#include + #include #include #include @@ -83,12 +86,14 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -96,6 +101,12 @@ #define STD_SORT_ALGO 1 +// When the following macro is defined, ShapeFix_ShapeTolerance function is used to set max tolerance of curve +// in GEOMUtils::FixShapeCurves function; otherwise less restrictive BRep_Builder::UpdateEdge/UpdateVertex +// approach is used +// VSR (29/12/2014): macro disabled +//#define USE_LIMIT_TOLERANCE + namespace { /** @@ -1033,19 +1044,19 @@ gp_Pnt GEOMUtils::ConvertClickToPoint( int x, int y, Handle(V3d_View) aView ) // function : ConvertTreeToString() // purpose : Returns the string representation of dependency tree //======================================================================= -void GEOMUtils::ConvertTreeToString( const TreeModel &tree, - std::string &treeStr ) +void GEOMUtils::ConvertTreeToString( const TreeModel& tree, + std::string& dependencyStr ) { TreeModel::const_iterator i; for ( i = tree.begin(); i != tree.end(); ++i ) { - treeStr.append( i->first ); - treeStr.append( "-" ); + dependencyStr.append( i->first ); + dependencyStr.append( "-" ); std::vector upLevelList = i->second.first; - treeStr.append( "upward" ); - parseWard( upLevelList, treeStr ); + dependencyStr.append( "upward" ); + parseWard( upLevelList, dependencyStr ); std::vector downLevelList = i->second.second; - treeStr.append( "downward" ); - parseWard( downLevelList, treeStr ); + dependencyStr.append( "downward" ); + parseWard( downLevelList, dependencyStr ); } } @@ -1053,23 +1064,105 @@ void GEOMUtils::ConvertTreeToString( const TreeModel &tree, // function : ConvertStringToTree() // purpose : Returns the dependency tree //======================================================================= -void GEOMUtils::ConvertStringToTree( const std::string &theData, - TreeModel &tree ) +void GEOMUtils::ConvertStringToTree( const std::string& dependencyStr, + TreeModel& tree ) { std::size_t cursor = 0; - while( theData.find('-',cursor) != std::string::npos ) //find next selected object + while( dependencyStr.find('-',cursor) != std::string::npos ) //find next selected object { - std::size_t objectIndex = theData.find( '-', cursor ); - std::string objectEntry = theData.substr( cursor, objectIndex - cursor ); + std::size_t objectIndex = dependencyStr.find( '-', cursor ); + std::string objectEntry = dependencyStr.substr( cursor, objectIndex - cursor ); cursor = objectIndex; - std::size_t upwardIndexBegin = theData.find("{",cursor) + 1; - std::size_t upwardIndexFinish = theData.find("}",upwardIndexBegin); - LevelsList upwardList = parseWard( theData, cursor ); + std::size_t upwardIndexBegin = dependencyStr.find("{",cursor) + 1; + std::size_t upwardIndexFinish = dependencyStr.find("}",upwardIndexBegin); + LevelsList upwardList = parseWard( dependencyStr, cursor ); - LevelsList downwardList = parseWard( theData, cursor ); + LevelsList downwardList = parseWard( dependencyStr, cursor ); tree[objectEntry] = std::pair( upwardList, downwardList ); } } + +bool GEOMUtils::CheckShape( TopoDS_Shape& shape, + bool checkGeometry ) +{ + BRepCheck_Analyzer analyzer( shape, checkGeometry ); + return analyzer.IsValid(); +} + +bool GEOMUtils::FixShapeTolerance( TopoDS_Shape& shape, + TopAbs_ShapeEnum type, + Standard_Real tolerance ) +{ + ShapeFix_ShapeTolerance aSft; + aSft.LimitTolerance( shape, tolerance, tolerance, type ); + Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape( shape ); + aSfs->Perform(); + shape = aSfs->Shape(); + return CheckShape( shape ); +} + +bool GEOMUtils::FixShapeTolerance( TopoDS_Shape& shape, + Standard_Real tolerance ) +{ + return FixShapeTolerance( shape, TopAbs_SHAPE, tolerance ); +} + +bool GEOMUtils::FixShapeCurves( TopoDS_Shape& shape ) +{ + Standard_Real aT, aTolE, aD, aDMax; + TopExp_Explorer aExpF, aExpE; + NCollection_DataMap aDMETol; + aExpF.Init(shape, TopAbs_FACE); + for (; aExpF.More(); aExpF.Next()) { + const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current(); + aExpE.Init(aF, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current(); + try { + if (!BOPTools_AlgoTools::ComputeTolerance(aF, aE, aDMax, aT)) { + continue; + } + } + catch(...) { + continue; + } + aTolE = BRep_Tool::Tolerance(aE); + if (aDMax < aTolE) continue; + if (aDMETol.IsBound(aE)) { + aD = aDMETol.Find(aE); + if (aDMax > aD) { + aDMETol.UnBind(aE); + aDMETol.Bind(aE, aDMax); + } + } + else { + aDMETol.Bind(aE, aDMax); + } + } + } + NCollection_DataMap::Iterator aDMETolIt(aDMETol); +#ifdef USE_LIMIT_TOLERANCE + ShapeFix_ShapeTolerance sat; +#else + BRep_Builder b; +#endif + for (; aDMETolIt.More(); aDMETolIt.Next()) { +#ifdef USE_LIMIT_TOLERANCE + sat.LimitTolerance(aDMETolIt.Key(), aDMETolIt.Value()*1.001); +#else + TopoDS_Iterator itv(aDMETolIt.Key()); + for (; itv.More(); itv.Next()) + b.UpdateVertex(TopoDS::Vertex(itv.Value()), aDMETolIt.Value()*1.001); + b.UpdateEdge(aDMETolIt.Key(), aDMETolIt.Value()*1.001); +#endif + } + return CheckShape( shape ); +} + +bool GEOMUtils::Write( const TopoDS_Shape& shape, const char* fileName ) +{ + return BRepTools::Write( shape, fileName ); +} diff --git a/src/GEOMUtils/GEOMUtils.hxx b/src/GEOMUtils/GEOMUtils.hxx index 95c0e7c0f..b75501024 100644 --- a/src/GEOMUtils/GEOMUtils.hxx +++ b/src/GEOMUtils/GEOMUtils.hxx @@ -193,12 +193,80 @@ namespace GEOMUtils */ Standard_EXPORT gp_Pnt ConvertClickToPoint( int x, int y, Handle(V3d_View) theView ); - Standard_EXPORT void ConvertTreeToString( const TreeModel &theTree, - std::string &DependencyStr ); + /*! + * \brief Convert dependency tree data to the string representation + * + * \param tree dependency tree data + * \param dependencyStr output string + */ + Standard_EXPORT void ConvertTreeToString( const TreeModel& tree, + std::string& dependencyStr ); - Standard_EXPORT void ConvertStringToTree( const std::string &theDependencyStr, - TreeModel &tree ); + /*! + * \brief Restore dependency tree data from the string representation + * + * \param dependencyStr string representation of tree data + * \param tree output dependency tree data + */ + Standard_EXPORT void ConvertStringToTree( const std::string& dependencyStr, + TreeModel& tree ); + /*! + * \brief Check shape + * + * \param shape input shape object + * \param checkGeometry when set to \c true, causes check of underlying geometry + * in addition to the topology + * \return \c true if shape is valid or \c false otherwise + */ + Standard_EXPORT bool CheckShape( TopoDS_Shape& shape, bool checkGeometry = false ); + + /*! + * \brief Limit shape tolerance to the given value + * + * \param shape shape being fixed + * \param type topology type which tolerance is to be limited; TopAbs_SHAPE means + * all types of topology + * \param tolerance expected tolerance value (1e-7 by default) + * \return \c true if resulting shape is valid + * + * \note Resulting tolerance of the shape is not mandatory equal to requested value + * as it might be changed by fixshape operation in order to get valid shape where possible + */ + Standard_EXPORT bool FixShapeTolerance( TopoDS_Shape& shape, + TopAbs_ShapeEnum type, + Standard_Real tolerance = Precision::Confusion() ); + + /*! + * \brief Limit shape tolerance to the given value + * This is overloaded function, it behaves exactly as previous one + */ + Standard_EXPORT bool FixShapeTolerance( TopoDS_Shape& shape, + Standard_Real tolerance = Precision::Confusion() ); + + + /*! + * \brief Fix curves of the given shape + * + * The function checks each curve of the input shape in the following way: + * - compute deviation of the curve from the underlying surface in a set of points + * computed with the certain discretization step value + * - find maximum tolerance between computed deviation values + * - limit tolerance of the curve with the computed maximum value + * + * \param shape shape being fixed + * \return \c true if resulting shape is valid + */ + Standard_EXPORT bool FixShapeCurves( TopoDS_Shape& shape ); + + /*! + * \brief Write shape to the BREP file + * + * \param source shape + * \return \c true if file was written or \c false otherwise + */ + Standard_EXPORT bool Write( const TopoDS_Shape& shape, + const char* fileName ); }; #endif -- 2.39.2