Salome HOME
Issue #2563: CEA 2018-1 Common
authordbv <dbv@opencascade.com>
Mon, 20 Aug 2018 07:48:12 +0000 (10:48 +0300)
committerdbv <dbv@opencascade.com>
Mon, 20 Aug 2018 07:48:32 +0000 (10:48 +0300)
Added simple mode with one Objects field in Common feature.

14 files changed:
src/FeaturesAPI/FeaturesAPI_BooleanCommon.cpp
src/FeaturesAPI/FeaturesAPI_BooleanCommon.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.h
src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
src/FeaturesPlugin/FeaturesPlugin_Validators.h
src/FeaturesPlugin/Test/Test2394.py [deleted file]
src/FeaturesPlugin/boolean_common_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h

index bd53854ef0e99c93d25775ab1c77672b7f2ce235..b1af676882115e71249dd47b099eba95ccff94b2 100644 (file)
@@ -32,6 +32,20 @@ FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon(
   initialize();
 }
 
+//==================================================================================================
+FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theMainObjects)
+: ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE(), mycreationMethod);
+    fillAttribute(theMainObjects, mymainObjects);
+
+    execute(false);
+  }
+}
+
 //==================================================================================================
 FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon(
   const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -40,6 +54,7 @@ FeaturesAPI_BooleanCommon::FeaturesAPI_BooleanCommon(
 : ModelHighAPI_Interface(theFeature)
 {
   if(initialize()) {
+    fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_ADVANCED(), mycreationMethod);
     fillAttribute(theMainObjects, mymainObjects);
     fillAttribute(theToolObjects, mytoolObjects);
 
@@ -66,11 +81,24 @@ void FeaturesAPI_BooleanCommon::setMainObjects(
 void FeaturesAPI_BooleanCommon::setToolObjects(
   const std::list<ModelHighAPI_Selection>& theToolObjects)
 {
+  fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_ADVANCED(), mycreationMethod);
   fillAttribute(theToolObjects, mytoolObjects);
 
   execute();
 }
 
+//==================================================================================================
+void FeaturesAPI_BooleanCommon::setAdvancedMode(const bool theMode)
+{
+  if (theMode) {
+    fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_ADVANCED(), mycreationMethod);
+  } else {
+    fillAttribute(FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE(), mycreationMethod);
+  }
+
+  execute();
+}
+
 //==================================================================================================
 void FeaturesAPI_BooleanCommon::dump(ModelHighAPI_Dumper& theDumper) const
 {
@@ -79,12 +107,27 @@ void FeaturesAPI_BooleanCommon::dump(ModelHighAPI_Dumper& theDumper) const
   theDumper << aBase << " = model.addCommon";
 
   const std::string& aDocName = theDumper.name(aBase->document());
+  AttributeStringPtr aMode = aBase->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD());
   AttributeSelectionListPtr anObjects =
     aBase->selectionList(FeaturesPlugin_BooleanCommon::OBJECT_LIST_ID());
   AttributeSelectionListPtr aTools =
     aBase->selectionList(FeaturesPlugin_BooleanCommon::TOOL_LIST_ID());
 
-  theDumper << "(" << aDocName << ", " << anObjects << ", " << aTools << ")" << std::endl;
+  theDumper << "(" << aDocName << ", " << anObjects;
+
+  if (aMode->value() == FeaturesPlugin_BooleanCommon::CREATION_METHOD_ADVANCED()) {
+    theDumper << ", " << aTools;
+  }
+
+  theDumper << ")" << std::endl;
+}
+
+//==================================================================================================
+BooleanCommonPtr addCommon(const std::shared_ptr<ModelAPI_Document>& thePart,
+                           const std::list<ModelHighAPI_Selection>& theMainObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_BooleanCommon::ID());
+  return BooleanCommonPtr(new FeaturesAPI_BooleanCommon(aFeature, theMainObjects));
 }
 
 //==================================================================================================
index 56e49bb79e5b2ab706d266a4e63bf0ff34e27541..e6e20576d0db5dc256570dac3021515b3bc4f6a8 100644 (file)
@@ -41,6 +41,11 @@ public:
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_BooleanCommon(const std::shared_ptr<ModelAPI_Feature>& theFeature);
 
