From 631375bfe684e0eb11834499c88e835da7ff9d13 Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 20 May 2019 15:52:19 +0300 Subject: [PATCH] Task #2924 implementation : Ability to remove a result --- src/FeaturesAPI/CMakeLists.txt | 2 + src/FeaturesAPI/FeaturesAPI.i | 2 + src/FeaturesAPI/FeaturesAPI_RemoveResults.cpp | 74 +++++++++++++++++++ src/FeaturesAPI/FeaturesAPI_RemoveResults.h | 73 ++++++++++++++++++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesPlugin/CMakeLists.txt | 5 ++ src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 3 + .../FeaturesPlugin_RemoveResults.cpp | 33 +++++++++ .../FeaturesPlugin_RemoveResults.h | 67 +++++++++++++++++ .../Test/TestRemoveResultsBody.py | 38 ++++++++++ .../Test/TestRemoveResultsConstruction.py | 38 ++++++++++ .../Test/TestRemoveResultsPart.py | 32 ++++++++ src/FeaturesPlugin/plugin-Features.xml | 3 + src/Model/Model_AttributeSelection.cpp | 3 +- src/Model/Model_Data.cpp | 12 ++- src/Model/Model_Document.cpp | 12 +++ src/Model/Model_ResultBody.cpp | 4 +- src/Model/Model_ResultBody.h | 2 +- src/Model/Model_ResultConstruction.cpp | 7 +- src/Model/Model_ResultConstruction.h | 4 +- src/ModelAPI/ModelAPI_Result.cpp | 2 +- src/ModelAPI/ModelAPI_Result.h | 2 +- src/ModelAPI/ModelAPI_Tools.cpp | 24 ++++++ src/ModelAPI/ModelAPI_Tools.h | 4 + src/ModuleBase/ModuleBase_Tools.cpp | 2 + src/ModuleBase/ModuleBase_Tools.h | 20 ++--- src/PythonAPI/model/dump/DumpAssistant.py | 6 +- src/PythonAPI/model/features/__init__.py | 1 + src/XGUI/XGUI_ContextMenuMgr.cpp | 6 +- src/XGUI/XGUI_Workshop.cpp | 23 ++++-- 30 files changed, 471 insertions(+), 34 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_RemoveResults.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_RemoveResults.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_RemoveResults.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_RemoveResults.h create mode 100644 src/FeaturesPlugin/Test/TestRemoveResultsBody.py create mode 100644 src/FeaturesPlugin/Test/TestRemoveResultsConstruction.py create mode 100644 src/FeaturesPlugin/Test/TestRemoveResultsPart.py diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 23cdb1c47..9311f491d 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -37,6 +37,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Pipe.h FeaturesAPI_Placement.h FeaturesAPI_Recover.h + FeaturesAPI_RemoveResults.h FeaturesAPI_RemoveSubShapes.h FeaturesAPI_Revolution.h FeaturesAPI_RevolutionBoolean.h @@ -65,6 +66,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Pipe.cpp FeaturesAPI_Placement.cpp FeaturesAPI_Recover.cpp + FeaturesAPI_RemoveResults.cpp FeaturesAPI_RemoveSubShapes.cpp FeaturesAPI_Revolution.cpp FeaturesAPI_RevolutionBoolean.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index d9082cc25..35bdfcefc 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -66,6 +66,7 @@ %shared_ptr(FeaturesAPI_Translation) %shared_ptr(FeaturesAPI_Union) %shared_ptr(FeaturesAPI_FusionFaces) +%shared_ptr(FeaturesAPI_RemoveResults) // all supported interfaces %include "FeaturesAPI_BooleanCut.h" @@ -93,3 +94,4 @@ %include "FeaturesAPI_Translation.h" %include "FeaturesAPI_Union.h" %include "FeaturesAPI_FusionFaces.h" +%include "FeaturesAPI_RemoveResults.h" diff --git a/src/FeaturesAPI/FeaturesAPI_RemoveResults.cpp b/src/FeaturesAPI/FeaturesAPI_RemoveResults.cpp new file mode 100644 index 000000000..ba5447840 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_RemoveResults.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2014-2019 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 +// + +#include "FeaturesAPI_RemoveResults.h" + +#include +#include + + +//================================================================================================== +FeaturesAPI_RemoveResults::FeaturesAPI_RemoveResults( + const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{} + +//================================================================================================== +FeaturesAPI_RemoveResults::FeaturesAPI_RemoveResults( + const std::shared_ptr& theFeature, + const std::list& theResults) +: ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + setRemoved(theResults); + } +} + +//================================================================================================== +FeaturesAPI_RemoveResults::~FeaturesAPI_RemoveResults() +{} + +//================================================================================================== +void FeaturesAPI_RemoveResults::setRemoved( + const std::list& theResults) +{ + fillAttribute(theResults, myremoved); +} + +//================================================================================================== +void FeaturesAPI_RemoveResults::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrResults = + aBase->selectionList(FeaturesPlugin_RemoveResults::RESULTS_ID()); + + theDumper << aBase << " = model.addRemoveResults(" + << aDocName << ", " << anAttrResults << ")" << std::endl; +} + +//================================================================================================== +RemoveResultsPtr addRemoveResults(const std::shared_ptr& thePart, + const std::list& theResults) +{ + std::shared_ptr aFeature = + thePart->addFeature(FeaturesAPI_RemoveResults::ID()); + return RemoveResultsPtr(new FeaturesAPI_RemoveResults(aFeature, theResults)); +} diff --git a/src/FeaturesAPI/FeaturesAPI_RemoveResults.h b/src/FeaturesAPI/FeaturesAPI_RemoveResults.h new file mode 100644 index 000000000..926742851 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_RemoveResults.h @@ -0,0 +1,73 @@ +// Copyright (C) 2014-2019 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 +// + +#ifndef FeaturesAPI_RemoveResults_H_ +#define FeaturesAPI_RemoveResults_H_ + +#include "FeaturesAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_RemoveResults +/// \ingroup CPPHighAPI +/// \brief Interface for RemoveResults feature. +class FeaturesAPI_RemoveResults: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_RemoveResults(const std::shared_ptr& theFeature); + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_RemoveResults(const std::shared_ptr& theFeature, + const std::list& theResults); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_RemoveResults(); + + INTERFACE_1(FeaturesPlugin_RemoveResults::ID(), + removed, FeaturesPlugin_RemoveResults::RESULTS_ID(), + ModelAPI_AttributeSelectionList, /** Results to remove */) + + /// Modify removed results arguments. + FEATURESAPI_EXPORT + void setRemoved(const std::list& theResults); + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer on RemoveResults object. +typedef std::shared_ptr RemoveResultsPtr; + +/// \ingroup CPPHighAPI +/// \brief Create RemoveResults feature. +FEATURESAPI_EXPORT +RemoveResultsPtr addRemoveResults(const std::shared_ptr& thePart, + const std::list& theResults); + +#endif // FeaturesAPI_RemoveResults_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index 6eeaf064b..f427c3f7d 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -48,5 +48,6 @@ #include "FeaturesAPI_Translation.h" #include "FeaturesAPI_Union.h" #include "FeaturesAPI_FusionFaces.h" + #include "FeaturesAPI_RemoveResults.h" #endif // FeaturesAPI_swig_H_ diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 0ceae4e1c..26c65c2b2 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -59,6 +59,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_Fillet.h FeaturesPlugin_Measurement.h FeaturesPlugin_FusionFaces.h + FeaturesPlugin_RemoveResults.h ) SET(PROJECT_SOURCES @@ -99,6 +100,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_Fillet.cpp FeaturesPlugin_Measurement.cpp FeaturesPlugin_FusionFaces.cpp + FeaturesPlugin_RemoveResults.cpp ) SET(XML_RESOURCES @@ -495,4 +497,7 @@ ADD_UNIT_TESTS(TestExtrusion.py TestUnion_MultiLevelCompound_v0.py TestUnion_MultiLevelCompound_v20190506.py TestUnionFaces_v20190506.py + TestRemoveResultsBody.py + TestRemoveResultsConstruction.py + TestRemoveResultsPart.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 625381a19..9efa6c1fd 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -171,6 +172,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Fillet); } else if (theFeatureID == FeaturesPlugin_Measurement::ID()) { return FeaturePtr(new FeaturesPlugin_Measurement); + } else if (theFeatureID == FeaturesPlugin_RemoveResults::ID()) { + return FeaturePtr(new FeaturesPlugin_RemoveResults); } // feature of such kind is not found diff --git a/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.cpp b/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.cpp new file mode 100644 index 000000000..7c0b77d20 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.cpp @@ -0,0 +1,33 @@ +// Copyright (C) 2014-2019 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 +// + +#include "FeaturesPlugin_RemoveResults.h" + +#include + +//================================================================================================== +FeaturesPlugin_RemoveResults::FeaturesPlugin_RemoveResults() +{ +} + +//================================================================================================== +void FeaturesPlugin_RemoveResults::initAttributes() +{ + data()->addAttribute(RESULTS_ID(), ModelAPI_AttributeSelectionList::typeId()); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.h b/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.h new file mode 100644 index 000000000..7d9faf329 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_RemoveResults.h @@ -0,0 +1,67 @@ +// Copyright (C) 2014-2019 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 +// + +#ifndef FeaturesPlugin_RemoveResults_H_ +#define FeaturesPlugin_RemoveResults_H_ + +#include "FeaturesPlugin.h" + +#include + +/// \class FeaturesPlugin_RemoveResults +/// \ingroup Plugins +/// \brief AN internal, hidden feature for results removal. +class FeaturesPlugin_RemoveResults : public ModelAPI_Feature +{ +public: + /// Use plugin manager for features creation + FeaturesPlugin_RemoveResults(); + + /// Feature kind. + inline static const std::string& ID() + { + static const std::string MY_ID("RemoveResults"); + return MY_ID; + } + + /// Attribute name of removed shapes selector. + inline static const std::string& RESULTS_ID() + { + static const std::string MY_BASE_SHAPE_ID("results"); + return MY_BASE_SHAPE_ID; + } + + /// \return the kind of a feature. + FEATURESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = FeaturesPlugin_RemoveResults::ID(); + return MY_KIND; + } + + /// Request for initialization of data model of the feature: adding all attributes. + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Does nothing, has no results. + FEATURESPLUGIN_EXPORT virtual void execute() {} + + /// Hidden from the user. + FEATURESPLUGIN_EXPORT virtual bool isInHistory() {return false;} +}; + +#endif diff --git a/src/FeaturesPlugin/Test/TestRemoveResultsBody.py b/src/FeaturesPlugin/Test/TestRemoveResultsBody.py new file mode 100644 index 000000000..5ede10d2b --- /dev/null +++ b/src/FeaturesPlugin/Test/TestRemoveResultsBody.py @@ -0,0 +1,38 @@ +# Copyright (C) 2014-2019 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 + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchCircle_1 = Sketch_1.addCircle(0, 0, 2) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0) +RemoveResults_1 = model.addRemoveResults(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")]) +model.end() + +# check the number of bodies = 0, number of construction = 1 +from ModelAPI import * +assert(Part_1.document().size(ModelAPI_ResultConstruction.group()) == 1) +assert(Part_1.document().size(ModelAPI_ResultBody.group()) == 0) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestRemoveResultsConstruction.py b/src/FeaturesPlugin/Test/TestRemoveResultsConstruction.py new file mode 100644 index 000000000..ac8189981 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestRemoveResultsConstruction.py @@ -0,0 +1,38 @@ +# Copyright (C) 2014-2019 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 + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchCircle_1 = Sketch_1.addCircle(0, 0, 2) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0) +RemoveResults_1 = model.addRemoveResults(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")]) +model.end() + +# check the number of bodies = 1, number of construction = 0 +from ModelAPI import * +assert(Part_1.document().size(ModelAPI_ResultConstruction.group()) == 0) +assert(Part_1.document().size(ModelAPI_ResultBody.group()) == 1) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestRemoveResultsPart.py b/src/FeaturesPlugin/Test/TestRemoveResultsPart.py new file mode 100644 index 000000000..a8790d17f --- /dev/null +++ b/src/FeaturesPlugin/Test/TestRemoveResultsPart.py @@ -0,0 +1,32 @@ +# Copyright (C) 2014-2019 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 + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +model.do() +RemoveResults_1 = model.addRemoveResults(partSet, [model.selection("SHAPE", "Part_1/")]) +model.end() + +# check the number of parts = 0 +from ModelAPI import * +assert(Part_1.document().size(ModelAPI_ResultPart.group()) == 0) diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index eb72aa4e4..cec9dd59e 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -97,6 +97,9 @@ helpfile="recoverFeature.html"> + + + aResult; if (myRef.isInitialized()) { TDF_Label aSelLab = selectionLabel(); - if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape + // it is just reference to shape, not sub-shape + if (aSelLab.IsAttribute(kSIMPLE_REF_ID) || aSelLab.IsAttribute(kPART_REF_ID)) { ResultPtr aContext = context(); return aContext.get() != NULL; } diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 01315a892..5f867fca1 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -579,7 +580,7 @@ void Model_Data::addBackReference(FeaturePtr theFeature, std::string theAttrID, // be displayed and previewed; also for avoiding of quick show/hide on history // moving deep down if (aRes && !theFeature->isDisabled()) { - aRes->setIsConcealed(true); + aRes->setIsConcealed(true, theFeature->getKind() == "RemoveResults"); } } } @@ -604,8 +605,13 @@ void Model_Data::updateConcealmentFlag() std::shared_ptr aRes = std::dynamic_pointer_cast(myObject); if (aRes.get()) { - aRes->setIsConcealed(true); // set concealed - return; + if (aRes->groupName() != ModelAPI_ResultConstruction::group()) { + aRes->setIsConcealed(true); // set concealed + return; + } else if (aFeature->getKind() == "RemoveResults") { + aRes->setIsConcealed(true, true); + return; + } } } } diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 26cb173d5..082a6c60f 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1244,6 +1244,18 @@ void Model_Document::setCurrentFeature( } } } + if (theVisible) { // make RemoveResults feature be active even it is performed after the current + int anIndex = kUNDEFINED_FEATURE_INDEX; + FeaturePtr aNext = + theCurrent.get() ? myObjs->nextFeature(theCurrent, anIndex, false) : myObjs->firstFeature(); + for (; aNext.get(); aNext = myObjs->nextFeature(theCurrent, anIndex, false)) { + if (aNext->isInHistory()) { + break; // next in history is not needed + } else if (aNext->getKind() == "RemoveResults"){ + theCurrent = aNext; + } + } + } if (theCurrent.get()) { std::shared_ptr aData = std::static_pointer_cast(theCurrent->data()); if (!aData.get() || !aData->isValid()) { diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 1be002979..c5bedb6ba 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -157,10 +157,10 @@ bool Model_ResultBody::isConcealed() return myLastConcealed; } -void Model_ResultBody::setIsConcealed(const bool theValue) +void Model_ResultBody::setIsConcealed(const bool theValue, const bool theForced) { if (ModelAPI_ResultBody::isConcealed() != theValue) { - ModelAPI_ResultBody::setIsConcealed(theValue); + ModelAPI_ResultBody::setIsConcealed(theValue, theForced); updateConcealment(); } } diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index 8abd44089..663bf8cec 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -103,7 +103,7 @@ public: MODEL_EXPORT virtual bool isConcealed(); /// Sets all subs as concealed in the data tree (referenced by other objects) - MODEL_EXPORT virtual void setIsConcealed(const bool theValue); + MODEL_EXPORT virtual void setIsConcealed(const bool theValue, const bool theForced = false); /// Returns true is the topology is connected. MODEL_EXPORT virtual bool isConnectedTopology(); diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 041e8f226..9b5dd8729 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -216,9 +216,12 @@ std::shared_ptr Model_ResultConstruction::face(const int theIndex) return aResult; } -void Model_ResultConstruction::setIsConcealed(const bool theValue) +void Model_ResultConstruction::setIsConcealed(const bool theValue, const bool theForced) { - // do nothing: the construction element is never concealed + // the construction element may be concealed only by "delete" feature + if (!theValue || theForced) { + ModelAPI_ResultConstruction::setIsConcealed(theValue, theForced); + } } void Model_ResultConstruction::storeShape(std::shared_ptr theShape) diff --git a/src/Model/Model_ResultConstruction.h b/src/Model/Model_ResultConstruction.h index 8f7670158..a6913c4ae 100644 --- a/src/Model/Model_ResultConstruction.h +++ b/src/Model/Model_ResultConstruction.h @@ -63,8 +63,8 @@ class Model_ResultConstruction : public ModelAPI_ResultConstruction MODEL_EXPORT virtual bool isInfinite(); /// Sets the flag that it is infinite MODEL_EXPORT virtual void setInfinite(const bool theInfinite); - /// The construction element is never concealed - MODEL_EXPORT virtual void setIsConcealed(const bool theValue); + /// The construction element may be concealed only by "delete" feature + MODEL_EXPORT virtual void setIsConcealed(const bool theValue, const bool theForced = false); /// Updates the shape taking the current value from the data structure, returns true /// if update has been correctly done diff --git a/src/ModelAPI/ModelAPI_Result.cpp b/src/ModelAPI/ModelAPI_Result.cpp index c92a8ea3b..9e38ffb46 100644 --- a/src/ModelAPI/ModelAPI_Result.cpp +++ b/src/ModelAPI/ModelAPI_Result.cpp @@ -76,7 +76,7 @@ bool ModelAPI_Result::isConcealed() return myIsConcealed; } -void ModelAPI_Result::setIsConcealed(const bool theValue) +void ModelAPI_Result::setIsConcealed(const bool theValue, const bool theForced) { if (myIsConcealed != theValue) { myIsConcealed = theValue; diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index aee93eed6..81709e749 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -67,7 +67,7 @@ class ModelAPI_Result : public ModelAPI_Object MODELAPI_EXPORT virtual bool isConcealed(); /// Sets the result as concealed in the data tree (referenced by other objects) - MODELAPI_EXPORT virtual void setIsConcealed(const bool theValue); + MODELAPI_EXPORT virtual void setIsConcealed(const bool theValue, const bool theForced = false); /// Enables/disables the result. The disabled result does not participate in any calculation /// and visualization: like it was removed. But it keeps the general parameters: colors, diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index d09d215eb..c6b8a6f72 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -760,4 +761,27 @@ std::set getParents(const FeaturePtr& theFeature) return aParents; } +void removeResults(const std::list& theResults) +{ + // collect all documents where the results must be removed + std::map > aDocs; + + std::list::const_iterator aResIter = theResults.cbegin(); + for(; aResIter != theResults.cend(); aResIter++) { + DocumentPtr aDoc = (*aResIter)->document(); + if (!aDocs.count(aDoc)) + aDocs[aDoc] = std::list(); + aDocs[aDoc].push_back(*aResIter); + } + // create a "remove" feature in each doc + std::map >::iterator aDoc = aDocs.begin(); + for(; aDoc != aDocs.end(); aDoc++) { + FeaturePtr aRemove = aDoc->first->addFeature("RemoveResults"); + if (aRemove) { + for(aResIter = aDoc->second.cbegin(); aResIter != aDoc->second.cend(); aResIter++) + aRemove->selectionList("results")->append(*aResIter, GeomShapePtr()); + } + } +} + } // namespace ModelAPI_Tools diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index 1b2395351..6b4d31f84 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -205,6 +205,10 @@ MODELAPI_EXPORT std::pair getDefaultName( */ MODELAPI_EXPORT std::set > getParents(const std::shared_ptr& theFeature); + +/*! Creates a remove result features with the given results +*/ +MODELAPI_EXPORT void removeResults(const std::list >& theResults); } #endif diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index cdbd9202b..e49a994ff 100644 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -992,6 +992,8 @@ bool askToDelete(const std::set theFeatures, aLast = theReferencesToDelete.end(); for (; anIt != aLast; anIt++) { FeaturePtr aFeature = *anIt; + if (aFeature->getKind() == "RemoveResults") + continue; // skip the remove results feature mentioning: result will be removed anyway if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group())) aPartFeatureNames.append(aFeature->name().c_str()); else diff --git a/src/ModuleBase/ModuleBase_Tools.h b/src/ModuleBase/ModuleBase_Tools.h index 40058999f..4523b7d80 100644 --- a/src/ModuleBase/ModuleBase_Tools.h +++ b/src/ModuleBase/ModuleBase_Tools.h @@ -79,7 +79,7 @@ MODULEBASE_EXPORT void setFocus(QWidget* theWidget, const QString& theInfo = QSt /// Sets or removes the shadow effect to the widget /// \param theWidget a widget to be styled -/// \param isSetEffect if true, the shadow effect is set, overwise cleared +/// \param isSetEffect if true, the shadow effect is set, otherwise cleared /// \return resulting pixmap MODULEBASE_EXPORT void setShadowEffect(QWidget* theWidget, const bool isSetEffect); @@ -193,7 +193,7 @@ MODULEBASE_EXPORT void checkObjects(const QObjectPtrList& theObjects, bool& hasR /// Sets the default coeffient into the driver calculated accordingly the shape type. /// It provides 1.e-4 for results of construction type -/// \param theResult a result object to define the deviation coeffient +/// \param theResult a result object to define the deviation coefficient /// \param theDrawer a drawer //MODULEBASE_EXPORT void setDefaultDeviationCoefficient( // const std::shared_ptr& theResult, @@ -201,7 +201,7 @@ MODULEBASE_EXPORT void checkObjects(const QObjectPtrList& theObjects, bool& hasR /// Sets the default coeffient into the driver calculated accordingly the shape type. /// It provides 1.e-4 for a shape withe Edge shape type -/// \param theShape a shape to define the deviation coeffient, +/// \param theShape a shape to define the deviation coefficient, /// \param theDrawer a drawer MODULEBASE_EXPORT void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer); @@ -300,7 +300,7 @@ void MODULEBASE_EXPORT refsToFeatureInFeatureDocument(const ObjectPtr& theObject /// Returns true if the object if a sub child of the feature. The feature is casted to the -/// composite one. If it is possible, the sub object check happens. The method is applyed +/// composite one. If it is possible, the sub object check happens. The method is applied /// recursively to the feature subs. /// \param theObject a candidate to be a sub object /// \param theFeature a candidate to be a composite feature @@ -339,18 +339,18 @@ bool MODULEBASE_EXPORT askToDelete(const std::set aFeatures, std::set& theReferencesToDelete, const std::string& thePrefixInfo = ""); -/// Converts a list of objects to set of corresponded features. If object is result, it is ingored -/// because the feauture only might be removed. But if result is in a parameter group, the feature +/// Converts a list of objects to set of corresponded features. If object is result, it is ignored +/// because the feature only might be removed. But if result is in a parameter group, the feature /// of this parameter is to be removed /// \param theObjects a list of objects -/// \param theFeatures an out conteiner of features +/// \param theFeatures an out container of features void MODULEBASE_EXPORT convertToFeatures(const QObjectPtrList& theObjects, std::set& theFeatures); /// Converts a list of objects to set of folders. /// \param theObjects a list of objects -/// \param theFeatures an out conteiner of features +/// \param theFeatures an out container of features void MODULEBASE_EXPORT convertToFolders(const QObjectPtrList& theObjects, std::set& theFolders); @@ -358,14 +358,14 @@ void MODULEBASE_EXPORT convertToFolders(const QObjectPtrList& theObjects, /// Returns translation from the given data. /// If translation is not exists then it returns a string /// from the info data without translation -/// \param theMessage a message which dave to be translated +/// \param theMessage a message which have to be translated QString MODULEBASE_EXPORT translate(const Events_InfoMessage& theMessage); /// Returns translation from the given data. /// If translation is not exists then it returns a string /// from the info data without translation /// \param theContext context of the message (Feature Id) -/// \param theMessage a message which dave to be translated +/// \param theMessage a message which have to be translated QString MODULEBASE_EXPORT translate(const std::string& theContext, const std::string& theMessage); /// Set Highlighting of points as a Ball shape diff --git a/src/PythonAPI/model/dump/DumpAssistant.py b/src/PythonAPI/model/dump/DumpAssistant.py index 4e739a382..0b3eeb167 100644 --- a/src/PythonAPI/model/dump/DumpAssistant.py +++ b/src/PythonAPI/model/dump/DumpAssistant.py @@ -60,9 +60,9 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper): aFeatureKind = theFeature.getKind() if aFeatureKind in self.myFeatures: # Dump only feature created by user (in history). - # Also dump Export features (hard-coded here in order not to change the data model). + # Also dump Export and RemoveResults features (hard-coded here in order not to change the data model). # For all other features, just keep their name. - if theForce or theFeature.isInHistory() or aFeatureKind=="Export": + if theForce or theFeature.isInHistory() or aFeatureKind=="Export" or aFeatureKind=="RemoveResults": self.myFeatures[aFeatureKind](theFeature).dump(self) else: self.name(theFeature) @@ -98,4 +98,4 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper): return std_string() # Instance of dumper -dumper = DumpAssistant \ No newline at end of file +dumper = DumpAssistant diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 3e1e6bdc6..19f7b2ed0 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -30,3 +30,4 @@ from FeaturesAPI import addRecover from FeaturesAPI import addFillet from FeaturesAPI import addFusionFaces from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle +from FeaturesAPI import addRemoveResults diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index 0df020d32..22ec2603c 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -446,7 +446,7 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu() break; } if (!hasCompositeOwner && allActive ) { - if (hasFeature || hasParameter) + if (hasResult || hasFeature || hasParameter) // #2924 results can be erased action("DELETE_CMD")->setEnabled(true); } if (!hasCompositeOwner && allActive && (hasFeature|| hasParameter)) @@ -622,6 +622,8 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() aList.append(action("TRANSPARENCY_CMD")); #endif aList.append(action("SHOW_FEATURE_CMD")); + aList.append(mySeparator2); + aList.append(action("DELETE_CMD")); myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList; //------------------------------------- @@ -642,6 +644,8 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() aList.append(action("TRANSPARENCY_CMD")); #endif aList.append(action("SHOW_FEATURE_CMD")); + aList.append(mySeparator3); + aList.append(action("DELETE_CMD")); myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList; // Group menu myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index a7caf5007..4586610e2 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -922,7 +922,6 @@ void XGUI_Workshop::onOpen() //save current file before close if modified SessionPtr aSession = ModelAPI_Session::get(); if (aSession->isModified()) { - //TODO(sbh): re-launch the app? int anAnswer = QMessageBox::question( desktop(), tr("Save current file"), tr("The document is modified, save before opening another?"), @@ -1528,7 +1527,7 @@ void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget) // the property panel is active window of the desktop, when it is // hidden, it is undefined which window becomes active. By this reason // it is defined to perform the desktop as the active window. - // in SALOME mode, workstack made the PyConsole the active window, + // in SALOME mode, work-stack made the PyConsole the active window, // set the focus on it. As a result, shortcuts of the application, like // are processed by this console. For example Undo actions. // It is possible that this code is to be moved to SHAPER package @@ -1797,7 +1796,7 @@ void XGUI_Workshop::deleteObjects() bool hasFolder = false; ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasCompositeOwner, hasResultInHistory, hasFolder); - if (!(hasFeature || hasParameter || hasFolder)) + if (!(hasResult || hasFeature || hasParameter || hasFolder)) return; // delete objects @@ -1838,6 +1837,16 @@ void XGUI_Workshop::deleteObjects() } } } + // remove results selected + std::list aResults; + for(QObjectPtrList::const_iterator anIt = anObjects.begin(); anIt != anObjects.end(); anIt++) { + ResultPtr aRes = std::dynamic_pointer_cast(*anIt); + if (aRes.get() && aRes->data()->isValid() && !aRes->data()->isDeleted()) + aResults.push_back(aRes); + } + if (!aResults.empty()) { + ModelAPI_Tools::removeResults(aResults); + } if (aDone) operationMgr()->commitOperation(); @@ -1892,11 +1901,11 @@ void XGUI_Workshop::cleanHistory() ModelAPI_Tools::findAllReferences(aFeatures, aReferences, true, false); // find for each object whether all reference values are in the map as key, that means that there // is no other reference in the model to this object, so it might be removed by cleaning history - // sk_1(ext_1, vertex_1) + (sk_3, bool_1) - cann't be deleted, dependency to bool_1 - // ext_1(bool_1, sk_3) - cann't be deleted, dependency to bool_1 + // sk_1(ext_1, vertex_1) + (sk_3, bool_1) - can't be deleted, dependency to bool_1 + // ext_1(bool_1, sk_3) - can't be deleted, dependency to bool_1 // vertex_1() - // sk_2(ext_2) + (bool_1) - cann't be deleted, dependency to bool_1 - // ext_2(bool_1) - cann't be deleted, dependency to bool_1 + // sk_2(ext_2) + (bool_1) - can't be deleted, dependency to bool_1 + // ext_2(bool_1) - can't be deleted, dependency to bool_1 // sk_3() // Information: bool_1 is not selected std::set anUnusedObjects; -- 2.39.2