Salome HOME
PAL11992. fix cleanMesh()
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_AddQuadraticElementDlg.cxx
1 #include "SMESHGUI_AddQuadraticElementDlg.h"
2
3 #include "SMESHGUI.h"
4 #include "SMESHGUI_Utils.h"
5 #include "SMESHGUI_VTKUtils.h"
6 #include "SMESHGUI_MeshUtils.h"
7 #include "SMESHGUI_IdValidator.h"
8 #include "SMESH_ActorUtils.h"
9
10 #include "SMDS_Mesh.hxx"
11 #include "SMESH_Actor.h"
12
13 #include "SUIT_Session.h"
14 #include "SUIT_MessageBox.h"
15
16 #include "SVTK_Selection.h"
17 #include "SVTK_Selector.h"
18 #include "SALOME_ListIO.hxx"
19 #include "SALOME_ListIteratorOfListIO.hxx"
20
21 #include "SalomeApp_Study.h"
22 #include "SalomeApp_Application.h"
23
24 #include "SVTK_ViewModel.h"
25 #include "SVTK_ViewWindow.h"
26
27 #include "utilities.h"
28
29 // OCCT Includes
30 #include <TColStd_MapOfInteger.hxx>
31 #include <TColStd_IndexedMapOfInteger.hxx>
32
33 // VTK Includes
34 #include <vtkCell.h>
35 #include <vtkIdList.h>
36 #include <vtkIntArray.h>
37 #include <vtkCellArray.h>
38 #include <vtkUnsignedCharArray.h>
39 #include <vtkUnstructuredGrid.h>
40 #include <vtkDataSetMapper.h>
41 #include <vtkProperty.h>
42
43 #include <vtkQuadraticEdge.h>
44 #include <vtkQuadraticTriangle.h>
45 #include <vtkQuadraticQuad.h>
46 #include <vtkQuadraticHexahedron.h>
47 #include <vtkQuadraticTetra.h>
48
49 // QT Includes
50 #include <qbuttongroup.h>
51 #include <qgroupbox.h>
52 #include <qlabel.h>
53 #include <qlineedit.h>
54 #include <qpushbutton.h>
55 #include <qradiobutton.h>
56 #include <qlayout.h>
57 #include <qpixmap.h>
58 #include <qcheckbox.h>
59
60 // STL includes
61 #include <list>
62
63 using namespace std;
64
65 namespace SMESH {
66
67   void ReverseConnectivity( vector<int> & ids, int type )
68   {
69     // for reverse connectivity of other types keeping the first id, see
70     // void SMESH_VisualObjDef::buildElemPrs() in SMESH_Object.cxx:900
71     const int* conn = 0;
72    
73     switch ( type ) {
74     case QUAD_TETRAHEDRON: {
75       static int aConn[] = {0,2,1,3,6,5,4,7,9,8};
76       conn = aConn;
77       break;
78     }
79     case QUAD_PYRAMID: {
80       static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
81       conn = aConn;
82       break;
83     }
84     case QUAD_PENTAHEDRON: {
85       static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
86       conn = aConn;
87       break;
88     }
89     case QUAD_HEXAHEDRON: {
90       static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
91       conn = aConn;
92       break;
93     }
94     default:;
95     }
96     if ( !conn ) {
97       reverse( ids.begin(), ids.end() );
98     }
99     else {
100       vector<int> aRevIds( ids.size() );
101       for ( int i = 0; i < ids.size(); i++)
102         aRevIds[ i ] = ids[ conn[ i ]];
103       ids = aRevIds;
104     }
105   }
106
107   class TElementSimulation {
108     SalomeApp_Application* myApplication;
109     SUIT_ViewWindow* myViewWindow;
110     SVTK_ViewWindow* myVTKViewWindow;
111
112     SALOME_Actor* myPreviewActor;
113     vtkDataSetMapper* myMapper;
114     vtkUnstructuredGrid* myGrid;
115     //vtkProperty* myBackProp, *myProp;
116
117     float anRGB[3], aBackRGB[3];
118
119   public:
120     TElementSimulation (SalomeApp_Application* theApplication)
121     {
122       myApplication = theApplication;
123       SUIT_ViewManager* mgr = theApplication->activeViewManager();
124       if (!mgr) return;
125       myViewWindow = mgr->getActiveView();
126       myVTKViewWindow = GetVtkViewWindow(myViewWindow);
127
128       myGrid = vtkUnstructuredGrid::New();
129
130       // Create and display actor
131       myMapper = vtkDataSetMapper::New();
132       myMapper->SetInput(myGrid);
133
134       myPreviewActor = SALOME_Actor::New();
135       myPreviewActor->PickableOff();
136       myPreviewActor->VisibilityOff();
137       myPreviewActor->SetMapper(myMapper);
138
139       vtkProperty* myProp = vtkProperty::New();
140       GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
141       myProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
142       myPreviewActor->SetProperty( myProp );
143       myProp->Delete();
144
145       vtkProperty* myBackProp = vtkProperty::New();
146       GetColor( "SMESH", "backface_color", aBackRGB[0], aBackRGB[1], aBackRGB[2], QColor( 0, 0, 255 ) );
147       myBackProp->SetColor( aBackRGB[0], aBackRGB[1], aBackRGB[2] );
148       myPreviewActor->SetBackfaceProperty( myBackProp );
149       myBackProp->Delete();
150
151       myVTKViewWindow->AddActor(myPreviewActor);
152     }
153
154     typedef std::vector<vtkIdType> TVTKIds;
155     void SetPosition (SMESH_Actor* theActor,
156                       const int    theType,
157                       TVTKIds&     theIds,
158                       const int    theMode,
159                       const bool   theReverse)
160     {
161       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
162       myGrid->SetPoints(aGrid->GetPoints());
163
164       //add points
165
166       vtkIdType aType = 0;
167
168       switch (theType) {
169       case QUAD_EDGE:
170         aType = VTK_QUADRATIC_EDGE;
171         break;
172       case QUAD_TRIANGLE:
173         aType = VTK_QUADRATIC_TRIANGLE; 
174         break;
175       case QUAD_QUADRANGLE:
176         aType = VTK_QUADRATIC_QUAD; 
177         break;
178       case QUAD_TETRAHEDRON:
179         aType = VTK_QUADRATIC_TETRA; 
180         break;
181       case QUAD_PYRAMID:
182         //aType = VTK_QUADRATIC_PYRAMID; // NOT SUPPORTED IN VTK4.2
183         aType = VTK_CONVEX_POINT_SET;
184         break;
185       case QUAD_PENTAHEDRON:
186         //aType = VTK_QUADRATIC_WEDGE; // NOT SUPPORTED IN VTK4.2
187         aType = VTK_CONVEX_POINT_SET;
188         break; 
189       case QUAD_HEXAHEDRON:
190         aType = VTK_QUADRATIC_HEXAHEDRON;
191         break;
192       }
193
194       // take care of orientation
195       if ( aType == VTK_CONVEX_POINT_SET ) {
196         if ( theReverse && theMode == VTK_SURFACE ) {
197           //myPreviewActor->GetProperty()->SetColor( aBackRGB[0], aBackRGB[1], aBackRGB[2] );
198         }
199       }
200       else {
201         // VTK cell connectivity opposites the MED one
202         if ( !theReverse ) {
203           ReverseConnectivity( theIds, theType );
204         }
205       }
206             
207       myGrid->Reset();
208       vtkIdList *anIds = vtkIdList::New();
209       
210       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
211         anIds->InsertId(i,theIds[i]);
212         //std::cout << i<< ": " << theIds[i] << std::endl;
213       }
214       
215       myGrid->InsertNextCell(aType,anIds);
216       anIds->Delete();
217       
218       myGrid->Modified();
219
220       myPreviewActor->GetMapper()->Update();
221       myPreviewActor->SetRepresentation( theMode );
222       SetVisibility(true);
223
224       // restore normal orientation
225       if ( aType == VTK_CONVEX_POINT_SET ) {
226         if ( theReverse  && theMode == VTK_SURFACE ) {
227           //myPreviewActor->GetProperty()->SetColor( anRGB[0], anRGB[1], anRGB[2] );
228         }
229       }
230     }
231
232
233     void SetVisibility (bool theVisibility)
234     {
235       myPreviewActor->SetVisibility(theVisibility);
236       RepaintCurrentView();
237     }
238
239
240     ~TElementSimulation()
241     {
242       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
243         myVTKViewWindow->RemoveActor(myPreviewActor);
244       }
245       myPreviewActor->Delete();
246
247       myMapper->RemoveAllInputs();
248       myMapper->Delete();
249
250       myGrid->Delete();
251
252 //       myProp->Delete();
253 //       myBackProp->Delete();
254     }
255   };
256 }
257
258
259 // Define the sequences of ids
260 static int FirstEdgeIds[] = {0};
261 static int LastEdgeIds[] =  {1};
262
263 static int FirstTriangleIds[] = {0,1,2};
264 static int LastTriangleIds[] =  {1,2,0};
265
266 static int FirstQuadrangleIds[] = {0,1,2,3};
267 static int LastQuadrangleIds[] =  {1,2,3,0};
268
269 static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
270 static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
271
272 static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
273 static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
274
275 static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
276 static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
277
278 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
279 static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
280
281
282
283 //=================================================================================
284 // function : SMESHGUI_AddQuadraticElementDlg()
285 // purpose  : constructor
286 //=================================================================================
287 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
288                                                                   const int theType,
289                                                                   const char* name,
290                                                                   bool modal, WFlags fl)
291      : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
292                 WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
293      mySMESHGUI( theModule ),
294      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
295      myType( theType )
296 {
297   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
298     (SUIT_Session::session()->activeApplication());
299   
300   mySimulation = new SMESH::TElementSimulation (anApp);
301   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
302
303   QString anElementName;
304
305   switch ( myType ) {
306   case QUAD_EDGE:
307     anElementName = QString("QUADRATIC_EDGE");
308     break;
309   case QUAD_TRIANGLE:
310     anElementName = QString("QUADRATIC_TRIANGLE");
311     break; 
312   case QUAD_QUADRANGLE:
313     anElementName = QString("QUADRATIC_QUADRANGLE");
314     break;
315   case QUAD_TETRAHEDRON:
316     anElementName = QString("QUADRATIC_TETRAHEDRON");
317     break;
318   case QUAD_PYRAMID:
319     anElementName = QString("QUADRATIC_PYRAMID");
320     break;
321   case QUAD_PENTAHEDRON:
322     anElementName = QString("QUADRATIC_PENTAHEDRON");
323     break;
324   case QUAD_HEXAHEDRON:
325     anElementName = QString("QUADRATIC_HEXAHEDRON");
326     break;
327   default:
328     myType = QUAD_EDGE;
329     anElementName = QString("QUADRATIC_EDGE");
330   }
331
332   QString iconName           = tr(QString("ICON_DLG_%1").arg(anElementName));
333   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName));
334   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName));
335   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName));
336   
337   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
338   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
339
340   if (!name)
341     setName("SMESHGUI_AddQuadraticElementDlg");
342   setCaption(caption);
343   
344   setSizeGripEnabled(TRUE);
345   QGridLayout* aDialogLayout = new QGridLayout(this);
346   aDialogLayout->setSpacing(6);
347   aDialogLayout->setMargin(11);
348
349   /***************************************************************/
350   GroupConstructors = new QButtonGroup(this, "GroupConstructors");
351   GroupConstructors->setTitle(constructorGrTitle);
352
353   GroupConstructors->setExclusive(TRUE);
354   GroupConstructors->setColumnLayout(0, Qt::Vertical);
355   GroupConstructors->layout()->setSpacing(0);
356   GroupConstructors->layout()->setMargin(0);
357   GroupConstructors->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
358   QGridLayout* aGroupConstructorsLayout = new QGridLayout(GroupConstructors->layout());
359   aGroupConstructorsLayout->setAlignment(Qt::AlignTop);
360   aGroupConstructorsLayout->setSpacing(6);
361   aGroupConstructorsLayout->setMargin(11);
362   myRadioButton1 = new QRadioButton(GroupConstructors, "myRadioButton1");
363   myRadioButton1->setText(tr("" ));
364   myRadioButton1->setPixmap(image0);
365   myRadioButton1->setChecked(TRUE);
366   myRadioButton1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, myRadioButton1->sizePolicy().hasHeightForWidth()));
367   aGroupConstructorsLayout->addWidget(myRadioButton1, 0, 0);
368   aGroupConstructorsLayout->addItem( new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1);
369   aDialogLayout->addWidget(GroupConstructors, 0, 0);
370
371   /***************************************************************/
372   GroupArguments = new QGroupBox(this, "GroupArguments");
373   GroupArguments->setTitle(argumentsGrTitle);
374   GroupArguments->setColumnLayout(0, Qt::Vertical);
375   GroupArguments->layout()->setSpacing(0);
376   GroupArguments->layout()->setMargin(0);
377   GroupArguments->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding));
378   QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments->layout());
379   aGroupArgumentsLayout->setAlignment(Qt::AlignTop);
380   aGroupArgumentsLayout->setSpacing(6);
381   aGroupArgumentsLayout->setMargin(11);
382   QLabel* aCornerNodesLabel = new QLabel(GroupArguments, "aCornerNodesLabel");
383   aCornerNodesLabel->setText(tr("SMESH_CORNER_NODES" ));
384   aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0);
385   mySelectButton = new QPushButton(GroupArguments, "mySelectButton");
386   mySelectButton->setPixmap(image1);
387   aGroupArgumentsLayout->addWidget(mySelectButton, 0, 1);
388   myCornerNodes = new QLineEdit(GroupArguments, "myCornerNodes");
389   aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2);
390
391   myTable = new QTable(GroupArguments);
392   aGroupArgumentsLayout->addMultiCellWidget(myTable, 1, 1, 0, 2);
393  
394   myReverseCB = new QCheckBox(GroupArguments, "myReverseCB");
395   myReverseCB->setText(tr("SMESH_REVERSE" ));
396   aGroupArgumentsLayout->addWidget(myReverseCB, 2, 0);
397  
398   aDialogLayout->addWidget(GroupArguments, 1, 0);
399
400   
401   /***************************************************************/
402   GroupButtons = new QGroupBox(this, "GroupButtons");
403   GroupButtons->setColumnLayout(0, Qt::Vertical);
404   GroupButtons->layout()->setSpacing(0);
405   GroupButtons->layout()->setMargin(0);
406   GroupButtons->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
407   QGridLayout* aGroupButtonsLayout = new QGridLayout(GroupButtons->layout());
408   aGroupButtonsLayout->setAlignment(Qt::AlignTop);
409   aGroupButtonsLayout->setSpacing(6);
410   aGroupButtonsLayout->setMargin(11);
411   buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
412   buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
413   buttonCancel->setAutoDefault(TRUE);
414   aGroupButtonsLayout->addWidget(buttonCancel, 0, 3);
415   buttonApply = new QPushButton(GroupButtons, "buttonApply");
416   buttonApply->setText(tr("SMESH_BUT_APPLY" ));
417   buttonApply->setAutoDefault(TRUE);
418   aGroupButtonsLayout->addWidget(buttonApply, 0, 1);
419   aGroupButtonsLayout->addItem( new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2);
420   buttonOk = new QPushButton(GroupButtons, "buttonOk");
421   buttonOk->setText(tr("SMESH_BUT_OK" ));
422   buttonOk->setAutoDefault(TRUE);
423   buttonOk->setDefault(TRUE);
424   aGroupButtonsLayout->addWidget(buttonOk, 0, 0);
425   buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
426   buttonHelp->setText(tr("SMESH_BUT_HELP" ));
427   buttonHelp->setAutoDefault(TRUE);
428   aGroupButtonsLayout->addWidget(buttonHelp, 0, 4);
429
430   aDialogLayout->addWidget(GroupButtons, 2, 0);
431
432   Init(); /* Initialisations */
433 }
434
435 //=================================================================================
436 // function : ~SMESHGUI_AddQuadraticElementDlg()
437 // purpose  : Destroys the object and frees any allocated resources
438 //=================================================================================
439 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
440 {
441   // no need to delete child widgets, Qt does it all for us
442   delete mySimulation;
443 }
444
445 //=================================================================================
446 // function : Init()
447 // purpose  :
448 //=================================================================================
449 void SMESHGUI_AddQuadraticElementDlg::Init()
450 {
451   GroupArguments->show();
452   myRadioButton1->setChecked(TRUE);
453   myIsEditCorners = true;
454   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
455   
456   myActor = 0;
457
458   int aNumRows;
459
460   switch (myType) {
461   case QUAD_EDGE:
462     aNumRows = 1;
463     myNbCorners = 2;
464     myHelpFileName = "/files/adding_nodes_and_elements.htm#?"; //Adding_edges
465     break;
466   case QUAD_TRIANGLE:
467     aNumRows = 3;
468     myNbCorners = 3;
469     myHelpFileName = "/files/adding_nodes_and_elements.htm#?"; //Adding_triangles
470     break;
471   case QUAD_QUADRANGLE:
472     aNumRows = 4;
473     myNbCorners = 4;
474     myHelpFileName = "/files/adding_nodes_and_elements.htm#?"; //Adding_quadrangles
475     break;
476   case QUAD_TETRAHEDRON:
477     aNumRows = 6;
478     myNbCorners = 4;
479     myHelpFileName = "/files/adding_nodes_and_elements.htm#?"; //Adding_tetrahedrons
480     break;
481   case QUAD_PYRAMID:
482     aNumRows = 8;
483     myNbCorners = 5;
484     myHelpFileName = "/files/adding_nodes_and_elements.htm#?";
485     break;
486   case QUAD_PENTAHEDRON:
487     aNumRows = 9;
488     myNbCorners = 6;
489     myHelpFileName = "/files/adding_nodes_and_elements.htm#?";
490     break; 
491   case QUAD_HEXAHEDRON:
492     aNumRows = 12;
493     myNbCorners = 8;
494     myHelpFileName = "/files/adding_nodes_and_elements.htm#?"; //Adding_hexahedrons
495     break;
496   }
497     
498   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, "validator", myNbCorners));
499
500   /* initialize table */
501   myTable->setNumCols(3);
502   myTable->setNumRows(aNumRows);
503
504   QStringList aColLabels;
505   aColLabels.append(tr("SMESH_FIRST"));
506   aColLabels.append(tr("SMESH_MIDDLE"));
507   aColLabels.append(tr("SMESH_LAST"));
508   myTable->setColumnLabels(aColLabels);
509   
510   for ( int col = 0; col < myTable->numCols(); col++ )
511     myTable->setColumnWidth(col, 80);
512
513   myTable->setColumnReadOnly(0, true);
514   myTable->setColumnReadOnly(2, true);
515
516   myTable->setEnabled( false );
517   
518   for ( int row = 0; row < myTable->numRows(); row++ )
519     {
520       SMESHGUI_IdEditItem* anEditItem = new SMESHGUI_IdEditItem( myTable, QTableItem::OnTyping, "" );
521       anEditItem->setReplaceable(false);
522       myTable->setItem(row, 1, anEditItem);
523     }
524   
525   /* signals and slots connections */
526   connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners()));
527   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
528   connect(myTable,        SIGNAL(doubleClicked(int, int, int, const QPoint&)), SLOT(onCellDoubleClicked(int, int, int, const QPoint&)));
529   connect(myTable,        SIGNAL(valueChanged (int, int)), SLOT(onCellTextChange(int, int)));
530   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
531   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
532
533   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
534   connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
535   connect(buttonApply, SIGNAL(clicked()),  SLOT(ClickOnApply()));
536   connect(buttonHelp, SIGNAL(clicked()),   SLOT(ClickOnHelp()));
537
538   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
539   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
540
541   this->show(); // displays Dialog
542
543   // set selection mode
544   SMESH::SetPointRepresentation(true);
545
546   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
547     aViewWindow->SetSelectionMode( NodeSelection );
548
549   myBusy = false;
550
551   SetEditCorners();
552 }
553
554 //=================================================================================
555 // function : ClickOnApply()
556 // purpose  :
557 //=================================================================================
558 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
559 {
560   if (IsValid() && !mySMESHGUI->isActiveStudyLocked()) {
561     myBusy = true;
562     
563     vector<int> anIds;
564
565     switch (myType) {
566     case QUAD_EDGE:
567       anIds.push_back(myTable->text(0, 0).toInt());
568       anIds.push_back(myTable->text(0, 2).toInt());
569       anIds.push_back(myTable->text(0, 1).toInt());
570       break;
571     case QUAD_TRIANGLE:
572     case QUAD_QUADRANGLE:
573     case QUAD_TETRAHEDRON:
574     case QUAD_PYRAMID:
575     case QUAD_PENTAHEDRON:
576     case QUAD_HEXAHEDRON:
577       for ( int row = 0; row < myNbCorners; row++ )
578         anIds.push_back(myTable->text(row, 0).toInt());
579       for ( int row = 0; row < myTable->numRows(); row++ )
580         anIds.push_back(myTable->text(row, 1).toInt());
581       break;
582     }
583     if ( myReverseCB->isChecked())
584       SMESH::ReverseConnectivity( anIds, myType );
585     
586     int aNumberOfIds =  anIds.size();
587     SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
588     anArrayOfIdeces->length( aNumberOfIds );
589     
590     for (int i = 0; i < aNumberOfIds; i++)
591       anArrayOfIdeces[i] = anIds[ i ];
592
593     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
594     switch (myType) {
595     case QUAD_EDGE:
596       aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
597     case QUAD_TRIANGLE:
598     case QUAD_QUADRANGLE:
599       aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
600     case QUAD_TETRAHEDRON:
601     case QUAD_PYRAMID:
602     case QUAD_PENTAHEDRON: 
603     case QUAD_HEXAHEDRON:
604       aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
605     }
606     
607     SALOME_ListIO aList; aList.Append( myActor->getIO() );
608     mySelector->ClearIndex();
609     mySelectionMgr->setSelectedObjects( aList, false );
610
611     SMESH::UpdateView();
612     mySimulation->SetVisibility(false);
613     
614     buttonOk->setEnabled(false);
615     buttonApply->setEnabled(false);
616
617     UpdateTable();
618     SetEditCorners();
619
620     myBusy = false;
621   }
622 }
623
624 //=================================================================================
625 // function : ClickOnOk()
626 // purpose  :
627 //=================================================================================
628 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
629 {
630   ClickOnApply();
631   ClickOnCancel();
632   return;
633 }
634
635 //=================================================================================
636 // function : ClickOnCancel()
637 // purpose  :
638 //=================================================================================
639 void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
640 {
641   mySelectionMgr->clearSelected();
642   mySimulation->SetVisibility(false);
643   SMESH::SetPointRepresentation(false);
644   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
645     aViewWindow->SetSelectionMode( ActorSelection );
646   disconnect(mySelectionMgr, 0, this, 0);
647   mySMESHGUI->ResetState();
648   reject();
649   return;
650 }
651
652 //=================================================================================
653 // function : ClickOnHelp()
654 // purpose  :
655 //=================================================================================
656 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
657 {
658   SalomeApp_Application* app = (SalomeApp_Application*)(SUIT_Session::session()->activeApplication());
659   if (app) 
660     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
661   else {
662     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
663                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
664                            arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
665                            QObject::tr("BUT_OK"));
666   }
667 }
668
669 //=================================================================================
670 // function : onTextChange()
671 // purpose  :
672 //=================================================================================
673 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
674 {
675   if (myBusy) return;
676   myBusy = true;
677   
678   buttonOk->setEnabled(false);
679   buttonApply->setEnabled(false);
680
681   mySimulation->SetVisibility(false);
682
683   // hilight entered nodes
684   SMDS_Mesh* aMesh = 0;
685   if (myActor)
686     aMesh = myActor->GetObject()->GetMesh();
687
688   if (aMesh) {
689     TColStd_MapOfInteger newIndices;
690     
691     QStringList aListId = QStringList::split(" ", theNewText, false);
692     bool allOk = true;
693     for (int i = 0; i < aListId.count(); i++) {
694       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
695         newIndices.Add( n->GetID() );
696       else
697         {
698           allOk = false;
699           break;
700         }
701     }
702     
703     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
704     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
705       aViewWindow->highlight( myActor->getIO(), true, true );
706     
707     if ( sender() == myCornerNodes )
708       UpdateTable( allOk );
709   }
710   
711   if( IsValid() ) {
712     buttonOk->setEnabled(true);
713     buttonApply->setEnabled(true);
714   }
715
716   if ( sender() == myTable )
717     displaySimulation();
718   
719   myBusy = false;
720 }
721
722 //=================================================================================
723 // function : SelectionIntoArgument()
724 // purpose  : Called when selection has changed
725 //=================================================================================
726 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
727 {
728   if (myBusy) return;
729   
730   if ( myIsEditCorners )
731     {
732       // clear
733       myActor = 0;
734       
735       myBusy = true;
736       myCornerNodes->setText("");
737       myBusy = false;
738       
739       if (!GroupButtons->isEnabled()) // inactive
740         return;
741       
742       buttonOk->setEnabled(false);
743       buttonApply->setEnabled(false);
744       
745       mySimulation->SetVisibility(false);
746       
747       // get selected mesh
748       SALOME_ListIO aList;
749       mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
750       
751       if (aList.Extent() != 1)
752         {
753           UpdateTable();
754           return;
755         }
756       
757       Handle(SALOME_InteractiveObject) anIO = aList.First();
758       myMesh = SMESH::GetMeshByIO(anIO);
759       if (myMesh->_is_nil())
760         return;
761       
762       myActor = SMESH::FindActorByEntry(anIO->getEntry());
763   
764     }
765   
766   if (!myActor)
767     return;
768   
769   // get selected nodes
770   QString aString = "";
771   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
772   
773   if ( myIsEditCorners )
774     {
775       myBusy = true;
776       myCornerNodes->setText(aString);
777       myBusy = false;
778       
779       UpdateTable();
780     }
781   else if ( myTable->isEnabled() && nbNodes == 1 )
782     {
783       myBusy = true;
784       int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
785       if ( theCol == 1 )
786         myTable->setText(theRow, 1, aString);
787       myBusy = false;
788     }
789   
790   if ( IsValid() )
791     {
792       buttonOk->setEnabled( true );
793       buttonApply->setEnabled( true );
794     }
795
796   displaySimulation();
797 }
798
799 //=================================================================================
800 // function : displaySimulation()
801 // purpose  :
802 //=================================================================================
803 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
804 {
805   if (!myIsEditCorners) {
806     SMESH::TElementSimulation::TVTKIds anIds;
807     
808     // Collect ids from the dialog
809     int anID;
810     bool ok;
811     int aDisplayMode = VTK_SURFACE;
812
813     if ( myType == QUAD_EDGE )
814       {
815         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(0, 0).toInt() ) );
816         anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(0, 2).toInt() ) );
817         anID = (myTable->text(0, 1)).toInt(&ok);
818         if (!ok) anID = (myTable->text(0, 0)).toInt();
819         anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
820         aDisplayMode = VTK_WIREFRAME;
821       }
822     else
823       {
824         for ( int row = 0; row < myNbCorners; row++ )
825           anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->text(row, 0).toInt() ) );
826         
827         for ( int row = 0; row < myTable->numRows(); row++ )
828           {
829             anID = (myTable->text(row, 1)).toInt(&ok);
830             if (!ok) {
831               anID = (myTable->text(row, 0)).toInt();
832               aDisplayMode = VTK_WIREFRAME;
833             }
834             anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
835           }
836       }
837     
838     mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
839     SMESH::UpdateView();
840   }
841 }
842
843 //=================================================================================
844 // function : SetEditCorners()
845 // purpose  :
846 //=================================================================================
847 void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
848 {
849   myCornerNodes->setFocus();
850   myIsEditCorners = true;
851   
852   SelectionIntoArgument();
853 }
854
855 //=================================================================================
856 // function : DeactivateActiveDialog()
857 // purpose  :
858 //=================================================================================
859 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
860 {
861   if (GroupConstructors->isEnabled()) {
862     GroupConstructors->setEnabled(false);
863     GroupArguments->setEnabled(false);
864     GroupButtons->setEnabled(false);
865     mySimulation->SetVisibility(false);
866     mySMESHGUI->ResetState();
867     mySMESHGUI->SetActiveDialogBox(0);
868   }
869 }
870
871 //=================================================================================
872 // function : ActivateThisDialog()
873 // purpose  :
874 //=================================================================================
875 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
876 {
877   /* Emit a signal to deactivate the active dialog */
878   mySMESHGUI->EmitSignalDeactivateDialog();
879
880   GroupConstructors->setEnabled(true);
881   GroupArguments->setEnabled(true);
882   GroupButtons->setEnabled(true);
883
884   SMESH::SetPointRepresentation(true);
885
886   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
887     aViewWindow->SetSelectionMode( NodeSelection );
888   SelectionIntoArgument();
889 }
890
891 //=================================================================================
892 // function : enterEvent()
893 // purpose  :
894 //=================================================================================
895 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
896 {
897   if (GroupConstructors->isEnabled())
898     return;
899   ActivateThisDialog();
900   return;
901 }
902
903 //=================================================================================
904 // function : closeEvent()
905 // purpose  :
906 //=================================================================================
907 void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*)
908 {
909   /* same than click on cancel button */
910   ClickOnCancel();
911   return;
912 }
913
914 //=================================================================================
915 // function : hideEvent()
916 // purpose  : caused by ESC key
917 //=================================================================================
918 void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*)
919 {
920   if (!isMinimized())
921     ClickOnCancel();
922 }
923
924 //=================================================================================
925 // function : onReverse()
926 // purpose  :
927 //=================================================================================
928 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
929 {
930   if (!IsValid())
931     return;
932
933   if (state >= 0) {
934     mySimulation->SetVisibility(false);
935     displaySimulation();
936   }
937 }
938
939
940 //=================================================================================
941 // function : IsValid()
942 // purpose  :
943 //=================================================================================
944 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
945 {
946   SMDS_Mesh* aMesh = 0;
947   if (myActor)
948     aMesh = myActor->GetObject()->GetMesh();
949   if (!aMesh)
950     return false;
951
952   bool ok;
953   
954   for ( int row = 0; row < myTable->numRows(); row++ )
955     {
956       int anID =  (myTable->text(row, 1)).toInt(&ok);
957       if ( !ok )
958         return false;
959       
960       const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
961       if ( !aNode )
962         return false;
963     }
964   
965   return true;
966 }
967
968 //=================================================================================
969 // function : UpdateTable()
970 // purpose  :
971 //=================================================================================
972 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
973 {
974   QStringList aListCorners = QStringList::split(" ", myCornerNodes->text(), false);
975   
976   if ( aListCorners.count() == myNbCorners && theConersValidity )
977     {
978       myTable->setEnabled( true );
979       
980       // clear the Middle column 
981       for ( int row = 0; row < myTable->numRows(); row++ )
982         myTable->setText( row, 1, "");
983       
984       int* aFirstColIds;
985       int* aLastColIds;
986
987       switch (myType) {
988       case QUAD_EDGE:
989         aFirstColIds = FirstEdgeIds;
990         aLastColIds  = LastEdgeIds;
991         break;
992       case QUAD_TRIANGLE:
993         aFirstColIds = FirstTriangleIds;
994         aLastColIds  = LastTriangleIds;
995         break;
996       case QUAD_QUADRANGLE:
997         aFirstColIds = FirstQuadrangleIds;
998         aLastColIds  = LastQuadrangleIds;
999         break;
1000       case QUAD_TETRAHEDRON:
1001         aFirstColIds = FirstTetrahedronIds;
1002         aLastColIds  = LastTetrahedronIds;
1003         break;
1004       case QUAD_PYRAMID:
1005         aFirstColIds = FirstPyramidIds;
1006         aLastColIds  = LastPyramidIds;
1007         break;
1008       case QUAD_PENTAHEDRON:
1009         aFirstColIds = FirstPentahedronIds;
1010         aLastColIds  = LastPentahedronIds;
1011         break; 
1012       case QUAD_HEXAHEDRON:
1013         aFirstColIds = FirstHexahedronIds;
1014         aLastColIds  = LastHexahedronIds;
1015         break;
1016       }
1017       
1018       // fill the First and the Last columns
1019       for (int i = 0, iEnd = myTable->numRows(); i < iEnd; i++)
1020         myTable->setText( i, 0, aListCorners[ aFirstColIds[i] ] );
1021       
1022       for (int i = 0, iEnd = myTable->numRows(); i < iEnd; i++)
1023         myTable->setText( i, 2, aListCorners[ aLastColIds[i] ] );
1024     }
1025   else
1026     {
1027       // clear table
1028       for ( int row = 0; row < myTable->numRows(); row++ )
1029         for ( int col = 0; col < myTable->numCols(); col++ )
1030           myTable->setText(row, col, "");
1031       
1032       myTable->setEnabled( false );
1033     }
1034 }
1035
1036
1037 //=================================================================================
1038 // function : onTableActivate()
1039 // purpose  :
1040 //=================================================================================
1041 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol, int theButton, const QPoint& theMousePos )
1042 {
1043   if ( theButton == 1 && theCol == 1 )
1044     myIsEditCorners = false;
1045   
1046   displaySimulation();
1047   return;
1048 }
1049
1050
1051 //=================================================================================
1052 // function : onCellTextChange()
1053 // purpose  :
1054 //=================================================================================
1055 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1056 {
1057   onTextChange( myTable->text(theRow, theCol) );
1058 }
1059
1060
1061 QWidget* SMESHGUI_IdEditItem::createEditor() const
1062 {
1063   QLineEdit *aLineEdit = new QLineEdit(text(), table()->viewport());
1064   aLineEdit->setValidator( new SMESHGUI_IdValidator(table()->viewport(), "validator", 1) );
1065   return aLineEdit;
1066 }