]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
bos #26374 In python, be able to use filters to select sub-shapes
authorjfa <jfa@opencascade.com>
Wed, 16 Feb 2022 19:06:08 +0000 (22:06 +0300)
committervsr <vsr@opencascade.com>
Wed, 2 Mar 2022 15:01:51 +0000 (18:01 +0300)
src/FiltersAPI/FiltersAPI_Selection.cpp
src/FiltersAPI/FiltersAPI_Selection.h
src/FiltersPlugin/Test/TestFilters_Select.py [new file with mode: 0644]
src/FiltersPlugin/tests.set
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/Model/Model_FiltersFactory.cpp
src/Model/Model_FiltersFactory.h
src/ModelAPI/ModelAPI_FiltersFactory.h
src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp

index 09eee7debf2c6016fadb1a97e39d207b45759849..378365131cc5e756ebed039f4dba59475d88cc28 100644 (file)
 
 #include "FiltersAPI_Selection.h"
 
+#include "GeomAPI_Edge.h"
+#include "ModelAPI_Session.h"
+#include "ModelAPI_FiltersFactory.h"
+#include "ModelHighAPI_Services.h"
+
 FiltersAPI_Selection::FiltersAPI_Selection(const FiltersPtr & theFeature)
 {
   myVariantType = VT_Filtering;
@@ -34,6 +39,33 @@ FiltersFeaturePtr FiltersAPI_Selection::feature() const
   return myFilterFeature;
 }
 
+std::list<ModelHighAPI_Selection> FiltersAPI_Selection::select
+                                  (const std::string theShapeType) const
+{
+  return select(GeomAPI_Shape::shapeTypeByStr(theShapeType));
+}
+
+std::list<ModelHighAPI_Selection> FiltersAPI_Selection::select
+                                  (const GeomAPI_Shape::ShapeType theShapeType) const
+{
+  // finish operation to make sure the selection is done on the current state of the history
+  apply();
+
+  std::list<ModelHighAPI_Selection> aSelList;
+  static SessionPtr aSession = ModelAPI_Session::get();
+  std::list< std::pair<ResultPtr, GeomShapePtr> > aResList =
+    aSession->filters()->select(myFilterFeature, theShapeType);
+
+  std::list< std::pair<ResultPtr, GeomShapePtr> >::const_iterator itSelected = aResList.cbegin();
+  for (; itSelected != aResList.cend(); itSelected++) {
+    ResultPtr aCurRes = (*itSelected).first;
+    GeomShapePtr aSubShape = (*itSelected).second;
+    aSelList.push_back(ModelHighAPI_Selection(aCurRes, aSubShape));
+  }
+
+  return aSelList;
+}
+
 // ================================================================================================
 FiltersAPI_Selection filters(const std::shared_ptr<ModelAPI_Document>& thePart,
                              const std::list<FilterAPIPtr>& theFilters)
index 9a9756a07842cc2890c7c83f06f8ec2914d82246..a520097f715650b55349f34920e5dfe1bb80b0f8 100644 (file)
@@ -44,6 +44,12 @@ public:
   /// Return filters feature
   FILTERSAPI_EXPORT
   FiltersFeaturePtr feature() const;
+
+  /// Return selected entities
+  FILTERSAPI_EXPORT
+  std::list<ModelHighAPI_Selection> select(const std::string theShapeType) const;
+  FILTERSAPI_EXPORT
+  std::list<ModelHighAPI_Selection> select(const GeomAPI_Shape::ShapeType theShapeType) const;
 };
 
 /// Create list of filters
diff --git a/src/FiltersPlugin/Test/TestFilters_Select.py b/src/FiltersPlugin/Test/TestFilters_Select.py
new file mode 100644 (file)
index 0000000..165ede3
--- /dev/null
@@ -0,0 +1,64 @@
+# 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
+#
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+from ModelHighAPI import *
+import math
+
+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)
+model.do()
+
+### Create Filters
+filter_1 = model.addFilter(name = "OnPlane",
+                           args = [model.selection("FACE", "Box_1_1/Left")])
+
+filter_2 = model.addFilter(name = "OnPlane",
+                           args = [model.selection("FACE", "Box_1_1/Top")])
+
+filters = model.filters(Part_1_doc, [filter_1, filter_2])
+
+### Select all (one) suitable edges
+selected_edges = filters.select("Edges")
+
+group_1 = model.addGroup(Part_1_doc, "Edges", selected_edges)
+assert(group_1.feature().results().size() == 1)
+
+# Check the selected edge
+aResult = group_1.results()[0].resultSubShapePair()[0]
+aShape = aResult.shape()
+aShapeExplorer = GeomAPI_ShapeExplorer(aShape, GeomAPI_Shape.EDGE)
+assert(aShapeExplorer.more())
+anEdge = aShapeExplorer.current()
+assert(anEdge.edge().isLine() and math.fabs(anEdge.edge().line().direction().x() - 1.0) < 1.e-7)
+aLoc = anEdge.edge().line().location()
+assert(math.fabs(aLoc.x()) < 1.e-7)
+assert(math.fabs(aLoc.y()) < 1.e-7)
+assert(math.fabs(aLoc.z() - 10.0) < 1.e-7)
+aShapeExplorer.next()
+assert(not aShapeExplorer.more())
+
+model.end()
index 98aa0c3404835d86882b10545df937860cc9c5b0..2a61388bb3aacf3da299958d74f24fbf31f191fb 100644 (file)
@@ -27,6 +27,7 @@ SET(TEST_NAMES
   TestFilters_FilterName.py
   TestFilters_IsReversed.py
   TestFilters_Remove.py
+  TestFilters_Select.py
   TestFilter_BelongsTo.py
   TestFilter_BelongsTo_Exclude.py
   TestFilter_OnPlane.py
index 7168ccdb5ac04c8bfc87a3aec94ac45d3a7b6a2b..5e1c8f2142a08888e382190121ced8a426c3473b 100644 (file)
@@ -419,21 +419,25 @@ std::shared_ptr<GeomAPI_Solid> GeomAPI_Shape::solid() const
 }
 
 std::list<std::shared_ptr<GeomAPI_Shape> >
-GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const
+GeomAPI_Shape::subShapes(const ShapeType theSubShapeType, const bool theOnlyUnique) const
 {
   ListOfShape aSubs;
   const TopoDS_Shape& aShape = impl<TopoDS_Shape>();
   if (aShape.IsNull())
     return aSubs;
 
+  TopTools_MapOfShape alreadyThere;
+
   // process multi-level compounds
   if (shapeType() == COMPOUND && theSubShapeType == COMPOUND) {
     for (TopoDS_Iterator anIt(aShape); anIt.More(); anIt.Next()) {
       const TopoDS_Shape& aCurrent = anIt.Value();
       if (aCurrent.ShapeType() == TopAbs_COMPOUND) {
-        GeomShapePtr aSub(new GeomAPI_Shape);
-        aSub->setImpl(new TopoDS_Shape(aCurrent));
-        aSubs.push_back(aSub);
+        if (!theOnlyUnique || alreadyThere.Add(aCurrent)) {
+          GeomShapePtr aSub(new GeomAPI_Shape);
+          aSub->setImpl(new TopoDS_Shape(aCurrent));
+          aSubs.push_back(aSub);
+        }
       }
     }
     // add self
@@ -444,9 +448,11 @@ GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const
   else {
     for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType);
          anExp.More(); anExp.Next()) {
-      GeomShapePtr aSub(new GeomAPI_Shape);
-      aSub->setImpl(new TopoDS_Shape(anExp.Current()));
-      aSubs.push_back(aSub);
+      if (!theOnlyUnique || alreadyThere.Add(anExp.Current())) {
+        GeomShapePtr aSub(new GeomAPI_Shape);
+        aSub->setImpl(new TopoDS_Shape(anExp.Current()));
+        aSubs.push_back(aSub);
+      }
     }
   }
   return aSubs;
index fad3425c05e15990e474458e8ac76494d1e075be..f8ed719713708a2fd715f5567db45a5cfa9dd7fe 100644 (file)
@@ -156,8 +156,12 @@ public:
   std::shared_ptr<GeomAPI_Solid> solid() const;
 
   /// Returns list of sub-shapes of the given type
+  /// \param theSubShapeType type of sub-shapes to search.
+  /// \param theOnlyUnique set it to \c true to omit subsequent
+  ///        inclusions of the same sub-shape. By default it is \c false.
   GEOMAPI_EXPORT
-  std::list<std::shared_ptr<GeomAPI_Shape> > subShapes(ShapeType theSubShapeType) const;
+  std::list< std::shared_ptr<GeomAPI_Shape> > subShapes(const ShapeType theSubShapeType,
+                                                        const bool theOnlyUnique = false) const;
 
   /// Returns the shape type
   GEOMAPI_EXPORT
