Salome HOME
Tests fix.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_CompositeBoolean.cpp
index 507cd2da4f7479b556e98867c088088828bd098d..f54449b36ed98d0e6939561bcfea1eebfab2ef8f 100644 (file)
@@ -1,12 +1,27 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        FeaturesPlugin_CompositeBoolean.cpp
-// Created:     11 June 2015
-// Author:      Dmitry Bobylev
+// Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
+//
 
 #include "FeaturesPlugin_CompositeBoolean.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_Tools.h>
 
 #include <GeomAlgoAPI_Boolean.h>
@@ -36,7 +51,8 @@ void FeaturesPlugin_CompositeBoolean::executeCompositeBoolean()
 
   // Getting tools.
   ListOfShape aTools;
-  for(ListOfMakeShape::const_iterator anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) {
+  for(ListOfMakeShape::const_iterator
+      anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) {
     aTools.push_back((*anIt)->shape());
   }
 
@@ -62,20 +78,27 @@ void FeaturesPlugin_CompositeBoolean::executeCompositeBoolean()
     int aTag = 1;
 
     ResultBodyPtr aResultBody = myFeature->document()->createBody(myFeature->data(), aResultIndex);
-    aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape(), aTag);
-
-    aTag += 5000;
 
-    // Store generation history.
-    ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin();
-    ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin();
-    for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend();
-        ++aGenBaseIt, ++aGenMSIt) {
-      storeGenerationHistory(aResultBody, *aGenBaseIt, *aGenMSIt, aTag);
+    if((*aBoolObjIt)->isEqual((*aBoolMSIt)->shape())) {
+      aResultBody->store((*aBoolMSIt)->shape(), false);
     }
+    else
+    {
+      aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape(), aTag);
+
+      aTag += 5000;
+
+      // Store generation history.
+      ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin();
+      ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin();
+      for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend();
+          ++aGenBaseIt, ++aGenMSIt) {
+        storeGenerationHistory(aResultBody, *aGenBaseIt, *aGenMSIt, aTag);
+      }
 
-    int aModTag = aTag;
-    storeModificationHistory(aResultBody, *aBoolObjIt, aTools, *aBoolMSIt, aModTag);
+      int aModTag = aTag;
+      storeModificationHistory(aResultBody, *aBoolObjIt, aTools, *aBoolMSIt, aModTag);
+    }
 
     myFeature->setResult(aResultBody, aResultIndex++);
   }
@@ -132,13 +155,14 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       }
 
       // For solids cut each object with all tools.
-      for(ListOfShape::const_iterator anIt = anObjects.cbegin(); anIt != anObjects.cend(); ++anIt) {
+      for(ListOfShape::const_iterator
+          anIt = anObjects.cbegin(); anIt != anObjects.cend(); ++anIt) {
         GeomShapePtr anObject = *anIt;
         ListOfShape aListWithObject;
         aListWithObject.push_back(anObject);
         std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aListWithObject,
-                                                                               theTools,
-                                                                               GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                                theTools,
+                                                                GeomAlgoAPI_Boolean::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
@@ -160,7 +184,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
 
         // Collecting solids from compsolids which will not be modified in boolean operation.
         ListOfShape aShapesToAdd;
-        for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+        for(GeomAPI_ShapeExplorer
+            anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
           GeomShapePtr aSolidInCompSolid = anExp.current();
           ListOfShape::const_iterator aUsedShapesIt = aUsedShapes.cbegin();
           for(; aUsedShapesIt != aUsedShapes.cend(); ++aUsedShapesIt) {
@@ -174,8 +199,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         }
 
         std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedShapes,
-                                                                               theTools,
-                                                                               GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                                  theTools,
+                                                                  GeomAlgoAPI_Boolean::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
@@ -188,7 +213,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
 
         // Add result to not used solids from compsolid.
         aShapesToAdd.push_back(aBoolAlgo->shape());
-        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
+        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
+          new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
         if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) {
           myFeature->setError("Error: PaveFiller algorithm failed.");
           return false;
@@ -220,7 +246,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         }
       }
 
-      if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
+      if((anObjects.size() + aTools.size() +
+          aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
         myFeature->setError("Error: Not enough objects for boolean operation.");
         return false;
       }
@@ -230,7 +257,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
       aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
 
-      // Collecting solids from compsolids which will not be modified in boolean operation and will be added to result.
+      // Collecting solids from compsolids which will not be
+      // modified in boolean operation and will be added to result.
       ListOfShape aShapesToAdd;
       for(std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
           anIt != aCompSolidsObjects.end(); anIt++) {
@@ -239,7 +267,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end());
 
         // Collect solids from compsolid which will not be modified in boolean operation.
-        for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+        for(GeomAPI_ShapeExplorer
+            anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
           GeomShapePtr aSolidInCompSolid = anExp.current();
           ListOfShape::iterator anIt = aUsedShapes.begin();
           for(; anIt != aUsedShapes.end(); anIt++) {
@@ -262,8 +291,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
       if(!anEdgesAndFaces.empty() && !aCutTools.empty()) {
         std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
-                                                                              aCutTools,
-                                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                              aCutTools,
+                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
         if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) {
           anEdgesAndFaces.clear();
           anEdgesAndFaces.push_back(aCutAlgo->shape());
@@ -274,8 +303,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       // If we have compsolids then cut with not used solids all others.
       if(!aShapesToAdd.empty()) {
         std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse,
-                                                                              aShapesToAdd,
-                                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                              aShapesToAdd,
+                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
         if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
           aSolidsToFuse.clear();
           aSolidsToFuse.push_back(aCutAlgo->shape());
@@ -294,8 +323,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         aTools = aSolidsToFuse;
 
         std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
-                                                                               aTools,
-                                                                               GeomAlgoAPI_Boolean::BOOL_FUSE));
+                                                          aTools,
+                                                          GeomAlgoAPI_Boolean::BOOL_FUSE));
 
         // Checking that the algorithm worked properly.
         if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) {
@@ -314,7 +343,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
           aShapesToAdd.push_back(aFusedShape);
         }
 
-        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
+        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
+          new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
         if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) {
           myFeature->setError("Error: PaveFiller algorithm failed.");
           return false;
@@ -364,8 +394,9 @@ void FeaturesPlugin_CompositeBoolean::storeModificationHistory(ResultBodyPtr the
       aTag = aModTag;
       aName = aModName;
     }
-    theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, (*anIt)->shapeType() == GeomAPI_Shape::EDGE ?
-                                               GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get());
+    theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt,
+      (*anIt)->shapeType() == GeomAPI_Shape::EDGE ?
+      GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get(), false, false, true);
     theResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
   }
 }