+    /// Constructor with values.
+  FEATURESAPI_EXPORT
+  FeaturesAPI_BooleanCommon(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                            const std::list<ModelHighAPI_Selection>& theMainObjects);
+
   /// Constructor with values.
   FEATURESAPI_EXPORT
   FeaturesAPI_BooleanCommon(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -51,7 +56,9 @@ public:
   FEATURESAPI_EXPORT
   virtual ~FeaturesAPI_BooleanCommon();
 
-  INTERFACE_2(FeaturesPlugin_BooleanCommon::ID(),
+  INTERFACE_3(FeaturesPlugin_BooleanCommon::ID(),
+              creationMethod, FeaturesPlugin_BooleanCommon::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
               mainObjects, FeaturesPlugin_BooleanCommon::OBJECT_LIST_ID(),
               ModelAPI_AttributeSelectionList, /** Main objects */,
               toolObjects, FeaturesPlugin_BooleanCommon::TOOL_LIST_ID(),
@@ -65,6 +72,10 @@ public:
   FEATURESAPI_EXPORT
   void setToolObjects(const std::list<ModelHighAPI_Selection>& theToolObjects);
 
+  /// Set mode.
+  FEATURESAPI_EXPORT
+  void setAdvancedMode(const bool theMode);
+
   /// Dump wrapped feature
   FEATURESAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
@@ -73,6 +84,12 @@ public:
 /// Pointer on Boolean object.
 typedef std::shared_ptr<FeaturesAPI_BooleanCommon> BooleanCommonPtr;
 
+/// \ingroup CPPHighAPI
+/// \brief Create Boolean Common feature.
+FEATURESAPI_EXPORT
+BooleanCommonPtr addCommon(const std::shared_ptr<ModelAPI_Document>& thePart,
+                           const std::list<ModelHighAPI_Selection>& theMainObjects);
+
 /// \ingroup CPPHighAPI
 /// \brief Create Boolean Common feature.
 FEATURESAPI_EXPORT
index a49cd84fda1973fa75300574a8b86d3371fb2433..a4d80e857c93e40378ea05160cbe797142b7cecd 100644 (file)
@@ -70,6 +70,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_Boolean.cpp
     FeaturesPlugin_BooleanCut.cpp
     FeaturesPlugin_BooleanFuse.cpp
+    FeaturesPlugin_BooleanCommon.cpp
     FeaturesPlugin_BooleanSmash.cpp
     FeaturesPlugin_Intersection.cpp
     FeaturesPlugin_Partition.cpp
@@ -108,6 +109,7 @@ SET(XML_RESOURCES
   translation_widget.xml
   boolean_widget.xml
   boolean_fuse_widget.xml
+  boolean_common_widget.xml
   boolean_smash_widget.xml
   recover_widget.xml
   partition_widget.xml
diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp
new file mode 100644 (file)
index 0000000..c180f72
--- /dev/null
@@ -0,0 +1,294 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "FeaturesPlugin_BooleanCommon.h"
+
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_MakeShapeCustom.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_Face.h>
+#include <GeomAPI_ShapeIterator.h>
+
+
+//==================================================================================================
+FeaturesPlugin_BooleanCommon::FeaturesPlugin_BooleanCommon()
+: FeaturesPlugin_Boolean(FeaturesPlugin_Boolean::BOOL_COMMON)
+{
+}
+
+//==================================================================================================
+void FeaturesPlugin_BooleanCommon::initAttributes()
+{
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+
+  data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+  data()->addAttribute(TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//==================================================================================================
+void FeaturesPlugin_BooleanCommon::execute()
+{
+  ListOfShape anObjects, aTools, aPlanes;
+  std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
+
+  bool isSimpleMode = false;
+
+  AttributeStringPtr aCreationMethodAttr = string(CREATION_METHOD());
+  if (aCreationMethodAttr.get()
+      && aCreationMethodAttr->value() == CREATION_METHOD_SIMPLE()) {
+    isSimpleMode = true;
+  }
+
+  // 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 (!isSimpleMode
+        && 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);
+    }
+  }
+
+  // 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 ((anObjects.empty() && aCompSolidsObjects.empty())
+      || (!isSimpleMode && aTools.empty() && aPlanes.empty())) {
+    std::string aFeatureError = "Error: Not enough objects for boolean operation.";
+    setError(aFeatureError);
+    return;
+  }
+
+  int aResultIndex = 0;
+  GeomAlgoAPI_MakeShapeList aMakeShapeList;
+  GeomAPI_DataMapOfShapeShape aMapOfShapes;
+
+  if (isSimpleMode)
+  {
+    ListOfShape::iterator anObjectsIt = anObjects.begin();
+    GeomShapePtr aShape = *anObjectsIt;
+    for (++anObjectsIt; anObjectsIt != anObjects.end(); ++anObjectsIt) {
+      std::shared_ptr<GeomAlgoAPI_Boolean> aCommonAlgo(
+        new GeomAlgoAPI_Boolean(aShape,
+                                *anObjectsIt,
+                                GeomAlgoAPI_Boolean::BOOL_COMMON));
+
+      if (!aCommonAlgo->isDone()) {
+        std::string aFeatureError = "Error: An algorithm failed.";
+        setError(aFeatureError);
+        return;
+      }
+      if (aCommonAlgo->shape()->isNull()) {
+        static const std::string aShapeError = "Error: Resulting shape is Null.";
+        setError(aShapeError);
+        return;
+      }
+      if (!aCommonAlgo->isValid()) {
+        std::string aFeatureError = "Error: Resulting shape is not valid.";
+        setError(aFeatureError);
+        return;
+      }
+
+      aShape = aCommonAlgo->shape();
+      aMakeShapeList.appendAlgo(aCommonAlgo);
+      aMapOfShapes.merge(aCommonAlgo->mapOfSubShapes());
+    }
+
+    GeomAPI_ShapeIterator aShapeIt(aShape);
+    if (aShapeIt.more() || aShape->shapeType() == GeomAPI_Shape::VERTEX) {
+      std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+        document()->createBody(data(), aResultIndex);
+
+      loadNamingDS(aResultBody, anObjects.front(), anObjects, aShape, aMakeShapeList, aMapOfShapes);
+      setResult(aResultBody, aResultIndex);
+      aResultIndex++;
+    }
+  } else {
+    for (ListOfShape::iterator anObjectsIt = anObjects.begin();
+         anObjectsIt != anObjects.end();
+         ++anObjectsIt)
+    {
+      std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
+      ListOfShape aListWithObject;
+      aListWithObject.push_back(anObject);
+      GeomAlgoAPI_MakeShapeList aMakeShapeList;
+      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 (!aBoolAlgo->isDone()) {
+        static const std::string aFeatureError = "Error: Boolean algorithm failed.";
+        setError(aFeatureError);
+        return;
+      }
+      if (aResShape->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);
+
+      GeomAPI_ShapeIterator aShapeIt(aResShape);
+      if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) {
+        std::shared_ptr<ModelAPI_ResultBody> aResultBody =
+          document()->createBody(data(), aResultIndex);
+
+        loadNamingDS(aResultBody, anObject, aTools, aResShape,
+                     aMakeShapeList, *(aBoolAlgo->mapOfSubShapes()));
+        setResult(aResultBody, aResultIndex);
+        aResultIndex++;
+      }
+    }
+  }
+
+  // remove the rest results if there were produced in the previous pass
+  removeResults(aResultIndex);
+}
+
+//==================================================================================================
+void FeaturesPlugin_BooleanCommon::loadNamingDS(ResultBodyPtr theResultBody,
+                                                const GeomShapePtr theBaseShape,
+                                                const ListOfShape& theTools,
+                                                const GeomShapePtr theResultShape,
+                                                GeomAlgoAPI_MakeShape& theMakeShape,
+                                                GeomAPI_DataMapOfShapeShape& theMapOfShapes)
+{
+  //load result
+  if (theBaseShape->isEqual(theResultShape)) {
+    theResultBody->store(theResultShape, false);
+  } else {
+    const int aModifyVTag = 1;
+    const int aModifyETag = 2;
+    const int aModifyFTag = 3;
+    const int aDeletedTag = 4;
+    /// sub solids will be placed at labels 5, 6, etc. if result is compound of solids
+    const int aSubsolidsTag = 5;
+
+    theResultBody->storeModified(theBaseShape, theResultShape, aSubsolidsTag);
+
+    const std::string aModVName = "Modified_Vertex";
+    const std::string aModEName = "Modified_Edge";
+    const std::string aModFName = "Modified_Face";
+
+    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX,
+                                               aModifyVTag, aModVName, theMapOfShapes, false,
+                                               false, true);
+    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::EDGE,
+                                               aModifyETag, aModEName, theMapOfShapes, false,
+                                               false, true);
+    theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
+                                               aModifyFTag, aModFName, theMapOfShapes, false,
+                                               false, true);
+
+    theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
+                                     GeomAPI_Shape::VERTEX, aDeletedTag);
+    theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
+                                     GeomAPI_Shape::EDGE, aDeletedTag);
+    theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
+                                     GeomAPI_Shape::FACE, aDeletedTag);
+
+    for (ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++)
+    {
+      theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::VERTEX,
+                                                 aModifyVTag, aModVName, theMapOfShapes, false,
+                                                 false, true);
+
+      theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::EDGE,
+                                                 aModifyETag, aModEName, theMapOfShapes, false,
+                                                 false, true);
+
+      theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE,
+                                                 aModifyFTag, aModFName, theMapOfShapes, false,
+                                                 false, true);
+
+      theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::VERTEX, aDeletedTag);
+      theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::EDGE, aDeletedTag);
+      theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
+    }
+  }
+}
index 7acab2e3188b5a9342ec2ca4cf36b51cb69f1e18..caf67d38e76c1c90999d0bca2eeda1ccd583a49c 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "FeaturesPlugin_Boolean.h"
 
