Salome HOME
Finalize implementation of filter "F8: On/In/Out a Solid"
authorazv <azv@opencascade.com>
Thu, 4 Jul 2019 07:28:28 +0000 (10:28 +0300)
committerazv <azv@opencascade.com>
Thu, 4 Jul 2019 07:28:28 +0000 (10:28 +0300)
21 files changed:
src/FiltersAPI/CMakeLists.txt
src/FiltersAPI/FiltersAPI.i
src/FiltersAPI/FiltersAPI_Argument.cpp [new file with mode: 0644]
src/FiltersAPI/FiltersAPI_Argument.h [new file with mode: 0644]
src/FiltersAPI/FiltersAPI_Feature.cpp
src/FiltersAPI/FiltersAPI_Filter.cpp
src/FiltersAPI/FiltersAPI_Filter.h
src/FiltersAPI/FiltersAPI_swig.h
src/FiltersPlugin/CMakeLists.txt
src/FiltersPlugin/FiltersPlugin_RelativeToSolid.cpp
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_In.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_InAndOn.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_NotOn.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_On.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_Out.py [new file with mode: 0644]
src/FiltersPlugin/Test/TestFilter_RelativeToSolid_OutAndOn.py [new file with mode: 0644]
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.h [new file with mode: 0644]
src/ModelHighAPI/ModelHighAPI.i
src/PythonAPI/model/tests/tests.py

index f0ff3da6048bb9ca0ee2678c6e84954c6c8e1762..82e244436bb4de4b6d7b0ea830b4349fa8eb13bc 100644 (file)
@@ -21,12 +21,14 @@ INCLUDE(Common)
 
 SET(PROJECT_HEADERS
   FiltersAPI.h
+  FiltersAPI_Argument.h
   FiltersAPI_Feature.h
   FiltersAPI_Filter.h
   FiltersAPI_Selection.h
 )
 
 SET(PROJECT_SOURCES
+  FiltersAPI_Argument.cpp
   FiltersAPI_Feature.cpp
   FiltersAPI_Filter.cpp
   FiltersAPI_Selection.cpp
index 6249bfe4a3ccf07cbd9c75000a756cd7e82b8742..4c0e180848cf7c094eb7036b42c5da610cbfe676 100644 (file)
 %shared_ptr(FiltersAPI_Feature)
 %shared_ptr(FiltersAPI_Filter)
 
+// function with named parameters
+%feature("kwargs") addFilter;
+
+
 // std::list -> []
 %template(FilterList) std::list<std::shared_ptr<FiltersAPI_Filter> >;
+%template(ArgumentList) std::list<FiltersAPI_Argument>;
+
+// fix compilarion error: 'res*' was not declared in this scope
+%typemap(freearg) const std::list<FiltersAPI_Argument> & {}
+
+%typecheck(SWIG_TYPECHECK_POINTER) std::list<FiltersAPI_Argument>, const std::list<FiltersAPI_Argument> & {
+  ModelHighAPI_Selection* temp_selection;
+  std::string* temp_string;
+  int newmem = 0;
+  $1 = 1;
+  if (PySequence_Check($input)) {
+    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+      PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_selection, $descriptor(ModelHighAPI_Selection *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_selection) {
+          $1 = 0;
+        }
+      } else
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_string, $descriptor(std::string *), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_string) {
+          $1 = 0;
+        }
+      } else
+      if (!PyUnicode_Check(item))
+        $1 = 0;
+    }
+  }
+}
+
+%typemap(in) const std::list<FiltersAPI_Argument> & (std::list<FiltersAPI_Argument> temp) {
+  ModelHighAPI_Selection* temp_selection;
+  std::string* temp_string;
+  int newmem = 0;
+  if (PySequence_Check($input)) {
+    for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
+      PyObject * item = PySequence_GetItem($input, i);
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_selection, $descriptor(ModelHighAPI_Selection*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_selection) {
+          PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection or string.");
+          return NULL;
+        }
+        temp.push_back(FiltersAPI_Argument(*temp_selection));
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_selection;
+        }
+      } else
+      if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_string, $descriptor(std::string*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
+        if (!temp_string) {
+          PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection or string.");
+          return NULL;
+        }
+        temp.push_back(FiltersAPI_Argument(*temp_string));
+        if (newmem & SWIG_CAST_NEW_MEMORY) {
+          delete temp_string;
+        }
+      } else
+      if (PyUnicode_Check(item)) {
+        temp.push_back(FiltersAPI_Argument(PyUnicode_AsUTF8(item)));
+      } else {
+        PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection or string.");
+        return NULL;
+      }
+      Py_DECREF(item);
+    }
+    $1 = &temp;
+  } else {
+    PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection or std::string.");
+    return NULL;
+  }
+}
 
-// function with named parameters
-%feature("kwargs") addFilter;
 
 // all supported interfaces
+%include "FiltersAPI_Argument.h"
 %include "FiltersAPI_Feature.h"
 %include "FiltersAPI_Filter.h"
 %include "FiltersAPI_Selection.h"
