Salome HOME
Multiple objects and tools for Boolean operations.
authordbv <dbv@opencascade.com>
Thu, 28 May 2015 18:08:12 +0000 (21:08 +0300)
committerdbv <dbv@opencascade.com>
Thu, 28 May 2015 18:08:12 +0000 (21:08 +0300)
12 files changed:
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/boolean_widget.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeProps.h
src/PartSet/PartSet_Validators.cpp

index 2bf1f1ff07df017a9894b5ac2ebb73a5bd5a3cfc..471e5c7c08d0ba2eadb823da7e6a483e1e8469cf 100644 (file)
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeSelectionList.h>
-#include <GeomAlgoAPI_Boolean.h>
-using namespace std;
 
-// to use multi-selection, please comment the next define and uncomment multi_selector in boolean_widget.xml
-#define DEBUG_ONE_OBJECT
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_ShapeProps.h>
 
 #define FACE 4
 #define _MODIFY_TAG 1
 #define _DELETED_TAG 2
+
+//=================================================================================================
 FeaturesPlugin_Boolean::FeaturesPlugin_Boolean()
 {
 }
 
+//=================================================================================================
 void FeaturesPlugin_Boolean::initAttributes()
 {
   data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
 
-#ifdef DEBUG_ONE_OBJECT
-  data()->addAttribute(FeaturesPlugin_Boolean::OBJECT_ID(), ModelAPI_AttributeReference::typeId());
-#else
   AttributeSelectionListPtr aSelection = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
   // extrusion works with faces always
   aSelection->setSelectionType("SOLID");
-#endif
 
-#ifdef DEBUG_ONE_OBJECT
-  data()->addAttribute(FeaturesPlugin_Boolean::TOOL_ID(), ModelAPI_AttributeReference::typeId());
-#else
   aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
   // extrusion works with faces always
   aSelection->setSelectionType("SOLID");
-#endif
 }
 
+//=================================================================================================
 std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::string& theAttrName)
 {
   std::shared_ptr<ModelAPI_AttributeReference> aObjRef = std::dynamic_pointer_cast<
@@ -62,104 +57,196 @@ std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::strin
   return std::shared_ptr<GeomAPI_Shape>();
 }
 
-
+//=================================================================================================
 void FeaturesPlugin_Boolean::execute()
 {
+  // Getting operation type.
   std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
   if (!aTypeAttr)
     return;
   int aType = aTypeAttr->value();
-#ifdef DEBUG_ONE_OBJECT
-  std::shared_ptr<GeomAPI_Shape> anObject = this->getShape(FeaturesPlugin_Boolean::OBJECT_ID());
-#else
-  std::shared_ptr<GeomAPI_Shape> anObject;
-  {
-    AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
-    if (anObjects->size() == 0)
-      return;
-
-    // Getting bounding planes.
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = anObjects->value(0);
-    if (!anObjRef.get())
-      return;
-    anObject = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
-  }
-#endif
-  if (!anObject)
-    return;
 
-#ifdef DEBUG_ONE_OBJECT
-  std::shared_ptr<GeomAPI_Shape> aTool = this->getShape(FeaturesPlugin_Boolean::TOOL_ID());
-#else
-  std::shared_ptr<GeomAPI_Shape> aTool;
-  {
-    AttributeSelectionListPtr anObjects = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
-    if (anObjects->size() == 0)
-      return;
+  ListOfShape anObjects, aTools;
 
-    // Getting bounding planes.
-    std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = anObjects->value(0);
-    if (!anObjRef.get())
+  // Getting objects.
+  AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID());
+  if (anObjectsSelList->size() == 0) {
+    return;
+  }
+  for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+    std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
+    if(!anObject.get()) {
       return;
-    aTool = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
+    }
+    anObjects.push_back(anObject);
   }
-#endif
-  if (!aTool)
-    return;
-
-  std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
 
