Salome HOME
0023193: [CEA] Show sub-shapes with given tolerance
authorskv <skv@opencascade.com>
Tue, 3 Nov 2015 08:38:55 +0000 (11:38 +0300)
committerskv <skv@opencascade.com>
Tue, 3 Nov 2015 08:38:55 +0000 (11:38 +0300)
18 files changed:
doc/salome/gui/GEOM/images/inspect_object.png
doc/salome/gui/GEOM/images/inspect_object2.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/inspect_object_operation.doc [changed mode: 0755->0644]
doc/salome/gui/GEOM/input/tui_test_all.doc
idl/GEOM_Gen.idl
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMImpl/GEOMImpl_IShapesOperations.cxx
src/GEOMImpl/GEOMImpl_IShapesOperations.hxx
src/GEOMUtils/GEOMUtils.cxx
src/GEOMUtils/GEOMUtils.hxx
src/GEOM_I/GEOM_IShapesOperations_i.cc
src/GEOM_I/GEOM_IShapesOperations_i.hh
src/GEOM_SWIG/GEOM_TestAll.py
src/GEOM_SWIG/geomBuilder.py
src/RepairGUI/CMakeLists.txt
src/RepairGUI/RepairGUI.cxx
src/RepairGUI/RepairGUI_InspectObjectDlg.cxx
src/RepairGUI/RepairGUI_InspectObjectDlg.h

index 09d90d0699337e4314fb5409490731e33a5af3f9..23065bd2edba206a5ae4212b65474085ed186a46 100644 (file)
Binary files a/doc/salome/gui/GEOM/images/inspect_object.png and b/doc/salome/gui/GEOM/images/inspect_object.png differ
diff --git a/doc/salome/gui/GEOM/images/inspect_object2.png b/doc/salome/gui/GEOM/images/inspect_object2.png
new file mode 100644 (file)
index 0000000..121e152
Binary files /dev/null and b/doc/salome/gui/GEOM/images/inspect_object2.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 0650bd4..bff2fbd
@@ -6,12 +6,41 @@ This operation allows browsing the contents of the selected shape.
 
 To <b>Inspect Object</b>, in the <b>Main Menu</b> select <b>Measures - > Inspect Object</b>.
 
-\image html inspect_object.png
+The dialog can be used in two modes. The first one is a tree view mode:
+\image html inspect_object.png "Dialog in the tree view mode"
 
-In this dialog:
+This is a default mode that allows to inspect an object in the form of tree
+starting from the shape itself. Its children are its direct sub-shapes that
+have they own children as sub-shapes etc. till most very base sub-shapes,
+i.e. vertices.
+
+The second mode is a filtering one. It is activated when the user selects
+<b>Tolerance filter</b> check box:
+\image html inspect_object2.png "Dialog in the filtering mode"
+
+In this mode the user can check the type of sub-shapes to work with using
+the radio-buttons. The type can be either \b Vertex, \b Edge or \b Face.
+Then the user choses a tolerance criterion to be applied to filter out
+sub-shapes. It is possible to chose one of the following values:
+- \b > - greater than (default value)
+- \b >= - greater than or equal to
+- \b < - lower than
+- \b <= - lower than or equal to
+
+The last parameter to be chosen is the tolerance value. The result is the shapes
+of a certain type that satisfy the defined tolerance criterion. E.g. if the user
+chooses \b Face, criterion \b > and tolerance value equal to \b 1.e-6 the faces
+with the tolerance greater than \b 1.e-6 are displayed.
+
+It is possible to set maximal and minimal value of the tolerance using the
+buttons <b>Max value</b> and <b>Min value</b>. These values are displayed in
+the labels <b>Max :</b> and <b>Min :</b>
+
+In this dialog never mind of its mode it is possible to:
 - Click on the "selection" button and select an object to inspect in the Object Browser or in the viewer.
-- Show/hide sub-shape(s) in the 3D viewer, by pressing “eye” icon in the first column of the tree view.
-- Show/hide all sub-shapes in the 3D viewer, by pressing “eye” icon in the first column of the tree view header.
+- Show/hide sub-shape(s) in the 3D viewer, by pressing "eye" icon in the first column of the tree view.
+- Show/hide all sub-shapes in the tree, by pressing "eye" icon in the first column of the tree view header or
+  by pressing <b>Show all</b>/<b>Hide all</b> buttons.
 - Rename the selected sub-shape by double-clicking on the item or pressing <F2> key.
 - Show the selected sub-shape(s) in the 3D viewer by pressing <b>Show Selected</b> button.
 - Show the selected sub-shape(s) in the 3D viewer and erase all currently shown objects by pressing <b>Show Only Selected</b> button.
@@ -19,4 +48,18 @@ In this dialog:
 - Publish the selected sub-shapes in the study, by pressing <b>Publish Selected</b> button.
 - Close dialog box, by pressing <b>Close</b> button.
 
+\n <b>TUI Command:</b>
+
+A command to filter sub-shapes is defined:
+
+<em>geompy.GetSubShapesWithTolerance(theShape, theShapeType, theCondition, theTolerance),</em> \n
+where \n
+\em theShape is the shape to be exploded. \n
+\em theShapeType is the type of sub-shapes to be returned. Can have
+    the values \b GEOM.FACE, \b GEOM.EDGE and \b GEOM.VERTEX only.\n
+\em theCondition is the condition type (the value of GEOM.comparison_condition emuneration).\n
+\em theTolerance is the tolerance filter.
+
+See also a \ref swig_GetSubShapesWithTolerance "TUI example".
+
 */
index f2407ca29685460eb968d5e6583910dc9dfc3f14..5ed1334a00c422e25c2482809dafd8e1f663e5ea 100644 (file)
 \until geompy.RestoreSubShapes(Partition1)
 
 \anchor swig_GetSubShapeEdgeSorted
+\until geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges")
+
+\anchor swig_GetSubShapesWithTolerance
 \until print "DONE"
 
 */
index 98af123bdfcc18da290c3b0c8c97030c09e1e37e..830fcc3984dfdef42f54e5e4567a932a644e3a86 100644 (file)
@@ -209,6 +209,17 @@ module GEOM
     SI_ALL      // all interferences
   };
 
+  /**
+   * This enumeration represents comparison conditions.
+   */
+  enum comparison_condition
+  {
+    CC_GT, ///< Greater then
+    CC_GE, ///< Greater then or equal to
+    CC_LT, ///< Less then
+    CC_LE  ///< Less then or equal to
+  };
+
  /*!
    * \brief Object creation parameters
    *
@@ -2747,6 +2758,26 @@ module GEOM
     ListOfGO GetSubShapeEdgeSorted (in GEOM_Object theShape,
                                     in GEOM_Object theStartPoint);
 
+    /*!
+     * \brief Return the list of subshapes that satisfies a certain tolerance
+     * criterion. The user defines the type of shapes to be returned, the
+     * condition and the tolerance value. The operation is defined for
+     * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition
+     * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape
+     * that have tolerances greater then 1.e7.
+     *
+     * \param theShape the shape to be exploded
+     * \param theShapeType the type of shapes to be returned. Can have the
+     *        values FACE, EDGE and VERTEX only.
+     * \param theCondition the condition type.
+     * \param theTolerance the tolerance filter.
+     * \return the list of shapes that satisfy the conditions.
+     */
+    ListOfGO GetSubShapesWithTolerance(in GEOM_Object          theShape,
+                                       in short                theShapeType,
+                                       in comparison_condition theCondition,
+                                       in double               theTolerance);
+
   };
 
  // # GEOM_IBlocksOperations: 
index 491d964f84abd7a51aa2548739a4e357776ddf8d..2f225edbdfc22452eeecfecae315cd2c05525567 100644 (file)
@@ -5440,6 +5440,14 @@ shells and solids on the other hand.</translation>
         <source>GEOM_DIM_AXES</source>
         <translation>Dimensions along local axes</translation>
     </message>
+    <message>
+        <source>SHOW_ALL_BTN</source>
+        <translation>Show all</translation>
+    </message>
+    <message>
+        <source>HIDE_ALL_BTN</source>
+        <translation>Hide all</translation>
+    </message>
 </context>
 <context>
     <name>GeometryGUI</name>
@@ -6507,14 +6515,6 @@ Number of sketch points too small</translation>
         <source>REMOVE_BTN</source>
         <translation>Remove</translation>
     </message>
-    <message>
-        <source>SHOW_ALL_BTN</source>
-        <translation>Show all</translation>
-    </message>
-    <message>
-        <source>HIDE_ALL_BTN</source>
-        <translation>Hide all</translation>
-    </message>
     <message>
         <source>DISTANCE_ITEM</source>
         <translation>Distance</translation>
@@ -7231,7 +7231,19 @@ Do you want to create new material?</translation>
         <translation>Main shape</translation>
     </message>
     <message>
-        <source>GEOM_INSPECT_OBJECT_SHOW</source>
+      <source>GEOM_INSPECT_TOLERANCE_FILTER</source>
+      <translation>Tolerance filter</translation>
+    </message>
+    <message>
+      <source>GEOM_INSPECT_RESET_MIN</source>
+      <translation>Min value</translation>
+    </message>
+    <message>
+      <source>GEOM_INSPECT_RESET_MAX</source>
+      <translation>Max value</translation>
+    </message>
+    <message>
+      <source>GEOM_INSPECT_OBJECT_SHOW</source>
         <translation>Show Selected</translation>
     </message>
     <message>
index 96c8e49b159408c40b2616a734d7ca9e61c98bd0..3ed4513ecd8181068f80fe7d1710f8d0a9fd8d12 100644 (file)
@@ -3062,6 +3062,106 @@ Handle(TColStd_HSequenceOfTransient)
   return aSeq;
 }
 