diff --git a/src/FiltersAPI/FiltersAPI_Argument.cpp b/src/FiltersAPI/FiltersAPI_Argument.cpp
new file mode 100644 (file)
index 0000000..d4c77ab
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2014-2019  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
+//
+
+#include "FiltersAPI_Argument.h"
+
+FiltersAPI_Argument::FiltersAPI_Argument()
+{
+}
+
+FiltersAPI_Argument::FiltersAPI_Argument(const std::string& theValue)
+  : myValue(theValue)
+{
+}
+
+FiltersAPI_Argument::FiltersAPI_Argument(const ModelHighAPI_Selection& theSelection)
+  : mySelection(theSelection)
+{
+}
+
+FiltersAPI_Argument::FiltersAPI_Argument(const AttributeSelectionPtr& theSelection)
+  : mySelectionAttr(theSelection)
+{
+}
+
+FiltersAPI_Argument::~FiltersAPI_Argument()
+{
+}
+
+void FiltersAPI_Argument::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  if (mySelectionAttr)
+    theDumper << mySelectionAttr;
+  else if (mySelection.variantType() == ModelHighAPI_Selection::VT_Empty)
+    theDumper << "\"" << myValue << "\"";
+}
diff --git a/src/FiltersAPI/FiltersAPI_Argument.h b/src/FiltersAPI/FiltersAPI_Argument.h
new file mode 100644 (file)
index 0000000..2e3d210
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2014-2019  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
+//
+
+#ifndef FILTERSAPI_ARGUMENT_H_
+#define FILTERSAPI_ARGUMENT_H_
+
+#include "FiltersAPI.h"
+
+#include <ModelAPI_AttributeSelection.h>
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Selection.h>
+
+/**\class FiltersAPI_Argument
+ * \ingroup CPPHighAPI
+ * \brief Argument of the Filter
+ */
+class FiltersAPI_Argument
+{
+public:
+  FILTERSAPI_EXPORT FiltersAPI_Argument();
+
+  FILTERSAPI_EXPORT
+  FiltersAPI_Argument(const std::string& theValue);
+
+  FILTERSAPI_EXPORT
+  FiltersAPI_Argument(const ModelHighAPI_Selection& theSelection);
+
+  FILTERSAPI_EXPORT
+  FiltersAPI_Argument(const AttributeSelectionPtr& theSelection);
+
+  /// Destructor
+  FILTERSAPI_EXPORT
+  virtual ~FiltersAPI_Argument();
+
+  const std::string& string() const { return myValue; }
+  const ModelHighAPI_Selection& selection() const { return mySelection; }
+
+  /// Dump wrapped feature
+  FILTERSAPI_EXPORT
+  void dump(ModelHighAPI_Dumper& theDumper) const;
+
+private:
+  std::string myValue;
+  ModelHighAPI_Selection mySelection;
+  AttributeSelectionPtr mySelectionAttr;
+};
+
+#endif
index b6646abfdaed7ffac60bff0d6197eaca002c3480..8cd8ebeac395554de241a91f057caec26ea666a7 100644 (file)
@@ -35,6 +35,19 @@ FiltersAPI_Feature::~FiltersAPI_Feature()
 {
 }
 
+static void separateArguments(const std::list<FiltersAPI_Argument>& theArguments,
+                              std::list<ModelHighAPI_Selection>& theSelections,
+                              std::list<std::string>& theTextArgs)
+{
+  std::list<FiltersAPI_Argument>::const_iterator anIt = theArguments.begin();
+  for (; anIt != theArguments.end(); ++anIt) {
+    if (anIt->selection().variantType() != ModelHighAPI_Selection::VT_Empty)
+      theSelections.push_back(anIt->selection());
+    else if (!anIt->string().empty())
+      theTextArgs.push_back(anIt->string());
+  }
+}
+
 void FiltersAPI_Feature::setFilters(const std::list<FilterAPIPtr>& theFilters)
 {
   FiltersFeaturePtr aBase = std::dynamic_pointer_cast<ModelAPI_FiltersFeature>(feature());
@@ -43,21 +56,32 @@ void FiltersAPI_Feature::setFilters(const std::list<FilterAPIPtr>& theFilters)
     aBase->addFilter((*anIt)->name());
     aBase->setReversed((*anIt)->name(), (*anIt)->isReversed());
 
-    const std::list<ModelHighAPI_Selection>& anArgs = (*anIt)->arguments();
+    const std::list<FiltersAPI_Argument>& anArgs = (*anIt)->arguments();
     if (!anArgs.empty()) {
-      // find selectionList argument and fill it
+      // separate selection arguments and strings
+      std::list<ModelHighAPI_Selection> aSelections;
+      std::list<std::string> aTexts;
+      separateArguments(anArgs, aSelections, aTexts);
+
+      // fill arguments of the filter
       std::list<AttributePtr> aFilterArgs = aBase->filterArgs((*anIt)->name());
       for (std::list<AttributePtr>::iterator aFIt = aFilterArgs.begin();
            aFIt != aFilterArgs.end(); ++aFIt) {
         AttributeSelectionListPtr aSelList =
             std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aFIt);
         if (aSelList)
-          fillAttribute(anArgs, aSelList);
+          fillAttribute(aSelections, aSelList);
         else {
           AttributeSelectionPtr aSelection =
               std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aFIt);
-          if (aSelection && anArgs.size() == 1)
-            fillAttribute(anArgs.front(), aSelection);
+          if (aSelection && aSelections.size() == 1)
+            fillAttribute(aSelections.front(), aSelection);
+          else {
+            AttributeStringPtr aString =
+                std::dynamic_pointer_cast<ModelAPI_AttributeString>(*aFIt);
+            if (aString && aTexts.size() == 1)
+              fillAttribute(aTexts.front(), aString);
+          }
         }
       }
     }
