Salome HOME
0022762: [EDF] Fast detection of face/face face/solid solid/solid interference
authorakl <alexander.kovalev@opencascade.com>
Tue, 28 Apr 2015 08:21:22 +0000 (12:21 +0400)
committervsr <vsr@opencascade.com>
Thu, 4 Jun 2015 11:51:15 +0000 (14:51 +0300)
- Part 2: introduce CheckSelfIntersectionsFast function

21 files changed:
doc/salome/examples/CMakeLists.txt
doc/salome/examples/check_self_intersections.py
doc/salome/examples/check_self_intersections_fast.py [new file with mode: 0644]
doc/salome/gui/GEOM/images/measures11.png
doc/salome/gui/GEOM/images/measures13.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/check_self_intersections.doc
doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc [new file with mode: 0644]
doc/salome/gui/GEOM/input/tui_measurement_tools.doc
doc/salome/gui/GEOM/input/tui_test_measures.doc
idl/GEOM_Gen.idl
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMGUI/GEOM_msg_ja.ts
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_SWIG/GEOM_TestMeasures.py
src/GEOM_SWIG/geomBuilder.py
src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx
src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h

index a437b407821414d21b884a2522095e0029cf3e54..e9dc70f96577ee85cf4bbe5858d336ed4bffea47 100644 (file)
@@ -56,6 +56,7 @@ SET(GOOD_TESTS
   center_of_mass.py
   check_compound_of_blocks.py
   check_self_intersections.py
+  check_self_intersections_fast.py
   check_shape.py
   complex_objs_ex01.py
   complex_objs_ex02.py
index 8df91b9fe480015bbb1a8c30063db2dd3a2904f3..f70a545408742406726db20a2cda0181fba96cc9 100644 (file)
@@ -7,9 +7,15 @@ from salome.geom import geomBuilder
 geompy = geomBuilder.New(salome.myStudy)
 
 # create a box
-box = geompy.MakeBoxDXDYDZ(100,30,100)
-IsValid = geompy.CheckSelfIntersections(box)
-if IsValid == 0:
-    raise RuntimeError, "Box with self-intersections created"
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+# create a cylinder
+cylinder = geompy.MakeCylinderRH(100, 300)
+# make a compound
+compound = geompy.MakeCompound([box, cylinder])
+
+# check self-intersection
+IsValid = geompy.CheckSelfIntersections(compound)
+if not IsValid:
+    print "Shape is self-intersected!"
 else:
-    print "\nBox is valid"
+    print "No self-intersection detected in a shape"
diff --git a/doc/salome/examples/check_self_intersections_fast.py b/doc/salome/examples/check_self_intersections_fast.py
new file mode 100644 (file)
index 0000000..83c8a74
--- /dev/null
@@ -0,0 +1,21 @@
+# Detect Self-intersections fast
+
+import salome
+salome.salome_init()
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+
+# create a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+# create a cylinder
+cylinder = geompy.MakeCylinderRH(100, 300)
+# make a compound
+compound = geompy.MakeCompound([box, cylinder])
+
+# check self-intersection
+IsValid = geompy.CheckSelfIntersectionsFast(compound)
+if not IsValid:
+    print "Shape is self-intersected!"
+else:
+    print "No self-intersection detected in a shape"
index 6ee44987416555bf22ca65b9ea84c5a5835cb1b6..562714d31227c690518d3a8011b2e264e248096d 100644 (file)
Binary files a/doc/salome/gui/GEOM/images/measures11.png and b/doc/salome/gui/GEOM/images/measures11.png differ
diff --git a/doc/salome/gui/GEOM/images/measures13.png b/doc/salome/gui/GEOM/images/measures13.png
new file mode 100644 (file)
index 0000000..6e9deb5
Binary files /dev/null and b/doc/salome/gui/GEOM/images/measures13.png differ
index 41658151a35203cea0453fcba98600cf44f66281..f806d4dd6e82ba669acc26c6da46cdc827b158d5 100644 (file)
@@ -2,6 +2,14 @@
 
 \page check_self_intersections_page Detect Self-intersections
 
+\n To <b>Detect Self-intersections</b> in the <b>Main Menu</b> select
+<b>Inspection - > Detect Self-intersections</b>.
+
+There are two ways to check self-intersections.
+
+\anchor check_self_intersections_topological
+<br><h3>Check topological intersections</h2>
+
 This operation checks the topology of the selected shape to detect self-intersections.
 
 \image html measures11.png
@@ -29,5 +37,28 @@ where: \n
 
 See also a \ref tui_check_self_intersections_page "TUI example".
 
+\anchor check_self_intersections_fast
+<br><h3>Fast intersection</h2>
+
+This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections.
+
+\image html measures13.png
+
+This algorithm works on the faces level, i.e. it computes only face-to-face intersections. No additional types of intersections is computed.
+This case can be useful in order to detect all the intersections between the subshapes of type "surface" inside assembly.
+Quality of result will depend on the quality of tesselation (managed via the deflection parameter). However, small values of deflection can
+significantly decrease performance of the algorithm.
+Nevertheless, performance of Fast Intersect algorithm is much higher than topological intersection.
+
+\n <b>Result:</b> Boolean.
+\n <b>TUI Command:</b> <em>geompy.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance),</em> \n
+where: \n
+\em theShape is the shape checked for validity. \n
+\em theDeflection is a linear deflection coefficient that specifies quality of tesselation. If theDeflection <= 0, default deflection 0.001 is used.
+\em theTolerance Specifies a distance between shapes used for detecting gaps:
+     - if theTolerance <= 0, algorithm detects intersections;
+     - if theTolerance > 0, algorithm detects gaps.
+
+See also a \ref tui_check_self_intersections_fast_page "TUI example".
 
 */
\ No newline at end of file
diff --git a/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc b/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc
new file mode 100644 (file)
index 0000000..c8266e3
--- /dev/null
@@ -0,0 +1,6 @@
+/*!
+
+\page tui_check_self_intersections_fast_page Detect Self-intersections fast
+\tui_script{check_self_intersections_fast.py}
+
+*/
index 6e83325c3dc8b10a24a6f9ff04128d60a592ba39..be111dbb16e2372e877388ae8a4dfcca6feaa3a1 100644 (file)
@@ -19,6 +19,7 @@
 <li>\subpage tui_check_compound_of_blocks_page</li>
 <li>\subpage tui_get_non_blocks_page</li>
 <li>\subpage tui_check_self_intersections_page</li>
+<li>\subpage tui_check_self_intersections_fast_page</li>
 <li>\subpage tui_fast_intersection_page</li>
 </ul>
 
index b954b7f605bec8b10f4efb6cd54d1f98bc4eb760..3e147f3882f8d34099fd87809547948a9b0ad20d 100644 (file)
 \until Detect Self-intersections
 
 \anchor swig_CheckSelfIntersections
