Salome HOME
Issue #2307: 1.1.2.5 Remove Sub-Shapes mode
authordbv <dbv@opencascade.com>
Mon, 27 Nov 2017 16:11:49 +0000 (19:11 +0300)
committerdbv <dbv@opencascade.com>
Mon, 27 Nov 2017 16:12:02 +0000 (19:12 +0300)
Added mode to select which sub-shapes should be removed.

src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp
src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp
src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/Test/TestRemoveSubShapes2.py [new file with mode: 0644]
src/FeaturesPlugin/icons/keep_subshapes_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/icons/remove_subshapes_32x32.png [new file with mode: 0644]
src/FeaturesPlugin/remove_subshapes_widget.xml

index 24447bc00ecb24490d2467f47f47c9eec66e0e84..4d5b40ba324680961b78db3b49932c8ad78c2b51 100644 (file)
@@ -62,7 +62,20 @@ void FeaturesAPI_RemoveSubShapes::setBase(const ModelHighAPI_Selection& theBase)
 void FeaturesAPI_RemoveSubShapes::setSubShapesToKeep(
   const std::list<ModelHighAPI_Selection>& theSubShapes)
 {
-  fillAttribute(theSubShapes, mysubshapes);
+  fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES(),
+                mycreationMethod);
+  fillAttribute(theSubShapes, mysubshapesToKeep);
+
+  execute();
+}
+
+//==================================================================================================
+void FeaturesAPI_RemoveSubShapes::setSubShapesToRemove(
+  const std::list<ModelHighAPI_Selection>& theSubShapes)
+{
+  fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_REMOVE_SUBSHAPES(),
+                mycreationMethod);
+  fillAttribute(theSubShapes, mysubshapesToRemove);
 
   execute();
 }
@@ -75,12 +88,27 @@ void FeaturesAPI_RemoveSubShapes::dump(ModelHighAPI_Dumper& theDumper) const
 
   AttributeSelectionPtr anAttrBaseShape =
     aBase->selection(FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID());
-  AttributeSelectionListPtr anAttrSubShapes =
-    aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID());
 
-  theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName <<
-    ", " << anAttrBaseShape << ")" << std::endl;
-  theDumper << aBase << ".setSubShapesToKeep(" << anAttrSubShapes << ")" << std::endl;
+  std::string aCreationMethod =
+    aBase->string(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD())->value();
+
+  AttributeSelectionListPtr anAttrSubShapes;
+
+  if (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES()) {
+    anAttrSubShapes =
+      aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID());
+  }
+  else {
+    anAttrSubShapes =
+      aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID());
+  }
+
+  theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName << ", " << anAttrBaseShape << ")"
+            << std::endl;
+  theDumper << aBase
+    << (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES() ?
+       ".setSubShapesToKeep(" : ".setSubShapesToRemove(")
+    << anAttrSubShapes << ")" << std::endl;
 }
 
 //==================================================================================================
index cabae5368de9a50b60411a8a2f9dbeab7d324ce9..15a1d04955edbe434da7db64f179da41b877de64 100644 (file)
@@ -50,11 +50,15 @@ public:
   FEATURESAPI_EXPORT
   virtual ~FeaturesAPI_RemoveSubShapes();
 
-  INTERFACE_2(FeaturesPlugin_RemoveSubShapes::ID(),
+  INTERFACE_4(FeaturesPlugin_RemoveSubShapes::ID(),
               base, FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID(),
               ModelAPI_AttributeSelection, /** Base */,
-              subshapes, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID(),
-              ModelAPI_AttributeSelectionList, /** Subshapes */)
+              creationMethod, FeaturesPlugin_RemoveSubShapes::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
+              subshapesToKeep, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID(),
+              ModelAPI_AttributeSelectionList, /** Subshapes to keep*/,
+              subshapesToRemove, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID(),
+              ModelAPI_AttributeSelectionList, /** Subshapes to remove*/)
 
   /// Modify objects attribute of the feature.
   FEATURESAPI_EXPORT
@@ -64,6 +68,10 @@ public:
   FEATURESAPI_EXPORT
   void setSubShapesToKeep(const std::list<ModelHighAPI_Selection>& theSubShapes);
 
+  /// Modify tools attribute of the feature.
+  FEATURESAPI_EXPORT
+  void setSubShapesToRemove(const std::list<ModelHighAPI_Selection>& theSubShapes);
+
   /// Dump wrapped feature
   FEATURESAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
