]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
Salome HOME
Minor DOC changes
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_AddMeshElementDlg.cxx
25 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_AddQuadraticElementDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_MeshUtils.h"
34 #include "SMESHGUI_GroupUtils.h"
35 #include "SMESHGUI_IdValidator.h"
36
37 #include <SMESH_Actor.h>
38 #include <SMESH_ActorUtils.h>
39 #include <SMESH_FaceOrientationFilter.h>
40 #include <SMDS_Mesh.hxx>
41
42 // SALOME GUI includes
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_ViewManager.h>
48
49 #include <LightApp_SelectionMgr.h>
50
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
53
54 #include <SALOME_ListIO.hxx>
55
56 #include <SalomeApp_Application.h>
57
58 #include <Qtx.h>
59
60 // IDL includes
61 #include <SALOMEconfig.h>
62 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
63
64 // OCCT includes
65 #include <TColStd_MapOfInteger.hxx>
66
67 // VTK includes
68 #include <vtkIdList.h>
69 #include <vtkUnstructuredGrid.h>
70 #include <vtkDataSetMapper.h>
71 #include <vtkPolyDataMapper.h>
72 #include <vtkProperty.h>
73 #include <vtkCellType.h>
74
75 // Qt includes
76 #include <QComboBox>
77 #include <QGroupBox>
78 #include <QLabel>
79 #include <QLineEdit>
80 #include <QPushButton>
81 #include <QRadioButton>
82 #include <QVBoxLayout>
83 #include <QHBoxLayout>
84 #include <QGridLayout>
85 #include <QCheckBox>
86 #include <QTableWidget>
87 #include <QKeyEvent>
88 #include <QButtonGroup>
89
90 // STL includes
91 #include <vector>
92
93 #define SPACING 6
94 #define MARGIN  11
95
96 namespace
97 {
98
99   // Define the sequences of ids
100   static int FirstEdgeIds[] = {0};
101   static int LastEdgeIds[] =  {1};
102
103   static int FirstTriangleIds[] = {0,1,2};
104   static int LastTriangleIds[] =  {1,2,0};
105
106   static int FirstQuadrangleIds[] = {0,1,2,3};
107   static int LastQuadrangleIds[] =  {1,2,3,0};
108
109   static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
110   static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
111
112   static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
113   static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
114
115   static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
116   static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
117
118   static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
119   static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
120
121   static std::vector<int> FirstPolygonIds;
122   static std::vector<int> LastPolygonIds;
123
124   void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
125                             bool toReverse, // inverse element
126                             bool toVtkOrder ) // smds connectivity to vtk one
127   {
128     if ( toReverse ) // first reverse smds order
129     {
130       const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type, ids.size());
131       SMDS_MeshCell::applyInterlace( index, ids );
132     }
133     if ( toVtkOrder ) // from smds to vtk connectivity
134     {
135       const std::vector<int>& index = SMDS_MeshCell::toVtkOrder(type);
136       SMDS_MeshCell::applyInterlace( index, ids );
137     }
138   }
139 }
140 namespace SMESH
141 {
142   class TElementSimulationQuad
143   {
144     SalomeApp_Application* myApplication;
145     SUIT_ViewWindow* myViewWindow;
146     SVTK_ViewWindow* myVTKViewWindow;
147
148     SALOME_Actor* myPreviewActor;
149     vtkDataSetMapper* myMapper;
150     vtkUnstructuredGrid* myGrid;
151     //vtkProperty* myBackProp, *myProp;
152
153     //double myRGB[3], myBackRGB[3];
154
155     SALOME_Actor* myFaceOrientation;
156     vtkPolyDataMapper* myFaceOrientationDataMapper;
157     SMESH_FaceOrientationFilter* myFaceOrientationFilter;
158
159   public:
160     TElementSimulationQuad (SalomeApp_Application* theApplication)
161     {
162       myApplication = theApplication;
163       SUIT_ViewManager* mgr = theApplication->activeViewManager();
164       if (!mgr) return;
165       myViewWindow = mgr->getActiveView();
166       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
167
168       myGrid = vtkUnstructuredGrid::New();
169
170       // Create and display actor
171       myMapper = vtkDataSetMapper::New();
172       myMapper->SetInputData(myGrid);
173
174       myPreviewActor = SALOME_Actor::New();
175       myPreviewActor->PickableOff();
176       myPreviewActor->VisibilityOff();
177       myPreviewActor->SetMapper(myMapper);
178
179       QColor ffc, bfc;
180       int delta;
181       vtkProperty* myProp = vtkProperty::New();
182       SMESH::GetColor( "SMESH", "preview_color", ffc, delta, "0, 255, 0|-100" ) ;
183    
184       myProp->SetColor( ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255. );
185       myPreviewActor->SetProperty( myProp );
186       myProp->Delete();
187
188       vtkProperty* myBackProp = vtkProperty::New();
189       bfc = Qtx::mainColorToSecondary(ffc, delta);
190       myBackProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
191       myPreviewActor->SetBackfaceProperty( myBackProp );
192       myBackProp->Delete();
193
194       myVTKViewWindow->AddActor(myPreviewActor);
195
196       // Orientation of faces
197       myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
198       myFaceOrientationFilter->SetInputData(myGrid);
199
200       myFaceOrientationDataMapper = vtkPolyDataMapper::New();
201       myFaceOrientationDataMapper->SetInputConnection(myFaceOrientationFilter->GetOutputPort());
202
203       myFaceOrientation = SALOME_Actor::New();
204       myFaceOrientation->PickableOff();
205       myFaceOrientation->VisibilityOff();
206       myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
207
208       vtkProperty* anOrientationProp = vtkProperty::New();
209       double aRGB[3];
210       GetColor( "SMESH", "orientation_color", aRGB[0], aRGB[1], aRGB[2], QColor( 255, 255, 255 ) );
211       anOrientationProp->SetColor( aRGB[0], aRGB[1], aRGB[2] );
212       myFaceOrientation->SetProperty( anOrientationProp );
213       anOrientationProp->Delete();
214
215       myVTKViewWindow->AddActor(myFaceOrientation);
216     }
217
218     typedef std::vector<vtkIdType> TVTKIds;
219     void SetPosition (SMESH_Actor*       theActor,
220                       SMDSAbs_EntityType theType,
221                       TVTKIds&           theIds,
222                       const int          theMode,
223                       const bool         theReverse)
224     {
225       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
226       myGrid->SetPoints(aGrid->GetPoints());
227
228       //add points
229
230       ReverseConnectivity( theIds, theType, theReverse, /*toVtkOrder=*/true);
231
232       myGrid->Reset();
233       vtkIdList *anIds = vtkIdList::New();
234
235       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
236         anIds->InsertId(i,theIds[i]);
237         //std::cout << i<< ": " << theIds[i] << std::endl;
238       }
239
240       vtkIdType aType = SMDS_MeshCell::toVtkType(theType);
241       myGrid->InsertNextCell(aType,anIds);
242       anIds->Delete();
243
244       myGrid->Modified();
245
246       myPreviewActor->GetMapper()->Update();
247       myPreviewActor->SetRepresentation( theMode );
248       SetVisibility(true, theActor->GetFacesOriented());
249     }
250
251
252     void SetVisibility (bool theVisibility, bool theShowOrientation = false)
253     {
254       myPreviewActor->SetVisibility(theVisibility);
255       myFaceOrientation->SetVisibility(theShowOrientation);
256       RepaintCurrentView();
257     }
258
259
260     ~TElementSimulationQuad()
261     {
262       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
263         myVTKViewWindow->RemoveActor(myPreviewActor);
264         myVTKViewWindow->RemoveActor(myFaceOrientation);
265       }
266       myPreviewActor->Delete();
267       myFaceOrientation->Delete();
268
269       myMapper->RemoveAllInputs();
270       myMapper->Delete();
271
272       myFaceOrientationFilter->Delete();
273
274       myFaceOrientationDataMapper->RemoveAllInputs();
275       myFaceOrientationDataMapper->Delete();
276
277       myGrid->Delete();
278
279       //       myProp->Delete();
280       //       myBackProp->Delete();
281     }
282   };
283 }
284
285 /*!
286   \class BusyLocker
287   \brief Simple 'busy state' flag locker.
288   \internal
289 */
290 class BusyLocker
291 {
292 public:
293   //! Constructor. Sets passed boolean flag to \c true.
294   BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
295   //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
296   ~BusyLocker() { myBusy = false; }
297 private:
298   bool& myBusy; //! External 'busy state' boolean flag
299 };
300
301 /*!
302   \class IdEditItem
303   \brief Simple editable table item.
304   \internal
305 */
306 class IdEditItem: public QTableWidgetItem
307 {
308 public:
309   IdEditItem(const QString& text );
310   ~IdEditItem();
311
312   QWidget* createEditor() const;
313 };
314
315 IdEditItem::IdEditItem(const QString& text )
316   : QTableWidgetItem(text, QTableWidgetItem::UserType+100)
317 {
318 }
319
320 IdEditItem::~IdEditItem()
321 {
322 }
323
324 QWidget* IdEditItem::createEditor() const
325 {
326   QLineEdit *aLineEdit = new QLineEdit(text(), tableWidget());
327   aLineEdit->setValidator( new SMESHGUI_IdValidator(tableWidget(), 1) );
328   return aLineEdit;
329 }
330
331 //=================================================================================
332 // function : SMESHGUI_AddQuadraticElementDlg()
333 // purpose  : constructor
334 //=================================================================================
335
336 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
337                                                                   const SMDSAbs_EntityType theType )
338   : QDialog( SMESH::GetDesktop( theModule ) ),
339     mySMESHGUI( theModule ),
340     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
341     myBusy( false ),
342     myGeomType( theType )
343 {
344   setModal( false );
345   setAttribute( Qt::WA_DeleteOnClose, true );
346
347   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
348     (SUIT_Session::session()->activeApplication());
349
350   mySimulation = new SMESH::TElementSimulationQuad (anApp);
351   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
352
353   QString anElementName;
354
355   switch ( myGeomType ) {
356   case SMDSEntity_Quad_Edge:
357     anElementName = QString("QUADRATIC_EDGE");
358     break;
359   case SMDSEntity_Quad_Triangle:
360     anElementName = QString("QUADRATIC_TRIANGLE");
361     break;
362   case SMDSEntity_Quad_Quadrangle:
363     anElementName = QString("QUADRATIC_QUADRANGLE");
364     break;
365   case SMDSEntity_Quad_Polygon:
366     anElementName = QString("QUADRATIC_POLYGON");
367     break;
368   case SMDSEntity_BiQuad_Quadrangle:
369     anElementName = QString("BIQUADRATIC_QUADRANGLE");
370     break;
371   case SMDSEntity_BiQuad_Triangle:
372     anElementName = QString("BIQUADRATIC_TRIANGLE");
373     break;
374   case SMDSEntity_Quad_Tetra:
375     anElementName = QString("QUADRATIC_TETRAHEDRON");
376     break;
377   case SMDSEntity_Quad_Pyramid:
378     anElementName = QString("QUADRATIC_PYRAMID");
379     break;
380   case SMDSEntity_Quad_Penta:
381     anElementName = QString("QUADRATIC_PENTAHEDRON");
382     break;
383   case SMDSEntity_Quad_Hexa:
384     anElementName = QString("QUADRATIC_HEXAHEDRON");
385     break;
386   case SMDSEntity_TriQuad_Hexa:
387     anElementName = QString("TRIQUADRATIC_HEXAHEDRON");
388     break;
389   default:
390     myGeomType = SMDSEntity_Quad_Edge;
391     anElementName = QString("QUADRATIC_EDGE");
392   }
393
394   QString iconName           = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
395   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
396   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
397   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
398
399   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
400   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
401
402   setWindowTitle(caption);
403
404   setSizeGripEnabled(true);
405
406   QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
407   aDialogLayout->setSpacing(SPACING);
408   aDialogLayout->setMargin(MARGIN);
409
410   /***************************************************************/
411   GroupConstructors = new QGroupBox(constructorGrTitle, this);
412   QButtonGroup* ButtonGroup = new QButtonGroup(this);
413   QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
414   aGroupConstructorsLayout->setSpacing(SPACING);
415   aGroupConstructorsLayout->setMargin(MARGIN);
416
417   myRadioButton1 = new QRadioButton(GroupConstructors);
418   myRadioButton1->setIcon(image0);
419   aGroupConstructorsLayout->addWidget(myRadioButton1);
420   ButtonGroup->addButton(myRadioButton1, 0);
421
422   /***************************************************************/
423   GroupArguments = new QGroupBox(argumentsGrTitle, this);
424   QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
425   aGroupArgumentsLayout->setSpacing(SPACING);
426   aGroupArgumentsLayout->setMargin(MARGIN);
427
428   // Corner nodes
429   QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
430   myCornerSelectButton = new QPushButton(GroupArguments);
431   myCornerSelectButton->setIcon(image1);
432   myCornerNodes = new QLineEdit(GroupArguments);
433
434   // Mid-edge nodes
435   myTable = new QTableWidget(GroupArguments);
436
437   // Mid-face nodes
438   myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments);
439   myMidFaceSelectButton = new QPushButton(GroupArguments);
440   myMidFaceSelectButton->setIcon(image1);
441   myMidFaceNodes = new QLineEdit(GroupArguments);
442   myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6));
443
444   // Central node
445   myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments);
446   myCenterSelectButton = new QPushButton(GroupArguments);
447   myCenterSelectButton->setIcon(image1);
448   myCenterNode = new QLineEdit(GroupArguments);
449   myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1));
450
451   myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
452
453   aGroupArgumentsLayout->addWidget(aCornerNodesLabel,     0, 0);
454   aGroupArgumentsLayout->addWidget(myCornerSelectButton,  0, 1);
455   aGroupArgumentsLayout->addWidget(myCornerNodes,         0, 2);
456   aGroupArgumentsLayout->addWidget(myTable,               1, 0, 1, 3);
457   aGroupArgumentsLayout->addWidget(myMidFaceLabel,        2, 0);
458   aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1);
459   aGroupArgumentsLayout->addWidget(myMidFaceNodes,        2, 2);
460   aGroupArgumentsLayout->addWidget(myCenterLabel,         3, 0);
461   aGroupArgumentsLayout->addWidget(myCenterSelectButton,  3, 1);
462   aGroupArgumentsLayout->addWidget(myCenterNode,          3, 2);
463   aGroupArgumentsLayout->addWidget(myReverseCB,           4, 0, 1, 3);
464
465     /***************************************************************/
466   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
467   GroupGroups->setCheckable( true );
468   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
469   GroupGroupsLayout->setSpacing(SPACING);
470   GroupGroupsLayout->setMargin(MARGIN);
471
472   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
473   ComboBox_GroupName = new QComboBox( GroupGroups );
474   ComboBox_GroupName->setEditable( true );
475   ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
476
477   GroupGroupsLayout->addWidget( TextLabel_GroupName );
478   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
479
480   /***************************************************************/
481   GroupButtons = new QGroupBox(this);
482   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
483   aGroupButtonsLayout->setSpacing(SPACING);
484   aGroupButtonsLayout->setMargin(MARGIN);
485
486   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
487   buttonOk->setAutoDefault(true);
488   buttonOk->setDefault(true);
489   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
490   buttonApply->setAutoDefault(true);
491   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
492   buttonCancel->setAutoDefault(true);
493   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
494   buttonHelp->setAutoDefault(true);
495
496   aGroupButtonsLayout->addWidget(buttonOk);
497   aGroupButtonsLayout->addSpacing(10);
498   aGroupButtonsLayout->addWidget(buttonApply);
499   aGroupButtonsLayout->addSpacing(10);
500   aGroupButtonsLayout->addStretch();
501   aGroupButtonsLayout->addWidget(buttonCancel);
502   aGroupButtonsLayout->addWidget(buttonHelp);
503
504   /***************************************************************/
505   aDialogLayout->addWidget(GroupConstructors);
506   aDialogLayout->addWidget(GroupArguments);
507   aDialogLayout->addWidget(GroupGroups);
508   aDialogLayout->addWidget(GroupButtons);
509
510   Init(); /* Initialisations */
511 }
512
513 //=================================================================================
514 // function : ~SMESHGUI_AddQuadraticElementDlg()
515 // purpose  : Destroys the object and frees any allocated resources
516 //=================================================================================
517
518 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
519 {
520   delete mySimulation;
521 }
522
523 //=================================================================================
524 // function : Init()
525 // purpose  :
526 //=================================================================================
527
528 void SMESHGUI_AddQuadraticElementDlg::Init()
529 {
530   myRadioButton1->setChecked(true);
531   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
532
533   /* reset "Add to group" control */
534   GroupGroups->setChecked( false );
535
536   myActor = 0;
537   myNbMidFaceNodes = 0;
538   myNbCenterNodes = 0;
539
540   int aNumRows = 0;
541
542   switch (myGeomType) {
543   case SMDSEntity_Quad_Edge:
544     aNumRows = 1;
545     myNbCorners = 2;
546     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
547     break;
548   case SMDSEntity_Quad_Triangle:
549     aNumRows = 3;
550     myNbCorners = 3;
551     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
552     break;
553   case SMDSEntity_BiQuad_Triangle:
554     aNumRows = 3;
555     myNbCorners = 3;
556     myNbCenterNodes = 1;
557     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
558     break;
559   case SMDSEntity_Quad_Quadrangle:
560     aNumRows = 4;
561     myNbCorners = 4;
562     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
563     break;
564   case SMDSEntity_BiQuad_Quadrangle:
565     aNumRows = 4;
566     myNbCorners = 4;
567     myNbCenterNodes = 1;
568     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
569     break;
570   case SMDSEntity_Quad_Polygon:
571     aNumRows = 5;
572     myNbCorners = 0; // no limit
573     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_polygons
574     break;
575   case SMDSEntity_Quad_Tetra:
576     aNumRows = 6;
577     myNbCorners = 4;
578     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
579     break;
580   case SMDSEntity_Quad_Pyramid:
581     aNumRows = 8;
582     myNbCorners = 5;
583     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
584     break;
585   case SMDSEntity_Quad_Penta:
586     aNumRows = 9;
587     myNbCorners = 6;
588     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
589     break;
590   case SMDSEntity_Quad_Hexa:
591     aNumRows = 12;
592     myNbCorners = 8;
593     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
594     break;
595   case SMDSEntity_TriQuad_Hexa:
596     aNumRows = 12;
597     myNbCorners = 8;
598     myNbMidFaceNodes = 6;
599     myNbCenterNodes = 1;
600     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
601     break;
602   default:;
603   }
604
605   myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
606   myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
607   myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
608   myCenterLabel        ->setVisible( myNbCenterNodes );
609   myCenterSelectButton ->setVisible( myNbCenterNodes );
610   myCenterNode         ->setVisible( myNbCenterNodes );
611
612   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
613
614   /* initialize table */
615   myTable->setColumnCount(3);
616   myTable->setRowCount(aNumRows);
617
618   QStringList aColLabels;
619   aColLabels.append(tr("SMESH_FIRST"));
620   aColLabels.append(tr("SMESH_MIDDLE"));
621   aColLabels.append(tr("SMESH_LAST"));
622   myTable->setHorizontalHeaderLabels(aColLabels);
623
624   for ( int col = 0; col < myTable->columnCount(); col++ )
625     myTable->setColumnWidth(col, 80);
626
627   //myTable->setColumnReadOnly(0, true); // VSR: TODO
628   //myTable->setColumnReadOnly(2, true); // VSR: TODO
629
630   myTable->setEnabled( false );
631
632   for ( int row = 0; row < myTable->rowCount(); row++ )
633   {
634     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
635     myTable->item( row, 0 )->setFlags(0);
636
637     IdEditItem* anEditItem = new IdEditItem( "" );
638     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
639     myTable->setItem(row, 1, anEditItem);
640
641     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
642     myTable->item( row, 2 )->setFlags(0);
643   }
644
645   /* signals and slots connections */
646   connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
647   connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
648   connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
649   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
650   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
651   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
652   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
653   connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
654   connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
655   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
656
657   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
658   connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
659   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
660   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
661
662   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
663   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
664   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
665   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), SLOT(onOpenView()));
666   connect(mySMESHGUI, SIGNAL (SignalCloseView()), SLOT(onCloseView()));
667
668   myCurrentLineEdit = myCornerNodes;
669
670   // set selection mode
671   SMESH::SetPointRepresentation(true);
672
673   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
674     aViewWindow->SetSelectionMode( NodeSelection );
675
676   SelectionIntoArgument();
677 }
678
679 //=================================================================================
680 // function : ClickOnApply()
681 // purpose  :
682 //=================================================================================
683
684 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
685 {
686   if( !isValid() )
687     return false;
688
689   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
690     return false;
691
692   BusyLocker lock( myBusy );
693
694   std::vector<vtkIdType> anIds;
695
696   switch (myGeomType) {
697   case SMDSEntity_Quad_Edge:
698     anIds.push_back(myTable->item(0, 0)->text().toInt());
699     anIds.push_back(myTable->item(0, 2)->text().toInt());
700     anIds.push_back(myTable->item(0, 1)->text().toInt());
701     break;
702   case SMDSEntity_Quad_Triangle:
703   case SMDSEntity_Quad_Quadrangle:
704   case SMDSEntity_Quad_Polygon:
705   case SMDSEntity_BiQuad_Triangle:
706   case SMDSEntity_BiQuad_Quadrangle:
707   case SMDSEntity_Quad_Tetra:
708   case SMDSEntity_Quad_Pyramid:
709   case SMDSEntity_Quad_Penta:
710   case SMDSEntity_Quad_Hexa:
711   case SMDSEntity_TriQuad_Hexa:
712     for ( int row = 0; row < myNbCorners; row++ )
713       anIds.push_back(myTable->item(row, 0)->text().toInt());
714     for ( int row = 0; row < myTable->rowCount(); row++ )
715       anIds.push_back(myTable->item(row, 1)->text().toInt());
716     if ( myNbMidFaceNodes )
717     {
718       QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
719       for (int i = 0; i < aListId.count(); i++)
720         anIds.push_back( aListId[ i ].toInt() );
721     }
722     if ( myNbCenterNodes )
723     {
724       QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
725       anIds.push_back( aListId[ 0 ].toInt() );
726     }
727     break;
728   default:;
729   }
730   if ( myReverseCB->isChecked())
731     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
732
733   int aNumberOfIds = anIds.size();
734   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
735   anArrayOfIdeces->length( aNumberOfIds );
736
737   for (int i = 0; i < aNumberOfIds; i++)
738     anArrayOfIdeces[i] = anIds[ i ];
739
740   bool addToGroup = GroupGroups->isChecked();
741   QString aGroupName;
742
743   SMESH::SMESH_GroupBase_var aGroup;
744   int idx = 0;
745   if( addToGroup ) {
746     aGroupName = ComboBox_GroupName->currentText();
747     for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
748       QString aName = ComboBox_GroupName->itemText( i );
749       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
750         idx = i;
751     }
752     if ( idx > 0 && idx <= myGroups.count() ) {
753       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
754       if ( !aGeomGroup->_is_nil() ) {
755         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
756                                              tr( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
757                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
758         if ( res == 1 ) return false;
759       }
760       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
761       if ( !aFilterGroup->_is_nil() ) {
762         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
763                                              tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
764                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
765         if ( res == 1 ) return false;
766       }
767       aGroup = myGroups[idx-1];
768     }
769   }
770
771   SMESH::ElementType anElementType = SMESH::ALL;
772   long anElemId = -1, nbElemsBefore = 0;
773   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
774   switch (myGeomType) {
775   case SMDSEntity_Quad_Edge:
776     anElementType = SMESH::EDGE;
777     nbElemsBefore = myMesh->NbEdges();
778     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
779   case SMDSEntity_Quad_Triangle:
780   case SMDSEntity_Quad_Quadrangle:
781   case SMDSEntity_BiQuad_Triangle:
782   case SMDSEntity_BiQuad_Quadrangle:
783     anElementType = SMESH::FACE;
784     nbElemsBefore = myMesh->NbFaces();
785     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
786   case SMDSEntity_Quad_Polygon:
787     anElementType = SMESH::FACE;
788     nbElemsBefore = myMesh->NbFaces();
789     anElemId = aMeshEditor->AddQuadPolygonalFace(anArrayOfIdeces.inout()); break;
790   case SMDSEntity_Quad_Tetra:
791   case SMDSEntity_Quad_Pyramid:
792   case SMDSEntity_Quad_Penta:
793   case SMDSEntity_Quad_Hexa:
794   case SMDSEntity_TriQuad_Hexa:
795     anElementType = SMESH::VOLUME;
796     nbElemsBefore = myMesh->NbVolumes();
797     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
798   default: break;
799   }
800
801   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
802     SMESH::SMESH_Group_var aGroupUsed;
803     if ( aGroup->_is_nil() ) {
804       // create new group
805       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
806       if ( !aGroupUsed->_is_nil() ) {
807         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
808         ComboBox_GroupName->addItem( aGroupName );
809       }
810     }
811     else {
812       SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
813       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
814       if ( !aGeomGroup->_is_nil() ) {
815         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
816         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
817           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
818           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
819         }
820       }
821       else if ( !aFilterGroup->_is_nil() ) {
822         aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
823         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
824           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
825           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
826         }
827       }
828       else
829         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
830     }
831
832     if ( !aGroupUsed->_is_nil() ) {
833       SMESH::long_array_var anIdList = new SMESH::long_array;
834       anIdList->length( 1 );
835       anIdList[0] = anElemId;
836       aGroupUsed->Add( anIdList.inout() );
837     }
838   }
839
840   if ( nbElemsBefore == 0  )
841   {
842     // 1st element of the type has been added, update actor to show this entity
843     unsigned int aMode = myActor->GetEntityMode();
844     switch ( anElementType ) {
845     case SMESH::EDGE:
846       myActor->SetRepresentation(SMESH_Actor::eEdge);
847       myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
848     case SMESH::FACE:
849       myActor->SetRepresentation(SMESH_Actor::eSurface);
850       myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
851     case SMESH::VOLUME:
852       myActor->SetRepresentation(SMESH_Actor::eSurface);
853       myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
854     default:;
855     }
856   }
857
858   SALOME_ListIO aList; aList.Append( myActor->getIO() );
859   mySelector->ClearIndex();
860   mySelectionMgr->setSelectedObjects( aList, false );
861
862   mySimulation->SetVisibility(false);
863   SMESH::UpdateView();
864
865   UpdateTable();
866   SetCurrentSelection();
867
868   updateButtons();
869
870   SMESHGUI::Modified();
871
872   return true;
873 }
874
875 //=================================================================================
876 // function : ClickOnOk()
877 // purpose  :
878 //=================================================================================
879
880 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
881 {
882   if ( ClickOnApply() )
883     reject();
884 }
885
886 //=================================================================================
887 // function : reject()
888 // purpose  :
889 //=================================================================================
890
891 void SMESHGUI_AddQuadraticElementDlg::reject()
892 {
893   mySelectionMgr->clearSelected();
894   mySimulation->SetVisibility(false);
895   SMESH::SetPointRepresentation(false);
896   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
897     aViewWindow->SetSelectionMode( ActorSelection );
898   disconnect(mySelectionMgr, 0, this, 0);
899   mySMESHGUI->ResetState();
900   QDialog::reject();
901 }
902
903 //=================================================================================
904 // function : onOpenView()
905 // purpose  :
906 //=================================================================================
907 void SMESHGUI_AddQuadraticElementDlg::onOpenView()
908 {
909   if ( mySelector && mySimulation ) {
910     mySimulation->SetVisibility(false);
911     SMESH::SetPointRepresentation(false);
912   }
913   else {
914     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
915     mySimulation = new SMESH::TElementSimulationQuad(
916       dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
917     ActivateThisDialog();
918   }
919 }
920
921 //=================================================================================
922 // function : onCloseView()
923 // purpose  :
924 //=================================================================================
925 void SMESHGUI_AddQuadraticElementDlg::onCloseView()
926 {
927   DeactivateActiveDialog();
928   mySelector = 0;
929   delete mySimulation;
930   mySimulation = 0;
931 }
932 //=================================================================================
933 // function : ClickOnHelp()
934 // purpose  :
935 //=================================================================================
936
937 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
938 {
939   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
940   if (app)
941     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
942   else {
943     QString platform;
944 #ifdef WIN32
945     platform = "winapplication";
946 #else
947     platform = "application";
948 #endif
949     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
950                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
951                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
952                                                                  platform)).
953                              arg(myHelpFileName));
954   }
955 }
956
957 //=================================================================================
958 // function : onTextChange()
959 // purpose  :
960 //=================================================================================
961
962 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
963 {
964   if (myBusy) return;
965   BusyLocker lock( myBusy );
966
967   mySimulation->SetVisibility(false);
968
969   // hilight entered nodes
970   SMDS_Mesh* aMesh = 0;
971   if (myActor)
972     aMesh = myActor->GetObject()->GetMesh();
973
974   QLineEdit* send = (QLineEdit*)sender();
975   if (send == myCornerNodes ||
976       send == myMidFaceNodes ||
977       send == myCenterNode)
978     myCurrentLineEdit = send;
979
980   if (aMesh) {
981     TColStd_MapOfInteger newIndices;
982
983     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
984     bool allOk = true;
985     for (int i = 0; i < aListId.count(); i++) {
986       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
987       {
988         newIndices.Add( n->GetID() );
989       }
990       else
991       {
992         allOk = false;
993         break;
994       }
995     }
996
997     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
998     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
999       aViewWindow->highlight( myActor->getIO(), true, true );
1000
1001     if ( myCurrentLineEdit == myCornerNodes )
1002       UpdateTable( allOk );
1003   }
1004
1005   updateButtons();
1006   displaySimulation();
1007 }
1008
1009 //=================================================================================
1010 // function : SelectionIntoArgument()
1011 // purpose  : Called when selection has changed
1012 //=================================================================================
1013
1014 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
1015 {
1016   if (myBusy) return;
1017   BusyLocker lock( myBusy );
1018
1019   QString aCurrentEntry = myEntry;
1020
1021   if ( myCurrentLineEdit )
1022   {
1023     // clear
1024     myActor = 0;
1025
1026     myCurrentLineEdit->setText("");
1027
1028     if (!GroupButtons->isEnabled()) // inactive
1029       return;
1030
1031     mySimulation->SetVisibility(false);
1032
1033     // get selected mesh
1034     SALOME_ListIO aList;
1035     mySelectionMgr->selectedObjects(aList);
1036
1037     if (aList.Extent() != 1)
1038     {
1039       UpdateTable();
1040       updateButtons();
1041       return;
1042     }
1043
1044     Handle(SALOME_InteractiveObject) anIO = aList.First();
1045     myEntry = anIO->getEntry();
1046     myMesh = SMESH::GetMeshByIO(anIO);
1047     if (myMesh->_is_nil()) {
1048       updateButtons();
1049       return;
1050     }
1051
1052     myActor = SMESH::FindActorByEntry(anIO->getEntry());
1053
1054   }
1055
1056   // process groups
1057   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
1058     SMESH::ElementType anElementType = SMESH::ALL;
1059     switch ( myGeomType ) {
1060     case SMDSEntity_Quad_Edge:
1061       anElementType = SMESH::EDGE; break;
1062     case SMDSEntity_Quad_Triangle:
1063     case SMDSEntity_Quad_Quadrangle:
1064     case SMDSEntity_Quad_Polygon:
1065     case SMDSEntity_BiQuad_Triangle:
1066     case SMDSEntity_BiQuad_Quadrangle:
1067       anElementType = SMESH::FACE; break;
1068     case SMDSEntity_Quad_Tetra:
1069     case SMDSEntity_Quad_Pyramid:
1070     case SMDSEntity_Quad_Penta:
1071     case SMDSEntity_Quad_Hexa:
1072     case SMDSEntity_TriQuad_Hexa:
1073       anElementType = SMESH::VOLUME; break;
1074     default:;
1075     }
1076     myGroups.clear();
1077     ComboBox_GroupName->clear();
1078     ComboBox_GroupName->addItem( QString() );
1079     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
1080     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
1081       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
1082       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
1083         QString aGroupName( aGroup->GetName() );
1084         if ( !aGroupName.isEmpty() ) {
1085           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
1086           ComboBox_GroupName->addItem( aGroupName );
1087         }
1088       }
1089     }
1090   }
1091
1092   if (!myActor) {
1093     updateButtons();
1094     return;
1095   }
1096
1097   // get selected nodes
1098   QString aString = "";
1099   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
1100
1101   if ( myCurrentLineEdit )
1102   {
1103     if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
1104       myCurrentLineEdit->setText(aString);
1105
1106     if ( myCurrentLineEdit == myCornerNodes )
1107       UpdateTable();
1108   }
1109   else if ( myTable->isEnabled() && nbNodes == 1 )
1110   {
1111     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1112     if ( theCol == 1 )
1113       myTable->item(theRow, 1)->setText(aString);
1114   }
1115
1116   updateButtons();
1117   displaySimulation();
1118 }
1119
1120 //=================================================================================
1121 // function : displaySimulation()
1122 // purpose  :
1123 //=================================================================================
1124
1125 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1126 {
1127   if ( IsValid() )
1128   {
1129     SMESH::TElementSimulationQuad::TVTKIds anIds;
1130
1131     // Collect ids from the dialog
1132     int anID;
1133     bool ok;
1134     int aDisplayMode = VTK_SURFACE;
1135
1136     if ( myGeomType == SMDSEntity_Quad_Edge )
1137     {
1138       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1139       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1140       anID = myTable->item(0, 1)->text().toInt(&ok);
1141       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1142       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1143       aDisplayMode = VTK_WIREFRAME;
1144     }
1145     else
1146     {
1147       for ( int row = 0; row < myNbCorners; row++ )
1148         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1149
1150       for ( int row = 0; row < myTable->rowCount(); row++ )
1151       {
1152         anID = myTable->item(row, 1)->text().toInt(&ok);
1153         if (!ok) {
1154           anID = myTable->item(row, 0)->text().toInt();
1155           aDisplayMode = VTK_WIREFRAME;
1156         }
1157         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1158       }
1159       if ( myNbMidFaceNodes )
1160       {
1161         QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1162         for (int i = 0; i < aListId.count(); i++)
1163           anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1164       }
1165       if ( myNbCenterNodes )
1166       {
1167         QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1168         anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1169       }
1170     }
1171
1172     mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1173   }
1174   else
1175   {
1176     mySimulation->SetVisibility(false);
1177   }
1178   SMESH::UpdateView();
1179 }
1180
1181 //=================================================================================
1182 // function : SetCurrentSelection()
1183 // purpose  :
1184 //=================================================================================
1185
1186 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1187 {
1188   QPushButton* send = (QPushButton*)sender();
1189   myCurrentLineEdit = 0;
1190
1191   if (send == myCornerSelectButton)
1192     myCurrentLineEdit = myCornerNodes;
1193   else if ( send == myMidFaceSelectButton )
1194     myCurrentLineEdit = myMidFaceNodes;
1195   else if ( send == myCenterSelectButton )
1196     myCurrentLineEdit = myCenterNode;
1197
1198   if ( myCurrentLineEdit )
1199   {
1200     myCurrentLineEdit->setFocus();
1201     SelectionIntoArgument();
1202   }
1203 }
1204
1205 //=================================================================================
1206 // function : DeactivateActiveDialog()
1207 // purpose  :
1208 //=================================================================================
1209
1210 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1211 {
1212   if (GroupConstructors->isEnabled()) {
1213     GroupConstructors->setEnabled(false);
1214     GroupArguments->setEnabled(false);
1215     GroupButtons->setEnabled(false);
1216     mySimulation->SetVisibility(false);
1217     mySMESHGUI->ResetState();
1218     mySMESHGUI->SetActiveDialogBox(0);
1219   }
1220 }
1221
1222 //=================================================================================
1223 // function : ActivateThisDialog()
1224 // purpose  :
1225 //=================================================================================
1226
1227 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1228 {
1229   /* Emit a signal to deactivate the active dialog */
1230   mySMESHGUI->EmitSignalDeactivateDialog();
1231
1232   GroupConstructors->setEnabled(true);
1233   GroupArguments->setEnabled(true);
1234   GroupButtons->setEnabled(true);
1235
1236   SMESH::SetPointRepresentation(true);
1237
1238   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1239     aViewWindow->SetSelectionMode( NodeSelection );
1240   SelectionIntoArgument();
1241 }
1242
1243 //=================================================================================
1244 // function : enterEvent()
1245 // purpose  :
1246 //=================================================================================
1247 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1248 {
1249   if ( !GroupConstructors->isEnabled() ) {
1250     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1251     if ( aViewWindow && !mySelector && !mySimulation) {
1252       mySelector = aViewWindow->GetSelector();
1253       mySimulation = new SMESH::TElementSimulationQuad(
1254         dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
1255     }
1256     ActivateThisDialog();
1257   }
1258 }
1259
1260 //=================================================================================
1261 // function : onReverse()
1262 // purpose  :
1263 //=================================================================================
1264
1265 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1266 {
1267   mySimulation->SetVisibility(false);
1268   displaySimulation();
1269   updateButtons();
1270 }
1271
1272 //=================================================================================
1273 // function : IsValid()
1274 // purpose  :
1275 //=================================================================================
1276
1277 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1278 {
1279   SMDS_Mesh* aMesh = 0;
1280   if (myActor)
1281     aMesh = myActor->GetObject()->GetMesh();
1282   if (!aMesh)
1283     return false;
1284
1285   bool ok;
1286   std::set< int > okIDs;
1287   for ( int row = 0; row < myTable->rowCount(); row++ )
1288   {
1289     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1290     if ( !ok )
1291       return false;
1292
1293     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1294     if ( !aNode )
1295       return false;
1296     okIDs.insert( anID );
1297   }
1298
1299   QStringList aListId;
1300   if ( myNbMidFaceNodes )
1301     aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1302   if ( myNbCenterNodes )
1303     aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1304
1305   for (int i = 0; i < aListId.count(); i++)
1306   {
1307     int anID = aListId[ i ].toInt(&ok);
1308     if ( !ok )
1309       return false;
1310
1311     if ( !aMesh->FindNode(anID) )
1312       return false;
1313     okIDs.insert( anID );
1314   }
1315
1316   return (int) okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1317 }
1318
1319 //=================================================================================
1320 // function : UpdateTable()
1321 // purpose  :
1322 //=================================================================================
1323
1324 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1325 {
1326   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1327
1328   if ( myGeomType == SMDSEntity_Quad_Polygon )        // POLYGON
1329   {
1330     if ( aListCorners.count() < 3 )
1331       theConersValidity = false;
1332
1333     if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
1334     {
1335       // adjust nb of rows for the polygon
1336       int oldNbRows = myTable->rowCount();
1337       myTable->setRowCount( aListCorners.count() );
1338       for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
1339       {
1340         myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
1341         myTable->item( row, 0 )->setFlags(0);
1342
1343         IdEditItem* anEditItem = new IdEditItem( "" );
1344         anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
1345         myTable->setItem(row, 1, anEditItem);
1346
1347         myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
1348         myTable->item( row, 2 )->setFlags(0);
1349       }
1350       myNbCorners = aListCorners.count();
1351
1352       // fill FirstPolygonIds and LastPolygonIds
1353       FirstPolygonIds.resize( aListCorners.count() );
1354       LastPolygonIds .resize( aListCorners.count() );
1355       for ( int i = 0; i < aListCorners.count(); ++i )
1356       {
1357         FirstPolygonIds[i] = i;
1358         LastPolygonIds [i] = i+1;
1359       }
1360       LastPolygonIds.back() = 0;
1361
1362       myNbCorners = aListCorners.count();
1363     }
1364   }
1365
1366   if ( aListCorners.count() == myNbCorners && theConersValidity )
1367   {
1368     myTable->setEnabled( true );
1369
1370     // clear the Middle column
1371     for ( int row = 0; row < myTable->rowCount(); row++ )
1372       myTable->item( row, 1 )->setText("");
1373
1374     int* aFirstColIds = 0;
1375     int* aLastColIds  = 0;
1376
1377     switch (myGeomType) {
1378     case SMDSEntity_Quad_Edge:
1379       aFirstColIds = FirstEdgeIds;
1380       aLastColIds  = LastEdgeIds;
1381       break;
1382     case SMDSEntity_Quad_Triangle:
1383     case SMDSEntity_BiQuad_Triangle:
1384       aFirstColIds = FirstTriangleIds;
1385       aLastColIds  = LastTriangleIds;
1386       break;
1387     case SMDSEntity_Quad_Quadrangle:
1388     case SMDSEntity_BiQuad_Quadrangle:
1389       aFirstColIds = FirstQuadrangleIds;
1390       aLastColIds  = LastQuadrangleIds;
1391       break;
1392     case SMDSEntity_Quad_Polygon:
1393       aFirstColIds = & FirstPolygonIds[0];
1394       aLastColIds  = & LastPolygonIds[0];
1395       break;
1396     case SMDSEntity_Quad_Tetra:
1397       aFirstColIds = FirstTetrahedronIds;
1398       aLastColIds  = LastTetrahedronIds;
1399       break;
1400     case SMDSEntity_Quad_Pyramid:
1401       aFirstColIds = FirstPyramidIds;
1402       aLastColIds  = LastPyramidIds;
1403       break;
1404     case SMDSEntity_Quad_Penta:
1405       aFirstColIds = FirstPentahedronIds;
1406       aLastColIds  = LastPentahedronIds;
1407       break;
1408     case SMDSEntity_Quad_Hexa:
1409     case SMDSEntity_TriQuad_Hexa:
1410       aFirstColIds = FirstHexahedronIds;
1411       aLastColIds  = LastHexahedronIds;
1412       break;
1413     default:;
1414     }
1415
1416     // fill the First and the Last columns
1417     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1418       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1419
1420     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1421       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1422   }
1423   else
1424   {
1425     // clear table
1426     for ( int row = 0; row < myTable->rowCount(); row++ )
1427       for ( int col = 0; col < myTable->columnCount(); col++ )
1428         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1429
1430     myTable->setEnabled( false );
1431   }
1432 }
1433
1434 //=================================================================================
1435 // function : onTableActivate()
1436 // purpose  :
1437 //=================================================================================
1438
1439 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1440 {
1441   myCurrentLineEdit = 0;
1442   displaySimulation();
1443   updateButtons();
1444 }
1445
1446 //=================================================================================
1447 // function : onCellTextChange()
1448 // purpose  :
1449 //=================================================================================
1450
1451 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1452 {
1453   myCurrentLineEdit = 0;
1454   displaySimulation();
1455   updateButtons();
1456 }
1457
1458 //=================================================================================
1459 // function : keyPressEvent()
1460 // purpose  :
1461 //=================================================================================
1462
1463 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1464 {
1465   QDialog::keyPressEvent( e );
1466   if ( e->isAccepted() )
1467     return;
1468
1469   if ( e->key() == Qt::Key_F1 ) {
1470     e->accept();
1471     ClickOnHelp();
1472   }
1473 }
1474
1475 //=======================================================================
1476 //function : updateButtons
1477 //purpose  : 
1478 //=======================================================================
1479
1480 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1481 {
1482   bool valid = IsValid();
1483   buttonOk->setEnabled( valid );
1484   buttonApply->setEnabled( valid );
1485 }
1486
1487 //=================================================================================
1488 // function : isValid
1489 // purpose  :
1490 //=================================================================================
1491
1492 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1493 {
1494   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1495     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1496     return false;
1497   }
1498   return true;
1499 }