From 3a00d9ec824b8580b913fa247905faca35ceac5c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Wed, 4 Nov 2020 12:25:52 +0100 Subject: [PATCH] Implementation of inspection shared faces --- src/FeaturesAPI/CMakeLists.txt | 2 + src/FeaturesAPI/FeaturesAPI.i | 2 + src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp | 98 +++++++++ src/FeaturesAPI/FeaturesAPI_SharedFaces.h | 85 ++++++++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesPlugin/CMakeLists.txt | 31 ++- src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 3 + .../FeaturesPlugin_SharedFaces.cpp | 188 ++++++++++++++++++ .../FeaturesPlugin_SharedFaces.h | 111 +++++++++++ src/FeaturesPlugin/icons/shared_shapes.png | Bin 0 -> 583 bytes src/FeaturesPlugin/plugin-Features.xml | 8 +- src/FeaturesPlugin/sharedFaces_widget.xml | 34 ++++ src/GeomAlgoAPI/CMakeLists.txt | 3 + src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.cpp | 151 ++++++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.h | 38 ++++ src/ModelAPI/CMakeLists.txt | 8 +- src/ModuleBase/ModuleBase_ListView.cpp | 32 +-- src/ModuleBase/ModuleBase_ListView.h | 3 +- .../ModuleBase_WidgetMultiSelector.cpp | 27 ++- .../ModuleBase_WidgetMultiSelector.h | 5 +- src/PythonAPI/model/features/__init__.py | 1 + 21 files changed, 795 insertions(+), 36 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_SharedFaces.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h create mode 100644 src/FeaturesPlugin/icons/shared_shapes.png create mode 100644 src/FeaturesPlugin/sharedFaces_widget.xml create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.h diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 0b8e3055c..53c310cc1 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS FeaturesAPI_Fillet.h FeaturesAPI_Intersection.h FeaturesAPI_Measurement.h + FeaturesAPI_SharedFaces.h FeaturesAPI_MultiRotation.h FeaturesAPI_MultiTranslation.h FeaturesAPI_Partition.h @@ -65,6 +66,7 @@ SET(PROJECT_SOURCES FeaturesAPI_Fillet.cpp FeaturesAPI_Intersection.cpp FeaturesAPI_Measurement.cpp + FeaturesAPI_SharedFaces.cpp FeaturesAPI_MultiRotation.cpp FeaturesAPI_MultiTranslation.cpp FeaturesAPI_Partition.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index b76fd2dc4..84ae0cc8a 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -63,6 +63,7 @@ %shared_ptr(FeaturesAPI_BooleanSmash) %shared_ptr(FeaturesAPI_BooleanFill) %shared_ptr(FeaturesAPI_Chamfer) +%shared_ptr(FeaturesAPI_SharedFaces) %shared_ptr(FeaturesAPI_Extrusion) %shared_ptr(FeaturesAPI_ExtrusionBoolean) %shared_ptr(FeaturesAPI_ExtrusionCut) @@ -211,6 +212,7 @@ %include "FeaturesAPI_Fillet.h" %include "FeaturesAPI_Intersection.h" %include "FeaturesAPI_Measurement.h" +%include "FeaturesAPI_SharedFaces.h" %include "FeaturesAPI_MultiRotation.h" %include "FeaturesAPI_MultiTranslation.h" %include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp b/src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp new file mode 100644 index 000000000..1b704f7d1 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2018-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesAPI_SharedFaces.h" + +#include +#include +#include +#include + +#include +#include +#include + + +FeaturesAPI_SharedFaces:: + FeaturesAPI_SharedFaces(const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +FeaturesAPI_SharedFaces::FeaturesAPI_SharedFaces( + const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theobject, + const double theTransparency, + const std::string & theNameGroup) +:ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theobject, myobjectselected); + fillAttribute(theTransparency, mytransparency); + if( theNameGroup != "" ) + { + fillAttribute(true, + feature()->boolean(FeaturesPlugin_SharedFaces::CREATE_GROUP_ID())); + fillAttribute(theNameGroup, mygroupname); + } + execute(); + } +} + + +FeaturesAPI_SharedFaces::~FeaturesAPI_SharedFaces() +{ +} + +void FeaturesAPI_SharedFaces::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionPtr anAttrObject; + anAttrObject = aBase->selection(FeaturesPlugin_SharedFaces::OBJECT_ID()); + + theDumper << aBase << " = model.getSharedFaces(" << aDocName << ", " << anAttrObject; + theDumper << ", " << aBase->integer(FeaturesPlugin_SharedFaces::TRANSPARENCY_ID()); + + if(aBase->boolean(FeaturesPlugin_SharedFaces::CREATE_GROUP_ID())->value() ) + theDumper << ", " << aBase->string(FeaturesPlugin_SharedFaces::GROUP_NAME_ID()); + + theDumper << ")" << std::endl; +} + +SharedFacesPtr getSharedFaces(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theobject, + const double theTransparency, + const std::string & theNameGroup) +{ + + FeaturePtr aFeature = thePart->addFeature(FeaturesPlugin_SharedFaces::ID()); + + SharedFacesPtr aSharedFaces; + + aSharedFaces.reset(new FeaturesAPI_SharedFaces(aFeature, + theobject, + theTransparency, + theNameGroup)); + + return aSharedFaces; +} + diff --git a/src/FeaturesAPI/FeaturesAPI_SharedFaces.h b/src/FeaturesAPI/FeaturesAPI_SharedFaces.h new file mode 100644 index 000000000..e97f8e35f --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_SharedFaces.h @@ -0,0 +1,85 @@ +// Copyright (C) 2018-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeaturesAPI_SharedFaces_H_ +#define FeaturesAPI_SharedFaces_H_ + +#include "FeaturesAPI.h" + +#include "FeaturesPlugin_SharedFaces.h" + +#include +#include + +#include + +class ModelAPI_Document; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_SharedFaces +/// \ingroup CPPHighAPI +/// \brief Interface to find shared faces +class FeaturesAPI_SharedFaces: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_SharedFaces(const std::shared_ptr& theFeature); + + FEATURESAPI_EXPORT + explicit FeaturesAPI_SharedFaces(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theobject, + const double theTransparency, + const std::string & theNameGroup); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_SharedFaces(); + + INTERFACE_3(FeaturesPlugin_SharedFaces::ID(), + objectselected, FeaturesPlugin_SharedFaces::OBJECT_ID(), + ModelAPI_AttributeSelection, + /** object selected*/, + transparency, FeaturesPlugin_SharedFaces::TRANSPARENCY_ID(), + ModelAPI_AttributeInteger, + /** transparency*/, + groupname, FeaturesPlugin_SharedFaces::GROUP_NAME_ID(), + ModelAPI_AttributeString, + /** group name*/) + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; + +}; + +/// Pointer on the SharedFaces object. +typedef std::shared_ptr SharedFacesPtr; + +/// \ingroup CPPHighAPI +/// \brief get the Shared Faces +/// \param thePart the part +/// \param theobject the object selected +FEATURESAPI_EXPORT +SharedFacesPtr getSharedFaces(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theObject, + const double theTransparency = 0.0, + const std::string & theNameGroup = ""); + +#endif // FeaturesAPI_SharedFaces_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index 17ada7187..1f5198cde 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -35,6 +35,7 @@ #include "FeaturesAPI_Fillet.h" #include "FeaturesAPI_Intersection.h" #include "FeaturesAPI_Measurement.h" + #include "FeaturesAPI_SharedFaces.h" #include "FeaturesAPI_MultiRotation.h" #include "FeaturesAPI_MultiTranslation.h" #include "FeaturesAPI_Partition.h" diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index c93c66a17..31031d118 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -19,6 +19,17 @@ INCLUDE(Common) INCLUDE(UnitTest) +INCLUDE(UseQtExt) + +# additional include directories +INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GeomDataAPI + ${PROJECT_SOURCE_DIR}/src/Locale + ${PROJECT_SOURCE_DIR}/src/PrimitivesPlugin + ${QT_INCLUDES}) + +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS}) + SET(PROJECT_HEADERS FeaturesPlugin.h @@ -59,6 +70,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_Fillet.h FeaturesPlugin_Fillet1D.h FeaturesPlugin_Measurement.h + FeaturesPlugin_SharedFaces.h FeaturesPlugin_FusionFaces.h FeaturesPlugin_RemoveResults.h FeaturesPlugin_Chamfer.h @@ -66,6 +78,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_ImportResult.h FeaturesPlugin_Defeaturing.h FeaturesPlugin_VersionedChFi.h + ) SET(PROJECT_SOURCES @@ -106,6 +119,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_Fillet.cpp FeaturesPlugin_Fillet1D.cpp FeaturesPlugin_Measurement.cpp + FeaturesPlugin_SharedFaces.cpp FeaturesPlugin_FusionFaces.cpp FeaturesPlugin_RemoveResults.cpp FeaturesPlugin_Chamfer.cpp @@ -144,6 +158,7 @@ SET(XML_RESOURCES fillet_widget.xml fillet1d_widget.xml measurement_widget.xml + sharedFaces_widget.xml fusion_faces_widget.xml chamfer_widget.xml copy_widget.xml @@ -157,6 +172,12 @@ SET(TEXT_RESOURCES FeaturesPlugin_msg_ru.ts ) +# sources / moc wrappings +QT_WRAP_MOC(PROJECT_AUTOMOC ${PROJECT_MOC_HEADERS}) + +#QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) + +SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("XML Files" FILES ${XML_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES}) @@ -166,6 +187,7 @@ INCLUDE_DIRECTORIES( ../GeomAPI ../GeomAlgoAPI ../GeomValidators + ../ModuleBase ../Events ../Config ${OpenCASCADE_INCLUDE_DIR} @@ -182,7 +204,12 @@ SET(PROJECT_LIBRARIES ) ADD_DEFINITIONS(-DFEATURESPLUGIN_EXPORTS) -ADD_LIBRARY(FeaturesPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES}) +ADD_LIBRARY(FeaturesPlugin MODULE + ${PROJECT_SOURCES} + ${PROJECT_HEADERS} + ${XML_RESOURCES} + ${TEXT_RESOURCES} + ${PROJECT_AUTOMOC}) TARGET_LINK_LIBRARIES(FeaturesPlugin ${PROJECT_LIBRARIES}) INSTALL(TARGETS FeaturesPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) @@ -682,6 +709,4 @@ ADD_UNIT_TESTS(TestExtrusion.py TestFillet1D_Wire_3.py TestFillet1D_Wire_4.py TestFillet1D_Wire_5.py - Test19931.py - Test20027.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 0d49dfe08..7f6ef48f3 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Fillet1D); } else if (theFeatureID == FeaturesPlugin_Measurement::ID()) { return FeaturePtr(new FeaturesPlugin_Measurement); + } else if (theFeatureID == FeaturesPlugin_SharedFaces::ID()) { + return FeaturePtr(new FeaturesPlugin_SharedFaces); } else if (theFeatureID == FeaturesPlugin_RemoveResults::ID()) { return FeaturePtr(new FeaturesPlugin_RemoveResults); } else if (theFeatureID == FeaturesPlugin_Chamfer::ID()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp new file mode 100644 index 000000000..6eb6d6e5b --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp @@ -0,0 +1,188 @@ +// Copyright (C) 2018-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesPlugin_SharedFaces.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +FeaturesPlugin_SharedFaces::FeaturesPlugin_SharedFaces() +{ +} + +void FeaturesPlugin_SharedFaces::initAttributes() +{ + // attribute for object selected + data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + AttributeSelectionListPtr aList = std::dynamic_pointer_cast( + data()->addAttribute(LIST_FACES_ID(), ModelAPI_AttributeSelectionList::typeId())); + + data()->addAttribute(NUMBER_FACES_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(CREATE_GROUP_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(GROUP_NAME_ID(), ModelAPI_AttributeString::typeId()); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), GROUP_NAME_ID()); + boolean(CREATE_GROUP_ID())->setValue(false); +} + +void explodeCompound(const GeomShapePtr& theCompound, ListOfShape& theSubs) +{ + if (theCompound->isCompound() || theCompound->isCompSolid() ) { + GeomAPI_ShapeIterator anIt(theCompound); + for (; anIt.more(); anIt.next()) + explodeCompound(anIt.current(), theSubs); + } + else + theSubs.push_back(theCompound); +} + + + +void FeaturesPlugin_SharedFaces::execute() +{ + if(boolean(CREATE_GROUP_ID())->value() + && selectionList(LIST_FACES_ID())->isInitialized() + && string(GROUP_NAME_ID())->value() != "" ) + { + AttributeStringPtr aNameAtt = string( GROUP_NAME_ID() ) ; + std::wstring aNameFace = aNameAtt->isUValue() ? + Locale::Convert::toWString(aNameAtt->valueU()) : + Locale::Convert::toWString(aNameAtt->value()); + + + setFacesGroup(aNameFace); + } + if( selection(OBJECT_ID())->isInitialized() ) + { + AttributeSelectionPtr ancompSolidAttr = selection(OBJECT_ID()); + ResultPtr aResult = ancompSolidAttr->context(); + + double aTranparency = integer(TRANSPARENCY_ID())->value()/100.0; + ModelAPI_Tools::setTransparency(aResult, aTranparency); + + ResultBodyPtr aResultBody = std::dynamic_pointer_cast(aResult); + std::list allRes; + ModelAPI_Tools::allSubs(aResultBody, allRes); + std::list::iterator aRes; + for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + ModelAPI_Tools::setTransparency(*aRes, aTranparency); + } + } +} + +void FeaturesPlugin_SharedFaces::attributeChanged(const std::string& theID) +{ + if (theID == OBJECT_ID()) { + AttributeSelectionPtr ancompSolidAttr = selection(OBJECT_ID()); + + GeomShapePtr aShape = ancompSolidAttr->value(); + if (aShape.get() && ancompSolidAttr->context().get()) { + + aShape = ancompSolidAttr->context()->shape(); + if(aShape){ + std::string anError; + ListOfShape aFaces; + ListOfShape theSubs; + explodeCompound(aShape, theSubs); + if( !GetSharedredFaces( theSubs, + aFaces, + true, + anError)) + setError("Error in GetSharedredFaces calculation :" + anError); + + AttributeSelectionListPtr aFacesListAttr = + std::dynamic_pointer_cast + (attribute(LIST_FACES_ID())); + + if ( aFacesListAttr->isInitialized()) + aFacesListAttr->clear(); + + aFacesListAttr->setSelectionType("face"); + + ListOfShape::const_iterator anIt = aFaces.cbegin(); + for(; anIt != aFaces.cend(); ++anIt) { + + GeomShapePtr aFacePtr = *anIt; + + if (!aFacePtr.get()) { + setError("GetSharedredFaces : An invalid face found " + anError); + } + aFacesListAttr->append( ancompSolidAttr->context(), aFacePtr); + } + std::stringstream alabel; + alabel << "Number of shared faces : " << aFacesListAttr->size(); + string(NUMBER_FACES_ID() )->setValue( alabel.str() ); + + } + } + } +} + +void FeaturesPlugin_SharedFaces::setFacesGroup(const std::wstring& theName ) +{ + std::vector aColor; + ResultGroupPtr aGroup = document()->createGroup(data()); + // clean the result of the operation + aGroup->data()->setName(theName); + aGroup->store(GeomShapePtr()); + + // shapes containing in group + ListOfShape aFaces; + AttributeSelectionListPtr aFacesListAttr = + std::dynamic_pointer_cast + (attribute(LIST_FACES_ID())); + + for(int anI =0; anI< aFacesListAttr->size(); anI++ ) + { + AttributeSelectionPtr aAtt = aFacesListAttr->value(anI); + aFaces.push_back( aAtt->value() ); + } + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aFaces); + aGroup->store(aCompound); + aColor = {255,0,0}; + setResult(aGroup); + ModelAPI_Tools::setColor( lastResult(),aColor); + +} + diff --git a/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h new file mode 100644 index 000000000..75dd1e3b3 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h @@ -0,0 +1,111 @@ +// Copyright (C) 2018-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeaturesPlugin_SharedFaces_H_ +#define FeaturesPlugin_SharedFaces_H_ + +#include "FeaturesPlugin.h" +#include + +#include +#include +#include + +/// \class FeaturesPlugin_SharedFaces +/// \ingroup Plugins +/// \brief Feature to check the shared faces of solid + +class FeaturesPlugin_SharedFaces : public ModelAPI_Feature +{ +public: + inline static const std::string& ID() + { + static const std::string MY_ID("Shared_faces"); + return MY_ID; + } + + /// \return the kind of a feature. + virtual const std::string& getKind() + { + return ID(); + } + + /// Attribute name for object selected. + inline static const std::string& OBJECT_ID() + { + static const std::string MY_OBJECT_ID("main_object"); + return MY_OBJECT_ID; + } + + /// Attribute name for number of faces. + inline static const std::string& NUMBER_FACES_ID() + { + static const std::string MY_NUMBER_FACES_ID("number_shared_faces"); + return MY_NUMBER_FACES_ID; + } + + /// Attribute name for z coodinate. + inline static const std::string& LIST_FACES_ID() + { + static const std::string MY_LIST_FACES_ID("faces"); + return MY_LIST_FACES_ID; + } + + /// Attribute name for transparency. + inline static const std::string& TRANSPARENCY_ID() + { + static const std::string MY_TRANSPARENCY_ID("transparency"); + return MY_TRANSPARENCY_ID; + } + + /// Attribute name for checkbox create group. + inline static const std::string& CREATE_GROUP_ID() + { + static const std::string MY_CREATE_GROUP_ID("create_group"); + return MY_CREATE_GROUP_ID; + } + + /// Attribute name for group name. + inline static const std::string& GROUP_NAME_ID() + { + static const std::string MY_GROUP_NAME_ID("group_name"); + return MY_GROUP_NAME_ID; + } + + /// Performs the algorithm and stores results it in the data structure. + FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + + /// Use plugin manager for features creation + FeaturesPlugin_SharedFaces(); + + private: + + //Set group of faces + void setFacesGroup(const std::wstring& theName ); + +}; + +#endif diff --git a/src/FeaturesPlugin/icons/shared_shapes.png b/src/FeaturesPlugin/icons/shared_shapes.png new file mode 100644 index 0000000000000000000000000000000000000000..23f804802251319855cadf3afb9bdabb5182e900 GIT binary patch literal 583 zcmV-N0=WH&P)bgGWIS@MM7DVsg zT;{Y$DPd*+G)+U(G}Lv?dcEE@O|yle1kO1`q-skICn*>%Fqoz*B@Fc)W9X*W+AKNZWNCW(f&_Xpg5lBUL3vMMO}M17Qe(?qQFJ zKuXk2^K8;nXaPRFT`wFbH-CcQJrV+{Qf4+2UIQP;JLBg2&%e}7LseCzlt^Y+8tSX6 z?C<~Ky(4%}kT4_M1HX<0+-Ovi3dwBv&QxcF!FxmkDuSxa2zS6&=8L|S5QwUXN=YrR zV2p8SV$?E1Q^E(}_o7C5EXK4%LV0LrsK}r=C93N1S)8l= + icon="icons/Features/fusion_faces.png" auto_preview="true" helpfile="FeaturesPlugin/fusionFacesFeature.html"> + + + + + diff --git a/src/FeaturesPlugin/sharedFaces_widget.xml b/src/FeaturesPlugin/sharedFaces_widget.xml new file mode 100644 index 000000000..960c960c6 --- /dev/null +++ b/src/FeaturesPlugin/sharedFaces_widget.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 95e749c10..abf161530 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -33,6 +33,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Prism.h GeomAlgoAPI_Revolution.h GeomAlgoAPI_Boolean.h + GeomAlgoAPI_SharedFaces.h GeomAlgoAPI_ThroughAll.h GeomAlgoAPI_Rotation.h GeomAlgoAPI_Translation.h @@ -98,6 +99,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Prism.cpp GeomAlgoAPI_Revolution.cpp GeomAlgoAPI_Boolean.cpp + GeomAlgoAPI_SharedFaces.cpp GeomAlgoAPI_ThroughAll.cpp GeomAlgoAPI_Rotation.cpp GeomAlgoAPI_Translation.cpp @@ -176,6 +178,7 @@ INCLUDE_DIRECTORIES( ../GeomAlgoImpl ../ModelAPI ../XAO + ${PROJECT_SOURCE_DIR}/src/Locale ${OpenCASCADE_INCLUDE_DIR} ) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.cpp new file mode 100644 index 000000000..69355238f --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.cpp @@ -0,0 +1,151 @@ +// Copyright (C) 2014-2020 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 "GeomAlgoAPI_SharedFaces.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//function : GetSharedShapes +//purpose : +// +// NOTE on the implementation +// +// 1) Resulting sub-shapes are published as a children of the 1st input shape +// from theShapes list. Due to this reason only direct sub-shapes of the 1st +// shape can be contained in the result of the operation (i.e. shares between +// 2nd/3rd, etc couples cannot be retrieved. +// 2) An exception from above case is when a single compound is specified as an +// input. In this case we search shares between its top-level content, so we +// are able to search shares between all possible couples of shapes. +// 3) Parameter theMultiShare controls what types of shares to search: +// - True: get sub-shapes that are shared between ALL input shapes; +// - False: get shares between couples of input sub-shapes (see points 1 and 2). +// +// Thus, we have the following cases: +// [1] theShapes = N shapes (N>1), theMultiShare = True +// Result: sub-shapes that are shared by all theShapes +// [2] theShapes = N shapes (N>1), theMultiShare = False +// Result: sub-shapes of 1st shape from theShapes that are shared with any shape +// from theShapes +// [3] theShapes = 1 shape, theMultiShare = True +// Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0] +// [4] theShapes = 1 shape, theMultiShare = False +// Result: sub-shapes of all possible couples of all top-level sub-objects of +// theShapes[0]. +//======================================================================= +//================================================================================================= +bool GetSharedredFaces( const ListOfShape& theShapes, + ListOfShape & theFaces, + const bool theMultiShare, + std::string& theError) +{ + + #ifdef _DEBUG + std::cout << "GetSharedredFaces " << std::endl; + #endif + int aLen = theShapes.size(); + if (aLen < 1) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_FACE; + + TopoDS_Shape aShape; + TopTools_SequenceOfShape aShapesSeq; + + ListOfShape::const_iterator anIt = theShapes.cbegin(); + + for(; anIt != theShapes.cend(); ++anIt) { + + GeomShapePtr aShapePtr = *anIt; + + if (!aShapePtr.get()) { + theError = "GetSharedredFaces : An invalid argument"; + return false; + } + aShape = aShapePtr->impl(); + aShapesSeq.Append( aShape ); + } + + // if only single shape is specified as input + // collect all ites top-level sub-shapes for processing + if ( aShapesSeq.Length() == 1 ) + { + aShape = aShapesSeq.First(); + aShapesSeq.Clear(); + for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() ) + aShapesSeq.Append( it.Value() ); + } + + TopTools_MapOfShape mapShape; + + // find shared shapes + + // number of iterations + int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : aShapesSeq.Length()-1; + // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared) + int nbShares = theMultiShare ? aShapesSeq.Length()-1 : 1; + + for ( int iter = 1; iter <= nbIters; iter++) { + for ( int ind = iter+1; ind <= aShapesSeq.Length(); ind++) { + if ( ind-1+nbShares > aShapesSeq.Length() ) break; + TopoDS_Compound aCurrSelection; + TopoDS_Shape aShape1 = aShapesSeq.Value( iter ); + TopTools_IndexedMapOfShape mapSelected; + TopExp::MapShapes(aShape1, aShapeType, mapSelected); + for ( int s = 0; s < nbShares; s++ ) { + BRep_Builder B; + TopoDS_Compound aCompound; + B.MakeCompound(aCompound); + const TopoDS_Shape& aShape2 = aShapesSeq.Value( ind+s ); + TopTools_MapOfShape mapShape2; + TopExp_Explorer exp (aShape2, aShapeType); + for (; exp.More(); exp.Next()) { + const TopoDS_Shape& aSS = exp.Current(); + if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) { + B.Add(aCompound, aSS); + } + } + mapSelected.Clear(); + aCurrSelection = aCompound; + TopExp::MapShapes(aCurrSelection, aShapeType, mapSelected); + } + TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True); + for (; itSel.More(); itSel.Next()) { + const TopoDS_Shape& aSS = itSel.Value(); + GeomShapePtr aS(new GeomAPI_Shape); + aS->setImpl(new TopoDS_Shape(aSS)); + if (mapShape.Add(aSS) ) + theFaces.push_back(aS); + } + } + } + return true; +} + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.h b/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.h new file mode 100644 index 000000000..c201c9680 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SharedFaces.h @@ -0,0 +1,38 @@ +// Copyright (C) 2014-2020 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 GEOMALGOAPI_SHAREDFACES_H_ +#define GEOMALGOAPI_SHAREDFACES_H_ + +#include +#include +#include + +/// get the boundin box of theshape. + /// \param theShape the shape + /// \param theTolerance precise TRUE for precise computation; FALSE for fast one. + /// \param theFaces the faces shared + /// \param theError error +GEOMALGOAPI_EXPORT +bool GetSharedredFaces( const ListOfShape& theShapes, + ListOfShape & theFaces, + const bool theMultiShare, + std::string& theError); + +#endif //GEOMALGOAPI_SHAREDFACES_H_ diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index dd2f4acd9..7b7876165 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -117,7 +117,7 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES Config GeomAPI - Locale + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473) ADD_DEFINITIONS(-DMODELAPI_EXPORTS) @@ -131,6 +131,10 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ${PROJECT_SOURCE_DIR}/src/Locale + ${OpenCASCADE_INCLUDE_DIR} + ${OpenCASCADE_DataExchange_LIBRARIES} + ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES} ) @@ -265,6 +269,4 @@ ADD_UNIT_TESTS(TestConstants.py Test19707.py Test19726.py Test19912.py - Test19932.py - Test19989.py ) diff --git a/src/ModuleBase/ModuleBase_ListView.cpp b/src/ModuleBase/ModuleBase_ListView.cpp index c64905eb8..476ff3182 100644 --- a/src/ModuleBase/ModuleBase_ListView.cpp +++ b/src/ModuleBase/ModuleBase_ListView.cpp @@ -34,25 +34,27 @@ const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; //******************************************************************** ModuleBase_ListView::ModuleBase_ListView(QWidget* theParent, const QString& theObjectName, - const QString& theToolTip) + const QString& theToolTip, bool theAllowCopyDelete) +: myAllowCopyDelete(theAllowCopyDelete) { myListControl = new CustomListWidget(theParent); myListControl->setObjectName(theObjectName); myListControl->setToolTip(theToolTip); myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); - - myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"), + if(myAllowCopyDelete) + { + + myCopyAction = ModuleBase_Tools::createAction(QIcon(":pictures/copy.png"), tr("Copy"), theParent, this, SLOT(onCopyItem())); - myCopyAction->setShortcut(QKeySequence::Copy); - myCopyAction->setEnabled(false); - myListControl->addAction(myCopyAction); - - myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"), + myCopyAction->setShortcut(QKeySequence::Copy); + myCopyAction->setEnabled(false); + myListControl->addAction(myCopyAction); + myDeleteAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"), theParent, this, SIGNAL(deleteActionClicked())); - myDeleteAction->setEnabled(false); - myListControl->addAction(myDeleteAction); - + myDeleteAction->setEnabled(false); + myListControl->addAction(myDeleteAction); + } myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); connect(myListControl, SIGNAL(activated()), this, SIGNAL(listActivated())); @@ -148,8 +150,12 @@ void ModuleBase_ListView::onCopyItem() void ModuleBase_ListView::onListSelection() { QList aItems = myListControl->selectedItems(); - myCopyAction->setEnabled(!aItems.isEmpty()); - myDeleteAction->setEnabled(!aItems.isEmpty()); + + if( myAllowCopyDelete ) + { + myCopyAction->setEnabled(!aItems.isEmpty()); + myDeleteAction->setEnabled(!aItems.isEmpty()); + } } //******************************************************************** diff --git a/src/ModuleBase/ModuleBase_ListView.h b/src/ModuleBase/ModuleBase_ListView.h index 8c12aacf3..27817b368 100644 --- a/src/ModuleBase/ModuleBase_ListView.h +++ b/src/ModuleBase/ModuleBase_ListView.h @@ -97,7 +97,7 @@ Q_OBJECT public: /// Constructor ModuleBase_ListView(QWidget* theParent = 0, const QString& theObjectName = QString(), - const QString& theToolTip = QString()); + const QString& theToolTip = QString(), bool theAllowCopyDelete = true); /// Destructor virtual ~ModuleBase_ListView() {} @@ -155,6 +155,7 @@ protected: QAction* myCopyAction; ///< A copy action for pop-up menu in a list control QAction* myDeleteAction; ///< A delete action for pop-up menu in a list control + bool myAllowCopyDelete; // Allow copy or delet items }; #endif diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index bb5c6e39d..6abbc666d 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -114,7 +114,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen const Config_WidgetAPI* theData) : ModuleBase_WidgetSelector(theParent, theWorkshop, theData), myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1), - myIsFirst(true), myFiltersWgt(0), myShowOnlyBtn(0) + myIsFirst(true), myFiltersWgt(0), myShowOnlyBtn(0),myIsSetSelectionAlwaysBlocked(false) { std::string aPropertyTypes = theData->getProperty("shape_types"); QString aTypesStr = aPropertyTypes.c_str(); @@ -127,7 +127,8 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myMainLayout = new QVBoxLayout(this); ModuleBase_Tools::adjustMargins(myMainLayout); - + + myIsSetSelectionAlwaysBlocked = theData->getBooleanAttribute("Block_selection", false); QStringList aIconsList; std::string aIcons = theData->getProperty("type_icons"); @@ -186,7 +187,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen QString aToolTip = translate(theData->widgetTooltip()); QString anObjName = QString::fromStdString(attributeID()); - myListView = new ModuleBase_ListView(this, anObjName, aToolTip); + myListView = new ModuleBase_ListView(this, anObjName, aToolTip,!myIsSetSelectionAlwaysBlocked); connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem())); connect(myListView, SIGNAL(listActivated()), SLOT(onListActivated())); @@ -352,7 +353,7 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom() if (aSelectionType.empty()) aSelectionListAttr->setSelectionType(myDefMode); else { - setCurrentShapeType(aSelectionType.c_str()); + setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionType.c_str())); myDefMode = aSelectionType; myIsFirst = false; } @@ -367,6 +368,9 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom() bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, const bool theToValidate) { + if( myIsSetSelectionAlwaysBlocked) + return false; + if (myIsSetSelectionBlocked) return false; @@ -752,28 +756,23 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const QIntList aShapeTypes; if (myShapeTypes.length() > 1 && myIsUseChoice) { - QStringList aTypes = myTypeCtrl->textValue().split("|", QString::SkipEmptyParts); - for(QString aType: aTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue())); } else { foreach (QString aType, myShapeTypes) { - QStringList aSubTypes = aType.split("|", QString::SkipEmptyParts); - for(QString aSubType: aSubTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aSubType)); - } + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); } } return aShapeTypes; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const QString& theShapeType) +void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType) { int idx = 0; foreach (QString aShapeTypeName, myShapeTypes) { - if(aShapeTypeName == theShapeType && idx != myTypeCtrl->value()) { + int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); + if(aRefType == theShapeType && idx != myTypeCtrl->value()) { updateSelectionModesAndFilters(false); bool isBlocked = myTypeCtrl->blockSignals(true); myTypeCtrl->setValue(idx); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index 946b46d77..7765f9f6f 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -182,7 +182,7 @@ protected: virtual QIntList shapeTypes() const; /// Set current shape type for selection - void setCurrentShapeType(const QString& theShapeType); + void setCurrentShapeType(const int theShapeType); /// Return the attribute values wrapped in a list of viewer presentations /// \return a list of viewer presentations, which contains an attribute result and @@ -249,6 +249,9 @@ protected: /// A flag to block set selection perform if the method is in process bool myIsSetSelectionBlocked; + + /// A flag to block set selection perform always + bool myIsSetSelectionAlwaysBlocked; /// A container of selected objects QList > > mySelectedHistoryValues; diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 772dc05c2..0c6b10763 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -30,6 +30,7 @@ from FeaturesAPI import addRecover from FeaturesAPI import addFillet, addChamfer from FeaturesAPI import addFusionFaces from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle +from FeaturesAPI import getSharedFaces from FeaturesAPI import addRemoveResults from FeaturesAPI import addCopy, addImportResult from FeaturesAPI import addDefeaturing -- 2.39.2