Salome HOME
Refactor Boolean operations in FeaturesPlugin.
authorazv <azv@opencascade.com>
Fri, 26 Apr 2019 07:31:10 +0000 (10:31 +0300)
committerazv <azv@opencascade.com>
Fri, 26 Apr 2019 07:31:10 +0000 (10:31 +0300)
13 files changed:
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Partition.cpp
src/FeaturesPlugin/FeaturesPlugin_Union.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h
src/GeomAlgoAPI/GeomAlgoAPI_Tools.h

index b768b90af0aadaf7e6dde8a80af97b2601189f5f..d466d1a1348e046c44d7350dc6027645309ebfd9 100644 (file)
 #include <ModelAPI_Tools.h>
 
 #include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_MakeShapeCustom.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_Partition.h>
 #include <GeomAlgoAPI_PaveFiller.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_Tools.h>
 #include <GeomAPI_Face.h>
 #include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_ShapeIterator.h>
@@ -68,6 +70,48 @@ FeaturesPlugin_Boolean::OperationType FeaturesPlugin_Boolean::operationType()
   return myOperationType;
 }
 
+//=================================================================================================
+void FeaturesPlugin_Boolean::parentForShape(const GeomShapePtr& theShape,
+                                            const ResultPtr& theContext,
+                                            ObjectHierarchy& theShapesHierarchy)
+{
+  ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(theContext);
+  if (aResCompSolidPtr.get()) {
+    std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
+    if (aContextShape->shapeType() <= GeomAPI_Shape::COMPSOLID) {
+      theShapesHierarchy.AddParent(theShape, aContextShape);
+      parentForShape(aContextShape, aResCompSolidPtr, theShapesHierarchy);
+    }
+  }
+}
+
+bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeName,
+                                              ObjectHierarchy& theObjects,
+                                              ListOfShape& thePlanesList)
+{
+  AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName);
+  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    GeomShapePtr anObject = anObjectAttr->value();
+    if (!anObject.get()) {
+      // It could be a construction plane.
+      ResultPtr aContext = anObjectAttr->context();
+      anObject = anObjectAttr->context()->shape();
+      if (anObject.get()) {
+        thePlanesList.push_back(anObject);
+        continue;
+      } else
+        return false;
+    }
+
+    theObjects.AddObject(anObject);
+
+    ResultPtr aContext = anObjectAttr->context();
+    parentForShape(anObject, aContext, theObjects);
+  }
+  return true;
+}
+
 //=================================================================================================
 void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
                                           const std::shared_ptr<GeomAPI_Shape> theBaseShape,
@@ -100,3 +144,385 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> t
     theResultBody->loadDeletedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE);
   }
 }