+//=============================================================================
+/*!
+ *  GetSubShapesWithTolerance
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient)
+    GEOMImpl_IShapesOperations::GetSubShapesWithTolerance
+                     (const Handle(GEOM_Object)            &theShape,
+                      const Standard_Integer                theShapeType,
+                      const GEOMUtils::ComparisonCondition  theCondition,
+                      const Standard_Real                   theTolerance)
+{
+  if (theShape.IsNull()) {
+    SetErrorCode("NULL GEOM object");
+    return NULL;
+  }
+
+  TopoDS_Shape aShape = theShape->GetValue();
+
+  if (aShape.IsNull()) {
+    SetErrorCode("NULL Shape");
+    return NULL;
+  }
+
+  if (theShapeType != TopAbs_FACE && theShapeType != TopAbs_EDGE &&
+      theShapeType != TopAbs_VERTEX && aShape.ShapeType() >= theShapeType) {
+    SetErrorCode("Invalid shape type");
+    return NULL;
+  }
+
+  TopTools_IndexedMapOfShape         anIndices;
+  TopTools_MapOfShape                aMapFence;
+  TopExp_Explorer                    anExp(aShape,
+                                           (TopAbs_ShapeEnum) theShapeType);
+  Handle(TColStd_HSequenceOfInteger) anIDs = new TColStd_HSequenceOfInteger;
+
+  TopExp::MapShapes(aShape, anIndices);
+
+  for (; anExp.More(); anExp.Next()) {
+    const TopoDS_Shape &aSubShape = anExp.Current();
+
+    if (aMapFence.Add(aSubShape)) {
+      // Compute tolerance
+      Standard_Real aTolerance = -1.;
+
+      switch (aSubShape.ShapeType()) {
+        case TopAbs_FACE:
+          aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape));
+          break;
+        case TopAbs_EDGE:
+          aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape));
+          break;
+        case TopAbs_VERTEX:
+          aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape));
+          break;
+        default:
+          break;
+      }
+
+      if (aTolerance < 0.) {
+        continue;
+      }
+
+      // Compare the tolerance with reference value.
+      if (GEOMUtils::IsFitCondition (theCondition, aTolerance, theTolerance)) {
+        anIDs->Append(anIndices.FindIndex(aSubShape));
+      }
+    }
+  }
+
+  if (anIDs->IsEmpty()) {
+    SetErrorCode("Empty sequence of sub-shapes");
+    return NULL;
+  }
+
+  // Get objects by indices.
+  TCollection_AsciiString              anAsciiList;
+  Handle(TColStd_HSequenceOfTransient) aSeq =
+    getObjectsShapesOn(theShape, anIDs, anAsciiList);
+
+  if (aSeq.IsNull() || aSeq->IsEmpty()) {
+    SetErrorCode("Empty sequence of edges");
+    return NULL;
+  }
+
+  // Make a Python command
+  Handle(GEOM_Object)   anObj     =
+    Handle(GEOM_Object)::DownCast(aSeq->Value(1));
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction)
+    << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapesWithTolerance("
+    << theShape << ", " << theShapeType << ", " << theCondition << ", "
+    << theTolerance << ")";
+
+  SetErrorCode(OK);
+
+  return aSeq;
+}
+
 //=======================================================================
 //function : getShapesOnSurfaceIDs
   /*!
index 795a55d1b0af24729adb3aca433db0cca6aef022..5078a386a8b68d47acc6d5ff8a28e78e2760492b 100644 (file)
@@ -33,6 +33,7 @@
 #include "GEOM_IOperations.hxx"
 
 #include "GEOMAlgo_State.hxx"
+#include "GEOMUtils.hxx"
 
 #include <TColStd_HSequenceOfTransient.hxx>
 #include <TColStd_HSequenceOfInteger.hxx>
@@ -448,6 +449,27 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
     GetSubShapeEdgeSorted (const Handle(GEOM_Object) &theShape,
                            const Handle(GEOM_Object) &theStartPoint);
 
+  /*!
+   * \brief Return the list of subshapes that satisfies a certain tolerance
+   * criterion. The user defines the type of shapes to be returned, the
+   * condition and the tolerance value. The operation is defined for
+   * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition
+   * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape
+   * that have tolerances greater then 1.e7.
+   *
+   * \param theShape the shape to be exploded
+   * \param theShapeType the type of shapes to be returned. Can have the
+   *        values FACE, EDGE and VERTEX only.
+   * \param theCondition the condition type.
+   * \param theTolerance the tolerance filter.
+   * \return the list of shapes that satisfy the conditions.
+   */
+  Handle(TColStd_HSequenceOfTransient) GetSubShapesWithTolerance
+                     (const Handle(GEOM_Object)            &theShape,
+                      const Standard_Integer                theShapeType,
+                      const GEOMUtils::ComparisonCondition  theCondition,
+                      const Standard_Real                   theTolerance);
+
  private:
   Handle(GEOM_Object) MakeShape (std::list<Handle(GEOM_Object)>      theShapes,
                                  const Standard_Integer         theObjectType,
index 3e0b18977de279e5b07a1e1e15efad56bcf371f2..c359c25676034168ea8bb651a3c41c5d9db17964 100644 (file)
 
 #define STD_SORT_ALGO 1
 
+#define DEFAULT_TOLERANCE_TOLERANCE     1.e-02
+#define DEFAULT_MAX_TOLERANCE_TOLERANCE 1.e-06
+
 // When the following macro is defined, ShapeFix_ShapeTolerance function is used to set max tolerance of curve
 // in GEOMUtils::FixShapeCurves function; otherwise less restrictive BRep_Builder::UpdateEdge/UpdateVertex
 // approach is used
@@ -1287,3 +1290,55 @@ bool GEOMUtils::IsOpenPath(const TopoDS_Shape &theShape)
 
   return isOpen;
 }
+
+//=======================================================================
+//function : CompareToleranceValues
+//purpose  : 
+//=======================================================================
+int GEOMUtils::CompareToleranceValues(const double theTolShape,
+                                      const double theTolRef)
+{
+  const double aTolTol = Min(DEFAULT_MAX_TOLERANCE_TOLERANCE,
+                             theTolRef*DEFAULT_TOLERANCE_TOLERANCE);
+
+  int aResult = 0;
+
+  if (theTolShape < theTolRef - aTolTol) {
+    aResult = -1;
+  } else if (theTolShape > theTolRef + aTolTol) {
+    aResult = 1;
+  }
+
+  return aResult;
+}
+
+//=======================================================================
+//function : IsFitCondition
+//purpose  : 
+//=======================================================================
+bool GEOMUtils::IsFitCondition(const ComparisonCondition theCondition,
+                               const double              theTolShape,
+                               const double              theTolRef)
+{
+  const int aCompValue = CompareToleranceValues(theTolShape, theTolRef);
+  bool      isFit      = false;
+
+  switch (theCondition) {
+    case CC_GT:
+      isFit = aCompValue == 1;
+      break;
+    case GEOMUtils::CC_GE:
+      isFit = aCompValue != -1;
+      break;
+    case GEOMUtils::CC_LT:
+      isFit = aCompValue == -1;
+      break;
+    case GEOMUtils::CC_LE:
+      isFit = aCompValue != 1;
+      break;
+    default:
+      break;
+  }
+
+  return isFit;
+}
index 8ffa25be2e10bb75ad3e2e2b9ed592c14d4b542d..184bc970395e4286397f2e9e10cac776ca343f65 100644 (file)
@@ -55,6 +55,16 @@ inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
 namespace GEOMUtils
 {
 
+  /**
+   * This enumeration represents comparison conditions.
+   */
+  enum ComparisonCondition {
+    CC_GT, ///< Greater then
+    CC_GE, ///< Greater then or equal to
+    CC_LT, ///< Less then
+    CC_LE  ///< Less then or equal to
+  };
+
   typedef std::vector<std::string> NodeLinks;
   typedef std::map<std::string, NodeLinks> LevelInfo;
   typedef std::vector<LevelInfo> LevelsList;
@@ -341,6 +351,36 @@ namespace GEOMUtils
    */
   Standard_EXPORT bool IsOpenPath(const TopoDS_Shape &theShape);
 
+  /**
+   * This function compares two tolerances. The shape tolerance (the first
+   * argument) is considered less than the reference tolerance (the second
+   * argument) if theTolShape < theTolRef - Tolerance(theTolRef). theTolShape is
+   * considered greater than theTolRef if theTolShape > theTolRef +
+   * Tolerance(theTolRef). Otherwise these tolerances are equal.
+   * Tolerance(theTolRef) = theTolRef*DEFAULT_TOLERANCE_TOLERANCE. But this value
+   * should not be greated than DEFAULT_MAX_TOLERANCE_TOLERANCE.
+   *
+   * \param theTolShape the shape tolerance
+   * \param theTolRef the reference tolerance
+   * \return -1 if theTolShape is less than theTolRef; 1 if theTolShape is greater
+   * than theTolRef; 0 if they are equal
+   */
+  Standard_EXPORT int CompareToleranceValues(const double theTolShape,
+                                             const double theTolRef);
+
+  /**
+   * Check if the comarison of tolerances fit the condition. The comparison of
+   * tolerances is performed using the function CompareToleranceValues.
+   *
+   * \param theCondition the condition
+   * \param theTolShape the shape tolerance
+   * \param theTolRef the reference tolerance
+   * \return true if the shape tolerance fits the condition; false otherwise.
+   */
+  Standard_EXPORT bool IsFitCondition(const ComparisonCondition theCondition,
+                                      const double              theTolShape,
+                                      const double              theTolRef);
+
 };
 
 #endif
index 1e88b88f904adebcd032ecf817d7cb1316ef6ab0..7561d9a168461e0fe90191c2214a5d216ddc28d9 100644 (file)
 #include <TColStd_HSequenceOfTransient.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 