index 668a89f7b81f65e8f6440d6b1fb59cfefc741436..0e799e49eab87a8f725b29983f5bb5d960c1dacf 100644 (file)
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeBoolean.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 
 #include <ModelHighAPI_Dumper.h>
 
 FiltersAPI_Filter::FiltersAPI_Filter(
     const std::string& theName,
     const bool theRevertFilter,
-    const std::list<ModelHighAPI_Selection>& theArguments)
+    const std::list<FiltersAPI_Argument>& theArguments)
   : myName(theName), myReversed(theRevertFilter), myFilterArguments(theArguments)
 {
 }
@@ -41,19 +42,33 @@ FiltersAPI_Filter::FiltersAPI_Filter(const std::string& theName,
        anArgIt != theArguments.end(); ++anArgIt) {
     AttributeBooleanPtr aBoolAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(*anArgIt);
-    if (aBoolAttr)
+    if (aBoolAttr) {
       myReversed = aBoolAttr->value();
-    else {
-      AttributeSelectionListPtr aSelList =
-          std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*anArgIt);
-      if (aSelList) {
-        int aSize = aSelList->size();
-        for (int i = 0; i < aSize; ++i) {
-          AttributeSelectionPtr aSelection = aSelList->value(i);
-          myFilterArguments.push_back(
-              ModelHighAPI_Selection(aSelection->context(), aSelection->value()));
-        }
+      continue;
+    }
+
+    AttributeSelectionListPtr aSelList =
+        std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*anArgIt);
+    if (aSelList) {
+      int aSize = aSelList->size();
+      for (int i = 0; i < aSize; ++i) {
+        AttributeSelectionPtr aSelection = aSelList->value(i);
+        myFilterArguments.push_back(FiltersAPI_Argument(aSelection));
       }
+      continue;
+    }
+
+    AttributeSelectionPtr aSelection =
+        std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anArgIt);
+    if (aSelection) {
+      myFilterArguments.push_back(FiltersAPI_Argument(aSelection));
+      continue;
+    }
+
+    AttributeStringPtr aString = std::dynamic_pointer_cast<ModelAPI_AttributeString>(*anArgIt);
+    if (aString) {
+      myFilterArguments.push_back(FiltersAPI_Argument(aString->value()));
+      continue;
     }
   }
 }
@@ -67,15 +82,26 @@ void FiltersAPI_Filter::dump(ModelHighAPI_Dumper& theDumper) const
   theDumper << "model.addFilter(name = \"" << myName << "\"";
   if (myReversed)
     theDumper << ", exclude = " << myReversed;
-  if (!myFilterArguments.empty())
-    theDumper << ", args = []";
+  if (!myFilterArguments.empty()) {
+    theDumper << ", args = [";
+    bool isFirstArg = true;
+    for (std::list<FiltersAPI_Argument>::const_iterator anIt = myFilterArguments.begin();
+         anIt != myFilterArguments.end(); ++anIt) {
+      if (isFirstArg)
+        isFirstArg = false;
+      else
+        theDumper << ", ";
+      anIt->dump(theDumper);
+    }
+    theDumper << "]";
+  }
   theDumper << ")";
 }
 
 // ================================================================================================
 FilterAPIPtr addFilter(const std::string& name,
                        const bool exclude,
-                       const std::list<ModelHighAPI_Selection>& args)
+                       const std::list<FiltersAPI_Argument>& args)
 {
   return FilterAPIPtr(new FiltersAPI_Filter(name, exclude, args));
 }
index 27b576b976b1b87c6ea8ae2d6e6a7f9c2a43d1d8..987592722f164b65bb3c5ee0c8d99f31799d915c 100644 (file)
@@ -21,6 +21,7 @@
 #define FILTERSAPI_FILTER_H_
 
 #include "FiltersAPI.h"
+#include "FiltersAPI_Argument.h"
 
 #include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Selection.h>
@@ -38,7 +39,7 @@ public:
   FiltersAPI_Filter(
       const std::string& theName,
       const bool theRevertFilter = false,
-      const std::list<ModelHighAPI_Selection>& theArguments = std::list<ModelHighAPI_Selection>());
+      const std::list<FiltersAPI_Argument>& theArguments = std::list<FiltersAPI_Argument>());
 
   // Internal constructor based on filter arguments
   FILTERSAPI_EXPORT
@@ -51,7 +52,7 @@ public:
 
   const std::string& name() const { return myName; }
   bool isReversed() const { return myReversed; }
-  const std::list<ModelHighAPI_Selection>& arguments() const { return myFilterArguments; }
+  const std::list<FiltersAPI_Argument>& arguments() const { return myFilterArguments; }
 
   /// Dump wrapped feature
   FILTERSAPI_EXPORT