-\until Detect Fast intersection
+\until Detect Self-intersections fast
+
+\anchor swig_CheckSelfIntersectionsFast
+\until Fast intersection
 
 \anchor swig_FastIntersection
 \until WhatIs
index 87a912edc3829cb0cbb0237637947422e9819efe..88edc8f0782591e32295cb02a943f54b363c894d 100644 (file)
@@ -4448,6 +4448,21 @@ module GEOM
                                     in long        theCheckLevel,
                                     out ListOfLong theIntersections);
 
+    /*!
+     *  \brief Detect self-intersections of the given shape with algorithm based on mesh intersections.
+     *  \param theShape Shape to check validity of.
+     *  \param theDeflection Linear deflection coefficient that specifies quality of tesselation.
+     *  \param theTolerance Specifies a distance between sub-shapes used for detecting gaps:
+     *                       - if \a theTolerance <= 0, algorithm detects intersections
+     *                       - if \a theTolerance > 0, algorithm detects gaps
+     *  \param theIntersections Output. List of intersected sub-shapes IDs, it contains pairs of IDs.
+     *  \return TRUE, if the shape does not have any self-intersections.
+     */
+    boolean CheckSelfIntersectionsFast (in GEOM_Object theShape,
+                                       in float       theDeflection,
+                                       in double      theTolerance,
+                                       out ListOfLong theIntersections);
+
     /*!
      *  \brief Detect intersections of the given shapes with algorithm based on mesh intersections.
      *  \param theShape1 First source object
index 8c43d9c848b5c1a1e61e51499ecd733d4e44fdac..9d86a99dbf97ce9a342000f2934f137e4a35a0b1 100644 (file)
@@ -7274,6 +7274,10 @@ Do you want to create new material?</translation>
 </context>
 <context>
     <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
+    <message>
+        <source>GEOM_CHECK_INTERSECT_TYPE</source>
+        <translation>Self-intersection Detection Type</translation>
+    </message>
     <message>
         <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
         <translation>Self-intersections</translation>
@@ -7338,6 +7342,14 @@ Do you want to create new material?</translation>
         <source>GEOM_CHECK_INTE_ALL</source>
         <translation>Face to Face + all above</translation>
     </message>
+    <message>
+        <source>GEOM_CHECK_INT_DEFLECT</source>
+        <translation>Deflection coefficient</translation>
+    </message>
+    <message>
+        <source>GEOM_CHECK_INT_DETECT_GAPS</source>
+        <translation>Detect gaps with tolerance</translation>
+    </message>
 </context>
 <context>
     <name>MeasureGUI_FastCheckIntersectionsDlg</name>
index 0d8d4623c3bbb62f7dd84caf99fa79a2861d1980..06169dafb610ac1a076eae5cf43d52be0effeec0 100644 (file)
@@ -7274,6 +7274,10 @@ Voulez-vous en créer un nouveau ?</translation>
 </context>
 <context>
     <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
+    <message>
+        <source>GEOM_CHECK_INTERSECT_TYPE</source>
+        <translation type="unfinished">Self-intersection Detection Type</translation>
+    </message>
     <message>
         <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
         <translation>Auto-intersections</translation>
@@ -7338,6 +7342,14 @@ Voulez-vous en créer un nouveau ?</translation>
         <source>GEOM_CHECK_INTE_ALL</source>
         <translation>Face à Face + tout au-delà</translation>
     </message>
+    <message>
+        <source>GEOM_CHECK_INT_DEFLECT</source>
+        <translation type="unfinished">Deflection coefficient</translation>
+    </message>
+    <message>
+        <source>GEOM_CHECK_INT_DETECT_GAPS</source>
+        <translation type="unfinished">Detect gaps with tolerance</translation>
+    </message>
 </context>
 <context>
     <name>MeasureGUI_FastCheckIntersectionsDlg</name>
index 6efba76e0b9f9bb483c940df350fca65d89633bb..a92a3e60bddedf058303b60e75ed9b91ff8672a0 100644 (file)
   </context>
   <context>
     <name>MeasureGUI_CheckSelfIntersectionsDlg</name>
+    <message>
+      <source>GEOM_CHECK_INTERSECT_TYPE</source>
+      <translation type="unfinished">Self-intersection Detection Type</translation>
+    </message>
     <message>
       <source>GEOM_CHECK_INTE_INTERSECTIONS</source>
       <translation>自己交差</translation>
       <source>GEOM_CHECK_INTE_ALL</source>
       <translation>面から面と上記すべて</translation>
     </message>
+    <message>
+      <source>GEOM_CHECK_INT_DEFLECT</source>
+      <translation type="unfinished">Deflection coefficient</translation>
+    </message>
+    <message>
+      <source>GEOM_CHECK_INT_DETECT_GAPS</source>
+      <translation type="unfinished">Detect gaps with tolerance</translation>
+    </message>
   </context>
   <context>
     <name>MeasureGUI_FastCheckIntersectionsDlg</name>
index d1d23d51c1e14cc86afaae6033dd09e04db557a1..5e33ac622941477a146c23d37991c85d4bdcc1b0 100644 (file)
@@ -50,8 +50,9 @@
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
-#if OCC_VERSION_LARGE > 0x06080000
 #include <BRepExtrema_ShapeProximity.hxx>
+#if OCC_VERSION_LARGE > 0x06090000
+#include <BRepExtrema_SelfIntersection.hxx>
 #endif
 #include <BRepGProp.hxx>
 #include <BRepTools.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
+#include <set>
+
 //=============================================================================
 /*!
  *  Constructor
@@ -1510,7 +1514,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
                           Handle(TColStd_HSequenceOfInteger)& theIntersections)
 {
   SetErrorCode(KO);
-  bool isGood = false;
 
   if (theIntersections.IsNull())
     theIntersections = new TColStd_HSequenceOfInteger;
@@ -1518,13 +1521,13 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
     theIntersections->Clear();
 
   if (theShape.IsNull())
-    return isGood;
+    return false;
 
   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
-  if (aRefShape.IsNull()) return isGood;
+  if (aRefShape.IsNull()) return false;
 
   TopoDS_Shape aShape = aRefShape->GetValue();
-  if (aShape.IsNull()) return isGood;
+  if (aShape.IsNull()) return false;
 
   // 0. Prepare data
   TopoDS_Shape aScopy;
@@ -1546,7 +1549,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
   aCSI.Perform();
   Standard_Integer iErr = aCSI.ErrorStatus();
 
-  isGood = true;
   //
   Standard_Integer aNbS, n1, n2;
   BOPDS_MapIteratorMapOfPassKey aItMPK;
@@ -1570,14 +1572,82 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
 
     theIntersections->Append(anIndices.FindIndex(aS1));
     theIntersections->Append(anIndices.FindIndex(aS2));
-    isGood = false;
   }
 
   if (!iErr) {
     SetErrorCode(OK);
   }
 
-  return isGood;
+  return theIntersections->IsEmpty();
+}
+
+//=============================================================================
+/*!
+ *  CheckSelfIntersectionsFast
+ */
+//=============================================================================
+bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
+                         (Handle(GEOM_Object) theShape,
+                         float theDeflection, double theTolerance,
+                          Handle(TColStd_HSequenceOfInteger)& theIntersections)
+{
+  SetErrorCode(KO);
+
+  if (theIntersections.IsNull())
+    theIntersections = new TColStd_HSequenceOfInteger;
+  else
+    theIntersections->Clear();
+
+  if (theShape.IsNull())
+    return false;
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return false;
+
+  TopoDS_Shape aShape = aRefShape->GetValue();
+  if (aShape.IsNull()) return false;
+
+  // Prepare data
+  TopoDS_Shape aScopy;
+
+  GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
+  GEOMUtils::MeshShape(aScopy, theDeflection);
+
+  // Map sub-shapes and their indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aScopy, anIndices);
+
+#if OCC_VERSION_LARGE > 0x06090000
+  // Checker of fast interferences
+  BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance);
+
+  // Launch the checker
+  aTool.Perform();
+  
+  const BRepExtrema_OverlapTool::OverlapSubShapes& intersections = aTool.OverlapElements();
+  
+  std::set<Standard_Integer> processed;
+  
+  for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator it(intersections); it.More(); it.Next()) {
+    Standard_Integer idxLeft = it.Key();
+    if (processed.count(idxLeft) > 0) continue; // already added
+    processed.insert(idxLeft);
+    const TColStd_PackedMapOfInteger& overlaps = it.Value();
+    for (TColStd_MapIteratorOfPackedMapOfInteger subit(overlaps); subit.More(); subit.Next()) {
+      Standard_Integer idxRight = subit.Key();
+      if (processed.count(idxRight) > 0) continue; // already added
+      const TopoDS_Shape& aS1 = aTool.GetSubShape(idxLeft);
+      const TopoDS_Shape& aS2 = aTool.GetSubShape(idxRight);
+      theIntersections->Append(anIndices.FindIndex(aS1));
+      theIntersections->Append(anIndices.FindIndex(aS2));
+    }
+  }
+
+  if (aTool.IsDone())
+    SetErrorCode(OK);
+#endif
+
+  return theIntersections->IsEmpty();
 }
 
 //=============================================================================
