From: mbs Date: Tue, 20 Dec 2022 19:25:10 +0000 (+0000) Subject: support fuzzy parameter in all boolean operations X-Git-Tag: V9_12_0a1~16^2~32^2~24 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=660930f24994da13c3a3ac089abfbfa20cb9b109;p=modules%2Fshaper.git support fuzzy parameter in all boolean operations --- diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanCommon.cpp b/src/FeaturesAPI/FeaturesAPI_BooleanCommon.cpp index b6d06c30c..7b8fe4217 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanCommon.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BooleanCommon.cpp @@ -34,12 +34,14 @@ FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon( //================================================================================================== FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon( const std::shared_ptr& theFeature, - const std::list& theMainObjects) + const std::list& theMainObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE(), mycreationMethod); fillAttribute(theMainObjects, mymainObjects); + fillAttribute(theFuzzy, myfuzzyValue); execute(false); } @@ -49,13 +51,15 @@ FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon( FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon( const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects) + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_ADVANCED(), mycreationMethod); fillAttribute(theMainObjects, mymainObjects); fillAttribute(theToolObjects, mytoolObjects); + fillAttribute(theFuzzy, myfuzzyValue); execute(false); } @@ -86,6 +90,14 @@ void FeaturesAPI_BooleanCommon::setToolObjects( execute(); } +//================================================================================================== +void FeaturesAPI_BooleanCommon::setFuzzyValue(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyValue); + + execute(); +} + //================================================================================================== void FeaturesAPI_BooleanCommon::setAdvancedMode(const bool theMode) { @@ -111,6 +123,7 @@ void FeaturesAPI_BooleanCommon::dump(ModelHighAPI_Dumper& theDumper) const aBase->selectionList(FeaturesPlugin_BooleanCommon::OBJECT_LIST_ID()); AttributeSelectionListPtr aTools = aBase->selectionList(FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_BooleanCommon::FUZZY_PARAM_ID())->value(); theDumper << "(" << aDocName << ", " << anObjects; @@ -118,6 +131,8 @@ void FeaturesAPI_BooleanCommon::dump(ModelHighAPI_Dumper& theDumper) const theDumper << ", " << aTools; } + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -128,6 +143,7 @@ void FeaturesAPI_BooleanCommon::dump(ModelHighAPI_Dumper& theDumper) const BooleanCommonPtr addCommon(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_BooleanCommon::ID()); @@ -135,8 +151,8 @@ BooleanCommonPtr addCommon(const std::shared_ptr& thePart, aFeature->data()->setVersion(""); BooleanCommonPtr aCommon; if (theToolObjects.empty()) - aCommon.reset(new FeaturesAPI_BooleanCommon(aFeature, theMainObjects)); + aCommon.reset(new FeaturesAPI_BooleanCommon(aFeature, theMainObjects, fuzzyParam)); else - aCommon.reset(new FeaturesAPI_BooleanCommon(aFeature, theMainObjects, theToolObjects)); + aCommon.reset(new FeaturesAPI_BooleanCommon(aFeature, theMainObjects, theToolObjects, fuzzyParam)); return aCommon; } diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanCommon.h b/src/FeaturesAPI/FeaturesAPI_BooleanCommon.h index c2a055d30..b5daab109 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanCommon.h +++ b/src/FeaturesAPI/FeaturesAPI_BooleanCommon.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Integer; class ModelHighAPI_Selection; @@ -43,25 +44,29 @@ public: /// Constructor with values. FEATURESAPI_EXPORT FeaturesAPI_BooleanCommon(const std::shared_ptr& theFeature, - const std::list& theMainObjects); + const std::list& theMainObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Constructor with values. FEATURESAPI_EXPORT FeaturesAPI_BooleanCommon(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects); + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_BooleanCommon(); - INTERFACE_3(FeaturesPlugin_BooleanCommon::ID(), + INTERFACE_4(FeaturesPlugin_BooleanCommon::ID(), creationMethod, FeaturesPlugin_BooleanCommon::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */, mainObjects, FeaturesPlugin_BooleanCommon::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList, /** Main objects */, toolObjects, FeaturesPlugin_BooleanCommon::TOOL_LIST_ID(), - ModelAPI_AttributeSelectionList, /** Tool objects*/) + ModelAPI_AttributeSelectionList, /** Tool objects*/, + fuzzyValue, FeaturesPlugin_BooleanCommon::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter*/) /// Set main objects. FEATURESAPI_EXPORT @@ -71,6 +76,10 @@ public: FEATURESAPI_EXPORT void setToolObjects(const std::list& theToolObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Set mode. FEATURESAPI_EXPORT void setAdvancedMode(const bool theMode); @@ -89,6 +98,7 @@ FEATURESAPI_EXPORT BooleanCommonPtr addCommon( const std::shared_ptr& part, const std::list& objects, const std::list& tools = std::list(), + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_BooleanCommon_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanCut.cpp b/src/FeaturesAPI/FeaturesAPI_BooleanCut.cpp index 658defee7..8bb3e9e40 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanCut.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BooleanCut.cpp @@ -34,12 +34,14 @@ FeaturesAPI_BooleanCut::FeaturesAPI_BooleanCut(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects) + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(theMainObjects, mymainObjects); fillAttribute(theToolObjects, mytoolObjects); + fillAttribute(theFuzzy, myfuzzyParam); execute(false); } @@ -67,6 +69,14 @@ void FeaturesAPI_BooleanCut::setToolObjects(const std::listselectionList(FeaturesPlugin_BooleanCut::OBJECT_LIST_ID()); AttributeSelectionListPtr aTools = aBase->selectionList(FeaturesPlugin_BooleanCut::TOOL_LIST_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_BooleanCut::FUZZY_PARAM_ID())->value(); theDumper << "(" << aDocName << ", " << anObjects << ", " << aTools; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -92,12 +105,11 @@ void FeaturesAPI_BooleanCut::dump(ModelHighAPI_Dumper& theDumper) const BooleanCutPtr addCut(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_BooleanCut::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return BooleanCutPtr(new FeaturesAPI_BooleanCut(aFeature, - theMainObjects, - theToolObjects)); + return BooleanCutPtr(new FeaturesAPI_BooleanCut(aFeature, theMainObjects, theToolObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanCut.h b/src/FeaturesAPI/FeaturesAPI_BooleanCut.h index 0035c6fdb..09f673743 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanCut.h +++ b/src/FeaturesAPI/FeaturesAPI_BooleanCut.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Integer; class ModelHighAPI_Selection; @@ -44,17 +45,20 @@ public: FEATURESAPI_EXPORT FeaturesAPI_BooleanCut(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects); + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_BooleanCut(); - INTERFACE_2(FeaturesPlugin_BooleanCut::ID(), + INTERFACE_3(FeaturesPlugin_BooleanCut::ID(), mainObjects, FeaturesPlugin_BooleanCut::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList, /** Main objects */, toolObjects, FeaturesPlugin_BooleanCut::TOOL_LIST_ID(), - ModelAPI_AttributeSelectionList, /** Tool objects*/) + ModelAPI_AttributeSelectionList, /** Tool objects*/, + fuzzyParam, FeaturesPlugin_BooleanCut::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Set main objects. FEATURESAPI_EXPORT @@ -64,6 +68,10 @@ public: FEATURESAPI_EXPORT void setToolObjects(const std::list& theToolObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -78,6 +86,7 @@ FEATURESAPI_EXPORT BooleanCutPtr addCut(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_BooleanCut_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanFill.cpp b/src/FeaturesAPI/FeaturesAPI_BooleanFill.cpp index 7c4716cec..09d4a4774 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanFill.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BooleanFill.cpp @@ -35,12 +35,14 @@ FeaturesAPI_BooleanFill::FeaturesAPI_BooleanFill( FeaturesAPI_BooleanFill::FeaturesAPI_BooleanFill( const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects) + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(theMainObjects, mymainObjects); fillAttribute(theToolObjects, mytoolObjects); + fillAttribute(theFuzzy, myfuzzyParam); execute(false); } @@ -70,6 +72,14 @@ void FeaturesAPI_BooleanFill::setToolObjects( execute(); } +//================================================================================================== +void FeaturesAPI_BooleanFill::setFuzzyValue(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); +} + //================================================================================================== void FeaturesAPI_BooleanFill::dump(ModelHighAPI_Dumper& theDumper) const { @@ -82,9 +92,12 @@ void FeaturesAPI_BooleanFill::dump(ModelHighAPI_Dumper& theDumper) const aBase->selectionList(FeaturesPlugin_BooleanFill::OBJECT_LIST_ID()); AttributeSelectionListPtr aTools = aBase->selectionList(FeaturesPlugin_BooleanFill::TOOL_LIST_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_BooleanFill::FUZZY_PARAM_ID())->value(); theDumper << "(" << aDocName << ", " << anObjects << ", " << aTools; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -95,10 +108,11 @@ void FeaturesAPI_BooleanFill::dump(ModelHighAPI_Dumper& theDumper) const BooleanFillPtr addSplit(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_BooleanFill::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return BooleanFillPtr(new FeaturesAPI_BooleanFill(aFeature, theMainObjects, theToolObjects)); + return BooleanFillPtr(new FeaturesAPI_BooleanFill(aFeature, theMainObjects, theToolObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanFill.h b/src/FeaturesAPI/FeaturesAPI_BooleanFill.h index 9a80cbce4..35743ffc9 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanFill.h +++ b/src/FeaturesAPI/FeaturesAPI_BooleanFill.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Integer; class ModelHighAPI_Selection; @@ -44,17 +45,20 @@ public: FEATURESAPI_EXPORT FeaturesAPI_BooleanFill(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects); + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_BooleanFill(); - INTERFACE_2(FeaturesPlugin_BooleanFill::ID(), + INTERFACE_3(FeaturesPlugin_BooleanFill::ID(), mainObjects, FeaturesPlugin_BooleanFill::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList, /** Main objects */, toolObjects, FeaturesPlugin_BooleanFill::TOOL_LIST_ID(), - ModelAPI_AttributeSelectionList, /** Tool objects*/) + ModelAPI_AttributeSelectionList, /** Tool objects*/, + fuzzyParam, FeaturesPlugin_BooleanFill::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Set main objects. FEATURESAPI_EXPORT @@ -64,6 +68,10 @@ public: FEATURESAPI_EXPORT void setToolObjects(const std::list& theToolObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -78,6 +86,7 @@ FEATURESAPI_EXPORT BooleanFillPtr addSplit(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_BooleanFill_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanFuse.cpp b/src/FeaturesAPI/FeaturesAPI_BooleanFuse.cpp index 5d3ceffed..2fd8df093 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanFuse.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BooleanFuse.cpp @@ -35,13 +35,15 @@ FeaturesAPI_BooleanFuse::FeaturesAPI_BooleanFuse( FeaturesAPI_BooleanFuse::FeaturesAPI_BooleanFuse( const std::shared_ptr& theFeature, const std::list& theMainObjects, - const bool theRemoveEdges) + const bool theRemoveEdges, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if (initialize()) { fillAttribute(FeaturesPlugin_BooleanFuse::CREATION_METHOD_SIMPLE(), mycreationMethod); fillAttribute(theMainObjects, mymainObjects); fillAttribute(theRemoveEdges, myremoveEdges); + fillAttribute(theFuzzy, myfuzzyParam); execute(false); } @@ -52,7 +54,8 @@ FeaturesAPI_BooleanFuse::FeaturesAPI_BooleanFuse( const std::shared_ptr& theFeature, const std::list& theMainObjects, const std::list& theToolObjects, - const bool theRemoveEdges) + const bool theRemoveEdges, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { @@ -60,6 +63,7 @@ FeaturesAPI_BooleanFuse::FeaturesAPI_BooleanFuse( fillAttribute(theMainObjects, mymainObjects); fillAttribute(theToolObjects, mytoolObjects); fillAttribute(theRemoveEdges, myremoveEdges); + fillAttribute(theFuzzy, myfuzzyParam); execute(false); } @@ -98,6 +102,14 @@ void FeaturesAPI_BooleanFuse::setRemoveEdges(const bool theRemoveEdges) execute(); } +//================================================================================================== +void FeaturesAPI_BooleanFuse::setFuzzyValue(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); +} + //================================================================================================== void FeaturesAPI_BooleanFuse::setAdvancedMode(const bool theMode) { @@ -125,6 +137,7 @@ void FeaturesAPI_BooleanFuse::dump(ModelHighAPI_Dumper& theDumper) const aBase->selectionList(FeaturesPlugin_BooleanFuse::TOOL_LIST_ID()); AttributeBooleanPtr aRemoveEdges = aBase->boolean(FeaturesPlugin_BooleanFuse::REMOVE_INTERSECTION_EDGES_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_BooleanFuse::FUZZY_PARAM_ID())->value(); theDumper << "(" << aDocName << ", " << anObjects; @@ -136,6 +149,10 @@ void FeaturesAPI_BooleanFuse::dump(ModelHighAPI_Dumper& theDumper) const theDumper << ", removeEdges = True"; } + if (aFuzzy != 1.e-8) { + theDumper << ", fuzzyParam = " << aFuzzy; + } + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -147,6 +164,7 @@ BooleanFusePtr addFuse(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::pair, bool>& theToolObjects, const bool theRemoveEdges, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_BooleanFuse::ID()); @@ -159,10 +177,10 @@ BooleanFusePtr addFuse(const std::shared_ptr& thePart, BooleanFusePtr aFuse; if (theToolObjects.first.empty()) - aFuse.reset(new FeaturesAPI_BooleanFuse(aFeature, theMainObjects, aRemoveEdges)); + aFuse.reset(new FeaturesAPI_BooleanFuse(aFeature, theMainObjects, aRemoveEdges, fuzzyParam)); else { aFuse.reset(new FeaturesAPI_BooleanFuse(aFeature, theMainObjects, theToolObjects.first, - aRemoveEdges)); + aRemoveEdges, fuzzyParam)); } return aFuse; } diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanFuse.h b/src/FeaturesAPI/FeaturesAPI_BooleanFuse.h index 3c4fdccdf..04da890e6 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanFuse.h +++ b/src/FeaturesAPI/FeaturesAPI_BooleanFuse.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Integer; class ModelHighAPI_Selection; @@ -44,20 +45,22 @@ public: FEATURESAPI_EXPORT FeaturesAPI_BooleanFuse(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const bool theRemoveEdges = false); + const bool theRemoveEdges = false, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Constructor with values. FEATURESAPI_EXPORT FeaturesAPI_BooleanFuse(const std::shared_ptr& theFeature, const std::list& theMainObjects, const std::list& theToolObjects, - const bool theRemoveEdges = false); + const bool theRemoveEdges = false, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_BooleanFuse(); - INTERFACE_4(FeaturesPlugin_BooleanFuse::ID(), + INTERFACE_5(FeaturesPlugin_BooleanFuse::ID(), creationMethod, FeaturesPlugin_BooleanFuse::CREATION_METHOD(), ModelAPI_AttributeString, /** Creation method */, mainObjects, FeaturesPlugin_BooleanFuse::OBJECT_LIST_ID(), @@ -65,7 +68,9 @@ public: toolObjects, FeaturesPlugin_BooleanFuse::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList, /** Tool objects*/, removeEdges, FeaturesPlugin_BooleanFuse::REMOVE_INTERSECTION_EDGES_ID(), - ModelAPI_AttributeBoolean, /** Remove edges */) + ModelAPI_AttributeBoolean, /** Remove edges */, + fuzzyParam, FeaturesPlugin_BooleanFuse::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Set main objects. FEATURESAPI_EXPORT @@ -79,6 +84,10 @@ public: FEATURESAPI_EXPORT void setRemoveEdges(const bool theRemoveEdges); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Set mode. FEATURESAPI_EXPORT void setAdvancedMode(const bool theMode); @@ -101,6 +110,7 @@ FEATURESAPI_EXPORT BooleanFusePtr addFuse( const std::list& objects, const std::pair, bool>& tools = DUMMY_TOOLS, const bool removeEdges = false, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_BooleanFuse_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanSmash.cpp b/src/FeaturesAPI/FeaturesAPI_BooleanSmash.cpp index 4a4d0330f..7c5ce1722 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanSmash.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BooleanSmash.cpp @@ -35,12 +35,14 @@ FeaturesAPI_BooleanSmash::FeaturesAPI_BooleanSmash( FeaturesAPI_BooleanSmash::FeaturesAPI_BooleanSmash( const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects) + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(theMainObjects, mymainObjects); fillAttribute(theToolObjects, mytoolObjects); + fillAttribute(theFuzzy, myfuzzyParam); execute(false); } @@ -70,6 +72,14 @@ void FeaturesAPI_BooleanSmash::setToolObjects( execute(); } +//================================================================================================== +void FeaturesAPI_BooleanSmash::setFuzzyValue(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); +} + //================================================================================================== void FeaturesAPI_BooleanSmash::dump(ModelHighAPI_Dumper& theDumper) const { @@ -82,9 +92,12 @@ void FeaturesAPI_BooleanSmash::dump(ModelHighAPI_Dumper& theDumper) const aBase->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()); AttributeSelectionListPtr aTools = aBase->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_BooleanSmash::FUZZY_PARAM_ID())->value(); theDumper << "(" << aDocName << ", " << anObjects << ", " << aTools; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -95,10 +108,11 @@ void FeaturesAPI_BooleanSmash::dump(ModelHighAPI_Dumper& theDumper) const BooleanSmashPtr addSmash(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_BooleanSmash::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return BooleanSmashPtr(new FeaturesAPI_BooleanSmash(aFeature, theMainObjects, theToolObjects)); + return BooleanSmashPtr(new FeaturesAPI_BooleanSmash(aFeature, theMainObjects, theToolObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_BooleanSmash.h b/src/FeaturesAPI/FeaturesAPI_BooleanSmash.h index a59db43d0..188079af7 100644 --- a/src/FeaturesAPI/FeaturesAPI_BooleanSmash.h +++ b/src/FeaturesAPI/FeaturesAPI_BooleanSmash.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Integer; class ModelHighAPI_Selection; @@ -44,17 +45,20 @@ public: FEATURESAPI_EXPORT FeaturesAPI_BooleanSmash(const std::shared_ptr& theFeature, const std::list& theMainObjects, - const std::list& theToolObjects); + const std::list& theToolObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_BooleanSmash(); - INTERFACE_2(FeaturesPlugin_BooleanSmash::ID(), + INTERFACE_3(FeaturesPlugin_BooleanSmash::ID(), mainObjects, FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList, /** Main objects */, toolObjects, FeaturesPlugin_BooleanSmash::TOOL_LIST_ID(), - ModelAPI_AttributeSelectionList, /** Tool objects*/) + ModelAPI_AttributeSelectionList, /** Tool objects*/, + fuzzyParam, FeaturesPlugin_BooleanSmash::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Set main objects. FEATURESAPI_EXPORT @@ -64,6 +68,10 @@ public: FEATURESAPI_EXPORT void setToolObjects(const std::list& theToolObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -78,6 +86,7 @@ FEATURESAPI_EXPORT BooleanSmashPtr addSmash(const std::shared_ptr& thePart, const std::list& theMainObjects, const std::list& theToolObjects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_BooleanSmash_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_Intersection.cpp b/src/FeaturesAPI/FeaturesAPI_Intersection.cpp index 6ac09629c..6ceafb170 100644 --- a/src/FeaturesAPI/FeaturesAPI_Intersection.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Intersection.cpp @@ -33,11 +33,13 @@ FeaturesAPI_Intersection::FeaturesAPI_Intersection( //================================================================================================== FeaturesAPI_Intersection::FeaturesAPI_Intersection( const std::shared_ptr& theFeature, - const std::list& theObjects) + const std::list& theObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { fillAttribute(theObjects, myobjects); + fillAttribute(theFuzzy, myfuzzyParam); execute(); } @@ -57,6 +59,14 @@ void FeaturesAPI_Intersection::setObjects(const std::listselectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_Intersection::FUZZY_PARAM_ID())->value(); theDumper << aBase << " = model.addIntersection(" << aDocName << ", " << anAttrObjects; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -77,10 +90,11 @@ void FeaturesAPI_Intersection::dump(ModelHighAPI_Dumper& theDumper) const //================================================================================================== IntersectionPtr addIntersection(const std::shared_ptr& thePart, const std::list& theObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Intersection::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return IntersectionPtr(new FeaturesAPI_Intersection(aFeature, theObjects)); + return IntersectionPtr(new FeaturesAPI_Intersection(aFeature, theObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_Intersection.h b/src/FeaturesAPI/FeaturesAPI_Intersection.h index acaff95bc..f69daaff6 100644 --- a/src/FeaturesAPI/FeaturesAPI_Intersection.h +++ b/src/FeaturesAPI/FeaturesAPI_Intersection.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Dumper; class ModelHighAPI_Selection; @@ -43,20 +44,27 @@ public: /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_Intersection(const std::shared_ptr& theFeature, - const std::list& theObjects); + const std::list& theObjects, + const ModelHighAPI_Double& aFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_Intersection(); - INTERFACE_1(FeaturesPlugin_Intersection::ID(), + INTERFACE_2(FeaturesPlugin_Intersection::ID(), objects, FeaturesPlugin_Intersection::OBJECT_LIST_ID(), - ModelAPI_AttributeSelectionList, /** Objects */) + ModelAPI_AttributeSelectionList, /** Objects */, + fuzzyParam, FeaturesPlugin_Intersection::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Modify objects attribute of the feature. FEATURESAPI_EXPORT void setObjects(const std::list& theObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -70,6 +78,7 @@ typedef std::shared_ptr IntersectionPtr; FEATURESAPI_EXPORT IntersectionPtr addIntersection(const std::shared_ptr& part, const std::list& objects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_Intersection_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_Partition.cpp b/src/FeaturesAPI/FeaturesAPI_Partition.cpp index 54ff44bb3..c7ca9aa40 100644 --- a/src/FeaturesAPI/FeaturesAPI_Partition.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Partition.cpp @@ -32,11 +32,14 @@ FeaturesAPI_Partition::FeaturesAPI_Partition(const std::shared_ptr& theFeature, - const std::list& theBaseObjects) + const std::list& theBaseObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { - setBase(theBaseObjects); + fillAttribute(theBaseObjects, mybaseObjects); + fillAttribute(theFuzzy, myfuzzyParam); + execute(); } } @@ -54,6 +57,14 @@ void FeaturesAPI_Partition::setBase(const std::list& the execute(); } +//================================================================================================== +void FeaturesAPI_Partition::setFuzzy(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); +} + //================================================================================================== void FeaturesAPI_Partition::dump(ModelHighAPI_Dumper& theDumper) const { @@ -62,9 +73,12 @@ void FeaturesAPI_Partition::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Partition::BASE_OBJECTS_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_Partition::FUZZY_PARAM_ID())->value(); theDumper << aBase << " = model.addPartition(" << aDocName << ", " << anAttrObjects; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -74,10 +88,11 @@ void FeaturesAPI_Partition::dump(ModelHighAPI_Dumper& theDumper) const //================================================================================================== PartitionPtr addPartition(const std::shared_ptr& thePart, const std::list& theBaseObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Partition::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return PartitionPtr(new FeaturesAPI_Partition(aFeature, theBaseObjects)); + return PartitionPtr(new FeaturesAPI_Partition(aFeature, theBaseObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_Partition.h b/src/FeaturesAPI/FeaturesAPI_Partition.h index eb125b78f..3e533ff93 100644 --- a/src/FeaturesAPI/FeaturesAPI_Partition.h +++ b/src/FeaturesAPI/FeaturesAPI_Partition.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Dumper; class ModelHighAPI_Selection; @@ -43,20 +44,27 @@ public: /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_Partition(const std::shared_ptr& theFeature, - const std::list& theBaseObjects); + const std::list& theBaseObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_Partition(); - INTERFACE_1(FeaturesPlugin_Partition::ID(), + INTERFACE_2(FeaturesPlugin_Partition::ID(), baseObjects, FeaturesPlugin_Partition::BASE_OBJECTS_ID(), - ModelAPI_AttributeSelectionList, /** Base objects */) + ModelAPI_AttributeSelectionList, /** Base objects */, + fuzzyParam, FeaturesPlugin_Partition::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Modify base attribute of the feature. FEATURESAPI_EXPORT void setBase(const std::list& theBaseObjects); + /// Modify fuzzy parameter attribute of the feature. + FEATURESAPI_EXPORT + void setFuzzy(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -70,6 +78,7 @@ typedef std::shared_ptr PartitionPtr; FEATURESAPI_EXPORT PartitionPtr addPartition(const std::shared_ptr& thePart, const std::list& theBaseObjects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_Partition_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_Union.cpp b/src/FeaturesAPI/FeaturesAPI_Union.cpp index 082016c98..30e4234b2 100644 --- a/src/FeaturesAPI/FeaturesAPI_Union.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Union.cpp @@ -31,11 +31,15 @@ FeaturesAPI_Union::FeaturesAPI_Union(const std::shared_ptr& th //================================================================================================ FeaturesAPI_Union::FeaturesAPI_Union(const std::shared_ptr& theFeature, - const std::list& theBaseObjects) + const std::list& theBaseObjects, + const ModelHighAPI_Double& theFuzzy) : ModelHighAPI_Interface(theFeature) { if(initialize()) { - setBase(theBaseObjects); + fillAttribute(theBaseObjects, mybaseObjects); + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); } } @@ -53,6 +57,14 @@ void FeaturesAPI_Union::setBase(const std::list& theBase execute(); } +//================================================================================================== +void FeaturesAPI_Union::setFuzzyValue(const ModelHighAPI_Double& theFuzzy) +{ + fillAttribute(theFuzzy, myfuzzyParam); + + execute(); +} + //================================================================================================== void FeaturesAPI_Union::dump(ModelHighAPI_Dumper& theDumper) const { @@ -61,9 +73,12 @@ void FeaturesAPI_Union::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID()); + double aFuzzy = aBase->real(FeaturesPlugin_Union::FUZZY_PARAM_ID())->value(); theDumper << aBase << " = model.addUnion(" << aDocName << ", " << anAttrObjects; + theDumper << ", fuzzyParam = " << aFuzzy; + if (!aBase->data()->version().empty()) theDumper << ", keepSubResults = True"; @@ -73,10 +88,11 @@ void FeaturesAPI_Union::dump(ModelHighAPI_Dumper& theDumper) const //================================================================================================== UnionPtr addUnion(const std::shared_ptr& thePart, const std::list& theBaseObjects, + const ModelHighAPI_Double& fuzzyParam, const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Union::ID()); if (!keepSubResults) aFeature->data()->setVersion(""); - return UnionPtr(new FeaturesAPI_Union(aFeature, theBaseObjects)); + return UnionPtr(new FeaturesAPI_Union(aFeature, theBaseObjects, fuzzyParam)); } diff --git a/src/FeaturesAPI/FeaturesAPI_Union.h b/src/FeaturesAPI/FeaturesAPI_Union.h index af6de9746..022d14130 100644 --- a/src/FeaturesAPI/FeaturesAPI_Union.h +++ b/src/FeaturesAPI/FeaturesAPI_Union.h @@ -26,6 +26,7 @@ #include #include +#include class ModelHighAPI_Dumper; class ModelHighAPI_Selection; @@ -43,20 +44,27 @@ public: /// Constructor with values. FEATURESAPI_EXPORT explicit FeaturesAPI_Union(const std::shared_ptr& theFeature, - const std::list& theBaseObjects); + const std::list& theBaseObjects, + const ModelHighAPI_Double& theFuzzy = ModelHighAPI_Double(1.e-8)); /// Destructor. FEATURESAPI_EXPORT virtual ~FeaturesAPI_Union(); - INTERFACE_1(FeaturesPlugin_Union::ID(), + INTERFACE_2(FeaturesPlugin_Union::ID(), baseObjects, FeaturesPlugin_Union::BASE_OBJECTS_ID(), - ModelAPI_AttributeSelectionList, /** Base objects */) + ModelAPI_AttributeSelectionList, /** Base objects */, + fuzzyParam, FeaturesPlugin_Union::FUZZY_PARAM_ID(), + ModelAPI_AttributeDouble, /** Fuzzy parameter */) /// Modify base attribute of the feature. FEATURESAPI_EXPORT void setBase(const std::list& theBaseObjects); + /// Set fuzzy parameter. + FEATURESAPI_EXPORT + void setFuzzyValue(const ModelHighAPI_Double& theFuzzy); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; @@ -70,6 +78,7 @@ typedef std::shared_ptr UnionPtr; FEATURESAPI_EXPORT UnionPtr addUnion(const std::shared_ptr& thePart, const std::list& theBaseObjects, + const ModelHighAPI_Double& fuzzyParam = ModelHighAPI_Double(1.e-8), const bool keepSubResults = false); #endif // FeaturesAPI_Union_H_ diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index bb277c382..82f08f182 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -54,12 +55,14 @@ FeaturesPlugin_Boolean::FeaturesPlugin_Boolean(const OperationType theOperationT //================================================================================================= void FeaturesPlugin_Boolean::initAttributes() { - AttributeSelectionListPtr aSelection = - std::dynamic_pointer_cast(data()->addAttribute( - FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + data()->addAttribute(FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); - aSelection = std::dynamic_pointer_cast(data()->addAttribute( - FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + data()->addAttribute(FeaturesPlugin_Boolean::FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID()); @@ -120,10 +123,10 @@ void FeaturesPlugin_Boolean::storeResult( document()->createBody(data(), theResultIndex); ModelAPI_Tools::loadModifiedShapes(aResultBody, - theObjects, - theTools, - theMakeShapeList, - theResultShape); + theObjects, + theTools, + theMakeShapeList, + theResultShape); setResult(aResultBody, theResultIndex++); // merge algorithms diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index 960edb584..fc88bcbab 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -51,6 +51,13 @@ public: return MY_TOOL_LIST_ID; } + /// Attribute name of fuzzy parameter. + inline static const std::string& FUZZY_PARAM_ID() + { + static const std::string MY_FUZZY_PARAM_ID("fuzzy_param"); + return MY_FUZZY_PARAM_ID; + } + /// \return boolean operation type. FEATURESPLUGIN_EXPORT OperationType operationType(); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp index e3023859e..b3d4e4c53 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp @@ -20,6 +20,7 @@ #include "FeaturesPlugin_BooleanCommon.h" #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include + //================================================================================================== FeaturesPlugin_BooleanCommon::FeaturesPlugin_BooleanCommon() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_COMMON) @@ -52,6 +54,13 @@ void FeaturesPlugin_BooleanCommon::initAttributes() data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); data()->addAttribute(TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + initVersion(BOP_VERSION_9_4(), selectionList(OBJECT_LIST_ID()), selectionList(TOOL_LIST_ID())); } @@ -86,6 +95,10 @@ void FeaturesPlugin_BooleanCommon::execute() return; } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + // version of COMMON feature const std::string aCommonVersion = data()->version(); @@ -104,7 +117,8 @@ void FeaturesPlugin_BooleanCommon::execute() std::shared_ptr aCommonAlgo( new GeomAlgoAPI_Boolean(aShape, *anObjectsIt, - GeomAlgoAPI_Tools::BOOL_COMMON)); + GeomAlgoAPI_Tools::BOOL_COMMON, + aFuzzy)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) { setError(anError); @@ -129,10 +143,10 @@ void FeaturesPlugin_BooleanCommon::execute() ListOfShape anObjectList = anObjects.objects(); ListOfShape aToolsList; ModelAPI_Tools::loadModifiedShapes(aResultBody, - anObjectList, - aToolsList, - aMakeShapeList, - aShape); + anObjectList, + aToolsList, + aMakeShapeList, + aShape); GeomShapePtr aBaseShape = anObjectList.front(); anObjectList.pop_front(); setResult(aResultBody, aResultIndex); @@ -167,6 +181,7 @@ void FeaturesPlugin_BooleanCommon::execute() // Compound handling isOk = processCompound(GeomAlgoAPI_Tools::BOOL_COMMON, anObjects, aParent, aTools.objects(), + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -174,6 +189,7 @@ void FeaturesPlugin_BooleanCommon::execute() // Compsolid handling isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_COMMON, anObjects, aParent, aTools.objects(), ListOfShape(), + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -181,6 +197,7 @@ void FeaturesPlugin_BooleanCommon::execute() // process object as is isOk = processObject(GeomAlgoAPI_Tools::BOOL_COMMON, anObject, aTools.objects(), aPlanes, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -195,8 +212,8 @@ void FeaturesPlugin_BooleanCommon::execute() if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, - aTools.objects(), - aResultCompound); + aTools.objects(), + aResultCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.h b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.h index 7e46caf23..8817a5748 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.h +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.h @@ -66,20 +66,6 @@ public: return MY_CREATION_METHOD_ID; } - /// Attribute name of main objects. - inline static const std::string& OBJECT_LIST_ID() - { - static const std::string MY_OBJECT_LIST_ID("main_objects"); - return MY_OBJECT_LIST_ID; - } - - /// Attribute name of tool objects. - inline static const std::string& TOOL_LIST_ID() - { - static const std::string MY_TOOL_LIST_ID("tool_objects"); - return MY_TOOL_LIST_ID; - } - /// Request for initialization of data model of the feature: adding all attributes. FEATURESPLUGIN_EXPORT virtual void initAttributes(); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp index 3095f40fd..50de25d0c 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp @@ -20,6 +20,7 @@ #include "FeaturesPlugin_BooleanCut.h" #include +#include #include #include @@ -33,6 +34,7 @@ #include #include + //================================================================================================== FeaturesPlugin_BooleanCut::FeaturesPlugin_BooleanCut() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_CUT) @@ -78,6 +80,10 @@ void FeaturesPlugin_BooleanCut::execute() keepUnusedSubsOfCompound(GeomShapePtr(), anObjects, aTools, aMakeShapeList); } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + // For solids cut each object with all tools. bool isOk = true; for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin(); @@ -92,6 +98,7 @@ void FeaturesPlugin_BooleanCut::execute() // Compound handling isOk = processCompound(GeomAlgoAPI_Tools::BOOL_CUT, anObjects, aParent, aTools.objects(), + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -99,6 +106,7 @@ void FeaturesPlugin_BooleanCut::execute() // Compsolid handling isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_CUT, anObjects, aParent, aTools.objects(), ListOfShape(), + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -106,6 +114,7 @@ void FeaturesPlugin_BooleanCut::execute() // process object as is isOk = processObject(GeomAlgoAPI_Tools::BOOL_CUT, anObject, aTools.objects(), aPlanes, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -119,8 +128,8 @@ void FeaturesPlugin_BooleanCut::execute() if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, - aTools.objects(), - aResultCompound); + aTools.objects(), + aResultCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp index e0e2c6ed1..247fd3561 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp @@ -20,6 +20,7 @@ #include "FeaturesPlugin_BooleanFill.h" #include +#include #include #include @@ -39,6 +40,7 @@ #include #include + //================================================================================================= FeaturesPlugin_BooleanFill::FeaturesPlugin_BooleanFill() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_FILL) @@ -89,6 +91,10 @@ void FeaturesPlugin_BooleanFill::execute() keepUnusedSubsOfCompound(GeomShapePtr(), anObjects, aTools, aMakeShapeList); } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + // For solids cut each object with all tools. bool isOk = true; for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin(); @@ -103,12 +109,14 @@ void FeaturesPlugin_BooleanFill::execute() // compsolid handling isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_PARTITION, anObjects, aParent, aTools.objects(), aPlanes, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } else { // process object as is isOk = processObject(GeomAlgoAPI_Tools::BOOL_PARTITION, anObject, aTools.objects(), aPlanes, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } @@ -122,8 +130,8 @@ void FeaturesPlugin_BooleanFill::execute() if (!aResultCompound) aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, - aTools.objects(), - aResultCompound); + aTools.objects(), + aResultCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp index 764a7752f..a10fead97 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #include #include + +//================================================================================================== static void explodeCompound(const GeomShapePtr& theShape, ListOfShape& theResult) { if (theShape->shapeType() == GeomAPI_Shape::COMPOUND) { @@ -69,6 +72,12 @@ void FeaturesPlugin_BooleanFuse::initAttributes() data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); data()->addAttribute(TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + data()->addAttribute(REMOVE_INTERSECTION_EDGES_ID(), ModelAPI_AttributeBoolean::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID()); @@ -115,6 +124,10 @@ void FeaturesPlugin_BooleanFuse::execute() return; } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + // version of FUSE feature const std::string aFuseVersion = data()->version(); @@ -161,7 +174,7 @@ void FeaturesPlugin_BooleanFuse::execute() GeomShapePtr aCuttedEdgesAndFaces; if (!anEdgesAndFaces.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, - anOriginalShapes, GeomAlgoAPI_Tools::BOOL_CUT)); + anOriginalShapes, GeomAlgoAPI_Tools::BOOL_CUT, aFuzzy)); if (aCutAlgo->isDone()) { aCuttedEdgesAndFaces = aCutAlgo->shape(); aMakeShapeList->appendAlgo(aCutAlgo); @@ -181,7 +194,7 @@ void FeaturesPlugin_BooleanFuse::execute() ListOfShape aOneObjectList; aOneObjectList.push_back(*anIt); std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Tools::BOOL_CUT)); + new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Tools::BOOL_CUT, aFuzzy)); if (GeomAlgoAPI_ShapeTools::area(aCutAlgo->shape()) > 1.e-27) { aSolidsToFuse.push_back(aCutAlgo->shape()); @@ -206,7 +219,8 @@ void FeaturesPlugin_BooleanFuse::execute() } else if ((anObjects.size() + aTools.size()) > 1) { std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, - GeomAlgoAPI_Tools::BOOL_FUSE)); + GeomAlgoAPI_Tools::BOOL_FUSE, + aFuzzy)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFuseAlgo, getKind(), anError)) { @@ -229,7 +243,7 @@ void FeaturesPlugin_BooleanFuse::execute() aShapesToAdd.push_back(aShape); } std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true, aFuzzy)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFillerAlgo, getKind(), anError)) { setError(anError); return; diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp index 019d27a31..9f1aca998 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp @@ -20,6 +20,7 @@ #include "FeaturesPlugin_BooleanSmash.h" #include +#include #include #include @@ -33,6 +34,7 @@ #include #include + //================================================================================================== FeaturesPlugin_BooleanSmash::FeaturesPlugin_BooleanSmash() : FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_SMASH) @@ -45,6 +47,12 @@ void FeaturesPlugin_BooleanSmash::initAttributes() data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); data()->addAttribute(TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + initVersion(BOP_VERSION_9_4(), selectionList(OBJECT_LIST_ID()), selectionList(TOOL_LIST_ID())); } @@ -100,13 +108,18 @@ void FeaturesPlugin_BooleanSmash::execute() } } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); if (!aShapesToAdd.empty()) { // Cut objects with not used solids. std::shared_ptr anObjectsCutAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aShapesToAdd, - GeomAlgoAPI_Tools::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT, + aFuzzy)); if (GeomAlgoAPI_ShapeTools::area(anObjectsCutAlgo->shape()) > 1.e-27) { aShapesToSmash.clear(); @@ -118,7 +131,8 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aToolsCutAlgo( new GeomAlgoAPI_Boolean(aTools, aShapesToAdd, - GeomAlgoAPI_Tools::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT, + aFuzzy)); if (GeomAlgoAPI_ShapeTools::area(aToolsCutAlgo->shape()) > 1.e-27) { aTools.clear(); @@ -131,7 +145,8 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aBoolAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aTools, - GeomAlgoAPI_Tools::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT, + aFuzzy)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { @@ -154,7 +169,7 @@ void FeaturesPlugin_BooleanSmash::execute() } else { std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true, aFuzzy)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFillerAlgo, getKind(), anError)) { setError(anError); return; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp index 4d8705ab5..42dff80df 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ #include + static const std::string INTERSECTION_VERSION_1("v9.5"); //================================================================================================= @@ -46,6 +48,12 @@ void FeaturesPlugin_Intersection::initAttributes() AttributePtr anObjectsAttr = data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + initVersion(INTERSECTION_VERSION_1, anObjectsAttr, AttributePtr()); } @@ -60,11 +68,15 @@ void FeaturesPlugin_Intersection::execute() return; } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + int aResultIndex = 0; // Create result. const ListOfShape& anObjects = anObjectsHierarchy.objects(); - GeomMakeShapePtr anIntersectionAlgo(new GeomAlgoAPI_Intersection(anObjects)); + GeomMakeShapePtr anIntersectionAlgo(new GeomAlgoAPI_Intersection(anObjects, aFuzzy)); // Checking that the algorithm worked properly. std::string anError; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.h b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h index 0b0dc9d1c..08e3e7a72 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h @@ -48,6 +48,13 @@ public: return MY_OBJECT_LIST_ID; } + /// Attribute name of fuzzy parameter. + inline static const std::string& FUZZY_PARAM_ID() + { + static const std::string MY_FUZZY_PARAM_ID("fuzzy_param"); + return MY_FUZZY_PARAM_ID; + } + /// Returns the kind of a feature. FEATURESPLUGIN_EXPORT virtual const std::string& getKind() { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp index 46a16c54c..7e1a77c7a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp @@ -20,6 +20,7 @@ #include "FeaturesPlugin_Partition.h" #include +#include #include #include #include @@ -58,6 +59,13 @@ FeaturesPlugin_Partition::FeaturesPlugin_Partition() void FeaturesPlugin_Partition::initAttributes() { data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + initVersion(BOP_VERSION_9_4(), selectionList(BASE_OBJECTS_ID())); } @@ -75,6 +83,10 @@ void FeaturesPlugin_Partition::execute() return; } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + ListOfShape aBaseObjects = anObjects.objects(); aBaseObjects.insert(aBaseObjects.end(), aPlanes.begin(), aPlanes.end()); @@ -85,7 +97,7 @@ void FeaturesPlugin_Partition::execute() // cut unused solids of composolids from the objects of partition ListOfShape aTargetObjects, anUnusedSubs; std::string aError; - if (!cutSubs(anObjects, aTargetObjects, anUnusedSubs, aMakeShapeList, aError)) { + if (!cutSubs(anObjects, aTargetObjects, anUnusedSubs, aFuzzy, aMakeShapeList, aError)) { setError(aError); return; } @@ -93,7 +105,7 @@ void FeaturesPlugin_Partition::execute() // perform partition first time to split target solids by planes std::shared_ptr aPartitionAlgo( - new GeomAlgoAPI_Partition(aTargetObjects, aPlanes)); + new GeomAlgoAPI_Partition(aTargetObjects, aPlanes, aFuzzy)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), aError)) { @@ -209,9 +221,9 @@ void FeaturesPlugin_Partition::storeResult( //================================================================================================= - static bool cutSubs(ListOfShape& theSubsToCut, const ListOfShape& theTools, + const double theFuzzy, std::shared_ptr& theMakeShapeList, std::string& theError) { @@ -220,7 +232,7 @@ static bool cutSubs(ListOfShape& theSubsToCut, // cut from current list of solids std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(theSubsToCut, theTools, GeomAlgoAPI_Tools::BOOL_CUT)); + new GeomAlgoAPI_Boolean(theSubsToCut, theTools, GeomAlgoAPI_Tools::BOOL_CUT, theFuzzy)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, "", theError)) return false; theMakeShapeList->appendAlgo(aCutAlgo); @@ -233,10 +245,12 @@ static bool cutSubs(ListOfShape& theSubsToCut, return true; } +//================================================================================================= bool FeaturesPlugin_Partition::cutSubs( GeomAPI_ShapeHierarchy& theHierarchy, ListOfShape& theUsed, ListOfShape& theNotUsed, + const double theFuzzy, std::shared_ptr& theMakeShapeList, std::string& theError) { @@ -272,8 +286,8 @@ bool FeaturesPlugin_Partition::cutSubs( else aUsed.push_back(*anIt); - isOk = ::cutSubs(aUsed, aToolsForUsed, theMakeShapeList, theError) - && ::cutSubs(aNotUsed, aToolsForUnused, theMakeShapeList, theError); + isOk = ::cutSubs(aUsed, aToolsForUsed, theFuzzy, theMakeShapeList, theError) + && ::cutSubs(aNotUsed, aToolsForUnused, theFuzzy, theMakeShapeList, theError); if (isOk) { theUsed.insert(theUsed.end(), aUsed.begin(), aUsed.end()); theNotUsed.insert(theNotUsed.end(), aNotUsed.begin(), aNotUsed.end()); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.h b/src/FeaturesPlugin/FeaturesPlugin_Partition.h index 59cd77421..1448ff724 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.h @@ -46,6 +46,13 @@ public: return MY_BASE_OBJECTS_ID; } + /// Attribute name of fuzzy parameter. + inline static const std::string& FUZZY_PARAM_ID() + { + static const std::string MY_FUZZY_PARAM_ID("fuzzy_param"); + return MY_FUZZY_PARAM_ID; + } + /// \return the kind of a feature. FEATURESPLUGIN_EXPORT virtual const std::string& getKind() { @@ -76,6 +83,7 @@ private: bool cutSubs(GeomAPI_ShapeHierarchy& theHierarchy, ListOfShape& theUsed, ListOfShape& theNotUsed, + const double theFuzzy, std::shared_ptr& theMakeShapeList, std::string& theError); }; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp index 192e15e75..9627e7bf0 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp @@ -29,10 +29,12 @@ #include #include +#include #include #include #include + //================================================================================================= FeaturesPlugin_Union::FeaturesPlugin_Union() { @@ -42,6 +44,13 @@ FeaturesPlugin_Union::FeaturesPlugin_Union() void FeaturesPlugin_Union::initAttributes() { data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + // Initialize the fuzzy parameter with a value below Precision::Confusion() to indicate, + // that the internal algorithms should use their default fuzzy value, if none was specified + // by the user. + real(FUZZY_PARAM_ID())->setValue(1.e-8); + initVersion(BOP_VERSION_9_4(), selectionList(BASE_OBJECTS_ID())); } @@ -60,6 +69,10 @@ void FeaturesPlugin_Union::execute() return; } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + double aFuzzy = real(FUZZY_PARAM_ID())->value(); + std::string anError; int aResultIndex = 0; std::vector aResultBaseAlgoList; @@ -81,12 +94,14 @@ void FeaturesPlugin_Union::execute() // compsolid handling isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_FUSE, anObjects, aParent, anEmptyList, anEmptyList, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } else { // process object as is isOk = processObject(GeomAlgoAPI_Tools::BOOL_FUSE, anObject, anEmptyList, anEmptyList, + aFuzzy, aResultIndex, aResultBaseAlgoList, aResultShapesList, aResultCompound); } diff --git a/src/FeaturesPlugin/FeaturesPlugin_Union.h b/src/FeaturesPlugin/FeaturesPlugin_Union.h index 99b7369a5..52688310a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Union.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Union.h @@ -43,6 +43,13 @@ public: return MY_BASE_OBJECTS_ID; } + /// Attribute name of fuzzy parameter. + inline static const std::string& FUZZY_PARAM_ID() + { + static const std::string MY_FUZZY_PARAM_ID("fuzzy_param"); + return MY_FUZZY_PARAM_ID; + } + /// \return the kind of a feature. FEATURESPLUGIN_EXPORT virtual const std::string& getKind() { diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp index 3270605e8..e748063bb 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.cpp @@ -46,10 +46,13 @@ #include #include + +//================================================================================================= static void performBoolean(const GeomAlgoAPI_Tools::BOPType theBooleanType, GeomMakeShapePtr& theBooleanAlgo, const ListOfShape& theObjects, - const ListOfShape& theTools) + const ListOfShape& theTools, + const double theFuzzy) { if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) theBooleanAlgo.reset(new GeomAlgoAPI_Partition(theObjects, theTools)); @@ -62,11 +65,11 @@ static void performBoolean(const GeomAlgoAPI_Tools::BOPType theBooleanType, ListOfShape anObjects = theObjects; ListOfShape aTools; aTools.splice(aTools.begin(), anObjects, anObjects.begin()); - theBooleanAlgo.reset(new GeomAlgoAPI_Boolean(anObjects, aTools, theBooleanType)); + theBooleanAlgo.reset(new GeomAlgoAPI_Boolean(anObjects, aTools, theBooleanType, theFuzzy)); } } else - theBooleanAlgo.reset(new GeomAlgoAPI_Boolean(theObjects, theTools, theBooleanType)); + theBooleanAlgo.reset(new GeomAlgoAPI_Boolean(theObjects, theTools, theBooleanType, theFuzzy)); } } @@ -122,6 +125,7 @@ bool FeaturesPlugin_VersionedBoolean::processObject( const GeomShapePtr& theObject, const ListOfShape& theTools, const ListOfShape& thePlanes, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, @@ -140,11 +144,12 @@ bool FeaturesPlugin_VersionedBoolean::processObject( aToolsWithPlanes.insert(aToolsWithPlanes.end(), aPlanesCopy.begin(), aPlanesCopy.end()); if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) - aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes)); + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes, theFuzzy)); else aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, aToolsWithPlanes, - theBooleanType)); + theBooleanType, + theFuzzy)); // Checking that the algorithm worked properly. std::string anError; @@ -214,6 +219,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( const GeomShapePtr& theCompsolid, const ListOfShape& theTools, const ListOfShape& thePlanes, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, @@ -232,7 +238,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( aToolsWithPlanes.insert(aToolsWithPlanes.end(), aPlanesCopy.begin(), aPlanesCopy.end()); std::shared_ptr aBoolAlgo; - performBoolean(theBooleanType, aBoolAlgo, aUsedInOperationSolids, aToolsWithPlanes); + performBoolean(theBooleanType, aBoolAlgo, aUsedInOperationSolids, aToolsWithPlanes, theFuzzy); // Checking that the algorithm worked properly. std::string anError; @@ -251,7 +257,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompsolid( ListOfShape aShapesToAdd = aNotUsedSolids; aShapesToAdd.push_back(aBoolAlgo->shape()); std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true, theFuzzy)); if (!aFillerAlgo->isDone()) { std::string aFeatureError = "Error: PaveFiller algorithm failed."; setError(aFeatureError); @@ -308,6 +314,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompound( GeomAPI_ShapeHierarchy& theCompoundHierarchy, const GeomShapePtr& theCompound, const ListOfShape& theTools, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, @@ -324,7 +331,7 @@ bool FeaturesPlugin_VersionedBoolean::processCompound( std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); std::shared_ptr aBoolAlgo; - performBoolean(theBooleanType, aBoolAlgo, aUsedInOperationShapes, theTools); + performBoolean(theBooleanType, aBoolAlgo, aUsedInOperationShapes, theTools, theFuzzy); // Checking that the algorithm worked properly. std::string anError; diff --git a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h index eb5336fa1..e58945733 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_VersionedBoolean.h @@ -70,6 +70,7 @@ protected: const GeomShapePtr& theObject, const ListOfShape& theTools, const ListOfShape& thePlanes, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, @@ -84,6 +85,7 @@ protected: const GeomShapePtr& theCompsolid, const ListOfShape& theTools, const ListOfShape& thePlanes, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, @@ -97,6 +99,7 @@ protected: GeomAPI_ShapeHierarchy& theCompoundHierarchy, const GeomShapePtr& theCompound, const ListOfShape& theTools, + const double theFuzzy, int& theResultIndex, std::vector& theResultBaseAlgoList, ListOfShape& theResultShapesList, diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts index 18459cc64..41fa7dca7 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts @@ -344,6 +344,17 @@ Objets outils + + Common:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + Model_Data @@ -397,6 +408,17 @@ Objets outils + + Cut:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -1231,6 +1253,17 @@ Objets outils + + Fuse:fuzzy_param + + Fuzzy Parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -1294,6 +1327,17 @@ Sélectionner des objets. + + Intersection:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -1337,6 +1381,17 @@ Sélectionner des objets pour le partitionnement. + + Partition:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -2454,6 +2509,17 @@ Objets outils + + Smash:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -2496,6 +2562,17 @@ Objets outils + + Split:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -2520,6 +2597,17 @@ Sélectionner les solides pour la réunion. + + Union:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + @@ -3994,6 +4082,17 @@ La forme sélectionnée est du mauvais type. + + Boolean:fuzzy_param + + Fuzzy parameter + Paramètre flou + + + Additional tolerance to eliminate tiny result. + Tolérance supplémentaire pour éliminer les petits résultats. + + Boolean:GeomValidators_BooleanArguments diff --git a/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts b/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts index 3b2c6196a..d04a6bd01 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts +++ b/src/FeaturesPlugin/FeaturesPlugin_msg_ru.ts @@ -109,7 +109,7 @@ Error: Empty shape. Выбранные вспомогательные объекты невалидны. - + Error: Local selection not allowed. Локальная селекция запрещена. @@ -119,6 +119,17 @@ Выбраныне вспомогательные объекты имеют недопустимый тип. + + Boolean:fuzzy_param + + Fuzzy parameter + Нечеткий параметр + + + Additional tolerance to eliminate tiny result. + Дополнительный допуск для устранения крошечного результата. + + Boolean:GeomValidators_BooleanArguments diff --git a/src/FeaturesPlugin/Test/TestBooleanCommon_Fuzzy.py b/src/FeaturesPlugin/Test/TestBooleanCommon_Fuzzy.py new file mode 100644 index 000000000..9d01e2482 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestBooleanCommon_Fuzzy.py @@ -0,0 +1,80 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_fuzzy = model.addParameter(Part_1_doc, "fuzzy", '1e-06') + +### Create Sphere +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 5) + +### Create Point +Point_2 = model.addPoint(Part_1_doc, 9.999995, 0, 0) + +### Create Sphere +Sphere_2 = model.addSphere(Part_1_doc, model.selection("VERTEX", "Point_1"), 5) + +### Create Common +Common_1 = model.addCommon(Part_1_doc, [model.selection("SOLID", "Sphere_2_1"), model.selection("SOLID", "Sphere_1_1")], fuzzyParam = "fuzzy", keepSubResults = True) +model.do() + +model.testNbResults(Common_1, 1) +model.testNbSubResults(Common_1, [0]) +testNbUniqueSubShapes(Common_1, GeomAPI_Shape.SOLID, [1]) +testNbUniqueSubShapes(Common_1, GeomAPI_Shape.FACE, [3]) +testNbUniqueSubShapes(Common_1, GeomAPI_Shape.EDGE, [3]) +testNbUniqueSubShapes(Common_1, GeomAPI_Shape.VERTEX, [2]) + +### Set a higher fuzzy value +Param_fuzzy.setValue(1.e-5) +model.do() + +model.end() + +model.testNbResults(Common_1, 0) + +model.end() diff --git a/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_1.py b/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_1.py new file mode 100644 index 000000000..d880a3280 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_1.py @@ -0,0 +1,89 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_offset = model.addParameter(Part_1_doc, "offset", '5e-5') +Param_fuzzy = model.addParameter(Part_1_doc, "fuzzy", '1e-05') + +### Create Point +Point_2 = model.addPoint(Part_1_doc, "offset", "5", "5") + +### Create Box +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_1.result().setColor(255, 0, 0) + +### Create Cylinder +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("EDGE", "PartSet/OX"), 6, 13) +Cylinder_1.result().setColor(255, 255, 0) +Cylinder_1.result().setTransparency(0.6) + +### Create Cut +Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("SOLID", "Cylinder_1_1")], fuzzyParam = "fuzzy", keepSubResults = True) +model.do() + +model.testNbResults(Cut_1, 1) +model.testNbSubResults(Cut_1, [0]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.SOLID, [1]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.FACE, [14]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.EDGE, [36]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Cut_1, [49.093623770546]) + +### Set a higher fuzzy value +Param_fuzzy.setValue(5.e-5) +model.do() + +model.end() + +model.testNbResults(Cut_1, 1) +model.testNbSubResults(Cut_1, [4]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.SOLID, [4]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.FACE, [20]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.EDGE, [36]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(Cut_1, [49.088834629314]) diff --git a/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_2.py b/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_2.py new file mode 100644 index 000000000..61a26425a --- /dev/null +++ b/src/FeaturesPlugin/Test/TestBooleanCut_Fuzzy_2.py @@ -0,0 +1,132 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_fuzzy = model.addParameter(Part_1_doc, "fuzzy", '1e-07') + +### Create Point +Point_2 = model.addPoint(Part_1_doc, 5, 9.9999, 0) + +### Create Point +Point_3 = model.addPoint(Part_1_doc, 10, 10, 0) + +### Create Sketch +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchLine_1 = Sketch_1.addLine(5, 0, 0, 0) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result()) +SketchLine_2 = Sketch_1.addLine(0, 0, 0, 9.9999) +SketchLine_3 = Sketch_1.addLine(0, 9.9999, 5, 9.9999) +SketchLine_4 = Sketch_1.addLine(5, 9.9999, 5, 0) +Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +Sketch_1.setHorizontal(SketchLine_1.result()) +Sketch_1.setVertical(SketchLine_2.result()) +Sketch_1.setHorizontal(SketchLine_3.result()) +Sketch_1.setVertical(SketchLine_4.result()) +SketchProjection_2 = Sketch_1.addProjection(model.selection("VERTEX", "Point_1"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchPoint_2.result()) +SketchProjection_3 = Sketch_1.addProjection(model.selection("VERTEX", "Point_2"), False) +SketchPoint_3 = SketchProjection_3.createdFeature() +model.do() + +### Create Sketch +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchLine_5 = Sketch_2.addLine(10, 0, 0, 0) +SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_4 = SketchProjection_4.createdFeature() +Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchPoint_4.result()) +SketchLine_6 = Sketch_2.addLine(0, 0, 0, 10) +SketchLine_7 = Sketch_2.addLine(0, 10, 10, 10) +SketchLine_8 = Sketch_2.addLine(10, 10, 10, 0) +Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint()) +Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint()) +Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint()) +Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint()) +Sketch_2.setHorizontal(SketchLine_5.result()) +Sketch_2.setVertical(SketchLine_6.result()) +Sketch_2.setHorizontal(SketchLine_7.result()) +Sketch_2.setVertical(SketchLine_8.result()) +SketchProjection_5 = Sketch_2.addProjection(model.selection("VERTEX", "Point_2"), False) +SketchPoint_5 = SketchProjection_5.createdFeature() +Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchPoint_5.result()) +model.do() + +### Create Face +Face_1 = model.addFace(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")]) +Face_1.result().setColor(255, 0, 0) + +### Create Face +Face_2 = model.addFace(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")]) +Face_2.result().setColor(0, 255, 0) + +### Create Cut +Cut_1 = model.addCut(Part_1_doc, [model.selection("FACE", "Face_2_1")], [model.selection("FACE", "Face_1_1")], fuzzyParam = "fuzzy", keepSubResults = True) +model.do() + +model.testNbResults(Cut_1, 1) +model.testNbSubResults(Cut_1, [0]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.FACE, [1]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.EDGE, [6]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.VERTEX, [6]) + +### Set a higher fuzzy value +Param_fuzzy.setValue(1.e-4) +model.do() + +model.end() + +model.testNbResults(Cut_1, 1) +model.testNbSubResults(Cut_1, [0]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.FACE, [1]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.EDGE, [4]) +testNbUniqueSubShapes(Cut_1, GeomAPI_Shape.VERTEX, [4]) diff --git a/src/FeaturesPlugin/Test/TestBooleanFuse_Fuzzy.py b/src/FeaturesPlugin/Test/TestBooleanFuse_Fuzzy.py new file mode 100644 index 000000000..6a8535664 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestBooleanFuse_Fuzzy.py @@ -0,0 +1,85 @@ +# Copyright (C) 2014-2022 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from salome.shaper import model +from GeomAPI import GeomAPI_Shape + +aShapeTypes = { + GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID", + GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE", + GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE", + GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"} + +def testNbUniqueSubShapes(theFeature, theShapeType, theExpectedNbSubShapes): + """ Tests number of unique feature sub-shapes of passed type for each result. + :param theFeature: feature to test. + :param theShapeType: shape type of sub-shapes to test. + :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()). + """ + aResults = theFeature.feature().results() + aNbResults = len(aResults) + aListSize = len(theExpectedNbSubShapes) + assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize) + for anIndex in range(0, aNbResults): + aNbResultSubShapes = 0 + anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex] + aNbResultSubShapes = aResults[anIndex].shape().subShapes(theShapeType, True).size() + assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes) + + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_fuzzy = model.addParameter(Part_1_doc, "fuzzy", '1e-07') + +Point_2 = model.addPoint(Part_1_doc, 10, 0, 0) +Point_3 = model.addPoint(Part_1_doc, 20, 10.0001, 10.0001) + +### Create Box +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + +### Create Box +Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("VERTEX", "Point_2")) + +### Create Fuse +Fuse_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1")], fuzzyParam = "fuzzy", keepSubResults = True) +model.do() + +model.testNbResults(Fuse_1, 1) +model.testNbSubResults(Fuse_1, [0]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [1]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.FACE, [11]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [24]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [15]) +model.testResultsVolumes(Fuse_1, [2000.02000010]) + +### Set a higher fuzzy value +Param_fuzzy.setValue(1.e-4) +model.do() + +model.end() + +model.testNbResults(Fuse_1, 1) +model.testNbSubResults(Fuse_1, [0]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.SOLID, [1]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.FACE, [10]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.EDGE, [20]) +testNbUniqueSubShapes(Fuse_1, GeomAPI_Shape.VERTEX, [12]) +model.testResultsVolumes(Fuse_1, [2000.02166677]) diff --git a/src/FeaturesPlugin/boolean_common_widget.xml b/src/FeaturesPlugin/boolean_common_widget.xml index ebf6cf1b1..c34682a3d 100644 --- a/src/FeaturesPlugin/boolean_common_widget.xml +++ b/src/FeaturesPlugin/boolean_common_widget.xml @@ -38,6 +38,17 @@ + + + + + diff --git a/src/FeaturesPlugin/boolean_fuse_widget.xml b/src/FeaturesPlugin/boolean_fuse_widget.xml index 8617460db..1e9635a60 100644 --- a/src/FeaturesPlugin/boolean_fuse_widget.xml +++ b/src/FeaturesPlugin/boolean_fuse_widget.xml @@ -38,6 +38,17 @@ + + + + + + + + + + diff --git a/src/FeaturesPlugin/boolean_split_widget.xml b/src/FeaturesPlugin/boolean_split_widget.xml index 2131c8dda..7db9399c1 100644 --- a/src/FeaturesPlugin/boolean_split_widget.xml +++ b/src/FeaturesPlugin/boolean_split_widget.xml @@ -19,5 +19,16 @@ + + + + + diff --git a/src/FeaturesPlugin/boolean_widget.xml b/src/FeaturesPlugin/boolean_widget.xml index dca9d22a9..222e8007e 100644 --- a/src/FeaturesPlugin/boolean_widget.xml +++ b/src/FeaturesPlugin/boolean_widget.xml @@ -19,6 +19,17 @@ + + + + + diff --git a/src/FeaturesPlugin/doc/booleanArguments.rst b/src/FeaturesPlugin/doc/booleanArguments.rst index ad2f3c307..1de32398b 100644 --- a/src/FeaturesPlugin/doc/booleanArguments.rst +++ b/src/FeaturesPlugin/doc/booleanArguments.rst @@ -68,3 +68,8 @@ Construction planes (mentioned PLANE) can be used in several operations, but not | |union.icon| | 3 (SOLIDs from COMPSOLID) | --- | | :ref:`featureUnion` | | | +-------------------------+---------------------------+-------------------------+ + +The fuzzy parameter of each boolean operation is used as an additional tolerance to eliminate tiny results. + +*Note*: If a value is given, which is smaller than the lowest meaningful tolerance of 1.e-7, the boolean operation +will use the default internal fuzzy parameter. diff --git a/src/FeaturesPlugin/doc/commonFeature.rst b/src/FeaturesPlugin/doc/commonFeature.rst index a63df77cd..e96f00124 100644 --- a/src/FeaturesPlugin/doc/commonFeature.rst +++ b/src/FeaturesPlugin/doc/commonFeature.rst @@ -39,14 +39,16 @@ Simple - **Objects** contains a list of objects selected in the Object Browser or in the Viewer. If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored. +- **Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. - **See preview** button shows a result of the operation. **TUI Command**: -.. py:function:: model.addCommon(Part_doc, objects) +.. py:function:: model.addCommon(Part_doc, objects, fuzzy) :param part: The current part object :param list: A list of objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object Result @@ -74,17 +76,19 @@ Advanced other objects (to avoid self-intersection) and added to the result. - **Tools** contains a list of objects selected in the Object Browser or in the Viewer, which will be intersected with tool objects. If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored. +- **Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. - **See preview** button shows a result of the operation. Any kind of shape is supported as an object or a tool of Common. Moreover, constructions planes can be selected as tools. **TUI Command**: -.. py:function:: model.addCommon(Part_doc, objects, tools) +.. py:function:: model.addCommon(Part_doc, objects, tools, fuzzy) :param part: The current part object :param list: A list of objects. :param list: A list of tools. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object Result diff --git a/src/FeaturesPlugin/doc/cutFeature.rst b/src/FeaturesPlugin/doc/cutFeature.rst index 9ce390dbe..6fe34e58e 100644 --- a/src/FeaturesPlugin/doc/cutFeature.rst +++ b/src/FeaturesPlugin/doc/cutFeature.rst @@ -26,17 +26,19 @@ The following property panel will be opened: - **Tool Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will cut main objects. Any kind of shape can be selected, including subshapes of compsolids/compounds. Non-selected subshapes from compsolids/compounds will be ignored. +- **Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. - **See preview** button shows a result of the operation. The minimal dimension of Tool Objects should be not less than the maximal dimension of Main Objects. **TUI Command**: -.. py:function:: model.addCut(Part_doc, mainObjects, toolObjects) +.. py:function:: model.addCut(Part_doc, mainObjects, toolObjects, fuzzy) :param part: The current part object :param list: A list of main objects. :param list: A list of tool objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object Result diff --git a/src/FeaturesPlugin/doc/fuseFeature.rst b/src/FeaturesPlugin/doc/fuseFeature.rst index e9fb69620..e3bed7114 100644 --- a/src/FeaturesPlugin/doc/fuseFeature.rst +++ b/src/FeaturesPlugin/doc/fuseFeature.rst @@ -40,15 +40,17 @@ Simple - **Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be fused to a single result. If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will cut the fuse shape then will be joined to the result. - **Remove intersection edges** - if enabled, edges that lie on the same surface will be removed. +- **Fuzzy Parameter** - defines the additional tolerance value used to eliminate tiny results. - **See preview** - button shows a result of the operation. **TUI Command**: -.. py:function:: model.addFuse(Part_doc, objects, isRemoveEdges) +.. py:function:: model.addFuse(Part_doc, objects, isRemoveEdges, fuzzyParam) :param part: The current part object. :param list: A list of objects. :param boolean: Remove edges flag (optional). + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object. Result @@ -77,16 +79,18 @@ Advanced - **Tools** - contains a list of objects selected in the Object Browser or in the Viewer, which will be fused with tool objects. If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored. - **Remove intersection edges** - if enabled, edges that lie on the same surface will be removed. +- **Fuzzy Parameter** - defines the additional tolerance value used to eliminate tiny results. - **See preview** - button shows a result of the operation. **TUI Command**: -.. py:function:: model.addFuse(Part_doc, objects, tools, isRemoveEdges) +.. py:function:: model.addFuse(Part_doc, objects, tools, isRemoveEdges, fuzzyParam) :param part: The current part object. :param list: A list of objects. :param list: A list of tools. :param boolean: Remove edges flag (optional). + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object. Result diff --git a/src/FeaturesPlugin/doc/images/Partition.png b/src/FeaturesPlugin/doc/images/Partition.png index 70fb721a2..02499b2b9 100644 Binary files a/src/FeaturesPlugin/doc/images/Partition.png and b/src/FeaturesPlugin/doc/images/Partition.png differ diff --git a/src/FeaturesPlugin/doc/images/Smash.png b/src/FeaturesPlugin/doc/images/Smash.png index 2104b0381..1bcebe216 100644 Binary files a/src/FeaturesPlugin/doc/images/Smash.png and b/src/FeaturesPlugin/doc/images/Smash.png differ diff --git a/src/FeaturesPlugin/doc/images/Split_panel.png b/src/FeaturesPlugin/doc/images/Split_panel.png index 7673ef4a3..7d80c5f84 100644 Binary files a/src/FeaturesPlugin/doc/images/Split_panel.png and b/src/FeaturesPlugin/doc/images/Split_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/boolean_common_advanced_property_panel.png b/src/FeaturesPlugin/doc/images/boolean_common_advanced_property_panel.png index 3a28dcb46..879ea0075 100644 Binary files a/src/FeaturesPlugin/doc/images/boolean_common_advanced_property_panel.png and b/src/FeaturesPlugin/doc/images/boolean_common_advanced_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/boolean_common_simple_property_panel.png b/src/FeaturesPlugin/doc/images/boolean_common_simple_property_panel.png index 3a7577ee8..0a592579c 100644 Binary files a/src/FeaturesPlugin/doc/images/boolean_common_simple_property_panel.png and b/src/FeaturesPlugin/doc/images/boolean_common_simple_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/boolean_cut_property_panel.png b/src/FeaturesPlugin/doc/images/boolean_cut_property_panel.png index ba79dd142..696067fd4 100644 Binary files a/src/FeaturesPlugin/doc/images/boolean_cut_property_panel.png and b/src/FeaturesPlugin/doc/images/boolean_cut_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/boolean_fuse_advanced_property_panel.png b/src/FeaturesPlugin/doc/images/boolean_fuse_advanced_property_panel.png index 6c218f94c..4dd19cba0 100644 Binary files a/src/FeaturesPlugin/doc/images/boolean_fuse_advanced_property_panel.png and b/src/FeaturesPlugin/doc/images/boolean_fuse_advanced_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/boolean_fuse_simple_property_panel.png b/src/FeaturesPlugin/doc/images/boolean_fuse_simple_property_panel.png index 48b017ef2..069eb59da 100644 Binary files a/src/FeaturesPlugin/doc/images/boolean_fuse_simple_property_panel.png and b/src/FeaturesPlugin/doc/images/boolean_fuse_simple_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/images/intersection_property_panel.png b/src/FeaturesPlugin/doc/images/intersection_property_panel.png index d3fd35333..b439ac3e4 100644 Binary files a/src/FeaturesPlugin/doc/images/intersection_property_panel.png and b/src/FeaturesPlugin/doc/images/intersection_property_panel.png differ diff --git a/src/FeaturesPlugin/doc/intersectionFeature.rst b/src/FeaturesPlugin/doc/intersectionFeature.rst index e4057a2d5..20731bb07 100644 --- a/src/FeaturesPlugin/doc/intersectionFeature.rst +++ b/src/FeaturesPlugin/doc/intersectionFeature.rst @@ -19,16 +19,20 @@ The following property panel will be opened: **Intersection operation** -**Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be intersected. +**Objects** - contains a list of objects selected in the Object Browser or in the Viewer, which will be intersected. -All intersected objects should be 1- or 2-dimensional (edges, faces, shells). However, it is allowed to select 3-dimensional objects, but only their shells will be taken into operation. +**Fuzzy Parameter** - defines the additional tolerance value used to eliminate tiny results. + +All intersected objects should be 1- or 2-dimensional (edges, faces, shells). However, it is allowed to select +3-dimensional objects, but only their shells will be taken into operation. **TUI Command**: -.. py:function:: model.addIntersection(Part_doc, Objects) +.. py:function:: model.addIntersection(Part_doc, Objects, fuzzy) :param part: The current part object. :param list: A list of objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object. Result diff --git a/src/FeaturesPlugin/doc/partitionFeature.rst b/src/FeaturesPlugin/doc/partitionFeature.rst index e549310d2..1e8f3f34d 100644 --- a/src/FeaturesPlugin/doc/partitionFeature.rst +++ b/src/FeaturesPlugin/doc/partitionFeature.rst @@ -19,14 +19,19 @@ The following property panel will be opened: **Partition operation** -**Base Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be partitioned. Constuction planes are allowed too if at least one non-construction entity is selected. +**Base Objects** contains a list of objects selected in the Object Browser or in the Viewer, +which will be partitioned. Constuction planes are allowed too if at least one non-construction +entity is selected. + +**Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. **TUI Command**: -.. py:function:: model.addPartition(Part_doc, objects) +.. py:function:: model.addPartition(Part_doc, objects, fuzzy) :param part: The current part object. :param object: A list of objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Created object. Result diff --git a/src/FeaturesPlugin/doc/smashFeature.rst b/src/FeaturesPlugin/doc/smashFeature.rst index 2e3b45828..da77ad443 100644 --- a/src/FeaturesPlugin/doc/smashFeature.rst +++ b/src/FeaturesPlugin/doc/smashFeature.rst @@ -25,17 +25,19 @@ The following property panel will be opened: other objects (to avoid self intersection) and added to the result. - **Tool Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be smashed into main objects. If a subshape that belongs to a compsolid/compound was selected, other shapes of this compsolid/compound will be ignored. +- **Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. - **See preview** button shows a result of the operation. Main objects and Tools objects should have the same dimension. There are supported 2-dimensional (face) or 3-dimensional (solid, compsolid) arguments. **TUI Command**: -.. py:function:: model.addSmash(Part_doc, mainObjects, toolObjects) +.. py:function:: model.addSmash(Part_doc, mainObjects, toolObjects, fuzzy) :param part: The current part object. :param list: A list of main objects. :param list: A list of tool objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Rotated object. Result diff --git a/src/FeaturesPlugin/doc/splitFeature.rst b/src/FeaturesPlugin/doc/splitFeature.rst index d31bee857..eb5c49217 100644 --- a/src/FeaturesPlugin/doc/splitFeature.rst +++ b/src/FeaturesPlugin/doc/splitFeature.rst @@ -22,15 +22,17 @@ The following property panel will be opened: - **Main Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will be cut and splitted by tool objects. - **Tool Objects** contains a list of objects selected in the Object Browser or in the Viewer, which will cut and split the main objects. Construction planes may be selected too. +- **Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. - **See preview** button shows a result of the operation. **TUI Command**: -.. py:function:: model.addSplit(Part_doc, mainObjects, toolObjects) +.. py:function:: model.addSplit(Part_doc, mainObjects, toolObjects, fuzzy) :param part: The current part object. :param list: A list of main objects. :param list: A list of tool objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Result object. Result diff --git a/src/FeaturesPlugin/doc/unionFeature.rst b/src/FeaturesPlugin/doc/unionFeature.rst index 984764286..8bb04da46 100644 --- a/src/FeaturesPlugin/doc/unionFeature.rst +++ b/src/FeaturesPlugin/doc/unionFeature.rst @@ -23,16 +23,19 @@ The following property panel will be opened: Here it is necessary to select some objects. Only faces with shared edges or solids with shared faces are allowed for selection. +**Fuzzy Parameter** defines the additional tolerance value used to eliminate tiny results. + **Apply** button creates a union shape. **Cancel** button cancels the operation. **TUI Command**: -.. py:function:: model.addUnion(Part_doc, objects) +.. py:function:: model.addUnion(Part_doc, objects, fuzzy) :param part: The current part object. :param objects: A list of objects. + :param real: Additional tolerance used to eliminate tiny results (optional). :return: Result object. Result diff --git a/src/FeaturesPlugin/intersection_widget.xml b/src/FeaturesPlugin/intersection_widget.xml index bc07db630..bafcf1328 100644 --- a/src/FeaturesPlugin/intersection_widget.xml +++ b/src/FeaturesPlugin/intersection_widget.xml @@ -9,4 +9,15 @@ + + + + + diff --git a/src/FeaturesPlugin/partition_widget.xml b/src/FeaturesPlugin/partition_widget.xml index ad5e97ef5..6a2eda743 100644 --- a/src/FeaturesPlugin/partition_widget.xml +++ b/src/FeaturesPlugin/partition_widget.xml @@ -7,5 +7,16 @@ clear_in_neutral_point="false"> + + + + + diff --git a/src/FeaturesPlugin/tests.set b/src/FeaturesPlugin/tests.set index 3186ba368..75aabe51e 100644 --- a/src/FeaturesPlugin/tests.set +++ b/src/FeaturesPlugin/tests.set @@ -538,6 +538,10 @@ SET(TEST_NAMES_PARA TestGlueFaces_Solids.py TestLimitTolerance.py TestLimitTolerance_Face.py + TestBooleanCut_Fuzzy_1.py + TestBooleanCut_Fuzzy_2.py + TestBooleanFuse_Fuzzy.py + TestBooleanCommon_Fuzzy.py ) SET(TEST_NAMES_SEQ diff --git a/src/FeaturesPlugin/union_widget.xml b/src/FeaturesPlugin/union_widget.xml index 6bbc32395..f8676877b 100644 --- a/src/FeaturesPlugin/union_widget.xml +++ b/src/FeaturesPlugin/union_widget.xml @@ -7,6 +7,17 @@ concealment="true"> + + + + + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp index 2812b0ee1..6e3c60df1 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp @@ -27,42 +27,47 @@ #include #include + //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const GeomShapePtr theTool, - const GeomAlgoAPI_Tools::BOPType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy/*= 1.e-8*/) { ListOfShape aListWithObject, aListWithTool; aListWithObject.push_back(theObject); aListWithTool.push_back(theTool); - build(aListWithObject, aListWithTool, theOperationType); + build(aListWithObject, aListWithTool, theOperationType, theFuzzy); } //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy/*= 1.e-8*/) { ListOfShape aListWithObject; aListWithObject.push_back(theObject); - build(aListWithObject, theTools, theOperationType); + build(aListWithObject, theTools, theOperationType, theFuzzy); } //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy/*= 1.e-8*/) { - build(theObjects, theTools, theOperationType); + build(theObjects, theTools, theOperationType, theFuzzy); } //================================================================================================= void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy) { - if(theObjects.empty() || theTools.empty()) { + if (theObjects.empty() || theTools.empty()) { return; } @@ -111,7 +116,9 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, aBuilder->SetRunParallel(bRunParallel); // Set fuzzy value to eliminate thin results - static const Standard_Real aFuzzy = 1.e-5; + // => Either use the value set by the user (greater or equal than minimum valid value 1.e-7) + // => or use the old default value of 1.e-5 + Standard_Real aFuzzy = (theFuzzy >= 1.e-7 ? theFuzzy : 1.e-5); aBuilder->SetFuzzyValue(aFuzzy); // Building and getting result. @@ -139,11 +146,13 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, this->setDone(true); } +//================================================================================================= static bool isHistoryType(TopAbs_ShapeEnum theType) { return theType == TopAbs_VERTEX || theType == TopAbs_EDGE || theType == TopAbs_FACE || theType == TopAbs_SOLID; } +//================================================================================================= /// searches the corresponding result for theOld static void searchResult(const TopoDS_Shape& theOld, const TopoDS_Shape& theResult, BOPAlgo_BOP* theBuilder, TopTools_MapOfShape& theNews) @@ -179,6 +188,7 @@ static void searchResult(const TopoDS_Shape& theOld, const TopoDS_Shape& theResu } } +//================================================================================================= // check the shape is on the higher level of compound or compsolid bool isInComp(const TopoDS_Shape& theComp, const TopoDS_Shape& theShape) { if (theComp.ShapeType() == TopAbs_COMPOUND || theComp.ShapeType() == TopAbs_COMPSOLID) { diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h index f1c86be08..0182ff054 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h @@ -34,20 +34,41 @@ class GeomAlgoAPI_Boolean : public GeomAlgoAPI_MakeShape public: /// Constructor. + /// \param[in] theObject the main object. + /// \param[in] theTool the tool object. + /// \param[in] theOperationType type of boolean operation. + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// boolean operation will use a default additional tolerance value of 1.e-5. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const GeomShapePtr theTool, - const GeomAlgoAPI_Tools::BOPType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy = 1.e-8); /// Constructor. + /// \param[in] theObject the main object. + /// \param[in] theTools list of tools. + /// \param[in] theOperationType type of boolean operation. + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// boolean operation will use a default additional tolerance value of 1.e-5. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy = 1.e-8); /// Constructor. + /// \param[in] theObjects list of main objects. + /// \param[in] theTools list of tools. + /// \param[in] theOperationType type of boolean operation. + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// boolean operation will use a default additional tolerance value of 1.e-5. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const ListOfShape& theObjects, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy = 1.e-8); /// Redefinition of the generic method for the Fuse problem: OCCT 30481 GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape, @@ -57,7 +78,8 @@ private: /// Builds resulting shape. void build(const ListOfShape& theObjects, const ListOfShape& theTools, - const GeomAlgoAPI_Tools::BOPType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType, + const double theFuzzy); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp index 4958c3248..8ab6a1b07 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.cpp @@ -24,19 +24,22 @@ #include #include + //================================================================================================== -GeomAlgoAPI_Intersection::GeomAlgoAPI_Intersection(const ListOfShape& theObjects) +GeomAlgoAPI_Intersection::GeomAlgoAPI_Intersection(const ListOfShape& theObjects, const double theFuzzy) : myFiller(0) { - build(theObjects); + build(theObjects, theFuzzy); } +//================================================================================================== GeomAlgoAPI_Intersection::~GeomAlgoAPI_Intersection() { if (myFiller) delete (BOPAlgo_PaveFiller*)myFiller; } + //================================================================================================== -void GeomAlgoAPI_Intersection::build(const ListOfShape& theObjects) +void GeomAlgoAPI_Intersection::build(const ListOfShape& theObjects, const double theFuzzy) { if (theObjects.empty()) { return; @@ -64,6 +67,7 @@ void GeomAlgoAPI_Intersection::build(const ListOfShape& theObjects) aDSFiller->SetRunParallel(false); aDSFiller->SetNonDestructive(false); aDSFiller->SetGlue(BOPAlgo_GlueOff); + if (theFuzzy >= 1.e-7) aDSFiller->SetFuzzyValue(theFuzzy); // optimization for the issue #2399 BOPAlgo_SectionAttribute theSecAttr(Standard_True, @@ -79,6 +83,7 @@ void GeomAlgoAPI_Intersection::build(const ListOfShape& theObjects) anOperation->SetArguments(anObjects); anOperation->SetRunParallel(false); anOperation->SetCheckInverted(true); + if (theFuzzy >= 1.e-7) anOperation->SetFuzzyValue(theFuzzy); anOperation->PerformWithFiller(*aDSFiller); // it references a filler fields, so keep the filler myFiller = 0; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h index 8762e2c0a..39228ebc3 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Intersection.h @@ -34,15 +34,18 @@ class GeomAlgoAPI_Intersection : public GeomAlgoAPI_MakeShape public: /// \brief Constructor. /// \param[in] theObjects list of objects. - /// \param[in] theTools list of tools. - GEOMALGOAPI_EXPORT GeomAlgoAPI_Intersection(const ListOfShape& theObjects); + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// algorithm will use the default internal fuzzy value from OCCT. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Intersection(const ListOfShape& theObjects, + const double theFuzzy = 1.e-8); /// Destructor to erase the filler GEOMALGOAPI_EXPORT virtual ~GeomAlgoAPI_Intersection(); private: /// Builds resulting shape. - void build(const ListOfShape& theObjects); + void build(const ListOfShape& theObjects, const double theFuzzy); }; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp index cfd2c967f..fe49e167a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp @@ -127,9 +127,10 @@ static void sortCompound(TopoDS_Shape& theCompound, GEOMAlgo_Splitter* theOperat //================================================================================================= GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects, - const ListOfShape& theTools) + const ListOfShape& theTools, + const double theFuzzy) { - build(theObjects, theTools); + build(theObjects, theTools, theFuzzy); } static void prepareShapes(const TopoDS_Shape& theShape, @@ -150,7 +151,8 @@ static void prepareShapes(const TopoDS_Shape& theShape, //================================================================================================= void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, - const ListOfShape& theTools) + const ListOfShape& theTools, + const double theFuzzy) { if (theObjects.empty()) { return; @@ -200,6 +202,8 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, Standard_Boolean bRunParallel = Standard_True; anOperation->SetRunParallel(bRunParallel); + if (theFuzzy >= 1.e-7) anOperation->SetFuzzyValue(theFuzzy); + // Building and getting result. anOperation->Perform(); if (anOperation->HasErrors()) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.h b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.h index 5676a660b..b04982ad2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.h @@ -32,13 +32,20 @@ class GeomAlgoAPI_Partition : public GeomAlgoAPI_MakeShape { public: /// Constructor. + /// \param[in] theObjects list of main objects. + /// \param[in] theTools list of tools. + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// algorithm will use the default internal fuzzy value from OCCT. GEOMALGOAPI_EXPORT GeomAlgoAPI_Partition(const ListOfShape& theObjects, - const ListOfShape& theTools); + const ListOfShape& theTools, + const double theFuzzy = 1.e-8); private: /// Builds resulting shape. void build(const ListOfShape& theObjects, - const ListOfShape& theTools); + const ListOfShape& theTools, + const double theFuzzy); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp index 1ac8829a2..3801c8064 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp @@ -27,17 +27,20 @@ #include #include + //================================================================================================= GeomAlgoAPI_PaveFiller::GeomAlgoAPI_PaveFiller(const ListOfShape& theListOfShape, - const bool theIsMakeCompSolids) + const bool theIsMakeCompSolids, + const double theFuzzy) { - build(theListOfShape, theIsMakeCompSolids); + build(theListOfShape, theIsMakeCompSolids, theFuzzy); } //================================================================================================= void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape, - const bool theIsMakeCompSolids) + const bool theIsMakeCompSolids, + const double theFuzzy) { BOPAlgo_PaveFiller* aPaveFiller = new BOPAlgo_PaveFiller; TopTools_ListOfShape aListOfShape; @@ -53,6 +56,7 @@ void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape, } } aPaveFiller->SetArguments(aListOfShape); + if (theFuzzy >= 1.e-7) aPaveFiller->SetFuzzyValue(theFuzzy); aPaveFiller->Perform(); if (aPaveFiller->HasErrors()) return; @@ -61,6 +65,7 @@ void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape, this->setImpl(aBuilder); this->setBuilderType(OCCT_BOPAlgo_Builder); aBuilder->SetArguments(aListOfShape); + if (theFuzzy >= 1.e-7) aBuilder->SetFuzzyValue(theFuzzy); aBuilder->PerformWithFiller(*aPaveFiller); if (aBuilder->HasErrors()) return; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h index f068642d8..913c2960f 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.h @@ -35,12 +35,16 @@ public: /// \brief Constructor. /// \param[in] theListOfShape list of shape which should be splitted. /// \param[in] theIsMakeCompSolids if true gather shapes with shared faces to compsolids. + /// \param[in] theFuzzy additional tolerance value. + /// If the fuzzy value is below the minimum tolerance value (1.e-7), the + /// algorithm will use the default internal fuzzy value from OCCT. GEOMALGOAPI_EXPORT GeomAlgoAPI_PaveFiller(const ListOfShape& theListOfShape, - const bool theIsMakeCompSolids = false); + const bool theIsMakeCompSolids = false, + const double theFuzzy = 1.e-8); private: /// Builds resulting shape. - void build(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids); + void build(const ListOfShape& theListOfShape, const bool theIsMakeCompSolids, const double theFuzzy); }; #endif