+#include <ModelAPI_ResultBody.h>
+
 /// \class FeaturesPlugin_BooleanCommon
 /// \ingroup Plugins
 /// \brief Feature for applying of Boolean Common operation.
@@ -44,10 +46,61 @@ public:
     return MY_KIND;
   }
 
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
+  {
+    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_SIMPLE()
+  {
+    static const std::string MY_CREATION_METHOD_ID("simple");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_ADVANCED()
+  {
+    static const std::string MY_CREATION_METHOD_ID("advanced");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// 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 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;
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Creates a new part document if needed.
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
 public:
 
-    /// Use plugin manager for features creation.
-  FeaturesPlugin_BooleanCommon(): FeaturesPlugin_Boolean(BOOL_COMMON) {};
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_BooleanCommon();
+
+private:
+
+  /// Load Naming data structure of the feature to the document
+  void loadNamingDS(ResultBodyPtr theResultBody,
+                    const GeomShapePtr theBaseShape,
+                    const ListOfShape& theTools,
+                    const GeomShapePtr theResultShape,
+                    GeomAlgoAPI_MakeShape& theMakeShape,
+                    GeomAPI_DataMapOfShapeShape& theMapOfShapes);
 
 };
 
index 0319ee264c5ac9eac9d8ebe5a9d194cc59b010c1..341eb82ba3fdab2265bf472e1df8648faf251204 100644 (file)
@@ -58,7 +58,7 @@ void FeaturesPlugin_BooleanFuse::initAttributes()
 //==================================================================================================
 void FeaturesPlugin_BooleanFuse::execute()
 {
-  ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes;
+  ListOfShape anObjects, aTools, anEdgesAndFaces;
   std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
 
   bool isSimpleCreation = false;
@@ -111,12 +111,9 @@ void FeaturesPlugin_BooleanFuse::execute()
     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 if (aTool->shapeType() == GeomAPI_Shape::EDGE
-                 || aTool->shapeType() == GeomAPI_Shape::FACE) {
+      if (aTool->shapeType() == GeomAPI_Shape::EDGE
+          || aTool->shapeType() == GeomAPI_Shape::FACE)
+      {
         anEdgesAndFaces.push_back(aTool);
       } else {
         aTools.push_back(aTool);
index a53331c23136c6607b5e9bb0db96895111cbefa0..89c83bbef9e2a451187e4e8f0da9866fc31814ef 100644 (file)
@@ -104,6 +104,10 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorBooleanFuseSelection);
   aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanFuseArguments",
                               new FeaturesPlugin_ValidatorBooleanFuseArguments);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanCommonSelection",
+                              new FeaturesPlugin_ValidatorBooleanCommonSelection);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanCommonArguments",
+                              new FeaturesPlugin_ValidatorBooleanCommonArguments);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
index 4ab4e48cc1b151bcff7fe87fe58f2b25c0355846..0b33e4c1f8d5743ef834254105e5e6ee17d8d87b 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "FeaturesPlugin_Boolean.h"
 #include "FeaturesPlugin_BooleanFuse.h"
+#include "FeaturesPlugin_BooleanCommon.h"
 #include "FeaturesPlugin_BooleanSmash.h"
 #include "FeaturesPlugin_Union.h"
 
@@ -1509,4 +1510,111 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
   }
 
   return false;