+
+//=================================================================================================
+bool FeaturesPlugin_Boolean::processObject(
+    const GeomAlgoAPI_Tools::BOPType theBooleanType,
+    const GeomShapePtr& theObject,
+    const ListOfShape& theTools,
+    const ListOfShape& thePlanes,
+    int& theResultIndex,
+    std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+    ListOfShape& theResultShapesList)
+{
+  ListOfShape aListWithObject;
+  aListWithObject.push_back(theObject);
+  std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+  std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
+  GeomShapePtr aResShape;
+
+  std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+      GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0);
+
+  // Resize planes.
+  ListOfShape aToolsWithPlanes = theTools;
+  for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) {
+    GeomShapePtr aPlane = *anIt;
+    GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
+    std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
+        new GeomAlgoAPI_MakeShapeCustom);
+    aMkShCustom->addModified(aPlane, aTool);
+    aMakeShapeList->appendAlgo(aMkShCustom);
+    aToolsWithPlanes.push_back(aTool);
+  }
+
+  if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION)
+    aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes));
+  else
+    aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject,
+                                            aToolsWithPlanes,
+                                            theBooleanType));
+
+  // Checking that the algorithm worked properly.
+  std::string anError;
+  if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
+    setError(anError);
+    return false;
+  }
+
+  aResShape = aBoolAlgo->shape();
+  if (aResShape.get() && aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+    int aSubResultsNb = 0;
+    GeomAPI_ShapeIterator anIt(aResShape);
+    for (; anIt.more(); anIt.next())
+      ++aSubResultsNb;
+
+    if (aSubResultsNb == 1) {
+      anIt.init(aResShape);
+      if (anIt.more())
+        aResShape = anIt.current();
+    }
+  }
+
+  aMakeShapeList->appendAlgo(aBoolAlgo);
+
+  GeomAPI_ShapeIterator aShapeIt(aResShape);
+  if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) {
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+        document()->createBody(data(), theResultIndex);
+
+    ListOfShape aUsedTools = theTools;
+    aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end());
+
+    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+                                             aListWithObject,
+                                             aUsedTools,
+                                             aMakeShapeList,
+                                             aResShape);
+    setResult(aResultBody, theResultIndex);
+    ++theResultIndex;
+
+    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+    aRBA.resultBody = aResultBody;
+    aRBA.baseShape = theObject;
+    aRBA.makeShape = aMakeShapeList;
+    theResultBaseAlgoList.push_back(aRBA);
+    theResultShapesList.push_back(aResShape);
+  }
+  return true;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_Boolean::processCompsolid(
+    const GeomAlgoAPI_Tools::BOPType theBooleanType,
+    const ObjectHierarchy& theCompsolidHierarchy,
+    const GeomShapePtr& theCompsolid,
+    const ListOfShape& theTools,
+    const ListOfShape& thePlanes,
+    int& theResultIndex,
+    std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+    ListOfShape& theResultShapesList)
+{
+  ListOfShape aUsedInOperationSolids;
+  ListOfShape aNotUsedSolids;
+  theCompsolidHierarchy.SplitCompound(theCompsolid, aUsedInOperationSolids, aNotUsedSolids);
+
+  std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+
+  std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+      GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0);
+
+  // Resize planes.
+  ListOfShape aToolsWithPlanes = theTools;
+  for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt)
+  {
+    GeomShapePtr aPlane = *anIt;
+    GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
+    std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
+      new GeomAlgoAPI_MakeShapeCustom);
+    aMkShCustom->addModified(aPlane, aTool);
+    aMakeShapeList->appendAlgo(aMkShCustom);
+    aToolsWithPlanes.push_back(aTool);
+  }
+
+  std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
+  if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION)
+    aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes));
+  else
+    aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
+                                            aToolsWithPlanes,
+                                            theBooleanType));
+
+  // Checking that the algorithm worked properly.
+  std::string anError;
+  if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
+    setError(anError);
+    return false;
+  }
+
+  aMakeShapeList->appendAlgo(aBoolAlgo);
+  GeomShapePtr aResultShape = aBoolAlgo->shape();
+
+  // Add result to not used solids from compsolid.
+  if (!aNotUsedSolids.empty()) {
+    ListOfShape aShapesToAdd = aNotUsedSolids;
+    aShapesToAdd.push_back(aBoolAlgo->shape());
+    std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
+        new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
+    if (!aFillerAlgo->isDone()) {
+      std::string aFeatureError = "Error: PaveFiller algorithm failed.";
+      setError(aFeatureError);
+      return false;
+    }
+
+    aMakeShapeList->appendAlgo(aFillerAlgo);
+    aResultShape = aFillerAlgo->shape();
+  }
+
+  GeomAPI_ShapeIterator aShapeIt(aResultShape);
+  if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX)
+  {
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+        document()->createBody(data(), theResultIndex);
+
+    ListOfShape aCompSolidList;
+    aCompSolidList.push_back(theCompsolid);
+
+    ListOfShape aUsedTools = theTools;
+    aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end());
+
+    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+                                             aCompSolidList,
+                                             aUsedTools,
+                                             aMakeShapeList,
+                                             aResultShape);
+    setResult(aResultBody, theResultIndex);
+    ++theResultIndex;
+
+    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+    aRBA.resultBody = aResultBody;
+    aRBA.baseShape = theCompsolid;
+    aRBA.makeShape = aMakeShapeList;
+    theResultBaseAlgoList.push_back(aRBA);
+    theResultShapesList.push_back(aResultShape);
+  }
+  return true;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_Boolean::processCompound(
+    const GeomAlgoAPI_Tools::BOPType theBooleanType,
+    const ObjectHierarchy& theCompoundHierarchy,
+    const GeomShapePtr& theCompound,
+    const ListOfShape& theTools,
+    int& theResultIndex,
+    std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+    ListOfShape& theResultShapesList)
+{
+  ListOfShape aUsedInOperationShapes;
+  ListOfShape aNotUsedShapes;
+  theCompoundHierarchy.SplitCompound(theCompound, aUsedInOperationShapes, aNotUsedShapes);
+
+  std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+  std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(
+      new GeomAlgoAPI_Boolean(aUsedInOperationShapes,
+                              theTools,
+                              theBooleanType));
+
+  // Checking that the algorithm worked properly.
+  std::string anError;
+  if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
+    setError(anError);
+    return false;
+  }
+
+  aMakeShapeList->appendAlgo(aBoolAlgo);
+  GeomShapePtr aResultShape = aBoolAlgo->shape();
+
+  // Add result to not used shape from compound.
+  if (!aNotUsedShapes.empty()) {
+    ListOfShape aShapesForResult = aNotUsedShapes;
+    if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+      for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) {
+        aShapesForResult.push_back(aResultIt.current());
+      }
+    }
+    else {
+      aShapesForResult.push_back(aResultShape);
+    }
+
+    if (aShapesForResult.size() == 1) {
+      aResultShape = aShapesForResult.front();
+    }
+    else {
+      aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult);
+    }
+  }
+
+  GeomAPI_ShapeIterator aShapeIt(aResultShape);
+  if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) {
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+        document()->createBody(data(), theResultIndex);
+
+    ListOfShape aCompoundList;
+    aCompoundList.push_back(theCompound);
+    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+                                             aCompoundList,
+                                             theTools,
+                                             aMakeShapeList,
+                                             aResultShape);
+    setResult(aResultBody, theResultIndex);
+    ++theResultIndex;
+
+    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+    aRBA.resultBody = aResultBody;
+    aRBA.baseShape = theCompound;
+    aRBA.makeShape = aMakeShapeList;
+    theResultBaseAlgoList.push_back(aRBA);
+    theResultShapesList.push_back(aResultShape);
+  }
+  return true;
+}
+
+//=================================================================================================
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::AddObject(const GeomShapePtr& theObject)
+{
+  myObjects.push_back(theObject);
+}
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::AddParent(const GeomShapePtr& theShape,
+                                                        const GeomShapePtr& theParent)
+{
+  myParent[theShape] = theParent;
+  mySubshapes[theParent].push_back(theShape);
+}
+
+GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Parent(const GeomShapePtr& theShape,
+                                                             bool theMarkProcessed)
+{
+  MapShapeToParent::const_iterator aFound = myParent.find(theShape);
+  GeomShapePtr aParent;
+  if (aFound != myParent.end()) {
+    aParent = aFound->second;
+    if (theMarkProcessed) {
+      // mark the parent and all its subs as processed by Boolean algorithm
+      myProcessedObjects.insert(aParent);
+      const ListOfShape& aSubs = mySubshapes[aParent];
+      for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt)
+        myProcessedObjects.insert(*anIt);
+    }
+  }
+  return aParent;
+}
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape,
+                                                            ListOfShape& theUsed,
+                                                            ListOfShape& theNotUsed) const
+{
+  theUsed.clear();
+  theNotUsed.clear();
+
+  const ListOfShape& aSubs = mySubshapes.find(theCompShape)->second;
+  SetOfShape aSubsSet;
+  aSubsSet.insert(aSubs.begin(), aSubs.end());
+
+  for (GeomAPI_ShapeExplorer anExp(theCompShape, GeomAPI_Shape::SOLID);
+       anExp.more(); anExp.next()) {
+    GeomShapePtr aCurrent = anExp.current();
+    if (aSubsSet.find(aCurrent) == aSubsSet.end())
+      theNotUsed.push_back(aCurrent);
+    else
+      theUsed.push_back(aCurrent);
+  }
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::IsEmpty() const
+{
+  return myObjects.empty();
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::Begin()
+{
+  return Iterator(this);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::End()
+{
+  return Iterator(this, false);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::Iterator(
+    FeaturesPlugin_Boolean::ObjectHierarchy* theHierarchy, bool isBegin)
+  : myHierarchy(theHierarchy)
+{
+  if (isBegin) {
+    myObject = myHierarchy->myObjects.begin();
+    SkipAlreadyProcessed();
+  } else
+    myObject = myHierarchy->myObjects.end();
+}
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::SkipAlreadyProcessed()
+{
+  while (myObject != myHierarchy->myObjects.end() &&
+         myHierarchy->myProcessedObjects.find(*myObject) != myHierarchy->myProcessedObjects.end())
+    ++myObject;
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator==(const Iterator& theOther) const
+{
+  return myObject == theOther.myObject;
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator!=(const Iterator& theOther) const
+{
+  return !operator==(theOther);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator&
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++()
+{
+  ++myObject;
+  SkipAlreadyProcessed();
+  return *this;
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++(int)
+{
+  Iterator aCurrent;
+  aCurrent.myHierarchy = myHierarchy;
+  aCurrent.myObject = myObject;
+
+  // increase iterator
+  operator++();
+
+  return aCurrent;
+}
+
+GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator*() const
+{
+  myHierarchy->myProcessedObjects.insert(*myObject);
+  return *myObject;
+}
index 38c8a57ee2cf570b07bd79d4aeff2a4e38dc9b52..63185b17220ec5436653a7de227891d2cb8cb8cf 100644 (file)
 #define FeaturesPlugin_Boolean_H_
 
 #include "FeaturesPlugin.h"
+#include "FeaturesPlugin_Tools.h"
 
 #include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_Tools.h>
 
 #include <ModelAPI_Feature.h>
 
+class ModelAPI_Result;
+
 /// \class FeaturesPlugin_Boolean
 /// \ingroup Plugins
 /// \brief Feature for applying of Boolean operations on Solids.
@@ -73,6 +77,109 @@ protected:
                     const std::shared_ptr<GeomAPI_Shape> theResultShape,
                     const GeomMakeShapePtr& theMakeShape);
 
+
+  /// Auxiliary class to store hierarchy of Boolean operation objects/tools
+  /// and their parent shapes (compounds or compsolids)
+  class ObjectHierarchy {
+    typedef std::map<GeomShapePtr, ListOfShape, GeomAPI_Shape::Comparator>  MapShapeToSubshapes;
+    typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToParent;
+    typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShape;
+
+    ListOfShape myObjects;
+    MapShapeToParent myParent;
+    MapShapeToSubshapes mySubshapes;
+
+    SetOfShape myProcessedObjects;
+
+  public:
+    /// Add object of Boolean opration
+    void AddObject(const GeomShapePtr& theObject);
+
+    /// Maps shape and its parent
+    void AddParent(const GeomShapePtr& theShape, const GeomShapePtr& theParent);
+
+    /// Return parent shape for the given, or empty if it is a high-level shape.
+    /// By default, the parent and all its subshapes are marked as processed for further skip.
+    GeomShapePtr Parent(const GeomShapePtr& theShape, bool theMarkProcessed = true);
+
+    /// Split compound/compsolid shape for subshapes selected for Boolean operation and the other.
+    void SplitCompound(const GeomShapePtr& theCompShape,
+                       ListOfShape& theUsed,
+                       ListOfShape& theNotUsed) const;
+
+    /// Return \c true if there is no object in hierarchy
+    bool IsEmpty() const;
+
+    /// Return list of objects
+    const ListOfShape& Objects() const { return myObjects; }
+
+  public:
+    class Iterator {
+      friend class ObjectHierarchy;
+
+      ObjectHierarchy* myHierarchy;
+      ListOfShape::iterator myObject;
+
+      Iterator() {}
+      Iterator(ObjectHierarchy* theHierarchy, bool isBegin = true);
+
+      void SkipAlreadyProcessed();
+
+    public:
+      bool operator==(const Iterator&) const;
+      bool operator!=(const Iterator&) const;
+
+      Iterator& operator++();
+      Iterator  operator++(int);
+
+      GeomShapePtr operator*() const;
+    };
+
+    Iterator Begin();
+    Iterator End();
+  };
+
+  /// Process SelectionList attribute and fill the objects hierarchy.
+  bool processAttribute(const std::string& theAttributeName,
+                        ObjectHierarchy& theObjects,
+                        ListOfShape& thePlanesList);
+
+  /// Perform Boolean operation of the object with the tools
+  /// \return \c false if something went wrong
+  bool processObject(const GeomAlgoAPI_Tools::BOPType theBooleanType,
+                     const GeomShapePtr& theObject,
+                     const ListOfShape& theTools,
+                     const ListOfShape& thePlanes,
+                     int& theResultIndex,
+                     std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+                     ListOfShape& theResultShapesList);
+
+  /// Perform Boolean operation of the Compsolid with the tools
+  /// \return \c false if something went wrong
+  bool processCompsolid(const GeomAlgoAPI_Tools::BOPType theBooleanType,
+                        const ObjectHierarchy& theCompsolidHierarchy,
+                        const GeomShapePtr& theCompsolid,
+                        const ListOfShape& theTools,
+                        const ListOfShape& thePlanes,
+                        int& theResultIndex,
+                        std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+                        ListOfShape& theResultShapesList);
+
+  /// Perform Boolean operation of the Compound with the tools
+  /// \return \c false if something went wrong
+  bool processCompound(const GeomAlgoAPI_Tools::BOPType theBooleanType,
+                       const ObjectHierarchy& theCompoundHierarchy,
+                       const GeomShapePtr& theCompound,
+                       const ListOfShape& theTools,
+                       int& theResultIndex,
+                       std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
+                       ListOfShape& theResultShapesList);
+
+private:
+  void parentForShape(const GeomShapePtr& theShape,
+                      const std::shared_ptr<ModelAPI_Result>& theContext,
+                      ObjectHierarchy& theShapesHierarchy);
+
 private:
   OperationType myOperationType;
 };
index eb23d0bab2fe563e12263c35936482224cba2bec..af2d556f18afdd568e4375bac1c22b7cf6850ffe 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "FeaturesPlugin_BooleanCommon.h"
 
-#include "FeaturesPlugin_Tools.h"
-
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
@@ -56,9 +54,8 @@ void FeaturesPlugin_BooleanCommon::initAttributes()
 //==================================================================================================
 void FeaturesPlugin_BooleanCommon::execute()
 {
-  ListOfShape anObjects, aTools, aPlanes;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompoundObjects;
+  ListOfShape aPlanes;
+  ObjectHierarchy anObjects, aTools;
 
   bool isSimpleMode = false;
 
@@ -69,59 +66,17 @@ void FeaturesPlugin_BooleanCommon::execute()
   }
 
   // Getting objects.
-  AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
-  for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
-    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
-    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
-    if (!anObject.get()) {
-      return;
-    }
-    ResultPtr aContext = anObjectAttr->context();
-    ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
-    if (!isSimpleMode
-        && aResCompSolidPtr.get())
-    {
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
-      GeomAPI_Shape::ShapeType aShapeType = aResCompSolidPtr->shape()->shapeType();
-      std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>& aMap =
-        aShapeType == GeomAPI_Shape::COMPSOLID ? aCompSolidsObjects : aCompoundObjects;
-
-      std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-        anIt = aMap.begin();
-      for (; anIt != aMap.end(); anIt++) {
-        if (anIt->first->isEqual(aContextShape)) {
-          aMap[anIt->first].push_back(anObject);
-          break;
-        }
-      }
-      if (anIt == aMap.end()) {
-        aMap[aContextShape].push_back(anObject);
-      }
-
-    }
-    else {
-      anObjects.push_back(anObject);
-    }
-  }
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
+    return;
+  // Planes are not supported as objects of COMMON operation
+  aPlanes.clear();
 
   // Getting tools.
-  if (!isSimpleMode) {
-    AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
-    for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
-      AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
-      GeomShapePtr aTool = aToolAttr->value();
-      if (!aTool.get()) {
-        // It could be a construction plane.
-        ResultPtr aContext = aToolAttr->context();
-        aPlanes.push_back(aToolAttr->context()->shape());
-      } else {
-        aTools.push_back(aTool);
-      }
-    }
-  }
+  if (!isSimpleMode &&
+      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
+    return;
 
-  if ((anObjects.empty() && aCompSolidsObjects.empty() && aCompoundObjects.empty())
-      || (!isSimpleMode && aTools.empty() && aPlanes.empty())) {
+  if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) {
     std::string aFeatureError = "Error: Not enough objects for boolean operation.";
     setError(aFeatureError);
     return;
@@ -133,15 +88,14 @@ void FeaturesPlugin_BooleanCommon::execute()
   std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
   ListOfShape aResultShapesList;
 
-  if (isSimpleMode)
-  {
-    ListOfShape::iterator anObjectsIt = anObjects.begin();
+  if (isSimpleMode) {
+    ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
     GeomShapePtr aShape = *anObjectsIt;
-    for (++anObjectsIt; anObjectsIt != anObjects.end(); ++anObjectsIt) {
+    for (++anObjectsIt; anObjectsIt != anObjects.End(); ++anObjectsIt) {
       std::shared_ptr<GeomAlgoAPI_Boolean> aCommonAlgo(
         new GeomAlgoAPI_Boolean(aShape,
                                 *anObjectsIt,
-                                GeomAlgoAPI_Boolean::BOOL_COMMON));
+                                GeomAlgoAPI_Tools::BOOL_COMMON));
 
       if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) {
         setError(anError);
@@ -157,18 +111,19 @@ void FeaturesPlugin_BooleanCommon::execute()
       std::shared_ptr<ModelAPI_ResultBody> aResultBody =
         document()->createBody(data(), aResultIndex);
 
-      ListOfShape anEmptyTools;
+      ListOfShape anObjectList = anObjects.Objects();
+      ListOfShape aToolsList;
       FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               anObjects,
-                                               anEmptyTools,
+                                               anObjectList,
+                                               aToolsList,
                                                aMakeShapeList,
                                                aShape);
-      GeomShapePtr aBaseShape = anObjects.front();
-      anObjects.pop_front();
+      GeomShapePtr aBaseShape = anObjectList.front();
+      anObjectList.pop_front();
       setResult(aResultBody, aResultIndex);
       aResultIndex++;
 
-      aTools = anObjects;
+      aToolsList = anObjectList;
       FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
       aRBA.resultBody = aResultBody;
       aRBA.baseShape = aBaseShape;
@@ -177,245 +132,43 @@ void FeaturesPlugin_BooleanCommon::execute()
       aResultShapesList.push_back(aShape);
     }
   } else {
-    for (ListOfShape::iterator anObjectsIt = anObjects.begin();
-         anObjectsIt != anObjects.end();
+    bool isOk = true;
+    for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
+         anObjectsIt != anObjects.End() && isOk;
          ++anObjectsIt)
     {
-      std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
-      ListOfShape aListWithObject;
-      aListWithObject.push_back(anObject);
-      std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-      std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
-      GeomShapePtr aResShape;
-
-      std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
-        GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0);
-
-      // Resize planes.
-      ListOfShape aToolsWithPlanes = aTools;
-      for (ListOfShape::const_iterator anIt = aPlanes.cbegin();
-           anIt != aPlanes.cend();
-           ++anIt) {
-        GeomShapePtr aPlane = *anIt;
-        GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
-        std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
-          new GeomAlgoAPI_MakeShapeCustom);
-        aMkShCustom->addModified(aPlane, aTool);
-        aMakeShapeList->appendAlgo(aMkShCustom);
-        aToolsWithPlanes.push_back(aTool);
-      }
-
-      aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject,
-        aToolsWithPlanes,
-        GeomAlgoAPI_Boolean::BOOL_COMMON));
-      aResShape = aBoolAlgo->shape();
-
-      // Checking that the algorithm worked properly.
-      if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
-        setError(anError);
-        return;
-      }
-
-      aMakeShapeList->appendAlgo(aBoolAlgo);
-
-      GeomAPI_ShapeIterator aShapeIt(aResShape);
-      if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) {
-        std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-          document()->createBody(data(), aResultIndex);
-        ListOfShape anObjectList;
-        anObjectList.push_back(anObject);
-        FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 anObjectList,
-                                                 aTools,
-                                                 aMakeShapeList,
-                                                 aResShape);
-        setResult(aResultBody, aResultIndex);
-        aResultIndex++;
-
-        FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-        aRBA.resultBody = aResultBody;
-        aRBA.baseShape = anObject;
-        aRBA.makeShape = aMakeShapeList;
-        aResultBaseAlgoList.push_back(aRBA);
-        aResultShapesList.push_back(aResShape);
-      }
-    }
-
-    // Compsolids handling
-    for (std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-      anIt = aCompSolidsObjects.begin();
-      anIt != aCompSolidsObjects.end();
-      ++anIt)
-    {
-      std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
-      ListOfShape& aUsedInOperationSolids = anIt->second;
-
-      // Collecting solids from compsolids which will not be modified in boolean operation.
-      ListOfShape aNotUsedSolids;
-      for (GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID);
-        anExp.more();
-        anExp.next())
-      {
-        std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
-        ListOfShape::iterator aUsedIt = aUsedInOperationSolids.begin();
-        for (; aUsedIt != aUsedInOperationSolids.end(); aUsedIt++) {
-          if (aSolidInCompSolid->isEqual(*aUsedIt)) {
-            break;
-          }
+      GeomShapePtr anObject = *anObjectsIt;
+      GeomShapePtr aParent = anObjects.Parent(anObject);
+
+      if (aParent) {
+        GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType();
+        if (aShapeType == GeomAPI_Shape::COMPOUND) {
+          // Compound handling
+          isOk = processCompound(GeomAlgoAPI_Tools::BOOL_COMMON,
+                                 anObjects, aParent, aTools.Objects(),
+                                 aResultIndex, aResultBaseAlgoList, aResultShapesList);
         }
-        if (aUsedIt == aUsedInOperationSolids.end()) {
-          aNotUsedSolids.push_back(aSolidInCompSolid);
+        else if (aShapeType == GeomAPI_Shape::COMPSOLID) {
+          // Compsolid handling
+          isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_COMMON,
+                                  anObjects, aParent, aTools.Objects(), ListOfShape(),
+                                  aResultIndex, aResultBaseAlgoList, aResultShapesList);
         }
-      }
-
-      std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-      std::shared_ptr<GeomAlgoAPI_Boolean> aCommonAlgo(
-        new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
-          aTools,
-          GeomAlgoAPI_Boolean::BOOL_COMMON));
-
-      // Checking that the algorithm worked properly.
-      if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) {
-        setError(anError);
-        return;
-      }
-
-      aMakeShapeList->appendAlgo(aCommonAlgo);
-      GeomShapePtr aResultShape = aCommonAlgo->shape();
-
-      // Add result to not used solids from compsolid.
-      if (!aNotUsedSolids.empty()) {
-        ListOfShape aShapesToAdd = aNotUsedSolids;
-        aShapesToAdd.push_back(aCommonAlgo->shape());
-        std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
-          new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
-        if (!aFillerAlgo->isDone()) {
-          std::string aFeatureError = "Error: PaveFiller algorithm failed.";
-          setError(aFeatureError);
-          return;
-        }
-
-        aMakeShapeList->appendAlgo(aFillerAlgo);
-        aResultShape = aFillerAlgo->shape();
-      }
-
-      GeomAPI_ShapeIterator aShapeIt(aResultShape);
-      if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX)
-      {
-        std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-          document()->createBody(data(), aResultIndex);
-
-        ListOfShape aCompSolidList;
-        aCompSolidList.push_back(aCompSolid);
-        FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 aCompSolidList,
-                                                 aTools,
-                                                 aMakeShapeList,
-                                                 aResultShape);
-        setResult(aResultBody, aResultIndex);
-        aResultIndex++;
-
-        FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-        aRBA.resultBody = aResultBody;
-        aRBA.baseShape = aCompSolid;
-        aRBA.makeShape = aMakeShapeList;
-        aResultBaseAlgoList.push_back(aRBA);
-        aResultShapesList.push_back(aResultShape);
-      }
-    }
-
-    // Compounds handling
-    for (std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-      anIt = aCompoundObjects.begin();
-      anIt != aCompoundObjects.end();
-      ++anIt)
-    {
-      std::shared_ptr<GeomAPI_Shape> aCompound = anIt->first;
-      ListOfShape& aUsedInOperationShapes = anIt->second;
-
-      // Collecting shapes from compound which will not be modified in boolean operation.
-      ListOfShape aNotUsedShapes;
-      for (GeomAPI_ShapeIterator aCompIt(aCompound);
-        aCompIt.more();
-        aCompIt.next())
-      {
-        std::shared_ptr<GeomAPI_Shape> aShapeInCompound = aCompIt.current();
-        ListOfShape::iterator aUsedIt = aUsedInOperationShapes.begin();
-        for (; aUsedIt != aUsedInOperationShapes.end(); aUsedIt++) {
-          if (aShapeInCompound->isEqual(*aUsedIt)) {
-            break;
-          }
-        }
-        if (aUsedIt == aUsedInOperationShapes.end()) {
-          aNotUsedShapes.push_back(aShapeInCompound);
-        }
-      }
-
-      std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-      std::shared_ptr<GeomAlgoAPI_Boolean> aCommonAlgo(
-        new GeomAlgoAPI_Boolean(aUsedInOperationShapes,
-          aTools,
-          GeomAlgoAPI_Boolean::BOOL_COMMON));
-
-      // Checking that the algorithm worked properly.
-      if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) {
-        setError(anError);
-        return;
-      }
-
-      aMakeShapeList->appendAlgo(aCommonAlgo);
-      GeomShapePtr aResultShape = aCommonAlgo->shape();
-
-      // Add result to not used shape from compound.
-      if (!aNotUsedShapes.empty()) {
-        ListOfShape aShapesForResult = aNotUsedShapes;
-        if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
-          for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) {
-            aShapesForResult.push_back(aResultIt.current());
-          }
-        }
-        else {
-          aShapesForResult.push_back(aResultShape);
-        }
-
-        if (aShapesForResult.size() == 1) {
-          aResultShape = aShapesForResult.front();
-        }
-        else {
-          aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult);
-        }
-      }
-
-      GeomAPI_ShapeIterator aShapeIt(aResultShape);
-      if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) {
-        std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-          document()->createBody(data(), aResultIndex);
-
-        ListOfShape aCompoundList;
-        aCompoundList.push_back(aCompound);
-        FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                                 aCompoundList,
-                                                 aTools,
-                                                 aMakeShapeList,
-                                                 aResultShape);
-        setResult(aResultBody, aResultIndex);
-        aResultIndex++;
-
-        FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-        aRBA.resultBody = aResultBody;
-        aRBA.baseShape = aCompound;
-        aRBA.makeShape = aMakeShapeList;
-        aResultBaseAlgoList.push_back(aRBA);
-        aResultShapesList.push_back(aResultShape);
+      } else {
+        // process object as is
+        isOk = processObject(GeomAlgoAPI_Tools::BOOL_COMMON,
+                             anObject, aTools.Objects(), aPlanes,
+                             aResultIndex, aResultBaseAlgoList, aResultShapesList);
       }
     }
