Salome HOME
Copyright update 2022
[modules/geom.git] / src / MeasureGUI / MeasureGUI_CheckSelfIntersectionsDlg.cxx
index de58de84c5a9d356457fe1d8b7ad9f9781071b60..6c626af4597c2ca1286a7307c9e33f1d496301c1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -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>
@@ -42,6 +43,7 @@
 #include <GeometryGUI.h>
 #include <GEOMBase.h>
 #include <GEOMImpl_Types.hxx>
+#include <GEOM_GenericObjPtr.h>
 
 #include <QListWidget>
 
 //=================================================================================
 MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent)
   : GEOMBase_Skeleton (GUI, parent, false),
-    myTextView        (0),
-    mySelButton       (0),
-    myEditObjName     (0),
+    myCurrConstrId    (-1),
+    myComputeButton1  (0),
+    myTextView1       (0),
+    mySelButton1      (0),
+    myEditObjName1    (0),
     myLevelBox        (0),
-    myComputeButton   (0),
-    myInteList        (0),
-    myShapeList       (0)
+    myInteList1       (0),
+    myShapeList1      (0),
+    myComputeButton2  (0),
+    myTextView2       (0),
+    mySelButton2      (0),
+    myEditObjName2    (0),
+    myInteList2       (0),
+    myShapeList2      (0)
 {
   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;
-  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";
 
@@ -159,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();
 }
@@ -195,19 +295,56 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
 //=================================================================================
 void MeasureGUI_CheckSelfIntersectionsDlg::clear()
 {
-  myTextView->setText("");
-  disconnect(myInteList, SIGNAL(itemSelectionChanged()), this, 0);
-  disconnect(myShapeList, SIGNAL(itemSelectionChanged()), this, 0);
-  myInteList->clear();
-  myShapeList->clear();
-  connect(myInteList,    SIGNAL(itemSelectionChanged()),
-          SLOT(onInteListSelectionChanged()));
-  connect(myShapeList,    SIGNAL(itemSelectionChanged()),
-          SLOT(onSubShapesListSelectionChanged()));
+  getTextView()->setText("");
+  getComputeButton()->setEnabled(true);
+
+  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();
 }
 
 //=================================================================================
@@ -220,7 +357,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
   QString anErrMsg("");
 
   if (!findSelfIntersections(hasSelfInte, anErrMsg)) {
-    myTextView->setText(anErrMsg);
+    getTextView()->setText(anErrMsg);
     return;
   }
 
@@ -240,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 # ";
@@ -253,8 +390,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
     anInteList.append(anInteStr);
   }
 
-  myInteList->addItems(anInteList);
-  myComputeButton->setEnabled(false);
+  getInteList()->addItems(anInteList);
+  getComputeButton()->setEnabled(false);
 }
 
 //=================================================================================
@@ -288,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( needTypes );
+    break;
+  }
 }
 
 //=================================================================================
@@ -310,7 +463,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply()
   if ( !onAccept() )
     return false;
 
+  clear();
   initName();
+
+  ConstructorsClicked(getConstructorId());
+
   return true;
 }
 
@@ -329,7 +486,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::extractPrefix() const
 //=================================================================================
 GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation()
 {
-  return getGeomEngine()->GetIMeasureOperations( getStudyId() );
+  return getGeomEngine()->GetIMeasureOperations();
 }
 
 //=================================================================================
@@ -338,7 +495,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation
 //=================================================================================
 bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
 {
-  return !myObj->_is_nil();
+  return !getObj().isNull();
 }
 
 //=================================================================================
@@ -347,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()) : "");
 }
 
 //=================================================================================
@@ -397,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;
   }
 
@@ -407,11 +578,17 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
   int  nbPairs  = 0;
   int aLevel = myLevelBox->currentIndex();
 
+  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 != (int)getInters()->length()) {
       isOK = false;
     }
   }
@@ -421,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 {
@@ -442,28 +619,28 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
 void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged()
 {
   erasePreview();
-  int aCurItem = myInteList->currentRow();
-
-  if (aCurItem < 0)
-    return;
+  getShapeList()->clear();
 
-  QStringList aSubShapeList;
   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);
 
-    TopoDS_Shape aSubShape = anIndices.FindKey(myInters[aCurItem*2]);
-    QString aType = GEOMBase::GetShapeTypeString(aSubShape);
-    if (!aType.isEmpty())
-      aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2]));
-    aSubShape = anIndices.FindKey(myInters[aCurItem*2 + 1]);
-    aType = GEOMBase::GetShapeTypeString(aSubShape);
-    if (!aType.isEmpty())
-      aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2 + 1]));
+    int nbSelected = getInteList()->selectedItems().size();
+
+    for (int i = 0; i < getInteList()->count(); i++) {
+      if ( getInteList()->item(i)->isSelected() ) {
+        if ( nbSelected > 1 )
+          getShapeList()->addItem(QString("--- #%1 ---").arg(i+1));
+        for (int j = 0; j < 2; j++) {
+          TopoDS_Shape aSubShape = anIndices.FindKey(getInters()[i*2+j]);
+          QString aType = GEOMBase::GetShapeTypeString(aSubShape);
+          getShapeList()->addItem(QString("%1_%2").arg(aType).arg(getInters()[i*2+j]));
+          getShapeList()->item(getShapeList()->count()-1)->setData(Qt::UserRole, getInters()[i*2+j]);
+        }
+      }
+    }
   }
-  myShapeList->clear();
-  myShapeList->addItems(aSubShapeList);
 }
 
 //=================================================================================