-}
\ No newline at end of file
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
+  const AttributePtr& theAttribute,
+  const std::list<std::string>& theArguments,
+  Events_InfoMessage& theError) const
+{
+  AttributeSelectionListPtr anAttrSelectionList =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if (!anAttrSelectionList.get()) {
+    theError =
+      "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
+    return false;
+  }
+
+  for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+    if (!anAttrSelection.get()) {
+      theError = "Error: Empty attribute selection.";
+      return false;
+    }
+    ResultPtr aContext = anAttrSelection->context();
+    if (!aContext.get()) {
+      theError = "Error: Empty selection context.";
+      return false;
+    }
+    ResultConstructionPtr aResultConstruction =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+    if (aResultConstruction.get()) {
+      if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
+        theError = "Error: Result construction not allowed for selection.";
+        return false;
+      }
+    }
+    std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+    GeomShapePtr aContextShape = aContext->shape();
+    if (!aShape.get()) {
+      aShape = aContextShape;
+    }
+    if (!aShape.get()) {
+      theError = "Error: Empty shape.";
+      return false;
+    }
+    if (!aShape->isEqual(aContextShape)) {
+      theError = "Error: Local selection not allowed.";
+      return false;
+    }
+
+    if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
+      theError = "Error: Result construction should be plane.";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<std::string>& theArguments,
+  Events_InfoMessage& theError) const
+{
+  if (theArguments.size() != 2) {
+    theError = "Wrong number of arguments (expected 2).";
+    return false;
+  }
+
+  std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
+    std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
+
+  int anObjectsNb = 0, aToolsNb = 0;
+
+  std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+
+  bool isAllInSameCompSolid = true;
+  ResultBodyPtr aCompSolid;
+
+  AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
+  if (anAttrSelList) {
+    anObjectsNb = anAttrSelList->size();
+  }
+
+  bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
+                      == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
+
+  if (!isSimpleMode) {
+    anAttrSelList = theFeature->selectionList(*anIt);
+    if (anAttrSelList) {
+      aToolsNb = anAttrSelList->size();
+    }
+  }
+
+  if ((isSimpleMode && anObjectsNb < 2)
+      || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
+    theError = "Not enough arguments for Fuse operation.";
+    return false;
+  }
+}
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
+  std::string theFeature,
+  std::string theAttribute)
+{
+  return false;
+}
index 389ebb261003724c7aab005c15c6225b8e9112ba..18e1c241d21756a590d3a5069050da08ffdae891 100644 (file)
@@ -354,4 +354,40 @@ public:
   virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
 };
 
+/// \class FeaturesPlugin_ValidatorBooleanCommonSelection
+/// \ingroup Validators
+/// \brief Verifies the selected object for boolean common feature
+class FeaturesPlugin_ValidatorBooleanCommonSelection: public ModelAPI_AttributeValidator
+{
+public:
+  //! \return True if the attribute is valid.
+  //! \param[in] theAttribute the checked attribute.
+  //! \param[in] theArguments arguments of the attribute.
+  //! \param[out] theError error message.
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments,
+                       Events_InfoMessage& theError) const;
+};
+
+/** \class FeaturesPlugin_ValidatorBooleanCommonArguments
+*  \ingroup Validators
+*  \brief Validates that boolean operation have enough arguments.
+*/
+class FeaturesPlugin_ValidatorBooleanCommonArguments: public ModelAPI_FeatureValidator
+{
+public:
+  /** \brief Returns true if feature and/or attributes are valid.
+  *  \param[in] theFeature the validated feature.
+  *  \param[in] theArguments the arguments in the configuration file for this validator.
+  *  \param[out] theError error message.
+  *  \returns true if feature is valid.
+  */
+  virtual bool isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                       const std::list<std::string>& theArguments,
+                       Events_InfoMessage& theError) const;
+
+  /// \return true if the attribute in feature is not obligatory for the feature execution.
+  virtual bool isNotObligatory(std::string theFeature, std::string theAttribute);
+};
+
 #endif