@@ -60,7 +61,7 @@ public:
 private:
   std::string myName;
   bool myReversed;
-  std::list<ModelHighAPI_Selection> myFilterArguments;
+  std::list<FiltersAPI_Argument> myFilterArguments;
 };
 
 typedef std::shared_ptr<FiltersAPI_Filter> FilterAPIPtr;
@@ -69,6 +70,6 @@ typedef std::shared_ptr<FiltersAPI_Filter> FilterAPIPtr;
 FILTERSAPI_EXPORT FilterAPIPtr
 addFilter(const std::string& name = std::string(),
           const bool exclude = false,
-          const std::list<ModelHighAPI_Selection>& args = std::list<ModelHighAPI_Selection>());
+          const std::list<FiltersAPI_Argument>& args = std::list<FiltersAPI_Argument>());
 
 #endif
index 2681f480169dee0d6f5eb6b9b60cfe84d95a2967..ef45dafc968a79bfaa8a30848860cc886b72e4d0 100644 (file)
@@ -23,6 +23,7 @@
   #include <ModelHighAPI_swig.h>
 
   #include "FiltersAPI.h"
+  #include "FiltersAPI_Argument.h"
   #include "FiltersAPI_Feature.h"
   #include "FiltersAPI_Filter.h"
   #include "FiltersAPI_Selection.h"
index d0c3058264fa8e4943b876cfaf79da7ada0b1ae6..99493128761b5e7e8812f955adc00c1d619c711f 100644 (file)
@@ -54,6 +54,7 @@ SET(PROJECT_LIBRARIES
     Events
     Config
     GeomAPI
+    GeomAlgoAPI
 )
 
 SET(XML_RESOURCES
@@ -70,6 +71,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/Config
   ${PROJECT_SOURCE_DIR}/src/Events
   ${PROJECT_SOURCE_DIR}/src/GeomAPI
+  ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
   ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
 )
 
@@ -86,12 +88,12 @@ ADD_UNIT_TESTS(
   TestFilter_OnPlaneSide_Face.py
   TestFilter_OnPlaneSide_Plane.py
   TestFilter_OppositeToEdge.py
-#  TestFilter_RelativeToSolid_In.py
-#  TestFilter_RelativeToSolid_Out.py
-#  TestFilter_RelativeToSolid_On.py
-#  TestFilter_RelativeToSolid_NotOn.py
-#  TestFilter_RelativeToSolid_InAndOn.py
-#  TestFilter_RelativeToSolid_OutAndOn.py
+  TestFilter_RelativeToSolid_In.py
+  TestFilter_RelativeToSolid_Out.py
+  TestFilter_RelativeToSolid_On.py
+  TestFilter_RelativeToSolid_NotOn.py
+  TestFilter_RelativeToSolid_InAndOn.py
+  TestFilter_RelativeToSolid_OutAndOn.py
   TestFilter_HorizontalFaces.py
   TestFilter_VerticalFaces.py
 )
index 86743520ce5722bd72a6e41593f20394a2709af9..512f66563ec37c1960a8e3886ba8d60c6d2e9a12 100644 (file)
 
 #include "FiltersPlugin_RelativeToSolid.h"
 
+#include <GeomAPI_Solid.h>
+
+#include <GeomAlgoAPI_SolidClassifier.h>
+
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_AttributeString.h>
 
