Salome HOME
Implementation of shared faces inspection, bos #29568 cgt/sharedFaces_squashed V9_11_0a1 V9_11_0a2 V9_11_0b1
authorcg246364 <clarisse.genrault@cea.fr>
Wed, 13 Apr 2022 13:54:06 +0000 (15:54 +0200)
committerChristophe Bourcier <christophe.bourcier@cea.fr>
Wed, 10 May 2023 14:20:03 +0000 (16:20 +0200)
Fix problems with updating the number of faces and the list of faces

31 files changed:
src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_SharedFaces.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_CommonSharedFaces.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_CommonSharedFaces.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts
src/FeaturesPlugin/Test/TestCheckSharedFaces.py [new file with mode: 0644]
src/FeaturesPlugin/doc/FeaturesPlugin.rst
src/FeaturesPlugin/doc/TUI_sharedFacesFeature.rst [new file with mode: 0644]
src/FeaturesPlugin/doc/checkSharedFaceFeature.rst [new file with mode: 0644]
src/FeaturesPlugin/doc/examples/check_shared_faces.py [new file with mode: 0644]
src/FeaturesPlugin/doc/images/checkSharedFacesPropertyPanel.png [new file with mode: 0644]
src/FeaturesPlugin/doc/images/sharedFacesResult.png [new file with mode: 0644]
src/FeaturesPlugin/doc/images/shared_shapes.png [new file with mode: 0644]
src/FeaturesPlugin/icons/shared_shapes.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/FeaturesPlugin/shared_faces_macro_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/shared_faces_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/tests.set
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/PythonAPI/model/features/__init__.py

index f36be7a06465cca1b66cd832d7b6ce98c5e6e4b5..a27578e184ab11b892681aeeea9e62d0d40c200d 100644 (file)
@@ -163,51 +163,54 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
     # If theFields is true, the same is performed for Fields.
     def processGroups(self, theRes, theEngine, thePartFeatureId, theStudyShape, theFields):
       allGroupsProcessed = []
+      allRefGroups = []
       if theFields:
-        aRefGroups = ModelAPI.referencedFeatures(theRes, "Field", True)
+        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Field", True))
       else:
-        aRefGroups = ModelAPI.referencedFeatures(theRes, "Group", True)
-      for aRef in aRefGroups:
-        aGroupIndices = []
-        aGroupHasIndex = {}
-        aResShape = theRes.shape()
-        if theFields:
-          aSelList = aRef.selectionList("selected")
-        else:
-          aSelList = aRef.selectionList("group_list")
-        aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
-        for aGroupRes in aRef.results():
-          aShape = aGroupRes.shape()
-          anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
-          while anExplorer.more():
-            anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current())
-            if anId > 0 and not anId in aGroupHasIndex:
-              aGroupIndices.append(anId)
-              aGroupHasIndex[anId] = 0
-            anExplorer.next()
-        if len(aGroupIndices): # create group
-          aGroupFeatureId = aRef.data().featureId()
+        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Group", True))
+        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Shared_faces", True))
+      for aRefGroups in allRefGroups:
+        for aRef in aRefGroups:
+          aGroupIndices = []
+          aGroupHasIndex = {}
+          aResShape = theRes.shape()
           if theFields:
-            aFieldOp = theEngine.GetIFieldOperations()
-            aGroupEntry = "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
-            aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry)
+            aSelList = aRef.selectionList("selected")
           else:
-            aGroupOp = theEngine.GetIGroupOperations()
-            aGroupEntry = "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
-            aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry)
-          if not aGroup: # create a new
+            aSelList = aRef.selectionList("group_list")
+          aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
+          for aGroupRes in aRef.results():
+            aShape = aGroupRes.shape()
+            anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
+            while anExplorer.more():
+              anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current())
+              if anId > 0 and not anId in aGroupHasIndex:
+                aGroupIndices.append(anId)
+                aGroupHasIndex[anId] = 0
+              anExplorer.next()
+          if len(aGroupIndices): # create group
+            aGroupFeatureId = aRef.data().featureId()
             if theFields:
-              aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType)
+              aFieldOp = theEngine.GetIFieldOperations()
+              aGroupEntry = "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
+              aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry)
             else:
-              aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType)
-            aGroup.SetEntry(aGroupEntry)
-            theEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), theStudyShape)
-          aGroup.SetSelection(aGroupIndices)
-          if theFields:
-            self.fillField(aGroup, aRef, theEngine, aGroupIndices)
-          # a group takes shape from the main result
-          #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape
-          allGroupsProcessed.append(aGroupEntry)
+              aGroupOp = theEngine.GetIGroupOperations()
+              aGroupEntry = "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
+              aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry)
+            if not aGroup: # create a new
+              if theFields:
+                aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType)
+              else:
+                aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType)
+              aGroup.SetEntry(aGroupEntry)
+              theEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), theStudyShape)
+            aGroup.SetSelection(aGroupIndices)
+            if theFields:
+              self.fillField(aGroup, aRef, theEngine, aGroupIndices)
+            # a group takes shape from the main result
+            #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape
+            allGroupsProcessed.append(aGroupEntry)
       # check all existing groups: if some does not processed, remove it from the tree
       aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(theStudyShape.GetSO())
       while aSOIter.More():
index 15254f37d20640ea338e40025660ef56cb742c31..13c520322e516653bdd8da2768e74f6f1a37f2af 100644 (file)
@@ -60,6 +60,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_GeometryCalculation.h
   FeaturesAPI_BoundingBox.h
   FeaturesAPI_LimitTolerance.h