index a828b1a94d8f44cc23037b30c1a03a400712bcc7..81552dd4c0bb078bf4ff638fcac386a27e7f95d7 100644 (file)
@@ -162,6 +162,7 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestIntersection.py
                TestUnion.py
                TestRemoveSubShapes.py
+               TestRemoveSubShapes2.py
                TestPipe.py
                TestRecover.py
                TestRecover1798.py
index 53d02ab83e183e643c45c03357965aea72d51dc1..2f54129831f54599ecfee4f72b51c36924e03050 100644 (file)
@@ -21,6 +21,7 @@
 #include "FeaturesPlugin_RemoveSubShapes.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultCompSolid.h>
 #include <ModelAPI_ResultConstruction.h>
@@ -38,6 +39,7 @@
 
 //==================================================================================================
 FeaturesPlugin_RemoveSubShapes::FeaturesPlugin_RemoveSubShapes()
+: myChangedInCode(false)
 {
 }
 
@@ -46,59 +48,141 @@ void FeaturesPlugin_RemoveSubShapes::initAttributes()
 {
   data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
 
-  data()->addAttribute(SUBSHAPES_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+  data()->addAttribute(SUBSHAPES_TO_KEEP_ID(), ModelAPI_AttributeSelectionList::typeId());
+
+  data()->addAttribute(SUBSHAPES_TO_REMOVE_ID(), ModelAPI_AttributeSelectionList::typeId());
 }
 
 void FeaturesPlugin_RemoveSubShapes::attributeChanged(const std::string& theID)
 {
   ModelAPI_Feature::attributeChanged(theID);
 
-  if(theID == BASE_SHAPE_ID()) {
-    AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
-    AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
-    if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
-      return;
-    }
+  if (myChangedInCode) return;
 
-    aSubShapesAttrList->clear();
+  AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
+  AttributeSelectionListPtr aSubShapesToKeepAttrList = selectionList(SUBSHAPES_TO_KEEP_ID());
+  AttributeSelectionListPtr aSubShapesToRemoveAttrList = selectionList(SUBSHAPES_TO_REMOVE_ID());
+  if (!aShapeAttrSelection.get()
+      || !aSubShapesToKeepAttrList.get()
+      || !aSubShapesToRemoveAttrList.get())
+  {
+    return;
+  }
 
-    ResultPtr aContext = aShapeAttrSelection->context();
-    ResultCompSolidPtr aResultCompSolid =
-      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
-    if(!aResultCompSolid.get()) {
-      return;
-    }
+  ResultPtr aContext = aShapeAttrSelection->context();
+  ResultCompSolidPtr aResultCompSolid =
+    std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
+  if(!aResultCompSolid.get()) {
+    aSubShapesToKeepAttrList->clear();
+    aSubShapesToRemoveAttrList->clear();
+    return;
+  }
+  const int aNumOfSubs = aResultCompSolid->numberOfSubs();
 
-    GeomShapePtr aBaseShape = aShapeAttrSelection->value();
-    if(!aBaseShape.get()) {
-      aBaseShape = aContext->shape();
-    }
-    if(!aBaseShape.get()) {
-      return;
-    }
-    GeomAPI_Shape::ShapeType aShapeType = aBaseShape->shapeType();
-    if(aShapeType != GeomAPI_Shape::WIRE
-        && aShapeType != GeomAPI_Shape::SHELL
-        && aShapeType != GeomAPI_Shape::COMPSOLID
-        && aShapeType != GeomAPI_Shape::COMPOUND) {
+  GeomShapePtr aBaseShape = aShapeAttrSelection->value();
+  if(!aBaseShape.get()) {
+    aBaseShape = aContext->shape();
+  }
+
+  myChangedInCode = true;
+
+  if(theID == BASE_SHAPE_ID()) {
+    aSubShapesToKeepAttrList->clear();
+    aSubShapesToRemoveAttrList->clear();
+
+    if (!aBaseShape.get()) {
       return;
     }
+
     for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
       GeomShapePtr aSubShape = anIt.current();
-      const int aNumOfSubs = aResultCompSolid->numberOfSubs();
       if(aNumOfSubs == 0) {
-        aSubShapesAttrList->append(aContext, aSubShape);
+        aSubShapesToKeepAttrList->append(aContext, aSubShape);
       } else {
         for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
           ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
           if(aSubResult->shape()->isEqual(aSubShape)) {
-            aSubShapesAttrList->append(aSubResult, aSubShape);
+            aSubShapesToKeepAttrList->append(aSubResult, aSubShape);
             break;
           }
         }
       }
     }
   }
+  else if (theID == SUBSHAPES_TO_KEEP_ID())
+  {
+    aSubShapesToRemoveAttrList->clear();
+
+    if (!aBaseShape.get()) {
+      return;
+    }
+
+    int anIndex;
+    const int aSubsToKeepNb = aSubShapesToKeepAttrList->size();
+    for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+      GeomShapePtr aSubShape = anIt.current();
+      for(anIndex = 0; anIndex < aSubsToKeepNb; ++anIndex) {
+        AttributeSelectionPtr anAttrSelectionInList = aSubShapesToKeepAttrList->value(anIndex);
+        GeomShapePtr aSubShapeToKeep = anAttrSelectionInList->value();
+        if (aSubShapeToKeep.get() && aSubShapeToKeep->isEqual(aSubShape)) {
+          break;
+        }
+      }
+
+      if (anIndex == aSubsToKeepNb) {
+        if(aNumOfSubs == 0) {
+          aSubShapesToRemoveAttrList->append(aContext, aSubShape);
+        } else {
+          for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
+            ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
+            if(aSubResult->shape()->isEqual(aSubShape)) {
+              aSubShapesToRemoveAttrList->append(aSubResult, aSubShape);
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (theID == SUBSHAPES_TO_REMOVE_ID())
+  {
+    aSubShapesToKeepAttrList->clear();
+
+    if (!aBaseShape.get()) {
+      return;
+    }
+
+    int anIndex;
+    const int aSubsToRemoveNb = aSubShapesToRemoveAttrList->size();
+    for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+      GeomShapePtr aSubShape = anIt.current();
+      for(anIndex = 0; anIndex < aSubsToRemoveNb; ++anIndex) {
+        AttributeSelectionPtr anAttrSelectionInList = aSubShapesToRemoveAttrList->value(anIndex);
+        GeomShapePtr aSubShapeToRemove = anAttrSelectionInList->value();
+        if (aSubShapeToRemove.get() && aSubShapeToRemove->isEqual(aSubShape)) {
+          break;
+        }
+      }
+
+      if (anIndex == aSubsToRemoveNb) {
+        if(aNumOfSubs == 0) {
+          aSubShapesToKeepAttrList->append(aContext, aSubShape);
+        } else {
+          for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) {
+            ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex);
+            if(aSubResult->shape()->isEqual(aSubShape)) {
+              aSubShapesToKeepAttrList->append(aSubResult, aSubShape);
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  myChangedInCode = false;
 }
 
 //==================================================================================================
@@ -106,7 +190,7 @@ void FeaturesPlugin_RemoveSubShapes::execute()
 {
   // Get base shape and sub-shapes list.
   AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
-  AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
+  AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_TO_KEEP_ID());
   if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
     return;
   }
index 39cb6fabeafc166a9e99e5084807c03f276b99c3..4bbe6a01c2abf0b3017c5a4be2a92f7038137f6b 100644 (file)
@@ -48,13 +48,42 @@ public:
     return MY_BASE_SHAPE_ID;
   }
 
-  /// Attribute name of sub-shapes.
-  inline static const std::string& SUBSHAPES_ID()
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
   {
-    static const std::string MY_SUBSHAPES_ID("subshapes");
+    static const std::string MY_CREATION_METHOD_ID("creation_method");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_BY_KEEP_SUBSHAPES()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_keep_subshapes");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_BY_REMOVE_SUBSHAPES()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_remove_subshapes");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name of sub-shapes to keep.
+  inline static const std::string& SUBSHAPES_TO_KEEP_ID()
+  {
+    static const std::string MY_SUBSHAPES_ID("subshapes_to_keep");
     return MY_SUBSHAPES_ID;
   }
 
+  /// Attribute name of sub-shapes to remove.
+  inline static const std::string& SUBSHAPES_TO_REMOVE_ID()
+  {
+    static const std::string MY_SUBSHAPES_ID("subshapes_to_remove");
+    return MY_SUBSHAPES_ID;
+  }
+
+
   /// \return the kind of a feature.
   FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -71,6 +100,9 @@ public:
 
   /// Creates a new part document if needed.
   FEATURESPLUGIN_EXPORT virtual void execute();
+
+private:
+  bool myChangedInCode;
 };
 
 #endif
index fa2ab069581d86172ceeb58b33910474365c4371..ddcdfacf20b3ffc666907b81ced3ef6328998b79 100644 (file)
@@ -771,7 +771,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
   Events_InfoMessage& theError) const
 {
   static const std::string aBaseShapeID = "base_shape";
-  static const std::string aSubShapesID = "subshapes";
+  static const std::string aSubShapesID = "subshapes_to_keep";
 
   if(theFeature->getKind() != "Remove_SubShapes") {
     theError = "Error: Feature \"%1\" does not supported by this validator.";
@@ -801,6 +801,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
   }
   GeomShapePtr aResultShape = aBaseShape->emptyCopied();
 
+  if (aSubShapesAttrList->size() == 0) {
+    theError = "Error: Resulting shape is not valid.";
+    return false;
+  }
+
   // Copy sub-shapes from list to new shape.
   for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
     AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
diff --git a/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py b/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py
new file mode 100644 (file)
index 0000000..f630056
--- /dev/null
@@ -0,0 +1,47 @@
+## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-38.80617495711836, 0.1732418524871273, 42.63017006028262)
+SketchCircle_2 = Sketch_1.addCircle(-117.8044596912521, -0.1732418524871385, 54.50817511994374)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Extrusion_1_1"))
+Remove_SubShapes_1.setSubShapesToRemove([model.selection("SOLID", "Extrusion_1_1_3")])
+model.do()
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Remove_SubShapes_1, 1)
+model.testNbSubResults(Remove_SubShapes_1, [2])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.FACE, [10])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.EDGE, [36])
+model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.VERTEX, [72])
+model.testResultsVolumes(Remove_SubShapes_1, [136619.795923917088657617568969727])
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/icons/keep_subshapes_32x32.png b/src/FeaturesPlugin/icons/keep_subshapes_32x32.png
new file mode 100644 (file)
index 0000000..45319eb
Binary files /dev/null and b/src/FeaturesPlugin/icons/keep_subshapes_32x32.png differ
diff --git a/src/FeaturesPlugin/icons/remove_subshapes_32x32.png b/src/FeaturesPlugin/icons/remove_subshapes_32x32.png
new file mode 100644 (file)
index 0000000..094f6d4
Binary files /dev/null and b/src/FeaturesPlugin/icons/remove_subshapes_32x32.png differ
index 353881c4554a970d05053b9dfe1498f76634b6f5..4169fa587ad7fc95e5c59724cd6bac705804be16 100644 (file)
@@ -29,12 +29,29 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
     <validator id="GeomValidators_ShapeType" parameters="wire,shell,compsolid,compound"/>
     <validator id="GeomValidators_BodyShapes" parameters="toplevel"/>
   </shape_selector>