-
   }
 
   // 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, aTools, aResultShapesCompound);
+  FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
+                                          aTools.Objects(),
+                                          aResultShapesCompound);
 
   // remove the rest results if there were produced in the previous pass
   removeResults(aResultIndex);
index 04b9020ba0858e837393e6d29b78b4487b60a4ad..be93d26ec8233e3e33dc7076135108b13e9ecbf1 100644 (file)
@@ -44,59 +44,17 @@ FeaturesPlugin_BooleanCut::FeaturesPlugin_BooleanCut()
 //==================================================================================================
 void FeaturesPlugin_BooleanCut::execute()
 {
-  ListOfShape anObjects, aTools;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompoundObjects;
+  ObjectHierarchy anObjects, aTools;
+  ListOfShape aPlanes;
 
-  // Getting objects.
-  AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
-  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
-    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
-    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
-    if(!anObject.get()) {
-      return;
-    }
-    ResultPtr aContext = anObjectAttr->context();
-    ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
-    if (aResCompSolidPtr.get())
-    {
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
-      GeomAPI_Shape::ShapeType aShapeType = aResCompSolidPtr->shape()->shapeType();
-      std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>& aMap =
-        aShapeType == GeomAPI_Shape::COMPSOLID ? aCompSolidsObjects : aCompoundObjects;
-
-        std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-          anIt = aMap.begin();
-        for (; anIt != aMap.end(); anIt++) {
-          if (anIt->first->isEqual(aContextShape)) {
-            aMap[anIt->first].push_back(anObject);
-            break;
-          }
-        }
-        if (anIt == aMap.end()) {
-          aMap[aContextShape].push_back(anObject);
-        }
-
-    } else {
-      anObjects.push_back(anObject);
-    }
-  }
-
-  // Getting tools.
-  AttributeSelectionListPtr aToolsSelList = selectionList(TOOL_LIST_ID());
-  for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
-    AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
-    GeomShapePtr aTool = aToolAttr->value();
-    if(!aTool.get()) {
-      return;
-    }
-    aTools.push_back(aTool);
-  }
+  // Getting objects and tools
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes) ||
+      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
+    return;
 
   int aResultIndex = 0;
 