@@ -1593,8 +1663,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
   SetErrorCode(KO);
   bool isGood = false;
 
-#if OCC_VERSION_LARGE > 0x06080000
-
   if (theIntersections1.IsNull())
     theIntersections1 = new TColStd_HSequenceOfInteger;
   else
@@ -1646,12 +1714,22 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
   aBSP.Perform();
  
   // 2. Get sets of IDs of overlapped faces
-  for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) {
+#if OCC_VERSION_LARGE > 0x06090000
+  for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
+#else
+  for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
+#endif
+  {
     const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key());
     theIntersections1->Append(anIndices1.FindIndex(aS1));
   }
   
-  for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) {
+#if OCC_VERSION_LARGE > 0x06090000
+  for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
+#else
+  for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
+#endif
+  {
     const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key());
     theIntersections2->Append(anIndices2.FindIndex(aS2));
   }
@@ -1661,8 +1739,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
   if (aBSP.IsDone())
     SetErrorCode(OK);
 
-#endif // OCC_VERSION_LARGE > 0x06080000
-
   return isGood;
 }
 
index 3798af25eb4e9c779c95436c23c3259e26ac2e3e..e81e5db1f6982de6ed998d86f11cb6967ffc2df8 100644 (file)
@@ -158,6 +158,11 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
                                                const SICheckLevel  theCheckLevel,
                                                Handle(TColStd_HSequenceOfInteger)& theIntersections);
   
+  Standard_EXPORT bool CheckSelfIntersectionsFast (Handle(GEOM_Object) theShape,
+                                                  float  deflection, 
+                                                  double tolerance,
+                                                  Handle(TColStd_HSequenceOfInteger)& theIntersections);
+  
   Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
                                       double tolerance, float deflection,
                                       Handle(TColStd_HSequenceOfInteger)& theIntersections1,
index f75787a3c7317e1a65fdc78e04554c239331e68f..407d71f05f8c972ec0ab716d31181a70b6a0e0ec 100644 (file)
@@ -765,6 +765,49 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Obj
   return isGood;
 }
 
