From: azv Date: Mon, 12 Aug 2019 05:36:58 +0000 (+0300) Subject: Merge remote-tracking branch 'remotes/origin/Operations_on_Groups' X-Git-Tag: VEDF2019Lot4~59 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=95375993f1f35e4716475c0b0c8e265c082c875d;hp=83578c47d9b2f8c51a63fe2415972b27bcaca395;p=modules%2Fshaper.git Merge remote-tracking branch 'remotes/origin/Operations_on_Groups' --- diff --git a/src/CollectionAPI/CMakeLists.txt b/src/CollectionAPI/CMakeLists.txt index 0b2815bdd..f5c90abee 100644 --- a/src/CollectionAPI/CMakeLists.txt +++ b/src/CollectionAPI/CMakeLists.txt @@ -22,11 +22,17 @@ INCLUDE(Common) SET(PROJECT_HEADERS CollectionAPI.h CollectionAPI_Group.h + CollectionAPI_GroupAddition.h + CollectionAPI_GroupIntersection.h + CollectionAPI_GroupSubstraction.h CollectionAPI_Field.h ) 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 c27d56cb2..552a33d3d 100644 --- a/src/CollectionAPI/CollectionAPI.i +++ b/src/CollectionAPI/CollectionAPI.i @@ -29,6 +29,9 @@ #include "CollectionAPI.h" #include "CollectionAPI_Group.h" + #include "CollectionAPI_GroupAddition.h" + #include "CollectionAPI_GroupIntersection.h" + #include "CollectionAPI_GroupSubstraction.h" #include "CollectionAPI_Field.h" #endif // CollectionAPI_swig_H_ @@ -66,8 +69,14 @@ // shared pointers %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_GroupAddition.cpp b/src/CollectionAPI/CollectionAPI_GroupAddition.cpp new file mode 100644 index 000000000..d0fecada7 --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupAddition.cpp @@ -0,0 +1,70 @@ +// 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_GroupAddition.h" + +#include +#include + +CollectionAPI_GroupAddition::CollectionAPI_GroupAddition( + const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +CollectionAPI_GroupAddition::CollectionAPI_GroupAddition( + const std::shared_ptr& theFeature, + const std::list& theGroupList) + : ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + setGroupList(theGroupList); + } +} + +CollectionAPI_GroupAddition::~CollectionAPI_GroupAddition() +{ +} + +void CollectionAPI_GroupAddition::setGroupList( + const std::list& theGroupList) +{ + fillAttribute(theGroupList, mygroupList); + execute(); +} + +void CollectionAPI_GroupAddition::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrList = + aBase->selectionList(CollectionPlugin_GroupAddition::LIST_ID()); + + theDumper << aBase << " = model.addGroupAddition(" << aDocName << ", " + << anAttrList << ")" << std::endl; +} + +GroupAdditionPtr addGroupAddition(const std::shared_ptr& thePart, + const std::list& theGroupList) +{ + std::shared_ptr aFeature = thePart->addFeature(CollectionAPI_GroupAddition::ID()); + return GroupAdditionPtr(new CollectionAPI_GroupAddition(aFeature, theGroupList)); +} diff --git a/src/CollectionAPI/CollectionAPI_GroupAddition.h b/src/CollectionAPI/CollectionAPI_GroupAddition.h new file mode 100644 index 000000000..102e84afa --- /dev/null +++ b/src/CollectionAPI/CollectionAPI_GroupAddition.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_GroupAddition_H_ +#define CollectionAPI_GroupAddition_H_ + +#include "CollectionAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Dumper; +class ModelHighAPI_Selection; + +/// \class CollectionAPI_GroupAddition +/// \ingroup CPPHighAPI +/// \brief Interface for Group Addition feature. +class CollectionAPI_GroupAddition : public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + COLLECTIONAPI_EXPORT + explicit CollectionAPI_GroupAddition(const std::shared_ptr& theFeature); + + /// Constructor with values. + COLLECTIONAPI_EXPORT + CollectionAPI_GroupAddition(const std::shared_ptr& theFeature, + const std::list& theGroupList); + + /// Destructor. + COLLECTIONAPI_EXPORT + virtual ~CollectionAPI_GroupAddition(); + + INTERFACE_1(CollectionPlugin_GroupAddition::ID(), + groupList, CollectionPlugin_GroupAddition::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 GroupAdditionPtr; + +/// \ingroup CPPHighAPI +/// \brief Create Group Addition feature. +COLLECTIONAPI_EXPORT +GroupAdditionPtr addGroupAddition(const std::shared_ptr& thePart, + const std::list& theGroupsList); + +#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/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 2e2ff961d..cfdaaa8e7 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -31,6 +31,9 @@ SET(PROJECT_HEADERS CollectionPlugin.h CollectionPlugin_Plugin.h CollectionPlugin_Group.h + CollectionPlugin_GroupAddition.h + CollectionPlugin_GroupIntersection.h + CollectionPlugin_GroupSubstraction.h CollectionPlugin_Field.h CollectionPlugin_WidgetCreator.h CollectionPlugin_WidgetField.h @@ -44,6 +47,9 @@ SET(PROJECT_MOC_HEADERS SET(PROJECT_SOURCES CollectionPlugin_Plugin.cpp CollectionPlugin_Group.cpp + CollectionPlugin_GroupAddition.cpp + CollectionPlugin_GroupIntersection.cpp + CollectionPlugin_GroupSubstraction.cpp CollectionPlugin_Field.cpp CollectionPlugin_WidgetCreator.cpp CollectionPlugin_WidgetField.cpp @@ -53,6 +59,9 @@ SET(PROJECT_SOURCES SET(XML_RESOURCES plugin-Collection.xml group_widget.xml + group_addition_widget.xml + group_intersection_widget.xml + group_substraction_widget.xml ) SET(TEXT_RESOURCES @@ -128,4 +137,11 @@ ADD_UNIT_TESTS( TestGroupMove19.py TestGroupMove20.py TestGroupShareTopology.py + TestGroupAddition.py + TestGroupAddition_Error.py + TestGroupIntersection.py + TestGroupIntersection_Error.py + TestGroupSubstraction.py + TestGroupSubstraction_Error1.py + TestGroupSubstraction_Error2.py ) diff --git a/src/CollectionPlugin/CollectionPlugin_GroupAddition.cpp b/src/CollectionPlugin/CollectionPlugin_GroupAddition.cpp new file mode 100644 index 000000000..c27826ce8 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupAddition.cpp @@ -0,0 +1,87 @@ +// 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_GroupAddition.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +CollectionPlugin_GroupAddition::CollectionPlugin_GroupAddition() +{ +} + +void CollectionPlugin_GroupAddition::initAttributes() +{ + data()->addAttribute(CollectionPlugin_GroupAddition::LIST_ID(), + ModelAPI_AttributeSelectionList::typeId()); +} + +static void explodeCompound(const GeomShapePtr& theCompound, ListOfShape& theSubs) +{ + if (theCompound->isCompound()) { + GeomAPI_ShapeIterator anIt(theCompound); + for (; anIt.more(); anIt.next()) + explodeCompound(anIt.current(), theSubs); + } + else + theSubs.push_back(theCompound); +} + +static void keepUniqueShapes(ListOfShape& theShapes) +{ + ListOfShape::iterator anIt = theShapes.begin(); + while (anIt != theShapes.end()) { + GeomShapePtr aCurrent = *anIt; + ListOfShape::iterator anIt2 = theShapes.begin(); + for (; anIt2 != anIt; ++anIt2) + if (aCurrent->isEqual(*anIt2)) + break; + if (anIt2 != anIt) { + // the same shape is found + ListOfShape::iterator aRemoveIt = anIt++; + theShapes.erase(aRemoveIt); + } + else + ++anIt; + } +} + +void CollectionPlugin_GroupAddition::execute() +{ + ResultGroupPtr aGroup = document()->createGroup(data()); + // clean the result of the operation + aGroup->store(GeomShapePtr()); + + // collect all unique sub-shapes + GeomShapePtr aCompound = aGroup->shape(); + ListOfShape aSubs; + explodeCompound(aCompound, aSubs); + keepUniqueShapes(aSubs); + aCompound = aSubs.empty() ? GeomShapePtr() : GeomAlgoAPI_CompoundBuilder::compound(aSubs); + aGroup->store(aCompound); + + setResult(aGroup); +} diff --git a/src/CollectionPlugin/CollectionPlugin_GroupAddition.h b/src/CollectionPlugin/CollectionPlugin_GroupAddition.h new file mode 100644 index 000000000..17b1ed1c6 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_GroupAddition.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_GROUPADDITION_H_ +#define COLLECTIONPLUGIN_GROUPADDITION_H_ + +#include "CollectionPlugin.h" +#include "CollectionPlugin_Group.h" + +/**\class CollectionPlugin_GroupAddition + * \ingroup Plugins + * \brief Merge several groups of same shape type into single group. + */ +class CollectionPlugin_GroupAddition : public CollectionPlugin_Group +{ + public: + /// Extrusion kind + inline static const std::string& ID() + { + static const std::string MY_GROUP_ID("GroupAddition"); + 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_GroupAddition::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_GroupAddition(); + +}; + +#endif 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_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 7b0fc28e1..8a62c07a8 100644 --- a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include #include @@ -45,6 +48,8 @@ CollectionPlugin_Plugin::CollectionPlugin_Plugin() ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); aFactory->registerValidator("CollectionPlugin_FieldValidator", new CollectionPlugin_FieldValidator); + aFactory->registerValidator("CollectionPlugin_OperationAttribute", + new CollectionPlugin_GroupOperationAttributeValidator); // register this plugin ModelAPI_Session::get()->registerPlugin(this); @@ -56,6 +61,12 @@ FeaturePtr CollectionPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new CollectionPlugin_Group); } else if (theFeatureID == CollectionPlugin_Field::ID()) { 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); + } 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 d644c13f6..7ef185389 100644 --- a/src/CollectionPlugin/CollectionPlugin_Validators.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Validators.cpp @@ -18,8 +18,10 @@ // #include "CollectionPlugin_Validators.h" +#include "CollectionPlugin_Group.h" #include "CollectionPlugin_Field.h" #include +#include #include @@ -42,3 +44,59 @@ bool CollectionPlugin_FieldValidator::isValid(const FeaturePtr& theFeature, theError = "Selection list is not initialized"; 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, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr aSelList = + std::dynamic_pointer_cast(theAttribute); + if (!aSelList) { + theError = "Error: This validator can only work with selection list of attributes"; + return false; + } + + FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner()); + // check selected items + std::string aType; + for (int anIndex = 0; anIndex < aSelList->size(); ++anIndex) { + AttributeSelectionPtr aCurSelection = aSelList->value(anIndex); + if (!isGroupTypeCorrect(aCurSelection, aType, theError)) + return false; + } + // 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/CollectionPlugin_Validators.h b/src/CollectionPlugin/CollectionPlugin_Validators.h index 5932e2c4f..4f5db68d3 100644 --- a/src/CollectionPlugin/CollectionPlugin_Validators.h +++ b/src/CollectionPlugin/CollectionPlugin_Validators.h @@ -21,14 +21,13 @@ #define CollectionPlugin_Validators_H #include "CollectionPlugin.h" +#include #include -/**\class SketchPlugin_SolverErrorValidator -* \ingroup Validators -* \brief Validator for the solver error. -* -* Simply checks that solver error attribute is empty. Returns the attribute value as an error. -*/ +/**\class CollectionPlugin_FieldValidator + * \ingroup Validators + * \brief Validator for the field. + */ class CollectionPlugin_FieldValidator : public ModelAPI_FeatureValidator { public: @@ -41,4 +40,19 @@ public: Events_InfoMessage& theError) const; }; +/**\class CollectionPlugin_GroupOperationAttributeValidator + * \ingroup Validators + * \brief Validator for the parameters of operation on groups. + */ +class CollectionPlugin_GroupOperationAttributeValidator : public ModelAPI_AttributeValidator +{ + //! Returns true if attribute is ok. + //! \param[in] theAttribute the checked attribute. + //! \param[in] theArguments arguments of the attribute. + //! \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + #endif \ No newline at end of file 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/TestGroupAddition.py b/src/CollectionPlugin/Test/TestGroupAddition.py new file mode 100644 index 000000000..a5e88cc4c --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupAddition.py @@ -0,0 +1,42 @@ +# 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")]) +GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")]) +model.end() + +from GeomAPI import * + +model.testNbResults(GroupAddition_1, 1) +model.testNbSubResults(GroupAddition_1, [0]) +model.testNbSubShapes(GroupAddition_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(GroupAddition_1, GeomAPI_Shape.FACE, [3]) +model.testNbSubShapes(GroupAddition_1, GeomAPI_Shape.EDGE, [12]) +model.testNbSubShapes(GroupAddition_1, GeomAPI_Shape.VERTEX, [24]) +model.testResultsVolumes(GroupAddition_1, [300]) + +assert(model.checkPythonDump()) diff --git a/src/CollectionPlugin/Test/TestGroupAddition_Error.py b/src/CollectionPlugin/Test/TestGroupAddition_Error.py new file mode 100644 index 000000000..b69a24939 --- /dev/null +++ b/src/CollectionPlugin/Test/TestGroupAddition_Error.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("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() + +assert(GroupAddition_1.feature().error() != "") 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/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/doc/CollectionPlugin.rst b/src/CollectionPlugin/doc/CollectionPlugin.rst index e31d77823..2b83ddd8c 100644 --- a/src/CollectionPlugin/doc/CollectionPlugin.rst +++ b/src/CollectionPlugin/doc/CollectionPlugin.rst @@ -13,3 +13,6 @@ Collection plug-in deals with groups of geometrical entities created by selectio fieldFeature.rst groupFeature.rst + groupAdditionFeature.rst + groupIntersectionFeature.rst + groupSubstractionFeature.rst diff --git a/src/CollectionPlugin/doc/TUI_groupAdditionFeature.rst b/src/CollectionPlugin/doc/TUI_groupAdditionFeature.rst new file mode 100644 index 000000000..ea9cbaf21 --- /dev/null +++ b/src/CollectionPlugin/doc/TUI_groupAdditionFeature.rst @@ -0,0 +1,11 @@ + + .. _tui_create_group_addition: + +Create Group Addition +===================== + +.. literalinclude:: examples/group_addition.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/CollectionPlugin/doc/TUI_groupIntersectionFeature.rst b/src/CollectionPlugin/doc/TUI_groupIntersectionFeature.rst new file mode 100644 index 000000000..37a7d8df7 --- /dev/null +++ b/src/CollectionPlugin/doc/TUI_groupIntersectionFeature.rst @@ -0,0 +1,11 @@ + + .. _tui_create_group_intersection: + +Create Group Intersection +========================= + +.. literalinclude:: examples/group_intersection.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/CollectionPlugin/doc/TUI_groupSubstractionFeature.rst b/src/CollectionPlugin/doc/TUI_groupSubstractionFeature.rst new file mode 100644 index 000000000..ca836f9f0 --- /dev/null +++ b/src/CollectionPlugin/doc/TUI_groupSubstractionFeature.rst @@ -0,0 +1,11 @@ + + .. _tui_create_group_substraction: + +Create Group Substraction +========================= + +.. literalinclude:: examples/group_substraction.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/CollectionPlugin/doc/examples/group_addition.py b/src/CollectionPlugin/doc/examples/group_addition.py new file mode 100644 index 000000000..20f80fce8 --- /dev/null +++ b/src/CollectionPlugin/doc/examples/group_addition.py @@ -0,0 +1,14 @@ +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")]) +GroupAddition_1 = model.addGroupAddition(Part_1_doc, [model.selection("COMPOUND", "Group_1"), + model.selection("COMPOUND", "Group_2")]) +model.end() diff --git a/src/CollectionPlugin/doc/examples/group_intersection.py b/src/CollectionPlugin/doc/examples/group_intersection.py new file mode 100644 index 000000000..84cb476e0 --- /dev/null +++ b/src/CollectionPlugin/doc/examples/group_intersection.py @@ -0,0 +1,19 @@ +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"), + model.selection("FACE", "Box_1_1/Top")]) +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() diff --git a/src/CollectionPlugin/doc/examples/group_substraction.py b/src/CollectionPlugin/doc/examples/group_substraction.py new file mode 100644 index 000000000..75cf55690 --- /dev/null +++ b/src/CollectionPlugin/doc/examples/group_substraction.py @@ -0,0 +1,33 @@ +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() diff --git a/src/CollectionPlugin/doc/groupAdditionFeature.rst b/src/CollectionPlugin/doc/groupAdditionFeature.rst new file mode 100644 index 000000000..568ca10be --- /dev/null +++ b/src/CollectionPlugin/doc/groupAdditionFeature.rst @@ -0,0 +1,37 @@ +.. |group_addition.icon| image:: images/group_addition.png + +Group Addition +============== + +Group addition produces a union of all the elements of the selected groups. +To create a Group Addition in the active part: + +#. select in the Main Menu *Features - > Group Addition* item or +#. click |group_addition.icon| **Group Addition** button in the toolbar: + +The following property panel appears. + +.. image:: images/group_addition_property_panel.png + :align: center + +.. centered:: + Create a group addition operation + +Input fields: + +- **Name** defines the name of the group, by default, it is **GroupAddition_n**. +- The list of selected groups of the same type. Multiple selection can be done manually in OCC 3D Viewer by mouse click with Shift button pressed or by rectangle selection. To delete entities from the list, select them and call pop-up menu *Delete* item. + +Note, that operation is valid only for the groups of the same type. + +**TUI Command**: + +.. py:function:: model.addGroupAddition(Part_1_doc, + [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")]) + + :param part: The current part object + :param list: A list of selected groups + :return: Created object. + + +**See Also** a sample TUI Script of :ref:`tui_create_group_addition` operation. diff --git a/src/CollectionPlugin/doc/groupIntersectionFeature.rst b/src/CollectionPlugin/doc/groupIntersectionFeature.rst new file mode 100644 index 000000000..dadbd4390 --- /dev/null +++ b/src/CollectionPlugin/doc/groupIntersectionFeature.rst @@ -0,0 +1,37 @@ +.. |group_intersection.icon| image:: images/group_intersection.png + +Group Intersection +================== + +Group intersection produces a group of elements present in all the selected groups. +To create a Group Intersection in the active part: + +#. select in the Main Menu *Features - > Group Intersection* item or +#. click |group_intersection.icon| **Group Intersection** button in the toolbar: + +The following property panel appears. + +.. image:: images/group_intersection_property_panel.png + :align: center + +.. centered:: + Create a group intersection operation + +Input fields: + +- **Name** defines the name of the group, by default, it is **GroupIntersection_n**. +- The list of selected groups of the same type. Multiple selection can be done manually in OCC 3D Viewer by mouse click with Shift button pressed or by rectangle selection. To delete entities from the list, select them and call pop-up menu *Delete* item. + +Note, that operation is valid only for the groups of the same type. + +**TUI Command**: + +.. py:function:: model.addGroupIntersection(Part_1_doc, + [model.selection("COMPOUND", "Group_1"), model.selection("COMPOUND", "Group_2")]) + + :param part: The current part object + :param list: A list of selected groups + :return: Created object. + + +**See Also** a sample TUI Script of :ref:`tui_create_group_intersection` operation. diff --git a/src/CollectionPlugin/doc/groupSubstractionFeature.rst b/src/CollectionPlugin/doc/groupSubstractionFeature.rst new file mode 100644 index 000000000..b6ac22789 --- /dev/null +++ b/src/CollectionPlugin/doc/groupSubstractionFeature.rst @@ -0,0 +1,40 @@ +.. |group_substraction.icon| image:: images/group_substraction.png + +Group Substraction +================== + +Group substraction produces a group containing all elements of the main groups but not present in the tool groups. +To create a Group Substraction in the active part: + +#. select in the Main Menu *Features - > Group Substraction* item or +#. click |group_substraction.icon| **Group Substraction** button in the toolbar: + +The following property panel appears. + +.. image:: images/group_substraction_property_panel.png + :align: center + +.. centered:: + Create a group substraction operation + +Input fields: + +- **Name** defines the name of the group, by default, it is **GroupSubstraction_n**. +- The list of main groups. Multiple selection can be done manually in OCC 3D Viewer by mouse click with Shift button pressed or by rectangle selection. To delete entities from the list, select them and call pop-up menu *Delete* item. +- The list of tool groups. Selection approaches are the same as for the main groups. + +Note, that operation is valid only if all the main groups and all the tool groups have the same type. + +**TUI Command**: + +.. py:function:: 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")]) + + :param part: The current part object + :param list: A list of main groups + :param list: A list of tool groups + :return: Created object. + + +**See Also** a sample TUI Script of :ref:`tui_create_group_substraction` operation. diff --git a/src/CollectionPlugin/doc/images/group_addition.png b/src/CollectionPlugin/doc/images/group_addition.png new file mode 100644 index 000000000..6bc76e001 Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_addition.png differ diff --git a/src/CollectionPlugin/doc/images/group_addition_property_panel.png b/src/CollectionPlugin/doc/images/group_addition_property_panel.png new file mode 100644 index 000000000..54904a130 Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_addition_property_panel.png differ diff --git a/src/CollectionPlugin/doc/images/group_intersection.png b/src/CollectionPlugin/doc/images/group_intersection.png new file mode 100644 index 000000000..aba074c2e Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_intersection.png differ diff --git a/src/CollectionPlugin/doc/images/group_intersection_property_panel.png b/src/CollectionPlugin/doc/images/group_intersection_property_panel.png new file mode 100644 index 000000000..54db4935b Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_intersection_property_panel.png differ diff --git a/src/CollectionPlugin/doc/images/group_substraction.png b/src/CollectionPlugin/doc/images/group_substraction.png new file mode 100644 index 000000000..7db75ec26 Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_substraction.png differ diff --git a/src/CollectionPlugin/doc/images/group_substraction_property_panel.png b/src/CollectionPlugin/doc/images/group_substraction_property_panel.png new file mode 100644 index 000000000..543681f83 Binary files /dev/null and b/src/CollectionPlugin/doc/images/group_substraction_property_panel.png differ diff --git a/src/CollectionPlugin/group_addition_widget.xml b/src/CollectionPlugin/group_addition_widget.xml new file mode 100644 index 000000000..6274511c0 --- /dev/null +++ b/src/CollectionPlugin/group_addition_widget.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/CollectionPlugin/group_intersection_widget.xml b/src/CollectionPlugin/group_intersection_widget.xml new file mode 100644 index 000000000..6274511c0 --- /dev/null +++ b/src/CollectionPlugin/group_intersection_widget.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/CollectionPlugin/group_substraction_widget.xml b/src/CollectionPlugin/group_substraction_widget.xml new file mode 100644 index 000000000..b06929b0e --- /dev/null +++ b/src/CollectionPlugin/group_substraction_widget.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/src/CollectionPlugin/icons/group_addition.png b/src/CollectionPlugin/icons/group_addition.png new file mode 100644 index 000000000..6bc76e001 Binary files /dev/null and b/src/CollectionPlugin/icons/group_addition.png differ diff --git a/src/CollectionPlugin/icons/group_intersection.png b/src/CollectionPlugin/icons/group_intersection.png new file mode 100644 index 000000000..aba074c2e Binary files /dev/null and b/src/CollectionPlugin/icons/group_intersection.png differ diff --git a/src/CollectionPlugin/icons/group_substraction.png b/src/CollectionPlugin/icons/group_substraction.png new file mode 100644 index 000000000..7db75ec26 Binary files /dev/null and b/src/CollectionPlugin/icons/group_substraction.png differ diff --git a/src/CollectionPlugin/plugin-Collection.xml b/src/CollectionPlugin/plugin-Collection.xml index 27057f56f..25c6d0c71 100644 --- a/src/CollectionPlugin/plugin-Collection.xml +++ b/src/CollectionPlugin/plugin-Collection.xml @@ -21,6 +21,30 @@ + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp b/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp index c3a387887..f5a45f605 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Pipe.cpp @@ -18,6 +18,7 @@ // #include "FeaturesPlugin_Pipe.h" +#include "FeaturesPlugin_Tools.h" #include #include @@ -373,11 +374,12 @@ void FeaturesPlugin_Pipe::storeResult(const ListOfShape& theBaseShapes, aResultBody->loadGeneratedShapes(thePipeAlgo, thePathShape, GeomAPI_Shape::EDGE); // Store from shapes. - storeShapes(aResultBody, theBaseShapes.front()->shapeType(), thePipeAlgo->fromShapes(), "From_"); + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, thePipeAlgo->fromShapes(), ListOfShape(), + thePipeAlgo, thePipeAlgo->shape(), "From"); // Store to shapes. - storeShapes(aResultBody, theBaseShapes.back()->shapeType(), thePipeAlgo->toShapes(), "To_"); - + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, thePipeAlgo->toShapes(), ListOfShape(), + thePipeAlgo, thePipeAlgo->shape(), "To"); setResult(aResultBody, theResultIndex); } diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index e9c92ad53..ff194dac5 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,9 @@ bool Model_AttributeSelection::setValue(const ObjectPtr& theContext, aSelLab.ForgetAllAttributes(true); TDataStd_UAttribute::Set(aSelLab, kPART_REF_ID); selectPart(std::dynamic_pointer_cast(theContext), theSubShape); + } else if (theContext->groupName() == ModelAPI_ResultGroup::group()) { + aSelLab.ForgetAllAttributes(true); + TDataStd_UAttribute::Set(aSelLab, kSIMPLE_REF_ID); } else { // check the feature context: parent-Part of this feature should not be used FeaturePtr aFeatureContext = std::dynamic_pointer_cast(theContext); if (aFeatureContext.get()) { @@ -892,8 +896,11 @@ void Model_AttributeSelection::selectSubShape( // the whole result selection check if (aSubShapeName.find('/') == std::string::npos) { ObjectPtr aRes = aDoc->objectByName(ModelAPI_ResultConstruction::group(), aSubShapeName); - if (!aRes.get()) + if (!aRes.get()) { aRes = aDoc->objectByName(ModelAPI_ResultBody::group(), aSubShapeName); + if (!aRes.get()) + aRes = aDoc->objectByName(ModelAPI_ResultGroup::group(), aSubShapeName); + } if (aRes.get()) { setValue(aRes, anEmptyShape); return; diff --git a/src/Model/Model_ResultGroup.cpp b/src/Model/Model_ResultGroup.cpp index 7a4c5cfaf..87d1620f6 100644 --- a/src/Model/Model_ResultGroup.cpp +++ b/src/Model/Model_ResultGroup.cpp @@ -18,12 +18,19 @@ // #include +#include #include #include #include +#include +#include +#include +#include +#include + Model_ResultGroup::Model_ResultGroup(std::shared_ptr theOwnerData) { myOwnerData = theOwnerData; @@ -40,7 +47,25 @@ void Model_ResultGroup::colorConfigInfo(std::string& theSection, std::string& th std::shared_ptr Model_ResultGroup::shape() { std::shared_ptr aResult; - if (myOwnerData) { + // obtain stored shape + std::shared_ptr aData = std::dynamic_pointer_cast(data()); + if (aData && aData->isValid()) { + TDF_Label aShapeLab = aData->shapeLab(); + Handle(TDF_Reference) aRef; + if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) { + aShapeLab = aRef->Get(); + } + Handle(TNaming_NamedShape) aName; + if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) { + TopoDS_Shape aShape = aName->Get(); + if (!aShape.IsNull()) { + aResult.reset(new GeomAPI_Shape); + aResult->setImpl(new TopoDS_Shape(aShape)); + } + } + } + // collect shapes selected in group + if (!aResult && myOwnerData) { AttributeSelectionListPtr aList = myOwnerData->selectionList("group_list"); if (aList) { std::list > aSubs; @@ -57,3 +82,23 @@ std::shared_ptr Model_ResultGroup::shape() } return aResult; } + +void Model_ResultGroup::store(const GeomShapePtr& theShape) +{ + std::shared_ptr aData = std::dynamic_pointer_cast(data()); + if (aData) { + TDF_Label aShapeLab = aData->shapeLab(); + aShapeLab.ForgetAttribute(TDF_Reference::GetID()); + aShapeLab.ForgetAttribute(TNaming_NamedShape::GetID()); + + if (!theShape) + return; // bad shape + TopoDS_Shape aShape = theShape->impl(); + if (aShape.IsNull()) + return; // null shape inside + + // store the new shape as primitive + TNaming_Builder aBuilder(aShapeLab); + aBuilder.Generated(aShape); + } +} diff --git a/src/Model/Model_ResultGroup.h b/src/Model/Model_ResultGroup.h index aa0c068dd..68e549d32 100644 --- a/src/Model/Model_ResultGroup.h +++ b/src/Model/Model_ResultGroup.h @@ -41,6 +41,11 @@ public: /// Returns the compound of selected entities MODEL_EXPORT virtual std::shared_ptr shape(); + /// \brief Stores the result of operation made on groups. + /// Cleans the storage if empty shape is given. + /// param[in] theShape shape to store. + MODEL_EXPORT virtual void store(const GeomShapePtr& theShape); + /// Removes the stored builders MODEL_EXPORT virtual ~Model_ResultGroup() {} diff --git a/src/ModelAPI/ModelAPI_ResultGroup.h b/src/ModelAPI/ModelAPI_ResultGroup.h index 8644fc1cf..040f2a05c 100644 --- a/src/ModelAPI/ModelAPI_ResultGroup.h +++ b/src/ModelAPI/ModelAPI_ResultGroup.h @@ -52,6 +52,11 @@ public: return RESULT_GROUP_COLOR; } + /// \brief Stores the result of operation made on groups. + /// Cleans the storage if empty shape is given. + /// param[in] theShape shape to store. + MODELAPI_EXPORT virtual void store(const GeomShapePtr& theShape) + {} }; //! Pointer on feature object diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 409f1b430..ef6f1ee62 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -289,7 +290,8 @@ static void getShapeAndContext(const AttributeSelectionPtr& theAttrSelect, if (theAttrSelect->isGeometricalSelection() && theShape.get() && theShape->shapeType() == GeomAPI_Shape::COMPOUND && theContext.get() && !theShape->isEqual(theContext->shape()) && - theContext->groupName() != ModelAPI_ResultPart::group()) { + theContext->groupName() != ModelAPI_ResultPart::group() && + theContext->groupName() != ModelAPI_ResultGroup::group()) { GeomAPI_ShapeIterator anIt(theShape); theShape = anIt.current(); } diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index b528344ce..40d74c1d2 100644 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -1299,6 +1299,28 @@ std::string generateName(const AttributePtr& theAttribute, return aName; } +bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2) +{ + // In case of compound we cannot rely on simple comparison method. + // If the compound is generated by Group feature then this compound is alwais new. + // So, we have to compare content of these compounds + if (theShape1.ShapeType() != theShape2.ShapeType()) + return false; + + if (theShape1.ShapeType() != TopAbs_COMPOUND) + return theShape1.IsSame(theShape2); + + TopoDS_Iterator aIt1(theShape1); + TopoDS_Iterator aIt2(theShape2); + + for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) { + if (!(aIt1.Value()).IsSame(aIt2.Value())) + return false; + } + return true; +} + + } // namespace ModuleBase_Tools diff --git a/src/ModuleBase/ModuleBase_Tools.h b/src/ModuleBase/ModuleBase_Tools.h index 4523b7d80..d6e4c4c55 100644 --- a/src/ModuleBase/ModuleBase_Tools.h +++ b/src/ModuleBase/ModuleBase_Tools.h @@ -389,6 +389,12 @@ bool MODULEBASE_EXPORT isNameExist(const QString& theName, FeaturePtr theIgnoreP /// \theName a name of parameter FeaturePtr MODULEBASE_EXPORT findParameter(const QString& theName); +/// Returns true if both shapes are the same. In case of compounds it +/// compares their contents. +/// \param theShape1 a first shape to compare +/// \param theShape2 a second shape to compare +/// \return true if both shapes are the same +bool MODULEBASE_EXPORT isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2); //----------- Class members ------------- /// Returns a name in the next form: attribute_feature_name/attribute_id diff --git a/src/PartSet/PartSet_Filters.cpp b/src/PartSet/PartSet_Filters.cpp index b7e5ccbb1..582161ace 100644 --- a/src/PartSet/PartSet_Filters.cpp +++ b/src/PartSet/PartSet_Filters.cpp @@ -63,8 +63,7 @@ Standard_Boolean PartSet_GlobalFilter::IsOk(const Handle(SelectMgr_EntityOwner)& if (aResultGroupName == ModelAPI_ResultPart::group()) { SessionPtr aMgr = ModelAPI_Session::get(); aValid = aMgr->activeDocument() == aMgr->moduleDocument(); - } else if (aResultGroupName == ModelAPI_ResultGroup::group() || - aResultGroupName == ModelAPI_ResultField::group()) { + } else if (aResultGroupName == ModelAPI_ResultField::group()) { aValid = Standard_False; } else aValid = Standard_True; diff --git a/src/PartSet/PartSet_IconFactory.cpp b/src/PartSet/PartSet_IconFactory.cpp index 2b8118487..abe6aa025 100644 --- a/src/PartSet/PartSet_IconFactory.cpp +++ b/src/PartSet/PartSet_IconFactory.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -35,8 +36,6 @@ #include #include -#include - QMap PartSet_IconFactory::myIcons; PartSet_IconFactory::PartSet_IconFactory(PartSet_Module* theModule) @@ -128,8 +127,7 @@ QIcon PartSet_IconFactory::getIcon(ObjectPtr theObj) if(aShape.get()) { switch(aShape->shapeType()) { case GeomAPI_Shape::COMPOUND: { - FeaturePtr aFeature = ModelAPI_Feature::feature(theObj); - if (aFeature.get() && aFeature->getKind() == CollectionPlugin_Group::ID()) { + if (aResult->groupName() == ModelAPI_ResultGroup::group()) { switch (aShape->typeOfCompoundShapes()) { case GeomAPI_Shape::VERTEX: return QIcon(":icons/group_vertex.png"); diff --git a/src/PythonAPI/model/collection/__init__.py b/src/PythonAPI/model/collection/__init__.py index 5718df5f5..695d5303d 100644 --- a/src/PythonAPI/model/collection/__init__.py +++ b/src/PythonAPI/model/collection/__init__.py @@ -20,3 +20,4 @@ """ from CollectionAPI import addGroup, addField +from CollectionAPI import addGroupAddition, addGroupIntersection, addGroupSubstraction diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 23753cf8c..099d61ad0 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -1097,17 +1097,21 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th ::Iterator aShapeIt(theShapesToBeSelected); for (; aShapeIt.More(); aShapeIt.Next()) { const TopoDS_Shape& aParameterShape = aShapeIt.Key(); - // isSame should be used here as it does not check orientation of shapes - // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is - // different for Edges shapes in model shape and owner even if this is the same shape - if (aParameterShape.IsSame(aShape)) { + // In case of compound we cannot rely on simple comparison method. + // If the compound is generated by Group feature then this compound is alwais new. + // So, we have to compare content of these compounds + + // isSame should be used here as it does not check orientation of shapes + // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is + // different for Edges shapes in model shape and owner even if this is the same shape + if (ModuleBase_Tools::isSameShape(aParameterShape, aShape)) { Handle(AIS_InteractiveObject) anOwnerPresentation = - Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); + Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); NCollection_Map aPresentations = - theShapesToBeSelected.Find(aParameterShape); + theShapesToBeSelected.Find(aParameterShape); if (aPresentations.Contains(anOwnerPresentation)) { theContext->AddOrRemoveSelected(anOwner, Standard_False); - anOwner->SetSelected (Standard_True); + anOwner->SetSelected(Standard_True); // collect selected presentations to do not select them if compsolid is selected if (!aSelectedPresentations.Contains(anOwnerPresentation)) aSelectedPresentations.Add(anOwnerPresentation);