From: azv Date: Thu, 8 Aug 2019 10:14:38 +0000 (+0300) Subject: Task 2.5. Combination operations on Groups (issue #2935) X-Git-Tag: VEDF2019Lot4~59^2~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a03154b7e20e00019312382750069c1c2617199d;p=modules%2Fshaper.git Task 2.5. Combination operations on Groups (issue #2935) Implement Group Intersection feature. --- diff --git a/src/CollectionAPI/CMakeLists.txt b/src/CollectionAPI/CMakeLists.txt index f9ca6033b..0bf7bffa4 100644 --- a/src/CollectionAPI/CMakeLists.txt +++ b/src/CollectionAPI/CMakeLists.txt @@ -23,12 +23,14 @@ SET(PROJECT_HEADERS CollectionAPI.h CollectionAPI_Group.h CollectionAPI_GroupAddition.h + CollectionAPI_GroupIntersection.h CollectionAPI_Field.h ) SET(PROJECT_SOURCES CollectionAPI_Group.cpp CollectionAPI_GroupAddition.cpp + CollectionAPI_GroupIntersection.cpp CollectionAPI_Field.cpp ) diff --git a/src/CollectionAPI/CollectionAPI.i b/src/CollectionAPI/CollectionAPI.i index 2dee7dd08..a4fbd35ec 100644 --- a/src/CollectionAPI/CollectionAPI.i +++ b/src/CollectionAPI/CollectionAPI.i @@ -30,6 +30,7 @@ #include "CollectionAPI.h" #include "CollectionAPI_Group.h" #include "CollectionAPI_GroupAddition.h" + #include "CollectionAPI_GroupIntersection.h" #include "CollectionAPI_Field.h" #endif // CollectionAPI_swig_H_ @@ -68,9 +69,11 @@ // shared pointers %shared_ptr(CollectionAPI_Group) %shared_ptr(CollectionAPI_GroupAddition) +%shared_ptr(CollectionAPI_GroupIntersection) %shared_ptr(CollectionAPI_Field) // all supported interfaces %include "CollectionAPI_Group.h" %include "CollectionAPI_GroupAddition.h" +%include "CollectionAPI_GroupIntersection.h" %include "CollectionAPI_Field.h" diff --git a/src/CollectionAPI/CollectionAPI_GroupAddition.h b/src/CollectionAPI/CollectionAPI_GroupAddition.h index c6395300d..102e84afa 100644 --- a/src/CollectionAPI/CollectionAPI_GroupAddition.h +++ b/src/CollectionAPI/CollectionAPI_GroupAddition.h @@ -32,7 +32,7 @@ class ModelHighAPI_Selection; /// \class CollectionAPI_GroupAddition /// \ingroup CPPHighAPI -/// \brief Interface for Group feature. +/// \brief Interface for Group Addition feature. class CollectionAPI_GroupAddition : public ModelHighAPI_Interface { public: @@ -71,4 +71,4 @@ COLLECTIONAPI_EXPORT GroupAdditionPtr addGroupAddition(const std::shared_ptr& thePart, const std::list& theGroupsList); -#endif // CollectionAPI_Group_H_ +#endif // CollectionAPI_GroupAddition_H_ diff --git a/src/CollectionAPI/CollectionAPI_GroupIntersection.cpp b/src/CollectionAPI/CollectionAPI_GroupIntersection.cpp new file mode 100644 index 000000000..7d4fad73d --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupIntersection.cpp @@ -0,0 +1,71 @@ +// 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 "CollectionAPI_GroupIntersection.h" + +#include +#include + +CollectionAPI_GroupIntersection::CollectionAPI_GroupIntersection( + const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +CollectionAPI_GroupIntersection::CollectionAPI_GroupIntersection( + const std::shared_ptr& theFeature, + const std::list& theGroupList) + : ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + setGroupList(theGroupList); + } +} + +CollectionAPI_GroupIntersection::~CollectionAPI_GroupIntersection() +{ +} + +void CollectionAPI_GroupIntersection::setGroupList( + const std::list& theGroupList) +{ + fillAttribute(theGroupList, mygroupList); + execute(); +} + +void CollectionAPI_GroupIntersection::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrList = + aBase->selectionList(CollectionPlugin_GroupIntersection::LIST_ID()); + + theDumper << aBase << " = model.addGroupIntersection(" << aDocName << ", " + << anAttrList << ")" << std::endl; +} + +GroupIntersectionPtr addGroupIntersection(const std::shared_ptr& thePart, + const std::list& theGroupList) +{ + std::shared_ptr aFeature = + thePart->addFeature(CollectionAPI_GroupIntersection::ID()); + return GroupIntersectionPtr(new CollectionAPI_GroupIntersection(aFeature, theGroupList)); +} diff --git a/src/CollectionAPI/CollectionAPI_GroupIntersection.h b/src/CollectionAPI/CollectionAPI_GroupIntersection.h new file mode 100644 index 000000000..007853cb0 --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupIntersection.h @@ -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 +// + +#ifndef CollectionAPI_GroupIntersection_H_ +#define CollectionAPI_GroupIntersection_H_ + +#include "CollectionAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class CollectionAPI_GroupIntersection +/// \ingroup CPPHighAPI +/// \brief Interface for Group Intersection feature. +class CollectionAPI_GroupIntersection : public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + COLLECTIONAPI_EXPORT + explicit CollectionAPI_GroupIntersection(const std::shared_ptr& theFeature); + + /// Constructor with values. + COLLECTIONAPI_EXPORT + CollectionAPI_GroupIntersection(const std::shared_ptr& theFeature, + const std::list& theGroupList); + + /// Destructor. + COLLECTIONAPI_EXPORT + virtual ~CollectionAPI_GroupIntersection(); + + INTERFACE_1(CollectionPlugin_GroupIntersection::ID(), + groupList, CollectionPlugin_GroupIntersection::LIST_ID(), + ModelAPI_AttributeSelectionList, /** Group list*/) + + /// Set main objects. + COLLECTIONAPI_EXPORT + void setGroupList(const std::list& theGroupList); + + /// Dump wrapped feature + COLLECTIONAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer on Group Addition object. +typedef std::shared_ptr GroupIntersectionPtr; + +/// \ingroup CPPHighAPI +/// \brief Create Group Intersection feature. +COLLECTIONAPI_EXPORT +GroupIntersectionPtr addGroupIntersection(const std::shared_ptr& thePart, + const std::list& theGroupsList); + +#endif // CollectionAPI_GroupIntersection_H_ diff --git a/src/CollectionPlugin/CMakeLists.txt b/src/CollectionPlugin/CMakeLists.txt index a19513883..77ef3615d 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS CollectionPlugin_Plugin.h CollectionPlugin_Group.h CollectionPlugin_GroupAddition.h + CollectionPlugin_GroupIntersection.h CollectionPlugin_Field.h CollectionPlugin_WidgetCreator.h CollectionPlugin_WidgetField.h @@ -46,6 +47,7 @@ SET(PROJECT_SOURCES CollectionPlugin_Plugin.cpp CollectionPlugin_Group.cpp CollectionPlugin_GroupAddition.cpp + CollectionPlugin_GroupIntersection.cpp CollectionPlugin_Field.cpp CollectionPlugin_WidgetCreator.cpp CollectionPlugin_WidgetField.cpp @@ -135,4 +137,6 @@ ADD_UNIT_TESTS( TestGroupShareTopology.py TestGroupAddition.py TestGroupAddition_Error.py + TestGroupIntersection.py + TestGroupIntersection_Error.py ) diff --git a/src/CollectionPlugin/CollectionPlugin_GroupIntersection.cpp b/src/CollectionPlugin/CollectionPlugin_GroupIntersection.cpp new file mode 100644 index 000000000..e74ba4786 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupIntersection.cpp @@ -0,0 +1,103 @@ +// 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 "CollectionPlugin_GroupIntersection.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef std::set SetOfShape; + +CollectionPlugin_GroupIntersection::CollectionPlugin_GroupIntersection() +{ +} + +void CollectionPlugin_GroupIntersection::initAttributes() +{ + data()->addAttribute(CollectionPlugin_GroupIntersection::LIST_ID(), + ModelAPI_AttributeSelectionList::typeId()); +} + +static void explodeCompound(const GeomShapePtr& theCompound, SetOfShape& theSet) +{ + for (GeomAPI_ShapeIterator anIt(theCompound); anIt.more(); anIt.next()) + theSet.insert(anIt.current()); +} + +static void keepCommonShapes(const GeomShapePtr& theCompound, ListOfShape& theShapes) +{ + if (theShapes.empty()) { + for (GeomAPI_ShapeIterator anIt(theCompound); anIt.more(); anIt.next()) + theShapes.push_back(anIt.current()); + } + else { + SetOfShape aSubs; + explodeCompound(theCompound, aSubs); + + ListOfShape::iterator anIt = theShapes.begin(); + while (anIt != theShapes.end()) { + if (aSubs.find(*anIt) == aSubs.end()) { + // the shape is not found + ListOfShape::iterator aRemoveIt = anIt++; + theShapes.erase(aRemoveIt); + } + else + ++anIt; + } + } +} + +void CollectionPlugin_GroupIntersection::execute() +{ + ResultGroupPtr aGroup = document()->createGroup(data()); + // clean the result of the operation + aGroup->store(GeomShapePtr()); + + // shapes containing in each group + ListOfShape aCommon; + + // collect shapes containing in all groups + AttributeSelectionListPtr aSelectedGroups = selectionList(LIST_ID()); + for (int anIndex = 0; anIndex < aSelectedGroups->size(); ++anIndex) { + AttributeSelectionPtr aCurSelection = aSelectedGroups->value(anIndex); + ResultGroupPtr aCurGroup = + std::dynamic_pointer_cast(aCurSelection->context()); + keepCommonShapes(aCurGroup->shape(), aCommon); + if (aCommon.empty()) + break; + } + + if (aCommon.empty()) { + setError("Error: Empty result."); + removeResults(0); + } + else { + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aCommon); + aGroup->store(aCompound); + setResult(aGroup); + } +} diff --git a/src/CollectionPlugin/CollectionPlugin_GroupIntersection.h b/src/CollectionPlugin/CollectionPlugin_GroupIntersection.h new file mode 100644 index 000000000..115f3f544 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupIntersection.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 COLLECTIONPLUGIN_GROUPINTERSECTION_H_ +#define COLLECTIONPLUGIN_GROUPINTERSECTION_H_ + +#include "CollectionPlugin.h" +#include "CollectionPlugin_Group.h" + +/**\class CollectionPlugin_GroupIntersection + * \ingroup Plugins + * \brief Merge several groups of same shape type into single group. + */ +class CollectionPlugin_GroupIntersection : public CollectionPlugin_Group +{ + public: + /// Extrusion kind + inline static const std::string& ID() + { + static const std::string MY_GROUP_ID("GroupIntersection"); + return MY_GROUP_ID; + } + /// attribute name of selected entities list + inline static const std::string& LIST_ID() + { + static const std::string MY_GROUP_LIST_ID("group_list"); + return MY_GROUP_LIST_ID; + } + + /// Returns the kind of a feature + COLLECTIONPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = CollectionPlugin_GroupIntersection::ID(); + return MY_KIND; + } + + /// Creates a new group result if needed + COLLECTIONPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + COLLECTIONPLUGIN_EXPORT virtual void initAttributes(); + + /// Result of groups is created on the fly and don't stored to the document + COLLECTIONPLUGIN_EXPORT virtual bool isPersistentResult() {return true;} + + /// Use plugin manager for features creation + CollectionPlugin_GroupIntersection(); + +}; + +#endif diff --git a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp index 560615e5e..d8514f518 100644 --- a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,8 @@ FeaturePtr CollectionPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new CollectionPlugin_Field); } else if (theFeatureID == CollectionPlugin_GroupAddition::ID()) { return FeaturePtr(new CollectionPlugin_GroupAddition); + } else if (theFeatureID == CollectionPlugin_GroupIntersection::ID()) { + return FeaturePtr(new CollectionPlugin_GroupIntersection); } // feature of such kind is not found diff --git a/src/CollectionPlugin/CollectionPlugin_msg_en.ts b/src/CollectionPlugin/CollectionPlugin_msg_en.ts index 061f3923d..3c2d28234 100644 --- a/src/CollectionPlugin/CollectionPlugin_msg_en.ts +++ b/src/CollectionPlugin/CollectionPlugin_msg_en.ts @@ -37,5 +37,12 @@ Components are not selected + + GroupIntersection:EmptyResult + + Error: Empty result. + Error: Empty result. + + diff --git a/src/CollectionPlugin/Test/TestGroupIntersection.py b/src/CollectionPlugin/Test/TestGroupIntersection.py new file mode 100644 index 000000000..e53bfb1d5 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupIntersection.py @@ -0,0 +1,45 @@ +# 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Left")]) +Group_2 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Top")]) +Group_3_objects = [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Top")] +Group_3 = model.addGroup(Part_1_doc, Group_3_objects) +GroupIntersection_1_objects = [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2"), model.selection("COMPOUND", "Group_3")] +GroupIntersection_1 = model.addGroupIntersection(Part_1_doc, GroupIntersection_1_objects) +model.end() + +from GeomAPI import * + +model.testNbResults(GroupIntersection_1, 1) +model.testNbSubResults(GroupIntersection_1, [0]) +model.testNbSubShapes(GroupIntersection_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(GroupIntersection_1, GeomAPI_Shape.FACE, [1]) +model.testNbSubShapes(GroupIntersection_1, GeomAPI_Shape.EDGE, [4]) +model.testNbSubShapes(GroupIntersection_1, GeomAPI_Shape.VERTEX, [8]) +model.testResultsVolumes(GroupIntersection_1, [100]) + +assert(model.checkPythonDump()) diff --git a/src/CollectionPlugin/Test/TestGroupIntersection_Error.py b/src/CollectionPlugin/Test/TestGroupIntersection_Error.py new file mode 100644 index 000000000..cfa9601a4 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupIntersection_Error.py @@ -0,0 +1,34 @@ +# 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Left")]) +Group_2 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Top")]) +Group_3 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Right")]) +GroupIntersection_1_objects = [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2"), model.selection("COMPOUND", "Group_3")] +GroupIntersection_1 = model.addGroupIntersection(Part_1_doc, GroupIntersection_1_objects) +model.end() + +assert(GroupIntersection_1.feature().error() != "") diff --git a/src/CollectionPlugin/group_addition_widget.xml b/src/CollectionPlugin/group_addition_widget.xml index 510e6953c..6274511c0 100644 --- a/src/CollectionPlugin/group_addition_widget.xml +++ b/src/CollectionPlugin/group_addition_widget.xml @@ -8,4 +8,4 @@ type_choice="objects"> - \ No newline at end of file + diff --git a/src/CollectionPlugin/group_intersection_widget.xml b/src/CollectionPlugin/group_intersection_widget.xml index 3a1f83feb..6274511c0 100644 --- a/src/CollectionPlugin/group_intersection_widget.xml +++ b/src/CollectionPlugin/group_intersection_widget.xml @@ -1,15 +1,11 @@ + label="Name" + placeholder="Please input the group name"> - + tooltip="Select a set of groups" + type_choice="objects"> + - \ No newline at end of file + diff --git a/src/CollectionPlugin/plugin-Collection.xml b/src/CollectionPlugin/plugin-Collection.xml index 9ec5c5dd6..295204898 100644 --- a/src/CollectionPlugin/plugin-Collection.xml +++ b/src/CollectionPlugin/plugin-Collection.xml @@ -30,6 +30,15 @@ helpfile="groupAdditionFeature.html"> + + + + diff --git a/src/PythonAPI/model/collection/__init__.py b/src/PythonAPI/model/collection/__init__.py index 96b7089ce..3e96808fd 100644 --- a/src/PythonAPI/model/collection/__init__.py +++ b/src/PythonAPI/model/collection/__init__.py @@ -20,4 +20,4 @@ """ from CollectionAPI import addGroup, addField -from CollectionAPI import addGroupAddition +from CollectionAPI import addGroupAddition, addGroupIntersection