1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File : SMESHGUI_AddMeshElementDlg.cxx
25 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
28 #include "SMESHGUI_AddQuadraticElementDlg.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_MeshUtils.h"
34 #include "SMESHGUI_GroupUtils.h"
35 #include "SMESHGUI_IdValidator.h"
37 #include <SMESH_Actor.h>
38 #include <SMESH_ActorUtils.h>
39 #include <SMESH_FaceOrientationFilter.h>
40 #include <SMDS_Mesh.hxx>
42 // SALOME GUI includes
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_ViewManager.h>
49 #include <LightApp_SelectionMgr.h>
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
54 #include <SALOME_ListIO.hxx>
56 #include <SalomeApp_Application.h>
61 #include <SALOMEconfig.h>
62 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
65 #include <TColStd_MapOfInteger.hxx>
68 #include <vtkIdList.h>
69 #include <vtkUnstructuredGrid.h>
70 #include <vtkDataSetMapper.h>
71 #include <vtkPolyDataMapper.h>
72 #include <vtkProperty.h>
73 #include <vtkCellType.h>
80 #include <QPushButton>
81 #include <QRadioButton>
82 #include <QVBoxLayout>
83 #include <QHBoxLayout>
84 #include <QGridLayout>
86 #include <QTableWidget>
88 #include <QButtonGroup>
98 void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
99 bool toReverse, // inverse element
100 bool toVtkOrder ) // smds connectivity to vtk one
102 if ( toReverse ) // first reverse smds order
104 const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type);
105 SMDS_MeshCell::applyInterlace( index, ids );
107 if ( toVtkOrder ) // from smds to vtk connectivity
109 const std::vector<int>& index = SMDS_MeshCell::toVtkOrder(type);
110 SMDS_MeshCell::applyInterlace( index, ids );
116 class TElementSimulation {
117 SalomeApp_Application* myApplication;
118 SUIT_ViewWindow* myViewWindow;
119 SVTK_ViewWindow* myVTKViewWindow;
121 SALOME_Actor* myPreviewActor;
122 vtkDataSetMapper* myMapper;
123 vtkUnstructuredGrid* myGrid;
124 //vtkProperty* myBackProp, *myProp;
126 //double myRGB[3], myBackRGB[3];
128 SALOME_Actor* myFaceOrientation;
129 vtkPolyDataMapper* myFaceOrientationDataMapper;
130 SMESH_FaceOrientationFilter* myFaceOrientationFilter;
133 TElementSimulation (SalomeApp_Application* theApplication)
135 myApplication = theApplication;
136 SUIT_ViewManager* mgr = theApplication->activeViewManager();
138 myViewWindow = mgr->getActiveView();
139 myVTKViewWindow = GetVtkViewWindow(myViewWindow);
141 myGrid = vtkUnstructuredGrid::New();
143 // Create and display actor
144 myMapper = vtkDataSetMapper::New();
145 myMapper->SetInputData(myGrid);
147 myPreviewActor = SALOME_Actor::New();
148 myPreviewActor->PickableOff();
149 myPreviewActor->VisibilityOff();
150 myPreviewActor->SetMapper(myMapper);
154 vtkProperty* myProp = vtkProperty::New();
155 SMESH::GetColor( "SMESH", "preview_color", ffc, delta, "0, 255, 0|-100" ) ;
157 myProp->SetColor( ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255. );
158 myPreviewActor->SetProperty( myProp );
161 vtkProperty* myBackProp = vtkProperty::New();
162 bfc = Qtx::mainColorToSecondary(ffc, delta);
163 myBackProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
164 myPreviewActor->SetBackfaceProperty( myBackProp );
165 myBackProp->Delete();
167 myVTKViewWindow->AddActor(myPreviewActor);
169 // Orientation of faces
170 myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
171 myFaceOrientationFilter->SetInputData(myGrid);
173 myFaceOrientationDataMapper = vtkPolyDataMapper::New();
174 myFaceOrientationDataMapper->SetInputConnection(myFaceOrientationFilter->GetOutputPort());
176 myFaceOrientation = SALOME_Actor::New();
177 myFaceOrientation->PickableOff();
178 myFaceOrientation->VisibilityOff();
179 myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
181 vtkProperty* anOrientationProp = vtkProperty::New();
183 GetColor( "SMESH", "orientation_color", aRGB[0], aRGB[1], aRGB[2], QColor( 255, 255, 255 ) );
184 anOrientationProp->SetColor( aRGB[0], aRGB[1], aRGB[2] );
185 myFaceOrientation->SetProperty( anOrientationProp );
186 anOrientationProp->Delete();
188 myVTKViewWindow->AddActor(myFaceOrientation);
191 typedef std::vector<vtkIdType> TVTKIds;
192 void SetPosition (SMESH_Actor* theActor,
193 SMDSAbs_EntityType theType,
196 const bool theReverse)
198 vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
199 myGrid->SetPoints(aGrid->GetPoints());
203 ReverseConnectivity( theIds, theType, theReverse, /*toVtkOrder=*/true);
206 vtkIdList *anIds = vtkIdList::New();
208 for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
209 anIds->InsertId(i,theIds[i]);
210 //std::cout << i<< ": " << theIds[i] << std::endl;
213 vtkIdType aType = SMDS_MeshCell::toVtkType(theType);
214 myGrid->InsertNextCell(aType,anIds);
219 myPreviewActor->GetMapper()->Update();
220 myPreviewActor->SetRepresentation( theMode );
221 SetVisibility(true, theActor->GetFacesOriented());
225 void SetVisibility (bool theVisibility, bool theShowOrientation = false)
227 myPreviewActor->SetVisibility(theVisibility);
228 myFaceOrientation->SetVisibility(theShowOrientation);
229 RepaintCurrentView();
233 ~TElementSimulation()
235 if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
236 myVTKViewWindow->RemoveActor(myPreviewActor);
237 myVTKViewWindow->RemoveActor(myFaceOrientation);
239 myPreviewActor->Delete();
240 myFaceOrientation->Delete();
242 myMapper->RemoveAllInputs();
245 myFaceOrientationFilter->Delete();
247 myFaceOrientationDataMapper->RemoveAllInputs();
248 myFaceOrientationDataMapper->Delete();
253 // myBackProp->Delete();
259 // Define the sequences of ids
260 static int FirstEdgeIds[] = {0};
261 static int LastEdgeIds[] = {1};
263 static int FirstTriangleIds[] = {0,1,2};
264 static int LastTriangleIds[] = {1,2,0};
266 static int FirstQuadrangleIds[] = {0,1,2,3};
267 static int LastQuadrangleIds[] = {1,2,3,0};
269 static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
270 static int LastTetrahedronIds[] = {1,2,0,0,1,2};
272 static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
273 static int LastPyramidIds[] = {1,2,3,0,0,1,2,3};
275 static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
276 static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5};
278 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
279 static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7};
283 \brief Simple 'busy state' flag locker.
289 //! Constructor. Sets passed boolean flag to \c true.
290 BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
291 //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
292 ~BusyLocker() { myBusy = false; }
294 bool& myBusy; //! External 'busy state' boolean flag
299 \brief Simple editable table item.
302 class IdEditItem: public QTableWidgetItem
305 IdEditItem(const QString& text );
308 QWidget* createEditor() const;
311 IdEditItem::IdEditItem(const QString& text )
312 : QTableWidgetItem(text, QTableWidgetItem::UserType+100)
316 IdEditItem::~IdEditItem()
320 QWidget* IdEditItem::createEditor() const
322 QLineEdit *aLineEdit = new QLineEdit(text(), tableWidget());
323 aLineEdit->setValidator( new SMESHGUI_IdValidator(tableWidget(), 1) );
327 //=================================================================================
328 // function : SMESHGUI_AddQuadraticElementDlg()
329 // purpose : constructor
330 //=================================================================================
332 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
333 const SMDSAbs_EntityType theType )
334 : QDialog( SMESH::GetDesktop( theModule ) ),
335 mySMESHGUI( theModule ),
336 mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
337 myGeomType( theType ),
342 setAttribute( Qt::WA_DeleteOnClose, true );
344 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
345 (SUIT_Session::session()->activeApplication());
347 mySimulation = new SMESH::TElementSimulation (anApp);
348 mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
350 QString anElementName;
352 switch ( myGeomType ) {
353 case SMDSEntity_Quad_Edge:
354 anElementName = QString("QUADRATIC_EDGE");
356 case SMDSEntity_Quad_Triangle:
357 anElementName = QString("QUADRATIC_TRIANGLE");
359 case SMDSEntity_Quad_Quadrangle:
360 anElementName = QString("QUADRATIC_QUADRANGLE");
362 case SMDSEntity_BiQuad_Quadrangle:
363 anElementName = QString("BIQUADRATIC_QUADRANGLE");
365 case SMDSEntity_BiQuad_Triangle:
366 anElementName = QString("BIQUADRATIC_TRIANGLE");
368 case SMDSEntity_Quad_Tetra:
369 anElementName = QString("QUADRATIC_TETRAHEDRON");
371 case SMDSEntity_Quad_Pyramid:
372 anElementName = QString("QUADRATIC_PYRAMID");
374 case SMDSEntity_Quad_Penta:
375 anElementName = QString("QUADRATIC_PENTAHEDRON");
377 case SMDSEntity_Quad_Hexa:
378 anElementName = QString("QUADRATIC_HEXAHEDRON");
380 case SMDSEntity_TriQuad_Hexa:
381 anElementName = QString("TRIQUADRATIC_HEXAHEDRON");
384 myGeomType = SMDSEntity_Quad_Edge;
385 anElementName = QString("QUADRATIC_EDGE");
388 QString iconName = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
389 QString caption = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
390 QString argumentsGrTitle = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
391 QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
393 QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
394 QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
396 setWindowTitle(caption);
398 setSizeGripEnabled(true);
400 QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
401 aDialogLayout->setSpacing(SPACING);
402 aDialogLayout->setMargin(MARGIN);
404 /***************************************************************/
405 GroupConstructors = new QGroupBox(constructorGrTitle, this);
406 QButtonGroup* ButtonGroup = new QButtonGroup(this);
407 QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
408 aGroupConstructorsLayout->setSpacing(SPACING);
409 aGroupConstructorsLayout->setMargin(MARGIN);
411 myRadioButton1 = new QRadioButton(GroupConstructors);
412 myRadioButton1->setIcon(image0);
413 aGroupConstructorsLayout->addWidget(myRadioButton1);
414 ButtonGroup->addButton(myRadioButton1, 0);
416 /***************************************************************/
417 GroupArguments = new QGroupBox(argumentsGrTitle, this);
418 QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
419 aGroupArgumentsLayout->setSpacing(SPACING);
420 aGroupArgumentsLayout->setMargin(MARGIN);
423 QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
424 myCornerSelectButton = new QPushButton(GroupArguments);
425 myCornerSelectButton->setIcon(image1);
426 myCornerNodes = new QLineEdit(GroupArguments);
429 myTable = new QTableWidget(GroupArguments);
432 myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments);
433 myMidFaceSelectButton = new QPushButton(GroupArguments);
434 myMidFaceSelectButton->setIcon(image1);
435 myMidFaceNodes = new QLineEdit(GroupArguments);
436 myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6));
439 myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments);
440 myCenterSelectButton = new QPushButton(GroupArguments);
441 myCenterSelectButton->setIcon(image1);
442 myCenterNode = new QLineEdit(GroupArguments);
443 myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1));
445 myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
447 aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0);
448 aGroupArgumentsLayout->addWidget(myCornerSelectButton, 0, 1);
449 aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2);
450 aGroupArgumentsLayout->addWidget(myTable, 1, 0, 1, 3);
451 aGroupArgumentsLayout->addWidget(myMidFaceLabel, 2, 0);
452 aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1);
453 aGroupArgumentsLayout->addWidget(myMidFaceNodes, 2, 2);
454 aGroupArgumentsLayout->addWidget(myCenterLabel, 3, 0);
455 aGroupArgumentsLayout->addWidget(myCenterSelectButton, 3, 1);
456 aGroupArgumentsLayout->addWidget(myCenterNode, 3, 2);
457 aGroupArgumentsLayout->addWidget(myReverseCB, 4, 0, 1, 3);
459 /***************************************************************/
460 GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
461 GroupGroups->setCheckable( true );
462 QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
463 GroupGroupsLayout->setSpacing(SPACING);
464 GroupGroupsLayout->setMargin(MARGIN);
466 TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
467 ComboBox_GroupName = new QComboBox( GroupGroups );
468 ComboBox_GroupName->setEditable( true );
469 ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
471 GroupGroupsLayout->addWidget( TextLabel_GroupName );
472 GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
474 /***************************************************************/
475 GroupButtons = new QGroupBox(this);
476 QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
477 aGroupButtonsLayout->setSpacing(SPACING);
478 aGroupButtonsLayout->setMargin(MARGIN);
480 buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
481 buttonOk->setAutoDefault(true);
482 buttonOk->setDefault(true);
483 buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
484 buttonApply->setAutoDefault(true);
485 buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
486 buttonCancel->setAutoDefault(true);
487 buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
488 buttonHelp->setAutoDefault(true);
490 aGroupButtonsLayout->addWidget(buttonOk);
491 aGroupButtonsLayout->addSpacing(10);
492 aGroupButtonsLayout->addWidget(buttonApply);
493 aGroupButtonsLayout->addSpacing(10);
494 aGroupButtonsLayout->addStretch();
495 aGroupButtonsLayout->addWidget(buttonCancel);
496 aGroupButtonsLayout->addWidget(buttonHelp);
498 /***************************************************************/
499 aDialogLayout->addWidget(GroupConstructors);
500 aDialogLayout->addWidget(GroupArguments);
501 aDialogLayout->addWidget(GroupGroups);
502 aDialogLayout->addWidget(GroupButtons);
504 Init(); /* Initialisations */
507 //=================================================================================
508 // function : ~SMESHGUI_AddQuadraticElementDlg()
509 // purpose : Destroys the object and frees any allocated resources
510 //=================================================================================
512 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
517 //=================================================================================
520 //=================================================================================
522 void SMESHGUI_AddQuadraticElementDlg::Init()
524 myRadioButton1->setChecked(true);
525 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
527 /* reset "Add to group" control */
528 GroupGroups->setChecked( false );
531 myNbMidFaceNodes = 0;
536 switch (myGeomType) {
537 case SMDSEntity_Quad_Edge:
540 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
542 case SMDSEntity_Quad_Triangle:
545 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
547 case SMDSEntity_BiQuad_Triangle:
551 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
553 case SMDSEntity_Quad_Quadrangle:
556 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
558 case SMDSEntity_BiQuad_Quadrangle:
562 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
564 case SMDSEntity_Quad_Tetra:
567 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
569 case SMDSEntity_Quad_Pyramid:
572 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
574 case SMDSEntity_Quad_Penta:
577 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
579 case SMDSEntity_Quad_Hexa:
582 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
584 case SMDSEntity_TriQuad_Hexa:
587 myNbMidFaceNodes = 6;
589 myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
593 myMidFaceLabel ->setVisible( myNbMidFaceNodes );
594 myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
595 myMidFaceNodes ->setVisible( myNbMidFaceNodes );
596 myCenterLabel ->setVisible( myNbCenterNodes );
597 myCenterSelectButton ->setVisible( myNbCenterNodes );
598 myCenterNode ->setVisible( myNbCenterNodes );
600 myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
602 /* initialize table */
603 myTable->setColumnCount(3);
604 myTable->setRowCount(aNumRows);
606 QStringList aColLabels;
607 aColLabels.append(tr("SMESH_FIRST"));
608 aColLabels.append(tr("SMESH_MIDDLE"));
609 aColLabels.append(tr("SMESH_LAST"));
610 myTable->setHorizontalHeaderLabels(aColLabels);
612 for ( int col = 0; col < myTable->columnCount(); col++ )
613 myTable->setColumnWidth(col, 80);
615 //myTable->setColumnReadOnly(0, true); // VSR: TODO
616 //myTable->setColumnReadOnly(2, true); // VSR: TODO
618 myTable->setEnabled( false );
620 for ( int row = 0; row < myTable->rowCount(); row++ )
622 myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
623 myTable->item( row, 0 )->setFlags(0);
625 IdEditItem* anEditItem = new IdEditItem( "" );
626 anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
627 myTable->setItem(row, 1, anEditItem);
629 myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
630 myTable->item( row, 2 )->setFlags(0);
633 /* signals and slots connections */
634 connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
635 connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
636 connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
637 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
638 connect(myTable, SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
639 connect(myTable, SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
640 connect(myCornerNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
641 connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
642 connect(myCenterNode, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
643 connect(myReverseCB, SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
645 connect(buttonOk, SIGNAL(clicked()), SLOT(ClickOnOk()));
646 connect(buttonCancel, SIGNAL(clicked()), SLOT(reject()));
647 connect(buttonApply, SIGNAL(clicked()), SLOT(ClickOnApply()));
648 connect(buttonHelp, SIGNAL(clicked()), SLOT(ClickOnHelp()));
650 connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
651 connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
652 connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
654 myCurrentLineEdit = myCornerNodes;
656 // set selection mode
657 SMESH::SetPointRepresentation(true);
659 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
660 aViewWindow->SetSelectionMode( NodeSelection );
662 SelectionIntoArgument();
665 //=================================================================================
666 // function : ClickOnApply()
668 //=================================================================================
670 bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
675 if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
678 BusyLocker lock( myBusy );
680 std::vector<vtkIdType> anIds;
682 switch (myGeomType) {
683 case SMDSEntity_Quad_Edge:
684 anIds.push_back(myTable->item(0, 0)->text().toInt());
685 anIds.push_back(myTable->item(0, 2)->text().toInt());
686 anIds.push_back(myTable->item(0, 1)->text().toInt());
688 case SMDSEntity_Quad_Triangle:
689 case SMDSEntity_Quad_Quadrangle:
690 case SMDSEntity_BiQuad_Triangle:
691 case SMDSEntity_BiQuad_Quadrangle:
692 case SMDSEntity_Quad_Tetra:
693 case SMDSEntity_Quad_Pyramid:
694 case SMDSEntity_Quad_Penta:
695 case SMDSEntity_Quad_Hexa:
696 case SMDSEntity_TriQuad_Hexa:
697 for ( int row = 0; row < myNbCorners; row++ )
698 anIds.push_back(myTable->item(row, 0)->text().toInt());
699 for ( int row = 0; row < myTable->rowCount(); row++ )
700 anIds.push_back(myTable->item(row, 1)->text().toInt());
701 if ( myNbMidFaceNodes )
703 QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
704 for (int i = 0; i < aListId.count(); i++)
705 anIds.push_back( aListId[ i ].toInt() );
707 if ( myNbCenterNodes )
709 QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
710 anIds.push_back( aListId[ 0 ].toInt() );
714 if ( myReverseCB->isChecked())
715 ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
717 int aNumberOfIds = anIds.size();
718 SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
719 anArrayOfIdeces->length( aNumberOfIds );
721 for (int i = 0; i < aNumberOfIds; i++)
722 anArrayOfIdeces[i] = anIds[ i ];
724 bool addToGroup = GroupGroups->isChecked();
727 SMESH::SMESH_GroupBase_var aGroup;
730 aGroupName = ComboBox_GroupName->currentText();
731 for ( int i = 1; i <= ComboBox_GroupName->count(); i++ ) {
732 QString aName = ComboBox_GroupName->itemText( i );
733 if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
736 if ( idx > 0 && idx <= myGroups.count() ) {
737 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
738 if ( !aGeomGroup->_is_nil() ) {
739 int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
740 tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
741 tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
742 if ( res == 1 ) return false;
744 aGroup = myGroups[idx-1];
748 SMESH::ElementType anElementType;
750 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
751 switch (myGeomType) {
752 case SMDSEntity_Quad_Edge:
753 anElementType = SMESH::EDGE;
754 anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
755 case SMDSEntity_Quad_Triangle:
756 case SMDSEntity_Quad_Quadrangle:
757 case SMDSEntity_BiQuad_Triangle:
758 case SMDSEntity_BiQuad_Quadrangle:
759 anElementType = SMESH::FACE;
760 anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
761 case SMDSEntity_Quad_Tetra:
762 case SMDSEntity_Quad_Pyramid:
763 case SMDSEntity_Quad_Penta:
764 case SMDSEntity_Quad_Hexa:
765 case SMDSEntity_TriQuad_Hexa:
766 anElementType = SMESH::VOLUME;
767 anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
771 if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
772 SMESH::SMESH_Group_var aGroupUsed;
773 if ( aGroup->_is_nil() ) {
775 aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
776 if ( !aGroupUsed->_is_nil() ) {
777 myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
778 ComboBox_GroupName->addItem( aGroupName );
782 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
783 if ( !aGeomGroup->_is_nil() ) {
784 aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
785 if ( !aGroupUsed->_is_nil() && idx > 0 ) {
786 myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
787 SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
791 aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
794 if ( !aGroupUsed->_is_nil() ) {
795 SMESH::long_array_var anIdList = new SMESH::long_array;
796 anIdList->length( 1 );
797 anIdList[0] = anElemId;
798 aGroupUsed->Add( anIdList.inout() );
802 SALOME_ListIO aList; aList.Append( myActor->getIO() );
803 mySelector->ClearIndex();
804 mySelectionMgr->setSelectedObjects( aList, false );
806 mySimulation->SetVisibility(false);
810 SetCurrentSelection();
814 SMESHGUI::Modified();
819 //=================================================================================
820 // function : ClickOnOk()
822 //=================================================================================
824 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
826 if ( ClickOnApply() )
830 //=================================================================================
831 // function : reject()
833 //=================================================================================
835 void SMESHGUI_AddQuadraticElementDlg::reject()
837 mySelectionMgr->clearSelected();
838 mySimulation->SetVisibility(false);
839 SMESH::SetPointRepresentation(false);
840 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
841 aViewWindow->SetSelectionMode( ActorSelection );
842 disconnect(mySelectionMgr, 0, this, 0);
843 mySMESHGUI->ResetState();
847 //=================================================================================
848 // function : ClickOnHelp()
850 //=================================================================================
852 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
854 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
856 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
860 platform = "winapplication";
862 platform = "application";
864 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
865 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
866 arg(app->resourceMgr()->stringValue("ExternalBrowser",
868 arg(myHelpFileName));
872 //=================================================================================
873 // function : onTextChange()
875 //=================================================================================
877 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
880 BusyLocker lock( myBusy );
882 mySimulation->SetVisibility(false);
884 // hilight entered nodes
885 SMDS_Mesh* aMesh = 0;
887 aMesh = myActor->GetObject()->GetMesh();
889 QLineEdit* send = (QLineEdit*)sender();
890 if (send == myCornerNodes ||
891 send == myMidFaceNodes ||
892 send == myCenterNode)
893 myCurrentLineEdit = send;
896 TColStd_MapOfInteger newIndices;
898 QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
900 for (int i = 0; i < aListId.count(); i++) {
901 if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
903 newIndices.Add( n->GetID() );
912 mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
913 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
914 aViewWindow->highlight( myActor->getIO(), true, true );
916 if ( myCurrentLineEdit == myCornerNodes )
917 UpdateTable( allOk );
924 //=================================================================================
925 // function : SelectionIntoArgument()
926 // purpose : Called when selection has changed
927 //=================================================================================
929 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
932 BusyLocker lock( myBusy );
934 QString aCurrentEntry = myEntry;
936 if ( myCurrentLineEdit )
941 myCurrentLineEdit->setText("");
943 if (!GroupButtons->isEnabled()) // inactive
946 mySimulation->SetVisibility(false);
950 mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
952 if (aList.Extent() != 1)
959 Handle(SALOME_InteractiveObject) anIO = aList.First();
960 myEntry = anIO->getEntry();
961 myMesh = SMESH::GetMeshByIO(anIO);
962 if (myMesh->_is_nil()) {
967 myActor = SMESH::FindActorByEntry(anIO->getEntry());
972 if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
973 SMESH::ElementType anElementType;
974 switch ( myGeomType ) {
975 case SMDSEntity_Quad_Edge:
976 anElementType = SMESH::EDGE; break;
977 case SMDSEntity_Quad_Triangle:
978 case SMDSEntity_Quad_Quadrangle:
979 case SMDSEntity_BiQuad_Triangle:
980 case SMDSEntity_BiQuad_Quadrangle:
981 anElementType = SMESH::FACE; break;
982 case SMDSEntity_Quad_Tetra:
983 case SMDSEntity_Quad_Pyramid:
984 case SMDSEntity_Quad_Penta:
985 case SMDSEntity_Quad_Hexa:
986 case SMDSEntity_TriQuad_Hexa:
987 anElementType = SMESH::VOLUME; break;
990 ComboBox_GroupName->clear();
991 ComboBox_GroupName->addItem( QString() );
992 SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
993 for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
994 SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
995 if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
996 QString aGroupName( aGroup->GetName() );
997 if ( !aGroupName.isEmpty() ) {
998 myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
999 ComboBox_GroupName->addItem( aGroupName );
1010 // get selected nodes
1011 QString aString = "";
1012 int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
1014 if ( myCurrentLineEdit )
1016 if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
1017 myCurrentLineEdit->setText(aString);
1019 if ( myCurrentLineEdit == myCornerNodes )
1022 else if ( myTable->isEnabled() && nbNodes == 1 )
1024 int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
1026 myTable->item(theRow, 1)->setText(aString);
1030 displaySimulation();
1033 //=================================================================================
1034 // function : displaySimulation()
1036 //=================================================================================
1038 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
1042 SMESH::TElementSimulation::TVTKIds anIds;
1044 // Collect ids from the dialog
1047 int aDisplayMode = VTK_SURFACE;
1049 if ( myGeomType == SMDSEntity_Quad_Edge )
1051 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
1052 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
1053 anID = myTable->item(0, 1)->text().toInt(&ok);
1054 if (!ok) anID = myTable->item(0, 0)->text().toInt();
1055 anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1056 aDisplayMode = VTK_WIREFRAME;
1060 for ( int row = 0; row < myNbCorners; row++ )
1061 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
1063 for ( int row = 0; row < myTable->rowCount(); row++ )
1065 anID = myTable->item(row, 1)->text().toInt(&ok);
1067 anID = myTable->item(row, 0)->text().toInt();
1068 aDisplayMode = VTK_WIREFRAME;
1070 anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
1072 if ( myNbMidFaceNodes )
1074 QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1075 for (int i = 0; i < aListId.count(); i++)
1076 anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
1078 if ( myNbCenterNodes )
1080 QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
1081 anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
1085 mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
1089 mySimulation->SetVisibility(false);
1091 SMESH::UpdateView();
1094 //=================================================================================
1095 // function : SetCurrentSelection()
1097 //=================================================================================
1099 void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
1101 QPushButton* send = (QPushButton*)sender();
1102 myCurrentLineEdit = 0;
1104 if (send == myCornerSelectButton)
1105 myCurrentLineEdit = myCornerNodes;
1106 else if ( send == myMidFaceSelectButton )
1107 myCurrentLineEdit = myMidFaceNodes;
1108 else if ( send == myCenterSelectButton )
1109 myCurrentLineEdit = myCenterNode;
1111 if ( myCurrentLineEdit )
1113 myCurrentLineEdit->setFocus();
1114 SelectionIntoArgument();
1118 //=================================================================================
1119 // function : DeactivateActiveDialog()
1121 //=================================================================================
1123 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
1125 if (GroupConstructors->isEnabled()) {
1126 GroupConstructors->setEnabled(false);
1127 GroupArguments->setEnabled(false);
1128 GroupButtons->setEnabled(false);
1129 mySimulation->SetVisibility(false);
1130 mySMESHGUI->ResetState();
1131 mySMESHGUI->SetActiveDialogBox(0);
1135 //=================================================================================
1136 // function : ActivateThisDialog()
1138 //=================================================================================
1140 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
1142 /* Emit a signal to deactivate the active dialog */
1143 mySMESHGUI->EmitSignalDeactivateDialog();
1145 GroupConstructors->setEnabled(true);
1146 GroupArguments->setEnabled(true);
1147 GroupButtons->setEnabled(true);
1149 SMESH::SetPointRepresentation(true);
1151 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1152 aViewWindow->SetSelectionMode( NodeSelection );
1153 SelectionIntoArgument();
1156 //=================================================================================
1157 // function : enterEvent()
1159 //=================================================================================
1161 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
1163 if (GroupConstructors->isEnabled())
1165 ActivateThisDialog();
1168 //=================================================================================
1169 // function : onReverse()
1171 //=================================================================================
1173 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
1175 mySimulation->SetVisibility(false);
1176 displaySimulation();
1180 //=================================================================================
1181 // function : IsValid()
1183 //=================================================================================
1185 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
1187 SMDS_Mesh* aMesh = 0;
1189 aMesh = myActor->GetObject()->GetMesh();
1194 std::set< int > okIDs;
1195 for ( int row = 0; row < myTable->rowCount(); row++ )
1197 int anID = myTable->item(row, 1)->text().toInt(&ok);
1201 const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
1204 okIDs.insert( anID );
1207 QStringList aListId;
1208 if ( myNbMidFaceNodes )
1209 aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
1210 if ( myNbCenterNodes )
1211 aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
1213 for (int i = 0; i < aListId.count(); i++)
1215 int anID = aListId[ i ].toInt(&ok);
1219 if ( !aMesh->FindNode(anID) )
1221 okIDs.insert( anID );
1224 return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
1227 //=================================================================================
1228 // function : UpdateTable()
1230 //=================================================================================
1232 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
1234 QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
1236 if ( aListCorners.count() == myNbCorners && theConersValidity )
1238 myTable->setEnabled( true );
1240 // clear the Middle column
1241 for ( int row = 0; row < myTable->rowCount(); row++ )
1242 myTable->item( row, 1 )->setText("");
1247 switch (myGeomType) {
1248 case SMDSEntity_Quad_Edge:
1249 aFirstColIds = FirstEdgeIds;
1250 aLastColIds = LastEdgeIds;
1252 case SMDSEntity_Quad_Triangle:
1253 case SMDSEntity_BiQuad_Triangle:
1254 aFirstColIds = FirstTriangleIds;
1255 aLastColIds = LastTriangleIds;
1257 case SMDSEntity_Quad_Quadrangle:
1258 case SMDSEntity_BiQuad_Quadrangle:
1259 aFirstColIds = FirstQuadrangleIds;
1260 aLastColIds = LastQuadrangleIds;
1262 case SMDSEntity_Quad_Tetra:
1263 aFirstColIds = FirstTetrahedronIds;
1264 aLastColIds = LastTetrahedronIds;
1266 case SMDSEntity_Quad_Pyramid:
1267 aFirstColIds = FirstPyramidIds;
1268 aLastColIds = LastPyramidIds;
1270 case SMDSEntity_Quad_Penta:
1271 aFirstColIds = FirstPentahedronIds;
1272 aLastColIds = LastPentahedronIds;
1274 case SMDSEntity_Quad_Hexa:
1275 case SMDSEntity_TriQuad_Hexa:
1276 aFirstColIds = FirstHexahedronIds;
1277 aLastColIds = LastHexahedronIds;
1281 // fill the First and the Last columns
1282 for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1283 myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
1285 for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
1286 myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
1291 for ( int row = 0; row < myTable->rowCount(); row++ )
1292 for ( int col = 0; col < myTable->columnCount(); col++ )
1293 if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
1295 myTable->setEnabled( false );
1299 //=================================================================================
1300 // function : onTableActivate()
1302 //=================================================================================
1304 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
1306 myCurrentLineEdit = 0;
1307 displaySimulation();
1311 //=================================================================================
1312 // function : onCellTextChange()
1314 //=================================================================================
1316 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
1318 myCurrentLineEdit = 0;
1319 displaySimulation();
1323 //=================================================================================
1324 // function : keyPressEvent()
1326 //=================================================================================
1328 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
1330 QDialog::keyPressEvent( e );
1331 if ( e->isAccepted() )
1334 if ( e->key() == Qt::Key_F1 ) {
1340 //=======================================================================
1341 //function : updateButtons
1343 //=======================================================================
1345 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
1347 bool valid = IsValid();
1348 buttonOk->setEnabled( valid );
1349 buttonApply->setEnabled( valid );
1352 //=================================================================================
1353 // function : isValid
1355 //=================================================================================
1357 bool SMESHGUI_AddQuadraticElementDlg::isValid()
1359 if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
1360 SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );