Salome HOME
[EDF] (2023-T1) Filters on group
[modules/shaper.git] / src / Model / Model_FiltersFactory.cpp
index 005d927ce00b2dba18b51c4a1197fab9f5b9f68f..3e213d04e140ee09f1d91fc040d527b3779ee767 100644 (file)
 
 #include "GeomAPI_Edge.h"
 
+#include <unordered_map>
+#include <stack>
+
+typedef std::unordered_map<GeomShapePtr, ResultBodyPtr,
+                          GeomAPI_Shape::Hash, GeomAPI_Shape::Equal> DataMapOfShapesToResults;
+
 void Model_FiltersFactory::registerFilter(const std::string& theID, ModelAPI_Filter* theFilter)
 {
   if (myFilters.find(theID) != myFilters.end()) {
@@ -56,6 +62,50 @@ static std::string pureFilterID(const std::string& theID)
   return theID;
 }
 
+static void fillMapOfShapesToResults(DataMapOfShapesToResults& theMap,
+                             const ResultBodyPtr& theBodyResult,
+                             const GeomAPI_Shape::ShapeType theShapeType)
+{
+  std::stack<ResultBodyPtr> stack;
+  stack.push(theBodyResult);
+
+  while(!stack.empty())
+  {
+    ResultBodyPtr aCurrBodyRes = stack.top();
+    stack.pop();
+
+    int nbSubs = aCurrBodyRes->numberOfSubs();
+    if(nbSubs == 0)
+    {
+      GeomShapePtr aShape = aCurrBodyRes->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;
+        
+        if (theMap.find(aSubShape) == theMap.end()) 
+        {
+          theMap.emplace(aSubShape, aCurrBodyRes);
+        }
+      }
+    }
+    else
+    {
+        for (int aSubIndex = 0; aSubIndex < nbSubs; aSubIndex++) 
+        {
+          stack.push(aCurrBodyRes->subResult(aSubIndex));
+        }
+    }
+  }
+
+}
+
 bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature,
                                    ResultPtr theResult,
                                    GeomShapePtr theShape)
@@ -104,6 +154,7 @@ bool Model_FiltersFactory::isValid(FeaturePtr theFiltersFeature,
   for(; aFilter != aFilters.end(); aFilter++) {
     anArgs.setFilter(aFilter->myFilterID);
     bool aResult = aFilter->myFilter->isOk(theShape, theResult, anArgs);
+
     if (aFilter->myReverse)
       aResult = !aResult;
     if (!aResult) // one filter is failed => exit immediately
@@ -123,46 +174,36 @@ std::list< std::pair<ResultPtr, GeomShapePtr> > Model_FiltersFactory::select
   int aNb = aDoc->size(ModelAPI_ResultBody::group());
   ObjectPtr aObj;
   ResultBodyPtr aBody;
-  for (int i = 0; i < aNb; i++) {
+  for (int i = 0; i < aNb; i++) 
+  {
     aObj = aDoc->object(ModelAPI_ResultBody::group(), i);
     aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
+    DataMapOfShapesToResults aShapeToResMap;
+    fillMapOfShapesToResults(aShapeToResMap, aBody, theShapeType);
+
     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++) {
+    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;
-            }
-          }
+
+      if (aShapeToResMap.find(aSubShape) != aShapeToResMap.end()) 
+      {
+        ResultBodyPtr aResBody = aShapeToResMap[aSubShape];
+        if(this->isValid(theFilterFeature, aResBody, aSubShape))
+        {
+           std::pair<ResultPtr, GeomShapePtr> aPair(aResBody, aSubShape);
+          aResList.push_back(aPair);
         }
-        std::pair<ResultPtr, GeomShapePtr> aPair (aContext, aSubShape);
-        aResList.push_back(aPair);
       }
     }
   }
-
   return aResList;
 }