+//=============================================================================
+/*!
+ *  CheckSelfIntersectionsFast
+ */
+//=============================================================================
+CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersectionsFast 
+  (GEOM::GEOM_Object_ptr theShape,
+   CORBA::Float          theDeflection,
+   CORBA::Double         theTolerance,
+   GEOM::ListOfLong_out  theIntersections)
+{
+  // Set a not done flag
+  GetOperations()->SetNotDone();
+
+  bool isGood = false;
+
+  // Allocate the CORBA arrays
+  GEOM::ListOfLong_var anIntegersArray = new GEOM::ListOfLong();
+
+  // Get the reference shape
+  Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
+
+  if (!aShape.IsNull()) {
+    Handle(TColStd_HSequenceOfInteger) anIntegers = new TColStd_HSequenceOfInteger;
+
+    // Detect self-intersections
+    isGood = GetOperations()->CheckSelfIntersectionsFast
+      (aShape, theDeflection, theTolerance, anIntegers);
+
+    int nbInts = anIntegers->Length();
+
+    anIntegersArray->length(nbInts);
+
+    for (int ii = 0; ii < nbInts; ii++) {
+      anIntegersArray[ii] = anIntegers->Value(ii + 1);
+    }
+  }
+
+  // Initialize out-parameters with local arrays
+  theIntersections = anIntegersArray._retn();
+  return isGood;
+}
+
 //=============================================================================
 /*!
  *  FastIntersect
index 27e2e5d429e67eacd5e4e4eb18d8e804df9ff2ed..71e6194bac7780562f53a23b4024fe35d34366cd 100644 (file)
@@ -100,6 +100,11 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
                                          CORBA::Long           theCheckLevel,
                                          GEOM::ListOfLong_out  theIntersections);
 
+  CORBA::Boolean CheckSelfIntersectionsFast (GEOM::GEOM_Object_ptr theShape,
+                                            CORBA::Float          theDeflection,
+                                            CORBA::Double         theTolerance,
+                                            GEOM::ListOfLong_out  theIntersections);
+
   CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1,
                                 GEOM::GEOM_Object_ptr theShape2,
                                 CORBA::Double         theTolerance,
index 87c9a0d1104fb2cbf075fcd59fb165d609a04597..7ad571552f9104b8b77ad2422c0a9cf514ac96cf 100644 (file)
@@ -33,8 +33,12 @@ def TestMeasureOperations (geompy, math):
   p678 = geompy.MakeVertex(60, 70, 80)
   p789 = geompy.MakeVertex(70, 80, 90)
 
+  vz = geompy.MakeVectorDXDYDZ(0, 0, 1)
+
   cube = geompy.MakeBoxTwoPnt(p678, p789)
 
+  cylinder = geompy.MakeCylinder(p0, vz, 5, 70)
+
   ####### PointCoordinates #######
 
   Coords = geompy.PointCoordinates(p137)
@@ -52,18 +56,20 @@ def TestMeasureOperations (geompy, math):
 
   ####### Detect Self-intersections #######
 
-  [Face_1,Face_2] = geompy.SubShapes(box, [33, 23])
-  Translation_1 = geompy.MakeTranslation(Face_1, 5, -15, -40)
-  Compound_1 = geompy.MakeCompound([Face_2, Translation_1])
-  if geompy.CheckSelfIntersections(Compound_1) == True:
+  selfIntersected = geompy.MakeCompound([box, cylinder])
+  if geompy.CheckSelfIntersections(selfIntersected):
     raise RuntimeError, "Existing self-intersection is not detected"
 
-  ####### Detect Fast intersection #######
+  ####### Detect Self-intersections fast #######
+
+  if salome_version.getXVersion() > "0x70600":
+    if geompy.CheckSelfIntersectionsFast(selfIntersected):
+      raise RuntimeError, "Existing self-intersection is not detected"
+
+  ####### Fast intersection #######
 
-  if salome_version.getXVersion() > "0x70501":
-    cylinder = geompy.MakeCylinderRH(100, 300)
-    if geompy.FastIntersect(box, cylinder)[0] == False:
-      raise RuntimeError, "Existing intersection is not detected"
+  if not geompy.FastIntersect(box, cylinder)[0]:
+    raise RuntimeError, "Existing intersection is not detected"
 
   ####### WhatIs #######
 
index f932a632a2147d3fdb7c85af77f1f971c30c5b88..982a45dc581edc3c72376d3ad3a80e2f7373c334 100644 (file)
@@ -11257,6 +11257,37 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             RaiseIfFailed("CheckSelfIntersections", self.MeasuOp)
             return IsValid
 
+        ## Detect self-intersections of the given shape with algorithm based on mesh intersections.
+        #  @param theShape Shape to check.
+        #  @param theDeflection Linear deflection coefficient that specifies quality of tesselation:
+        #         - if \a theDeflection <= 0, default deflection 0.001 is used
+        #  @param theTolerance Specifies a distance between sub-shapes used for detecting gaps:
+        #         - if \a theTolerance <= 0, algorithm detects intersections (default behavior)
+        #         - if \a theTolerance > 0, algorithm detects gaps
+        #  @return TRUE, if the shape contains no self-intersections.
+        #
+        #  @ref tui_check_self_intersections_fast_page "Example"
+        @ManageTransactions("MeasuOp")
+        def CheckSelfIntersectionsFast(self, theShape, theDeflection = 0.001, theTolerance = 0.0):
+            """
+            Detect self-intersections of the given shape with algorithm based on mesh intersections.
+
+            Parameters:
+                theShape Shape to check.
+                theDeflection Linear deflection coefficient that specifies quality of tesselation:
+                    - if theDeflection <= 0, default deflection 0.001 is used
+                theTolerance Specifies a distance between shapes used for detecting gaps:
+                    - if theTolerance <= 0, algorithm detects intersections (default behavior)
+                    - if theTolerance > 0, algorithm detects gaps
+            Returns:
+                TRUE, if the shape contains no self-intersections.
+            """
+            # Example: see GEOM_TestMeasures.py
+            (IsValid, Pairs) = self.MeasuOp.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance)
+            RaiseIfFailed("CheckSelfIntersectionsFast", self.MeasuOp)
+            return IsValid
+
         ## Detect intersections of the given shapes with algorithm based on mesh intersections.
         #  @param theShape1 First source object
         #  @param theShape2 Second source object
index a07e919e5be3e09e1e073d784fc593d011e49051..97b3d170eedfaea1bfeb7bd1c7112d35f34016c0 100644 (file)
@@ -26,6 +26,7 @@
 #include "MeasureGUI_CheckSelfIntersectionsDlg.h"
 #include "MeasureGUI.h"
 
+#include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
 //=================================================================================
 MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent)
   : GEOMBase_Skeleton (GUI, parent, false),
-    myTextView        (0),
-    mySelButton       (0),
-    myEditObjName     (0),
+    myTextView1       (0),
+    myTextView2       (0),
+    mySelButton1      (0),
+    mySelButton2      (0),
+    myEditObjName1    (0),
+    myEditObjName2    (0),
     myLevelBox        (0),
-    myComputeButton   (0),
-    myInteList        (0),
-    myShapeList       (0)
+    myComputeButton1  (0),
+    myComputeButton2  (0),
+    myInteList1       (0),
+    myShapeList1      (0),
+    myInteList2       (0),
+    myShapeList2      (0),
+    myCurrConstrId    (-1)
 {
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS")));
   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
+  QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FAST_CHECK_INTERSECTIONS")));
 
   setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS"));
 
   /***************************************************************/
-  mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS"));
+  mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_INTERSECT_TYPE"));
   mainFrame()->RadioButton1->setIcon(image0);
-  mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
-  mainFrame()->RadioButton2->close();
+  mainFrame()->RadioButton2->setIcon(image2);;
   mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
   mainFrame()->RadioButton3->close();
 
-  QGroupBox *aGrp      = new QGroupBox(tr("GEOM_CHECK_INFOS"));
-  QLabel    *anObjLbl  = new QLabel(tr("GEOM_OBJECT"));
-  QLabel    *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"));
-  QLabel    *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"));
-  QLabel    *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL"));
-  QLabel    *aSummaryLbl = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
+  /***************************************************************/
+  /* SIMPLE SELF-INTERSECTION constructor
+  /***************************************************************/
+  mySimpleGrp             = new QGroupBox(tr("GEOM_CHECK_INFOS"));
+  QLabel    *anObjLbl    = new QLabel(tr("GEOM_OBJECT"));
+  QLabel    *anInteLbl   = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"));
+  QLabel    *aShapeLbl   = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"));
+  QLabel    *aLevelLbl   = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL"));
+  QLabel    *aSummaryLbl1 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
   QFont      aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE);
 
   aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias);
-  myTextView = new QTextBrowser;
-  myTextView->setReadOnly(true);
-  myTextView->setFont(aFont);
+  myTextView1 = new QTextBrowser;
+  myTextView1->setReadOnly(true);
+  myTextView1->setFont(aFont);
 
-  mySelButton = new QPushButton;
-  mySelButton->setIcon(image1);
-  mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+  mySelButton1 = new QPushButton;
+  mySelButton1->setIcon(image1);
+  mySelButton1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
 
-  myEditObjName = new QLineEdit;
-  myEditObjName->setReadOnly(true);
+  myEditObjName1 = new QLineEdit;
+  myEditObjName1->setReadOnly(true);
 
   myLevelBox = new QComboBox;
 
-  myComputeButton = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
+  myComputeButton1 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
 
 
-  myInteList  = new QListWidget;
-  myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection);
-  myShapeList = new QListWidget;
-  myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  myInteList1  = new QListWidget;
+  myInteList1->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  myShapeList1 = new QListWidget;
+  myShapeList1->setSelectionMode(QAbstractItemView::ExtendedSelection);
 
-  QGridLayout *aGrpLayout = new QGridLayout(aGrp);
+  QGridLayout *aGrpLayout1 = new QGridLayout(mySimpleGrp);
 
-  aGrpLayout->setMargin(9);
-  aGrpLayout->setSpacing(6);
-  aGrpLayout->addWidget(anObjLbl,        0, 0);
-  aGrpLayout->addWidget(anInteLbl,       5, 0);
-  aGrpLayout->addWidget(aShapeLbl,       5, 2);
-  aGrpLayout->addWidget(aLevelLbl,       1, 0);
-  aGrpLayout->addWidget(myLevelBox,      1, 1, 1, 2);
-  aGrpLayout->addWidget(myComputeButton, 2, 0, 1, 3);
-  aGrpLayout->addWidget(aSummaryLbl,     3, 0);
-  aGrpLayout->addWidget(myTextView,      4, 0, 1, 3);
-  aGrpLayout->addWidget(mySelButton,     0, 1);
-  aGrpLayout->addWidget(myEditObjName,   0, 2);
-  aGrpLayout->addWidget(myInteList,      6, 0, 1, 2);
-  aGrpLayout->addWidget(myShapeList,     6, 2);
-
-  QVBoxLayout* layout = new QVBoxLayout (centralWidget());
-  layout->setMargin(0); layout->setSpacing(6);
-  layout->addWidget(aGrp);
+  aGrpLayout1->setMargin(9);
+  aGrpLayout1->setSpacing(6);
+  aGrpLayout1->addWidget(anObjLbl,         0, 0);
+  aGrpLayout1->addWidget(mySelButton1,     0, 1);
+  aGrpLayout1->addWidget(myEditObjName1,   0, 2);
+  aGrpLayout1->addWidget(aLevelLbl,        1, 0);
+  aGrpLayout1->addWidget(myLevelBox,       1, 1, 1, 2);
+  aGrpLayout1->addWidget(myComputeButton1, 2, 0, 1, 3);
+  aGrpLayout1->addWidget(aSummaryLbl1,     3, 0);
+  aGrpLayout1->addWidget(myTextView1,      4, 0, 1, 3);
+  aGrpLayout1->addWidget(anInteLbl,        5, 0);
+  aGrpLayout1->addWidget(aShapeLbl,        5, 2);
+  aGrpLayout1->addWidget(myInteList1,      6, 0, 1, 2);
+  aGrpLayout1->addWidget(myShapeList1,     6, 2);
 
+  /***************************************************************/
+  /* FAST SELF-INTERSECTION constructor
+  /***************************************************************/
+  
+  myFastGrp               = new QGroupBox(tr("GEOM_CHECK_INFOS"), centralWidget());
+  QLabel    *anObjLbl2    = new QLabel(tr("GEOM_OBJECT"), myFastGrp);
+  QLabel    *aDeflectLbl  = new QLabel(tr("GEOM_CHECK_INT_DEFLECT"), myFastGrp);
+  QLabel    *aSummaryLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
+  QLabel    *anInteLbl2   = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"), myFastGrp);
+  QLabel    *aShapeLbl2   = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"), myFastGrp);
+
+  mySelButton2 = new QPushButton(myFastGrp);
+  mySelButton2->setIcon(image1);
+  mySelButton2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+  myEditObjName2 = new QLineEdit(myFastGrp);
+  myEditObjName2->setReadOnly(true);
+
+  myDeflection = new SalomeApp_DoubleSpinBox(myFastGrp);
+  myDetGaps = new QCheckBox(tr( "GEOM_CHECK_INT_DETECT_GAPS" ));
+  myTolerance = new SalomeApp_DoubleSpinBox(myFastGrp);
+
+  myComputeButton2 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
+
+  myTextView2 = new QTextBrowser;
+  myTextView2->setReadOnly(true);
+  myTextView2->setFont(aFont);
+
+  myInteList2  = new QListWidget(myFastGrp);
+  myInteList2->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  myShapeList2 = new QListWidget(myFastGrp);
+  myShapeList2->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+  QGridLayout *aGrpLayout2 = new QGridLayout(myFastGrp);
+  aGrpLayout2->setMargin(9);
+  aGrpLayout2->setSpacing(6);
+  aGrpLayout2->addWidget(anObjLbl2,        0, 0);
+  aGrpLayout2->addWidget(mySelButton2,     0, 1);
+  aGrpLayout2->addWidget(myEditObjName2,   0, 2);
+  aGrpLayout2->addWidget(aDeflectLbl,      1, 0);
+  aGrpLayout2->addWidget(myDeflection,     1, 1, 1, 2);
+  aGrpLayout2->addWidget(myDetGaps,        2, 0);
+  aGrpLayout2->addWidget(myTolerance,      2, 1, 1, 2);
+  aGrpLayout2->addWidget(myComputeButton2, 3, 0, 1, 3);
+  aGrpLayout2->addWidget(aSummaryLbl2,     4, 0);
+  aGrpLayout2->addWidget(myTextView2,      5, 0, 1, 3);
+  aGrpLayout2->addWidget(anInteLbl2,       6, 0);
+  aGrpLayout2->addWidget(aShapeLbl2,       6, 1, 1, 2);
+  aGrpLayout2->addWidget(myInteList2,      7, 0);
+  aGrpLayout2->addWidget(myShapeList2,     7, 1, 1, 2);
+  
   /***************************************************************/
 
+  QVBoxLayout* layout2 = new QVBoxLayout (centralWidget());
+  layout2->setMargin(0); layout2->setSpacing(6);
+  layout2->addWidget(mySimpleGrp);
+  layout2->addWidget(myFastGrp);
+
+ /***************************************************************/
+
   myHelpFileName = "check_self_intersections_page.html";
 
   /* Initialisation */
@@ -161,32 +226,65 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
   myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F"));
   myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL"));
   myLevelBox->setCurrentIndex(GEOM::SI_ALL);
+  myComputeButton1->setEnabled(false);
 