-  GeomAlgoAPI_Boolean* aFeature = new GeomAlgoAPI_Boolean(anObject, aTool, aType);
-  if(aFeature && !aFeature->isDone()) {
-    static const std::string aFeatureError = "Boolean feature: algorithm failed";  
-    setError(aFeatureError);
-    return;
-  }
-   // Check if shape is valid
-  if (aFeature->shape()->isNull()) {
-    static const std::string aShapeError = "Boolean feature: resulting shape is Null";     
-    setError(aShapeError);
+  // Getting tools.
+  AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID());
+  if (aToolsSelList->size() == 0) {
     return;
   }
-  if(!aFeature->isValid()) {
-    static const std::string aFeatureError = "Boolean feature: resulting shape is not valid";  
-    setError(aFeatureError);
-    return;
-  }  
-  // if result of Boolean operation is same as was before it means that Boolean operation has no sence
-  // and naming provides no result, so, generate an error in this case
-  if (anObject->isEqual(aFeature->shape())) {
-    static const std::string aFeatureError = "Boolean feature: operation was not performed";  
-    setError(aFeatureError);
-    return;
+  for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
+    std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
+    if(!aTool.get()) {
+      return;
+    }
+    aTools.push_back(aTool);
   }
-  //LoadNamingDS
-  LoadNamingDS(aFeature, aResultBody, anObject, aTool, aType);
 