@@ -31,7 +35,41 @@ bool FiltersPlugin_RelativeToSolid::isSupported(GeomAPI_Shape::ShapeType theType
 bool FiltersPlugin_RelativeToSolid::isOk(const GeomShapePtr& theShape,
                                          const ModelAPI_FiltersArgs& theArgs) const
 {
-  return false;
+  AttributePtr anAttr = theArgs.argument("Solid");
+  AttributeSelectionPtr aSel = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(anAttr);
+  if (!aSel)
+    return false;
+
+  anAttr = theArgs.argument("Location");
+  AttributeStringPtr aLocAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(anAttr);
+  if (!aLocAttr)
+    return false;
+  std::string aLocString = aLocAttr->value();
+
+  GeomShapePtr aSolidSelected = aSel->value();
+  if (!aSolidSelected && aSel->context())
+    aSolidSelected = aSel->context()->shape();
+  GeomSolidPtr aSolid = aSolidSelected ? aSolidSelected->solid() : GeomSolidPtr();
+  if (!aSolid)
+    return false;
+
+  GeomAlgoAPI_SolidClassifier aClassifier(aSolid, theShape);
+  GeomAlgoAPI_SolidClassifier::State aState = aClassifier.state();
+
+  bool isOK = false;
+  if (aLocString == "in")
+    isOK = aState == GeomAlgoAPI_SolidClassifier::State_IN;
+  else if (aLocString == "out")
+    isOK = aState == GeomAlgoAPI_SolidClassifier::State_OUT;
+  else if (aLocString == "on")
+    isOK = aState == GeomAlgoAPI_SolidClassifier::State_ON;
+  else if (aLocString == "not_on")
+    isOK = !(aState & GeomAlgoAPI_SolidClassifier::State_ON);
+  else if (aLocString == "not_out")
+    isOK = !(aState & GeomAlgoAPI_SolidClassifier::State_OUT);
+  else if (aLocString == "not_in")
+    isOK = !(aState & GeomAlgoAPI_SolidClassifier::State_IN);
+  return isOK;
 }
 
 static std::string XMLRepresentation =
@@ -46,9 +84,9 @@ static std::string XMLRepresentation =
 "   <case id=\"in\" title=\"In\"/>"
 "   <case id=\"out\" title=\"Out\"/>"
 "   <case id=\"on\" title=\"On\"/>"
-"   <case id=\"noton\" title=\"Not On\"/>"
-"   <case id=\"inon\" title=\"In and On\"/>"
-"   <case id=\"outon\" title=\"On and Out\"/>"
+"   <case id=\"not_on\" title=\"Not On\"/>"
+"   <case id=\"not_out\" title=\"In and On\"/>"
+"   <case id=\"not_in\" title=\"On and Out\"/>"
 " </switch>"
 "</filter>";
 
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_In.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_In.py
new file mode 100644 (file)
index 0000000..69937f8
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "in"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): False,
+    model.selection(Solid2, emptyShape): False,
+    model.selection(Solid3, emptyShape): False,
+    model.selection(Solid4, emptyShape): False,
+    model.selection(Solid5, emptyShape): True,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): False,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): False,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): True,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): False,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): False,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): True,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): False,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_InAndOn.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_InAndOn.py
new file mode 100644 (file)
index 0000000..c3247de
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "not_out"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): True,
+    model.selection(Solid2, emptyShape): False,
+    model.selection(Solid3, emptyShape): False,
+    model.selection(Solid4, emptyShape): True,
+    model.selection(Solid5, emptyShape): True,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): True,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): False,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): True,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): True,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): False,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): True,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): True,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): False,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_NotOn.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_NotOn.py
new file mode 100644 (file)
index 0000000..4c82e35
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "not_on"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): False,
+    model.selection(Solid2, emptyShape): True,
+    model.selection(Solid3, emptyShape): False,
+    model.selection(Solid4, emptyShape): False,
+    model.selection(Solid5, emptyShape): True,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): False,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): True,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): True,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): False,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): False,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): True,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): True,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): True,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): True,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): True,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): True,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_On.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_On.py
new file mode 100644 (file)
index 0000000..aa57cfe
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "on"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): False,
+    model.selection(Solid2, emptyShape): False,
+    model.selection(Solid3, emptyShape): False,
+    model.selection(Solid4, emptyShape): False,
+    model.selection(Solid5, emptyShape): False,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): True,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): False,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): False,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): False,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): False,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): False,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): False,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): False,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_Out.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_Out.py
new file mode 100644 (file)
index 0000000..eeb33a2
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "out"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): False,
+    model.selection(Solid2, emptyShape): True,
+    model.selection(Solid3, emptyShape): False,
+    model.selection(Solid4, emptyShape): False,
+    model.selection(Solid5, emptyShape): False,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): False,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): False,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): True,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): False,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): False,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): False,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): False,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): True,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): False,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): False,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): True,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): True,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
diff --git a/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_OutAndOn.py b/src/FiltersPlugin/Test/TestFilter_RelativeToSolid_OutAndOn.py
new file mode 100644 (file)
index 0000000..6154daa
--- /dev/null
@@ -0,0 +1,197 @@
+# Copyright (C) 2014-2019  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
+#
+
+from SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 20, 0, 0, 20, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchAPI_Line(SketchLine_2).startPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchLine_3 = Sketch_1.addLine(0, 32.83768482493814, 29.63380351263586, 0)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_2.result())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_1.result())
+SketchLine_4 = Sketch_1.addLine(29.63380351263586, 0, 62.471488337574, 29.63380351263586)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(62.471488337574, 29.63380351263586, 32.83768482493814, 62.471488337574)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(32.83768482493814, 62.471488337574, 0, 32.83768482493814)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_6.endPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchLine_3.result(), 22, True)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchLine_7 = Sketch_1.addLine(0, 20, 0, 0)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 20, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_8.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f"), model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_7f-SketchLine_8f")], model.selection(), 30, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(28.24714778717828, 31.38901581881253, 10)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"), False)
+SketchLine_9 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_9.result(), 20, True)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"), False)
+SketchLine_10 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_1.center(), SketchLine_10.result(), 20, True)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchCircle_1_2r_wire")], model.selection(), 10, 0)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 0, 10)
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), -10, 20)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], 50, 10, 10)
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "RelativeToSolid", args = [model.selection("SOLID", "Extrusion_1_1"), "not_in"])])
+model.end()
+
+Solid1 = Extrusion_1.results()[0].resultSubShapePair()[0]
+Solid2 = Extrusion_1.results()[1].resultSubShapePair()[0]
+Solid3 = Extrusion_2.result().resultSubShapePair()[0]
+Solid4 = Extrusion_3.result().resultSubShapePair()[0]
+Solid5 = Extrusion_4.result().resultSubShapePair()[0]
+Solid6 = Translation_1.result().resultSubShapePair()[0]
+
+from GeomAPI import GeomAPI_Shape
+emptyShape = GeomAPI_Shape()
+
+Reference = {
+    # Solids
+    model.selection(Solid1, emptyShape): False,
+    model.selection(Solid2, emptyShape): True,
+    model.selection(Solid3, emptyShape): True,
+    model.selection(Solid4, emptyShape): False,
+    model.selection(Solid5, emptyShape): False,
+    model.selection(Solid6, emptyShape): False,
+
+    # Faces of solid 1
+    model.selection("FACE", "Extrusion_1_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5"): True,
+    model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6"): True,
+    # Faces of solid 2
+    model.selection("FACE", "Extrusion_1_2/To_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/From_Face"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8"): True,
+    model.selection("FACE", "Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2"): True,
+    # Faces of solid 3
+    model.selection("FACE", "Extrusion_2_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/From_Face"): True,
+    model.selection("FACE", "Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2"): True,
+    # Faces of solid 4
+    model.selection("FACE", "Extrusion_3_1/To_Face"): True,
+    model.selection("FACE", "Extrusion_3_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 5
+    model.selection("FACE", "Extrusion_4_1/To_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/From_Face"): False,
+    model.selection("FACE", "Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2"): False,
+    # Faces of solid 6
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_1"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_2"): False,
+    model.selection("FACE", "Translation_1_1/MF:Translated&Cylinder_1_1/Face_3"): False,
+
+    # Edges of solid 1
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6]"): True,
+    # Edges of solid 2
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    # Edges of solid 3
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    model.selection("EDGE", "([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face])([Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face])"): True,
+    # Edges of solid 4
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("EDGE", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face])([Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face])"): False,
+    # Edges of solid 5
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("EDGE", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    model.selection("EDGE", "([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face])([Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face])"): False,
+    # Edges of solid 6
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): False,
+    model.selection("EDGE", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): False,
+    model.selection("EDGE", "([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2])([Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3])"): True,
+
+    # Vertices of solid 1
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_6][Extrusion_1_1/From_Face]"): True,
+    # Vertices of solid 2
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_8][Extrusion_1_2/From_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_1_2/Generated_Face&Sketch_1/SketchArc_1_2][Extrusion_1_2/Generated_Face&Sketch_1/SketchLine_7][Extrusion_1_2/From_Face]"): True,
+    # Vertices of solid 3
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_2_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_2_1/From_Face]"): True,
+    # Vertices of solid 4
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/To_Face]"): True,
+    model.selection("VERTEX", "[Extrusion_3_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_3_1/From_Face]"): False,
+    # Vertices of solid 5
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/To_Face]"): False,
+    model.selection("VERTEX", "[Extrusion_4_1/Generated_Face&Sketch_2/SketchCircle_1_2][Extrusion_4_1/From_Face]"): False,
+    # Vertices of solid 6
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_2]"): True,
+    model.selection("VERTEX", "[Translation_1_1/MF:Translated&Cylinder_1_1/Face_1][Translation_1_1/MF:Translated&Cylinder_1_1/Face_3]"): True,
+}
+model.checkFilter(Part_1_doc, model, Filters, Reference)
index cecaa458f959ec2e12e2b2cc486983fd9dff5a9c..49734838f7897b8faf3fc6959051c7d3daa31362 100644 (file)
@@ -79,6 +79,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_CurveBuilder.h
     GeomAlgoAPI_NExplode.h
     GeomAlgoAPI_Offset.h
