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