diff --git a/src/FeaturesPlugin/Test/Test2394.py b/src/FeaturesPlugin/Test/Test2394.py
deleted file mode 100644 (file)
index 13639bb..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-# -*- coding: utf-8 -*-
-
-## Copyright (C) 2018-20xx  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 GeomAPI import *
-from SketchAPI import *
-
-from salome.shaper import model
-
-model.begin()
-partSet = model.moduleDocument()
-Part_1 = model.addPart(partSet)
-Part_1_doc = Part_1.document()
-
-model.addParameter(Part_1_doc, "R", "58")
-model.addParameter(Part_1_doc, "cote_cube", "R/2")
-model.addParameter(Part_1_doc, "theta", "54")
-model.addParameter(Part_1_doc, "phi", "36")
-model.addParameter(Part_1_doc, "pi", "3.141592653589793")
-model.addParameter(Part_1_doc, "x", "R*sin(phi/180*pi)*cos(theta/180*pi)")
-model.addParameter(Part_1_doc, "y", "R*sin(phi/180*pi)*sin(theta/180*pi)")
-model.addParameter(Part_1_doc, "z", "R*cos(phi/180*pi)")
-model.addParameter(Part_1_doc, "haut_ext_tuyau", "5")
-model.addParameter(Part_1_doc, "haut_int_tuyau", "14")
-Param_Diam = model.addParameter(Part_1_doc, "diam_tuyau", "10")
-
-Revolution_1 = model.addRevolution(Part_1_doc, [], model.selection("EDGE", "PartSet/OZ"), 90, 0)
-Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
-SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
-SketchPoint_1 = SketchProjection_1.createdFeature()
-SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
-SketchLine_1 = SketchProjection_2.createdFeature()
-SketchArc_1 = Sketch_1.addArc(0, 0, 58, 0, 0, -58, True)
-SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
-SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
-SketchLine_2 = Sketch_1.addLine(0, -58, 0, 0)
-SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_2.startPoint())
-SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_2.endPoint())
-SketchLine_3 = Sketch_1.addLine(0, 0, 58, 0)
-SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
-SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_3.endPoint())
-SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
-SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), "R")
-Revolution_1.setNestedSketch(Sketch_1)
-
-Extrusion_1 = model.addExtrusion(Part_1_doc, [], model.selection(), 0, "cote_cube")
-Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face_2"))
-SketchLine_4 = Sketch_2.addLine(29, 0, 0, 0)
-SketchLine_5 = Sketch_2.addLine(0, 0, 0, 29)
-SketchLine_6 = Sketch_2.addLine(0, 29, 29, 29)
-SketchLine_7 = Sketch_2.addLine(29, 29, 29, 0)
-SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_4.startPoint())
-SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
-SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
-SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
-SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_4.result())
-SketchConstraintVertical_2 = Sketch_2.setVertical(SketchLine_5.result())
-SketchConstraintHorizontal_2 = Sketch_2.setHorizontal(SketchLine_6.result())
-SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_7.result())
-SketchConstraintLength_2 = Sketch_2.setLength(SketchLine_6.result(), "cote_cube")
-SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_6.result(), SketchLine_7.result())
-SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "Revolution_1_1/Generated_Face_2&Revolution_1_1/To_Face_1"), False)
-SketchLine_8 = SketchProjection_3.createdFeature()
-SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_8.result())
-SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "Revolution_1_1/Generated_Face_2&Revolution_1_1/From_Face_1"), False)
-SketchLine_9 = SketchProjection_4.createdFeature()
-SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_4.startPoint(), SketchLine_9.result())
-Extrusion_1.setNestedSketch(Sketch_2)
-
-Fill_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("SOLID", "Extrusion_1_1")])
-
-Point_2 = model.addPoint(Part_1_doc, "x", "y", "-z")
-Axis_4 = model.addAxis(Part_1_doc, model.selection("VERTEX", "Point_1"), model.selection("VERTEX", "Fill_1_1_2/Modified_Face_3&Fill_1_1_2/Modified_Face_2&Fill_1_1_2/Modified_Face_1"))
-Plane_4 = model.addPlane(Part_1_doc, model.selection("EDGE", "Axis_1"), model.selection("VERTEX", "Point_1"), True)
-Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Plane_1"), "haut_ext_tuyau", True)
-Plane_5.result().setName("Plane_2 arrivee tuyau")
-Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_1"), 45)
-Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_1"), 45)
-Plane_8 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_4"), "90+45")
-
-Fill_2 = model.addFill(Part_1_doc, [model.selection("SOLID", "Fill_1_1_1")], [model.selection("FACE", "Plane_5")])
-Fill_3 = model.addFill(Part_1_doc, [model.selection("SOLID", "Fill_2_1_2")], [model.selection("FACE", "Plane_3")])
-Fill_4 = model.addFill(Part_1_doc, [model.selection("SOLID", "Fill_3_1_2")], [model.selection("FACE", "Plane_4")])
-Fill_4.result().setColor(102, 51, 51)
-Fill_4.result().subResult(0).setColor(153, 153, 76)
-Fill_4.result().subResult(1).setColor(0, 204, 204)
-Fill_4.result().subResult(2).setColor(51, 51, 102)
-Fill_4.result().subResult(3).setColor(102, 204, 102)
-Fill_4.result().subResult(4).setColor(204, 204, 0)
-
-Union_1 = model.addUnion(Part_1_doc, [model.selection("SOLID", "Fill_4_1_4"), model.selection("SOLID", "Fill_4_1_2")])
-
-Point_3 = model.addPoint(Part_1_doc, model.selection("EDGE", "Axis_1"), model.selection("FACE", "Plane_2 arrivee tuyau"))
-
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_2 arrivee tuyau"))
-SketchProjection_5 = Sketch_3.addProjection(model.selection("VERTEX", "Point_2"), False)
-SketchPoint_2 = SketchProjection_5.createdFeature()
-SketchCircle_1 = Sketch_3.addCircle(0, 0, 10)
-SketchConstraintCoincidence_13 = Sketch_3.setCoincident(SketchPoint_2.result(), SketchCircle_1.center())
-SketchConstraintRadius_1 = Sketch_3.setRadius(SketchCircle_1.results()[1], "diam_tuyau")
-SketchLine_10 = Sketch_3.addLine(-5, 5, 5, 5)
-SketchLine_11 = Sketch_3.addLine(5, 5, 5, -5)
-SketchLine_12 = Sketch_3.addLine(5, -5, -5, -5)
-SketchLine_13 = Sketch_3.addLine(-5, -5, -5, 5)
-SketchConstraintCoincidence_14 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_10.startPoint())
-SketchConstraintCoincidence_15 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
-SketchConstraintCoincidence_16 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
-SketchConstraintCoincidence_17 = Sketch_3.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
-SketchConstraintHorizontal_3 = Sketch_3.setHorizontal(SketchLine_10.result())
-SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_11.result())
-SketchConstraintHorizontal_4 = Sketch_3.setHorizontal(SketchLine_12.result())
-SketchConstraintVertical_5 = Sketch_3.setVertical(SketchLine_13.result())
-SketchConstraintEqual_2 = Sketch_3.setEqual(SketchLine_10.result(), SketchLine_13.result())
-SketchLine_14 = Sketch_3.addLine(5, 5, 7.071067811865479, 7.071067811865475)
-SketchConstraintCoincidence_18 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_14.startPoint())
-SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchCircle_1.results()[1])
-SketchLine_15 = Sketch_3.addLine(-5, -5, -7.071067811865472, -7.071067811865476)
-SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_12.endPoint(), SketchLine_15.startPoint())
-SketchConstraintCoincidence_21 = Sketch_3.setCoincident(SketchLine_15.endPoint(), SketchCircle_1.results()[1])
-SketchConstraintCollinear_1 = Sketch_3.setCollinear(SketchLine_14.result(), SketchLine_15.result())
-SketchLine_16 = Sketch_3.addLine(7.071067811865478, -7.071067811865476, 5, -5)
-SketchConstraintCoincidence_22 = Sketch_3.setCoincident(SketchLine_16.startPoint(), SketchCircle_1.results()[1])
-SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_16.endPoint())
-SketchLine_17 = Sketch_3.addLine(-5, 5, -7.071067811865472, 7.071067811865476)
-SketchConstraintCoincidence_24 = Sketch_3.setCoincident(SketchLine_10.startPoint(), SketchLine_17.startPoint())
-SketchConstraintCoincidence_25 = Sketch_3.setCoincident(SketchLine_17.endPoint(), SketchCircle_1.results()[1])
-SketchConstraintCollinear_2 = Sketch_3.setCollinear(SketchLine_17.result(), SketchLine_16.result())
-SketchConstraintEqual_3 = Sketch_3.setEqual(SketchLine_14.result(), SketchLine_15.result())
-SketchConstraintEqual_4 = Sketch_3.setEqual(SketchLine_17.result(), SketchLine_16.result())
-SketchConstraintLength_3 = Sketch_3.setLength(SketchLine_10.result(), "diam_tuyau")
-model.do()
-
-Extrusion_2_objects = [model.selection("FACE", "Sketch_3/Face-SketchCircle_1_2f-SketchLine_11f-SketchLine_14r-SketchLine_16r"), model.selection("FACE", "Sketch_3/Face-SketchCircle_1_2f-SketchLine_10f-SketchLine_14f-SketchLine_17r"), model.selection("FACE", "Sketch_3/Face-SketchCircle_1_2f-SketchLine_13f-SketchLine_15r-SketchLine_17f"), model.selection("FACE", "Sketch_3/Face-SketchCircle_1_2f-SketchLine_12f-SketchLine_15f-SketchLine_16f")]
-Extrusion_2 = model.addExtrusion(Part_1_doc, Extrusion_2_objects, model.selection(), 10, 0)
-Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_10r-SketchLine_11r-SketchLine_12r-SketchLine_13r")], model.selection(), "haut_int_tuyau", 0)
-
-Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/To_Face_3"))
-SketchProjection_6 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_4&Extrusion_2_1/To_Face_4"), False)
-SketchPoint_3 = SketchProjection_6.createdFeature()
-SketchProjection_7 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/Generated_Face_7&Extrusion_2_1/To_Face_3"), False)
-SketchPoint_4 = SketchProjection_7.createdFeature()
-SketchArc_2 = Sketch_4.addArc(0, 0, -7.071067811865476, -7.071067811865472, 7.071067811865476, 7.071067811865472, True)
-SketchConstraintCoincidence_26 = Sketch_4.setCoincident(SketchPoint_3.result(), SketchArc_2.startPoint())
-SketchConstraintCoincidence_27 = Sketch_4.setCoincident(SketchPoint_4.result(), SketchArc_2.results()[1])
-SketchLine_18 = Sketch_4.addLine(7.071067811865476, 7.071067811865472, -7.071067811865476, -7.071067811865472)
-SketchConstraintCoincidence_28 = Sketch_4.setCoincident(SketchArc_2.endPoint(), SketchLine_18.startPoint())
-SketchConstraintCoincidence_29 = Sketch_4.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_18.endPoint())
-SketchProjection_8 = Sketch_4.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_13&Extrusion_2_1/Generated_Face_12&Extrusion_2_1/To_Face_1"), False)
-SketchPoint_5 = SketchProjection_8.createdFeature()
-SketchConstraintCoincidence_30 = Sketch_4.setCoincident(SketchArc_2.endPoint(), SketchAPI_Point(SketchPoint_5).coordinates())
-model.do()
-
-Revolution_2 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchArc_2_2f-SketchLine_18r")], model.selection("EDGE", "Sketch_4/Edge-SketchLine_18"), 0, 180)
-
-Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_2_1")], [model.selection("SOLID", "Extrusion_3_1")])
-Cut_1.result().setName("demi-sphere")
-
-Plane_9 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_10&Extrusion_2_1/Generated_Face_1&Extrusion_2_1/From_Face_4"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_10&Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_4"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_10&Extrusion_2_1/To_Face_4"))
-Plane_10 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_12&Extrusion_2_1/Generated_Face_11&Extrusion_2_1/To_Face_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_13&Extrusion_2_1/Generated_Face_12&Extrusion_2_1/To_Face_1"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_13&Extrusion_2_1/Generated_Face_12&Extrusion_2_1/From_Face_1"))
-Plane_11 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/Generated_Face_7&Extrusion_2_1/To_Face_3"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_3&Extrusion_2_1/Generated_Face_7&Extrusion_2_1/To_Face_3"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_5&Extrusion_2_1/Generated_Face_7&Extrusion_2_1/From_Face_3"))
-Plane_12 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/Generated_Face_4&Extrusion_2_1/To_Face_4"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_4&Extrusion_2_1/To_Face_4"), model.selection("VERTEX", "Extrusion_2_1/Generated_Face_2&Extrusion_2_1/Generated_Face_4&Extrusion_2_1/From_Face_4"))
-
-Recover_1 = model.addRecover(Part_1_doc, Cut_1, [Extrusion_3.result()])
-
-Plane_13 = model.addPlane(Part_1_doc, model.selection("FACE", "Recover_1_1/Shape4"), model.selection("EDGE", "Recover_1_1/Shape4&Recover_1_1/Shape6"), "90+45")
-Plane_14 = model.addPlane(Part_1_doc, model.selection("FACE", "Recover_1_1/Shape1"), model.selection("EDGE", "Recover_1_1/Shape1&Recover_1_1/Shape6"), "90+45")
-Plane_15 = model.addPlane(Part_1_doc, model.selection("FACE", "Recover_1_1/Shape2"), model.selection("EDGE", "Recover_1_1/Shape2&Recover_1_1/Shape6"), "90+45")
-Plane_16 = model.addPlane(Part_1_doc, model.selection("FACE", "Recover_1_1/Shape6"), model.selection("EDGE", "Recover_1_1/Shape3&Recover_1_1/Shape6"), 45)
-
-Fill_5_objects_2 = [model.selection("FACE", "Plane_6"), model.selection("FACE", "Plane_7"), model.selection("FACE", "Plane_8"), model.selection("FACE", "Plane_9"), model.selection("FACE", "Plane_10"), model.selection("FACE", "Plane_11"), model.selection("FACE", "Plane_12"), model.selection("FACE", "Plane_13")]
-Fill_5 = model.addFill(Part_1_doc, [model.selection("SOLID", "demi-sphere")], Fill_5_objects_2)
-
-Union_2_objects = [model.selection("SOLID", "Fill_5_1_14"), model.selection("SOLID", "Fill_5_1_15"), model.selection("SOLID", "Fill_5_1_16")]
-Union_2 = model.addUnion(Part_1_doc, Union_2_objects)
-Union_3_objects = [model.selection("SOLID", "Fill_5_1_8/Fill_5_1_8"), model.selection("SOLID", "Fill_5_1_4/Fill_5_1_4"), model.selection("SOLID", "Fill_5_1_9/Fill_5_1_9"), model.selection("SOLID", "Fill_5_1_11/Fill_5_1_11")]
-Union_3 = model.addUnion(Part_1_doc, Union_3_objects)
-Union_4_objects = [model.selection("SOLID", "Fill_5_1_6/Fill_5_1_6"), model.selection("SOLID", "Fill_5_1_10/Fill_5_1_10"), model.selection("SOLID", "Fill_5_1_13/Fill_5_1_13")]
-Union_4 = model.addUnion(Part_1_doc, Union_4_objects)
-Union_5_objects = [model.selection("SOLID", "Fill_5_1_2/Fill_5_1_2"), model.selection("SOLID", "Fill_5_1_1/Fill_5_1_1"), model.selection("SOLID", "Fill_5_1_3/Fill_5_1_3")]
-Union_5 = model.addUnion(Part_1_doc, Union_5_objects)
-Union_6_objects = [model.selection("SOLID", "Fill_5_1_5/Fill_5_1_5"), model.selection("SOLID", "Fill_5_1_7/Fill_5_1_7"), model.selection("SOLID", "Fill_5_1_12/Fill_5_1_12")]
-Union_6 = model.addUnion(Part_1_doc, Union_6_objects)
-Union_6.result().setColor(0, 0, 204)
-Union_6.result().subResult(0).setColor(204, 102, 102)
-Union_6.result().subResult(1).setColor(127, 254, 127)
-Union_6.result().subResult(2).setColor(102, 51, 102)
-Union_6.result().subResult(3).setColor(76, 76, 153)
-Union_6.result().subResult(4).setColor(0, 0, 254)
-
-Partition_1_objects = [model.selection("SOLID", "Recover_1_1"), model.selection("COMPSOLID", "Union_1_1"), model.selection("COMPSOLID", "Extrusion_2_1"), model.selection("COMPSOLID", "demi-sphere")]
-Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
-Partition_1.result().setColor(102, 0, 0)
-Partition_1.result().subResult(0).setColor(255, 255, 0)
-Partition_1.result().subResult(1).setColor(0, 254, 0)
-Partition_1.result().subResult(2).setColor(0, 255, 255)
-Partition_1.result().subResult(3).setColor(255, 85, 0)
-Partition_1.result().subResult(4).setColor(153, 0, 0)
-Partition_1.result().subResult(5).setColor(254, 0, 254)
-Partition_1.result().subResult(6).setColor(127, 127, 254)
-Partition_1.result().subResult(7).setColor(102, 204, 102)
-Partition_1.result().subResult(8).setColor(127, 254, 127)
-Partition_1.result().subResult(9).setColor(153, 153, 76)
-Partition_1.result().subResult(10).setColor(204, 102, 102)
-Partition_1.result().subResult(11).setColor(127, 254, 254)
-Partition_1.result().subResult(12).setColor(255, 255, 0)
-Partition_1.result().subResult(13).setColor(102, 51, 102)
-Partition_1.result().subResult(14).setColor(102, 204, 204)
-Partition_1.result().subResult(15).setColor(254, 127, 254)
-Partition_1.result().subResult(16).setColor(153, 153, 0)
-Partition_1.result().subResult(17).setColor(153, 153, 0)
-Partition_1.result().subResult(18).setColor(204, 0, 204)
-
-Folder_1 = model.addFolder(Part_1_doc, Revolution_1, Union_1)
-Folder_2 = model.addFolder(Part_1_doc, Point_3, Union_6)
-model.do()
-
-# check the result
-model.testNbResults(Partition_1, 1)
-model.testNbSubResults(Partition_1, [19])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [19])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [199])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [814])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [1628])
-model.testResultsVolumes(Partition_1, [103867.289635450288187712430953979])
-
-# change parameter and check validity of the result
-Param_Diam.setValue(8)
-model.do()
-
-model.testNbResults(Partition_1, 1)
-model.testNbSubResults(Partition_1, [19])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.SOLID, [19])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.FACE, [191])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.EDGE, [744])
-model.testNbSubShapes(Partition_1, GeomAPI_Shape.VERTEX, [1488])
-model.testResultsVolumes(Partition_1, [103221.354557478349306620657444])
-
-model.end()
-
-#assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/boolean_common_widget.xml b/src/FeaturesPlugin/boolean_common_widget.xml
new file mode 100644 (file)
index 0000000..9065d1e
--- /dev/null
@@ -0,0 +1,64 @@
+<!--
+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>
+-->
+
+<source>
+  <toolbox id="creation_method">
+    <box id="simple"
+     title="Simple"
+     icon="icons/Features/bool_fuse_simple.png">
+      <multi_selector id="main_objects"
+        label="Objects"
+        icon=""
+        tooltip="Select objects"
+        type_choice="vertices edges wires faces shells solids compsolids compounds"
+        use_choice="false"
+        concealment="true">
+        <validator id="FeaturesPlugin_ValidatorBooleanCommonSelection"/>
+      </multi_selector>
+    </box>
+    <box id="advanced"
+     title="advanced"
+     icon="icons/Features/bool_fuse_advanced.png">
+      <multi_selector id="main_objects"
+        label="Main objects"
+        icon=""
+        tooltip="Select objects"
+        type_choice="vertices edges wires faces shells solids compsolids compounds"
+        use_choice="false"
+        concealment="true">
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorBooleanCommonSelection"/>
+      </multi_selector>
+      <multi_selector id="tool_objects"
+        label="Tool objects"
+        icon=""
+        tooltip="Select tools"
+        type_choice="vertices edges wires faces shells solids compsolids compounds"
+        use_choice="false"
+        concealment="true" >
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorBooleanCommonSelection"/>
+      </multi_selector>
+    </box>
+  </toolbox>
+  <validator id="FeaturesPlugin_ValidatorBooleanCommonArguments"
+             parameters="main_objects,tool_objects"/>
+</source>
index 36433dec5f5bbf1543217f2e11ed47d4ff3fa3d7..bb13f70af3184c6c6cd50cc10e6832e59e40cc3c 100644 (file)
@@ -75,7 +75,7 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
       <feature id="Common" title="Common" tooltip="Perform boolean common operation with objects"
                icon="icons/Features/bool_common.png"  helpfile="FeaturesPlugin/commonFeature.html"
                auto_preview="false">
