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