+/**
+ * This function converts GEOM::comparison_condition type into
+ * GEOMUtils::ComparisonCondition type.
+ *
+ * \param theCondition the condition of GEOM::comparison_condition type
+ * \return the condition of GEOMUtils::ComparisonCondition type.
+ */
+static GEOMUtils::ComparisonCondition ComparisonCondition
+                    (const GEOM::comparison_condition theCondition)
+{
+  GEOMUtils::ComparisonCondition aResult = GEOMUtils::CC_GT;
+
+  switch (theCondition) {
+  case GEOM::CC_GE:
+    aResult = GEOMUtils::CC_GE;
+    break;
+  case GEOM::CC_LT:
+    aResult = GEOMUtils::CC_LT;
+    break;
+  case GEOM::CC_LE:
+    aResult = GEOMUtils::CC_LE;
+    break;
+  default:
+    break;
+  }
+
+  return aResult;
+}
+
 //=============================================================================
 /*!
  *   constructor:
@@ -2156,3 +2185,48 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapeEdgeSorted
 
   return aSeq._retn();
 }
+
+//=============================================================================
+/*!
+ *  GetSubShapesWithTolerance
+ */
+//=============================================================================
+GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapesWithTolerance
+                     (GEOM::GEOM_Object_ptr      theShape,
+                      CORBA::Short               theShapeType,
+                      GEOM::comparison_condition theCondition,
+                      CORBA::Double              theTolerance)
+{
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  //Get the reference objects
+  Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
+
+  if (aShape.IsNull()) {
+    return aSeq._retn();
+  }
+
+  //Get Shapes On Shape
+  const GEOMUtils::ComparisonCondition aCondition =
+                ComparisonCondition(theCondition);
+  Handle(TColStd_HSequenceOfTransient) aHSeq      =
+      GetOperations()->GetSubShapesWithTolerance
+                (aShape, theShapeType, aCondition, theTolerance);
+
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  const Standard_Integer aLength = aHSeq->Length();
+  Standard_Integer       i;
+
+  aSeq->length(aLength);
+
+  for (i = 1; i <= aLength; i++) {
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+  }
+
+  return aSeq._retn();
+}
index f8dba7caf27354646c0b10cb899469831d97a535..0f36a38c3934aea05221cb243be714a0b59c1fd2 100644 (file)
@@ -300,6 +300,12 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i :
   GEOM::ListOfGO* GetSubShapeEdgeSorted (GEOM::GEOM_Object_ptr theShape,
                                          GEOM::GEOM_Object_ptr theStartPoint);
 
+  GEOM::ListOfGO* GetSubShapesWithTolerance
+                     (GEOM::GEOM_Object_ptr      theShape,
+                      CORBA::Short               theShapeType,
+                      GEOM::comparison_condition theCondition,
+                      CORBA::Double              theTolerance);
+
   ::GEOMImpl_IShapesOperations* GetOperations()
   { return (::GEOMImpl_IShapesOperations*)GetImpl(); }
 };
index 683918508d443c7bd99d9b868e9f39194bb8654f..ea862293f2ab957bf8dfbef186691895e3e96ed7 100644 (file)
@@ -584,5 +584,11 @@ def TestAll (geompy, math):
   geompy.GetSubShapeEdgeSorted(Sketcher3d_1, p2, "OrderedEdges")
   geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges")
 
+  # GetSubShapesWithTolerance
+  geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GT, 1.e-8, "gt")
+  geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GE, 1.e-7, "ge")
+  geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LT, 2.e-7, "lt")
+  geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LE, 1.e-7, "le")
+
 
   print "DONE"
index 46573011e832db7b49ca4cd35c3471b2bb99ad62..16e9ea4caaf52505634d018bf378a14720974106 100644 (file)
@@ -6574,6 +6574,57 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             self._autoPublish(ListObj, theName, "SortedEdges")
             return ListObj
 
+        ##
+        # Return the list of subshapes that satisfies a certain tolerance
+        # criterion. The user defines the type of shapes to be returned, the
+        # condition and the tolerance value. The operation is defined for
+        # faces, edges and vertices only. E.g. for theShapeType FACE,
+        # theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns
+        # all faces of theShape that have tolerances greater then 1.e7.
+        #
+        #  @param theShape the shape to be exploded
+        #  @param theShapeType the type of sub-shapes to be returned (see
+        #         ShapeType()). Can have the values FACE, EDGE and VERTEX only.
+        #  @param theCondition the condition type (see GEOM::comparison_condition).
+        #  @param theTolerance the tolerance filter.
+        #  @param theName Object name; when specified, this parameter is used
+        #         for result publication in the study. Otherwise, if automatic
+        #         publication is switched on, default value is used for result name.
+        #  @return the list of shapes that satisfy the conditions.
+        #
+        #  @ref swig_GetSubShapesWithTolerance "Example"
+        @ManageTransactions("ShapesOp")
+        def GetSubShapesWithTolerance(self, theShape, theShapeType,
+                                      theCondition, theTolerance, theName=None):
+            """
+            Return the list of subshapes that satisfies a certain tolerance
+            criterion. The user defines the type of shapes to be returned, the
+            condition and the tolerance value. The operation is defined for
+            faces, edges and vertices only. E.g. for theShapeType FACE,
+            theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns
+            all faces of theShape that have tolerances greater then 1.e7.
+            
+            Parameters:
+                theShape the shape to be exploded
+                theShapeType the type of sub-shapes to be returned (see
+                             ShapeType()). Can have the values FACE,
+                             EDGE and VERTEX only.
+                theCondition the condition type (see GEOM::comparison_condition).
+                theTolerance the tolerance filter.
+                theName Object name; when specified, this parameter is used
+                        for result publication in the study. Otherwise, if automatic
+                        publication is switched on, default value is used for result name.
+
+            Returns:
+                The list of shapes that satisfy the conditions.
+            """
+            # Example: see GEOM_TestAll.py
+            ListObj = self.ShapesOp.GetSubShapesWithTolerance(theShape, EnumToLong(theShapeType),
+                                                              theCondition, theTolerance)
+            RaiseIfFailed("GetSubShapesWithTolerance", self.ShapesOp)
+            self._autoPublish(ListObj, theName, "SubShapeWithTolerance")
+            return ListObj
+
         ## Check if the object is a sub-object of another GEOM object.
         #  @param aSubObject Checked sub-object (or its parent object, in case if
         #         \a theSubObjectIndex is non-zero).
index 34310cf4c0a697bd8362d1d310363ac9423e2dee..d9ae6fa297036529162433dab71a0711127fe2bc 100755 (executable)
@@ -41,6 +41,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/DlgRef
   ${PROJECT_BINARY_DIR}/src/DlgRef
   ${PROJECT_SOURCE_DIR}/src/GEOMAlgo
+  ${PROJECT_SOURCE_DIR}/src/GEOMUtils
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}
   )
@@ -55,6 +56,7 @@ ADD_DEFINITIONS(
 # libraries to link to
 SET(_link_LIBRARIES
   GEOMBase
+  GEOMUtils
   )
 
 # --- resources ---
index 6c177ab85bee6602a3793f7b925a6a9affae9f57..3eadcbe21d4c10477ba42b2e13410002cf991c93 100644 (file)
@@ -98,7 +98,7 @@ bool RepairGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
   case GEOMOp::OpRemoveExtraEdges: aDlg = new RepairGUI_RemoveExtraEdgesDlg  (getGeometryGUI(), parent); break;
   case GEOMOp::OpFuseEdges:        aDlg = new RepairGUI_FuseEdgesDlg         (getGeometryGUI(), parent); break;
   case GEOMOp::OpUnionFaces:       aDlg = new RepairGUI_UnionFacesDlg        (getGeometryGUI(), parent); break;
-  case GEOMOp::OpInspectObj:       aDlg = new RepairGUI_InspectObjectDlg     (parent); break;
+  case GEOMOp::OpInspectObj:       aDlg = new RepairGUI_InspectObjectDlg     (getGeometryGUI(), parent); break;
   default:
     app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
     break;
index e0c5ef0ba1b977fe81945d7a963de4ccb3b10ab7..a66f9c18edb8ff46ca807b4aa2f72d589f16bc49 100644 (file)
@@ -24,6 +24,7 @@
 #include <GEOMBase.h>
 #include <GEOM_Constants.h>
 #include <GeometryGUI.h>
+#include <GEOMUtils.hxx>
 
 // GUI includes
 #include <SUIT_Session.h>
 #include <LightApp_SelectionMgr.h>
 
 #include <SalomeApp_Application.h>
+#include <SalomeApp_DoubleSpinBox.h>
 #include <SalomeApp_Study.h>
 
 #include <OCCViewer_ViewModel.h>
 #include <SVTK_ViewModel.h>
 
 // OCCT includes
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
 #include <TopoDS_Iterator.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 // Qt includes
+#include <QButtonGroup>
+#include <QComboBox>
 #include <QGridLayout>
+#include <QGroupBox>
 #include <QPushButton>
 #include <QHeaderView>
 #include <QItemDelegate>
+#include <QLineEdit>
+#include <QRadioButton>
+#include <QStackedLayout>
+#include <QTreeWidgetItem>
+
+// Shape type definitions (values are equal to corresponding types of TopAbs_ShapeEnum).
+#define TYPE_FACE   4
+#define TYPE_EDGE   6
+#define TYPE_VERTEX 7
+
+// Comparison type definitions
+#define COMPARE_GT 0
+#define COMPARE_GE 1
+#define COMPARE_LT 2
+#define COMPARE_LE 3
+
+// Default tolerance values
+#define DEFAULT_TOLERANCE_VALUE         1.e-07
 
 //=================================================================================
 // class    : RepairGUI_InspectObjectDlg::TreeWidgetItem
 class RepairGUI_InspectObjectDlg::TreeWidgetItem : public QTreeWidgetItem
 {
 public:
-  TreeWidgetItem( QTreeWidget*, const QStringList&, const TopoDS_Shape&, const Handle(SALOME_InteractiveObject)&, int = Type );
-  TreeWidgetItem( QTreeWidgetItem*, const QStringList&, const TopoDS_Shape&, const QString&, int = Type );
+  TreeWidgetItem(QTreeWidget*,
+                 const QStringList&,
+                 const TopoDS_Shape&,
+                 const Handle(SALOME_InteractiveObject)&,
+                 double = DEFAULT_TOLERANCE_VALUE,
+                 int = Type);
+
+  TreeWidgetItem(QTreeWidgetItem*,
+                 const QStringList&,
+                 const TopoDS_Shape&,
+                 const QString&,
+                 double = DEFAULT_TOLERANCE_VALUE,
+                 int = Type);
+
   ~TreeWidgetItem();
 
   bool                             isVisible();
@@ -66,27 +107,43 @@ public:
   TopoDS_Shape                     getShape() const;
   Handle(SALOME_InteractiveObject) getIO() const;
 
+  double                           getTolerance() const;
+  void                             setTolerance(double theTolerance);
+
 private:
   bool                             myIsVisible;
   TopoDS_Shape                     myShape;
   Handle(SALOME_InteractiveObject) myIO;
+  double                           myTolerance;
 
 };
 
-RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidget* view, const QStringList &strings, const TopoDS_Shape& shape,
-                                                            const Handle(SALOME_InteractiveObject)& io, int type )
+RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem
+                     (QTreeWidget                            *view,
+                      const QStringList                      &strings,
+                      const TopoDS_Shape                     &shape,
+                      const Handle(SALOME_InteractiveObject) &io,
+                      double                                  theTolerance,
+                      int                                     type)
 : QTreeWidgetItem( view, strings, type ),
   myIsVisible( false ),
   myShape( shape ),