index df0f4e061a78d7c8a2f1a46b956b06db66b6d09b..6c36f286e42c63bb596223ba799c6009d740b5ed 100644 (file)
@@ -23,6 +23,7 @@
 #include "ModelAPI_AttributeSelectionList.h"
 #include <Events_InfoMessage.h>
 
+#include "GeomAPI_Edge.h"
 
 void Model_FiltersFactory::registerFilter(const std::string& theID, ModelAPI_Filter* theFilter)
 {
@@ -112,6 +113,59 @@ bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature,
   return true;
 }
 
+std::list< std::pair<ResultPtr, GeomShapePtr> > Model_FiltersFactory::select
+(const FiltersFeaturePtr& theFilterFeature,
+ const GeomAPI_Shape::ShapeType theShapeType)
+{
+  std::list< std::pair<ResultPtr, GeomShapePtr> > aResList;
+
+  DocumentPtr aDoc = theFilterFeature->document();
+  int aNb = aDoc->size(ModelAPI_ResultBody::group());
+  ObjectPtr aObj;
+  ResultBodyPtr aBody;
+  for (int i = 0; i < aNb; i++) {
+    aObj = aDoc->object(ModelAPI_ResultBody::group(), i);
+    aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
+    GeomShapePtr aShape = aBody->shape();
+    std::list<GeomShapePtr> aSubShapes = aShape->subShapes(theShapeType, true);
+    std::list<GeomShapePtr>::const_iterator aShapesIt;
+    for (aShapesIt = aSubShapes.cbegin(); aShapesIt != aSubShapes.cend(); aShapesIt++) {
+      GeomShapePtr aSubShape = (*aShapesIt);
+
+      // degenerated edge is not valid selection
+      if (theShapeType == GeomAPI_Shape::EDGE)
+        if (aSubShape->edge()->isDegenerated())
+          continue;
+
+      bool isValid = this->isValid(theFilterFeature, aBody, aSubShape);
+
+      if (isValid) {
+        // bos #24043: Naming on a compsolid works wrong.
+        // Find a simple sub-result for the ViewerPrs context:
+        ResultBodyPtr aContext = aBody;
+        bool isComposite = aContext->numberOfSubs() > 0;
+        while (isComposite) {
+          isComposite = false;
+          int nbSubs = aContext->numberOfSubs();
+          for (int aSubIndex = 0; aSubIndex < nbSubs; aSubIndex++) {
+            ResultBodyPtr aSubResult = aContext->subResult(aSubIndex);
+            GeomShapePtr aSubResultShape = aSubResult->shape();
+            if (aSubResultShape->isSubShape(aSubShape)) {
+              aContext = aSubResult;
+              isComposite = aContext->numberOfSubs() > 0;
+              break;
+            }
+          }
+        }
+        std::pair<ResultPtr, GeomShapePtr> aPair (aContext, aSubShape);
+        aResList.push_back(aPair);
+      }
+    }
+  }
+
+  return aResList;
+}
+
 /// Returns list of filters for the given shape type
 /// \param theType a shape type
 std::list<FilterPtr> Model_FiltersFactory::filters(GeomAPI_Shape::ShapeType theType)
index d272d0a4745cda8ec4f4a51aee3de91900622a57..8dab7427684315c94b7c79fa8b18b5c5ef8e0a91 100644 (file)
@@ -47,6 +47,14 @@ public:
                        ResultPtr theResult,
                        GeomShapePtr theShape);
 
+  /// Returns list of all shapes and subshapes in the study, satisfying
+  ///         criteria of all filters of \a theFilterFeature.
+  /// \param theFiltersFeature feature that contains all information about the filters
+  /// \param theShapeType the type of sub-shapes to find
+  virtual std::list< std::pair<ResultPtr, GeomShapePtr> > select
+    (const FiltersFeaturePtr& theFilterFeature,
+     const GeomAPI_Shape::ShapeType theShapeType);
+
   /// Returns the filters that support the given shape type
   virtual std::list<FilterPtr> filters(GeomAPI_Shape::ShapeType theType);
 
@@ -66,4 +74,4 @@ private:
   friend class Model_Session;
 };
 
-#endif
\ No newline at end of file
+#endif
index 70b93bb091195e6b37059936df94deb6cb069f3b..d82a738c8962ae1276f32b9bcb53b44ff5fa444f 100644 (file)
@@ -50,6 +50,14 @@ public:
                        ResultPtr theResult,
                        GeomShapePtr theShape) = 0;
 