@@ -474,36 +651,29 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
 {
   erasePreview();
 
-  // Current pair
-  int aErrCurItem = myInteList->currentRow();
-  if (aErrCurItem < 0)
-    return;
-
   // Selected IDs
+  QList<QListWidgetItem*> selected = getShapeList()->selectedItems();
   QList<int> aIds;
-  for (int i = 0, n = myShapeList->count(); i < n; i++) {
-    if (myShapeList->item(i)->isSelected())
-      aIds.append(i);
+  foreach(QListWidgetItem* item, selected) {
+    int idx = item->data(Qt::UserRole).toInt();
+    if (idx > 0 && aIds.indexOf(idx) < 0) aIds.append(idx);
   }
-  if (aIds.count() < 1)
-    return;
+
+  if (aIds.empty()) return;
 
   TopoDS_Shape aSelShape;
   TopoDS_Shape aSubShape;
   TopTools_IndexedMapOfShape anIndices;
-  if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
-    SALOME_Prs* aPrs = 0;
+  if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) {
     TopExp::MapShapes(aSelShape, anIndices);
-    QList<int>::iterator it;
-    for (it = aIds.begin(); it != aIds.end(); ++it) {
-      aSubShape = anIndices.FindKey(myInters[aErrCurItem*2 + (*it)]);
+    getDisplayer()->SetColor(Quantity_NOC_RED);
+    getDisplayer()->SetWidth(3);
+    getDisplayer()->SetToActivate(false);
+    foreach(int idx, aIds) {
+      aSubShape = anIndices.FindKey(idx);
       try {
-        getDisplayer()->SetColor(Quantity_NOC_RED);
-        getDisplayer()->SetWidth(3);
-        getDisplayer()->SetToActivate(false);
-        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);
@@ -525,59 +695,64 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
     return false;
   }
 
-  const int  aNbInteSelected    = myInteList->selectedItems().size();
-  const bool isPublishAllInte   = (aNbInteSelected < 1);
-  const bool isPublishAllShapes =
-    (aNbInteSelected != 1 || myShapeList->selectedItems().empty());
-  int        i;
-  const int  n = myInteList->count();
   TColStd_IndexedMapOfInteger aMapIndex;
+  QList<int> pairs;
 
-  // Collect the map of indices.
-  for (i = 0; i < n; i++) {
-    if (isPublishAllInte) {
-      // Collect the both of two indices.
-      aMapIndex.Add(myInters[i*2]);
-      aMapIndex.Add(myInters[i*2 + 1]);
-    } else if (myInteList->item(i)->isSelected()) {
-      if (isPublishAllShapes) {
-        // Collect the both of two indices.
-        aMapIndex.Add(myInters[i*2]);
-        aMapIndex.Add(myInters[i*2 + 1]);
-      } else if (myShapeList->count() == 2) {
-        // Collect only selected items.
-        if (myShapeList->item(0)->isSelected()) {
-          aMapIndex.Add(myInters[i*2]);
-        }
-        if (myShapeList->item(1)->isSelected()) {
-          aMapIndex.Add(myInters[i*2 + 1]);
-        }
-      }
+  int nbSelected = getInteList()->selectedItems().size();
+
+  // Collect the map of indices
+  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];
     }
   }
 
-  // Create objects.
+  GEOM::ShapesOpPtr shapesOper = getGeomEngine()->GetIShapesOperations();
+  
+  // Explode sub-shapes
   GEOM::ListOfLong_var anArray   = new GEOM::ListOfLong;
-  const int            aNbShapes = aMapIndex.Extent();
+  anArray->length(aMapIndex.Extent());
 
-  anArray->length(aNbShapes);
+  for (int i = 1; i <= aMapIndex.Extent(); i++)
+    anArray[i-1] = aMapIndex.FindKey(i);
 
-  for (i = 1; i <= aNbShapes; i++) {
-    anArray[i - 1] = aMapIndex.FindKey(i);
-  }
+  GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(getObj().get(), anArray);
 
-  if (myShapesOper->_is_nil()) {
-    myShapesOper = getGeomEngine()->GetIShapesOperations(getStudyId());
+  // Make compounds
+  for (int i = 0; i < pairs.count()/2; i++) {
+    GEOM::ListOfGO_var aPair = new GEOM::ListOfGO();
+    aPair->length(2);
+    aPair[0] = aList[ aMapIndex.FindIndex(pairs[i*2]) - 1 ];
+    aPair[1] = aList[ aMapIndex.FindIndex(pairs[i*2+1]) - 1 ];
+    GEOM::GEOM_Object_var aCompound = shapesOper->MakeCompound( aPair );
+    objects.push_back(aCompound._retn());
   }
 
-  GEOM::ListOfGO_var aList = myShapesOper->MakeSubShapes(myObj, anArray);
-  const int aNbObj = aList->length();
+  return true;
+}
 
-  for (i = 0; i < aNbObj; i++) {
-    objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
-  }
+//=================================================================================
+// function : getDeflection
+// purpose  :
+//=================================================================================
+float MeasureGUI_CheckSelfIntersectionsDlg::getDeflection()
+{
+  return (float)myDeflection->value();
+}
 
-  return true;
+//=================================================================================
+// function : getTolerance
+// purpose  :
+//=================================================================================
+double MeasureGUI_CheckSelfIntersectionsDlg::getTolerance()
+{
+  double aVal = myTolerance->value();
+  if (!myDetGaps->isChecked() || aVal < 0.0)
+    return 0.0;
+  return aVal;
 }
 
 //================================================================
@@ -588,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 );
 }