-  setResult(aResultBody);
+  int aResultIndex = 0;
+  ListOfMakeShape aListOfMakeShape;
+  std::shared_ptr<GeomAPI_Shape> aResShape;
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aDataMapOfShapes;
+
+  switch(aType) {
+    case GeomAlgoAPI_Boolean::BOOL_CUT: {
+      // Cut each object with all tools
+      for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+        std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+        aResShape = anObject;
+        ListOfShape aSingleObjectList; aSingleObjectList.push_back(anObject);
+        for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) {
+          std::shared_ptr<GeomAPI_Shape> aTool = *aToolsIt;
+          GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aResShape, aTool, aType);
+          if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
+            static const std::string aBoolAlgoError = "Boolean feature: algorithm failed";
+            setError(aBoolAlgoError);
+            return;
+          }
+          aListOfMakeShape.push_back(aBoolAlgo->makeShape());
+          aResShape = aBoolAlgo->shape();
+          aBoolAlgo->mapOfShapes(aDataMapOfShapes);
+        }
+
+        if(GeomAlgoAPI_ShapeProps::volume(aResShape) > 10.e-5) {
+          std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+          std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(
+            new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
+
+          LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, aSingleObjectList, aTools);
+          setResult(aResultBody, aResultIndex);
+          aResultIndex++;
+        }
+      }
+      break;
+    }
+    case GeomAlgoAPI_Boolean::BOOL_FUSE: {
+      // Fuse all objects.
+      std::shared_ptr<GeomAPI_Shape> aTempRes = anObjects.front();
+      for(ListOfShape::iterator anObjectsIt = ++anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+        std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+        GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aTempRes, anObject, aType);
+        if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
+          static const std::string aBoolAlgoError = "Boolean feature: algorithm failed";
+          setError(aBoolAlgoError);
+          return;
+        }
+        aListOfMakeShape.push_back(aBoolAlgo->makeShape());
+        aTempRes = aBoolAlgo->shape();
+      }
+
+      // Fuse all tools with result of objects fuse.
+      for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) {
+        std::shared_ptr<GeomAPI_Shape> aTool = *aToolsIt;
+        GeomAlgoAPI_Boolean* aBoolAlgo = new GeomAlgoAPI_Boolean(aTempRes, aTool, aType);
+        if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) {
+          static const std::string aBoolAlgoError = "Boolean feature: algorithm failed";
+          setError(aBoolAlgoError);
+          return;
+        }
+        aListOfMakeShape.push_back(aBoolAlgo->makeShape());
+        aTempRes = aBoolAlgo->shape();
+        aBoolAlgo->mapOfShapes(aDataMapOfShapes);
+      }
+      aResShape = aTempRes;
+
+      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
+      std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(
+        new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
+
+      LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, anObjects, aTools);
+      setResult(aResultBody);
+      aResultIndex++;
+      break;
+    }
+    case GeomAlgoAPI_Boolean::BOOL_COMMON: {
+      // Search common between object and tool and fuse them.
+      for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
+        std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+        std::shared_ptr<GeomAPI_Shape> aTempRes;
+        ListOfShape aSingleObjectList; aSingleObjectList.push_back(anObject);
+        for(ListOfShape::iterator aToolsIt = aTools.begin(); aToolsIt != aTools.end(); aToolsIt++) {
+          std::shared_ptr<GeomAPI_Shape> aTool = *aToolsIt;
+          GeomAlgoAPI_Boolean* aBoolAlgo1 = new GeomAlgoAPI_Boolean(anObject, aTool, aType);
+          if(!aBoolAlgo1->isDone() || aBoolAlgo1->shape()->isNull() || !aBoolAlgo1->isValid()) {
+            static const std::string aBoolAlgoError = "Boolean feature: algorithm failed";
+            setError(aBoolAlgoError);
+            return;
+          }
+          aListOfMakeShape.push_back(aBoolAlgo1->makeShape());
+
+          if(!aTempRes) {
+            aTempRes = aBoolAlgo1->shape();
+            aBoolAlgo1->mapOfShapes(aDataMapOfShapes);
+          } else {
+            // Fuse common result with previous common results.
+            GeomAlgoAPI_Boolean* aBoolAlgo2 = new GeomAlgoAPI_Boolean(aTempRes,
+                                                                      aBoolAlgo1->shape(),
+                                                                      GeomAlgoAPI_Boolean::BOOL_FUSE);
+            if(!aBoolAlgo1->isDone() || aBoolAlgo1->shape()->isNull() || !aBoolAlgo1->isValid()) {
+              static const std::string aBoolAlgoError = "Boolean feature: algorithm failed";
+              setError(aBoolAlgoError);
+              return;
+            }
+            aListOfMakeShape.push_back(aBoolAlgo2->makeShape());
+            aTempRes = aBoolAlgo2->shape();
+            aBoolAlgo2->mapOfShapes(aDataMapOfShapes);
+          }
+        }
+        aResShape = aTempRes;
+
+        if(GeomAlgoAPI_ShapeProps::volume(aResShape) > 10.e-5) {
+          std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+          std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(
+            new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
+
+          LoadNamingDS(aMakeShapeList, aResultBody, aResShape, aDataMapOfShapes, aSingleObjectList, aTools);
+          setResult(aResultBody, aResultIndex);
+          aResultIndex++;
+        }
+      }
+      break;
+    }
+  }
+  // remove the rest results if there were produced in the previous pass
+  removeResults(aResultIndex);
 }
 