-  if((anObjects.empty() && aCompSolidsObjects.empty() && aCompoundObjects.empty())
-     || aTools.empty()) {
+  if(anObjects.IsEmpty() || aTools.IsEmpty()) {
     std::string aFeatureError = "Error: Not enough objects for boolean operation.";
     setError(aFeatureError);
     return;
@@ -107,221 +65,41 @@ void FeaturesPlugin_BooleanCut::execute()
   std::string anError;
 
   // For solids cut each object with all tools.
-  for(ListOfShape::iterator anObjectsIt = anObjects.begin();
-      anObjectsIt != anObjects.end();
-      ++anObjectsIt) {
-    std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
-    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-    std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
-      new GeomAlgoAPI_Boolean(anObject,
-                              aTools,
-                              GeomAlgoAPI_Boolean::BOOL_CUT));
-    GeomShapePtr aResShape = aCutAlgo->shape();
-
-    // Checking that the algorithm worked properly.
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
-
-    aMakeShapeList->appendAlgo(aCutAlgo);
-
-    GeomAPI_ShapeIterator aShapeIt(aResShape);
-    if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX)
-    {
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-        document()->createBody(data(), aResultIndex);
-
-      ListOfShape anObjectList;
-      anObjectList.push_back(anObject);
-      FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               anObjectList,
-                                               aTools,
-                                               aMakeShapeList,
-                                               aResShape);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
-
-      FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-      aRBA.resultBody = aResultBody;
-      aRBA.baseShape = anObject;
-      aRBA.makeShape = aMakeShapeList;
-      aResultBaseAlgoList.push_back(aRBA);
-      aResultShapesList.push_back(aResShape);
-    }
-  }
-
-  // Compsolids handling
-  for (std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-       anIt = aCompSolidsObjects.begin();
-       anIt != aCompSolidsObjects.end();
-       ++anIt)
-  {
-    std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
-    ListOfShape& aUsedInOperationSolids = anIt->second;
-
-    // Collecting solids from compsolids which will not be modified in boolean operation.
-    ListOfShape aNotUsedSolids;
-    for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID);
-        anExp.more();
-        anExp.next())
-    {
-      std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
-      ListOfShape::iterator aUsedIt = aUsedInOperationSolids.begin();
-      for (; aUsedIt != aUsedInOperationSolids.end(); aUsedIt++) {
-        if (aSolidInCompSolid->isEqual(*aUsedIt)) {
-          break;
-        }
-      }
-      if (aUsedIt == aUsedInOperationSolids.end()) {
-        aNotUsedSolids.push_back(aSolidInCompSolid);
-      }
-    }
-
-    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-    std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
-      new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
-                              aTools,
-                              GeomAlgoAPI_Boolean::BOOL_CUT));
-
-    // Checking that the algorithm worked properly.
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
-
-    aMakeShapeList->appendAlgo(aCutAlgo);
-    GeomShapePtr aResultShape = aCutAlgo->shape();
-
-    // Add result to not used solids from compsolid.
-    if(!aNotUsedSolids.empty()) {
-      ListOfShape aShapesToAdd = aNotUsedSolids;
-      aShapesToAdd.push_back(aCutAlgo->shape());
-      std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
-        new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
-      if(!aFillerAlgo->isDone()) {
-        std::string aFeatureError = "Error: PaveFiller algorithm failed.";
-        setError(aFeatureError);
-        return;
-      }
-
-      aMakeShapeList->appendAlgo(aFillerAlgo);
-      aResultShape = aFillerAlgo->shape();
-    }
-
-    GeomAPI_ShapeIterator aShapeIt(aResultShape);
-    if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX)
-    {
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-        document()->createBody(data(), aResultIndex);
-
-      ListOfShape anObjectList;
-      anObjectList.push_back(aCompSolid);
-      FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               anObjectList,
-                                               aTools,
-                                               aMakeShapeList,
-                                               aResultShape);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
-
-      FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-      aRBA.resultBody = aResultBody;
-      aRBA.baseShape = aCompSolid;
-      aRBA.makeShape = aMakeShapeList;
-      aResultBaseAlgoList.push_back(aRBA);
-      aResultShapesList.push_back(aResultShape);
-    }
-  }
-
-  // Compounds handling
-  for (std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-       anIt = aCompoundObjects.begin();
-       anIt != aCompoundObjects.end();
-       ++anIt)
-  {
-    std::shared_ptr<GeomAPI_Shape> aCompound = anIt->first;
-    ListOfShape& aUsedInOperationShapes = anIt->second;
-
-    // Collecting shapes from compound which will not be modified in boolean operation.
-    ListOfShape aNotUsedShapes;
-    for (GeomAPI_ShapeIterator aCompIt(aCompound);
-         aCompIt.more();
-         aCompIt.next())
-    {
-      std::shared_ptr<GeomAPI_Shape> aShapeInCompound = aCompIt.current();
-      ListOfShape::iterator aUsedIt = aUsedInOperationShapes.begin();
-      for (; aUsedIt != aUsedInOperationShapes.end(); aUsedIt++) {
-        if (aShapeInCompound->isEqual(*aUsedIt)) {
-          break;
-        }
-      }
-      if (aUsedIt == aUsedInOperationShapes.end()) {
-        aNotUsedShapes.push_back(aShapeInCompound);
+  bool isOk = true;
+  for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
+       anObjectsIt != anObjects.End() && isOk;
+       ++anObjectsIt) {
+    GeomShapePtr anObject = *anObjectsIt;
+    GeomShapePtr aParent = anObjects.Parent(anObject);
+
+    if (aParent) {
+      GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType();
+      if (aShapeType == GeomAPI_Shape::COMPOUND) {
+        // Compound handling
+        isOk = processCompound(GeomAlgoAPI_Tools::BOOL_CUT,
+                               anObjects, aParent, aTools.Objects(),
+                               aResultIndex, aResultBaseAlgoList, aResultShapesList);
       }
-    }
-
-    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-    std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
-      new GeomAlgoAPI_Boolean(aUsedInOperationShapes,
-                              aTools,
-                              GeomAlgoAPI_Boolean::BOOL_CUT));
-
-    // Checking that the algorithm worked properly.
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
-
-    aMakeShapeList->appendAlgo(aCutAlgo);
-    GeomShapePtr aResultShape = aCutAlgo->shape();
-
-    // Add result to not used shape from compound.
-    if (!aNotUsedShapes.empty()) {
-      ListOfShape aShapesForResult = aNotUsedShapes;
-      if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
-        for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) {
-          aShapesForResult.push_back(aResultIt.current());
-        }
-      } else {
-        aShapesForResult.push_back(aResultShape);
+      else if (aShapeType == GeomAPI_Shape::COMPSOLID) {
+        // Compsolid handling
+        isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_CUT,
+                                anObjects, aParent, aTools.Objects(), ListOfShape(),
+                                aResultIndex, aResultBaseAlgoList, aResultShapesList);
       }
-
-      if (aShapesForResult.size() == 1) {
-        aResultShape = aShapesForResult.front();
-      } else {
-        aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult);
-      }
-    }
-
-    GeomAPI_ShapeIterator aShapeIt(aResultShape);
-    if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) {
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-        document()->createBody(data(), aResultIndex);
-
-      ListOfShape anObjectList;
-      anObjectList.push_back(aCompound);
-      FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
-                                               anObjectList,
-                                               aTools,
-                                               aMakeShapeList,
-                                               aResultShape);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
-
-      FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-      aRBA.resultBody = aResultBody;
-      aRBA.baseShape = aCompound;
-      aRBA.makeShape = aMakeShapeList;
-      aResultBaseAlgoList.push_back(aRBA);
-      aResultShapesList.push_back(aResultShape);
+    } else {
+      // process object as is
+      isOk = processObject(GeomAlgoAPI_Tools::BOOL_CUT,
+                           anObject, aTools.Objects(), aPlanes,
+                           aResultIndex, aResultBaseAlgoList, aResultShapesList);
     }
   }
 
   // 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, aTools, aResultShapesCompound);
