]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Boolean Smash feature
authordbv <dbv@opencascade.com>
Wed, 9 Mar 2016 12:06:25 +0000 (15:06 +0300)
committerdbv <dbv@opencascade.com>
Wed, 9 Mar 2016 12:06:53 +0000 (15:06 +0300)
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/boolean_widget.xml
src/ModuleBase/ModuleBase_WidgetChoice.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/bool_smash.png [new file with mode: 0644]

index 7360f443cda6aeaedf3b9b533bdff020195fb76c..701017b5238726c29f328ebcb12dd56dc9021d33 100644 (file)
@@ -71,7 +71,7 @@ void FeaturesPlugin_Boolean::execute()
       ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
   if (!aTypeAttr)
     return;
-  GeomAlgoAPI_Boolean::OperationType aType = (GeomAlgoAPI_Boolean::OperationType)aTypeAttr->value();
+  OperationType aType = (FeaturesPlugin_Boolean::OperationType)aTypeAttr->value();
 
   ListOfShape anObjects, aTools, anEdgesAndFaces;
   std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
@@ -127,8 +127,8 @@ void FeaturesPlugin_Boolean::execute()
   int aResultIndex = 0;
 
   switch(aType) {
-    case GeomAlgoAPI_Boolean::BOOL_CUT:
-    case GeomAlgoAPI_Boolean::BOOL_COMMON:{
+    case BOOL_CUT:
+    case BOOL_COMMON:{
       if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
         std::string aFeatureError = "Error: Not enough objects for boolean operation.";
         setError(aFeatureError);
@@ -140,7 +140,7 @@ void FeaturesPlugin_Boolean::execute()
         std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
         ListOfShape aListWithObject;
         aListWithObject.push_back(anObject);
-        GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, aType);
+        GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, (GeomAlgoAPI_Boolean::OperationType)aType);
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo.isDone()) {
@@ -188,7 +188,9 @@ void FeaturesPlugin_Boolean::execute()
           }
         }
 
-        std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, aType));
+        std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids,
+                                                                               aTools,
+                                                                               (GeomAlgoAPI_Boolean::OperationType)aType));
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo->isDone()) {
@@ -234,7 +236,7 @@ void FeaturesPlugin_Boolean::execute()
       }
       break;
     }
-    case GeomAlgoAPI_Boolean::BOOL_FUSE: {
+    case BOOL_FUSE: {
       if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
         std::string aFeatureError = "Error: Not enough objects for boolean operation.";
         setError(aFeatureError);
@@ -316,7 +318,9 @@ void FeaturesPlugin_Boolean::execute()
       } else if(anObjects.empty() && aTools.size() == 1) {
         aShape = aTools.front();
       } else if((anObjects.size() + aTools.size()) > 1){
-        std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, aType));
+        std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
+                                                                               aTools,
+                                                                               (GeomAlgoAPI_Boolean::OperationType)aType));
 
         // Checking that the algorithm worked properly.
         if(!aFuseAlgo->isDone()) {
@@ -380,6 +384,132 @@ void FeaturesPlugin_Boolean::execute()
       aResultIndex++;
       break;
     }
