Salome HOME
Fix for the problem of the nightly unit-tests performance.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Fillet.cpp
index cf1dda3d287a099f5d4b80700c6e06b769673cc1..8dcd2fae4e5383a3ebe1aa74ecf7d24b1c2a7114 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017  CEA/DEN, EDF R&D
+// Copyright (C) 2017-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // 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
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "FeaturesPlugin_Fillet.h"
+#include "FeaturesPlugin_Tools.h"
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_AttributeDouble.h>
@@ -29,6 +29,7 @@
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_Validator.h>
 
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_Fillet.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_Tools.h>
@@ -62,7 +63,7 @@ static ListOfShape selectEdges(const ListOfShape& theShapes)
   return anEdges;
 }
 
-// If theShape is a compound of single shape, return it
+// If theShape is a compound of a single sub-shape, return this sub-shape
 static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
 {
   GeomShapePtr aShape = theShape;
@@ -102,9 +103,9 @@ void FeaturesPlugin_Fillet::execute()
   if (!aCreationMethod)
     return;
 
-  GeomAPI_DataMapOfShapeMapOfShapes aSolidsAndSubs;
+  std::list<std::pair<GeomShapePtr, ListOfShape> > aSolidsAndSubs;
 
-  // getting objects and sort them accroding to parent solids
+  // getting objects and sort them according to parent solids
   AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
   for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
     AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
@@ -126,12 +127,26 @@ void FeaturesPlugin_Fillet::execute()
     if (!aParent)
       return;
 
+    // searching this parent is already in the list aSolidsAndSubs
+    std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator aSearch = aSolidsAndSubs.begin();
+    ListOfShape* aFound;
+    for(; aSearch != aSolidsAndSubs.end(); aSearch++) {
+      if (aSearch->first->isSame(aParent)) {
+        aFound = &(aSearch->second);
+        break;
+      }
+    }
+    if (aSearch == aSolidsAndSubs.end()) { // not found, so, add a new one
+      aSolidsAndSubs.push_back(std::pair<GeomShapePtr, ListOfShape>(aParent, ListOfShape()));
+      aFound = &(aSolidsAndSubs.back().second);
+    }
+
     ListOfShape anEdgesAndVertices;
     collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
     collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
     for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
          aEIt != anEdgesAndVertices.end(); ++aEIt)
-      aSolidsAndSubs.add(aParent, *aEIt);
+      aFound->push_back(*aEIt);
   }
 
   bool isFixedRadius = true;
@@ -150,10 +165,13 @@ void FeaturesPlugin_Fillet::execute()
   int aResultIndex = 0;
   std::string anError;
 
-  GeomAPI_DataMapOfShapeMapOfShapes::iterator anIt = aSolidsAndSubs.begin();
+  std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
+  ListOfShape anOriginalShapesList, aResultShapesList;
+
+  std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator anIt = aSolidsAndSubs.begin();
   for (; anIt != aSolidsAndSubs.end(); ++anIt) {
-    GeomShapePtr aSolid = anIt.first();
-    ListOfShape aFilletEdgesAndVertices = anIt.second();
+    GeomShapePtr aSolid = anIt->first;
+    ListOfShape aFilletEdgesAndVertices = anIt->second;
 
     ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
     if (isFixedRadius)
@@ -170,43 +188,37 @@ void FeaturesPlugin_Fillet::execute()
     std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
-    loadNamingDS(aResultBody, aSolid, aResult, aFilletBuilder);
+    ListOfShape aBaseShapes;
+    aBaseShapes.push_back(aSolid);
+    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+                                             aFilletBuilder, aResult, "Fillet");
+
     setResult(aResultBody, aResultIndex);
     aResultIndex++;
-  }
-  removeResults(aResultIndex);
-}
 
-void FeaturesPlugin_Fillet::loadNamingDS(
-    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
-    const std::shared_ptr<GeomAPI_Shape> theResultShape,
-    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
-{
-  //load result
-  if(theBaseShape->isEqual(theResultShape)) {
-    theResultBody->store(theResultShape, false);
-    return;
+    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+    aRBA.resultBody = aResultBody;
+    aRBA.baseShape = aSolid;
+    aRBA.makeShape = aFilletBuilder;
+    aResultBaseAlgoList.push_back(aRBA);
+    aResultShapesList.push_back(aResult);
+    anOriginalShapesList.push_back(aSolid);
+
+    const std::string aFilletFaceName = "Fillet";
+    ListOfShape::iterator aSelectedBase = aFilletEdges.begin();
+    for(; aSelectedBase != aFilletEdges.end(); aSelectedBase++) {
+      GeomShapePtr aBase = *aSelectedBase;
+      // Store new faces generated from edges and vertices
+      aResultBody->loadGeneratedShapes(
+        aFilletBuilder, aBase, GeomAPI_Shape::EDGE, aFilletFaceName, true);
+    }
   }
 
-  theResultBody->storeModified(theBaseShape, theResultShape);
+  // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
+  // result shape has been deleted, but in another it was modified or stayed.
+  GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
+  FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
+      anOriginalShapesList, aResultShapesCompound);
 
-  const std::string aFilletFaceName = "Fillet_Face";
-
-  // Store modified faces
-  theResultBody->loadModifiedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE);
-
-  // Store new faces generated from edges and vertices
-  theResultBody->loadGeneratedShapes(theMakeShape,
-                                     theBaseShape,
-                                     GeomAPI_Shape::EDGE,
-                                     aFilletFaceName);
-  theResultBody->loadGeneratedShapes(theMakeShape,
-                                     theBaseShape,
-                                     GeomAPI_Shape::VERTEX,
-                                     aFilletFaceName);
-
-  // Deleted shapes
-  theResultBody->loadDeletedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE);
-  theResultBody->loadDeletedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE);
+  removeResults(aResultIndex);
 }