+  FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
+                                          aTools.Objects(),
+                                          aResultShapesCompound);
 
   // remove the rest results if there were produced in the previous pass
   removeResults(aResultIndex);
index 92d513e5c521252197ea3dedfccc1ab0418426a3..a907823addc16bb4173a6e1982dfd4722f82f9e4 100644 (file)
@@ -50,58 +50,22 @@ FeaturesPlugin_BooleanFill::FeaturesPlugin_BooleanFill()
 void FeaturesPlugin_BooleanFill::execute()
 {
   std::string anError;
-  ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes;
-  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
+  ObjectHierarchy anObjects, aTools;
+  ListOfShape aPlanes;
 
   // Getting objects.
-  AttributeSelectionListPtr anObjectsSelList =
-    selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
-  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
-    AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
-    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
-    if(!anObject.get()) {
-      return;
-    }
-    ResultPtr aContext = anObjectAttr->context();
-    ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
-    if(aResCompSolidPtr.get()
-        && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) {
-      std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
-      std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-        anIt = aCompSolidsObjects.begin();
-      for(; anIt != aCompSolidsObjects.end(); anIt++) {
-        if(anIt->first->isEqual(aContextShape)) {
-          aCompSolidsObjects[anIt->first].push_back(anObject);
-          break;
-        }
-      }
-      if(anIt == aCompSolidsObjects.end()) {
-        aCompSolidsObjects[aContextShape].push_back(anObject);
-      }
-    } else {
-      anObjects.push_back(anObject);
-    }
-  }
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
+    return;
+  // Planes are not supported as objects of FILL operation
+  aPlanes.clear();
 
   // Getting tools.
