Salome HOME
23080: [CEA 1497] Do not merge a middle node in quadratic with the extreme nodes...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 // Copyright (C) 2007-2015  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 vector<int> FirstPolygonIds;
122   static 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     myGeomType( theType ),
342     myBusy( false )
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;
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   }
603
604   myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
605   myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
606   myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
607   myCenterLabel        ->setVisible( myNbCenterNodes );
608   myCenterSelectButton ->setVisible( myNbCenterNodes );
609   myCenterNode         ->setVisible( myNbCenterNodes );
610
611   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
612
613   /* initialize table */
614   myTable->setColumnCount(3);
615   myTable->setRowCount(aNumRows);
616
617   QStringList aColLabels;
618   aColLabels.append(tr("SMESH_FIRST"));
619   aColLabels.append(tr("SMESH_MIDDLE"));
620   aColLabels.append(tr("SMESH_LAST"));
621   myTable->setHorizontalHeaderLabels(aColLabels);
622
623   for ( int col = 0; col < myTable->columnCount(); col++ )
624     myTable->setColumnWidth(col, 80);
625
626   //myTable->setColumnReadOnly(0, true); // VSR: TODO
627   //myTable->setColumnReadOnly(2, true); // VSR: TODO
628
629   myTable->setEnabled( false );
630
631   for ( int row = 0; row < myTable->rowCount(); row++ )
632   {
633     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
634     myTable->item( row, 0 )->setFlags(0);
635
636     IdEditItem* anEditItem = new IdEditItem( "" );
637     anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
638     myTable->setItem(row, 1, anEditItem);
639
640     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
641     myTable->item( row, 2 )->setFlags(0);
642   }
643
644   /* signals and slots connections */
645   connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
646   connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
647   connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
648   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
649   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
650   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
651   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
652   connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
653   connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
654   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
655
656   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
657   connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
658   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
659   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
660
661   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
662   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
663   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
664   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), SLOT(onOpenView()));
665   connect(mySMESHGUI, SIGNAL (SignalCloseView()), SLOT(onCloseView()));
666
667   myCurrentLineEdit = myCornerNodes;
668
669   // set selection mode
670   SMESH::SetPointRepresentation(true);
671
672   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
673     aViewWindow->SetSelectionMode( NodeSelection );
674
675   SelectionIntoArgument();
676 }
677
678 //=================================================================================
679 // function : ClickOnApply()
680 // purpose  :
681 //=================================================================================
682
683 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
684 {
685   if( !isValid() )
686     return false;
687
688   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
689     return false;
690
691   BusyLocker lock( myBusy );
692
693   std::vector<vtkIdType> anIds;
694
695   switch (myGeomType) {
696   case SMDSEntity_Quad_Edge:
697     anIds.push_back(myTable->item(0, 0)->text().toInt());
698     anIds.push_back(myTable->item(0, 2)->text().toInt());
699     anIds.push_back(myTable->item(0, 1)->text().toInt());
700     break;
701   case SMDSEntity_Quad_Triangle:
702   case SMDSEntity_Quad_Quadrangle:
703   case SMDSEntity_Quad_Polygon:
704   case SMDSEntity_BiQuad_Triangle:
705   case SMDSEntity_BiQuad_Quadrangle:
706   case SMDSEntity_Quad_Tetra:
707   case SMDSEntity_Quad_Pyramid:
708   case SMDSEntity_Quad_Penta:
709   case SMDSEntity_Quad_Hexa:
710   case SMDSEntity_TriQuad_Hexa:
711     for ( int row = 0; row < myNbCorners; row++ )
712       anIds.push_back(myTable->item(row, 0)->text().toInt());
713     for ( int row = 0; row < myTable->rowCount(); row++ )
714       anIds.push_back(myTable->item(row, 1)->text().toInt());
715     if ( myNbMidFaceNodes )
716     {
717       QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
718       for (int i = 0; i < aListId.count(); i++)
719         anIds.push_back( aListId[ i ].toInt() );
720     }
721     if ( myNbCenterNodes )
722     {
723       QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
724       anIds.push_back( aListId[ 0 ].toInt() );
725     }
726     break;
727   }
728   if ( myReverseCB->isChecked())
729     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
730
731   int aNumberOfIds = anIds.size();
732   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
733   anArrayOfIdeces->length( aNumberOfIds );
734
735   for (int i = 0; i < aNumberOfIds; i++)
736     anArrayOfIdeces[i] = anIds[ i ];
737
738   bool addToGroup = GroupGroups->isChecked();
739   QString aGroupName;
740
741   SMESH::SMESH_GroupBase_var aGroup;
742   int idx = 0;
743   if( addToGroup ) {
744     aGroupName = ComboBox_GroupName->currentText();
745     for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
746       QString aName = ComboBox_GroupName->itemText( i );
747       if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
748         idx = i;
749     }
750     if ( idx > 0 && idx <= myGroups.count() ) {
751       SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
752       if ( !aGeomGroup->_is_nil() ) {
753         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
754                                              tr( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
755                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
756         if ( res == 1 ) return false;
757       }
758       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
759       if ( !aFilterGroup->_is_nil() ) {
760         int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
761                                              tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
762                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
763         if ( res == 1 ) return false;
764       }
765       aGroup = myGroups[idx-1];
766     }
767   }
768
769   SMESH::ElementType anElementType;
770   long anElemId = -1, nbElemsBefore = 0;
771   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
772   switch (myGeomType) {
773   case SMDSEntity_Quad_Edge:
774     anElementType = SMESH::EDGE;
775     nbElemsBefore = myMesh->NbEdges();
776     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
777   case SMDSEntity_Quad_Triangle:
778   case SMDSEntity_Quad_Quadrangle:
779   case SMDSEntity_BiQuad_Triangle:
780   case SMDSEntity_BiQuad_Quadrangle:
781     anElementType = SMESH::FACE;
782     nbElemsBefore = myMesh->NbFaces();
783     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
784   case SMDSEntity_Quad_Polygon:
785     anElementType = SMESH::FACE;
786     nbElemsBefore = myMesh->NbFaces();
787     anElemId = aMeshEditor->AddQuadPolygonalFace(anArrayOfIdeces.inout()); break;
788   case SMDSEntity_Quad_Tetra:
789   case SMDSEntity_Quad_Pyramid:
790   case SMDSEntity_Quad_Penta:
791   case SMDSEntity_Quad_Hexa:
792   case SMDSEntity_TriQuad_Hexa:
793     anElementType = SMESH::VOLUME;
794     nbElemsBefore = myMesh->NbVolumes();
795     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
796   default: break;
797   }
798
799   if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
800     SMESH::SMESH_Group_var aGroupUsed;
801     if ( aGroup->_is_nil() ) {
802       // create new group
803       aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
804       if ( !aGroupUsed->_is_nil() ) {
805         myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
806         ComboBox_GroupName->addItem( aGroupName );
807       }
808     }
809     else {
810       SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
811       SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
812       if ( !aGeomGroup->_is_nil() ) {
813         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
814         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
815           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
816           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
817         }
818       }
819       else if ( !aFilterGroup->_is_nil() ) {
820         aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
821         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
822           myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
823           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
824         }
825       }
826       else
827         aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
828     }
829
830     if ( !aGroupUsed->_is_nil() ) {
831       SMESH::long_array_var anIdList = new SMESH::long_array;
832       anIdList->length( 1 );
833       anIdList[0] = anElemId;
834       aGroupUsed->Add( anIdList.inout() );
835     }
836   }
837
838   if ( nbElemsBefore == 0  )
839   {
840     // 1st element of the type has been added, update actor to show this entity
841     unsigned int aMode = myActor->GetEntityMode();
842     switch ( anElementType ) {
843     case SMESH::EDGE:
844       myActor->SetRepresentation(SMESH_Actor::eEdge);
845       myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
846     case SMESH::FACE:
847       myActor->SetRepresentation(SMESH_Actor::eSurface);
848       myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
849     case SMESH::VOLUME:
850       myActor->SetRepresentation(SMESH_Actor::eSurface);
851       myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
852     }
853   }
854
855   SALOME_ListIO aList; aList.Append( myActor->getIO() );
856   mySelector->ClearIndex();
857   mySelectionMgr->setSelectedObjects( aList, false );
858
859   mySimulation->SetVisibility(false);
860   SMESH::UpdateView();
861
862   UpdateTable();
863   SetCurrentSelection();
864
865   updateButtons();
866
867   SMESHGUI::Modified();
868
869   return true;
870 }
871
872 //=================================================================================
873 // function : ClickOnOk()
874 // purpose  :
875 //=================================================================================
876
877 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
878 {
879   if ( ClickOnApply() )
880     reject();
881 }
882
883 //=================================================================================
884 // function : reject()
885 // purpose  :
886 //=================================================================================
887
888 void SMESHGUI_AddQuadraticElementDlg::reject()
889 {
890   mySelectionMgr->clearSelected();
891   mySimulation->SetVisibility(false);
892   SMESH::SetPointRepresentation(false);
893   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
894     aViewWindow->SetSelectionMode( ActorSelection );
895   disconnect(mySelectionMgr, 0, this, 0);
896   mySMESHGUI->ResetState();
897   QDialog::reject();
898 }
899
900 //=================================================================================
901 // function : onOpenView()
902 // purpose  :
903 //=================================================================================
904 void SMESHGUI_AddQuadraticElementDlg::onOpenView()
905 {
906   if ( mySelector && mySimulation ) {
907     mySimulation->SetVisibility(false);
908     SMESH::SetPointRepresentation(false);
909   }
910   else {
911     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
912     mySimulation = new SMESH::TElementSimulationQuad(
913       dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
914     ActivateThisDialog();
915   }
916 }
917
918 //=================================================================================
919 // function : onCloseView()
920 // purpose  :
921 //=================================================================================
922 void SMESHGUI_AddQuadraticElementDlg::onCloseView()
923 {
924   DeactivateActiveDialog();
925   mySelector = 0;
926   delete mySimulation;
927   mySimulation = 0;
928 }
929 //=================================================================================
930 // function : ClickOnHelp()
931 // purpose  :
932 //=================================================================================
933
934 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
935 {
936   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
937   if (app)
938     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
939   else {
940     QString platform;
941 #ifdef WIN32
942     platform = "winapplication";
943 #else
944     platform = "application";
945 #endif
946     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
947                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
948                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
949                                                                  platform)).
950                              arg(myHelpFileName));
951   }
952 }
953
954 //=================================================================================
955 // function : onTextChange()
956 // purpose  :
957 //=================================================================================
958
959 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
960 {
961   if (myBusy) return;
962   BusyLocker lock( myBusy );
963
964   mySimulation->SetVisibility(false);
965
966   // hilight entered nodes
967   SMDS_Mesh* aMesh = 0;
968   if (myActor)
969     aMesh = myActor->GetObject()->GetMesh();
970
971   QLineEdit* send = (QLineEdit*)sender();
972   if (send == myCornerNodes ||
973       send == myMidFaceNodes ||
974       send == myCenterNode)
975     myCurrentLineEdit = send;
976
977   if (aMesh) {
978     TColStd_MapOfInteger newIndices;
979
980     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
981     bool allOk = true;
982     for (int i = 0; i < aListId.count(); i++) {
983       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
984       {
985         newIndices.Add( n->GetID() );
986       }
987       else
988       {
989         allOk = false;
990         break;
991       }
992     }
993
994     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
995     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
996       aViewWindow->highlight( myActor->getIO(), true, true );
997
998     if ( myCurrentLineEdit == myCornerNodes )
999       UpdateTable( allOk );
1000   }
1001
1002   updateButtons();
1003   displaySimulation();
1004 }
1005
1006 //=================================================================================
1007 // function : SelectionIntoArgument()
1008 // purpose  : Called when selection has changed
1009 //=================================================================================
1010
1011 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
1012 {
1013   if (myBusy) return;
1014   BusyLocker lock( myBusy );
1015
1016   QString aCurrentEntry = myEntry;
1017
1018   if ( myCurrentLineEdit )
1019   {
1020     // clear
1021     myActor = 0;
1022
1023     myCurrentLineEdit->setText("");
1024
1025     if (!GroupButtons->isEnabled()) // inactive
1026       return;
1027
1028     mySimulation->SetVisibility(false);
1029
1030     // get selected mesh
1031     SALOME_ListIO aList;
1032     mySelectionMgr->selectedObjects(aList);
1033
1034     if (aList.Extent() != 1)
1035     {
1036       UpdateTable();
1037       updateButtons();
1038       return;
1039     }
1040
1041     Handle(SALOME_InteractiveObject) anIO = aList.First();
1042     myEntry = anIO->getEntry();
1043     myMesh = SMESH::GetMeshByIO(anIO);
1044     if (myMesh->_is_nil()) {
1045       updateButtons();
1046       return;
1047     }
1048
1049     myActor = SMESH::FindActorByEntry(anIO->getEntry());
1050
1051   }
1052
1053   // process groups
1054   if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
1055     SMESH::ElementType anElementType;
1056     switch ( myGeomType ) {
1057     case SMDSEntity_Quad_Edge:
1058       anElementType = SMESH::EDGE; break;
1059     case SMDSEntity_Quad_Triangle:
1060     case SMDSEntity_Quad_Quadrangle:
1061     case SMDSEntity_Quad_Polygon:
1062     case SMDSEntity_BiQuad_Triangle:
1063     case SMDSEntity_BiQuad_Quadrangle:
1064       anElementType = SMESH::FACE; break;
1065     case SMDSEntity_Quad_Tetra:
1066     case SMDSEntity_Quad_Pyramid:
1067     case SMDSEntity_Quad_Penta:
1068     case SMDSEntity_Quad_Hexa:
1069     case SMDSEntity_TriQuad_Hexa:
1070       anElementType = SMESH::VOLUME; break;
1071     }
1072     myGroups.clear();
1073     ComboBox_GroupName->clear();
1074     ComboBox_GroupName->addItem( QString() );
1075     SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
1076     for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
1077       SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
1078       if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
1079         QString aGroupName( aGroup->GetName() );
1080         if ( !aGroupName.isEmpty() ) {
1081           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
1082           ComboBox_GroupName->addItem( aGroupName );
1083         }
1084       }
1085     }
1086   }
1087
1088   if (!myActor) {
1089     updateButtons();
1090     return;
1091   }
1092
1093   // get selected nodes
1094   QString aString = "";
1095   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
1096
1097   if ( myCurrentLineEdit )
1098   {
1099     if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
1100       myCurrentLineEdit->setText(aString);
1101
1102     if ( myCurrentLineEdit == myCornerNodes )
1103       UpdateTable();
1104   }
1105   else if ( myTable->isEnabled() && nbNodes == 1 )
1106   {
1107     int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1108     if ( theCol == 1 )
1109       myTable->item(theRow, 1)->setText(aString);
1110   }
1111
1112   updateButtons();
1113   displaySimulation();
1114 }
1115
1116 //=================================================================================
1117 // function : displaySimulation()
1118 // purpose  :
1119 //=================================================================================
1120
1121 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1122 {
1123   if ( IsValid() )
1124   {
1125     SMESH::TElementSimulationQuad::TVTKIds anIds;
1126
1127     // Collect ids from the dialog
1128     int anID;
1129     bool ok;
1130     int aDisplayMode = VTK_SURFACE;
1131
1132     if ( myGeomType == SMDSEntity_Quad_Edge )
1133     {
1134       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1135       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1136       anID = myTable->item(0, 1)->text().toInt(&ok);
1137       if (!ok) anID = myTable->item(0, 0)->text().toInt();
1138       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1139       aDisplayMode = VTK_WIREFRAME;
1140     }
1141     else
1142     {
1143       for ( int row = 0; row < myNbCorners; row++ )
1144         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1145
1146       for ( int row = 0; row < myTable->rowCount(); row++ )
1147       {
1148         anID = myTable->item(row, 1)->text().toInt(&ok);
1149         if (!ok) {
1150           anID = myTable->item(row, 0)->text().toInt();
1151           aDisplayMode = VTK_WIREFRAME;
1152         }
1153         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1154       }
1155       if ( myNbMidFaceNodes )
1156       {
1157         QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1158         for (int i = 0; i < aListId.count(); i++)
1159           anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1160       }
1161       if ( myNbCenterNodes )
1162       {
1163         QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1164         anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1165       }
1166     }
1167
1168     mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1169   }
1170   else
1171   {
1172     mySimulation->SetVisibility(false);
1173   }
1174   SMESH::UpdateView();
1175 }
1176
1177 //=================================================================================
1178 // function : SetCurrentSelection()
1179 // purpose  :
1180 //=================================================================================
1181
1182 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1183 {
1184   QPushButton* send = (QPushButton*)sender();
1185   myCurrentLineEdit = 0;
1186
1187   if (send == myCornerSelectButton)
1188     myCurrentLineEdit = myCornerNodes;
1189   else if ( send == myMidFaceSelectButton )
1190     myCurrentLineEdit = myMidFaceNodes;
1191   else if ( send == myCenterSelectButton )
1192     myCurrentLineEdit = myCenterNode;
1193
1194   if ( myCurrentLineEdit )
1195   {
1196     myCurrentLineEdit->setFocus();
1197     SelectionIntoArgument();
1198   }
1199 }
1200
1201 //=================================================================================
1202 // function : DeactivateActiveDialog()
1203 // purpose  :
1204 //=================================================================================
1205
1206 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1207 {
1208   if (GroupConstructors->isEnabled()) {
1209     GroupConstructors->setEnabled(false);
1210     GroupArguments->setEnabled(false);
1211     GroupButtons->setEnabled(false);
1212     mySimulation->SetVisibility(false);
1213     mySMESHGUI->ResetState();
1214     mySMESHGUI->SetActiveDialogBox(0);
1215   }
1216 }
1217
1218 //=================================================================================
1219 // function : ActivateThisDialog()
1220 // purpose  :
1221 //=================================================================================
1222
1223 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1224 {
1225   /* Emit a signal to deactivate the active dialog */
1226   mySMESHGUI->EmitSignalDeactivateDialog();
1227
1228   GroupConstructors->setEnabled(true);
1229   GroupArguments->setEnabled(true);
1230   GroupButtons->setEnabled(true);
1231
1232   SMESH::SetPointRepresentation(true);
1233
1234   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1235     aViewWindow->SetSelectionMode( NodeSelection );
1236   SelectionIntoArgument();
1237 }
1238
1239 //=================================================================================
1240 // function : enterEvent()
1241 // purpose  :
1242 //=================================================================================
1243 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1244 {
1245   if ( !GroupConstructors->isEnabled() ) {
1246     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1247     if ( aViewWindow && !mySelector && !mySimulation) {
1248       mySelector = aViewWindow->GetSelector();
1249       mySimulation = new SMESH::TElementSimulationQuad(
1250         dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
1251     }
1252     ActivateThisDialog();
1253   }
1254 }
1255
1256 //=================================================================================
1257 // function : onReverse()
1258 // purpose  :
1259 //=================================================================================
1260
1261 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1262 {
1263   mySimulation->SetVisibility(false);
1264   displaySimulation();
1265   updateButtons();
1266 }
1267
1268 //=================================================================================
1269 // function : IsValid()
1270 // purpose  :
1271 //=================================================================================
1272
1273 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1274 {
1275   SMDS_Mesh* aMesh = 0;
1276   if (myActor)
1277     aMesh = myActor->GetObject()->GetMesh();
1278   if (!aMesh)
1279     return false;
1280
1281   bool ok;
1282   std::set< int > okIDs;
1283   for ( int row = 0; row < myTable->rowCount(); row++ )
1284   {
1285     int anID =  myTable->item(row, 1)->text().toInt(&ok);
1286     if ( !ok )
1287       return false;
1288
1289     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1290     if ( !aNode )
1291       return false;
1292     okIDs.insert( anID );
1293   }
1294
1295   QStringList aListId;
1296   if ( myNbMidFaceNodes )
1297     aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1298   if ( myNbCenterNodes )
1299     aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1300
1301   for (int i = 0; i < aListId.count(); i++)
1302   {
1303     int anID = aListId[ i ].toInt(&ok);
1304     if ( !ok )
1305       return false;
1306
1307     if ( !aMesh->FindNode(anID) )
1308       return false;
1309     okIDs.insert( anID );
1310   }
1311
1312   return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1313 }
1314
1315 //=================================================================================
1316 // function : UpdateTable()
1317 // purpose  :
1318 //=================================================================================
1319
1320 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1321 {
1322   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1323
1324   if ( myGeomType == SMDSEntity_Quad_Polygon )        // POLYGON
1325   {
1326     if ( aListCorners.count() < 3 )
1327       theConersValidity = false;
1328
1329     if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
1330     {
1331       // adjust nb of rows for the polygon
1332       int oldNbRows = myTable->rowCount();
1333       myTable->setRowCount( aListCorners.count() );
1334       for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
1335       {
1336         myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
1337         myTable->item( row, 0 )->setFlags(0);
1338
1339         IdEditItem* anEditItem = new IdEditItem( "" );
1340         anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
1341         myTable->setItem(row, 1, anEditItem);
1342
1343         myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
1344         myTable->item( row, 2 )->setFlags(0);
1345       }
1346       myNbCorners = aListCorners.count();
1347
1348       // fill FirstPolygonIds and LastPolygonIds
1349       FirstPolygonIds.resize( aListCorners.count() );
1350       LastPolygonIds .resize( aListCorners.count() );
1351       for ( int i = 0; i < aListCorners.count(); ++i )
1352       {
1353         FirstPolygonIds[i] = i;
1354         LastPolygonIds [i] = i+1;
1355       }
1356       LastPolygonIds.back() = 0;
1357
1358       myNbCorners = aListCorners.count();
1359     }
1360   }
1361
1362   if ( aListCorners.count() == myNbCorners && theConersValidity )
1363   {
1364     myTable->setEnabled( true );
1365
1366     // clear the Middle column
1367     for ( int row = 0; row < myTable->rowCount(); row++ )
1368       myTable->item( row, 1 )->setText("");
1369
1370     int* aFirstColIds;
1371     int* aLastColIds;
1372
1373     switch (myGeomType) {
1374     case SMDSEntity_Quad_Edge:
1375       aFirstColIds = FirstEdgeIds;
1376       aLastColIds  = LastEdgeIds;
1377       break;
1378     case SMDSEntity_Quad_Triangle:
1379     case SMDSEntity_BiQuad_Triangle:
1380       aFirstColIds = FirstTriangleIds;
1381       aLastColIds  = LastTriangleIds;
1382       break;
1383     case SMDSEntity_Quad_Quadrangle:
1384     case SMDSEntity_BiQuad_Quadrangle:
1385       aFirstColIds = FirstQuadrangleIds;
1386       aLastColIds  = LastQuadrangleIds;
1387       break;
1388     case SMDSEntity_Quad_Polygon:
1389       aFirstColIds = & FirstPolygonIds[0];
1390       aLastColIds  = & LastPolygonIds[0];
1391       break;
1392     case SMDSEntity_Quad_Tetra:
1393       aFirstColIds = FirstTetrahedronIds;
1394       aLastColIds  = LastTetrahedronIds;
1395       break;
1396     case SMDSEntity_Quad_Pyramid:
1397       aFirstColIds = FirstPyramidIds;
1398       aLastColIds  = LastPyramidIds;
1399       break;
1400     case SMDSEntity_Quad_Penta:
1401       aFirstColIds = FirstPentahedronIds;
1402       aLastColIds  = LastPentahedronIds;
1403       break;
1404     case SMDSEntity_Quad_Hexa:
1405     case SMDSEntity_TriQuad_Hexa:
1406       aFirstColIds = FirstHexahedronIds;
1407       aLastColIds  = LastHexahedronIds;
1408       break;
1409     }
1410
1411     // fill the First and the Last columns
1412     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1413       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1414
1415     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1416       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1417   }
1418   else
1419   {
1420     // clear table
1421     for ( int row = 0; row < myTable->rowCount(); row++ )
1422       for ( int col = 0; col < myTable->columnCount(); col++ )
1423         if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1424
1425     myTable->setEnabled( false );
1426   }
1427 }
1428
1429 //=================================================================================
1430 // function : onTableActivate()
1431 // purpose  :
1432 //=================================================================================
1433
1434 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1435 {
1436   myCurrentLineEdit = 0;
1437   displaySimulation();
1438   updateButtons();
1439 }
1440
1441 //=================================================================================
1442 // function : onCellTextChange()
1443 // purpose  :
1444 //=================================================================================
1445
1446 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1447 {
1448   myCurrentLineEdit = 0;
1449   displaySimulation();
1450   updateButtons();
1451 }
1452
1453 //=================================================================================
1454 // function : keyPressEvent()
1455 // purpose  :
1456 //=================================================================================
1457
1458 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1459 {
1460   QDialog::keyPressEvent( e );
1461   if ( e->isAccepted() )
1462     return;
1463
1464   if ( e->key() == Qt::Key_F1 ) {
1465     e->accept();
1466     ClickOnHelp();
1467   }
1468 }
1469
1470 //=======================================================================
1471 //function : updateButtons
1472 //purpose  : 
1473 //=======================================================================
1474
1475 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1476 {
1477   bool valid = IsValid();
1478   buttonOk->setEnabled( valid );
1479   buttonApply->setEnabled( valid );
1480 }
1481
1482 //=================================================================================
1483 // function : isValid
1484 // purpose  :
1485 //=================================================================================
1486
1487 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1488 {
1489   if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1490     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
1491     return false;
1492   }
1493   return true;
1494 }