-//============================================================================
-void FeaturesPlugin_Boolean::LoadNamingDS(GeomAlgoAPI_Boolean* theFeature, 
-                                               std::shared_ptr<ModelAPI_ResultBody> theResultBody, 
-                                               std::shared_ptr<GeomAPI_Shape> theObject,
-                                               std::shared_ptr<GeomAPI_Shape> theTool,
-                                               int theType)
-{  
-
+//=================================================================================================
+void FeaturesPlugin_Boolean::LoadNamingDS(std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList,
+                                          std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                                          std::shared_ptr<GeomAPI_Shape> theResult,
+                                          std::shared_ptr<GeomAPI_DataMapOfShapeShape> theDataMapOfShapes,
+                                          const ListOfShape& theObjects,
+                                          const ListOfShape& theTools)
+{
   //load result
-  theResultBody->storeModified(theObject, theFeature->shape()); 
+  theResultBody->storeModified(theObjects.front(), theResult);
 
   GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
-  theFeature->mapOfShapes(*aSubShapes);
 
-  // Put in DF modified faces
   std::string aModName = "Modified";
-  theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theObject, FACE, _MODIFY_TAG, aModName, *aSubShapes);
-  theResultBody->loadAndOrientModifiedShapes(theFeature->makeShape(), theTool,   FACE, _MODIFY_TAG, aModName, *aSubShapes);
+  for(ListOfShape::const_iterator anIter = theObjects.begin(); anIter != theObjects.end(); anIter++) {
+    theResultBody->loadAndOrientModifiedShapes(theMakeShapeList.get(), *anIter, FACE, _MODIFY_TAG, aModName, *theDataMapOfShapes.get());
+    theResultBody->loadDeletedShapes(theMakeShapeList.get(), *anIter, FACE, _DELETED_TAG);
+  }
 
-  //Put in DF deleted faces
-  theResultBody->loadDeletedShapes(theFeature->makeShape(), theObject, FACE, _DELETED_TAG);
-  theResultBody->loadDeletedShapes(theFeature->makeShape(), theTool,   FACE, _DELETED_TAG);  
+  for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
+    theResultBody->loadAndOrientModifiedShapes(theMakeShapeList.get(), *anIter, FACE, _MODIFY_TAG, aModName, *theDataMapOfShapes.get());
+    theResultBody->loadDeletedShapes(theMakeShapeList.get(), *anIter, FACE, _DELETED_TAG);
+  }
 }
index 53023300a90359148b8fccf7df6fde8152739e7f..959d06061f89400fbbbdfcbd7b3b5ee15b9402d9 100644 (file)
@@ -12,6 +12,8 @@
 #include <GeomAPI_Shape.h>
 #include <GeomAlgoAPI_Boolean.h>
 