-  AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
-  for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
-    AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex);
-    GeomShapePtr aTool = aToolAttr->value();
-    if(!aTool.get()) {
-      // It could be a construction plane.
-      ResultPtr aContext = aToolAttr->context();
-      aPlanes.push_back(aToolAttr->context()->shape());
-    }
-    else {
-      aTools.push_back(aTool);
-    }
-  }
+  if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
+    return;
 
   int aResultIndex = 0;
 
-  if ((anObjects.empty() && aCompSolidsObjects.empty())
-      || (aTools.empty() && aPlanes.empty())) {
+  if (anObjects.IsEmpty() || (aTools.IsEmpty() && aPlanes.empty())) {
     std::string aFeatureError = "Error: Not enough objects for boolean operation.";
     setError(aFeatureError);
     return;
@@ -111,178 +75,34 @@ void FeaturesPlugin_BooleanFill::execute()
   ListOfShape aResultShapesList;
 
   // For solids cut each object with all tools.
-  for(ListOfShape::iterator
-      anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
-    std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
-    ListOfShape aListWithObject;
-    aListWithObject.push_back(anObject);
-    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-    std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
-    GeomShapePtr aResShape;
-
-    std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
-        GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0);
-
-    // Resize planes.
-    ListOfShape aToolsWithPlanes = aTools;
-    for(ListOfShape::const_iterator anIt = aPlanes.cbegin();
-                                    anIt != aPlanes.cend();
-                                    ++anIt)
-    {
-      GeomShapePtr aPlane = *anIt;
-      GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
-      std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
-        new GeomAlgoAPI_MakeShapeCustom);
-      aMkShCustom->addModified(aPlane, aTool);
-      aMakeShapeList->appendAlgo(aMkShCustom);
-      aToolsWithPlanes.push_back(aTool);
-    }
-
-    aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes));
-    aResShape = aBoolAlgo->shape();
-    if (aResShape.get() && aResShape->shapeType() == GeomAPI_Shape::COMPOUND) {
-      int aSubResultsNb = 0;
-      GeomAPI_ShapeIterator anIt(aResShape);
-      for(; anIt.more(); anIt.next()) {
-        ++aSubResultsNb;
-      }
-      if(aSubResultsNb == 1) {
-        anIt.init(aResShape);
-        if(anIt.more()) {
-          aResShape = anIt.current();
-        }
-      }
-    }
-
-    // Checking that the algorithm worked properly.
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
-
-    aMakeShapeList->appendAlgo(aBoolAlgo);
-
-    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-        document()->createBody(data(), aResultIndex);
-
-    // tools should be added to the list to fulfill the correct history of modification
-    aListWithObject.insert(aListWithObject.end(), aTools.begin(), aTools.end());
-
-    ListOfShape aUsedTools = aTools;
-    aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
-
-    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aListWithObject, aUsedTools,
-                                             aMakeShapeList, aResShape);
-    setResult(aResultBody, aResultIndex);
-    aResultIndex++;
-
-    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-    aRBA.resultBody = aResultBody;
-    aRBA.baseShape = anObject;
-    aRBA.makeShape = aMakeShapeList;
-    aResultBaseAlgoList.push_back(aRBA);
-    aResultShapesList.push_back(aResShape);
-  }
-
-  // Compsolids handling
-  for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
-      anIt = aCompSolidsObjects.begin();
-      anIt != aCompSolidsObjects.end(); anIt++) {
-    std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
-    ListOfShape& aUsedInOperationSolids = anIt->second;
-
-    // Collecting solids from compsolids which will not be modified in boolean operation.
-    ListOfShape aNotUsedSolids;
-    for(GeomAPI_ShapeExplorer
-        anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
-      std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
-      ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
-      for(; anIt != aUsedInOperationSolids.end(); anIt++) {
-        if(aSolidInCompSolid->isEqual(*anIt)) {
-          break;
-        }
-      }
-      if(anIt == aUsedInOperationSolids.end()) {
-        aNotUsedSolids.push_back(aSolidInCompSolid);
-      }
-    }
-
-    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
-    std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
-
-    std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
-      GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0);
-
-    // Resize planes.
-    ListOfShape aToolsWithPlanes = aTools;
-    for(ListOfShape::const_iterator anIt = aPlanes.cbegin();
-                                    anIt != aPlanes.cend();
-                                    ++anIt)
-    {
-      GeomShapePtr aPlane = *anIt;
-      GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
-      std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(
-        new GeomAlgoAPI_MakeShapeCustom);
-      aMkShCustom->addModified(aPlane, aTool);
-      aMakeShapeList->appendAlgo(aMkShCustom);
-      aToolsWithPlanes.push_back(aTool);
-    }
-
-    aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes));
-
-    // Checking that the algorithm worked properly.
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
-
-    aMakeShapeList->appendAlgo(aBoolAlgo);
-    GeomShapePtr aResultShape = aBoolAlgo->shape();
-
-    // Add result to not used solids from compsolid.
-    if(!aNotUsedSolids.empty()) {
-      ListOfShape aShapesToAdd = aNotUsedSolids;
-      aShapesToAdd.push_back(aBoolAlgo->shape());
-      std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
-        new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
-      if(!aFillerAlgo->isDone()) {
-        std::string aFeatureError = "Error: PaveFiller algorithm failed.";
-        setError(aFeatureError);
-        return;
-      }
-
-      aMakeShapeList->appendAlgo(aFillerAlgo);
-      aResultShape = aFillerAlgo->shape();
+  bool isOk = true;
+  for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
+       anObjectsIt != anObjects.End() && isOk;
+       ++anObjectsIt) {
+    GeomShapePtr anObject = *anObjectsIt;
+    GeomShapePtr aParent = anObjects.Parent(anObject, false);
+
+    if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
+      // get parent once again to mark it and the subs as processed
+      aParent = anObjects.Parent(anObject);
+      // compsolid handling
+      isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_PARTITION,
+                              anObjects, aParent, aTools.Objects(), aPlanes,
+                              aResultIndex, aResultBaseAlgoList, aResultShapesList);
+    } else {
+      // process object as is
+      isOk = processObject(GeomAlgoAPI_Tools::BOOL_PARTITION,
+                           anObject, aTools.Objects(), aPlanes,
+                           aResultIndex, aResultBaseAlgoList, aResultShapesList);
     }