+    case BOOL_SMASH: {
+      if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
+        std::string aFeatureError = "Error: Not enough objects for boolean operation.";
+        setError(aFeatureError);
+        return;
+      }
+
+      // List of original solids for naming.
+      ListOfShape anOriginalShapes;
+      anOriginalShapes.insert(anOriginalShapes.end(), anObjects.begin(), anObjects.end());
+      anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end());
+
+      // Collecting all solids which will be smashed.
+      ListOfShape aShapesToSmash;
+      aShapesToSmash.insert(aShapesToSmash.end(), anObjects.begin(), anObjects.end());
+
+      // Collecting solids from compsolids which will not be modified in boolean operation and will be added to result.
+      ListOfShape aShapesToAdd;
+      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;
+        anOriginalShapes.push_back(aCompSolid);
+        aShapesToSmash.insert(aShapesToSmash.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end());
+
+        // Collect solids from compsolid which will not be modified in boolean operation.
+        for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+          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()) {
+            aShapesToAdd.push_back(aSolidInCompSolid);
+          }
+        }
+      }
+
+      GeomAlgoAPI_MakeShapeList aMakeShapeList;
+      GeomAPI_DataMapOfShapeShape aMapOfShapes;
+      if(!aShapesToAdd.empty()) {
+        // Cut objects with not used solids.
+        std::shared_ptr<GeomAlgoAPI_Boolean> anObjectsCutAlgo(new GeomAlgoAPI_Boolean(aShapesToSmash,
+                                                                                      aShapesToAdd,
+                                                                                      GeomAlgoAPI_Boolean::BOOL_CUT));
+
+        if(GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-7) {
+          aShapesToSmash.clear();
+          aShapesToSmash.push_back(anObjectsCutAlgo->shape());
+          aMakeShapeList.appendAlgo(anObjectsCutAlgo);
+          aMapOfShapes.merge(anObjectsCutAlgo->mapOfSubShapes());
+        }
+
+        // Cut tools with not used solids.
+        std::shared_ptr<GeomAlgoAPI_Boolean> aToolsCutAlgo(new GeomAlgoAPI_Boolean(aTools,
+                                                                                   aShapesToAdd,
+                                                                                   GeomAlgoAPI_Boolean::BOOL_CUT));
+
+        if(GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-7) {
+          aTools.clear();
+          aTools.push_back(aToolsCutAlgo->shape());
+          aMakeShapeList.appendAlgo(aToolsCutAlgo);
+          aMapOfShapes.merge(aToolsCutAlgo->mapOfSubShapes());
+        }
+      }
+
+      // Cut objects with tools.
+      std::shared_ptr<GeomAlgoAPI_Boolean> aBoolAlgo(new GeomAlgoAPI_Boolean(aShapesToSmash,
+                                                                             aTools,
+                                                                             GeomAlgoAPI_Boolean::BOOL_CUT));
+
+      // Checking that the algorithm worked properly.
+      if(!aBoolAlgo->isDone()) {
+        static const std::string aFeatureError = "Error: Boolean algorithm failed.";
+        setError(aFeatureError);
+        return;
+      }
+      if(aBoolAlgo->shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        return;
+      }
+      if(!aBoolAlgo->isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        return;
+      }
+      aMakeShapeList.appendAlgo(aBoolAlgo);
+      aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes());
+
+      // Put all (cut result, tools and not used solids) to PaveFiller.
+      aShapesToAdd.push_back(aBoolAlgo->shape());
+      aShapesToAdd.insert(aShapesToAdd.end(), aTools.begin(), aTools.end());
+
+      std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
+      if(!aFillerAlgo->isDone()) {
+        std::string aFeatureError = "Error: PaveFiller algorithm failed.";
+        setError(aFeatureError);
+        return;
+      }
+      if(aFillerAlgo->shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        return;
+      }
+      if(!aFillerAlgo->isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        return;
+      }
+
+      std::shared_ptr<GeomAPI_Shape> aShape = aFillerAlgo->shape();
+      aMakeShapeList.appendAlgo(aFillerAlgo);
+      aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
+
+      std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
+      anOriginalShapes.pop_front();
+      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+      loadNamingDS(aResultBody, aFrontShape, anOriginalShapes, aShape, aMakeShapeList, aMapOfShapes);
+      setResult(aResultBody, aResultIndex);
+      aResultIndex++;
+
+      break;
+    }
     default: {
       std::string anOperationError = "Error: Wrong type of operation";
       setError(anOperationError);
index 0a072e8229cf9a0f1a2a7849129286e05f0df949..fd25cff88e439979e86532865f70d4be7c321e08 100644 (file)
@@ -8,79 +8,67 @@
 #define FeaturesPlugin_Cut_H_
 
 #include "FeaturesPlugin.h"
-#include <ModelAPI_Feature.h>
 
-#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_MakeShape.h>
 
-class GeomAlgoAPI_MakeShapeList;
+#include <ModelAPI_Feature.h>
 
-/**\class FeaturesPlugin_Boolean
- * \ingroup Plugins
- * \brief Feature for applying of Boolean operations on Solids.
- *
- * Supports three kinds of Boolean operations: Cut, Fuse and Common.
- * For all of them requires two Solids: object and tool.
- */
+/// \class FeaturesPlugin_Boolean
+/// \ingroup Plugins
+/// \brief Feature for applying of Boolean operations on Solids.
+/// Supports four kinds of Boolean operations: Cut, Fuse, Common and Smash.
 class FeaturesPlugin_Boolean : public ModelAPI_Feature
 {
 public:
-  /// Extrusion kind
+  enum OperationType {
+    BOOL_CUT,
+    BOOL_FUSE,
+    BOOL_COMMON,
+    BOOL_SMASH
+  };
+
+  /// Feature kind.
   inline static const std::string& ID()
   {
     static const std::string MY_ID("Boolean");
     return MY_ID;
   }
-  /// attribute name of referenced object
+
+  /// Attribute name of main objects.
   inline static const std::string& OBJECT_LIST_ID()
   {
     static const std::string MY_OBJECT_LIST_ID("main_objects");
     return MY_OBJECT_LIST_ID;
   }
-  /// attribute name of referenced object
-  inline static const std::string& OBJECT_ID()
-  {
-    static const std::string MY_OBJECT_ID("main_object");
-    return MY_OBJECT_ID;
-  }
-  /// attribute name of tool object
-  inline static const std::string& TOOL_ID()
-  {
-    static const std::string MY_TOOL_ID("tool_object");
-    return MY_TOOL_ID;
-  }
-  /// attribute name of tool object
+
+  /// Attribute name of tool objects.
   inline static const std::string& TOOL_LIST_ID()
   {
     static const std::string MY_TOOL_LIST_ID("tool_objects");
     return MY_TOOL_LIST_ID;
   }
-  /// attribute name of operation type
+
+  /// Attribute name of operation type.
   inline static const std::string& TYPE_ID()
   {
     static const std::string MY_TYPE_ID("bool_type");
     return MY_TYPE_ID;
   }
 
-  enum {
-    BOOL_CUT,
-    BOOL_FUSE,
-    BOOL_COMMON
-  };
-
-  /// Returns the kind of a feature
+  /// \return the kind of a feature.
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
   {
     static std::string MY_KIND = FeaturesPlugin_Boolean::ID();
     return MY_KIND;
   }
 
-  /// Creates a new part document if needed
+  /// Creates a new part document if needed.
   FEATURESPLUGIN_EXPORT virtual void execute();
 
-  /// Request for initialization of data model of the feature: adding all attributes
+  /// Request for initialization of data model of the feature: adding all attributes.
   FEATURESPLUGIN_EXPORT virtual void initAttributes();
 
-  /// Use plugin manager for features creation
+  /// Use plugin manager for features creation.
   FeaturesPlugin_Boolean();
 
 private:
index 99d5ca6995b05d063fb70a3544c92911d2f159c2..f7d687d7bb643a9294ffe90c016d54ec6ef223b2 100644 (file)
@@ -6,8 +6,8 @@
     buttons_dir="horizontal"
     label="Operation type" 
     tooltip="Type of boolean operation"
-    string_list="Cut Fuse Common"
-    icons_list=":icons/bool_cut.png :icons/bool_fuse.png :icons/bool_common.png"
+    string_list="Cut Fuse Common Smash"
+    icons_list=":icons/bool_cut.png :icons/bool_fuse.png :icons/bool_common.png :icons/bool_smash.png"
     default="0"
   />
   <multi_selector id="main_objects"
index e8db6c289487d6942d47c8688fadc26c282b7e34..09052794e06fe0b5327f2af7e01c665c73acdff6 100644 (file)
@@ -23,7 +23,7 @@ class QButtonGroup;
 *   <choice id="bool_type" 
 *     label="Type" 
 *     tooltip="Type of boolean operation"
-*     string_list="Cut Fuse Common"
+*     string_list="Cut Fuse Common Smash"
 *   />
 * \endcode
 * Aditionally can be used: 
index a4e5d07a0bf07592b514e1925bfaf80b824c21fa..e0249291427008cb77a83a0748f212e1c46ea4a0 100755 (executable)
@@ -1187,6 +1187,9 @@ void PartSet_Module::onBooleanOperationChange(int theOperation)
   case 2:
     aPanel->setWindowTitle(tr("Common"));
     break;
+  case 3:
+    aPanel->setWindowTitle(tr("Smash"));
+    break;
   }
 }
 
index 150fffa4f01355654e0636c947055926db0f97f9..50267fb8bce64db0276d987a4922f069ec4381aa 100644 (file)
@@ -86,6 +86,7 @@
      <file>icons/bool_cut.png</file>
      <file>icons/bool_fuse.png</file>
      <file>icons/bool_common.png</file>
+     <file>icons/bool_smash.png</file>
      <file>icons/plane_view.png</file>
      <file>icons/collinear.png</file>
      <file>icons/middlepoint.png</file>
diff --git a/src/PartSet/icons/bool_smash.png b/src/PartSet/icons/bool_smash.png
new file mode 100644 (file)
index 0000000..bf82ac2
Binary files /dev/null and b/src/PartSet/icons/bool_smash.png differ