+class GeomAlgoAPI_MakeShapeList;
+
 /**\class FeaturesPlugin_Boolean
  * \ingroup Plugins
  * \brief Feature for applying of Boolean operations on Solids.
@@ -60,8 +62,8 @@ public:
   }
 
   enum {
-       BOOL_CUT,
-       BOOL_FUSE,
+    BOOL_CUT,
+    BOOL_FUSE,
     BOOL_COMMON
   };
 
@@ -83,13 +85,14 @@ public:
 
 private:
   std::shared_ptr<GeomAPI_Shape> getShape(const std::string& theAttrName);
-  
+
   /// Load Naming data structure of the feature to the document
-  void LoadNamingDS(GeomAlgoAPI_Boolean* theFeature, 
-                                       std::shared_ptr<ModelAPI_ResultBody> theResultBody,
-                       std::shared_ptr<GeomAPI_Shape> theObject,
-                       std::shared_ptr<GeomAPI_Shape> theTool,
-                                       int theType);
+  void LoadNamingDS(std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList,
+                    std::shared_ptr<ModelAPI_ResultBody> theResultBody,
+                    std::shared_ptr<GeomAPI_Shape> theResult,
+                    std::shared_ptr<GeomAPI_DataMapOfShapeShape> theDataMapOfShapes,
+                    const ListOfShape& theObjects,
+                    const ListOfShape& theTools);
 };
 
 #endif
index f356304b0ed84501ba5da677edb217b8ec00fa8e..76c854b460fbe63f847530c7833b75f33ac5f7a4 100644 (file)
@@ -1,22 +1,25 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <source>
-  <!--<multi_selector id="main_objects" 
-    label="Main object" 
-    icon=":icons/cut_shape.png" 
+  <multi_selector id="main_objects"
+    label="Main object"
+    icon=":icons/cut_shape.png"
     tooltip="Select an object solid"
     type_choice="Solids"
-    concealment="true"
-  />
+    concealment="true">
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="solid"/>
+  </multi_selector>
   <multi_selector id="tool_objects" 
     label="Tool object" 
     icon=":icons/cut_tool.png" 
     tooltip="Select a tool solid"
     type_choice="Solids"
     concealment="true" >
-       <validator id="PartSet_DifferentObjects"/>
-  </multi_selector>-->
-  <shape_selector id="main_object"
+    <validator id="PartSet_DifferentObjects"/>
+    <validator id="GeomValidators_ShapeType" parameters="solid"/>
+  </multi_selector>
+  <!--<shape_selector id="main_object"
     label="Main object"
     icon=":icons/cut_shape.png"
     tooltip="Select an object solid"
@@ -30,7 +33,7 @@
     shape_types="solid"
     concealment="true" >
        <validator id="PartSet_DifferentObjects"/>
-  </shape_selector>
+  </shape_selector>-->
   <choice id="bool_type" 
     label="Type" 
     tooltip="Type of boolean operation"
index 3a5b04d2f061409fbe38289985dc8c2b89f6117c..75870d35073409ceef3ef09a2c1f0b00de8322cc 100644 (file)
@@ -19,6 +19,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Boolean.h
     GeomAlgoAPI_Rotation.h
     GeomAlgoAPI_MakeShape.h
+    GeomAlgoAPI_MakeShapeList.h
     GeomAlgoAPI_ShapeProps.h
     GeomAlgoAPI_DFLoader.h
     GeomAlgoAPI_Placement.h
@@ -43,6 +44,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Boolean.cpp
     GeomAlgoAPI_Rotation.cpp
     GeomAlgoAPI_MakeShape.cpp
+    GeomAlgoAPI_MakeShapeList.cpp
     GeomAlgoAPI_ShapeProps.cpp
     GeomAlgoAPI_DFLoader.cpp
     GeomAlgoAPI_Placement.cpp
index 9d3a05873507cc28a76d59a47d59f0ace60616cc..4327a194e51d321d2913d3c9fa17352bffcef5c8 100644 (file)
@@ -67,7 +67,7 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Boolean::makeCommon(
 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(std::shared_ptr<GeomAPI_Shape> theObject,
                                          std::shared_ptr<GeomAPI_Shape> theTool,
                                          int theType)
-: myOperation(theType), myDone(false), myShape(new GeomAPI_Shape())
+: myOperation(theType), myDone(false), myShape(new GeomAPI_Shape()), myMap(new GeomAPI_DataMapOfShapeShape())
 {
   build(theObject, theTool);
 }
@@ -85,9 +85,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr<GeomAPI_Shape> theObject,
        {
          BRepAlgoAPI_Fuse* mkFuse = new BRepAlgoAPI_Fuse(anObject, aTool);
       if (mkFuse && mkFuse->IsDone()) {
-               setImpl(mkFuse);
                myDone = mkFuse->IsDone() == Standard_True;
-               myMkShape = new GeomAlgoAPI_MakeShape (mkFuse);
+    myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape (mkFuse));
                aResult = mkFuse->Shape();//GeomAlgoAPI_DFLoader::refineResult(aFuse->Shape());      
          }
          break;
@@ -96,9 +95,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr<GeomAPI_Shape> theObject,
        {
       BRepAlgoAPI_Cut* mkCut = new BRepAlgoAPI_Cut(anObject, aTool);
       if (mkCut && mkCut->IsDone()) {
-               setImpl(mkCut);
                myDone = mkCut->IsDone() == Standard_True;
-               myMkShape = new GeomAlgoAPI_MakeShape (mkCut);
+               myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape (mkCut));
                aResult = mkCut->Shape();    
          }
          break;
@@ -107,9 +105,8 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr<GeomAPI_Shape> theObject,
        {
       BRepAlgoAPI_Common* mkCom = new BRepAlgoAPI_Common(anObject, aTool);
       if (mkCom && mkCom->IsDone()) {
-               setImpl(mkCom);
                myDone = mkCom->IsDone() == Standard_True;
-               myMkShape = new GeomAlgoAPI_MakeShape (mkCom);
+               myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape (mkCom));
                aResult = mkCom->Shape(); 
          }
          break;
@@ -126,7 +123,7 @@ void GeomAlgoAPI_Boolean::build(std::shared_ptr<GeomAPI_Shape> theObject,
        for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
          std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
       aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
-         myMap.bind(aCurrentShape, aCurrentShape);
+         myMap->bind(aCurrentShape, aCurrentShape);
        }
   }  
 }
@@ -150,13 +147,13 @@ const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Boolean::shape () const
 }
 
 //============================================================================
-void GeomAlgoAPI_Boolean::mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const
+void GeomAlgoAPI_Boolean::mapOfShapes(std::shared_ptr<GeomAPI_DataMapOfShapeShape>& theMap) const
 {
   theMap = myMap;
 }
 
 //============================================================================
-GeomAlgoAPI_MakeShape * GeomAlgoAPI_Boolean::makeShape() const
+const std::shared_ptr<GeomAlgoAPI_MakeShape>& GeomAlgoAPI_Boolean::makeShape() const
 {
   return myMkShape;
 }
@@ -164,7 +161,4 @@ GeomAlgoAPI_MakeShape * GeomAlgoAPI_Boolean::makeShape() const
 //============================================================================
 GeomAlgoAPI_Boolean::~GeomAlgoAPI_Boolean()
 {
-  if (myImpl) {    
-       myMap.clear();
-  }
 }
\ No newline at end of file
index 9ca251863ef5a812ecc7479b340f8b5820424b52..6e92769a964ba4d950199dc9c3bb6ee9a58c4676 100644 (file)
@@ -70,10 +70,10 @@ class GeomAlgoAPI_Boolean : public GeomAPI_Interface
   GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape () const; 
  
   /// Returns map of sub-shapes of the result. To be used for History keeping
-  GEOMALGOAPI_EXPORT void  mapOfShapes (GeomAPI_DataMapOfShapeShape& theMap) const;
+  GEOMALGOAPI_EXPORT void  mapOfShapes(std::shared_ptr<GeomAPI_DataMapOfShapeShape>& theMap) const;
 
   /// Return interface for for History processing
-  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape* makeShape () const;
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAlgoAPI_MakeShape>& makeShape () const;
 
   ///Destructor
   GEOMALGOAPI_EXPORT  ~GeomAlgoAPI_Boolean();
@@ -86,9 +86,9 @@ class GeomAlgoAPI_Boolean : public GeomAPI_Interface
   double mySize;
   bool myDone;
   int  myOperation;
-  std::shared_ptr<GeomAPI_Shape> myShape;  
-  GeomAPI_DataMapOfShapeShape myMap;
-  GeomAlgoAPI_MakeShape * myMkShape;
+  std::shared_ptr<GeomAPI_Shape> myShape;
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> myMap;
+  std::shared_ptr<GeomAlgoAPI_MakeShape> myMkShape;
 };
 
 #endif
index 4682f1fb0c760213ab57f52b24533b17ac25abe7..b0c7be684cce7a4182ff4adbdd07a2f955b3ac06 100644 (file)
@@ -17,10 +17,6 @@ GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape)
 GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
   : GeomAPI_Interface(),myShape(new GeomAPI_Shape())
 {}
-void GeomAlgoAPI_MakeShape::init(void* theMkShape)
-{
-  setImpl((void *)implPtr<BRepBuilderAPI_MakeShape>());
-}
 
 const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
 {
index 186b12c67e794bb7e05eec981099fb9d8579db96..38519b03fa3c9e553100c1ff74e3f1838ec4012a 100644 (file)
@@ -7,9 +7,11 @@
 #define GeomAlgoAPI_MakeShape_H_
 
 #include <GeomAPI_Shape.h>
-#include <memory>
 #include <GeomAlgoAPI.h>
 
+#include <list>
+#include <memory>
+
 /**\class GeomAlgoAPI_MakeShape
  * \ingroup DataAlgo
  * \brief Interface to the root class of all topological shapes constructions
@@ -35,12 +37,12 @@ public:
 
   /// Returns whether the shape is an edge
   GEOMALGOAPI_EXPORT virtual bool isDeleted(const std::shared_ptr<GeomAPI_Shape> theShape);
-  /// Initializes the algorithm by the builder stored in the interface
-  GEOMALGOAPI_EXPORT void init(void* theMkShape);
 
   protected:
   /// The resulting shape
        std::shared_ptr<GeomAPI_Shape> myShape;
 };
 
+typedef std::list<std::shared_ptr<GeomAlgoAPI_MakeShape> > ListOfMakeShape;
+
 #endif
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.cpp
new file mode 100644 (file)
index 0000000..d5c050c
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_MakeShapeListList.h
+// Created:     27 May 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAlgoAPI_MakeShapeList.h>
+
+#include <BRepBuilderAPI_MakeShape.hxx>
+#include <NCollection_Map.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_MakeShapeList::GeomAlgoAPI_MakeShapeList()
+: GeomAlgoAPI_MakeShape()
+{}
+
+//=================================================================================================
+GeomAlgoAPI_MakeShapeList::GeomAlgoAPI_MakeShapeList(const ListOfMakeShape& theMakeShapeList)
+: GeomAlgoAPI_MakeShape()
+{
+  init(theMakeShapeList);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShapeList::init(const ListOfMakeShape& theMakeShapeList)
+{
+  myMakeShapeList = theMakeShapeList;
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShapeList::shape() const
+{
+  if(myMakeShapeList.empty()) {
+    return std::shared_ptr<GeomAPI_Shape>();
+  } else {
+    return myMakeShapeList.back()->shape();
+  }
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShapeList::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                          ListOfShape& theHistory)
+{
+  result(theShape, theHistory, GeomAlgoAPI_MakeShapeList::Generated);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeShapeList::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                         ListOfShape& theHistory)
+{
+  result(theShape, theHistory, GeomAlgoAPI_MakeShapeList::Modified);
+}
+
+void GeomAlgoAPI_MakeShapeList::result(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                       ListOfShape& theHistory,
+                                       OperationType theOperationType)
+{
+  if(myMakeShapeList.empty()) {
+    return;
+  }
+
+  NCollection_Map<TopoDS_Shape> aTempShapes;
+  NCollection_Map<TopoDS_Shape> aResultShapes;
+  aTempShapes.Add(theShape->impl<TopoDS_Shape>());
+
+  for(ListOfMakeShape::iterator aBuilderIt = myMakeShapeList.begin(); aBuilderIt != myMakeShapeList.end(); aBuilderIt++) {
+    BRepBuilderAPI_MakeShape* aBuilder = (*aBuilderIt)->implPtr<BRepBuilderAPI_MakeShape>();
+    for(NCollection_Map<TopoDS_Shape>::Iterator aShapeIt(aTempShapes); aShapeIt.More(); aShapeIt.Next()) {
+      const TopoDS_Shape& aShape = aShapeIt.Value();
+      const TopTools_ListOfShape& aList = theOperationType == GeomAlgoAPI_MakeShapeList::Generated ?
+                                          aBuilder->Generated(aShape) : aBuilder->Modified(aShape);
+      bool prevResRemoved = false;
+      for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
+        aTempShapes.Add(anIt.Value());
+        aResultShapes.Add(anIt.Value());
+        if(!prevResRemoved) {
+          aResultShapes.Remove(aShape);
+          prevResRemoved = true;
+        }
+      }
+    }
+  }
+
+  for(NCollection_Map<TopoDS_Shape>::Iterator aShapeIt(aResultShapes); aShapeIt.More(); aShapeIt.Next()) {
+    std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+    aShape->setImpl(new TopoDS_Shape(aShapeIt.Value()));
+    theHistory.push_back(aShape);
+  }
+}
+
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeList.h
new file mode 100644 (file)
index 0000000..8d79750
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_MakeShapeList.h
+// Created:     27 May 2015
+// Author:      Dmitry Bobylev
+#ifndef GeomAlgoAPI_MakeShapeList_H_
+#define GeomAlgoAPI_MakeShapeList_H_
+
+#include <GeomAPI_Shape.h>
+#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <memory>
+
+/** \class GeomAlgoAPI_MakeShapeList
+ *  \ingroup DataAlgo
+ *  \brief Interface to the root class of all topological shapes constructions
+ */
+class GeomAlgoAPI_MakeShapeList : public GeomAlgoAPI_MakeShape
+{
+  enum OperationType {
+    Generated,
+    Modified
+  };
+
+public:
+  /// Default constructor
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShapeList();
+
+  /** \brief Constructor
+   *  \param[in] theMakeShapeList list of algorithms.
+   */
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShapeList(const ListOfMakeShape& theMakeShapeList);
+
+  /** \brief Initializes a class with new list of algorithms.
+   *  \param[in] theMakeShapeList list of algorithms.
+   */
+  GEOMALGOAPI_EXPORT void init(const ListOfMakeShape& theMakeShapeList);
+
+  /// \return a shape built by the shape construction algorithms
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape> shape() const;
+
+  /// \return the list of shapes generated from the shape \a theShape
+  GEOMALGOAPI_EXPORT virtual void generated(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                            ListOfShape& theHistory);
+
+  /// \return the list of shapes modified from the shape \a theShape
+  GEOMALGOAPI_EXPORT virtual void modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                           ListOfShape& theHistory);
+
+private:
+  void result(const std::shared_ptr<GeomAPI_Shape> theShape,
+              ListOfShape& theHistory,
+              OperationType theOperationType);
+
+
+protected:
+  ListOfMakeShape myMakeShapeList;
+};
+
+#endif
index abc7faa724bc77bfc401d2d98304db49b539c97c..d802840db214514bb1c61b81419067bf060d1b8f 100644 (file)
@@ -22,8 +22,8 @@ public:
   /// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
   static double volume(std::shared_ptr<GeomAPI_Shape> theShape);
 
