Salome HOME
Fix bug 12796: Warning missed for the bad file 'test18.med'
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MultiEditDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SMESHGUI_MultiEditDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_MultiEditDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Filter.h"
32 #include "SMESHGUI_FilterDlg.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
36 #include "SMESHGUI_FilterUtils.h"
37 #include "SMESHGUI_SpinBox.h"
38
39 #include "SMESH_Actor.h"
40 #include "SMESH_TypeFilter.hxx"
41 #include "SMDS_Mesh.hxx"
42 #include "SMDS_MeshElement.hxx"
43
44 #include "SUIT_ResourceMgr.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_Session.h"
47 #include "SUIT_MessageBox.h"
48
49 #include "LightApp_SelectionMgr.h"
50 #include "LightApp_Application.h"
51 #include "SALOME_ListIO.hxx"
52 #include "SALOME_ListIteratorOfListIO.hxx"
53
54 #include "SVTK_Selector.h"
55 #include "SVTK_ViewModel.h"
56 #include "SVTK_ViewWindow.h"
57 #include "VTKViewer_CellLocationsArray.h"
58
59 // OCCT Includes
60 #include <Precision.hxx>
61 #include <TColStd_IndexedMapOfInteger.hxx>
62 #include <TColStd_DataMapOfIntegerInteger.hxx>
63 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
64
65 // VTK Includes
66 #include <vtkCell3D.h>
67 #include <vtkQuad.h>
68 #include <vtkTriangle.h>
69 #include <vtkPolygon.h>
70 #include <vtkConvexPointSet.h>
71 #include <vtkIdList.h>
72 #include <vtkCellArray.h>
73 #include <vtkUnsignedCharArray.h>
74 #include <vtkUnstructuredGrid.h>
75 #include <vtkDataSetMapper.h>
76 #include <vtkProperty.h>
77
78 // QT Includes
79 #include <qframe.h>
80 #include <qlabel.h>
81 #include <qlayout.h>
82 #include <qlistbox.h>
83 #include <qcheckbox.h>
84 #include <qcombobox.h>
85 #include <qgroupbox.h>
86 #include <qlineedit.h>
87 #include <qpushbutton.h>
88 #include <qapplication.h>
89 #include <qradiobutton.h>
90 #include <qhbuttongroup.h>
91
92 // IDL Headers
93 #include "SALOMEconfig.h"
94 #include CORBA_SERVER_HEADER(SMESH_Group)
95
96 #define SPACING 5
97 #define MARGIN  10
98
99 /*!
100  *  Class       : SMESHGUI_MultiEditDlg
101  *  Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
102  *                2 neighboring triangles with 1 common edge
103  */
104
105 //=======================================================================
106 // name    : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
107 // Purpose : Constructor
108 //=======================================================================
109 SMESHGUI_MultiEditDlg
110 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
111                         const int theMode,
112                         const bool the3d2d,
113                         const char* theName):
114   QDialog(SMESH::GetDesktop(theModule),
115           theName,
116           false,
117           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
118     mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
119     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
120     mySMESHGUI(theModule)
121 {
122   myFilterDlg = 0;
123   myEntityType = 0;
124
125   myFilterType = theMode;
126   QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
127
128   QFrame* aMainFrame = createMainFrame  (this, the3d2d);
129   QFrame* aBtnFrame  = createButtonFrame(this);
130
131   aDlgLay->addWidget(aMainFrame);
132   aDlgLay->addWidget(aBtnFrame);
133
134   aDlgLay->setStretchFactor(aMainFrame, 1);
135   aDlgLay->setStretchFactor(aBtnFrame, 0);
136   Init();
137 }
138
139 //=======================================================================
140 // name    : SMESHGUI_MultiEditDlg::createMainFrame
141 // Purpose : Create frame containing dialog's input fields
142 //=======================================================================
143 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
144 {
145   QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
146   aMainGrp->setFrameStyle(QFrame::NoFrame);
147   aMainGrp->setInsideMargin(0);
148
149   QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
150
151   // "Selected cells" group
152   mySelGrp = new QGroupBox(1, Qt::Horizontal,  aMainGrp);
153
154   myEntityTypeGrp = 0;
155   if (the3d2d) {
156     myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
157     (new QRadioButton(tr("SMESH_FACE"),   myEntityTypeGrp))->setChecked(true);
158     (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
159     myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
160   }
161
162   QFrame* aFrame = new QFrame(mySelGrp);
163
164   myListBox = new QListBox(aFrame);
165   myListBox->setSelectionMode(QListBox::Extended);
166   myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
167   myListBox->installEventFilter(this);
168
169   myFilterBtn = new QPushButton(tr("FILTER")   , aFrame);
170   myAddBtn    = new QPushButton(tr("ADD")      , aFrame);
171   myRemoveBtn = new QPushButton(tr("REMOVE")   , aFrame);
172   mySortBtn   = new QPushButton(tr("SORT_LIST"), aFrame);
173
174   QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
175   aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
176   aLay->addWidget(myFilterBtn, 0, 1);
177   aLay->addWidget(myAddBtn, 1, 1);
178   aLay->addWidget(myRemoveBtn, 2, 1);
179   aLay->addWidget(mySortBtn, 3, 1);
180
181   QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
182   aLay->addItem(aSpacer, 4, 1);
183
184   myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
185
186   // Split/Join criterion group
187   myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp);
188
189   myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp);
190   myGroupChoice->setInsideMargin(0);
191   myGroupChoice->setFrameStyle(QFrame::NoFrame);
192   (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true);
193   (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice));
194   (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice));
195
196   myComboBoxFunctor = new QComboBox(myCriterionGrp);
197   myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS"));
198   myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS"));
199   myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS"));
200   myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS"));
201   //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only
202   //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only
203   myComboBoxFunctor->setCurrentItem(0);
204
205   myCriterionGrp->hide();
206   myGroupChoice->hide();
207   myComboBoxFunctor->setEnabled(false);
208
209   // "Select from" group
210   QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
211
212   mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
213   mySubmeshBtn = new QPushButton(aGrp);
214   mySubmesh = new QLineEdit(aGrp);
215   mySubmesh->setReadOnly(true);
216   mySubmeshBtn->setPixmap(aPix);
217
218   myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp);
219   myGroupBtn = new QPushButton(aGrp);
220   myGroup = new QLineEdit(aGrp);
221   myGroup->setReadOnly(true);
222   myGroupBtn->setPixmap(aPix);
223
224   return aMainGrp;
225 }
226
227 //=======================================================================
228 // name    : SMESHGUI_MultiEditDlg::createButtonFrame
229 // Purpose : Create frame containing buttons
230 //=======================================================================
231 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
232 {
233   QFrame* aFrame = new QFrame (theParent);
234   aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
235
236   myOkBtn     = new QPushButton (tr("SMESH_BUT_OK"   ), aFrame);
237   myApplyBtn  = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
238   myCloseBtn  = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
239   myHelpBtn   = new QPushButton (tr("SMESH_BUT_HELP"), aFrame);
240
241   QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
242
243   QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
244
245   aLay->addWidget(myOkBtn);
246   aLay->addWidget(myApplyBtn);
247   aLay->addItem(aSpacer);
248   aLay->addWidget(myCloseBtn);
249   aLay->addWidget(myHelpBtn);
250
251   return aFrame;
252 }
253
254 //=======================================================================
255 // name    : SMESHGUI_MultiEditDlg::isValid
256 // Purpose : Verify validity of input data
257 //=======================================================================
258 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
259 {
260   return (!myMesh->_is_nil() &&
261           (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
262 }
263
264 //=======================================================================
265 // name    : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
266 // Purpose : Destructor
267 //=======================================================================
268 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
269 {
270   if (myFilterDlg != 0)
271   {
272     myFilterDlg->reparent(0, QPoint());
273     delete myFilterDlg;
274   }
275 }
276
277 //=======================================================================
278 // name    : SMESHGUI_MultiEditDlg::eventFilter
279 // Purpose : event filter
280 //=======================================================================
281 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
282 {
283   if (object == myListBox && event->type() == QEvent::KeyPress) {
284     QKeyEvent* ke = (QKeyEvent*)event;
285     if (ke->key() == Key_Delete)
286       onRemoveBtn();
287   }
288   return QDialog::eventFilter(object, event);
289 }
290
291 //=======================================================================
292 // name    : SMESHGUI_MultiEditDlg::getNumericalFunctor
293 // Purpose :
294 //=======================================================================
295 SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
296 {
297   SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil();
298
299   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
300   if (aFilterMgr->_is_nil())
301     return aNF._retn();
302
303   if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS"))
304     aNF = aFilterMgr->CreateAspectRatio();
305   else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS"))
306     aNF = aFilterMgr->CreateWarping();
307   else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS"))
308     aNF = aFilterMgr->CreateMinimumAngle();
309   else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS"))
310     aNF = aFilterMgr->CreateTaper();
311   else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS"))
312     aNF = aFilterMgr->CreateSkew();
313   else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS"))
314     aNF = aFilterMgr->CreateArea();
315   else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES"))
316     aNF = aFilterMgr->CreateLength2D();
317   else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
318     aNF = aFilterMgr->CreateMultiConnection2D();
319   else ;
320
321   return aNF._retn();
322 }
323
324 //=======================================================================
325 // name    : SMESHGUI_MultiEditDlg::Init
326 // Purpose : Init dialog fields, connect signals and slots, show dialog
327 //=======================================================================
328 void SMESHGUI_MultiEditDlg::Init()
329 {
330   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
331   myListBox->clear();
332   myIds.Clear();
333   myBusy = false;
334   myActor = 0;
335   emit ListContensChanged();
336
337   // main buttons
338   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
339   connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
340   connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
341   connect(myHelpBtn,  SIGNAL(clicked()), SLOT(onHelp()));
342
343   // selection and SMESHGUI
344   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
345   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
346   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
347
348   // dialog controls
349   connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn()  ));
350   connect(myAddBtn   , SIGNAL(clicked()), SLOT(onAddBtn()     ));
351   connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn()  ));
352   connect(mySortBtn  , SIGNAL(clicked()), SLOT(onSortListBtn()));
353
354   connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
355   connect(myGroupChk  , SIGNAL(stateChanged(int)), SLOT(onGroupChk()  ));
356   connect(myToAllChk  , SIGNAL(stateChanged(int)), SLOT(onToAllChk()  ));
357
358   if (myEntityTypeGrp)
359     connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
360
361   connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
362
363   onSelectionDone();
364
365   // set selection mode
366   setSelectionMode();
367   updateButtons();
368 }
369
370 //=======================================================================
371 // name    : SMESHGUI_MultiEditDlg::onOk
372 // Purpose : SLOT called when "Ok" button pressed.
373 //           Assign filters VTK viewer and close dialog
374 //=======================================================================
375 void SMESHGUI_MultiEditDlg::onOk()
376 {
377   if (onApply())
378     onClose();
379 }
380
381 //=======================================================================
382 // name    : SMESHGUI_MultiEditDlg::getIds
383 // Purpose : Retrive identifiers from list box
384 //=======================================================================
385 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
386 {
387   SMESH::long_array_var anIds = new SMESH::long_array;
388
389   if (myToAllChk->isChecked())
390   {
391     myIds.Clear();
392     SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
393     if (!anActor)
394       anActor = myActor;
395     if (anActor != 0)
396     {
397       // skl 07.02.2006
398       SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
399       if( myFilterType == SMESHGUI_TriaFilter || 
400           myFilterType == SMESHGUI_QuadFilter ||
401           myFilterType == SMESHGUI_FaceFilter ) {
402         SMDS_FaceIteratorPtr it = aMesh->facesIterator();
403         while(it->more()) {
404           const SMDS_MeshFace* f = it->next();
405           if(myFilterType == SMESHGUI_FaceFilter) {
406             myIds.Add(f->GetID());
407           }
408           else if( myFilterType==SMESHGUI_TriaFilter &&
409                    ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
410             myIds.Add(f->GetID());
411           }
412           else if( myFilterType==SMESHGUI_QuadFilter &&
413                    ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
414             myIds.Add(f->GetID());
415           }
416         }
417       }
418       else if(myFilterType == SMESHGUI_VolumeFilter) {
419         SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
420         while(it->more()) {
421           const SMDS_MeshVolume* f = it->next();
422           myIds.Add(f->GetID());
423         }
424       }
425       /* commented by skl 07.02.2006
426       TVisualObjPtr aVisualObj = anActor->GetObject();
427       vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
428       if (aGrid != 0) {
429         for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
430           vtkCell* aCell = aGrid->GetCell(i);
431           if (aCell != 0) {
432             vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
433             vtkQuad*     aQua = vtkQuad::SafeDownCast(aCell);
434             vtkPolygon*  aPG  = vtkPolygon::SafeDownCast(aCell);
435
436             vtkCell3D*   a3d  = vtkCell3D::SafeDownCast(aCell);
437             vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
438
439             if (aTri && myFilterType == SMESHGUI_TriaFilter ||
440                 aQua && myFilterType == SMESHGUI_QuadFilter ||
441                 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
442                 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
443               int anObjId = aVisualObj->GetElemObjId(i);
444               myIds.Add(anObjId);
445             }
446           }
447         }
448       }
449       */
450     }
451   }
452
453   anIds->length(myIds.Extent());
454   TColStd_MapIteratorOfMapOfInteger anIter(myIds);
455   for (int i = 0; anIter.More(); anIter.Next() )
456   {
457     anIds[ i++ ] = anIter.Key();
458   }
459   return anIds._retn();
460 }
461
462 //=======================================================================
463 // name    : SMESHGUI_MultiEditDlg::onClose
464 // Purpose : SLOT called when "Close" button pressed. Close dialog
465 //=======================================================================
466 void SMESHGUI_MultiEditDlg::onClose()
467 {
468   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
469     aViewWindow->SetSelectionMode(ActorSelection);
470   disconnect(mySelectionMgr, 0, this, 0);
471   disconnect(mySMESHGUI, 0, this, 0);
472   mySMESHGUI->ResetState();
473
474   SMESH::RemoveFilters();
475   SMESH::SetPickable();
476
477   //mySelectionMgr->clearSelected();
478   mySelectionMgr->clearFilters();
479
480   reject();
481 }
482
483 //=================================================================================
484 // function : onHelp()
485 // purpose  :
486 //=================================================================================
487 void SMESHGUI_MultiEditDlg::onHelp()
488 {
489   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
490   if (app) 
491     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
492   else {
493     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
494                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
495                            arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
496                            QObject::tr("BUT_OK"));
497   }
498 }
499
500 //=======================================================================
501 // name    : SMESHGUI_MultiEditDlg::onSelectionDone
502 // Purpose : SLOT called when selection changed
503 //=======================================================================
504 void SMESHGUI_MultiEditDlg::onSelectionDone()
505 {
506   if (myBusy || !isEnabled()) return;
507   myBusy = true;
508
509   const SALOME_ListIO& aList = mySelector->StoredIObjects();
510
511   int nbSel = aList.Extent();
512   myListBox->clearSelection();
513
514   if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
515     QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
516     if (nbSel == 1) {
517       Handle(SALOME_InteractiveObject) anIO = aList.First();
518       QString aName = "";
519       SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
520       anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
521
522       if (mySubmeshChk->isChecked()) {
523         SMESH::SMESH_subMesh_var aSubMesh =
524           SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
525         if (!aSubMesh->_is_nil())
526           myMesh = aSubMesh->GetFather();
527       } else {
528         SMESH::SMESH_GroupBase_var aGroup =
529           SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
530         if (!aGroup->_is_nil())
531           myMesh = aGroup->GetMesh();
532       }
533     } else if (nbSel > 1) {
534       QString aStr = mySubmeshChk->isChecked() ?
535         tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
536       aNameEdit->setText(aStr.arg(nbSel));
537     } else {
538       aNameEdit->clear();
539     }
540   } else if (nbSel == 1) {
541     QString aListStr = "";
542     Handle(SALOME_InteractiveObject) anIO = aList.First();
543     int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
544     if (aNbItems > 0) {
545       QStringList anElements = QStringList::split(" ", aListStr);
546       QListBoxItem* anItem = 0;
547       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
548         anItem = myListBox->findItem(*it, Qt::ExactMatch);
549         if (anItem) myListBox->setSelected(anItem, true);
550       }
551     }
552
553     myMesh = SMESH::GetMeshByIO(anIO);
554   }
555
556   if (nbSel == 1) {
557     myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
558     if (!myActor)
559       myActor = SMESH::FindActorByObject(myMesh);
560     SVTK_Selector* aSelector = SMESH::GetSelector();
561     Handle(VTKViewer_Filter) aFilter = aSelector->GetFilter(myFilterType);
562     if (!aFilter.IsNull())
563       aFilter->SetActor(myActor);
564   }
565   myBusy = false;
566
567   updateButtons();
568 }
569
570 //=======================================================================
571 // name    : SMESHGUI_MultiEditDlg::onDeactivate
572 // Purpose : SLOT called when dialog must be deativated
573 //=======================================================================
574 void SMESHGUI_MultiEditDlg::onDeactivate()
575 {
576   setEnabled(false);
577 }
578
579 //=======================================================================
580 // name    : SMESHGUI_MultiEditDlg::enterEvent
581 // Purpose : Event filter
582 //=======================================================================
583 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
584 {
585   if (!isEnabled()) {
586     mySMESHGUI->EmitSignalDeactivateDialog();
587     setEnabled(true);
588     setSelectionMode();
589   }
590 }
591
592 //=======================================================================
593 // name    : SMESHGUI_MultiEditDlg::closeEvent
594 // Purpose :
595 //=======================================================================
596 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
597 {
598   onClose();
599 }
600 //=======================================================================
601 // name    : SMESHGUI_MultiEditDlg::hideEvent
602 // Purpose : caused by ESC key
603 //=======================================================================
604 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
605 {
606   if (!isMinimized())
607     onClose();
608 }
609
610 //=======================================================================
611 // name    : SMESHGUI_MultiEditDlg::onFilterBtn
612 // Purpose : SLOT. Called when "Filter" button pressed.
613 //           Start "Selection filters" dialog
614 //=======================================================================
615 void SMESHGUI_MultiEditDlg::onFilterBtn()
616 {
617   if (myFilterDlg == 0) {
618     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
619     connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
620   } else {
621     myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
622   }
623
624   myFilterDlg->SetSelection();
625   myFilterDlg->SetMesh(myMesh);
626   myFilterDlg->SetSourceWg(myListBox);
627
628   myFilterDlg->show();
629 }
630
631 //=======================================================================
632 // name    : onFilterAccepted()
633 // Purpose : SLOT. Called when Filter dlg closed with OK button.
634 //            Uncheck "Select submesh" and "Select group" checkboxes
635 //=======================================================================
636 void SMESHGUI_MultiEditDlg::onFilterAccepted()
637 {
638   myIds.Clear();
639   for (int i = 0, n = myListBox->count(); i < n; i++)
640     myIds.Add(myListBox->text(i).toInt());
641
642   emit ListContensChanged();
643
644   if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
645     mySubmeshChk->blockSignals(true);
646     myGroupChk->blockSignals(true);
647     mySubmeshChk->setChecked(false);
648     myGroupChk->setChecked(false);
649     mySubmeshChk->blockSignals(false);
650     myGroupChk->blockSignals(false);
651   }
652   updateButtons();
653 }
654
655 //=======================================================================
656 // name    : SMESHGUI_MultiEditDlg::isIdValid
657 // Purpose : Verify whether Id of element satisfies to filters from viewer
658 //=======================================================================
659 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
660 {
661   SVTK_Selector* aSelector = SMESH::GetSelector();
662   Handle(SMESHGUI_Filter) aFilter =
663     Handle(SMESHGUI_Filter)::DownCast(aSelector->GetFilter(myFilterType));
664
665   return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
666 }
667
668 //=======================================================================
669 // name    : SMESHGUI_MultiEditDlg::onAddBtn
670 // Purpose : SLOT. Called when "Add" button pressed.
671 //           Add selected in viewer entities in list box
672 //=======================================================================
673 void SMESHGUI_MultiEditDlg::onAddBtn()
674 {
675   const SALOME_ListIO& aList = mySelector->StoredIObjects();
676
677   int nbSelected = aList.Extent();
678   if (nbSelected == 0)
679     return;
680
681   TColStd_IndexedMapOfInteger toBeAdded;
682
683   if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
684     if (nbSelected == 1)
685       mySelector->GetIndex(aList.First(),toBeAdded);
686   } else if (mySubmeshChk->isChecked()) {
687     SALOME_ListIteratorOfListIO anIter(aList);
688     for (; anIter.More(); anIter.Next()) {
689       SMESH::SMESH_subMesh_var aSubMesh =
690         SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
691       if (!aSubMesh->_is_nil()) {
692         if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
693           SMESH::long_array_var anIds = aSubMesh->GetElementsId();
694           for (int i = 0, n = anIds->length(); i < n; i++) {
695             if (isIdValid(anIds[ i ]))
696               toBeAdded.Add(anIds[ i ]);
697           }
698         }
699       }
700     }
701   } else if (myGroupChk->isChecked()) {
702     SALOME_ListIteratorOfListIO anIter(aList);
703     for (; anIter.More(); anIter.Next()) {
704       SMESH::SMESH_GroupBase_var aGroup =
705         SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
706       if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
707                                  entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
708                                  entityType() == 1)) {
709         if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
710           SMESH::long_array_var anIds = aGroup->GetListOfID();
711           for (int i = 0, n = anIds->length(); i < n; i++) {
712             if (isIdValid(anIds[ i ]))
713               toBeAdded.Add(anIds[ i ]);
714           }
715         }
716       }
717     }
718   } else {
719   }
720
721   myBusy = true;
722   bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
723   mySubmeshChk->setChecked(false);
724   myGroupChk->setChecked(false);
725   for(int i = 1; i <= toBeAdded.Extent(); i++)
726     if (myIds.Add(toBeAdded(i))) {
727       QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
728       myListBox->insertItem(item);
729       myListBox->setSelected(item, true);
730     }
731   myBusy = false;
732
733   emit ListContensChanged();
734
735   if (isGroupOrSubmesh)
736     onListSelectionChanged();
737
738   updateButtons();
739 }
740
741 //=======================================================================
742 // name    : SMESHGUI_MultiEditDlg::updateButtons
743 // Purpose : Enable/disable buttons of dialog in accordance with current state
744 //=======================================================================
745 void SMESHGUI_MultiEditDlg::updateButtons()
746 {
747   bool isOk = isValid(false);
748   myOkBtn->setEnabled(isOk);
749   myApplyBtn->setEnabled(isOk);
750
751   bool isListBoxNonEmpty = myListBox->count() > 0;
752   bool isToAll = myToAllChk->isChecked();
753   myFilterBtn->setEnabled(!isToAll);
754   myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
755   mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
756
757   const SALOME_ListIO& aList = mySelector->StoredIObjects();
758
759   if (isToAll ||
760       myMesh->_is_nil() ||
761       aList.Extent() != 1 ||
762       (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
763        SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
764        SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
765     myAddBtn->setEnabled(false);
766   else
767     myAddBtn->setEnabled(true);
768
769   mySubmeshChk->setEnabled(!isToAll);
770   mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
771   mySubmesh->setEnabled(mySubmeshChk->isChecked());
772
773   myGroupChk->setEnabled(!isToAll);
774   myGroupBtn->setEnabled(myGroupChk->isChecked());
775   myGroup->setEnabled(myGroupChk->isChecked());
776
777   if (!mySubmeshChk->isChecked())
778     mySubmesh->clear();
779   if (!myGroupChk->isChecked())
780     myGroup->clear();
781
782 }
783
784 //=======================================================================
785 // name    : SMESHGUI_MultiEditDlg::onRemoveBtn
786 // Purpose : SLOT. Called when "Remove" button pressed.
787 //           Remove selected in list box entities
788 //=======================================================================
789 void SMESHGUI_MultiEditDlg::onRemoveBtn()
790 {
791   myBusy = true;
792
793   for (int i = 0, n = myListBox->count(); i < n; i++)
794   {
795     for (int i = myListBox->count(); i > 0; i--) {
796       if (myListBox->isSelected(i - 1))
797       {
798         int anId = myListBox->text(i - 1).toInt();
799         myIds.Remove(anId);
800         myIds.Remove(anId);
801               myListBox->removeItem(i-1);
802       }
803     }
804   }
805   myBusy = false;
806
807   emit ListContensChanged();
808   updateButtons();
809 }
810
811 //=======================================================================
812 // name    : SMESHGUI_MultiEditDlg::onSortListBtn
813 // Purpose : SLOT. Called when "Sort list" button pressed.
814 //           Sort entities of list box
815 //=======================================================================
816 void SMESHGUI_MultiEditDlg::onSortListBtn()
817 {
818   myBusy = true;
819
820   int i, k = myListBox->count();
821   if (k > 0)
822   {
823     QStringList aSelected;
824     std::vector<int> anArray(k);
825     QListBoxItem* anItem;
826     for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
827     {
828       anArray[ i ] = anItem->text().toInt();
829       if (anItem->isSelected())
830         aSelected.append(anItem->text());
831     }
832
833     std::sort(anArray.begin(), anArray.end());
834     myListBox->clear();
835     for (i = 0; i < k; i++)
836       myListBox->insertItem(QString::number(anArray[ i ]));
837
838     for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
839     {
840       anItem = myListBox->findItem(*it, Qt::ExactMatch);
841       if (anItem)
842         myListBox->setSelected(anItem, true);
843     }
844   }
845   myBusy = false;
846 }
847
848 //=======================================================================
849 // name    : SMESHGUI_MultiEditDlg::onListSelectionChanged
850 // Purpose : SLOT. Called when selection in list box changed.
851 //           Highlight in selected entities
852 //=======================================================================
853 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
854 {
855   if (myActor == 0 || myBusy)
856     return;
857
858   if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
859     return;
860
861   SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
862   if (!anActor)
863     anActor = myActor;
864   TVisualObjPtr anObj = anActor->GetObject();
865
866   TColStd_MapOfInteger anIndexes;
867   for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
868   {
869     if (anItem->isSelected())
870     {
871       int anId = anItem->text().toInt();
872       if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
873         anIndexes.Add(anId);
874     }
875   }
876
877   mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
878   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
879     aViewWindow->highlight(anActor->getIO(),true,true);
880 }
881
882 //=======================================================================
883 // name    : SMESHGUI_MultiEditDlg::onSubmeshChk
884 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
885 //           Activate/deactivate selection of submeshes
886 //=======================================================================
887 void SMESHGUI_MultiEditDlg::onSubmeshChk()
888 {
889   bool isChecked = mySubmeshChk->isChecked();
890   mySubmeshBtn->setEnabled(isChecked);
891   mySubmesh->setEnabled(isChecked);
892   if (!isChecked)
893     mySubmesh->clear();
894   if (isChecked && myGroupChk->isChecked())
895       myGroupChk->setChecked(false);
896
897   setSelectionMode();
898 }
899
900 //=======================================================================
901 // name    : SMESHGUI_MultiEditDlg::onGroupChk
902 // Purpose : SLOT. Called when state of "Group" check box changed.
903 //           Activate/deactivate selection of groupes
904 //=======================================================================
905 void SMESHGUI_MultiEditDlg::onGroupChk()
906 {
907   bool isChecked = myGroupChk->isChecked();
908   myGroupBtn->setEnabled(isChecked);
909   myGroup->setEnabled(isChecked);
910   if (!isChecked)
911     myGroup->clear();
912   if (isChecked && mySubmeshChk->isChecked())
913       mySubmeshChk->setChecked(false);
914
915   setSelectionMode();
916 }
917
918 //=======================================================================
919 // name    : SMESHGUI_MultiEditDlg::onToAllChk
920 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
921 //           Activate/deactivate selection
922 //=======================================================================
923 void SMESHGUI_MultiEditDlg::onToAllChk()
924 {
925   bool isChecked = myToAllChk->isChecked();
926
927   if (isChecked)
928     myListBox->clear();
929
930   myIds.Clear();
931
932   emit ListContensChanged();
933
934   updateButtons();
935   setSelectionMode();
936 }
937
938 //=======================================================================
939 // name    : SMESHGUI_MultiEditDlg::setSelectionMode
940 // Purpose : Set selection mode
941 //=======================================================================
942 void SMESHGUI_MultiEditDlg::setSelectionMode()
943 {
944   SMESH::RemoveFilters();
945
946   mySelectionMgr->clearSelected();
947   mySelectionMgr->clearFilters();
948
949   if (mySubmeshChk->isChecked()) {
950     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
951       aViewWindow->SetSelectionMode(ActorSelection);
952     mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
953   }
954   else if (myGroupChk->isChecked()) {
955     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
956       aViewWindow->SetSelectionMode(ActorSelection);
957     mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
958   }
959
960   if (entityType()) {
961     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
962       aViewWindow->SetSelectionMode(VolumeSelection);
963     SMESH::SetFilter(new SMESHGUI_VolumesFilter());
964   } else {
965     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
966       aViewWindow->SetSelectionMode(FaceSelection);
967     if (myFilterType == SMESHGUI_TriaFilter)
968       SMESH::SetFilter(new SMESHGUI_TriangleFilter());
969     else if (myFilterType == SMESHGUI_QuadFilter)
970       SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
971     else
972       SMESH::SetFilter(new SMESHGUI_FacesFilter());
973   }
974 }
975
976 //=======================================================================
977 // name    : SMESHGUI_MultiEditDlg::onApply
978 // Purpose : SLOT. Called when "Apply" button clicked.
979 //=======================================================================
980 bool SMESHGUI_MultiEditDlg::onApply()
981 {
982   if (mySMESHGUI->isActiveStudyLocked())
983     return false;
984   if (!isValid(true))
985     return false;
986
987   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
988   if (aMeshEditor->_is_nil())
989     return false;
990
991   myBusy = true;
992
993   SMESH::long_array_var anIds = getIds();
994
995   bool aResult = process(aMeshEditor, anIds.inout());
996   if (aResult) {
997     if (myActor) {
998       SALOME_ListIO sel;
999       mySelectionMgr->selectedObjects( sel );
1000       mySelector->ClearIndex();
1001       mySelectionMgr->setSelectedObjects( sel );
1002       SMESH::UpdateView();
1003     }
1004
1005     myListBox->clear();
1006     myIds.Clear();
1007     emit ListContensChanged();
1008
1009     updateButtons();
1010   }
1011
1012   myBusy = false;
1013   return aResult;
1014 }
1015
1016 //=======================================================================
1017 // name    : SMESHGUI_MultiEditDlg::on3d2dChanged
1018 // Purpose :
1019 //=======================================================================
1020 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
1021 {
1022   if (myEntityType != type) {
1023     myEntityType = type;
1024
1025     myListBox->clear();
1026     myIds.Clear();
1027
1028     emit ListContensChanged();
1029
1030     if (type)
1031       myFilterType = SMESHGUI_VolumeFilter;
1032     else
1033       myFilterType = SMESHGUI_FaceFilter;
1034
1035     updateButtons();
1036     setSelectionMode();
1037   }
1038 }
1039
1040 //=======================================================================
1041 // name    : SMESHGUI_MultiEditDlg::entityType
1042 // Purpose :
1043 //=======================================================================
1044 int SMESHGUI_MultiEditDlg::entityType()
1045 {
1046   return myEntityType;
1047 }
1048
1049 //=================================================================================
1050 // function : keyPressEvent()
1051 // purpose  :
1052 //=================================================================================
1053 void SMESHGUI_MultiEditDlg::keyPressEvent( QKeyEvent* e )
1054 {
1055   QDialog::keyPressEvent( e );
1056   if ( e->isAccepted() )
1057     return;
1058
1059   if ( e->key() == Key_F1 )
1060     {
1061       e->accept();
1062       onHelp();
1063     }
1064 }
1065
1066 /*!
1067  *  Class       : SMESHGUI_ChangeOrientationDlg
1068  *  Description : Modification of orientation of faces
1069  */
1070
1071 SMESHGUI_ChangeOrientationDlg
1072 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
1073                                 const char* theName):
1074   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
1075 {
1076   setCaption(tr("CAPTION"));
1077   myHelpFileName = "/files/changing_orientation_of_elements.htm";
1078 }
1079
1080 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
1081 {
1082 }
1083
1084 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1085                                              const SMESH::long_array&    theIds)
1086 {
1087   return theEditor->Reorient(theIds);
1088 }
1089
1090 /*!
1091  *  Class       : SMESHGUI_UnionOfTrianglesDlg
1092  *  Description : Construction of quadrangles by automatic association of triangles
1093  */
1094
1095 SMESHGUI_UnionOfTrianglesDlg
1096 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
1097                                const char* theName):
1098   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
1099 {
1100   setCaption(tr("CAPTION"));
1101
1102   myComboBoxFunctor->setEnabled(true);
1103   myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
1104   myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
1105
1106   // Maximum angle
1107   QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
1108   aMaxAngleGrp->setInsideMargin(0);
1109   aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
1110   new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
1111   myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
1112   myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
1113   myMaxAngleSpin->SetValue(30.0);
1114
1115   myCriterionGrp->show();
1116
1117   myHelpFileName = "/files/uniting_a_set_of_triangles.htm";
1118 }
1119
1120 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1121 {
1122 }
1123
1124 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1125                                             const SMESH::long_array&    theIds)
1126 {
1127   SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1128   double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
1129   return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
1130 }
1131
1132
1133 /*!
1134  *  Class       : SMESHGUI_CuttingOfQuadsDlg
1135  *  Description : Automatic splitting of quadrangles into triangles
1136  */
1137
1138 SMESHGUI_CuttingOfQuadsDlg
1139 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
1140                              const char* theName):
1141   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
1142 {
1143   setCaption(tr("CAPTION"));
1144   myPreviewActor = 0;
1145
1146   myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
1147
1148   myCriterionGrp->show();
1149   myGroupChoice->show();
1150   myComboBoxFunctor->setEnabled(false);
1151
1152   connect(myPreviewChk     , SIGNAL(stateChanged(int))   , this, SLOT(onPreviewChk()));
1153   connect(myGroupChoice    , SIGNAL(clicked(int))        , this, SLOT(onCriterionRB()));
1154   connect(myComboBoxFunctor, SIGNAL(activated(int))      , this, SLOT(onPreviewChk()));
1155   connect(this             , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1156
1157   myHelpFileName = "/files/cutting_quadrangles.htm";
1158 }
1159
1160 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1161 {
1162 }
1163
1164 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1165 {
1166   erasePreview();
1167   SMESHGUI_MultiEditDlg::onClose();
1168 }
1169
1170 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1171                                           const SMESH::long_array&    theIds)
1172 {
1173   switch (myGroupChoice->id(myGroupChoice->selected())) {
1174   case 0: // use diagonal 1-3
1175     return theEditor->SplitQuad(theIds, true);
1176   case 1: // use diagonal 2-4
1177     return theEditor->SplitQuad(theIds, false);
1178   default: // use numeric functor
1179     break;
1180   }
1181
1182   SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1183   return theEditor->QuadToTri(theIds, aCriterion);
1184 }
1185
1186 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
1187 {
1188   if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
1189     myComboBoxFunctor->setEnabled(true);
1190   else
1191     myComboBoxFunctor->setEnabled(false);
1192
1193   onPreviewChk();
1194 }
1195
1196 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1197 {
1198   myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1199 }
1200
1201 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1202 {
1203   if (myPreviewActor == 0)
1204     return;
1205
1206   if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1207     vf->RemoveActor(myPreviewActor);
1208     vf->Repaint();
1209   }
1210   myPreviewActor->Delete();
1211   myPreviewActor = 0;
1212 }
1213   
1214 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1215 {
1216   if (myActor == 0)
1217     return;
1218
1219   if (myPreviewActor != 0)
1220     erasePreview();
1221
1222   // get Ids of elements
1223   SMESH::long_array_var anElemIds = getIds();
1224   if (getIds()->length() == 0)
1225     return;
1226
1227   SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1228   if (aMesh == 0)
1229     return;
1230
1231   // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
1232   int aChoice = myGroupChoice->id(myGroupChoice->selected());
1233   SMESH::NumericalFunctor_var aCriterion  = SMESH::NumericalFunctor::_nil();
1234   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
1235   if (aChoice == 2) {
1236     aCriterion  = getNumericalFunctor();
1237     aMeshEditor = myMesh->GetMeshEditor();
1238     if (aMeshEditor->_is_nil())
1239       return;
1240   }
1241
1242   //Create grid
1243   vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1244
1245   vtkIdType aNbCells = anElemIds->length() * 2;
1246   vtkIdType aCellsSize = 4 * aNbCells;
1247   vtkCellArray* aConnectivity = vtkCellArray::New();
1248   aConnectivity->Allocate(aCellsSize, 0);
1249
1250   vtkPoints* aPoints = vtkPoints::New();
1251   aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1252
1253   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1254   aCellTypesArray->SetNumberOfComponents(1);
1255   aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1256
1257   vtkIdList *anIdList = vtkIdList::New();
1258   anIdList->SetNumberOfIds(3);
1259
1260   TColStd_DataMapOfIntegerInteger anIdToVtk;
1261
1262   int aNodes[ 4 ];
1263   int nbPoints = -1;
1264   for (int i = 0, n = anElemIds->length(); i < n; i++)
1265   {
1266     const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1267     if (anElem == 0 || anElem->NbNodes() != 4)
1268       continue;
1269
1270     SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1271     int k = 0;
1272     while (anIter->more()) {
1273       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
1274       if (aNode)
1275       {
1276         if (!anIdToVtk.IsBound(aNode->GetID()))
1277         {
1278           aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1279           anIdToVtk.Bind(aNode->GetID(), nbPoints);
1280         }
1281
1282         aNodes[ k++ ] = aNode->GetID();
1283       }
1284     }
1285
1286     if (k != 4)
1287       continue;
1288
1289     bool isDiag13 = true;
1290     if (aChoice == 0) // use diagonal 1-3
1291     {
1292       isDiag13 = true;
1293     }
1294     else if (aChoice == 1) // use diagonal 2-4
1295     {
1296       isDiag13 = false;
1297     }
1298     else // use numerical functor
1299     {
1300       // compare two sets of possible triangles
1301       int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
1302       if (diag == 1) // 1-3
1303         isDiag13 = true;
1304       else if (diag == 2) // 2-4
1305         isDiag13 = false;
1306       else // error
1307         continue;
1308     }
1309
1310     if (isDiag13)
1311     {
1312       anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1313       anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1314       anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1315       aConnectivity->InsertNextCell(anIdList);
1316       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1317
1318       anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1319       anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1320       anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1321       aConnectivity->InsertNextCell(anIdList);
1322       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1323     }
1324     else
1325     {
1326       anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1327       anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1328       anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1329       aConnectivity->InsertNextCell(anIdList);
1330       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1331
1332       anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1333       anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1334       anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1335       aConnectivity->InsertNextCell(anIdList);
1336       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1337     }
1338   }
1339
1340   VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
1341   aCellLocationsArray->SetNumberOfComponents(1);
1342   aCellLocationsArray->SetNumberOfTuples(aNbCells);
1343
1344   aConnectivity->InitTraversal();
1345   for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1346     aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1347
1348   aGrid->SetPoints(aPoints);
1349   aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1350
1351   // Create and display actor
1352   vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1353   aMapper->SetInput(aGrid);
1354
1355   myPreviewActor = SALOME_Actor::New();
1356   myPreviewActor->PickableOff();
1357   myPreviewActor->SetMapper(aMapper);
1358
1359   vtkProperty* aProp = vtkProperty::New();
1360   aProp->SetRepresentationToWireframe();
1361   aProp->SetColor(250, 0, 250);
1362   aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1363   myPreviewActor->SetProperty(aProp);
1364
1365   SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1366   SMESH::GetCurrentVtkView()->Repaint();
1367
1368   aProp->Delete();
1369   aPoints->Delete();
1370   aConnectivity->Delete();
1371   aGrid->Delete();
1372   aMapper->Delete();
1373   anIdList->Delete();
1374   aCellTypesArray->Delete();
1375   aCellLocationsArray->Delete();
1376 }