-
-    std::shared_ptr<ModelAPI_ResultBody> aResultBody =
-      document()->createBody(data(), aResultIndex);
-
-    ListOfShape aUsedTools = aTools;
-    aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
-
-    ListOfShape aBaseShapes;
-    aBaseShapes.push_back(aCompSolid);
-    // tools should be added to the list to fulfill the correct history of modification
-    aBaseShapes.insert(aBaseShapes.end(), aTools.begin(), aTools.end());
-
-    FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, aUsedTools,
-                                             aMakeShapeList, aResultShape);
-    setResult(aResultBody, aResultIndex);
-    aResultIndex++;
-
-    FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
-    aRBA.resultBody = aResultBody;
-    aRBA.baseShape = aCompSolid;
-    aRBA.makeShape = aMakeShapeList;
-    aResultBaseAlgoList.push_back(aRBA);
-    aResultShapesList.push_back(aResultShape);
   }
 
   // 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, aTools, aResultShapesCompound);
+  FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
+                                          aTools.Objects(),
+                                          aResultShapesCompound);
 
   // remove the rest results if there were produced in the previous pass
   removeResults(aResultIndex);
index 176e8b6fe9eecbfb5e28d458ed58bc7f1c3aec0a..cd9fae738cf47e3678f111759b6a68d1a292c74a 100644 (file)
@@ -174,7 +174,7 @@ void FeaturesPlugin_BooleanFuse::execute()
   GeomShapePtr aCuttedEdgesAndFaces;
   if (!anEdgesAndFaces.empty()) {
     std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
-      anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT));
+      anOriginalShapes, GeomAlgoAPI_Tools::BOOL_CUT));
     if (aCutAlgo->isDone()) {
       aCuttedEdgesAndFaces = aCutAlgo->shape();
       aMakeShapeList->appendAlgo(aCutAlgo);
@@ -191,7 +191,7 @@ void FeaturesPlugin_BooleanFuse::execute()
       ListOfShape aOneObjectList;
       aOneObjectList.push_back(*anIt);
       std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(
-        new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT));
+        new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Tools::BOOL_CUT));
 
       if (GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
         aSolidsToFuse.push_back(aCutAlgo->shape());
@@ -216,7 +216,7 @@ void FeaturesPlugin_BooleanFuse::execute()
   } else if ((anObjects.size() + aTools.size()) > 1) {
     std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
       aTools,
-      GeomAlgoAPI_Boolean::BOOL_FUSE));
+      GeomAlgoAPI_Tools::BOOL_FUSE));
 
     // Checking that the algorithm worked properly.
     if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFuseAlgo, getKind(), anError)) {
index 9c8bb1e578bffda2db38ab2ccc6990304361f277..c3b8243ae9267babc74c279e7f9102eec1f3641e 100644 (file)
@@ -154,7 +154,7 @@ void FeaturesPlugin_BooleanSmash::execute()
     std::shared_ptr<GeomAlgoAPI_Boolean> anObjectsCutAlgo(
       new GeomAlgoAPI_Boolean(aShapesToSmash,
                               aShapesToAdd,
-                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                              GeomAlgoAPI_Tools::BOOL_CUT));
 
     if (GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) {
       aShapesToSmash.clear();
@@ -166,7 +166,7 @@ void FeaturesPlugin_BooleanSmash::execute()
     std::shared_ptr<GeomAlgoAPI_Boolean> aToolsCutAlgo(
       new GeomAlgoAPI_Boolean(aTools,
                               aShapesToAdd,
-                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                              GeomAlgoAPI_Tools::BOOL_CUT));
 
     if (GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) {
       aTools.clear();
@@ -179,7 +179,7 @@ void FeaturesPlugin_BooleanSmash::execute()
   std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(
     new GeomAlgoAPI_Boolean(aShapesToSmash,
                             aTools,
-                            GeomAlgoAPI_Boolean::BOOL_CUT));
+                            GeomAlgoAPI_Tools::BOOL_CUT));
 
   // Checking that the algorithm worked properly.
   if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) {
index 4692110f43eb3efdee8889ae4a6a38af6a09b111..d10c82d852ff728393fc144d6cfcf34e01ffda99 100644 (file)
@@ -173,7 +173,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         aListWithObject.push_back(anObject);
         std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aListWithObject,
                                                                 theTools,
-                                                                GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                                GeomAlgoAPI_Tools::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
@@ -213,7 +213,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
 
         std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedShapes,
                                                                   theTools,
-                                                                  GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                                  GeomAlgoAPI_Tools::BOOL_CUT));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
@@ -307,7 +307,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       if(!anEdgesAndFaces.empty() && !aCutTools.empty()) {
         std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
                                                               aCutTools,
-                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                              GeomAlgoAPI_Tools::BOOL_CUT));
         if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) {
           anEdgesAndFaces.clear();
           anEdgesAndFaces.push_back(aCutAlgo->shape());
@@ -319,7 +319,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       if(!aShapesToAdd.empty()) {
         std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse,
                                                               aShapesToAdd,
-                                                              GeomAlgoAPI_Boolean::BOOL_CUT));
+                                                              GeomAlgoAPI_Tools::BOOL_CUT));
         if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
           aSolidsToFuse.clear();
           aSolidsToFuse.push_back(aCutAlgo->shape());