-  connect(myGeomGUI,          SIGNAL(SignalDeactivateActiveDialog()),
-          this,               SLOT(DeactivateActiveDialog()));
-  connect(myGeomGUI,          SIGNAL(SignalCloseAllDialogs()),
-          this,               SLOT(ClickOnCancel()));
-  connect(buttonOk(),         SIGNAL(clicked()), this, SLOT(ClickOnOk()));
-  connect(buttonApply(),      SIGNAL(clicked()), this, SLOT(ClickOnApply()));
-  connect(mySelButton,        SIGNAL(clicked()),
+  connect(mySelButton1,        SIGNAL(clicked()),
           this,               SLOT(SetEditCurrentArgument()));
-  connect(myInteList,         SIGNAL(itemSelectionChanged()),
+  connect(myInteList1,         SIGNAL(itemSelectionChanged()),
           SLOT(onInteListSelectionChanged()));
-  connect(myShapeList,        SIGNAL(itemSelectionChanged()),
+  connect(myShapeList1,        SIGNAL(itemSelectionChanged()),
           SLOT(onSubShapesListSelectionChanged()));
   connect(myLevelBox,         SIGNAL(currentIndexChanged(int)),
           this,               SLOT(clear()));
-  connect(myComputeButton,    SIGNAL(clicked()), this, SLOT(onCompute()));
+  connect(myComputeButton1,    SIGNAL(clicked()), this, SLOT(onCompute()));
 
-  LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
+  /***************************************************************/
+  myObj2.nullify();
+  myEditObjName2->setText("");
+  myEditObjName2->setEnabled(true);
+
+  myDetGaps->setChecked(false);
+  initSpinBox(myTolerance, 0, MAX_NUMBER, 1);
+  myTolerance->setValue(0);
+  myTolerance->setEnabled(false);
+  myComputeButton2->setEnabled(false);
+
+  // Obtain deflection from preferences
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  initSpinBox(myDeflection, 1e-3, 1.0, 1e-3);
+  myDeflection->setValue(qMax(1e-3, resMgr->doubleValue("Geometry", "deflection_coeff", 1e-3)));
+
+  connect( mySelButton2,       SIGNAL(clicked()),
+          this,               SLOT(SetEditCurrentArgument()));
+  connect( myDetGaps,          SIGNAL(toggled(bool)), this, SLOT(OnGaps(bool))); 
+  connect( myTolerance,       SIGNAL(valueChanged(double)), this, SLOT(clear()));
+  connect( myDeflection,      SIGNAL(valueChanged(double)), this, SLOT(clear()));
+  connect( myInteList2,         SIGNAL(itemSelectionChanged()),
+          SLOT(onInteListSelectionChanged()));
+  connect( myShapeList2,       SIGNAL(itemSelectionChanged()),
+          SLOT(onSubShapesListSelectionChanged()));
+  connect( myComputeButton2,    SIGNAL(clicked()), this, SLOT(onCompute()));
 
+  /***************************************************************/
+
+  connect(this,               SIGNAL(constructorsClicked(int)), 
+         this,               SLOT(ConstructorsClicked(int)));
+  connect(myGeomGUI,          SIGNAL(SignalDeactivateActiveDialog()),
+          this,               SLOT(DeactivateActiveDialog()));
+  connect(myGeomGUI,          SIGNAL(SignalCloseAllDialogs()),
+          this,               SLOT(ClickOnCancel()));
+  connect(buttonOk(),         SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply(),      SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
   connect(aSel,               SIGNAL(currentSelectionChanged()),
           this,               SLOT(SelectionIntoArgument()));
 
   initName( tr( "GEOM_SELF_INTERSECTION_NAME") );
   buttonOk()->setEnabled(false);
   buttonApply()->setEnabled(false);
-  myComputeButton->setEnabled(false);
+
+  ConstructorsClicked(0);
+
   activateSelection();
   SelectionIntoArgument();
 }
@@ -197,20 +295,56 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
 //=================================================================================
 void MeasureGUI_CheckSelfIntersectionsDlg::clear()
 {
-  myTextView->setText("");
+  getTextView()->setText("");
+  getComputeButton()->setEnabled(true);
 
-  myInteList->blockSignals(true);
-  myShapeList->blockSignals(true);
-  myInteList->clear();
-  myShapeList->clear();
-  myInteList->blockSignals(false);
-  myShapeList->blockSignals(false);
+  getInteList()->blockSignals(true);
+  getShapeList()->blockSignals(true);
+  getInteList()->clear();
+  getShapeList()->clear();
+  getInteList()->blockSignals(false);
+  getShapeList()->blockSignals(false);
 
   erasePreview();
-
   buttonOk()->setEnabled(false);
   buttonApply()->setEnabled(false);
-  myComputeButton->setEnabled(true);
+}
+
+//=================================================================================
+// function : ConstructorsClicked()
+// purpose  : Radio button management
+//=================================================================================
+void MeasureGUI_CheckSelfIntersectionsDlg::ConstructorsClicked(int constructorId)
+{
+  if (myCurrConstrId == constructorId)
+    return;
+
+  disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
+
+  switch (constructorId) {
+  case 0:
+    mySimpleGrp->show();
+    myFastGrp->hide();
+    break;
+  case 1:
+    mySimpleGrp->hide();
+    myFastGrp->show();
+    break;
+  }
+
+  myCurrConstrId = constructorId;
+
+  connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+           this, SLOT(SelectionIntoArgument()));
+
+  qApp->processEvents();
+  updateGeometry();
+  resize(minimumSizeHint());
+
+  processPreview();
+  //updateButtonState();
+  activateSelection();
+  SelectionIntoArgument();
 }
 
 //=================================================================================
@@ -223,7 +357,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
   QString anErrMsg("");
 
   if (!findSelfIntersections(hasSelfInte, anErrMsg)) {
-    myTextView->setText(anErrMsg);
+    getTextView()->setText(anErrMsg);
     return;
   }
 
@@ -243,12 +377,12 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
     aMsg += anErrMsg;
   }
 
-  myTextView->setText(aMsg);
+  getTextView()->setText(aMsg);
 
   // Pairs
   QStringList anInteList;
   QString anInteStr ("");
-  int nbPairs = myInters->length()/2;
+  int nbPairs = getInters()->length()/2;
 
   for (int i = 1; i <= nbPairs; i++) {
     anInteStr = "Intersection # ";
@@ -256,8 +390,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
     anInteList.append(anInteStr);
   }
 
-  myInteList->addItems(anInteList);
-  myComputeButton->setEnabled(false);
+  getInteList()->addItems(anInteList);
+  getComputeButton()->setEnabled(false);
 }
 
 //=================================================================================
@@ -291,7 +425,23 @@ void MeasureGUI_CheckSelfIntersectionsDlg::DeactivateActiveDialog()
 //=================================================================================
 void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection()
 {
-  globalSelection(GEOM_ALLSHAPES);
+  switch (getConstructorId()) {
+  case 0:
+    globalSelection(GEOM_ALLSHAPES);
+    break;
+  case 1:
+    TColStd_MapOfInteger aTypes;
+    aTypes.Add(GEOM_COMPOUND );
+    aTypes.Add(GEOM_SOLID );
+    aTypes.Add(GEOM_SHELL);
+    aTypes.Add(GEOM_FACE);
+    globalSelection(aTypes);
+
+    std::list<int> needTypes;
+    needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND );
+    localSelection(GEOM::GEOM_Object::_nil(), needTypes );
+    break;
+  }
 }
 
 //=================================================================================