+    GeomAlgoAPI_SolidClassifier.h
 )
 
 SET(PROJECT_SOURCES
@@ -137,6 +138,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_CurveBuilder.cpp
     GeomAlgoAPI_NExplode.cpp
     GeomAlgoAPI_Offset.cpp
+    GeomAlgoAPI_SolidClassifier.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.cpp
new file mode 100644 (file)
index 0000000..45533d2
--- /dev/null
@@ -0,0 +1,203 @@
+// Copyright (C) 2014-2019  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
+//
+
+#include "GeomAlgoAPI_SolidClassifier.h"
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Solid.h>
+
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <TopoDS.hxx>
+
+
+static GeomAlgoAPI_SolidClassifier::State stateToState(const TopAbs_State theState)
+{
+  GeomAlgoAPI_SolidClassifier::State aResult;
+  switch (theState)
+  {
+  case TopAbs_IN:
+    aResult = GeomAlgoAPI_SolidClassifier::State_IN;
+    break;
+  case TopAbs_ON:
+    aResult = GeomAlgoAPI_SolidClassifier::State_ON;
+    break;
+  case TopAbs_OUT:
+    aResult = GeomAlgoAPI_SolidClassifier::State_OUT;
+    break;
+  default:
+    aResult = GeomAlgoAPI_SolidClassifier::State_ALL;
+    break;
+  }
+  return aResult;
+}
+
+static GeomAlgoAPI_SolidClassifier::State
+classifyMiddlePoint(BRepClass3d_SolidClassifier& theClassifier,
+                    const GeomShapePtr& theShape,
+                    const double theTolerance)
+{
+  GeomPointPtr aMiddlePoint = theShape->middlePoint();
+  theClassifier.Perform(aMiddlePoint->impl<gp_Pnt>(), theTolerance);
+  return stateToState(theClassifier.State());
+}
+
+static GeomAlgoAPI_SolidClassifier::State
+classifyVertices(BRepClass3d_SolidClassifier& theClassifier,
+                 const GeomShapePtr& theShape,
+                 const double theTolerance)
+{
+  GeomAlgoAPI_SolidClassifier::State aResult = GeomAlgoAPI_SolidClassifier::State_UNKNOWN;
+  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+  for (TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
+       anExp.More() && aResult != GeomAlgoAPI_SolidClassifier::State_ALL;
+       anExp.Next()) {
+    TopoDS_Vertex aCurV = TopoDS::Vertex(anExp.Current());
+    theClassifier.Perform(BRep_Tool::Pnt(aCurV), theTolerance);
+    aResult |= stateToState(theClassifier.State());
+  }
+  return aResult;
+}
+
+static GeomAlgoAPI_SolidClassifier::State
+classifyVicinityOnEdge(BRepClass3d_SolidClassifier& theClassifier,
+                       const TopoDS_Edge& theEdge,
+                       const double theParameter,
+                       const double theTolerance)
+{
+  // coefficient to step out of the vicinity of theParameter
+  static const double THE_STEP_COEFF = 2.0;
+
+  BRepAdaptor_Curve aCurve(theEdge);
+  double aParStep = aCurve.Resolution(theTolerance) * THE_STEP_COEFF;
+  double aParams[2] = { theParameter - aParStep, theParameter + aParStep };
+
+  GeomAlgoAPI_SolidClassifier::State aResult = GeomAlgoAPI_SolidClassifier::State_UNKNOWN;
+  for (double* anIt = std::begin(aParams); anIt != std::end(aParams); ++anIt) {
+    if (*anIt < aCurve.FirstParameter())
+      *anIt = aCurve.FirstParameter();
+    else if (*anIt > aCurve.LastParameter())
+      *anIt = aCurve.LastParameter();
+
+    gp_Pnt aPnt = aCurve.Value(*anIt);
+    theClassifier.Perform(aPnt, theTolerance);
+    aResult |= stateToState(theClassifier.State());
+  }
+  return aResult;
+}
+
+static GeomAlgoAPI_SolidClassifier::State
+classifyVicinityOnFace(BRepClass3d_SolidClassifier& theClassifier,
+                       const TopoDS_Face& theFace,
+                       const double theU,
+                       const double theV,
+                       const double theTolerance)
+{
+  // coefficient to step out of the vicinity of parameters
+  static const double THE_STEP_COEFF = 2.0;
+
+  BRepAdaptor_Surface aSurf(theFace);
+  double aStepU = aSurf.UResolution(theTolerance) * THE_STEP_COEFF;
+  double aStepV = aSurf.VResolution(theTolerance) * THE_STEP_COEFF;
+  double aParamsU[3] = { theU - aStepU, theU, theU + aStepU };
+  double aParamsV[3] = { theV - aStepV, theV, theV + aStepV };
+  for (double* aU = std::begin(aParamsU); aU != std::end(aParamsU); ++aU) {
+    if (*aU < aSurf.FirstUParameter())
+      *aU = aSurf.FirstUParameter();
+    else if (*aU > aSurf.LastUParameter())
+      *aU = aSurf.LastUParameter();
+  }
+  for (double* aV = std::begin(aParamsV); aV != std::end(aParamsV); ++aV) {
+    if (*aV < aSurf.FirstVParameter())
+      *aV = aSurf.FirstVParameter();
+    else if (*aV > aSurf.LastVParameter())
+      *aV = aSurf.LastVParameter();
+  }
+
+  GeomAlgoAPI_SolidClassifier::State aResult = GeomAlgoAPI_SolidClassifier::State_UNKNOWN;
+  for (double* aU = std::begin(aParamsU); aU != std::end(aParamsU); ++aU)
+    for (double* aV = std::begin(aParamsV); aV != std::end(aParamsV); ++aV) {
+      gp_Pnt aPnt = aSurf.Value(*aU, *aV);
+      theClassifier.Perform(aPnt, theTolerance);
+      aResult |= stateToState(theClassifier.State());
+    }
+  return aResult;
+}
+
+static GeomAlgoAPI_SolidClassifier::State
+classifyByDistance(BRepClass3d_SolidClassifier& theClassifier,
+                   const GeomShapePtr& theSolid,
+                   const GeomShapePtr& theShape,
+                   const double theTolerance)
+{
+  GeomAlgoAPI_SolidClassifier::State aResult = GeomAlgoAPI_SolidClassifier::State_UNKNOWN;
+
+  const TopoDS_Shape& aSolid = theSolid->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  for (TopExp_Explorer anExp(aSolid, TopAbs_SHELL); anExp.More(); anExp.Next()) {
+    // compare distance from the shape to the solid's shells
+    BRepExtrema_DistShapeShape aDistance(anExp.Current(), aShape);
+    if (aDistance.Perform() && aDistance.Value() < theTolerance) {
+      aResult |= GeomAlgoAPI_SolidClassifier::State_ON;
+      // classify vicinity of intersection points
+      for (int sol = 1; sol <= aDistance.NbSolution(); ++sol) {
+        if (aDistance.SupportTypeShape2(sol) == BRepExtrema_IsOnEdge) {
+          TopoDS_Edge anEdge = TopoDS::Edge(aDistance.SupportOnShape2(sol));
+          double aParOnEdge;
+          aDistance.ParOnEdgeS2(sol, aParOnEdge);
+
+          aResult |= classifyVicinityOnEdge(theClassifier, anEdge, aParOnEdge, theTolerance);
+        }
+        else if (aDistance.SupportTypeShape2(sol) == BRepExtrema_IsInFace) {
+          TopoDS_Face aFace = TopoDS::Face(aDistance.SupportOnShape2(sol));
+          double aParU, aParV;
+          aDistance.ParOnFaceS2(sol, aParU, aParV);
+
+          aResult |= classifyVicinityOnFace(theClassifier, aFace, aParU, aParV, theTolerance);
+        }
+      }
+    }
+  }
+  return aResult;
+}
+
+
+//==================================================================================================
+GeomAlgoAPI_SolidClassifier::GeomAlgoAPI_SolidClassifier(const GeomSolidPtr theSolid,
+                                                         const GeomShapePtr theShape,
+                                                         const double theTolerance)
+  : myState(State_UNKNOWN)
+{
+  if (!theSolid || !theShape)
+    return;
+
+  BRepClass3d_SolidClassifier aClassifierAlgo(theSolid->impl<TopoDS_Shape>());
+
+  myState = classifyMiddlePoint(aClassifierAlgo, theShape, theTolerance);
+  if (!theShape->isVertex())
+    myState |= classifyVertices(aClassifierAlgo, theShape, theTolerance);
+  myState |= classifyByDistance(aClassifierAlgo, theSolid, theShape, theTolerance);
+
+  if (myState == State_ALL)
+    myState = State_UNKNOWN;
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.h b/src/GeomAlgoAPI/GeomAlgoAPI_SolidClassifier.h
new file mode 100644 (file)
index 0000000..fa8ab25
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2014-2019  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
+//
+
+#ifndef GeomAlgoAPI_SolidClassifier_H_
+#define GeomAlgoAPI_SolidClassifier_H_
+
+#include <GeomAlgoAPI.h>
+
+#include <memory>
+
+class GeomAPI_Shape;
+class GeomAPI_Solid;
+
+/// \class GeomAlgoAPI_SolidClassifier
+/// \ingroup DataAlgo
+/// \brief Classify shape according to the given solid.
+class GeomAlgoAPI_SolidClassifier
+{
+public:
+  typedef int State;
+
+  static const State State_UNKNOWN = 0x0;
+  static const State State_IN      = 0x1;
+  static const State State_ON      = 0x2;
+  static const State State_OUT     = 0x4;
+  static const State State_ALL     = State_IN & State_ON & State_OUT;
+
+public:
+  /// \brief Perform classification of the shape according to the solid.
+  /// \param[in] theSolid       the base solid
+  /// \param[in] theShape       the shape to classify
+  /// \param[in] theTolerance   comparison tolrence
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_SolidClassifier(const std::shared_ptr<GeomAPI_Solid> theSolid,
+                                                 const std::shared_ptr<GeomAPI_Shape> theShape,
+                                                 const double theTolerance = 1.e-7);
+
+  /// \return Classification result.
+  State state() const { return myState; }
+
+private:
+  State myState;
+};
+
+#endif
index 819e7579722715b836ec58a32fadd40d45b3814d..896af71efcf0385e682f72f244454bef69a068dd 100644 (file)
 
 // std::pair -> []
 %template(ResultSubShapePair) std::pair<std::shared_ptr<ModelAPI_Result>, std::shared_ptr<GeomAPI_Shape> >;
+%template(StringsPair) std::pair<std::string, std::string>;
 
 
 // fix compilarion error: 'res*' was not declared in this scope
index 167f5c2bfb0522ee51289605f17c6587f833f9d0..687d2e1bb0c256440fbf26ab2d73c0791ad61cf4 100644 (file)
@@ -340,16 +340,22 @@ def checkFilter(thePartDoc, theModel, theFilter, theShapesList):
   aFiltersFactory = ModelAPI_Session.get().filters()
   for sel, res in theShapesList.items():
     needUndo = False
+    shapeName = ""
+    shapeType = "UNKNOWN"
     if sel.variantType() == ModelHighAPI_Selection.VT_ResultSubShapePair:
       shape = sel.resultSubShapePair()[1]
       if shape.isNull():
         shape = sel.resultSubShapePair()[0].shape()
+        shapeName = sel.name()
+        shapeType = shape.shapeTypeStr()
     else:
       needUndo = True
       theModel.begin()
       subShapeFeature = createSubShape(thePartDoc, theModel, sel)
       theModel.end()
       shape = subShapeFeature.results()[0].resultSubShapePair()[0].shape()
-    assert(aFiltersFactory.isValid(theFilter.feature(), shape) == res)
+      shapeType = sel.typeSubShapeNamePair()[0]
+      shapeName = sel.typeSubShapeNamePair()[1]
+    assert aFiltersFactory.isValid(theFilter.feature(), shape) == res, "Filter result for {} \"{}\" incorrect. Expected {}.".format(shapeType, shapeName, res)
     if needUndo:
       theModel.undo()