+  /// Returns list of all shapes and subshapes in the study, satisfying
+  ///         criteria of all filters of \a theFilterFeature.
+  /// \param theFiltersFeature feature that contains all information about the filters
+  /// \param theShapeType the type of sub-shapes to find
+  virtual std::list< std::pair<ResultPtr, GeomShapePtr> > select
+    (const FiltersFeaturePtr& theFilterFeature,
+     const GeomAPI_Shape::ShapeType theShapeType) = 0;
+
   /// Returns the filters that support the given shape type
   virtual std::list<FilterPtr> filters(GeomAPI_Shape::ShapeType theType) = 0;
 
@@ -64,4 +72,4 @@ protected:
   ModelAPI_FiltersFactory() {}
 };
 
-#endif
\ No newline at end of file
+#endif
index acfc5c633872fb86afd492e0c2ba19a153602538..e027461f6034178b999cd2c36bfdc2631665a820 100644 (file)
@@ -454,60 +454,24 @@ void ModuleBase_WidgetSelectionFilter::onSelect()
 
   clearCurrentSelection();
 
+  FiltersFeaturePtr aFiltersFeature =
+    std::dynamic_pointer_cast<ModelAPI_FiltersFeature>(myFeature);
+  static SessionPtr aSession = ModelAPI_Session::get();
+  std::list< std::pair<ResultPtr, GeomShapePtr> > aResList =
+    aSession->filters()->select(aFiltersFeature, (GeomAPI_Shape::ShapeType)mySelectionType);
+
   BRep_Builder aBuilder;
   TopoDS_Compound aComp;
   aBuilder.MakeCompound(aComp);
 
-  DocumentPtr aDoc = myFeature->document();
-  int aNb = aDoc->size(ModelAPI_ResultBody::group());
-  ObjectPtr aObj;
-  ResultBodyPtr aBody;
-  for (int i = 0; i < aNb; i++) {
-    aObj = aDoc->object(ModelAPI_ResultBody::group(), i);
-    aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
-    GeomShapePtr aShape = aBody->shape();
-    std::list<GeomShapePtr> aSubShapes =
-      aShape->subShapes((GeomAPI_Shape::ShapeType)mySelectionType);
-    TopTools_MapOfShape alreadyThere;
-    std::list<GeomShapePtr>::const_iterator aShapesIt;
-    for (aShapesIt = aSubShapes.cbegin(); aShapesIt != aSubShapes.cend(); aShapesIt++) {
-      GeomShapePtr aSubShape = (*aShapesIt);
-      TopoDS_Shape aTShape = aSubShape->impl<TopoDS_Shape>();
-      if (!alreadyThere.Add(aTShape))
-        continue;
-
-      // degenerated edge is not valid selection
-      if ((GeomAPI_Shape::ShapeType)mySelectionType == GeomAPI_Shape::EDGE)
-        if (aSubShape->edge()->isDegenerated())
-          continue;
-
-      static SessionPtr aSession = ModelAPI_Session::get();
-      bool isValid = aSession->filters()->isValid(myFeature, aBody, aSubShape);
-
-      if (isValid) {
-        aBuilder.Add(aComp, aTShape);
-        // bos #24043: Naming on a compsolid works wrong.
-        // Find a simple sub-result for the ViewerPrs context:
-        ResultBodyPtr aContext = aBody;
-        bool isComposite = aContext->numberOfSubs() > 0;
-        while (isComposite) {
-          isComposite = false;
-          int nbSubs = aContext->numberOfSubs();
-          for (int aSubIndex = 0; aSubIndex < nbSubs; aSubIndex++) {
-            ResultBodyPtr aSubResult = aContext->subResult(aSubIndex);
-            GeomShapePtr aSubResultShape = aSubResult->shape();
-            if (aSubResultShape->isSubShape(aSubShape)) {
-              aContext = aSubResult;
-              isComposite = aContext->numberOfSubs() > 0;
-              break;
-            }
-          }
-        }
-        ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aContext, aSubShape));
-        //ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aObj, aSubShape));
-        myValues.append(aValue);
-      }
-    }
+  std::list< std::pair<ResultPtr, GeomShapePtr> >::const_iterator itSelected = aResList.cbegin();
+  for (; itSelected != aResList.cend(); itSelected++) {
+    ResultPtr aCurRes = (*itSelected).first;
+    GeomShapePtr aSubShape = (*itSelected).second;
+    TopoDS_Shape aTShape = aSubShape->impl<TopoDS_Shape>();
+    aBuilder.Add(aComp, aTShape);
+    ModuleBase_ViewerPrsPtr aValue (new ModuleBase_ViewerPrs(aCurRes, aSubShape));
+    myValues.append(aValue);
   }
 
   if (myValues.size() > 0)