+  FeaturesAPI_SharedFaces.h
 )
 
 SET(PROJECT_SOURCES
@@ -102,6 +103,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_GeometryCalculation.cpp
   FeaturesAPI_BoundingBox.cpp
   FeaturesAPI_LimitTolerance.cpp
+  FeaturesAPI_SharedFaces.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 0e444f027fe53407befc722901ae24e330dbed6d..bab98e950b559dc43bd384dd1e0b289a85ddb235 100644 (file)
@@ -99,6 +99,7 @@
 %shared_ptr(FeaturesAPI_Rotation)
 %shared_ptr(FeaturesAPI_Scale)
 %shared_ptr(FeaturesAPI_Sewing)
+%shared_ptr(FeaturesAPI_SharedFaces)
 %shared_ptr(FeaturesAPI_Symmetry)
 %shared_ptr(FeaturesAPI_Translation)
 %shared_ptr(FeaturesAPI_Union)
 %include "FeaturesAPI_Rotation.h"
 %include "FeaturesAPI_Scale.h"
 %include "FeaturesAPI_Sewing.h"
+%include "FeaturesAPI_SharedFaces.h"
 %include "FeaturesAPI_Symmetry.h"
 %include "FeaturesAPI_Translation.h"
 %include "FeaturesAPI_Union.h"
diff --git a/src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp b/src/FeaturesAPI/FeaturesAPI_SharedFaces.cpp
new file mode 100644 (file)
index 0000000..402eb87
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright (C) 2018-2021  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 <FeaturesPlugin_GroupSharedFaces.h>
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Services.h>
+#include <ModelHighAPI_Tools.h>
+
+//=================================================================================================
+FeaturesAPI_SharedFaces::FeaturesAPI_SharedFaces(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//=================================================================================================
+FeaturesAPI_SharedFaces::FeaturesAPI_SharedFaces(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const ModelHighAPI_Selection& theObject,
+  const std::string & theNameGroup)
+:ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(theObject, myobjectselected);
+    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_GroupSharedFaces::OBJECT_ID());
+
+  theDumper << aBase << " = model.getSharedFaces(" << aDocName << ", " << anAttrObject;
+  theDumper << ", " << aBase->string(FeaturesPlugin_GroupSharedFaces::GROUP_NAME_ID());
+  theDumper << ")" << std::endl;
+}
+
+//=================================================================================================
+SharedFacesPtr getSharedFaces(const std::shared_ptr<ModelAPI_Document>& thePart,
+                              const ModelHighAPI_Selection& theObject,
+                              const std::string & theNameGroup)
+{
+  FeaturePtr aFeature = thePart->addFeature(FeaturesPlugin_GroupSharedFaces::ID());
+  SharedFacesPtr aSharedFaces;
+
+  aSharedFaces.reset(new FeaturesAPI_SharedFaces(aFeature,
+                                                 theObject,
+                                                 theNameGroup));
+  return aSharedFaces;
+}
+
diff --git a/src/FeaturesAPI/FeaturesAPI_SharedFaces.h b/src/FeaturesAPI/FeaturesAPI_SharedFaces.h
new file mode 100644 (file)
index 0000000..ac62ee7
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (C) 2018-2021  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_GroupSharedFaces.h"
+
+#include <ModelHighAPI_Integer.h>
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+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<ModelAPI_Feature>& theFeature);
+
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_SharedFaces(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                   const ModelHighAPI_Selection& theObject,
+                                   const std::string & theNameGroup);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT
+  virtual ~FeaturesAPI_SharedFaces();
+
+  INTERFACE_2(FeaturesPlugin_GroupSharedFaces::ID(),
+              objectselected, FeaturesPlugin_GroupSharedFaces::OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** object selected*/,
+              groupname, FeaturesPlugin_GroupSharedFaces::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<FeaturesAPI_SharedFaces> SharedFacesPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create a group of shared faces in a compsolid or a compound
+/// \param thePart the part
+/// \param theObject the selected object
+/// \param theNameGroup the group name
+FEATURESAPI_EXPORT
+SharedFacesPtr getSharedFaces(const std::shared_ptr<ModelAPI_Document>& thePart,
+                              const ModelHighAPI_Selection& theObject,
+                              const std::string & theNameGroup);
+
+#endif // FeaturesAPI_SharedFaces_H_
index a440abd0ba77cf56463d935dde9a33c0392a8c3d..53bdbb86feb35d44eb7b747b70b452f04e464cb6 100644 (file)
@@ -62,5 +62,6 @@
   #include "FeaturesAPI_GeometryCalculation.h"
   #include "FeaturesAPI_BoundingBox.h"
   #include "FeaturesAPI_LimitTolerance.h"
+  #include "FeaturesAPI_SharedFaces.h"
 
 #endif // FeaturesAPI_swig_H_
index d4db12a9df572450c8489ae5d864c45805d2fc25..198f7d82f4a9f1012a86ef45a21f7ec53e80371b 100644 (file)
@@ -79,6 +79,9 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_InspectNormalToFace.h
     FeaturesPlugin_GlueFaces.h
     FeaturesPlugin_LimitTolerance.h
+    FeaturesPlugin_CommonSharedFaces.h
+    FeaturesPlugin_GroupSharedFaces.h
+    FeaturesPlugin_SharedFaces.h
 )
 
 SET(PROJECT_SOURCES
@@ -138,6 +141,9 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_InspectNormalToFace.cpp
     FeaturesPlugin_GlueFaces.cpp
     FeaturesPlugin_LimitTolerance.cpp
+    FeaturesPlugin_CommonSharedFaces.cpp
+    FeaturesPlugin_GroupSharedFaces.cpp
+    FeaturesPlugin_SharedFaces.cpp
 )
 
 SET(XML_RESOURCES
@@ -184,6 +190,8 @@ SET(XML_RESOURCES
   normal_to_face_widget.xml
   create_normal_to_face_widget.xml
   limit_tolerance_widget.xml
+  shared_faces_macro_widget.xml
+  shared_faces_widget.xml
 )
 
 SET(TEXT_RESOURCES
@@ -204,6 +212,7 @@ INCLUDE_DIRECTORIES(
   ../ModuleBase
   ../Events
   ../Config
+  ../Locale
   ${OpenCASCADE_INCLUDE_DIR}
 )
 
diff --git a/src/FeaturesPlugin/FeaturesPlugin_CommonSharedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_CommonSharedFaces.cpp
new file mode 100644 (file)
index 0000000..8c154ed
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright (C) 2018-2021  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_CommonSharedFaces.h"
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <sstream>
+
+//=================================================================================================
+void FeaturesPlugin_CommonSharedFaces::updateFaces()
+{
+  AttributeSelectionPtr aCompSolidAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(attributObject());
+  AttributeSelectionListPtr aFacesListAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList> (attributListFaces());
+
+  GeomShapePtr aShape = aCompSolidAttr->value();
+
+  AttributeBooleanPtr anIsCompute =
+    std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(attributIsCompute());
+  if (!anIsCompute->value()) {
+    myShape = aShape;
+    anIsCompute->setValue(true);
+  }
+  if (aShape.get() && aCompSolidAttr->context().get() && !aShape->isEqual(myShape)) {
+    if (aFacesListAttr->isInitialized())
+        aFacesListAttr->clear();
+    aShape = aCompSolidAttr->context()->shape();
+    if (aShape) {
+      ListOfShape aFaces = GeomAlgoAPI_ShapeTools::getSharedFaces(aShape);
+      myShape = aShape;
+      aFacesListAttr->setSelectionType("face");
+      ListOfShape::const_iterator anIt = aFaces.cbegin();
+      for(; anIt != aFaces.cend(); ++anIt) {
+        GeomShapePtr aFacePtr = *anIt;
+        if (!(aFacesListAttr->isInList(aCompSolidAttr->context(), aFacePtr))) {
+          aFacesListAttr->append(aCompSolidAttr->context(), aFacePtr);
+        }
+      }
+      std::stringstream aLabel;
+      aLabel << aFacesListAttr->size();
+      AttributeStringPtr aNumberFacesAttr =
+        std::dynamic_pointer_cast<ModelAPI_AttributeString>(attributNumberFaces());
+      aNumberFacesAttr->setValue(aLabel.str());
+    }
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_CommonSharedFaces::setFacesGroup(const std::wstring& theName)
+{
+  std::vector<int> 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<ModelAPI_AttributeSelectionList> (attributListFaces());
+
+  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_CommonSharedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_CommonSharedFaces.h
new file mode 100644 (file)
index 0000000..3a31c3b
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2018-2021  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_CommonSharedFaces_H_
+#define FeaturesPlugin_CommonSharedFaces_H_
+
+#include "FeaturesPlugin.h"
+
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultGroup.h>
+
+
+/// \class FeaturesPlugin_CommonSharedFaces
+/// \ingroup Plugins
+/// \brief Feature to check the shared faces of solid
+
+class FeaturesPlugin_CommonSharedFaces : public ModelAPI_Feature
+{
+public:
+  /// Performs the algorithm and stores results it in the data structure.
+  FEATURESPLUGIN_EXPORT virtual void execute(){};
+
+  /// Return Attribut values of result.
+  virtual AttributePtr attributObject() = 0;
+
+  /// Return Attribut values of result.
+  virtual AttributePtr attributListFaces() = 0;
+
+  /// Return Attribut values of result.
+  virtual AttributePtr attributNumberFaces() = 0;
+
+  /// Return Attribut values of IsCompute.
+  virtual AttributePtr attributIsCompute() = 0;
+
+  protected:
+  FeaturesPlugin_CommonSharedFaces() {}
+
+  //Set group of faces
+  void setFacesGroup(const std::wstring& theName );
+
+  // Update the list of faces
+  void updateFaces();
+
+  // the shape studied
+  GeomShapePtr myShape;
+
+};
+
+#endif
diff --git a/src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.cpp
new file mode 100644 (file)
index 0000000..994a788
--- /dev/null
@@ -0,0 +1,131 @@
+// Copyright (C) 2018-2021  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_GroupSharedFaces.h"
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Validator.h>
+
+#include <Locale_Convert.h>
+
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_GroupSharedFaces::FeaturesPlugin_GroupSharedFaces()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_GroupSharedFaces::initAttributes()
+{
+  data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+  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(GROUP_NAME_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(COMPUTE_ID(), ModelAPI_AttributeBoolean::typeId());
+
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TRANSPARENCY_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), COMPUTE_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), NUMBER_FACES_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LIST_FACES_ID());
+
+  data()->boolean(COMPUTE_ID())->setValue(true);
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_GroupSharedFaces::attributObject()
+{
+  return attribute(OBJECT_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_GroupSharedFaces::attributIsCompute()
+{
+  return attribute(COMPUTE_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_GroupSharedFaces::attributListFaces()
+{
+  return attribute(LIST_FACES_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_GroupSharedFaces::attributNumberFaces()
+{
+  return attribute(NUMBER_FACES_ID());
+}
+
+//=================================================================================================
+void FeaturesPlugin_GroupSharedFaces::execute()
+{
+  if (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());
+
+    if (lastResult().get())
+      eraseResultFromList(lastResult());
+    setFacesGroup(aNameFace);
+  } else {
+    if (lastResult().get()) {
+      eraseResultFromList(lastResult());
+    }
+  }
+  if (selection(OBJECT_ID())->isInitialized() && integer(TRANSPARENCY_ID())->isInitialized()) {
+    AttributeSelectionPtr aCompSolidAttr = selection(OBJECT_ID());
+    ResultPtr aResult = aCompSolidAttr->context();
+
+    double aTranparency = integer(TRANSPARENCY_ID())->value() / 100.0;
+    ModelAPI_Tools::setTransparency(aResult, aTranparency);
+
+    ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
+    std::list<ResultPtr> allRes;
+    ModelAPI_Tools::allSubs(aResultBody, allRes);
+    std::list<ResultPtr>::iterator aRes;
+    for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
+      ModelAPI_Tools::setTransparency(*aRes, aTranparency);
+    }
+  }
+
+  // Update the number of shared faces
+  AttributeSelectionListPtr aFacesListAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList> (attributListFaces());
+  AttributeStringPtr aNumberFacesAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeString> (attributNumberFaces());
+  std::stringstream aLabel;
+  aLabel << aFacesListAttr->size();
+  aNumberFacesAttr->setValue(aLabel.str());
+}
+
+//=================================================================================================
+void FeaturesPlugin_GroupSharedFaces::attributeChanged(const std::string& theID)
+{
+  if (theID == OBJECT_ID() || theID == LIST_FACES_ID())
+    updateFaces();
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_GroupSharedFaces.h
new file mode 100644 (file)
index 0000000..d81781b
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2018-2021  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_GroupSharedFaces_H_
+#define FeaturesPlugin_GroupSharedFaces_H_
+
+#include <FeaturesPlugin_CommonSharedFaces.h>
+
+/// \class FeaturesPlugin_GroupSharedFaces
+/// \ingroup Plugins
+/// \brief Feature to check the shared faces of solid
+
+class FeaturesPlugin_GroupSharedFaces : public FeaturesPlugin_CommonSharedFaces
+{
+public:
+  /// Group shared faces kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Shared_faces");
+    return MY_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("group_list");
+    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 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;
+  }
+
+  /// Attribute name for indicate to launch the algo.
+  inline static const std::string& COMPUTE_ID()
+  {
+    static const std::string MY_COMPUTE_ID("compute");
+    return MY_COMPUTE_ID;
+  }
+
+  /// \return the kind of a feature.
+  virtual const std::string& getKind()
+  {
+    return 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_GroupSharedFaces();
+
+private:
+  /// Return Attribut values of object.
+  virtual AttributePtr attributObject();
+
+  /// Return Attribut values of list of faces.
+  virtual AttributePtr attributListFaces();
+
+  /// Return Attribut values of number of faces.
+  virtual AttributePtr attributNumberFaces();
+
+  /// Return Attribut values of IsCompute.
+  virtual AttributePtr attributIsCompute();
+};
+
+#endif
index 5c312469bd333f97c6161cb6bdab543a75dacd05..9659812ad44c59b0c72470cf40d559b458007f92 100644 (file)
@@ -34,6 +34,7 @@
 #include <FeaturesPlugin_Fillet1D.h>
 #include <FeaturesPlugin_GeometryCalculation.h>
 #include <FeaturesPlugin_GlueFaces.h>
+#include <FeaturesPlugin_GroupSharedFaces.h>
 #include <FeaturesPlugin_InspectBoundingBox.h>
 #include <FeaturesPlugin_InspectNormalToFace.h>
 #include <FeaturesPlugin_Intersection.h>
@@ -56,6 +57,7 @@
 #include <FeaturesPlugin_Rotation.h>
 #include <FeaturesPlugin_Scale.h>
 #include <FeaturesPlugin_Sewing.h>
+#include <FeaturesPlugin_SharedFaces.h>
 #include <FeaturesPlugin_Symmetry.h>
 #include <FeaturesPlugin_Translation.h>
 #include <FeaturesPlugin_Union.h>
@@ -236,6 +238,10 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_PointCloudOnFace);
   } else if (theFeatureID == FeaturesPlugin_LimitTolerance::ID()) {
     return FeaturePtr(new FeaturesPlugin_LimitTolerance);
+  } else if (theFeatureID == FeaturesPlugin_SharedFaces::ID()) {
+    return FeaturePtr(new FeaturesPlugin_SharedFaces);
+  } else if (theFeatureID == FeaturesPlugin_GroupSharedFaces::ID()) {
+    return FeaturePtr(new FeaturesPlugin_GroupSharedFaces);
   }
 
 
diff --git a/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.cpp
new file mode 100644 (file)
index 0000000..15eebf6
--- /dev/null
@@ -0,0 +1,185 @@
+// Copyright (C) 2018-2021  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 <FeaturesPlugin_GroupSharedFaces.h>
+
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Validator.h>
+
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_SharedFaces::FeaturesPlugin_SharedFaces()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_SharedFaces::initAttributes()
+{
+  data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+  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());
+  data()->addAttribute(COMPUTE_ID(), ModelAPI_AttributeBoolean::typeId());
+
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), GROUP_NAME_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), COMPUTE_ID());
+  data()->boolean(COMPUTE_ID())->setValue(true);
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_SharedFaces::attributIsCompute()
+{
+  return attribute(COMPUTE_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_SharedFaces::attributObject()
+{
+  return attribute(OBJECT_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_SharedFaces::attributListFaces()
+{
+  return attribute(LIST_FACES_ID());
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_SharedFaces::attributNumberFaces()
+{
+  return attribute(NUMBER_FACES_ID());
+}
+
+//=================================================================================================
+void FeaturesPlugin_SharedFaces::execute()
+{
+  if (boolean(CREATE_GROUP_ID())->value()) {
+
+    if (string(GROUP_NAME_ID())->value() != ""
+      && selectionList(LIST_FACES_ID())->isInitialized()) {
+
+      if (lastResult().get()) {
+        eraseResultFromList(lastResult());
+      }
+
+      if (!myCreateGroupFeature.get())
+        createGroup();
+      updateGroup();
+    }
+
+  } else {
+    if (selectionList(LIST_FACES_ID())->isInitialized()) {
+
+      if (myCreateGroupFeature.get()) {
+        myCreateGroupFeature->eraseResults();
+        SessionPtr aSession = ModelAPI_Session::get();
+        DocumentPtr aDoc =  aSession->activeDocument();
+        aDoc->removeFeature(myCreateGroupFeature);
+        myCreateGroupFeature.reset();
+      }
+
+      if (lastResult().get())
+        eraseResultFromList(lastResult());
+      setFacesGroup(L"Group_SharedFaces");
+    }
+  }
+
+  if (selection(OBJECT_ID())->isInitialized()) {
+    AttributeSelectionPtr aCompSolidAttr = selection(OBJECT_ID());
+    ResultPtr aResult = aCompSolidAttr->context();
+
+    double aTranparency = integer(TRANSPARENCY_ID())->value()/100.0;
+    ModelAPI_Tools::setTransparency(aResult, aTranparency);
+
+    ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
+    std::list<ResultPtr> allRes;
+    ModelAPI_Tools::allSubs(aResultBody, allRes);
+    std::list<ResultPtr>::iterator aRes;
+    for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
+      ModelAPI_Tools::setTransparency(*aRes, aTranparency);
+    }
+  }
+
+  // Update the number of shared faces
+  AttributeSelectionListPtr aFacesListAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList> (attributListFaces());
+  AttributeStringPtr aNumberFacesAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeString> (attributNumberFaces());
+  std::stringstream aLabel;
+  aLabel << aFacesListAttr->size();
+  aNumberFacesAttr->setValue(aLabel.str());
+}
+
+//=================================================================================================
+void FeaturesPlugin_SharedFaces::attributeChanged(const std::string& theID)
+{
+  if (theID == OBJECT_ID()) {
+    updateFaces();
+    if (myCreateGroupFeature.get())
+      updateGroup();
+  }
+}
+
+
+//=================================================================================================
+void FeaturesPlugin_SharedFaces::createGroup()
+{
+  SessionPtr aSession = ModelAPI_Session::get();
+
+  DocumentPtr aDoc =  aSession->activeDocument();
+
+  if (aDoc.get()) {
+    myCreateGroupFeature = aDoc->addFeature(FeaturesPlugin_GroupSharedFaces::ID());
+  }
+}
+
+//=================================================================================================
+void FeaturesPlugin_SharedFaces::updateGroup()
+{
+    myCreateGroupFeature->boolean(FeaturesPlugin_GroupSharedFaces::COMPUTE_ID())->setValue(false);
+    myCreateGroupFeature->string(FeaturesPlugin_GroupSharedFaces::GROUP_NAME_ID())
+      ->setValue(string(GROUP_NAME_ID())->value());
+
+    myCreateGroupFeature->selection(FeaturesPlugin_GroupSharedFaces::OBJECT_ID())
+      ->setValue(selection(OBJECT_ID())->context(), selection(OBJECT_ID())->value());
+    AttributeSelectionListPtr aFacesFeatures =
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>
+                               (myCreateGroupFeature->attribute(LIST_FACES_ID()));
+
+    AttributeSelectionListPtr aFaces =
+      std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(attribute(LIST_FACES_ID()));
+    aFaces->copyTo(aFacesFeatures);
+
+    myCreateGroupFeature->integer(FeaturesPlugin_GroupSharedFaces::TRANSPARENCY_ID())
+                          ->setValue( integer(TRANSPARENCY_ID())->value());
+    myCreateGroupFeature->execute();
+    myCreateGroupFeature->boolean(FeaturesPlugin_GroupSharedFaces::COMPUTE_ID())->setValue(true);
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h b/src/FeaturesPlugin/FeaturesPlugin_SharedFaces.h
new file mode 100644 (file)
index 0000000..2511253
--- /dev/null
@@ -0,0 +1,133 @@
+// Copyright (C) 2018-2021  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_CommonSharedFaces.h>
+
+/// \class FeaturesPlugin_SharedFaces
+/// \ingroup Plugins
+/// \brief Feature to check the shared faces of compsolid or compound
+
+class FeaturesPlugin_SharedFaces : public FeaturesPlugin_CommonSharedFaces
+{
+public:
+  /// Shared faces kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Shared_faces_macro");
+    return MY_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("group_list");
+    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 indicate to launch the algo.
+  inline static const std::string& COMPUTE_ID()
+  {
+    static const std::string MY_COMPUTE_ID("compute");
+    return MY_COMPUTE_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;
+  }
+
+  /// \return the kind of a feature.
+  virtual const std::string& getKind()
+  {
+    return 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);
+
+  /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true.
+  FEATURESPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+  /// Use plugin manager for features creation
+  FeaturesPlugin_SharedFaces();
+
+private:
+  /// Return attribut values of object.
+  virtual AttributePtr attributObject();
+
+  /// Return attribut values of list of faces.
+  virtual AttributePtr attributListFaces();
+
+  /// Return attribut values of number of faces.
+  virtual AttributePtr attributNumberFaces();
+
+  /// Return attribut values of IsCompute.
+  virtual AttributePtr attributIsCompute();
+
+  /// Create group
+  void createGroup();
+
+  /// Update group
+  void updateGroup();
+
+  /// Feature to create group
+  FeaturePtr myCreateGroupFeature;
+};
+
+#endif
index 41fa7dca7e680655f889a68c332aa2810d20c982..a01ffc9bc19e22eb61e295bf8b853174e8889e90 100644 (file)
       <source>Bounding box</source>
       <translation>Boîte englobante</translation>
     </message>
+    <message>
+      <source>Check shared faces</source>
+      <translation>Vérifier les faces partagées</translation>
+    </message>
     <message>
       <source>Placement</source>
       <translation>Placement</translation>
     </message>
   </context>
 
+  <!-- Check shared faces -->
+  <context>
+    <name>Shared_faces_macro</name>
+    <message>
+      <source>Check shared faces</source>
+      <translation>Vérifier les faces partagées</translation>
+    </message>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>
+    <message>
+      <source>Number of shared faces : </source>
+      <translation>Nombre de faces partagées : </translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces_macro:create_group</name>
+    <message>
+      <source>Create group</source>
+      <translation>Créer un groupe</translation>
+    </message>
+  </context>
+  <context>
+      <name>Shared_faces_macro:group_name</name>
+    <message>
+      <source>Group name</source>
+      <translation>Nom du groupe</translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces_macro:main_object</name>
+    <message>
+      <source>Object</source>
+      <translation>Objet</translation>
+    </message>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>
+  </context>
+  <context>
+      <name>Shared_faces_macro:group_list</name>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>   
+    <message>
+      <source>List of faces :</source>
+      <translation>Liste des faces :</translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces_macro:transparency</name>
+    <message>
+      <source>Transparency</source>
+      <translation>Transparence</translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces</name>
+    <message>
+      <source>Check shared faces</source>
+      <translation>Vérifier les faces partagées</translation>
+    </message>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>
+    <message>
+      <source>Number of shared faces : </source>
+      <translation>Nombre de faces partagées : </translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces:create_group</name>
+    <message>
+      <source>Create group</source>
+      <translation>Créer un groupe</translation>
+    </message>
+  </context>
+  <context>
+      <name>Shared_faces:group_name</name>
+    <message>
+      <source>Group name</source>
+      <translation>Nom du groupe</translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces:main_object</name>
+    <message>
+      <source>Object</source>
+      <translation>Objet</translation>
+    </message>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>
+  </context>
+  <context>
+      <name>Shared_faces:group_list</name>
+    <message>
+      <source>Shared faces</source>
+      <translation>Faces partagées</translation>
+    </message>   
+    <message>
+      <source>List of faces :</source>
+      <translation>Liste des faces :</translation>
+    </message>
+  </context>
+  <context>
+    <name>Shared_faces:transparency</name>
+    <message>
+      <source>Transparency</source>
+      <translation>Transparence</translation>
+    </message>
+  </context>
+
   <!-- Symmetry -->
   <context>
     <name>Symmetry</name>
diff --git a/src/FeaturesPlugin/Test/TestCheckSharedFaces.py b/src/FeaturesPlugin/Test/TestCheckSharedFaces.py
new file mode 100644 (file)
index 0000000..41f9e5c
--- /dev/null
@@ -0,0 +1,122 @@
+# Copyright (C) 2014-2021  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
+#
+
+"""
+      Unit test of Check shared faces
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+
+import os
+import math
+
+from ModelAPI import *
+from GeomAPI import *
+from salome.shaper import model
+
+
+__updated__ = "2020-11-12"
+
+
+if __name__ == '__main__':
+
+    model.begin()
+    partSet = model.moduleDocument()
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+    ### Create Box
+    Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+    ### Create Point
+    Point_2 = model.addPoint(Part_1_doc, 20, 10, 10)
+    ### Create Box
+    Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "Point_1"))
+    ### Create CompSolid
+    CompSolid_1 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1")])
+    ### Create Box
+    Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+    ### Create Box
+    Box_4 = model.addBox(Part_1_doc, 10, 10, 10)
+    ### Create Translation
+    Translation_1 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_4")], axis = model.selection("EDGE", "PartSet/OX"),
+                                         distance = 10, keepSubResults = True)
+    ### Create CompSolid
+    CompSolid_2 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_3_1"), model.selection("COMPOUND", "Translation_1_1")])
+    ### Create Box
+    Box_5 = model.addBox(Part_1_doc, 10, 10, 10)
+    ### Create Translation
+    Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_5_1")], vector = [10, 0, 10], keepSubResults = True)
+    ### Create Compound
+    Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPSOLID", "CompSolid_1_1"), model.selection("SOLID", "Translation_2_1")])
+    Compound_1.result().setTransparency(0.5)
+    Compound_1.result().subResult(0).setTransparency(0.5)
+    Compound_1.result().subResult(0).subResult(0).setTransparency(0.5)
+    Compound_1.result().subResult(0).subResult(1).setTransparency(0.5)
+    Compound_1.result().subResult(1).setTransparency(0.5)
+
+    ### Create Shared_faces for compsolid
+    Shared_faces_1 = model.getSharedFaces(Part_1_doc, model.selection("COMPSOLID", "CompSolid_1_1"), "faces_compsolid")
+
+    ### Create Shared_faces for compound
+    Shared_faces_2 = model.getSharedFaces(Part_1_doc, model.selection("COMPOUND", "Compound_1_1"), 'faces_compound')
+
+    model.do()
+
+     # Check results
+    assert(Part_1_doc.size("Groups") == 2)
+    Shared_faces_1_Feature = Shared_faces_1.feature()
+    assert Shared_faces_1_Feature.error() == ''
+    assert Shared_faces_1_Feature.name() == "Shared_faces_1"
+
+    aSelectionList = Shared_faces_1_Feature.selectionList("group_list")
+    assert aSelectionList.size() == 1
+
+    Shared_faces_2_Feature = Shared_faces_2.feature()
+    assert Shared_faces_2_Feature.error() == ''
+    assert Shared_faces_2_Feature.name() == "Shared_faces_2"
+
+    aSelectionList = Shared_faces_2_Feature.selectionList("group_list")
+    assert aSelectionList.size() == 1
+
+    resShape_1 = modelAPI_Result(Part_1_doc.object("Groups", 0)).shape()
+    assert(not resShape_1.isNull())
+
+    # the group result is a face, check that this is one face
+    aShapeExplorer = GeomAPI_ShapeExplorer(resShape_1, GeomAPI_Shape.FACE)
+    assert(aShapeExplorer.more())
+    assert(aShapeExplorer.current().isFace())
+    aShapeExplorer.next()
+    assert(not aShapeExplorer.more())
+
+    resShape_2 = modelAPI_Result(Part_1_doc.object("Groups", 1)).shape()
+    assert(not resShape_2.isNull())
+
+    # the group result is a face, check that this is one face
+    aShapeExplorer = GeomAPI_ShapeExplorer(resShape_2, GeomAPI_Shape.FACE)
+    assert(aShapeExplorer.more())
+    assert(aShapeExplorer.current().isFace())
+    aShapeExplorer.next()
+    assert(not aShapeExplorer.more())
+
+    model.end()
+
+    #=========================================================================
+    # End of test
+    #=========================================================================
index a47b713d06c4cbefed9c3b05275633488175efc1..43d13da812728109e42edb8a7f2b55499e2cb252 100644 (file)
@@ -14,6 +14,7 @@ Features plug-in provides a set of common topological operations. It implements
    angularCopyFeature.rst
    boundingBoxFeature.rst
    chamferFeature.rst
+   checkSharedFaceFeature.rst
    copyFeature.rst
    defeaturingFeature.rst
    extrusionCutFeature.rst
diff --git a/src/FeaturesPlugin/doc/TUI_sharedFacesFeature.rst b/src/FeaturesPlugin/doc/TUI_sharedFacesFeature.rst
new file mode 100644 (file)
index 0000000..48e2f33
--- /dev/null
@@ -0,0 +1,11 @@
+
+  .. _tui_shared_faces:
+
+Check shared faces
+==================
+
+.. literalinclude:: examples/check_shared_faces.py 
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/check_shared_faces.py>`
diff --git a/src/FeaturesPlugin/doc/checkSharedFaceFeature.rst b/src/FeaturesPlugin/doc/checkSharedFaceFeature.rst
new file mode 100644 (file)
index 0000000..48b7ec3
--- /dev/null
@@ -0,0 +1,52 @@
+.. |shared_shapes.icon|    image:: images/shared_shapes.png
+
+Check shared faces
+==================
+
+The **Check shared faces** feature find the shared faces within a composolid or compound.
+
+The result is a list of faces and a group that can be created with a specified name.
+
+To check shared faces in the active part:
+
+#. Select in the Main Menu *Inspection - > Check shared faces* item  or
+#. Click |shared_shapes.icon| **Check shared faces** button in the toolbar
+
+The property panel is shown below.
+
+.. figure:: images/checkSharedFacesPropertyPanel.png
+   :align: center
+
+   Check shared faces
+
+
+Input fields:
+
+- **Object** contains composolid or compound selected in 3D OCC viewer or object browser.
+- **Number of shared faces** indicate the number of found faces.
+- **List of faces** the list of found faces.
+- **Transparency** set the transparency of selected object.
+- **Create group** check-box that allows the creation of the found faces group.
+- **Group name**  specifies the name of the group created.
+
+
+**TUI Command**:
+
+.. py:function:: model.getSharedFaces(Part_doc, shape, nameGroup)
+
+    :param part: The current part object.
+    :param object: A composolid or compound in format *model.selection(TYPE, shape)*.
+    :param string: The name of group to create
+    :return: Created group.
+
+Result
+""""""
+
+Result of **Check shared faces** where **Create group** is checked.
+
+.. figure:: images/sharedFacesResult.png
+   :align: center
+
+   Shared faces
+
+**See Also** a sample TUI Script of :ref:`tui_shared_faces` operation.
diff --git a/src/FeaturesPlugin/doc/examples/check_shared_faces.py b/src/FeaturesPlugin/doc/examples/check_shared_faces.py
new file mode 100644 (file)
index 0000000..1980273
--- /dev/null
@@ -0,0 +1,21 @@
+from salome.shaper import model
+import os
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+### Create Point
+Point_2 = model.addPoint(Part_1_doc, 20, 10, 10)
+### Create Box
+Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "Point_1"))
+### Create CompSolid
+CompSolid_1 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1")])
+
+### Create Shared_faces
+Shared_faces_1 = model.getSharedFaces(Part_1_doc, model.selection("COMPSOLID", "CompSolid_1_1"), "mygroup")
+
+model.do()
+model.end()
diff --git a/src/FeaturesPlugin/doc/images/checkSharedFacesPropertyPanel.png b/src/FeaturesPlugin/doc/images/checkSharedFacesPropertyPanel.png
new file mode 100644 (file)
index 0000000..c5f0ee9
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/checkSharedFacesPropertyPanel.png differ
diff --git a/src/FeaturesPlugin/doc/images/sharedFacesResult.png b/src/FeaturesPlugin/doc/images/sharedFacesResult.png
new file mode 100644 (file)
index 0000000..114ac34
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/sharedFacesResult.png differ
diff --git a/src/FeaturesPlugin/doc/images/shared_shapes.png b/src/FeaturesPlugin/doc/images/shared_shapes.png
new file mode 100644 (file)
index 0000000..23f8048
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/shared_shapes.png differ
diff --git a/src/FeaturesPlugin/icons/shared_shapes.png b/src/FeaturesPlugin/icons/shared_shapes.png
new file mode 100644 (file)
index 0000000..23f8048
Binary files /dev/null and b/src/FeaturesPlugin/icons/shared_shapes.png differ
index 14c8cf72761a0630652a71800ec63a9241182752..3bebe12a5e9fc07aae90ce4b15fa4c208e82cf5a 100644 (file)
                icon="icons/Features/axis.png" helpfile="normalToFaceFeature.html" internal="1">
         <source path="create_normal_to_face_widget.xml"/>
       </feature>
+      <feature id="Shared_faces_macro" title="Check shared faces" tooltip="Check the shared faces" auto_preview="true"
+               icon="icons/Features/shared_shapes.png" helpfile="checkSharedFaceFeature.html">
+        <source path="shared_faces_macro_widget.xml"/>
+      </feature>
+      <feature id="Shared_faces" title="Check shared faces" tooltip="Check the shared faces" auto_preview="true"
+               icon="icons/Features/shared_shapes.png" helpfile="checkSharedFaceFeature.html" internal="1">
+        <source path="shared_faces_widget.xml"/>
+      </feature>
     </group>
   </workbench>
 </plugin>
diff --git a/src/FeaturesPlugin/shared_faces_macro_widget.xml b/src/FeaturesPlugin/shared_faces_macro_widget.xml
new file mode 100644 (file)
index 0000000..d9e1e4c
--- /dev/null
@@ -0,0 +1,35 @@
+<source>
+  <shape_selector id="main_object"
+                  label="Object"
+                  tooltip="Select a compsolid or a compound"
+                  shape_types="compsolid compound"
+                  default=""
+                  geometrical_selection="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="compsolid,compound"/>
+  </shape_selector>
+  <groupbox title="Shared faces">
+    <label id="number_shared_faces" label="Number of shared faces : "/>
+    <multi_selector id="group_list"
+                      label="List of faces :"
+                      icon=""
+                      shape_types="faces"
+                      Block_selection = "true"
+                      use_choice="false">
+          <validator id="PartSet_DifferentObjects"/>
+          <validator id="GeomValidators_ShapeType" parameters="faces"/>
+    </multi_selector>
+  </groupbox>
+  <integervalue id="transparency"
+                label="Transparency"
+                min="0"
+                max="100"
+                step="10"
+                default="50">
+  </integervalue>
+  <optionalbox id="create_group" title="Create group" show_title="true">
+    <groupbox>
+      <stringvalue id="group_name" label="Group name"/>
+    </groupbox>
+  </optionalbox>
+</source>
diff --git a/src/FeaturesPlugin/shared_faces_widget.xml b/src/FeaturesPlugin/shared_faces_widget.xml
new file mode 100644 (file)
index 0000000..0c63721
--- /dev/null
@@ -0,0 +1,31 @@
+<source>
+  <shape_selector id="main_object"
+                  label="Object"
+                  tooltip="Select a compsolid or a compound"
+                  shape_types="compsolid compound"
+                  default=""
+                  geometrical_selection="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="compsolid,compound"/>
+  </shape_selector>
+  <groupbox title="Shared faces">
+    <label id="number_shared_faces" label="Number of shared faces : "/>
+    <multi_selector id="group_list"
+                      label="List of faces :"
+                      icon=""
+                      shape_types="faces"
+                      Block_selection = "true"
+                      use_choice="false">
+          <validator id="PartSet_DifferentObjects"/>
+          <validator id="GeomValidators_ShapeType" parameters="faces"/>
+    </multi_selector>
+  </groupbox>
+  <integervalue id="transparency"
+                label="Transparency"
+                min="0"
+                max="100"
+                step="10"
+                default="50">
+  </integervalue>
+  <stringvalue id="group_name" label="Group name"/>
+</source>
index 98f8623c6e627e6f85f3dabf1bf004dc4c4e7614..eca27f5167d03bd0fe4c16ace0ee77adf925c600 100644 (file)
@@ -543,6 +543,7 @@ SET(TEST_NAMES_PARA
                TestBooleanCut_Fuzzy_2.py
                TestBooleanFuse_Fuzzy.py
                TestBooleanCommon_Fuzzy.py
+               TestCheckSharedFaces.py
 )
 
 SET(TEST_NAMES_SEQ
index 1a10fc35390f651ba9e8fe7e00340213e0cbb1ad..31087ffc083a621c2c384d1186852ea1528ef11a 100644 (file)
@@ -1781,3 +1781,20 @@ void GeomAlgoAPI_ShapeTools::computeThroughAll(const ListOfShape& theObjects,
     }
   }
 }
+
+ListOfShape GeomAlgoAPI_ShapeTools::getSharedFaces(const GeomShapePtr& theShape)
+{
+  ListOfShape aSharedFaces;
+  TopTools_IndexedDataMapOfShapeListOfShape aMapFS;
+  TopExp::MapShapesAndUniqueAncestors(theShape->impl<TopoDS_Shape>(),
+                                      TopAbs_FACE, TopAbs_SOLID, aMapFS);
+  for (Standard_Integer i = 1; i <= aMapFS.Extent(); i++) {
+    const TopTools_ListOfShape& ancestors = aMapFS.FindFromIndex(i);
+    if (ancestors.Size() > 1) {
+      GeomShapePtr aFace(new GeomAPI_Shape);
+      aFace->setImpl<TopoDS_Shape>(new TopoDS_Shape(aMapFS.FindKey(i)));
+      aSharedFaces.push_back(aFace);
+    }
+  }
+  return aSharedFaces;
+}
index 0c058e147472dcce39bd0b92716dc2fad1f4bf22..b1697bd0c1fc5aeaed2f7dbb49da74effd28df89 100644 (file)
@@ -235,6 +235,11 @@ public:
                                                    const ListOfShape& theBaseShapes,
                                                    const std::shared_ptr<GeomAPI_Dir> theDir,
                                                    double& theToSize, double& theFromSize);
+
+  /// \brief Get shared faces of a shape
+  /// \param[in] theShape shape that should be exploded
+  /// \return list of shared faces
+  GEOMALGOAPI_EXPORT static ListOfShape getSharedFaces(const GeomShapePtr& theShape);
 };
 
 #endif
index 14351b736c287980b1e873af80b8fcb44bd6d582..6226b5a6aec09c5f8fe691310748bd7fad5ac6ff 100644 (file)
@@ -33,6 +33,7 @@ from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAn
 from FeaturesAPI import shapeProximity
 from FeaturesAPI import getPointCoordinates, getGeometryCalculation, getBoundingBox
 from FeaturesAPI import getNormal
+from FeaturesAPI import getSharedFaces
 from FeaturesAPI import makeVertexInsideFace
 from FeaturesAPI import addRemoveResults
 from FeaturesAPI import addCopy, addImportResult