-  myIO( io )
+  myIO( io ),
+  myTolerance (theTolerance)
 {
 }
 
-RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings,
-                                                            const TopoDS_Shape& shape, const QString& entry, int type )
+RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem
+                     (QTreeWidgetItem    *parent,
+                      const QStringList  &strings,
+                      const TopoDS_Shape &shape,
+                      const QString      &entry,
+                      double              theTolerance,
+                      int                 type)
 : QTreeWidgetItem( parent, strings, type ),
   myIsVisible( false ),
-  myShape( shape )
+  myShape( shape ),
+  myTolerance (theTolerance)
 {
   myIO = new SALOME_InteractiveObject( entry.toAscii(), "GEOM", "TEMP_IO" );
   setFlags( flags() | Qt::ItemIsEditable );
@@ -117,6 +174,16 @@ Handle(SALOME_InteractiveObject) RepairGUI_InspectObjectDlg::TreeWidgetItem::get
   return myIO;
 }
 
+double RepairGUI_InspectObjectDlg::TreeWidgetItem::getTolerance() const
+{
+  return myTolerance;
+}
+
+void RepairGUI_InspectObjectDlg::TreeWidgetItem::setTolerance(double theTolerance)
+{
+  myTolerance = theTolerance;
+}
+
 //=================================================================================
 // class    : RepairGUI_InspectObjectDlg::Delegate
 // purpose  : class for "Inspect Object" tree item editing
@@ -169,120 +236,156 @@ QWidget* RepairGUI_InspectObjectDlg::Delegate::createEditor( QWidget* parent,
 // class    : RepairGUI_InspectObjectDlg()
 // purpose  : Constructs a RepairGUI_InspectObjectDlg which is a child of 'parent'.
 //=================================================================================
-RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg( SUIT_Desktop* parent )
-: GEOMBase_Helper( parent ),
-  QDialog( parent ),
-  myTransparency( 0.0 ),
-  myIsSelectAll( false )
+RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg(GeometryGUI *theGeomGUI, SUIT_Desktop* parent )
+: GEOMBase_Helper       (parent),
+  QDialog               (parent),
+  myGeomGUI             (theGeomGUI),
+  myTreeObjects         (0),
+  myFilteredTreeObjects (0),
+  myCurrentTreeObjects  (0),
+  myEditMainShape       (0),
+  myTolFilterGrp        (0),
+  myShapeTypeBtnGrp     (0),
+  myComparisonCompo     (0),
+  myMinTolValLabel      (0),
+  myMaxTolValLabel      (0),
+  myTolEdit             (0),
+  myTreesLayout         (0),
+  myTransparency        (0.0),
+  myIsSelectAll         (false),
+  myMaxTol              (-1.),
+  myMinTol              (-1.)
 {
-  QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
-  myVisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
-  myInvisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  QIcon iconSelect( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
+  myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
+  myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
+
+  QPixmap anImageVtx(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX")));
+  QPixmap anImageEdge(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_EDGE")));
+  QPixmap anImageFace(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_FACE")));
 
   setWindowTitle( tr( "GEOM_INSPECT_OBJECT_TITLE" ) );
   setAttribute( Qt::WA_DeleteOnClose );
 
-  myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
-  myViewWindow = myApp->desktop()->activeWindow();
+  myViewWindow = myGeomGUI->getApp()->desktop()->activeWindow();
 
   QGridLayout* topLayout = new QGridLayout( this );
   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
 
   /**********************   Inspected Object    **********************/
 
-  QHBoxLayout* mainShapeLayout = new QHBoxLayout();
+  QHBoxLayout* mainShapeLayout = new QHBoxLayout(this);
 
-  QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ) );
-  QPushButton* selBtn = new QPushButton();
+  QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ), this );
+  QPushButton* selBtn = new QPushButton(this);
   selBtn->setIcon( iconSelect );
-  myEditMainShape = new QLineEdit();
+  myEditMainShape = new QLineEdit(this);
   myEditMainShape->setReadOnly(true);
 
   mainShapeLayout->addWidget( label );
   mainShapeLayout->addWidget( selBtn );
   mainShapeLayout->addWidget( myEditMainShape );
 
-  /**********************   Sub-objects tree    **********************/
-
-  myTreeObjects = new QTreeWidget();
-  myTreeObjects->setColumnCount( 2 );
-  QStringList columnNames;
-  columnNames.append( tr( "GEOM_INSPECT_OBJECT_NAME" ) );
-  columnNames.append("");
-  myTreeObjects->setHeaderLabels( columnNames );
-  QTreeWidgetItem* headerItem = new QTreeWidgetItem( columnNames );
-  myTreeObjects->setHeaderItem( headerItem );
-  myTreeObjects->header()->moveSection( 1, 0 );
-  myTreeObjects->header()->setClickable( true );
-  myTreeObjects->header()->setMovable( false );
-  myTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents );
-  myTreeObjects->setSelectionMode( QAbstractItemView::ExtendedSelection );
-  myTreeObjects->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed );
-  // set custom item delegate
-  myTreeObjects->setItemDelegate( new Delegate( myTreeObjects ) );
+  /**********************   Tolerance filter    **********************/
+
+  myTolFilterGrp    = new QGroupBox (tr("GEOM_INSPECT_TOLERANCE_FILTER"), this);
+  myShapeTypeBtnGrp = new QButtonGroup(myTolFilterGrp);
+
+  // Filter on shape type
+  QRadioButton *aVtx   = new QRadioButton(tr("GEOM_VERTEX"), myTolFilterGrp);
+  QRadioButton *anEdge = new QRadioButton(tr("GEOM_EDGE"),   myTolFilterGrp);
+  QRadioButton *aFace  = new QRadioButton(tr("GEOM_FACE"),   myTolFilterGrp);
+
+  aVtx->setIcon(anImageVtx);
+  anEdge->setIcon(anImageEdge);
+  aFace->setIcon(anImageFace);
+  myShapeTypeBtnGrp->addButton(aVtx,   TYPE_VERTEX);
+  myShapeTypeBtnGrp->addButton(anEdge, TYPE_EDGE);
+  myShapeTypeBtnGrp->addButton(aFace,  TYPE_FACE);
+
+  // Filter on sub-shape tolerance
+  QLabel      *aTolLabel     = new QLabel(tr("GEOM_TOLERANCE"), myTolFilterGrp);
+  QLabel      *aMinTolLabel  = new QLabel(tr("GEOM_MIN"), myTolFilterGrp);
+  QLabel      *aMaxTolLabel  = new QLabel(tr("GEOM_MAX"), myTolFilterGrp);
+  QGridLayout *aFilterLayout = new QGridLayout(myTolFilterGrp);
+
+  myMinTolValLabel  = new QLabel(myTolFilterGrp);
+  myMaxTolValLabel  = new QLabel(myTolFilterGrp);
+  myMinTolResetBtn  = new QPushButton(tr("GEOM_INSPECT_RESET_MIN"), myTolFilterGrp);
+  myMaxTolResetBtn  = new QPushButton(tr("GEOM_INSPECT_RESET_MAX"), myTolFilterGrp);
+  myComparisonCompo = new QComboBox(myTolFilterGrp);
+  myTolEdit         = new SalomeApp_DoubleSpinBox(myTolFilterGrp);
+  myTolEdit->setMinimumWidth(120);
+  aFilterLayout->addWidget(aVtx,   0, 0);
+  aFilterLayout->addWidget(anEdge, 0, 1);
+  aFilterLayout->addWidget(aFace,  0, 2);
+  aFilterLayout->addWidget(aMaxTolLabel,      1, 0, Qt::AlignRight);
+  aFilterLayout->addWidget(aTolLabel,         2, 0);
+  aFilterLayout->addWidget(aMinTolLabel,      3, 0, Qt::AlignRight);
+  aFilterLayout->addWidget(myMaxTolValLabel,  1, 1);
+  aFilterLayout->addWidget(myComparisonCompo, 2, 1);
+  aFilterLayout->addWidget(myMinTolValLabel,  3, 1);
+  aFilterLayout->addWidget(myMaxTolResetBtn,  1, 2);
+  aFilterLayout->addWidget(myTolEdit,         2, 2);
+  aFilterLayout->addWidget(myMinTolResetBtn,  3, 2);
+  aFilterLayout->setRowMinimumHeight(0, 30);
+
+  myTolFilterGrp->setCheckable(true);
+
+  /**********************   Sub-objects trees   **********************/
+  createTreeWidget(myTreeObjects);
+  createTreeWidget(myFilteredTreeObjects);
+
+  myTreesLayout = new QStackedLayout(this);
+  myTreesLayout->addWidget(myTreeObjects);
+  myTreesLayout->addWidget(myFilteredTreeObjects);
 
   /**********************        Buttons        **********************/
 
