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