Salome HOME
bos #20256: [CEA 18523] Porting SMESH to int 64 bits
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 // Copyright (C) 2007-2021  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_BiQuad_Penta:
384     anElementName = QString("BIQUADRATIC_PENTAHEDRON");
385     break;
386   case SMDSEntity_Quad_Hexa:
387     anElementName = QString("QUADRATIC_HEXAHEDRON");
388     break;
389   case SMDSEntity_TriQuad_Hexa:
390     anElementName = QString("TRIQUADRATIC_HEXAHEDRON");
391     break;
392   default:
393     myGeomType = SMDSEntity_Quad_Edge;
394     anElementName = QString("QUADRATIC_EDGE");
395   }
396
397   QString iconName           = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
398   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
399   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
400   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
401
402   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
403   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
404
405   setWindowTitle(caption);
406
407   setSizeGripEnabled(true);
408
409   QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
410   aDialogLayout->setSpacing(SPACING);
411   aDialogLayout->setMargin(MARGIN);
412
413   /***************************************************************/
414   GroupConstructors = new QGroupBox(constructorGrTitle, this);
415   QButtonGroup* ButtonGroup = new QButtonGroup(this);
416   QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
417   aGroupConstructorsLayout->setSpacing(SPACING);
418   aGroupConstructorsLayout->setMargin(MARGIN);
419
420   myRadioButton1 = new QRadioButton(GroupConstructors);
421   myRadioButton1->setIcon(image0);
422   aGroupConstructorsLayout->addWidget(myRadioButton1);
423   ButtonGroup->addButton(myRadioButton1, 0);
424
425   /***************************************************************/
426   GroupArguments = new QGroupBox(argumentsGrTitle, this);
427   QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
428   aGroupArgumentsLayout->setSpacing(SPACING);
429   aGroupArgumentsLayout->setMargin(MARGIN);
430
431   // Corner nodes
432   QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
433   myCornerSelectButton = new QPushButton(GroupArguments);
434   myCornerSelectButton->setIcon(image1);
435   myCornerNodes = new QLineEdit(GroupArguments);
436
437   // Mid-edge nodes
438   myTable = new QTableWidget(GroupArguments);
439
440   // Mid-face nodes
441   myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments);
442   myMidFaceSelectButton = new QPushButton(GroupArguments);
443   myMidFaceSelectButton->setIcon(image1);
444   myMidFaceNodes = new QLineEdit(GroupArguments);
445   myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6));
446
447   // Central node
448   myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments);
449   myCenterSelectButton = new QPushButton(GroupArguments);
450   myCenterSelectButton->setIcon(image1);
451   myCenterNode = new QLineEdit(GroupArguments);
452   myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1));
453
454   myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
455
456   aGroupArgumentsLayout->addWidget(aCornerNodesLabel,     0, 0);
457   aGroupArgumentsLayout->addWidget(myCornerSelectButton,  0, 1);
458   aGroupArgumentsLayout->addWidget(myCornerNodes,         0, 2);
459   aGroupArgumentsLayout->addWidget(myTable,               1, 0, 1, 3);
460   aGroupArgumentsLayout->addWidget(myMidFaceLabel,        2, 0);
461   aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1);
462   aGroupArgumentsLayout->addWidget(myMidFaceNodes,        2, 2);
463   aGroupArgumentsLayout->addWidget(myCenterLabel,         3, 0);
464   aGroupArgumentsLayout->addWidget(myCenterSelectButton,  3, 1);
465   aGroupArgumentsLayout->addWidget(myCenterNode,          3, 2);
466   aGroupArgumentsLayout->addWidget(myReverseCB,           4, 0, 1, 3);
467
468     /***************************************************************/
469   GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
470   GroupGroups->setCheckable( true );
471   QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
472   GroupGroupsLayout->setSpacing(SPACING);
473   GroupGroupsLayout->setMargin(MARGIN);
474
475   TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
476   ComboBox_GroupName = new QComboBox( GroupGroups );
477   ComboBox_GroupName->setEditable( true );
478   ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
479
480   GroupGroupsLayout->addWidget( TextLabel_GroupName );
481   GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
482
483   /***************************************************************/
484   GroupButtons = new QGroupBox(this);
485   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
486   aGroupButtonsLayout->setSpacing(SPACING);
487   aGroupButtonsLayout->setMargin(MARGIN);
488
489   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
490   buttonOk->setAutoDefault(true);
491   buttonOk->setDefault(true);
492   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
493   buttonApply->setAutoDefault(true);
494   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
495   buttonCancel->setAutoDefault(true);
496   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
497   buttonHelp->setAutoDefault(true);
498
499   aGroupButtonsLayout->addWidget(buttonOk);
500   aGroupButtonsLayout->addSpacing(10);
501   aGroupButtonsLayout->addWidget(buttonApply);
502   aGroupButtonsLayout->addSpacing(10);
503   aGroupButtonsLayout->addStretch();
504   aGroupButtonsLayout->addWidget(buttonCancel);
505   aGroupButtonsLayout->addWidget(buttonHelp);
506
507   /***************************************************************/
508   aDialogLayout->addWidget(GroupConstructors);
509   aDialogLayout->addWidget(GroupArguments);
510   aDialogLayout->addWidget(GroupGroups);
511   aDialogLayout->addWidget(GroupButtons);
512
513   Init(); /* Initialisations */
514 }
515
516 //=================================================================================
517 // function : ~SMESHGUI_AddQuadraticElementDlg()
518 // purpose  : Destroys the object and frees any allocated resources
519 //=================================================================================
520
521 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
522 {
523   delete mySimulation;
524 }
525
526 //=================================================================================
527 // function : Init()
528 // purpose  :
529 //=================================================================================
530
531 void SMESHGUI_AddQuadraticElementDlg::Init()
532 {
533   myRadioButton1->setChecked(true);
534   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
535
536   /* reset "Add to group" control */
537   GroupGroups->setChecked( false );
538
539   myActor = 0;
540   myNbMidFaceNodes = 0;
541   myNbCenterNodes = 0;
542
543   int aNumRows = 0;
544
545   switch (myGeomType) {
546   case SMDSEntity_Quad_Edge:
547     aNumRows = 1;
548     myNbCorners = 2;
549     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_edges
550     break;
551   case SMDSEntity_Quad_Triangle:
552     aNumRows = 3;
553     myNbCorners = 3;
554     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_triangles
555     break;
556   case SMDSEntity_BiQuad_Triangle:
557     aNumRows = 3;
558     myNbCorners = 3;
559     myNbCenterNodes = 1;
560     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_triangles
561     break;
562   case SMDSEntity_Quad_Quadrangle:
563     aNumRows = 4;
564     myNbCorners = 4;
565     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_quadrangles
566     break;
567   case SMDSEntity_BiQuad_Quadrangle:
568     aNumRows = 4;
569     myNbCorners = 4;
570     myNbCenterNodes = 1;
571     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_quadrangles
572     break;
573   case SMDSEntity_Quad_Polygon:
574     aNumRows = 5;
575     myNbCorners = 0; // no limit
576     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_polygons
577     break;
578   case SMDSEntity_Quad_Tetra:
579     aNumRows = 6;
580     myNbCorners = 4;
581     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_tetrahedrons
582     break;
583   case SMDSEntity_Quad_Pyramid:
584     aNumRows = 8;
585     myNbCorners = 5;
586     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_pyramids
587     break;
588   case SMDSEntity_Quad_Penta:
589     aNumRows = 9;
590     myNbCorners = 6;
591     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_pentahedrons
592     break;
593   case SMDSEntity_BiQuad_Penta:
594     aNumRows = 9;
595     myNbCorners = 6;
596     myNbMidFaceNodes = 3;
597     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_pentahedrons
598     break;
599   case SMDSEntity_Quad_Hexa:
600     aNumRows = 12;
601     myNbCorners = 8;
602     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_hexahedrons
603     break;
604   case SMDSEntity_TriQuad_Hexa:
605     aNumRows = 12;
606     myNbCorners = 8;
607     myNbMidFaceNodes = 6;
608     myNbCenterNodes = 1;
609     myHelpFileName = "adding_quadratic_elements.html#?"; //Adding_hexahedrons
610     break;
611   default:;
612   }
613
614   myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
615   myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
616   myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
617   myCenterLabel        ->setVisible( myNbCenterNodes );
618   myCenterSelectButton ->setVisible( myNbCenterNodes );
619   myCenterNode         ->setVisible( myNbCenterNodes );
620
621   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
622
623   /* initialize table */
624   myTable->setColumnCount(3);
625   myTable->setRowCount(aNumRows);
626
627   QStringList aColLabels;
628   aColLabels.append(tr("SMESH_FIRST"));
629   aColLabels.append(tr("SMESH_MIDDLE"));
630   aColLabels.append(tr("SMESH_LAST"));
631   myTable->setHorizontalHeaderLabels(aColLabels);
632
633   for ( int col = 0; col < myTable->columnCount(); col++ )
634     myTable->setColumnWidth(col, 80);
635
636   //myTable->setColumnReadOnly(0, true); // VSR: TODO
637   //myTable->setColumnReadOnly(2, true); // VSR: TODO
638
639   myTable->setEnabled( false );
640
641   for ( int row = 0; row < myTable->rowCount(); row++ )
642   {
643     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
644     myTable->item( row, 0 )->setFlags(0);
645
646     IdEditItem* anEditItem = new IdEditItem( "" );
647     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
648     myTable->setItem(row, 1, anEditItem);
649
650     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
651     myTable->item( row, 2 )->setFlags(0);
652   }
653
654   /* signals and slots connections */
655   connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
656   connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
657   connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
658   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
659   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
660   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
661   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
662   connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
663   connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
664   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
665
666   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
667   connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
668   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
669   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
670
671   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
672   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
673   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
674   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), SLOT(onOpenView()));
675   connect(mySMESHGUI, SIGNAL (SignalCloseView()), SLOT(onCloseView()));
676
677   myCurrentLineEdit = myCornerNodes;
678
679   // set selection mode
680   SMESH::SetPointRepresentation(true);
681
682   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
683     aViewWindow->SetSelectionMode( NodeSelection );
684
685   SelectionIntoArgument();
686 }
687
688 //=================================================================================
689 // function : ClickOnApply()
690 // purpose  :
691 //=================================================================================
692
693 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
694 {
695   if( !isValid() )
696     return false;
697
698   if ( SMESHGUI::isStudyLocked() || myBusy || !IsValid() )
699     return false;
700
701   BusyLocker lock( myBusy );
702
703   std::vector<vtkIdType> anIds;
704
705   switch (myGeomType) {
706   case SMDSEntity_Quad_Edge:
707     anIds.push_back(myTable->item(0, 0)->text().toInt());
708     anIds.push_back(myTable->item(0, 2)->text().toInt());
709     anIds.push_back(myTable->item(0, 1)->text().toInt());
710     break;
711   case SMDSEntity_Quad_Triangle:
712   case SMDSEntity_Quad_Quadrangle:
713   case SMDSEntity_Quad_Polygon:
714   case SMDSEntity_BiQuad_Triangle:
715   case SMDSEntity_BiQuad_Quadrangle:
716   case SMDSEntity_Quad_Tetra:
717   case SMDSEntity_Quad_Pyramid:
718   case SMDSEntity_Quad_Penta:
719   case SMDSEntity_BiQuad_Penta:
720   case SMDSEntity_Quad_Hexa:
721   case SMDSEntity_TriQuad_Hexa:
722     for ( int row = 0; row < myNbCorners; row++ )
723       anIds.push_back(myTable->item(row, 0)->text().toInt());
724     for ( int row = 0; row < myTable->rowCount(); row++ )
725       anIds.push_back(myTable->item(row, 1)->text().toInt());
726     if ( myNbMidFaceNodes )
727     {
728       QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
729       for (int i = 0; i < aListId.count(); i++)
730         anIds.push_back( aListId[ i ].toInt() );
731     }
732     if ( myNbCenterNodes )
733     {
734       QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
735       anIds.push_back( aListId[ 0 ].toInt() );
736     }
737     break;
738   default:;
739   }
740   if ( myReverseCB->isChecked())
741     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
742
743   int aNumberOfIds = anIds.size();
744   SMESH::smIdType_array_var anArrayOfIdeces = new SMESH::smIdType_array;
745   anArrayOfIdeces->length( aNumberOfIds );
746
747   for (int i = 0; i < aNumberOfIds; i++)
748     anArrayOfIdeces[i] = anIds[ i ];
749
750   bool addToGroup = GroupGroups->isChecked();
751   QString aGroupName;
752
753   SMESH::SMESH_GroupBase_var aGroup;
754   int idx = 0;
755   if( addToGroup ) {
756     aGroupName = ComboBox_GroupName->currentText();
757     for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
758       QString aName = ComboBox_GroupName->itemText( i );
759       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
760         idx = i;
761     }
762     if ( idx > 0 && idx <= myGroups.count() ) {
763       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
764       if ( !aGeomGroup->_is_nil() ) {
765         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
766                                              tr( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
767                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
768         if ( res == 1 ) return false;
769       }
770       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
771       if ( !aFilterGroup->_is_nil() ) {
772         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
773                                              tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
774                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
775         if ( res == 1 ) return false;
776       }
777       aGroup = myGroups[idx-1];
778     }
779   }
780
781   SMESH::ElementType anElementType = SMESH::ALL;
782   long anElemId = -1, nbElemsBefore = 0;
783   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
784   switch (myGeomType) {
785   case SMDSEntity_Quad_Edge:
786     anElementType = SMESH::EDGE;
787     nbElemsBefore = myMesh->NbEdges();
788     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
789   case SMDSEntity_Quad_Triangle:
790   case SMDSEntity_Quad_Quadrangle:
791   case SMDSEntity_BiQuad_Triangle:
792   case SMDSEntity_BiQuad_Quadrangle:
793     anElementType = SMESH::FACE;
794     nbElemsBefore = myMesh->NbFaces();
795     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
796   case SMDSEntity_Quad_Polygon:
797     anElementType = SMESH::FACE;
798     nbElemsBefore = myMesh->NbFaces();
799     anElemId = aMeshEditor->AddQuadPolygonalFace(anArrayOfIdeces.inout()); break;
800   case SMDSEntity_Quad_Tetra:
801   case SMDSEntity_Quad_Pyramid:
802   case SMDSEntity_Quad_Penta:
803   case SMDSEntity_BiQuad_Penta:
804   case SMDSEntity_Quad_Hexa:
805   case SMDSEntity_TriQuad_Hexa:
806     anElementType = SMESH::VOLUME;
807     nbElemsBefore = myMesh->NbVolumes();
808     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
809   default: break;
810   }
811
812   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
813     SMESH::SMESH_Group_var aGroupUsed;
814     if ( aGroup->_is_nil() ) {
815       // create new group
816       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
817       if ( !aGroupUsed->_is_nil() ) {
818         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
819         ComboBox_GroupName->addItem( aGroupName );
820       }
821     }
822     else {
823       SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
824       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
825       if ( !aGeomGroup->_is_nil() ) {
826         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
827         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
828           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
829           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
830         }
831       }
832       else if ( !aFilterGroup->_is_nil() ) {
833         aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
834         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
835           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
836           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
837         }
838       }
839       else
840         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
841     }
842
843     if ( !aGroupUsed->_is_nil() ) {
844       SMESH::smIdType_array_var anIdList = new SMESH::smIdType_array;
845       anIdList->length( 1 );
846       anIdList[0] = anElemId;
847       aGroupUsed->Add( anIdList.inout() );
848     }
849   }
850
851   if ( nbElemsBefore == 0  )
852   {
853     // 1st element of the type has been added, update actor to show this entity
854     unsigned int aMode = myActor->GetEntityMode();
855     switch ( anElementType ) {
856     case SMESH::EDGE:
857       myActor->SetRepresentation(SMESH_Actor::eEdge);
858       myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
859     case SMESH::FACE:
860       myActor->SetRepresentation(SMESH_Actor::eSurface);
861       myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
862     case SMESH::VOLUME:
863       myActor->SetRepresentation(SMESH_Actor::eSurface);
864       myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
865     default:;
866     }
867   }
868
869   SALOME_ListIO aList; aList.Append( myActor->getIO() );
870   mySelector->ClearIndex();
871   mySelectionMgr->setSelectedObjects( aList, false );
872
873   mySimulation->SetVisibility(false);
874   SMESH::UpdateView();
875
876   UpdateTable();
877   SetCurrentSelection();
878
879   updateButtons();
880
881   SMESHGUI::Modified();
882
883   return true;
884 }
885
886 //=================================================================================
887 // function : ClickOnOk()
888 // purpose  :
889 //=================================================================================
890
891 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
892 {
893   if ( ClickOnApply() )
894     reject();
895 }
896
897 //=================================================================================
898 // function : reject()
899 // purpose  :
900 //=================================================================================
901
902 void SMESHGUI_AddQuadraticElementDlg::reject()
903 {
904   mySelectionMgr->clearSelected();
905   mySimulation->SetVisibility(false);
906   SMESH::SetPointRepresentation(false);
907   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
908     aViewWindow->SetSelectionMode( ActorSelection );
909   disconnect(mySelectionMgr, 0, this, 0);
910   mySMESHGUI->ResetState();
911   QDialog::reject();
912 }
913
914 //=================================================================================
915 // function : onOpenView()
916 // purpose  :
917 //=================================================================================
918 void SMESHGUI_AddQuadraticElementDlg::onOpenView()
919 {
920   if ( mySelector && mySimulation ) {
921     mySimulation->SetVisibility(false);
922     SMESH::SetPointRepresentation(false);
923   }
924   else {
925     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
926     mySimulation = new SMESH::TElementSimulationQuad(
927       dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
928     ActivateThisDialog();
929   }
930 }
931
932 //=================================================================================
933 // function : onCloseView()
934 // purpose  :
935 //=================================================================================
936 void SMESHGUI_AddQuadraticElementDlg::onCloseView()
937 {
938   DeactivateActiveDialog();
939   mySelector = 0;
940   delete mySimulation;
941   mySimulation = 0;
942 }
943 //=================================================================================
944 // function : ClickOnHelp()
945 // purpose  :
946 //=================================================================================
947
948 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
949 {
950   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
951   if (app)
952     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
953   else {
954     QString platform;
955 #ifdef WIN32
956     platform = "winapplication";
957 #else
958     platform = "application";
959 #endif
960     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
961                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
962                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
963                                                                  platform)).
964                              arg(myHelpFileName));
965   }
966 }
967
968 //=================================================================================
969 // function : onTextChange()
970 // purpose  :
971 //=================================================================================
972
973 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
974 {
975   if (myBusy) return;
976   BusyLocker lock( myBusy );
977
978   mySimulation->SetVisibility(false);
979
980   // highlight entered nodes
981   SMDS_Mesh* aMesh = 0;
982   if (myActor)
983     aMesh = myActor->GetObject()->GetMesh();
984
985   QLineEdit* send = (QLineEdit*)sender();
986   if (send == myCornerNodes ||
987       send == myMidFaceNodes ||
988       send == myCenterNode)
989     myCurrentLineEdit = send;
990
991   if (aMesh) {
992     SVTK_TVtkIDsMap newIndices;
993
994     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
995     bool allOk = true;
996     for (int i = 0; i < aListId.count(); i++) {
997       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
998       {
999         newIndices.Add( n->GetID() );
1000       }
1001       else
1002       {
1003         allOk = false;
1004         break;
1005       }
1006     }
1007
1008     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
1009     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1010       aViewWindow->highlight( myActor->getIO(), true, true );
1011
1012     if ( myCurrentLineEdit == myCornerNodes )
1013       UpdateTable( allOk );
1014   }
1015
1016   updateButtons();
1017   displaySimulation();
1018 }
1019
1020 //=================================================================================
1021 // function : SelectionIntoArgument()
1022 // purpose  : Called when selection has changed
1023 //=================================================================================
1024
1025 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
1026 {
1027   if (myBusy) return;
1028   BusyLocker lock( myBusy );
1029
1030   QString aCurrentEntry = myEntry;
1031
1032   if ( myCurrentLineEdit )
1033   {
1034     // clear
1035     myActor = 0;
1036
1037     myCurrentLineEdit->setText("");
1038
1039     if (!GroupButtons->isEnabled()) // inactive
1040       return;
1041
1042     mySimulation->SetVisibility(false);
1043
1044     // get selected mesh
1045     SALOME_ListIO aList;
1046     mySelectionMgr->selectedObjects(aList);
1047
1048     if (aList.Extent() != 1)
1049     {
1050       UpdateTable();
1051       updateButtons();
1052       return;
1053     }
1054
1055     Handle(SALOME_InteractiveObject) anIO = aList.First();
1056     myEntry = anIO->getEntry();
1057     myMesh = SMESH::GetMeshByIO(anIO);
1058     if (myMesh->_is_nil()) {
1059       updateButtons();
1060       return;
1061     }
1062
1063     myActor = SMESH::FindActorByEntry(anIO->getEntry());
1064
1065   }
1066
1067   // process groups
1068   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
1069     SMESH::ElementType anElementType = SMESH::ALL;
1070     switch ( myGeomType ) {
1071     case SMDSEntity_Quad_Edge:
1072       anElementType = SMESH::EDGE; break;
1073     case SMDSEntity_Quad_Triangle:
1074     case SMDSEntity_Quad_Quadrangle:
1075     case SMDSEntity_Quad_Polygon:
1076     case SMDSEntity_BiQuad_Triangle:
1077     case SMDSEntity_BiQuad_Quadrangle:
1078       anElementType = SMESH::FACE; break;
1079     case SMDSEntity_Quad_Tetra:
1080     case SMDSEntity_Quad_Pyramid:
1081     case SMDSEntity_Quad_Penta:
1082     case SMDSEntity_BiQuad_Penta:
1083     case SMDSEntity_Quad_Hexa:
1084     case SMDSEntity_TriQuad_Hexa:
1085       anElementType = SMESH::VOLUME; break;
1086     default:;
1087     }
1088     myGroups.clear();
1089     ComboBox_GroupName->clear();
1090     ComboBox_GroupName->addItem( QString() );
1091     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
1092     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
1093       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
1094       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
1095         QString aGroupName( aGroup->GetName() );
1096         if ( !aGroupName.isEmpty() ) {
1097           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
1098           ComboBox_GroupName->addItem( aGroupName );
1099         }
1100       }
1101     }
1102   }
1103
1104   if (!myActor) {
1105     updateButtons();
1106     return;
1107   }
1108
1109   // get selected nodes
1110   QString aString = "";
1111   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
1112
1113   if ( myCurrentLineEdit )
1114   {
1115     if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
1116       myCurrentLineEdit->setText(aString);
1117
1118     if ( myCurrentLineEdit == myCornerNodes )
1119       UpdateTable();
1120   }
1121   else if ( myTable->isEnabled() && nbNodes == 1 )
1122   {
1123     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1124     if ( theCol == 1 )
1125       myTable->item(theRow, 1)->setText(aString);
1126   }
1127
1128   updateButtons();
1129   displaySimulation();
1130 }
1131
1132 //=================================================================================
1133 // function : displaySimulation()
1134 // purpose  :
1135 //=================================================================================
1136
1137 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1138 {
1139   if ( IsValid() )
1140   {
1141     SMESH::TElementSimulationQuad::TVTKIds anIds;
1142
1143     // Collect ids from the dialog
1144     int anID;
1145     bool ok;
1146     int aDisplayMode = VTK_SURFACE;
1147
1148     if ( myGeomType == SMDSEntity_Quad_Edge )
1149     {
1150       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1151       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1152       anID = myTable->item(0, 1)->text().toInt(&ok);
1153       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1154       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1155       aDisplayMode = VTK_WIREFRAME;
1156     }
1157     else
1158     {
1159       for ( int row = 0; row < myNbCorners; row++ )
1160         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1161
1162       for ( int row = 0; row < myTable->rowCount(); row++ )
1163       {
1164         anID = myTable->item(row, 1)->text().toInt(&ok);
1165         if (!ok) {
1166           anID = myTable->item(row, 0)->text().toInt();
1167           aDisplayMode = VTK_WIREFRAME;
1168         }
1169         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1170       }
1171       if ( myNbMidFaceNodes )
1172       {
1173         QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1174         for (int i = 0; i < aListId.count(); i++)
1175           anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1176       }
1177       if ( myNbCenterNodes )
1178       {
1179         QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1180         anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1181       }
1182     }
1183
1184     mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1185   }
1186   else
1187   {
1188     mySimulation->SetVisibility(false);
1189   }
1190   SMESH::UpdateView();
1191 }
1192
1193 //=================================================================================
1194 // function : SetCurrentSelection()
1195 // purpose  :
1196 //=================================================================================
1197
1198 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1199 {
1200   QPushButton* send = (QPushButton*)sender();
1201   myCurrentLineEdit = 0;
1202
1203   if (send == myCornerSelectButton)
1204     myCurrentLineEdit = myCornerNodes;
1205   else if ( send == myMidFaceSelectButton )
1206     myCurrentLineEdit = myMidFaceNodes;
1207   else if ( send == myCenterSelectButton )
1208     myCurrentLineEdit = myCenterNode;
1209
1210   if ( myCurrentLineEdit )
1211   {
1212     myCurrentLineEdit->setFocus();
1213     SelectionIntoArgument();
1214   }
1215 }
1216
1217 //=================================================================================
1218 // function : DeactivateActiveDialog()
1219 // purpose  :
1220 //=================================================================================
1221
1222 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1223 {
1224   if (GroupConstructors->isEnabled()) {
1225     GroupConstructors->setEnabled(false);
1226     GroupArguments->setEnabled(false);
1227     GroupButtons->setEnabled(false);
1228     mySimulation->SetVisibility(false);
1229     mySMESHGUI->ResetState();
1230     mySMESHGUI->SetActiveDialogBox(0);
1231   }
1232 }
1233
1234 //=================================================================================
1235 // function : ActivateThisDialog()
1236 // purpose  :
1237 //=================================================================================
1238
1239 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1240 {
1241   /* Emit a signal to deactivate the active dialog */
1242   mySMESHGUI->EmitSignalDeactivateDialog();
1243
1244   GroupConstructors->setEnabled(true);
1245   GroupArguments->setEnabled(true);
1246   GroupButtons->setEnabled(true);
1247
1248   SMESH::SetPointRepresentation(true);
1249
1250   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1251     aViewWindow->SetSelectionMode( NodeSelection );
1252   SelectionIntoArgument();
1253 }
1254
1255 //=================================================================================
1256 // function : enterEvent()
1257 // purpose  :
1258 //=================================================================================
1259 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1260 {
1261   if ( !GroupConstructors->isEnabled() ) {
1262     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1263     if ( aViewWindow && !mySelector && !mySimulation) {
1264       mySelector = aViewWindow->GetSelector();
1265       mySimulation = new SMESH::TElementSimulationQuad(
1266         dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
1267     }
1268     ActivateThisDialog();
1269   }
1270 }
1271
1272 //=================================================================================
1273 // function : onReverse()
1274 // purpose  :
1275 //=================================================================================
1276
1277 void SMESHGUI_AddQuadraticElementDlg::onReverse (int /*state*/)
1278 {
1279   mySimulation->SetVisibility(false);
1280   displaySimulation();
1281   updateButtons();
1282 }
1283
1284 //=================================================================================
1285 // function : IsValid()
1286 // purpose  :
1287 //=================================================================================
1288
1289 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1290 {
1291   SMDS_Mesh* aMesh = 0;
1292   if (myActor)
1293     aMesh = myActor->GetObject()->GetMesh();
1294   if (!aMesh)
1295     return false;
1296
1297   bool ok;
1298   std::set< int > okIDs;
1299   for ( int row = 0; row < myTable->rowCount(); row++ )
1300   {
1301     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1302     if ( !ok )
1303       return false;
1304
1305     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1306     if ( !aNode )
1307       return false;
1308     okIDs.insert( anID );
1309   }
1310
1311   QStringList aListId;
1312   if ( myNbMidFaceNodes )
1313     aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1314   if ( myNbCenterNodes )
1315     aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1316
1317   for (int i = 0; i < aListId.count(); i++)
1318   {
1319     int anID = aListId[ i ].toInt(&ok);
1320     if ( !ok )
1321       return false;
1322
1323     if ( !aMesh->FindNode(anID) )
1324       return false;
1325     okIDs.insert( anID );
1326   }
1327
1328   return (int) okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1329 }
1330
1331 //=================================================================================
1332 // function : UpdateTable()
1333 // purpose  :
1334 //=================================================================================
1335
1336 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1337 {
1338   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1339
1340   if ( myGeomType == SMDSEntity_Quad_Polygon )        // POLYGON
1341   {
1342     if ( aListCorners.count() < 3 )
1343       theConersValidity = false;
1344
1345     if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
1346     {
1347       // adjust nb of rows for the polygon
1348       int oldNbRows = myTable->rowCount();
1349       myTable->setRowCount( aListCorners.count() );
1350       for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
1351       {
1352         myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
1353         myTable->item( row, 0 )->setFlags(0);
1354
1355         IdEditItem* anEditItem = new IdEditItem( "" );
1356         anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
1357         myTable->setItem(row, 1, anEditItem);
1358
1359         myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
1360         myTable->item( row, 2 )->setFlags(0);
1361       }
1362       myNbCorners = aListCorners.count();
1363
1364       // fill FirstPolygonIds and LastPolygonIds
1365       FirstPolygonIds.resize( aListCorners.count() );
1366       LastPolygonIds .resize( aListCorners.count() );
1367       for ( int i = 0; i < aListCorners.count(); ++i )
1368       {
1369         FirstPolygonIds[i] = i;
1370         LastPolygonIds [i] = i+1;
1371       }
1372       LastPolygonIds.back() = 0;
1373
1374       myNbCorners = aListCorners.count();
1375     }
1376   }
1377
1378   if ( aListCorners.count() == myNbCorners && theConersValidity )
1379   {
1380     myTable->setEnabled( true );
1381
1382     // clear the Middle column
1383     for ( int row = 0; row < myTable->rowCount(); row++ )
1384       myTable->item( row, 1 )->setText("");
1385
1386     int* aFirstColIds = 0;
1387     int* aLastColIds  = 0;
1388
1389     switch (myGeomType) {
1390     case SMDSEntity_Quad_Edge:
1391       aFirstColIds = FirstEdgeIds;
1392       aLastColIds  = LastEdgeIds;
1393       break;
1394     case SMDSEntity_Quad_Triangle:
1395     case SMDSEntity_BiQuad_Triangle:
1396       aFirstColIds = FirstTriangleIds;
1397       aLastColIds  = LastTriangleIds;
1398       break;
1399     case SMDSEntity_Quad_Quadrangle:
1400     case SMDSEntity_BiQuad_Quadrangle:
1401       aFirstColIds = FirstQuadrangleIds;
1402       aLastColIds  = LastQuadrangleIds;
1403       break;
1404     case SMDSEntity_Quad_Polygon:
1405       aFirstColIds = & FirstPolygonIds[0];
1406       aLastColIds  = & LastPolygonIds[0];
1407       break;
1408     case SMDSEntity_Quad_Tetra:
1409       aFirstColIds = FirstTetrahedronIds;
1410       aLastColIds  = LastTetrahedronIds;
1411       break;
1412     case SMDSEntity_Quad_Pyramid:
1413       aFirstColIds = FirstPyramidIds;
1414       aLastColIds  = LastPyramidIds;
1415       break;
1416     case SMDSEntity_Quad_Penta:
1417     case SMDSEntity_BiQuad_Penta:
1418       aFirstColIds = FirstPentahedronIds;
1419       aLastColIds  = LastPentahedronIds;
1420       break;
1421     case SMDSEntity_Quad_Hexa:
1422     case SMDSEntity_TriQuad_Hexa:
1423       aFirstColIds = FirstHexahedronIds;
1424       aLastColIds  = LastHexahedronIds;
1425       break;
1426     default:;
1427     }
1428
1429     // fill the First and the Last columns
1430     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1431       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1432
1433     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1434       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1435   }
1436   else
1437   {
1438     // clear table
1439     for ( int row = 0; row < myTable->rowCount(); row++ )
1440       for ( int col = 0; col < myTable->columnCount(); col++ )
1441         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1442
1443     myTable->setEnabled( false );
1444   }
1445 }
1446
1447 //=================================================================================
1448 // function : onTableActivate()
1449 // purpose  :
1450 //=================================================================================
1451
1452 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int /*theRow*/, int /*theCol*/ )
1453 {
1454   myCurrentLineEdit = 0;
1455   displaySimulation();
1456   updateButtons();
1457 }
1458
1459 //=================================================================================
1460 // function : onCellTextChange()
1461 // purpose  :
1462 //=================================================================================
1463
1464 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int /*theRow*/, int /*theCol*/)
1465 {
1466   myCurrentLineEdit = 0;
1467   displaySimulation();
1468   updateButtons();
1469 }
1470
1471 //=================================================================================
1472 // function : keyPressEvent()
1473 // purpose  :
1474 //=================================================================================
1475
1476 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1477 {
1478   QDialog::keyPressEvent( e );
1479   if ( e->isAccepted() )
1480     return;
1481
1482   if ( e->key() == Qt::Key_F1 ) {
1483     e->accept();
1484     ClickOnHelp();
1485   }
1486 }
1487
1488 //=======================================================================
1489 //function : updateButtons
1490 //purpose  : 
1491 //=======================================================================
1492
1493 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1494 {
1495   bool valid = IsValid();
1496   buttonOk->setEnabled( valid );
1497   buttonApply->setEnabled( valid );
1498 }
1499
1500 //=================================================================================
1501 // function : isValid
1502 // purpose  :
1503 //=================================================================================
1504
1505 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1506 {
1507   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1508     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1509     return false;
1510   }
1511   return true;
1512 }