-  <multi_selector id="subshapes"
-                  label="Sub-Shapes to keep:"
-                  tooltip="Select shapes to keep."
-                  type_choice="vertices edges wires faces shells solids compsolids compounds"
-                  clear_in_neutral_point="false">
-    <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
-  </multi_selector>
+  <toolbox id="creation_method">
+    <box id="by_keep_subshapes"
+     title="By keeping sub-shapes"
+     icon="icons/Features/keep_subshapes_32x32.png">
+      <multi_selector id="subshapes_to_keep"
+                label="Sub-Shapes to keep:"
+                tooltip="Select shapes to keep."
+                type_choice="vertices edges wires faces shells solids compsolids compounds"
+                clear_in_neutral_point="false">
+        <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
+      </multi_selector>
+    </box>
+    <box id="by_remove_subshapes"
+     title="By removing sub-shapes"
+     icon="icons/Features/remove_subshapes_32x32.png">
+      <multi_selector id="subshapes_to_remove"
+                label="Sub-Shapes to remove:"
+                tooltip="Select shapes to remove."
+                type_choice="vertices edges wires faces shells solids compsolids compounds"
+                clear_in_neutral_point="false">
+        <validator id="FeaturesPlugin_ValidatorRemoveSubShapesSelection"/>
+      </multi_selector>
+    </box>
+  </toolbox>
   <validator id="FeaturesPlugin_ValidatorRemoveSubShapesResult"/>
 </source>