@@ -313,7 +463,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply()
   if ( !onAccept() )
     return false;
 
+  clear();
   initName();
+
+  ConstructorsClicked(getConstructorId());
+
   return true;
 }
 
@@ -341,7 +495,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation
 //=================================================================================
 bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
 {
-  return !myObj->_is_nil();
+  return !getObj().isNull();
 }
 
 //=================================================================================
@@ -350,37 +504,51 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
 //=================================================================================
 void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument()
 {
-  myEditObjName->setFocus();
+  getEditObjName()->setFocus();
   SelectionIntoArgument();
 }
 
+//=================================================================================
+// function : OnGaps()
+// purpose  :
+//=================================================================================
+void MeasureGUI_CheckSelfIntersectionsDlg::OnGaps(bool checked)
+{
+  clear();
+  myTolerance->setEnabled(checked);
+}
 //=================================================================================
 // function : SelectionIntoArgument
 // purpose  :
 //=================================================================================
 void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument()
 {
+  QList<TopAbs_ShapeEnum> typesLst;
+
+  if ( getConstructorId() == 0 ) {
+    typesLst << TopAbs_COMPOUND
+            << TopAbs_COMPSOLID
+            << TopAbs_SOLID
+            << TopAbs_SHELL
+            << TopAbs_FACE
+            << TopAbs_WIRE
+            << TopAbs_EDGE
+            << TopAbs_VERTEX
+            << TopAbs_SHAPE;
+  } else {
+    typesLst << TopAbs_FACE
+            << TopAbs_SHELL
+            << TopAbs_SOLID
+            << TopAbs_COMPOUND;
+  }
+
   // Clear the dialog.
   clear();
-  myObj = GEOM::GEOM_Object::_nil();
-
-  LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
-  SALOME_ListIO aSelList;
-  aSelMgr->selectedObjects(aSelList);
-
-  GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil();
 
-  if (aSelList.Extent() > 0) {
-    aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
-  }
-
-  if (aSelectedObject->_is_nil()) {
-    myEditObjName->setText("");
-    return;
-  }
+  GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst );
 
-  myObj = aSelectedObject;
-  myEditObjName->setText(GEOMBase::GetName(myObj));
+  (getConstructorId() == 0 ? myObj1 :myObj2) = aSelectedObject;
+  getEditObjName()->setText(getObj() ? GEOMBase::GetName(getObj().get()) : "");
 }
 
 //=================================================================================