-  QVBoxLayout* buttonsLayout1 = new QVBoxLayout();
+  QVBoxLayout* buttonsLayout1 = new QVBoxLayout(this);
+
+  QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ), this );
+  QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ), this );
+  QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ), this );
+  QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ), this );
+  QPushButton* aShowAllBtn = new QPushButton(tr("SHOW_ALL_BTN"), this);
+  QPushButton* aHideAllBtn = new QPushButton(tr("HIDE_ALL_BTN"), this);
 
-  QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ) );
-  QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ) );
-  QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ) );
-  QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ) );
 
   buttonsLayout1->addWidget( buttonShow );
   buttonsLayout1->addWidget( buttonShowOnly );
   buttonsLayout1->addWidget( buttonHide );
-  buttonsLayout1->addStretch();
+  buttonsLayout1->addWidget( aShowAllBtn );
+  buttonsLayout1->addWidget( aHideAllBtn );
   buttonsLayout1->addWidget( buttonPublish );
   buttonsLayout1->addStretch();
 
-  QHBoxLayout* buttonsLayout2 = new QHBoxLayout();
+  QHBoxLayout* buttonsLayout2 = new QHBoxLayout(this);
 
-  QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ) );
-  QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ) );
+  QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this );
+  QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this );
 
   buttonsLayout2->addWidget( buttonClose );
   buttonsLayout2->addStretch();
   buttonsLayout2->addWidget( buttonHelp );
 
   topLayout->addLayout( mainShapeLayout, 0, 0 );
-  topLayout->addWidget( myTreeObjects, 1, 0 );
-  topLayout->addLayout( buttonsLayout1, 0, 1, 2, 1 );
-  topLayout->addLayout( buttonsLayout2, 2, 0, 1, 2 );
-
-  // Signals and slots connections
+  topLayout->addWidget( myTolFilterGrp, 1, 0);
+  topLayout->addLayout( myTreesLayout, 2, 0 );
+  topLayout->addLayout( buttonsLayout1, 0, 1, 3, 1 );
+  topLayout->addLayout( buttonsLayout2, 3, 0, 1, 2 );
 
   connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) );
 
-  connect( myTreeObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ),
-           this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
-  connect( myTreeObjects, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ),
-           this, SLOT( onItemChanged( QTreeWidgetItem*, int ) ) );
-  connect( myTreeObjects, SIGNAL( itemExpanded ( QTreeWidgetItem* ) ),
-           this, SLOT( onItemExpanded( QTreeWidgetItem* ) ) );
-  connect( myTreeObjects, SIGNAL( itemSelectionChanged() ),
-           this, SLOT( onItemSelectionChanged() ) );
-
-  connect( myTreeObjects->header(), SIGNAL( sectionClicked( int ) ), this, SLOT( onHeaderClicked( int ) ) );
-
   connect( buttonShow,     SIGNAL( clicked() ), this, SLOT( clickOnShow() ) );
   connect( buttonShowOnly, SIGNAL( clicked() ), this, SLOT( clickOnShowOnly() ) );
   connect( buttonHide,     SIGNAL( clicked() ), this, SLOT( clickOnHide() ) );
   connect( buttonPublish,  SIGNAL( clicked() ), this, SLOT( clickOnPublish() ) );
-
   connect( buttonClose,    SIGNAL( clicked() ), this, SLOT( reject() ) );
   connect( buttonHelp,     SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) );
-
-  connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ),
-           this, SLOT( onViewSelectionChanged() ) );
-
-  connect( myApp->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
-           this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) );
-
-  if ( myViewWindow )
-    connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
-             this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
+  connect( aShowAllBtn,   SIGNAL( clicked() ), this, SLOT( clickOnShowAll() ) );
+  connect( aHideAllBtn,   SIGNAL( clicked() ), this, SLOT( clickOnHideAll() ) );
 
   init();
 }
@@ -297,59 +400,133 @@ RepairGUI_InspectObjectDlg::~RepairGUI_InspectObjectDlg()
   // no need to delete child widgets, Qt does it all for us
 }
 
+//=================================================================================
+// function : createTreeWidget()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::createTreeWidget(QTreeWidget *&theTreeObjects)
+{
+  theTreeObjects = new QTreeWidget(this);
+  theTreeObjects->setColumnCount(2);
+  QStringList columnNames;
+  columnNames.append(tr("GEOM_INSPECT_OBJECT_NAME"));
+  columnNames.append("");
+  theTreeObjects->setHeaderLabels(columnNames);
+  QTreeWidgetItem* headerItem = new QTreeWidgetItem(columnNames);
+
+  headerItem->setIcon(1, myInvisible);
+  theTreeObjects->setHeaderItem(headerItem);
+  theTreeObjects->header()->moveSection(1, 0);
+  theTreeObjects->header()->setClickable(true);
+  theTreeObjects->header()->setMovable(false);
+  theTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents);
+  theTreeObjects->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  theTreeObjects->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
+  // set custom item delegate
+  theTreeObjects->setItemDelegate(new Delegate(theTreeObjects));
+}
+
 //=================================================================================
 // function : init()
 // purpose  : initialize dialog data
 //=================================================================================
 void RepairGUI_InspectObjectDlg::init()
 {
-  //get shape from selection
-  SALOME_ListIO selected;
-  myApp->selectionMgr()->selectedObjects(selected);
+  myTolFilterGrp->setChecked(false);
+  myComparisonCompo->addItem(">",  GEOMUtils::CC_GT);
+  myComparisonCompo->addItem(">=", GEOMUtils::CC_GE);
+  myComparisonCompo->addItem("<",  GEOMUtils::CC_LT);
+  myComparisonCompo->addItem("<=", GEOMUtils::CC_LE);
 
-  if ( selected.Extent() != 1 )
-    return;
-
-  if ( !myViewWindow ) {
-    SUIT_ViewManager* occVm = myApp->getViewManager( OCCViewer_Viewer::Type(), true );
-    myViewWindow = occVm->getActiveView();
-    connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
-             this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
-  }
+  initSpinBox(myTolEdit, 0., 100., DEFAULT_TOLERANCE_VALUE, "len_tol_precision");
+  myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE);
 
-  TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected );
-  if ( aShape.IsNull() )
-    return;
+  // Signals and slots connections
+  initTreeWidget(myTreeObjects);
+  initTreeWidget(myFilteredTreeObjects);
+  myCurrentTreeObjects = myTreeObjects;
+  myMaxTolResetBtn->setEnabled(false);
+  myMinTolResetBtn->setEnabled(false);
+
+  connect(myMinTolResetBtn,  SIGNAL(clicked()), this, SLOT(clickOnResetToMin()));
+  connect(myMaxTolResetBtn,  SIGNAL(clicked()), this, SLOT(clickOnResetToMax()));
+  connect(myShapeTypeBtnGrp, SIGNAL(buttonClicked(int)), this, SLOT(onInitFilteredData()));
+  connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(reject()));
+
+  connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
+           this, SLOT( onViewSelectionChanged() ) );
 
-  Handle(SALOME_InteractiveObject) anIO = selected.First();
-  GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO );
-  QString aName = anObject->GetName();
-  CORBA::String_var anEntry = anObject->GetStudyEntry();
+  connect( myGeomGUI->getApp()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+           this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) );
 
-  myEditMainShape->setText( aName );
-  myEditMainShape->setEnabled( false );
+  // Connect signals and slots for filter group box elements.
+  connect(myTolFilterGrp, SIGNAL(toggled(bool)),
+          this, SLOT(onFilterToggled(bool)));
+  connect(myComparisonCompo, SIGNAL(currentIndexChanged(int)),
+          this, SLOT(onFilterData()));
+  connect(myTolEdit, SIGNAL(valueChanged(double)),
+          this, SLOT(onFilterData()));
 
-  // remember initial transparency value
-  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
-  QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(),
-                                          QString( anEntry.in() ),
-                                          GEOM::propertyName( GEOM::Transparency ), myTransparency );
-  if ( v.canConvert( QVariant::Double ) )
-    myTransparency = v.toDouble();
+  if ( myViewWindow )
+    connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+             this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
 
-  TreeWidgetItem* anItem = new TreeWidgetItem( myTreeObjects, QStringList() << aName, aShape, anIO );
-  if ( getDisplayer()->IsDisplayed( anEntry.in() ) )
-    anItem->setVisible( true, myVisible );
-  else
-    anItem->setVisible( false, myInvisible );
+  // Initialize the dialog with current selection.
+  onViewSelectionChanged();
+}
 
