Salome HOME
Merge branch 'Results_Hierarchy'
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Partition.cpp
index 1fed0c7d840ab7c244f1c5274256e554e142eb15..afb763fc614e09bd5a30eb49f3ba37afc0a40ac4 100755 (executable)
@@ -1,8 +1,22 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-// File:        FeaturesPlugin_Partition.cpp
-// Created:     31 Jul 2015
-// Author:      Natalia ERMOLAEVA
+// 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_Partition.h"
 
 #include <GeomAlgoAPI_ShapeTools.h>
 
 #include <GeomAPI_Face.h>
+#include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_ShapeIterator.h>
 
+#include <iostream>
 #include <sstream>
 
+static GeomShapePtr findBase(const GeomShapePtr theObjectShape,
+                             const GeomShapePtr theResultShape,
+                             const GeomAPI_Shape::ShapeType theShapeType,
+                             const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
 //=================================================================================================
 FeaturesPlugin_Partition::FeaturesPlugin_Partition()
 {
@@ -64,7 +85,8 @@ void FeaturesPlugin_Partition::execute()
     return;
   }
 
-  std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
+  std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+    GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
 
   // Resize planes.
   ListOfShape aTools;
@@ -79,7 +101,8 @@ void FeaturesPlugin_Partition::execute()
   }
 
   // Create single result.
-  std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
+  std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(
+    new GeomAlgoAPI_Partition(anObjects, aTools));
 
   // Checking that the algorithm worked properly.
   if (!aPartitionAlgo->isDone()) {
@@ -101,14 +124,13 @@ void FeaturesPlugin_Partition::execute()
   GeomShapePtr aResultShape = aPartitionAlgo->shape();
 
   int aResultIndex = 0;
-  anObjects.insert(anObjects.end(), aPlanes.begin(), aPlanes.end());
   if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
     for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
-      storeResult(anObjects, anIt.current(), aMakeShapeList, aResultIndex);
+      storeResult(anObjects, aPlanes, anIt.current(), aMakeShapeList, aResultIndex);
       ++aResultIndex;
     }
   } else {
-    storeResult(anObjects, aResultShape, aMakeShapeList, aResultIndex);
+    storeResult(anObjects, aPlanes, aResultShape, aMakeShapeList, aResultIndex);
     ++aResultIndex;
   }
 
@@ -117,26 +139,29 @@ void FeaturesPlugin_Partition::execute()
 }
 
 //=================================================================================================
-void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
-                                           const GeomShapePtr theResultShape,
-                                           const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
-                                           const int theIndex)
+void FeaturesPlugin_Partition::storeResult(
+  ListOfShape& theObjects, ListOfShape& thePlanes,
+  const GeomShapePtr theResultShape,
+  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+  const int theIndex)
 {
-  // Find base.
+  // Find base. The most complicated is the real modified object (#1799 if box is partitioned by
+  // two planes the box is the base, not planes, independently on the order in the list).
   GeomShapePtr aBaseShape;
   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
     GeomShapePtr anObjectShape = *anIt;
-    ListOfShape aModifiedShapes;
-    theMakeShape->modified(anObjectShape, aModifiedShapes);
-    for(ListOfShape::const_iterator aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
-      GeomShapePtr aModShape = *aModIt;
-      if(theResultShape->isSubShape(aModShape)) {
-        aBaseShape = anObjectShape;
-        break;
-      }
+    GeomShapePtr aCandidate =
+      findBase(anObjectShape, theResultShape, GeomAPI_Shape::VERTEX, theMakeShape);
+    if(!aCandidate.get()) {
+      aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::EDGE, theMakeShape);
     }
-    if(aBaseShape.get()) {
-      break;
+    if (!aCandidate.get())
+      aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::FACE, theMakeShape);
+
+    if(aCandidate.get()) {
+      if (!aBaseShape.get() || aBaseShape->shapeType() > aCandidate->shapeType()) {
+        aBaseShape = aCandidate;
+      }
     }
   }
 
@@ -145,31 +170,66 @@ void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
 
   // Store modified shape.
   if(!aBaseShape.get() || aBaseShape->isEqual(theResultShape)) {
-    aResultBody->store(theResultShape);
+    aResultBody->store(theResultShape, false);
     setResult(aResultBody, theIndex);
     return;
   }
 
   const int aDelTag = 1;
-  const int aSubTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
+  /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
+  const int aSubTag = 2;
   int aModTag = aSubTag + 10000;
   const std::string aModName = "Modified";
 
   aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
 
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
+  theObjects.insert(theObjects.end(), thePlanes.begin(), thePlanes.end());
   int anIndex = 1;
   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
-    std::ostringstream aStream;
-    aStream << aModName << "_" << anIndex++;
-    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE,
-                                             aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
-    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE,
-                                             aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
-    aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE, aDelTag);
-    aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
-    aModTag += 10000;
+    GeomShapePtr aShape = *anIt;
+    std::string aModEdgeName = aModName + "_Edge_" + std::to_string((long long)anIndex);
+    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::EDGE,
+      aModTag, aModEdgeName, *aMapOfSubShapes.get(), false, true, true);
+    std::string aModFaceName = aModName + "_Face_" + std::to_string((long long)anIndex++);
+    aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE,
+      aModTag + 1, aModFaceName, *aMapOfSubShapes.get(), false, true, true);
+    aResultBody->loadDeletedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE, aDelTag);
   }
 
   setResult(aResultBody, theIndex);
 }
+
+
+//=================================================================================================
+GeomShapePtr findBase(const GeomShapePtr theObjectShape,
+                      const GeomShapePtr theResultShape,
+                      const GeomAPI_Shape::ShapeType theShapeType,
+                      const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+  GeomShapePtr aBaseShape;
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
+  for(GeomAPI_ShapeExplorer anObjectSubShapesExp(theObjectShape, theShapeType);
+      anObjectSubShapesExp.more();
+      anObjectSubShapesExp.next()) {
+    GeomShapePtr anObjectSubShape = anObjectSubShapesExp.current();
+    ListOfShape aModifiedShapes;
+    theMakeShape->modified(anObjectSubShape, aModifiedShapes);
+    for(ListOfShape::const_iterator
+        aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
+      GeomShapePtr aModShape = *aModIt;
+      if(aMapOfSubShapes->isBound(aModShape)) {
+        aModShape = aMapOfSubShapes->find(aModShape);
+      }
+      if(theResultShape->isSubShape(aModShape)) {
+        aBaseShape = theObjectShape;
+        break;
+      }
+    }
+    if(aBaseShape.get()) {
+      break;
+    }
+  }
+
+  return aBaseShape;
+}