-  /// \return the centre of mass of the current shape. The coordinates returned for the center of mass
-  /// are expressed in the absolute Cartesian coordinate system.
+  /// \return the centre of mass of the current face. The coordinates returned for the center of mass
+  /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
   static std::shared_ptr<GeomAPI_Pnt> centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape);
 };
 
index e31b1b2b50257a04d870bc72860e4fac5953b839..1e0f79b2f75dfc882b3ab6b4470234d8e7a93345 100644 (file)
@@ -216,7 +216,7 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
       }
     }
   }
-  else if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
+  else if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
     AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
     ResultPtr aContext = anAttr->context();
     GeomShapePtr aShape = anAttr->value();
@@ -258,6 +258,32 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute
       }
     }
   }
+  else if(anAttrType == ModelAPI_AttributeSelectionList::typeId()) {
+    std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList = 
+            std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+    anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelectionList::typeId());
+    if(anAttrs.size() > 0) {
+      std::list<std::shared_ptr<ModelAPI_Attribute>>::iterator anAttrItr = anAttrs.begin();
+      for(; anAttrItr != anAttrs.end(); anAttrItr++){
+        if ((*anAttrItr).get() && (*anAttrItr)->id() != theAttribute->id()){
+          std::shared_ptr<ModelAPI_AttributeSelectionList> aRefSelList = 
+            std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*anAttrItr);
+          for(int i = 0; i < aCurSelList->size(); i++) {
+            std::shared_ptr<ModelAPI_AttributeSelection> aCurSel = aCurSelList->value(i);
+            for(int j = 0; j < aRefSelList->size(); j++) {
+              std::shared_ptr<ModelAPI_AttributeSelection> aRefSel = aRefSelList->value(j);
+              if(aCurSel->context() == aRefSel->context()) {
+                if(aCurSel->value().get() == NULL || aRefSel->value().get() == NULL
+                  || aCurSel->value()->isEqual(aRefSel->value())) {
+                    return false;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
   return !featureHasReferences(theAttribute);
 }