From 00e7032c437ca3e2e47996307b679505794842c1 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 8 Aug 2019 15:15:52 +0300 Subject: [PATCH] Task 2.5. Combination operations on Groups (issue #2935) Implement Group Substraction feature. --- src/CollectionAPI/CMakeLists.txt | 2 + src/CollectionAPI/CollectionAPI.i | 3 + .../CollectionAPI_GroupSubstraction.cpp | 84 ++++++++++++++ .../CollectionAPI_GroupSubstraction.h | 82 +++++++++++++ src/CollectionPlugin/CMakeLists.txt | 5 + .../CollectionPlugin_GroupSubstraction.cpp | 108 ++++++++++++++++++ .../CollectionPlugin_GroupSubstraction.h | 73 ++++++++++++ .../CollectionPlugin_Plugin.cpp | 3 + .../CollectionPlugin_Validators.cpp | 47 +++++--- .../Test/TestGroupAddition.py | 2 +- .../Test/TestGroupAddition_Error.py | 2 +- .../Test/TestGroupSubstraction.py | 47 ++++++++ .../Test/TestGroupSubstraction_Error1.py | 33 ++++++ .../Test/TestGroupSubstraction_Error2.py | 33 ++++++ .../group_substraction_widget.xml | 21 ++-- src/CollectionPlugin/plugin-Collection.xml | 9 ++ src/PythonAPI/model/collection/__init__.py | 2 +- 17 files changed, 529 insertions(+), 27 deletions(-) create mode 100644 src/CollectionAPI/CollectionAPI_GroupSubstraction.cpp create mode 100644 src/CollectionAPI/CollectionAPI_GroupSubstraction.h create mode 100644 src/CollectionPlugin/CollectionPlugin_GroupSubstraction.cpp create mode 100644 src/CollectionPlugin/CollectionPlugin_GroupSubstraction.h create mode 100644 src/CollectionPlugin/Test/TestGroupSubstraction.py create mode 100644 src/CollectionPlugin/Test/TestGroupSubstraction_Error1.py create mode 100644 src/CollectionPlugin/Test/TestGroupSubstraction_Error2.py diff --git a/src/CollectionAPI/CMakeLists.txt b/src/CollectionAPI/CMakeLists.txt index 0bf7bffa4..f5c90abee 100644 --- a/src/CollectionAPI/CMakeLists.txt +++ b/src/CollectionAPI/CMakeLists.txt @@ -24,6 +24,7 @@ SET(PROJECT_HEADERS CollectionAPI_Group.h CollectionAPI_GroupAddition.h CollectionAPI_GroupIntersection.h + CollectionAPI_GroupSubstraction.h CollectionAPI_Field.h ) @@ -31,6 +32,7 @@ SET(PROJECT_SOURCES CollectionAPI_Group.cpp CollectionAPI_GroupAddition.cpp CollectionAPI_GroupIntersection.cpp + CollectionAPI_GroupSubstraction.cpp CollectionAPI_Field.cpp ) diff --git a/src/CollectionAPI/CollectionAPI.i b/src/CollectionAPI/CollectionAPI.i index a4fbd35ec..552a33d3d 100644 --- a/src/CollectionAPI/CollectionAPI.i +++ b/src/CollectionAPI/CollectionAPI.i @@ -31,6 +31,7 @@ #include "CollectionAPI_Group.h" #include "CollectionAPI_GroupAddition.h" #include "CollectionAPI_GroupIntersection.h" + #include "CollectionAPI_GroupSubstraction.h" #include "CollectionAPI_Field.h" #endif // CollectionAPI_swig_H_ @@ -70,10 +71,12 @@ %shared_ptr(CollectionAPI_Group) %shared_ptr(CollectionAPI_GroupAddition) %shared_ptr(CollectionAPI_GroupIntersection) +%shared_ptr(CollectionAPI_GroupSubstraction) %shared_ptr(CollectionAPI_Field) // all supported interfaces %include "CollectionAPI_Group.h" %include "CollectionAPI_GroupAddition.h" %include "CollectionAPI_GroupIntersection.h" +%include "CollectionAPI_GroupSubstraction.h" %include "CollectionAPI_Field.h" diff --git a/src/CollectionAPI/CollectionAPI_GroupSubstraction.cpp b/src/CollectionAPI/CollectionAPI_GroupSubstraction.cpp new file mode 100644 index 000000000..bdd6494cf --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupSubstraction.cpp @@ -0,0 +1,84 @@ +// 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_GroupSubstraction.h" + +#include +#include + +CollectionAPI_GroupSubstraction::CollectionAPI_GroupSubstraction( + const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +CollectionAPI_GroupSubstraction::CollectionAPI_GroupSubstraction( + const std::shared_ptr& theFeature, + const std::list& theObjectsList, + const std::list& theToolsList) + : ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + setObjectsList(theObjectsList); + setToolsList(theToolsList); + } +} + +CollectionAPI_GroupSubstraction::~CollectionAPI_GroupSubstraction() +{ +} + +void CollectionAPI_GroupSubstraction::setObjectsList( + const std::list& theGroupList) +{ + fillAttribute(theGroupList, myobjectsList); + execute(); +} + +void CollectionAPI_GroupSubstraction::setToolsList( + const std::list& theGroupList) +{ + fillAttribute(theGroupList, mytoolsList); + execute(); +} + +void CollectionAPI_GroupSubstraction::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anObjectsList = + aBase->selectionList(CollectionPlugin_GroupSubstraction::LIST_ID()); + AttributeSelectionListPtr aToolsList = + aBase->selectionList(CollectionPlugin_GroupSubstraction::TOOLS_ID()); + + theDumper << aBase << " = model.addGroupSubstraction(" << aDocName << ", " + << anObjectsList << ", " << aToolsList << ")" << std::endl; +} + +GroupSubstractionPtr addGroupSubstraction(const std::shared_ptr& thePart, + const std::list& theObjectsList, + const std::list& theToolsList) +{ + std::shared_ptr aFeature = + thePart->addFeature(CollectionAPI_GroupSubstraction::ID()); + return GroupSubstractionPtr(new CollectionAPI_GroupSubstraction( + aFeature, theObjectsList, theToolsList)); +} diff --git a/src/CollectionAPI/CollectionAPI_GroupSubstraction.h b/src/CollectionAPI/CollectionAPI_GroupSubstraction.h new file mode 100644 index 000000000..0e119923c --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupSubstraction.h @@ -0,0 +1,82 @@ +// 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_GroupSubstraction_H_ +#define CollectionAPI_GroupSubstraction_H_ + +#include "CollectionAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class CollectionAPI_GroupSubstraction +/// \ingroup CPPHighAPI +/// \brief Interface for Group Intersection feature. +class CollectionAPI_GroupSubstraction : public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + COLLECTIONAPI_EXPORT + explicit CollectionAPI_GroupSubstraction(const std::shared_ptr& theFeature); + + /// Constructor with values. + COLLECTIONAPI_EXPORT + CollectionAPI_GroupSubstraction(const std::shared_ptr& theFeature, + const std::list& theObjectsList, + const std::list& theToolsList); + + /// Destructor. + COLLECTIONAPI_EXPORT + virtual ~CollectionAPI_GroupSubstraction(); + + INTERFACE_2(CollectionPlugin_GroupSubstraction::ID(), + objectsList, CollectionPlugin_GroupSubstraction::LIST_ID(), + ModelAPI_AttributeSelectionList, /** Objects list*/, + toolsList, CollectionPlugin_GroupSubstraction::TOOLS_ID(), + ModelAPI_AttributeSelectionList, /** Tools list*/) + + /// Set main objects. + COLLECTIONAPI_EXPORT + void setObjectsList(const std::list& theGroupList); + + /// Set tools. + COLLECTIONAPI_EXPORT + void setToolsList(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 GroupSubstractionPtr; + +/// \ingroup CPPHighAPI +/// \brief Create Group Substraction feature. +COLLECTIONAPI_EXPORT +GroupSubstractionPtr addGroupSubstraction(const std::shared_ptr& thePart, + const std::list& theObjectsList, + const std::list& theToolsList); + +#endif // CollectionAPI_GroupSubstraction_H_ diff --git a/src/CollectionPlugin/CMakeLists.txt b/src/CollectionPlugin/CMakeLists.txt index 77ef3615d..cfdaaa8e7 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS CollectionPlugin_Group.h CollectionPlugin_GroupAddition.h CollectionPlugin_GroupIntersection.h + CollectionPlugin_GroupSubstraction.h CollectionPlugin_Field.h CollectionPlugin_WidgetCreator.h CollectionPlugin_WidgetField.h @@ -48,6 +49,7 @@ SET(PROJECT_SOURCES CollectionPlugin_Group.cpp CollectionPlugin_GroupAddition.cpp CollectionPlugin_GroupIntersection.cpp + CollectionPlugin_GroupSubstraction.cpp CollectionPlugin_Field.cpp CollectionPlugin_WidgetCreator.cpp CollectionPlugin_WidgetField.cpp @@ -139,4 +141,7 @@ ADD_UNIT_TESTS( TestGroupAddition_Error.py TestGroupIntersection.py TestGroupIntersection_Error.py + TestGroupSubstraction.py + TestGroupSubstraction_Error1.py + TestGroupSubstraction_Error2.py ) diff --git a/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.cpp b/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.cpp new file mode 100644 index 000000000..18f0acad5 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.cpp @@ -0,0 +1,108 @@ +// 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_GroupSubstraction.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef std::set SetOfShape; + +CollectionPlugin_GroupSubstraction::CollectionPlugin_GroupSubstraction() +{ +} + +void CollectionPlugin_GroupSubstraction::initAttributes() +{ + data()->addAttribute(CollectionPlugin_GroupSubstraction::LIST_ID(), + ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(CollectionPlugin_GroupSubstraction::TOOLS_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 subtractLists(const GeomShapePtr& theCompound, + const SetOfShape& theExclude, + ListOfShape& theResult) +{ + for (GeomAPI_ShapeIterator anIt(theCompound); anIt.more(); anIt.next()) { + GeomShapePtr aCurrent = anIt.current(); + if (theExclude.find(aCurrent) != theExclude.end()) + continue; // shape has to be excluded + // check the shape is already in the list + ListOfShape::iterator anIt2 = theResult.begin(); + for (; anIt2 != theResult.end(); ++anIt2) + if (aCurrent->isEqual(*anIt2)) + break; + if (anIt2 == theResult.end()) + theResult.push_back(aCurrent); + } +} + +void CollectionPlugin_GroupSubstraction::execute() +{ + ResultGroupPtr aGroup = document()->createGroup(data()); + // clean the result of the operation + aGroup->store(GeomShapePtr()); + + // collect shapes to be excluded (tools) + SetOfShape aShapesToExclude; + AttributeSelectionListPtr aTools = selectionList(TOOLS_ID()); + for (int anIndex = 0; anIndex < aTools->size(); ++anIndex) { + AttributeSelectionPtr aCurSelection = aTools->value(anIndex); + ResultGroupPtr aCurGroup = + std::dynamic_pointer_cast(aCurSelection->context()); + explodeCompound(aCurGroup->shape(), aShapesToExclude); + } + + // keep only shapes that should not be excluded + ListOfShape aCut; + AttributeSelectionListPtr anObjects = selectionList(LIST_ID()); + for (int anIndex = 0; anIndex < anObjects->size(); ++anIndex) { + AttributeSelectionPtr aCurSelection = anObjects->value(anIndex); + ResultGroupPtr aCurGroup = + std::dynamic_pointer_cast(aCurSelection->context()); + subtractLists(aCurGroup->shape(), aShapesToExclude, aCut); + if (aCut.empty()) + break; + } + + if (aCut.empty()) { + setError("Error: Empty result."); + removeResults(0); + } + else { + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aCut); + aGroup->store(aCompound); + setResult(aGroup); + } +} diff --git a/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.h b/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.h new file mode 100644 index 000000000..3fcd74339 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupSubstraction.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 COLLECTIONPLUGIN_GROUPSUBSTRACTION_H_ +#define COLLECTIONPLUGIN_GROUPSUBSTRACTION_H_ + +#include "CollectionPlugin.h" +#include "CollectionPlugin_Group.h" + +/**\class CollectionPlugin_GroupSubstraction + * \ingroup Plugins + * \brief Remove all elements in "objects" groups which contain in "tools" groups. + */ +class CollectionPlugin_GroupSubstraction : public CollectionPlugin_Group +{ + public: + /// Extrusion kind + inline static const std::string& ID() + { + static const std::string MY_GROUP_ID("GroupSubstraction"); + return MY_GROUP_ID; + } + /// attribute name of selected objects list + inline static const std::string& LIST_ID() + { + static const std::string MY_GROUP_LIST_ID("group_list"); + return MY_GROUP_LIST_ID; + } + /// attribute name of selected tools list + inline static const std::string& TOOLS_ID() + { + static const std::string MY_GROUP_LIST_ID("tools_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_GroupSubstraction::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_GroupSubstraction(); + +}; + +#endif diff --git a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp index d8514f518..8a62c07a8 100644 --- a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,8 @@ FeaturePtr CollectionPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new CollectionPlugin_GroupAddition); } else if (theFeatureID == CollectionPlugin_GroupIntersection::ID()) { return FeaturePtr(new CollectionPlugin_GroupIntersection); + } else if (theFeatureID == CollectionPlugin_GroupSubstraction::ID()) { + return FeaturePtr(new CollectionPlugin_GroupSubstraction); } // feature of such kind is not found diff --git a/src/CollectionPlugin/CollectionPlugin_Validators.cpp b/src/CollectionPlugin/CollectionPlugin_Validators.cpp index caf64d0bb..7ef185389 100644 --- a/src/CollectionPlugin/CollectionPlugin_Validators.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Validators.cpp @@ -45,6 +45,29 @@ bool CollectionPlugin_FieldValidator::isValid(const FeaturePtr& theFeature, return false; } +static bool isGroupTypeCorrect(const AttributeSelectionPtr& theSelection, + std::string& theType, + Events_InfoMessage& theError) +{ + // applicable the groups only + ResultPtr aGroupResult = theSelection->context(); + if (aGroupResult->groupName() != ModelAPI_ResultGroup::group()) { + theError = "Error: Groups can be selected only."; + return false; + } + // groups of same type can be selected only + FeaturePtr aGroupFeature = ModelAPI_Feature::feature(aGroupResult->data()->owner()); + std::string aGroupType = + aGroupFeature->selectionList(CollectionPlugin_Group::LIST_ID())->selectionType(); + if (theType.empty()) + theType = aGroupType; + else if (theType != aGroupType) { + theError = "Error: Groups should have same type"; + return false; + } + return true; +} + bool CollectionPlugin_GroupOperationAttributeValidator::isValid( const AttributePtr& theAttribute, const std::list& theArguments, @@ -62,22 +85,18 @@ bool CollectionPlugin_GroupOperationAttributeValidator::isValid( std::string aType; for (int anIndex = 0; anIndex < aSelList->size(); ++anIndex) { AttributeSelectionPtr aCurSelection = aSelList->value(anIndex); - // applicable the groups only - ResultPtr aGroupResult = aCurSelection->context(); - if (aGroupResult->groupName() != ModelAPI_ResultGroup::group()) { - theError = "Error: Groups can be selected only."; + if (!isGroupTypeCorrect(aCurSelection, aType, theError)) return false; - } - // groups of same type can be selected only - FeaturePtr aGroupFeature = ModelAPI_Feature::feature(aGroupResult->data()->owner()); - std::string aGroupType = - aGroupFeature->selectionList(CollectionPlugin_Group::LIST_ID())->selectionType(); - if (aType.empty()) - aType = aGroupType; - else if (aType != aGroupType) { - theError = "Error: Groups should have same type"; + } + // check types of all selection lists are the same + for (std::list::const_iterator aParIt = theArguments.begin(); + aParIt != theArguments.end() && !aType.empty(); ++aParIt) { + AttributeSelectionListPtr aCurList = anOwner->selectionList(*aParIt); + if (aCurList->size() == 0) + continue; + AttributeSelectionPtr aCurSelection = aCurList->value(0); + if (!isGroupTypeCorrect(aCurSelection, aType, theError)) return false; - } } return true; } diff --git a/src/CollectionPlugin/Test/TestGroupAddition.py b/src/CollectionPlugin/Test/TestGroupAddition.py index de66eb527..a5e88cc4c 100644 --- a/src/CollectionPlugin/Test/TestGroupAddition.py +++ b/src/CollectionPlugin/Test/TestGroupAddition.py @@ -27,7 +27,7 @@ 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")]) GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")]) -model.end +model.end() from GeomAPI import * diff --git a/src/CollectionPlugin/Test/TestGroupAddition_Error.py b/src/CollectionPlugin/Test/TestGroupAddition_Error.py index ad6934da2..b69a24939 100644 --- a/src/CollectionPlugin/Test/TestGroupAddition_Error.py +++ b/src/CollectionPlugin/Test/TestGroupAddition_Error.py @@ -28,6 +28,6 @@ Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Top"), mo Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]")]) GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")]) GroupAddition_2 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("FACE", "Box_1_1/Front")]) -model.end +model.end() assert(GroupAddition_1.feature().error() != "") diff --git a/src/CollectionPlugin/Test/TestGroupSubstraction.py b/src/CollectionPlugin/Test/TestGroupSubstraction.py new file mode 100644 index 000000000..98669ca03 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupSubstraction.py @@ -0,0 +1,47 @@ +# 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_objects = [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]")] +Group_1 = model.addGroup(Part_1_doc, Group_1_objects) +Group_2_objects = [model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")] +Group_2 = model.addGroup(Part_1_doc, Group_2_objects) +Group_3_objects = [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]")] +Group_3 = model.addGroup(Part_1_doc, Group_3_objects) +Group_4_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]")] +Group_4 = model.addGroup(Part_1_doc, Group_4_objects) +GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")], [model.selection("COMPOUND", "Group_3"), model.selection("COMPOUND", "Group_4")]) +model.end() + +from GeomAPI import * + +model.testNbResults(GroupSubstraction_1, 1) +model.testNbSubResults(GroupSubstraction_1, [0]) +model.testNbSubShapes(GroupSubstraction_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(GroupSubstraction_1, GeomAPI_Shape.FACE, [0]) +model.testNbSubShapes(GroupSubstraction_1, GeomAPI_Shape.EDGE, [3]) +model.testNbSubShapes(GroupSubstraction_1, GeomAPI_Shape.VERTEX, [6]) + +assert(model.checkPythonDump()) diff --git a/src/CollectionPlugin/Test/TestGroupSubstraction_Error1.py b/src/CollectionPlugin/Test/TestGroupSubstraction_Error1.py new file mode 100644 index 000000000..65ba6684b --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupSubstraction_Error1.py @@ -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 +# + +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_objects = [model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]")] +Group_2 = model.addGroup(Part_1_doc, Group_2_objects) +GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "Group_1")], [model.selection("COMPOUND", "Group_2")]) +model.end() + +assert(GroupSubstraction_1.feature().error() != "") diff --git a/src/CollectionPlugin/Test/TestGroupSubstraction_Error2.py b/src/CollectionPlugin/Test/TestGroupSubstraction_Error2.py new file mode 100644 index 000000000..46967dda8 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupSubstraction_Error2.py @@ -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 +# + +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/Left"), model.selection("FACE", "Box_1_1/Front")]) +Group_3 = model.addGroup(Part_1_doc, [model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Top")]) +GroupSubstraction_1 = model.addGroupSubstraction(Part_1_doc, [model.selection("COMPOUND", "Group_1")], [model.selection("COMPOUND", "Group_2"), model.selection("COMPOUND", "Group_3")]) +model.end() + +assert(GroupSubstraction_1.feature().error() != "") diff --git a/src/CollectionPlugin/group_substraction_widget.xml b/src/CollectionPlugin/group_substraction_widget.xml index 3a1f83feb..b06929b0e 100644 --- a/src/CollectionPlugin/group_substraction_widget.xml +++ b/src/CollectionPlugin/group_substraction_widget.xml @@ -1,15 +1,16 @@ + 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 295204898..37a05a42d 100644 --- a/src/CollectionPlugin/plugin-Collection.xml +++ b/src/CollectionPlugin/plugin-Collection.xml @@ -39,6 +39,15 @@ helpfile="groupIntersectionFeature.html"> + + + + diff --git a/src/PythonAPI/model/collection/__init__.py b/src/PythonAPI/model/collection/__init__.py index 3e96808fd..695d5303d 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, addGroupIntersection +from CollectionAPI import addGroupAddition, addGroupIntersection, addGroupSubstraction -- 2.30.2