-  setMainObjectTransparency( 0.5 );
+//=================================================================================
+// function : initSpinBox()
+// purpose  : 
+//=================================================================================
+void RepairGUI_InspectObjectDlg::initSpinBox(SalomeApp_DoubleSpinBox* spinBox, 
+                                             double min,  double max, 
+                                             double step, const char* quantity)
+{
+  // Obtain precision from preferences
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  int aPrecision = resMgr->integerValue( "Geometry", quantity, 6 );
+  
+  spinBox->setPrecision( aPrecision );
+  spinBox->setDecimals( qAbs( aPrecision ) ); // it's necessary to set decimals before the range setting,
+                                    // by default Qt rounds boundaries to 2 decimals at setRange
+  spinBox->setRange( min, max );
+  spinBox->setSingleStep( step );
+  
+  // Add a hint for the user saying how to tune precision
+  QString userPropName = QObject::tr( QString( "GEOM_PREF_%1" ).arg( quantity ).toLatin1().constData() );
+  spinBox->setProperty( "validity_tune_hint", 
+                        QVariant( QObject::tr( "GEOM_PRECISION_HINT" ).arg( userPropName ) ) );
+}
 
-  // add sub-objects in the tree
-  addSubObjects( anItem );
+//=================================================================================
+// function : initTreeWidget()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::initTreeWidget(QTreeWidget *theTreeObjects)
+{
+  connect(theTreeObjects, SIGNAL(itemClicked (QTreeWidgetItem *, int)),
+          this, SLOT(onItemClicked(QTreeWidgetItem *, int)));
+  connect(theTreeObjects, SIGNAL(itemChanged (QTreeWidgetItem *, int)),
+          this, SLOT(onItemChanged(QTreeWidgetItem *, int)));
+  connect(theTreeObjects, SIGNAL(itemExpanded (QTreeWidgetItem *)),
+          this, SLOT(onItemExpanded(QTreeWidgetItem *)));
+  connect(theTreeObjects, SIGNAL(itemSelectionChanged()),
+          this, SLOT(onItemSelectionChanged()));
+
+  connect(theTreeObjects->header(), SIGNAL(sectionClicked(int)),
+          this, SLOT(onHeaderClicked(int)));
+}
 
-  // check icon for tree header
-  checkVisibleIcon();
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::enterEvent (QEvent*)
+{
+  if (!myTolFilterGrp->isEnabled())
+    ActivateThisDialog();
 }
 
 //=================================================================================
@@ -359,20 +536,22 @@ void RepairGUI_InspectObjectDlg::init()
 void RepairGUI_InspectObjectDlg::checkVisibleIcon()
 {
   bool isInvisible = false;
-  QTreeWidgetItemIterator it( myTreeObjects );
+  QTreeWidgetItemIterator it( myCurrentTreeObjects );
   while ( *it ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
-    if ( !anItem->isVisible() )
+    if ( !anItem->isHidden() &&  !anItem->isVisible() ) {
       isInvisible = true;
+      break;
+    }
     ++it;
   }
 
   if ( isInvisible ) {
-    myTreeObjects->headerItem()->setIcon( 1, myInvisible );
+    myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible );
     myIsSelectAll = false;
   }
   else {
-    myTreeObjects->headerItem()->setIcon( 1, myVisible );
+    myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible );
     myIsSelectAll = true;
   }
 }
@@ -381,20 +560,205 @@ void RepairGUI_InspectObjectDlg::checkVisibleIcon()
 // function : addSubObjects()
 // purpose  : add sub-objects to parent object in the tree
 //=================================================================================
-void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem )
+void RepairGUI_InspectObjectDlg::addSubObjects
+                    (TreeWidgetItem                   *theParentItem,
+                     const TopTools_IndexedMapOfShape &theIndices)
 {
   TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
   TopoDS_Iterator it( theParentItem->getShape() );
   for ( ; it.More(); it.Next() ) {
     TopoDS_Shape aSubShape = it.Value();
-    int anIndex = GEOMBase::GetIndex( aSubShape, aMainItem->getShape() );
+    int anIndex = theIndices.FindIndex(aSubShape);
     QString anEntry = QString( "TEMP_" ) + aMainItem->getIO()->getEntry() + QString("_%1").arg( anIndex );
     TreeWidgetItem* anItem = new TreeWidgetItem( theParentItem, QStringList(), aSubShape, anEntry);
     anItem->setVisible( false, myInvisible );
-    addSubObjects( anItem );
+    addSubObjects(anItem, theIndices);
+  }
+}
+
+//=================================================================================
+// function : onInitFilteredData()
+// purpose  : add sub-objects to parent object in the filtered tree
+//=================================================================================
+void RepairGUI_InspectObjectDlg::onInitFilteredData()
+{
+  TreeWidgetItem *aMainItem =
+          dynamic_cast<TreeWidgetItem*>(myFilteredTreeObjects->topLevelItem(0));
+
+  if (!aMainItem) {
+    return;
+  }
+
+  // Remove the children.
+  SALOME_ListIO           aListOfIO;
+  QTreeWidgetItemIterator it(aMainItem);
+
+  while (*it) {
+    TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
+    if (aMainItem != anItem && (anItem->flags() & Qt::ItemIsSelectable) &&
+        anItem->isVisible() && !anItem->isHidden()) {
+      aListOfIO.Append(anItem->getIO());
+    }
+
+    ++it;
+  }
+
+  myFilteredTreeObjects->clearSelection();
+  myFilteredTreeObjects->headerItem()->setIcon(1, myInvisible);
+  getDisplayer()->Erase(aListOfIO);
+  getDisplayer()->UpdateViewer();
+
+  // Delete child items.
+  QList<QTreeWidgetItem *> aListItems = aMainItem->takeChildren();
+
+  foreach (QTreeWidgetItem *anItem, aListItems) {
+    delete anItem;
+  }
+
+  // Initialize the tree with a new list.
+  TopoDS_Shape      aShape     = aMainItem->getShape();
+  TopAbs_ShapeEnum  aShapeType = aShape.ShapeType();
+
+  myShapeTypeBtnGrp->button(TYPE_FACE)->setVisible(aShapeType < TYPE_FACE);
+  myShapeTypeBtnGrp->button(TYPE_EDGE)->setVisible(aShapeType < TYPE_EDGE);
+  myShapeTypeBtnGrp->button(TYPE_VERTEX)->setVisible(aShapeType < TYPE_VERTEX);
+
+  int anId = myShapeTypeBtnGrp->checkedId();
+
+  myMaxTol = -RealLast();
+  myMinTol =  RealLast();
+
+  if (anId != -1 && myShapeTypeBtnGrp->checkedButton()->isVisible()) {
+    // Get sub-shapes
+    TopTools_MapOfShape         aMapFence;
+    TopExp_Explorer             anExp(aShape, (TopAbs_ShapeEnum)anId);
+    TopTools_IndexedMapOfShape  anIndices;
+
+    TopExp::MapShapes(aShape, anIndices);
+
+    for (; anExp.More(); anExp.Next()) {
+      const TopoDS_Shape &aSubShape = anExp.Current();
+
+      if (aMapFence.Add(aSubShape)) {
+        // Compute tolerance
+        Standard_Real aTolerance = -1.;
+
+        switch (aSubShape.ShapeType()) {
+          case TYPE_FACE:
+            aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape));
+            break;
+          case TYPE_EDGE:
+            aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape));
+            break;
+          case TYPE_VERTEX:
+            aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape));
+            break;
+          default:
+            break;
+        }
+
+        if (aTolerance < 0.) {
+          continue;
+        }
+
+        if (aTolerance > myMaxTol) {
+          myMaxTol = aTolerance;
+        }
+
+        if (aTolerance < myMinTol) {
+          myMinTol = aTolerance;
+        }
+
+        int anIndex = anIndices.FindIndex(aSubShape);
+        QString anEntry = QString( "TEMP_" ) +
+                          aMainItem->getIO()->getEntry() +
+                          QString::number(anIndex);
+        TreeWidgetItem* anItem =
+            new TreeWidgetItem(aMainItem, QStringList(),
+                               aSubShape, anEntry, aTolerance);
+        anItem->setVisible( false, myInvisible );
+      }
+    }
+  }
+
+  // Compose names of sub-items if the main item is expanded.
+  if (aMainItem->isExpanded()) {
+    onItemExpanded(aMainItem);
+  }
+
+  myMaxTolResetBtn->setEnabled(myMaxTol >= myMinTol);
+  myMinTolResetBtn->setEnabled(myMaxTol >= myMinTol);
+
+  if (myMaxTol < myMinTol) {
+    myMinTol = DEFAULT_TOLERANCE_VALUE;
+    myMaxTol = DEFAULT_TOLERANCE_VALUE;
+    myMinTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE));
+    myMaxTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE));
+    myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE);
+  } else {
+    myMinTolValLabel->setText(QString::number(myMinTol));
+    myMaxTolValLabel->setText(QString::number(myMaxTol));
+
+    if (GEOMUtils::CompareToleranceValues(myMinTol, myTolEdit->value()) == 1) {
+      clickOnResetToMin();
+    } else if (GEOMUtils::CompareToleranceValues
+                                         (myMaxTol, myTolEdit->value()) == -1) {
+      clickOnResetToMax();
+    } else {
+      onFilterData();
+    }
   }
 }
 