-          <source path="boolean_widget.xml"/>
+          <source path="boolean_common_widget.xml"/>
       </feature>
       <feature id="Smash" title="Smash" tooltip="Perform boolean smash operation with objects"
                icon="icons/Features/bool_smash.png" helpfile="FeaturesPlugin/smashFeature.html"
index b26849dd7b183e6810cd1c0015cdae874caea63d..c9d9524c41610898521dcb5c621638e44d23b201 100644 (file)
 #include <BOPAlgo_BOP.hxx>
 #include <TopTools_ListOfShape.hxx>
 
+//=================================================================================================
+GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
+                                         const GeomShapePtr theTool,
+                                         const OperationType theOperationType)
+{
+  ListOfShape aListWithObject, aListWithTool;
+  aListWithObject.push_back(theObject);
+  aListWithTool.push_back(theTool);
+  build(aListWithObject, aListWithTool, theOperationType);
+}
+
 //=================================================================================================
 GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const ListOfShape& theTools,
index 3cb2d6e9297f8dc2c679097ab7312352eef1dbcd..54a5d9428a870195917546d05739b6c065bb14af 100644 (file)
@@ -41,6 +41,11 @@ public:
 
 public:
 
+  /// Constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
+                                         const GeomShapePtr theTool,
+                                         const OperationType theOperationType);
+
   /// Constructor.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
                                          const ListOfShape& theTools,