@@ -339,7 +339,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
 
         std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
                                                           aTools,
-                                                          GeomAlgoAPI_Boolean::BOOL_FUSE));
+                                                          GeomAlgoAPI_Tools::BOOL_FUSE));
 
         // Checking that the algorithm worked properly.
         if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) {
index f572664a2cc85c8fa5e71914c0c62a06ee39613c..7c29a3efe222bf6a1cb075e989aebb72d59a8e65 100644 (file)
 
 typedef std::list<std::pair<GeomShapePtr, ListOfShape> > CompsolidSubs;
 
-static GeomShapePtr findBase(const GeomShapePtr theObjectShape,
-                             const GeomShapePtr theResultShape,
-                             const GeomAPI_Shape::ShapeType theShapeType,
-                             const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
-
 static void pullObjectsAndPlanes(const AttributeSelectionListPtr& theSelectedList,
                                  CompsolidSubs& theObjects, ListOfShape& thePlanes);
 
@@ -323,7 +318,7 @@ static bool cutSubs(const GeomShapePtr& theFirstArgument,
 
     // cut from current list of solids
     aCutAlgo.reset(
-        new GeomAlgoAPI_Boolean(aUIt->second, theTools, GeomAlgoAPI_Boolean::BOOL_CUT));
+        new GeomAlgoAPI_Boolean(aUIt->second, theTools, GeomAlgoAPI_Tools::BOOL_CUT));
     if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, "", theError))
       return false;
     theMakeShapeList->appendAlgo(aCutAlgo);
index 1a33cb12ada01d83f71cabc79b52ff6f4fa5e3ac..8daf2723ebffce8d911fc102d76ce377dbc04156 100644 (file)
@@ -116,7 +116,7 @@ void FeaturesPlugin_Union::execute()
     aTools.splice(aTools.begin(), anObjects, anObjects.begin());
     anAlgo.reset(new GeomAlgoAPI_Boolean(anObjects,
                  aTools,
-                 GeomAlgoAPI_Boolean::BOOL_FUSE));
+                 GeomAlgoAPI_Tools::BOOL_FUSE));
   } else {
     anAlgo.reset(new GeomAlgoAPI_UnifySameDomain(anObjects));
   }
index ef984332f823f9cad0e540b12a71108f0ed2d9cb..4b668f5d98637d0da5e34cd16648992eee059be7 100644 (file)
@@ -30,7 +30,7 @@
 //=================================================================================================
 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const GeomShapePtr theTool,
-                                         const OperationType theOperationType)
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType)
 {
   ListOfShape aListWithObject, aListWithTool;
   aListWithObject.push_back(theObject);
@@ -41,7 +41,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
 //=================================================================================================
 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const ListOfShape& theTools,
-                                         const OperationType theOperationType)
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType)
 {
   ListOfShape aListWithObject;
   aListWithObject.push_back(theObject);
@@ -51,7 +51,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
 //=================================================================================================
 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects,
                                          const ListOfShape& theTools,
-                                         const OperationType theOperationType)
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType)
 {
   build(theObjects, theTools, theOperationType);
 }
@@ -60,7 +60,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects,
 //=================================================================================================
 void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects,
                                 const ListOfShape& theTools,
-                                const OperationType theOperationType)
+                                const GeomAlgoAPI_Tools::BOPType theOperationType)
 {
   if(theObjects.empty() || theTools.empty()) {
     return;
@@ -85,15 +85,15 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects,
   // Creating boolean operation.
   BOPAlgo_BOP* aBuilder = new BOPAlgo_BOP();
   switch (theOperationType) {
-    case BOOL_CUT: {
+    case GeomAlgoAPI_Tools::BOOL_CUT: {
       aBuilder->SetOperation(BOPAlgo_CUT);
       break;
     }
-    case BOOL_FUSE: {
+    case GeomAlgoAPI_Tools::BOOL_FUSE: {
       aBuilder->SetOperation(BOPAlgo_FUSE);
       break;
     }
-    case BOOL_COMMON: {
+    case GeomAlgoAPI_Tools::BOOL_COMMON: {
       aBuilder->SetOperation(BOPAlgo_COMMON);
       break;
     }
index d5a08376c3d3163fec204e9ca730396703e9788a..32224162bc0d10a1d38f0f3571be27ded0212f2e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <GeomAlgoAPI.h>
 #include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_Tools.h>
 
 #include <GeomAPI_Shape.h>
 
 /// \brief Allows to perform of boolean operations
 class GeomAlgoAPI_Boolean : public GeomAlgoAPI_MakeShape
 {
-public:
-  /// Type of booelan operation
-  enum OperationType {
-    BOOL_CUT,   ///< Cut objects
-    BOOL_FUSE,  ///< Fuse objects
-    BOOL_COMMON ///< Take common part of objects
-  };
-
 public:
 
   /// Constructor.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const GeomShapePtr theTool,
-                                         const OperationType theOperationType);
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType);
 
   /// Constructor.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const ListOfShape& theTools,
-                                         const OperationType theOperationType);
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType);
 
 
   /// Constructor.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const ListOfShape& theObjects,
                                          const ListOfShape& theTools,
-                                         const OperationType theOperationType);
+                                         const GeomAlgoAPI_Tools::BOPType theOperationType);
 
   /// Redefinition of the generic method for the Fuse problem: OCCT 30481
   GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape,
@@ -64,7 +57,7 @@ private:
   /// Builds resulting shape.
   void build(const ListOfShape& theObjects,
              const ListOfShape& theTools,
-             const OperationType theOperationType);
+             const GeomAlgoAPI_Tools::BOPType theOperationType);
 };
 
 #endif
index 2cb26c75b8c532ae85288392836e00ad6bb3aafa..a9a57baf478c78d4efed0f9ffc0e1366cc727549 100644 (file)
 class GeomAlgoAPI_MakeShape;
 
 namespace GeomAlgoAPI_Tools {
+/// Type of booelan operation
+enum BOPType {
+  BOOL_CUT,      ///< Cut objects
+  BOOL_FUSE,     ///< Fuse objects
+  BOOL_COMMON,   ///< Take common part of objects
+  BOOL_PARTITION ///< Parition operation
+};
 
 /** \class Localizer
  *  \ingroup DataAlgo