+//=================================================================================
+// function : onFilterData()
+// purpose  : filter objects in the filtered tree
+//=================================================================================
+void RepairGUI_InspectObjectDlg::onFilterData()
+{
+  TreeWidgetItem *aMainItem =
+          dynamic_cast<TreeWidgetItem*>(myFilteredTreeObjects->topLevelItem(0));
+
+  if (!aMainItem) {
+    return;
+  }
+
+  SALOME_ListIO           aListOfIOToHide;
+  QTreeWidgetItemIterator anIt(aMainItem);
+  const int               aCompValue =
+         myComparisonCompo->itemData(myComparisonCompo->currentIndex()).toInt();
+  const double            aTolValue  = myTolEdit->value();
+
+  while (*anIt) {
+    TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*anIt);
+
+    if (aMainItem != anItem) {
+      const bool isToFilter = !GEOMUtils::IsFitCondition
+        ((GEOMUtils::ComparisonCondition) aCompValue,
+         anItem->getTolerance(), aTolValue);
+
+      if (isToFilter && !anItem->isHidden()) {
+        if (anItem->isVisible()) {
+          aListOfIOToHide.Append(anItem->getIO());
+        }
+
+        anItem->setVisible(false, myInvisible);
+      }
+
+      anItem->setHidden(isToFilter);
+    }
+
+    ++anIt;
+  }
+
+  if (!aListOfIOToHide.IsEmpty()) {
+    getDisplayer()->Erase(aListOfIOToHide);
+    getDisplayer()->UpdateViewer();
+  }
+
+  checkVisibleIcon();
+}
+
 //=================================================================================
 // function : displayItem()
 // purpose  : display sub-object of inspected object according its tree item
@@ -402,7 +766,7 @@ void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem )
 void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem )
 {
   GEOM_Displayer* aDisplayer = getDisplayer();
-  if ( theItem == myTreeObjects->topLevelItem(0) ) {
+  if ( theItem == myCurrentTreeObjects->topLevelItem(0) ) {
     aDisplayer->UnsetColor();
     aDisplayer->UnsetWidth();
   }
@@ -423,7 +787,7 @@ void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem )
 //=================================================================================
 void RepairGUI_InspectObjectDlg::setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible )
 {
-  QTreeWidgetItemIterator it( myTreeObjects );
+  QTreeWidgetItemIterator it( myCurrentTreeObjects );
   while (*it) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
     if ( anItem->getShape().IsSame( theItem->getShape() ) )
@@ -440,9 +804,14 @@ void RepairGUI_InspectObjectDlg::setMainObjectTransparency( double theTransparen
 {
   SUIT_ViewManager* aViewMan = myViewWindow->getViewManager();
   SALOME_View* aView = dynamic_cast<SALOME_View*>( aViewMan->getViewModel() );
-  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myGeomGUI->getApp()->activeStudy() );
+
+  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myCurrentTreeObjects->topLevelItem(0) );
+
+  if (!aMainItem) {
+    return;
+  }
 
-  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
   aStudy->setObjectProperty( myViewWindow->getViewManager()->getGlobalId(),
                              QString( aMainItem->getIO()->getEntry() ),
                              GEOM::propertyName( GEOM::Transparency ), theTransparency );
@@ -468,8 +837,8 @@ void RepairGUI_InspectObjectDlg::restoreParam()
   setMainObjectTransparency( myTransparency );
 
   // erase sub-shapes
-  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
-  QTreeWidgetItemIterator it( myTreeObjects );
+  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myCurrentTreeObjects->topLevelItem(0) );
+  QTreeWidgetItemIterator it( myCurrentTreeObjects );
   while (*it) {
     if ( *it != aMainItem ) {
       TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
@@ -496,6 +865,7 @@ void RepairGUI_InspectObjectDlg::onEditMainShape()
   myEditMainShape->setText("");
   myEditMainShape->setFocus();
   myTreeObjects->clear();
+  myFilteredTreeObjects->clear();
 }
 
 //=================================================================================
@@ -533,7 +903,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th
     return;
 
   // rename the same items in the tree
-  QTreeWidgetItemIterator it( myTreeObjects );
+  QTreeWidgetItemIterator it( myCurrentTreeObjects );
   while ( *it ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
     if ( anItem->getShape().IsSame( dynamic_cast<TreeWidgetItem*>( theItem )->getShape() ) )
@@ -548,7 +918,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th
 //=================================================================================
 void RepairGUI_InspectObjectDlg::onItemExpanded( QTreeWidgetItem* theItem )
 {
-  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
+  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myCurrentTreeObjects->topLevelItem(0) );
   GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() );
 
   for ( int i = 0; i < theItem->childCount(); i++ ) {
@@ -573,13 +943,13 @@ void RepairGUI_InspectObjectDlg::onItemSelectionChanged()
   if ( !myViewWindow )
     return;
 
-  QList<QTreeWidgetItem*> listItem = myTreeObjects->selectedItems();
+  QList<QTreeWidgetItem*> listItem = myCurrentTreeObjects->selectedItems();
   SALOME_ListIO aSelected;
   for ( int i = 0; i < listItem.size(); i++ ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>( listItem.at(i) );
     aSelected.Append( anItem->getIO() );
   }
-  myApp->selectionMgr()->setSelectedObjects( aSelected );
+  myGeomGUI->getApp()->selectionMgr()->setSelectedObjects( aSelected );
 }
 
 //=================================================================================
@@ -595,12 +965,13 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn )
 
   if ( myIsSelectAll ) {
     myIsSelectAll = false;
-    myTreeObjects->headerItem()->setIcon( 1, myInvisible );
+    myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible );
     SALOME_ListIO aListOfIO;
-    QTreeWidgetItemIterator it( myTreeObjects );
+    QTreeWidgetItemIterator it( myCurrentTreeObjects );
     while ( *it ) {
       TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
-      if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) {
+      if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) &&
+          anItem->isVisible() ) {
         aListOfIO.Append( anItem->getIO() );
         anItem->setVisible( false, myInvisible );
       }
@@ -610,11 +981,12 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn )
   }
   else {
     myIsSelectAll = true;
-    myTreeObjects->headerItem()->setIcon( 1, myVisible );
-    QTreeWidgetItemIterator it( myTreeObjects );
+    myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible );
+    QTreeWidgetItemIterator it( myCurrentTreeObjects );
     while ( *it ) {
       TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
-      if ( ( anItem->flags() & Qt::ItemIsSelectable ) && !anItem->isVisible() ) {
+      if ( !anItem->isHidden() &&  ( anItem->flags() & Qt::ItemIsSelectable ) &&
+           !anItem->isVisible() ) {
         displayItem( anItem );
         anItem->setVisible( true, myVisible );
       }
@@ -631,8 +1003,68 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn )
 //=================================================================================
 void RepairGUI_InspectObjectDlg::onViewSelectionChanged()
 {
-  if ( myEditMainShape->isEnabled() )
-    init();
+  if (!myEditMainShape->isEnabled())
+    return;
+
+  //get shape from selection
+  SALOME_ListIO selected;
+  myGeomGUI->getApp()->selectionMgr()->selectedObjects(selected);
+
+  if ( selected.Extent() != 1 )
+    return;
+
+  if ( !myViewWindow ) {
+    SUIT_ViewManager* occVm = myGeomGUI->getApp()->getViewManager( OCCViewer_Viewer::Type(), true );
+    myViewWindow = occVm->getActiveView();
+    connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+             this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
+  }
+
+  TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected );
+  if ( aShape.IsNull() )
+    return;
+
+  Handle(SALOME_InteractiveObject) anIO = selected.First();
+  GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO );
+  QString aName = anObject->GetName();
+  CORBA::String_var anEntry = anObject->GetStudyEntry();
+
+  myEditMainShape->setText( aName );
+  myEditMainShape->setEnabled( false );
+
+  // remember initial transparency value
+  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( myGeomGUI->getApp()->activeStudy() );
+  QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(),
+                                          QString( anEntry.in() ),
+                                          GEOM::propertyName( GEOM::Transparency ), myTransparency );
+  if ( v.canConvert( QVariant::Double ) )
+    myTransparency = v.toDouble();
+
+  TreeWidgetItem* anItem         = new TreeWidgetItem
+              (myTreeObjects, QStringList() << aName, aShape, anIO);
+  TreeWidgetItem* anItemFiltered = new TreeWidgetItem
+              (myFilteredTreeObjects, QStringList() << aName, aShape, anIO);
+
+  if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) {
+    anItem->setVisible( true, myVisible );
+    anItemFiltered->setVisible( true, myVisible );
+  } else {
+    anItem->setVisible( false, myInvisible );
+    anItemFiltered->setVisible( false, myInvisible );
+  }
+
+  setMainObjectTransparency( 0.5 );
+
+  // add sub-objects in the tree
+  TopTools_IndexedMapOfShape anIndices;
+
+  TopExp::MapShapes(aShape, anIndices);
+  addSubObjects(anItem, anIndices);
+  onInitFilteredData();
+  updateViewer(false);
+
+  // check icon for tree header
+  checkVisibleIcon();
 }
 
 //=================================================================================
@@ -654,9 +1086,9 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind
   }
   myViewWindow = theViewWindow;
 