@@ -400,7 +568,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::enterEvent(QEvent *)
 bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
         (bool &HasSelfInte, QString &theErrMsg)
 {
-  if (myObj->_is_nil()) {
+  if (getObj()->_is_nil()) {
     return false;
   }
 
@@ -413,10 +581,14 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
   SUIT_OverrideCursor wc;
 
   try {
-    HasSelfInte = !anOper->CheckSelfIntersections(myObj, aLevel, myInters);
-    nbPairs = myInters->length()/2;
+    if ( getConstructorId() == 0 ) {
+      HasSelfInte = !anOper->CheckSelfIntersections(myObj1.get(), aLevel, myInters1);
+    } else {
+      HasSelfInte = !anOper->CheckSelfIntersectionsFast(myObj2.get(), getDeflection(), getTolerance(), myInters2);
+    }
+    nbPairs = getInters()->length()/2;
 
-    if (nbPairs*2 != myInters->length()) {
+    if (nbPairs*2 != getInters()->length()) {
       isOK = false;
     }
   }
@@ -426,7 +598,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
   }
 
   if (!anOper->IsDone()) {
-    if (myInters->length() == 0) {
+    if (getInters()->length() == 0) {
       theErrMsg = tr(anOper->GetErrorCode());
       isOK = false;
     } else {
@@ -447,24 +619,24 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
 void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged()
 {
   erasePreview();
-  myShapeList->clear();
+  getShapeList()->clear();
 
   TopoDS_Shape aSelShape;
-  if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
+  if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) {
     TopTools_IndexedMapOfShape anIndices;
     TopExp::MapShapes(aSelShape, anIndices);
 
-    int nbSelected = myInteList->selectedItems().size();
+    int nbSelected = getInteList()->selectedItems().size();
 
-    for (int i = 0; i < myInteList->count(); i++) {
-      if ( myInteList->item(i)->isSelected() ) {
+    for (int i = 0; i < getInteList()->count(); i++) {
+      if ( getInteList()->item(i)->isSelected() ) {
         if ( nbSelected > 1 )
-          myShapeList->addItem(QString("--- #%1 ---").arg(i+1));
+          getShapeList()->addItem(QString("--- #%1 ---").arg(i+1));
         for (int j = 0; j < 2; j++) {
-          TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]);
+          TopoDS_Shape aSubShape = anIndices.FindKey(getInters()[i*2+j]);
           QString aType = GEOMBase::GetShapeTypeString(aSubShape);
-          myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j]));
-          myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]);
+          getShapeList()->addItem(QString("%1_%2").arg(aType).arg(getInters()[i*2+j]));
+          getShapeList()->item(getShapeList()->count()-1)->setData(Qt::UserRole, getInters()[i*2+j]);
         }
       }
     }
@@ -480,7 +652,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
   erasePreview();
 
   // Selected IDs
-  QList<QListWidgetItem*> selected = myShapeList->selectedItems();
+  QList<QListWidgetItem*> selected = getShapeList()->selectedItems();
   QList<int> aIds;
   foreach(QListWidgetItem* item, selected) {
     int idx = item->data(Qt::UserRole).toInt();
@@ -492,7 +664,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
   TopoDS_Shape aSelShape;
   TopoDS_Shape aSubShape;
   TopTools_IndexedMapOfShape anIndices;
-  if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
+  if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) {
     TopExp::MapShapes(aSelShape, anIndices);
     getDisplayer()->SetColor(Quantity_NOC_RED);
     getDisplayer()->SetWidth(3);
@@ -500,11 +672,11 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
     foreach(int idx, aIds) {
       aSubShape = anIndices.FindKey(idx);
       try {
-        SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0;
-        if (aPrs) displayPreview(aPrs, true);
+       SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0;
+       if (aPrs) displayPreview(aPrs, true);
       }
       catch (const SALOME::SALOME_Exception& e) {
-        SalomeApp_Tools::QtCatchCorbaException(e);
+       SalomeApp_Tools::QtCatchCorbaException(e);
       }
     }
   }
@@ -526,15 +698,15 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
   TColStd_IndexedMapOfInteger aMapIndex;
   QList<int> pairs;
 
-  int nbSelected = myInteList->selectedItems().size();
+  int nbSelected = getInteList()->selectedItems().size();
 
   // Collect the map of indices
-  for (int i = 0; i < myInteList->count(); i++) {
-    if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) {
-      aMapIndex.Add(myInters[i*2]);
-      aMapIndex.Add(myInters[i*2 + 1]);
-      pairs << myInters[i*2];
-      pairs << myInters[i*2 + 1];
+  for (int i = 0; i < getInteList()->count(); i++) {
+    if ( nbSelected < 1 || getInteList()->item(i)->isSelected() ) {
+      aMapIndex.Add(getInters()[i*2]);
+      aMapIndex.Add(getInters()[i*2 + 1]);
+      pairs << getInters()[i*2];
+      pairs << getInters()[i*2 + 1];
     }
   }
 
@@ -547,7 +719,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
   for (int i = 1; i <= aMapIndex.Extent(); i++)
     anArray[i-1] = aMapIndex.FindKey(i);
 
-  GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray);
+  GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(getObj().get(), anArray);
 
   // Make compounds
   for (int i = 0; i < pairs.count()/2; i++) {
@@ -562,6 +734,27 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
   return true;
 }
 
+//=================================================================================
+// function : getDeflection
+// purpose  :
+//=================================================================================
+float MeasureGUI_CheckSelfIntersectionsDlg::getDeflection()
+{
+  return (float)myDeflection->value();
+}
+
+//=================================================================================
+// function : getTolerance
+// purpose  :
+//=================================================================================
+double MeasureGUI_CheckSelfIntersectionsDlg::getTolerance()
+{
+  double aVal = myTolerance->value();
+  if (!myDetGaps->isChecked() || aVal < 0.0)
+    return 0.0;
+  return aVal;
+}
+
 //================================================================
 // Function : getFather
 // Purpose  : Get father object for object to be added in study
@@ -570,5 +763,54 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
 GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather
                   (GEOM::GEOM_Object_ptr)
 {
-  return myObj;
+  return getObj().get();
+}
+
+//=================================================================================
+// function : getSourceObjects
+// purpose  : virtual method to get source objects
+//=================================================================================
+QList<GEOM::GeomObjPtr> MeasureGUI_CheckSelfIntersectionsDlg::getSourceObjects()
+{
+  QList<GEOM::GeomObjPtr> res;
+  res << getObj();
+  return res;
+}
+
+//=================================================================================
+// GETTERS
+//=================================================================================
+QTextBrowser* MeasureGUI_CheckSelfIntersectionsDlg::getTextView()
+{
+  return ( getConstructorId() == 0 ? myTextView1 : myTextView2 );
+}
+
+QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getInteList()
+{
+  return ( getConstructorId() == 0 ? myInteList1 : myInteList2 );
+}
+
+QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getShapeList()
+{
+  return ( getConstructorId() == 0 ? myShapeList1 : myShapeList2 );
+}
+
+QPushButton* MeasureGUI_CheckSelfIntersectionsDlg::getComputeButton()
+{
+  return ( getConstructorId() == 0 ? myComputeButton1 : myComputeButton2 );
+}
+
+QLineEdit* MeasureGUI_CheckSelfIntersectionsDlg::getEditObjName()
+{
+  return ( getConstructorId() == 0 ? myEditObjName1 : myEditObjName2 );
+}
+
+GEOM::GeomObjPtr MeasureGUI_CheckSelfIntersectionsDlg::getObj()
+{
+  return ( getConstructorId() == 0 ? myObj1 : myObj2 );
+}
+
+GEOM::ListOfLong_var MeasureGUI_CheckSelfIntersectionsDlg::getInters()
+{
+  return ( getConstructorId() == 0 ? myInters1 : myInters2 );
 }
index f05dd81096e0950b074c10f17db9a7aac7efde6d..ac0f2d935d962d5f11a3a28010de29c70c4d283f 100644 (file)
@@ -54,6 +54,7 @@ protected:
   virtual bool                        execute(ObjectList &);
   virtual bool                        extractPrefix() const;
   virtual GEOM::GEOM_Object_ptr       getFather (GEOM::GEOM_Object_ptr);
+  virtual QList<GEOM::GeomObjPtr>     getSourceObjects();
 
 private slots:
 
@@ -67,6 +68,9 @@ private slots:
   void                                DeactivateActiveDialog();
   void                                SelectionIntoArgument();
   void                                SetEditCurrentArgument();
+  void                                ConstructorsClicked (int);
+  void                                OnGaps(bool);
+
 
 private:
 
@@ -76,18 +80,46 @@ private:
   bool                                findSelfIntersections
                                                     (bool    &HasSelfInte,
                                                      QString &theErrMsg);
+  float                               getDeflection();
+  double                              getTolerance();
+  
+// Getters
+  QTextBrowser*                       getTextView();
+  QListWidget*                        getInteList();
+  QListWidget*                        getShapeList();
+  QPushButton*                        getComputeButton();
+  QLineEdit*                          getEditObjName();
+  GEOM::GeomObjPtr                    getObj();
+  GEOM::ListOfLong_var                getInters();
 
-private:
 
-  QTextBrowser                       *myTextView;
-  QPushButton                        *mySelButton;
-  QLineEdit                          *myEditObjName;
+private:
+  int                                 myCurrConstrId;
+  // simple
+  QPushButton                        *myComputeButton1;
+  QGroupBox                          *mySimpleGrp;
+  QTextBrowser                       *myTextView1;
+  QPushButton                        *mySelButton1;
+  QLineEdit                          *myEditObjName1;
   QComboBox                          *myLevelBox;
-  QPushButton                        *myComputeButton;
-  QListWidget                        *myInteList;
-  QListWidget                        *myShapeList;
-  GEOM::GEOM_Object_var               myObj;
-  GEOM::ListOfLong_var                myInters;
+  QListWidget                        *myInteList1;
+  QListWidget                        *myShapeList1;
+  GEOM::GeomObjPtr                    myObj1;
+  GEOM::ListOfLong_var                myInters1;
+  // fast
+  QPushButton                        *myComputeButton2;
+  QGroupBox                          *myFastGrp;
+  QTextBrowser                       *myTextView2;
+  QPushButton                        *mySelButton2;
+  QLineEdit                          *myEditObjName2;
+  QCheckBox                          *myDetGaps;
+  SalomeApp_DoubleSpinBox            *myTolerance;
+  SalomeApp_DoubleSpinBox            *myDeflection;
+  QListWidget                        *myInteList2;
+  QListWidget                        *myShapeList2;
+  GEOM::GeomObjPtr                    myObj2;
+  GEOM::ListOfLong_var                myInters2;
+  GEOM::GEOM_IShapesOperations_var    myShapesOper;
 };
 
 #endif // MEASUREGUI_CHECKSELFINTERDLG_H