-  if ( myTreeObjects->topLevelItemCount() > 0 ) {
+  if ( myCurrentTreeObjects->topLevelItemCount() > 0 ) {
     setMainObjectTransparency( 0.5 );
-    TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
+    TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myCurrentTreeObjects->topLevelItem(0) );
     if ( getDisplayer()->IsDisplayed( aMainItem->getIO()->getEntry() ) )
       aMainItem->setVisible( true, myVisible );
     else
@@ -671,7 +1103,7 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind
 //=================================================================================
 void RepairGUI_InspectObjectDlg::onCloseView( SUIT_ViewWindow* )
 {
-  if ( myApp->desktop()->windows().size() == 0 ) {
+  if ( myGeomGUI->getApp()->desktop()->windows().size() == 0 ) {
     restoreParam();
     myViewWindow = 0;
   }
@@ -686,7 +1118,7 @@ void RepairGUI_InspectObjectDlg::clickOnShow()
   if ( !myViewWindow )
     return;
 
-  QList<QTreeWidgetItem*> listItem = myTreeObjects->selectedItems();
+  QList<QTreeWidgetItem*> listItem = myCurrentTreeObjects->selectedItems();
   for ( int i = 0; i < listItem.size(); i++ ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>( listItem.at(i) );
     if ( !anItem->isVisible() ) {
@@ -708,10 +1140,11 @@ void RepairGUI_InspectObjectDlg::clickOnShowOnly()
     return;
 
   SALOME_ListIO aListOfIO;
-  QTreeWidgetItemIterator it( myTreeObjects );
+  QTreeWidgetItemIterator it( myCurrentTreeObjects );
   while ( *it ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
-    if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) {
+    if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) &&
+         anItem->isVisible() ) {
       aListOfIO.Append( anItem->getIO() );
       anItem->setVisible( false, myInvisible );
     }
@@ -731,7 +1164,7 @@ void RepairGUI_InspectObjectDlg::clickOnHide()
   if ( !myViewWindow )
     return;
 
-  QList<QTreeWidgetItem*> listItem = myTreeObjects->selectedItems();
+  QList<QTreeWidgetItem*> listItem = myCurrentTreeObjects->selectedItems();
   for ( int i = 0; i < listItem.size(); i++ ) {
     TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>( listItem.at(i) );
     if ( anItem->isVisible() ) {
@@ -749,14 +1182,19 @@ void RepairGUI_InspectObjectDlg::clickOnHide()
 //=================================================================================
 void RepairGUI_InspectObjectDlg::clickOnPublish()
 {
-  _PTR(Study) studyDS = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() )->studyDS();
+  _PTR(Study) studyDS = dynamic_cast<SalomeApp_Study*>( myGeomGUI->getApp()->activeStudy() )->studyDS();
 
   // find main object
-  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myTreeObjects->topLevelItem(0) );
+  TreeWidgetItem* aMainItem = dynamic_cast<TreeWidgetItem*>( myCurrentTreeObjects->topLevelItem(0) );
+
+  if (!aMainItem) {
+    return;
+  }
+
   GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() );
 
   // find unique indices of selected objects
-  QList<QTreeWidgetItem*> selectedItems = myTreeObjects->selectedItems();
+  QList<QTreeWidgetItem*> selectedItems = myCurrentTreeObjects->selectedItems();
   QMap< int, QString > anIndices;
   GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
   anArray->length( selectedItems.size() );
@@ -790,5 +1228,139 @@ void RepairGUI_InspectObjectDlg::clickOnPublish()
 //=================================================================================
 void RepairGUI_InspectObjectDlg::clickOnHelp()
 {
-  myApp->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" );
+  myGeomGUI->getApp()->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" );
+}
+
+//=================================================================================
+// function : clickOnResetToMin()
+// purpose  : called when Reset button was clicked to reset tolerance filter to minimal value.
+//=================================================================================
+void RepairGUI_InspectObjectDlg::clickOnResetToMin()
+{
+  if (myMinTol >= myTolEdit->minimum() && myMinTol <= myTolEdit->maximum()) {
+    myTolEdit->setValue(myMinTol);
+  }
+}
+
+//=================================================================================
+// function : clickOnResetToMax()
+// purpose  : called when Reset button was clicked to reset tolerance filter to maximal value.
+//=================================================================================
+void RepairGUI_InspectObjectDlg::clickOnResetToMax()
+{
+  if (myMaxTol >= myTolEdit->minimum() && myMaxTol <= myTolEdit->maximum()) {
+    myTolEdit->setValue(myMaxTol);
+  }
+}
+
+//=================================================================================
+// function : clickOnShowAll()
+// purpose  : called when Help button was clicked to show all shapes
+//=================================================================================
+void RepairGUI_InspectObjectDlg::clickOnShowAll()
+{
+  myIsSelectAll = false;
+  onHeaderClicked(1);
+}
+
+//=================================================================================
+// function : clickOnHideAll()
+// purpose  : called when Help button was clicked to hide all shapes
+//=================================================================================
+void RepairGUI_InspectObjectDlg::clickOnHideAll()
+{
+  myIsSelectAll = true;
+  onHeaderClicked(1);
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::DeactivateActiveDialog()
+{
+  setEnabled(false);
+  disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
+  myGeomGUI->SetActiveDialogBox(0);
+  globalSelection();
+  erasePreview();
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  myGeomGUI->EmitSignalDeactivateDialog();
+  setEnabled(true);
+  myGeomGUI->SetActiveDialogBox( (QDialog*)this );
+
+  connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+          this, SLOT(onViewSelectionChanged()));
+
+  updateViewer(false);
+}
+
+//=================================================================================
+// function : onFilterToggled()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::onFilterToggled(bool isOn)
+{
+  if (isOn) {
+    myCurrentTreeObjects = myFilteredTreeObjects;
+    myTreesLayout->setCurrentIndex(1);
+  } else {
+    myCurrentTreeObjects = myTreeObjects;
+    myTreesLayout->setCurrentIndex(0);
+  }
+
+  updateViewer(true);
+}
+
+//=================================================================================
+// function : updateViewer()
+// purpose  :
+//=================================================================================
+void RepairGUI_InspectObjectDlg::updateViewer(const bool theIsHideOtherTree)
+{
+  GEOM_Displayer *aDisplayer  = getDisplayer();
+
+  if (theIsHideOtherTree) {
+    QTreeWidget    *aTreeToHide = myCurrentTreeObjects == myTreeObjects ?
+                                          myFilteredTreeObjects: myTreeObjects;
+
+    // Hide the objects of disappeared tree, do not switch off flags.
+    SALOME_ListIO           aListOfIO;
+    QTreeWidgetItemIterator it(aTreeToHide);
+
+    while (*it) {
+      TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it);
+      if ((anItem->flags() & Qt::ItemIsSelectable) &&
+          anItem->isVisible() && !anItem->isHidden()) {
+        aListOfIO.Append(anItem->getIO());
+      }
+
+      ++it;
+    }
+
+    aDisplayer->Erase(aListOfIO);
+  }
+
+  // Show the objects that are marked as shown in the appeared tree.
+  QTreeWidgetItemIterator it2(myCurrentTreeObjects);
+
+  while (*it2) {
+    TreeWidgetItem* anItem = dynamic_cast<TreeWidgetItem*>(*it2);
+    if ((anItem->flags() & Qt::ItemIsSelectable) &&
+        anItem->isVisible() && !anItem->isHidden()) {
+      displayItem(anItem);
+    }
+
+    ++it2;
+  }
+
+  aDisplayer->UpdateViewer();
 }
index d696ac904a1c83dcdfe65ab591b71b3f17f6f532..d8ffff0d4835507537810b31c1f2faec97e7b42f 100644 (file)
 
 // Qt includes
 #include <QDialog>
-#include <QTreeWidget>
-#include <QLabel>
-#include <QLineEdit>
 #include <QPointer>
+#include <QIcon>
+
+class GeometryGUI;
+class SalomeApp_DoubleSpinBox;
+
+class QButtonGroup;
+class QComboBox;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QStackedLayout;
+class QTreeWidget;
+class QTreeWidgetItem;
+
+class TopTools_IndexedMapOfShape;
 
 class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper
 { 
@@ -38,7 +51,7 @@ class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper
   class Delegate;
 
 public:
-  RepairGUI_InspectObjectDlg( SUIT_Desktop* );
+  RepairGUI_InspectObjectDlg(GeometryGUI*, SUIT_Desktop* );
   ~RepairGUI_InspectObjectDlg();
 
 private slots:
@@ -60,25 +73,54 @@ private slots:
   void                    clickOnHide();
   void                    clickOnPublish();
   void                    clickOnHelp();
+  void                    clickOnResetToMin();
+  void                    clickOnResetToMax();
+  void                    clickOnShowAll();
+  void                    clickOnHideAll();
+  void                    DeactivateActiveDialog();
+  void                    ActivateThisDialog();
+  void                    onFilterToggled(bool);
+  void                    onInitFilteredData();
+  void                    onFilterData();
 
 private:
+  void                    createTreeWidget(QTreeWidget *&theTreeObjects);
   void                    init();
+  void                    initSpinBox(SalomeApp_DoubleSpinBox* spinBox, 
+                                      double min,  double max, 
+                                      double step, const char* quantity);
+  void                    initTreeWidget(QTreeWidget *theTopLevelItem);
+  void                    enterEvent( QEvent* );
   void                    checkVisibleIcon();
-  void                    addSubObjects( TreeWidgetItem* );
+  void                    addSubObjects( TreeWidgetItem*, const TopTools_IndexedMapOfShape &);
+
   void                    displayItem( TreeWidgetItem* );
   void                    setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible );
   void                    setMainObjectTransparency( double );
   void                    restoreParam();
+  void                    updateViewer(const bool theIsHideOtherTree);
 
-  SalomeApp_Application*     myApp;
   QPointer<SUIT_ViewWindow>  myViewWindow;
+  GeometryGUI*               myGeomGUI;
 
   QIcon                      myVisible;
   QIcon                      myInvisible;
 
-  QTreeWidget*               myTreeObjects;
-  QLineEdit*                 myEditMainShape;
-
+  QTreeWidget               *myTreeObjects;
+  QTreeWidget               *myFilteredTreeObjects;
+  QTreeWidget               *myCurrentTreeObjects;
+  QLineEdit                 *myEditMainShape;
+  QGroupBox                 *myTolFilterGrp;
+  QButtonGroup              *myShapeTypeBtnGrp;
+  QComboBox                 *myComparisonCompo;
+  SalomeApp_DoubleSpinBox   *myTolEdit;
+  QLabel                    *myMinTolValLabel;
+  QLabel                    *myMaxTolValLabel;
+  QStackedLayout            *myTreesLayout;
+  QPushButton               *myMinTolResetBtn;
+  QPushButton               *myMaxTolResetBtn;
+  double                     myMaxTol;
+  double                     myMinTol;
   bool                       myIsSelectAll;
   double                     myTransparency;