00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "SMESHGUI_AddQuadraticElementDlg.h"
00029
00030 #include "SMESHGUI.h"
00031 #include "SMESHGUI_Utils.h"
00032 #include "SMESHGUI_VTKUtils.h"
00033 #include "SMESHGUI_MeshUtils.h"
00034 #include "SMESHGUI_GroupUtils.h"
00035 #include "SMESHGUI_IdValidator.h"
00036
00037 #include <SMESH_Actor.h>
00038 #include <SMESH_ActorUtils.h>
00039 #include <SMESH_FaceOrientationFilter.h>
00040 #include <SMDS_Mesh.hxx>
00041
00042
00043 #include <SUIT_Desktop.h>
00044 #include <SUIT_Session.h>
00045 #include <SUIT_MessageBox.h>
00046 #include <SUIT_ResourceMgr.h>
00047 #include <SUIT_ViewManager.h>
00048
00049 #include <LightApp_SelectionMgr.h>
00050
00051 #include <SVTK_ViewModel.h>
00052 #include <SVTK_ViewWindow.h>
00053
00054 #include <SALOME_ListIO.hxx>
00055
00056 #include <SalomeApp_Application.h>
00057
00058
00059 #include <SALOMEconfig.h>
00060 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
00061
00062
00063 #include <TColStd_MapOfInteger.hxx>
00064
00065
00066 #include <vtkIdList.h>
00067 #include <vtkUnstructuredGrid.h>
00068 #include <vtkDataSetMapper.h>
00069 #include <vtkPolyDataMapper.h>
00070 #include <vtkProperty.h>
00071 #include <vtkCellType.h>
00072
00073
00074 #include <QComboBox>
00075 #include <QGroupBox>
00076 #include <QLabel>
00077 #include <QLineEdit>
00078 #include <QPushButton>
00079 #include <QRadioButton>
00080 #include <QVBoxLayout>
00081 #include <QHBoxLayout>
00082 #include <QGridLayout>
00083 #include <QCheckBox>
00084 #include <QTableWidget>
00085 #include <QKeyEvent>
00086 #include <QButtonGroup>
00087
00088
00089 #include <vector>
00090
00091 #define SPACING 6
00092 #define MARGIN 11
00093
00094 namespace SMESH
00095 {
00096 void ReverseConnectivity( std::vector<vtkIdType> & ids, int type )
00097 {
00098
00099
00100 const int* conn = 0;
00101
00102 switch ( type ) {
00103 case QUAD_TETRAHEDRON: {
00104 static int aConn[] = {0,2,1,3,6,5,4,7,9,8};
00105 conn = aConn;
00106 break;
00107 }
00108 case QUAD_PYRAMID: {
00109 static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
00110 conn = aConn;
00111 break;
00112 }
00113 case QUAD_PENTAHEDRON: {
00114 static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
00115 conn = aConn;
00116 break;
00117 }
00118 case QUAD_HEXAHEDRON: {
00119 static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
00120 conn = aConn;
00121 break;
00122 }
00123 case QUAD_EDGE: {
00124 static int aConn[] = {1,0,2};
00125 conn = aConn;
00126 break;
00127 }
00128 case QUAD_TRIANGLE: {
00129 static int aConn[] = {0,2,1,5,4,3};
00130 conn = aConn;
00131 break;
00132 }
00133 case QUAD_QUADRANGLE: {
00134 static int aConn[] = {0,3,2,1,7,6,5,4};
00135 conn = aConn;
00136 break;
00137 }
00138 default:;
00139 }
00140 if ( !conn ) {
00141 reverse( ids.begin(), ids.end() );
00142 }
00143 else {
00144 std::vector<vtkIdType> aRevIds( ids.size() );
00145 for ( int i = 0; i < ids.size(); i++)
00146 aRevIds[ i ] = ids[ conn[ i ]];
00147 ids = aRevIds;
00148 }
00149 }
00150
00151 class TElementSimulation {
00152 SalomeApp_Application* myApplication;
00153 SUIT_ViewWindow* myViewWindow;
00154 SVTK_ViewWindow* myVTKViewWindow;
00155
00156 SALOME_Actor* myPreviewActor;
00157 vtkDataSetMapper* myMapper;
00158 vtkUnstructuredGrid* myGrid;
00159
00160
00161
00162
00163 SALOME_Actor* myFaceOrientation;
00164 vtkPolyDataMapper* myFaceOrientationDataMapper;
00165 SMESH_FaceOrientationFilter* myFaceOrientationFilter;
00166
00167 public:
00168 TElementSimulation (SalomeApp_Application* theApplication)
00169 {
00170 myApplication = theApplication;
00171 SUIT_ViewManager* mgr = theApplication->activeViewManager();
00172 if (!mgr) return;
00173 myViewWindow = mgr->getActiveView();
00174 myVTKViewWindow = GetVtkViewWindow(myViewWindow);
00175
00176 myGrid = vtkUnstructuredGrid::New();
00177
00178
00179 myMapper = vtkDataSetMapper::New();
00180 myMapper->SetInput(myGrid);
00181
00182 myPreviewActor = SALOME_Actor::New();
00183 myPreviewActor->PickableOff();
00184 myPreviewActor->VisibilityOff();
00185 myPreviewActor->SetMapper(myMapper);
00186
00187 vtkProperty* myProp = vtkProperty::New();
00188 vtkFloatingPointType aRGB[3], aBackRGB[3];
00189 GetColor( "SMESH", "fill_color", aRGB[0], aRGB[1], aRGB[2], QColor( 0, 170, 255 ) );
00190 myProp->SetColor( aRGB[0], aRGB[1], aRGB[2] );
00191 myPreviewActor->SetProperty( myProp );
00192 myProp->Delete();
00193
00194 vtkProperty* myBackProp = vtkProperty::New();
00195 GetColor( "SMESH", "backface_color", aBackRGB[0], aBackRGB[1], aBackRGB[2], QColor( 0, 0, 255 ) );
00196 myBackProp->SetColor( aBackRGB[0], aBackRGB[1], aBackRGB[2] );
00197 myPreviewActor->SetBackfaceProperty( myBackProp );
00198 myBackProp->Delete();
00199
00200 myVTKViewWindow->AddActor(myPreviewActor);
00201
00202
00203 myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
00204 myFaceOrientationFilter->SetInput(myGrid);
00205
00206 myFaceOrientationDataMapper = vtkPolyDataMapper::New();
00207 myFaceOrientationDataMapper->SetInput(myFaceOrientationFilter->GetOutput());
00208
00209 myFaceOrientation = SALOME_Actor::New();
00210 myFaceOrientation->PickableOff();
00211 myFaceOrientation->VisibilityOff();
00212 myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
00213
00214 vtkProperty* anOrientationProp = vtkProperty::New();
00215 GetColor( "SMESH", "orientation_color", aRGB[0], aRGB[1], aRGB[2], QColor( 255, 255, 255 ) );
00216 anOrientationProp->SetColor( aRGB[0], aRGB[1], aRGB[2] );
00217 myFaceOrientation->SetProperty( anOrientationProp );
00218 anOrientationProp->Delete();
00219
00220 myVTKViewWindow->AddActor(myFaceOrientation);
00221 }
00222
00223 typedef std::vector<vtkIdType> TVTKIds;
00224 void SetPosition (SMESH_Actor* theActor,
00225 const int theType,
00226 TVTKIds& theIds,
00227 const int theMode,
00228 const bool theReverse)
00229 {
00230 vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
00231 myGrid->SetPoints(aGrid->GetPoints());
00232
00233
00234
00235 vtkIdType aType = 0;
00236
00237 switch (theType) {
00238 case QUAD_EDGE:
00239 aType = VTK_QUADRATIC_EDGE;
00240 break;
00241 case QUAD_TRIANGLE:
00242 aType = VTK_QUADRATIC_TRIANGLE;
00243 break;
00244 case QUAD_QUADRANGLE:
00245 aType = VTK_QUADRATIC_QUAD;
00246 break;
00247 case QUAD_TETRAHEDRON:
00248 aType = VTK_QUADRATIC_TETRA;
00249 break;
00250 case QUAD_PYRAMID:
00251
00252 aType = VTK_CONVEX_POINT_SET;
00253 break;
00254 case QUAD_PENTAHEDRON:
00255 aType = VTK_QUADRATIC_WEDGE;
00256
00257 break;
00258 case QUAD_HEXAHEDRON:
00259 aType = VTK_QUADRATIC_HEXAHEDRON;
00260 break;
00261 }
00262
00263
00264 if ( aType == VTK_CONVEX_POINT_SET ) {
00265 if ( theReverse && theMode == VTK_SURFACE ) {
00266
00267 }
00268 }
00269 else {
00270
00271 if( aType != VTK_QUADRATIC_WEDGE) {
00272 if ( theIds.size() > 8 ? !theReverse : theReverse ) {
00273 ReverseConnectivity( theIds, theType );
00274 }
00275 }
00276 else if(theReverse)
00277 ReverseConnectivity( theIds, theType );
00278 }
00279
00280 myGrid->Reset();
00281 vtkIdList *anIds = vtkIdList::New();
00282
00283 for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
00284 anIds->InsertId(i,theIds[i]);
00285
00286 }
00287
00288 myGrid->InsertNextCell(aType,anIds);
00289 anIds->Delete();
00290
00291 myGrid->Modified();
00292
00293 myPreviewActor->GetMapper()->Update();
00294 myPreviewActor->SetRepresentation( theMode );
00295 SetVisibility(true, theActor->GetFacesOriented());
00296
00297
00298 if ( aType == VTK_CONVEX_POINT_SET ) {
00299 if ( theReverse && theMode == VTK_SURFACE ) {
00300
00301 }
00302 }
00303 }
00304
00305
00306 void SetVisibility (bool theVisibility, bool theShowOrientation = false)
00307 {
00308 myPreviewActor->SetVisibility(theVisibility);
00309 myFaceOrientation->SetVisibility(theShowOrientation);
00310 RepaintCurrentView();
00311 }
00312
00313
00314 ~TElementSimulation()
00315 {
00316 if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
00317 myVTKViewWindow->RemoveActor(myPreviewActor);
00318 myVTKViewWindow->RemoveActor(myFaceOrientation);
00319 }
00320 myPreviewActor->Delete();
00321 myFaceOrientation->Delete();
00322
00323 myMapper->RemoveAllInputs();
00324 myMapper->Delete();
00325
00326 myFaceOrientationFilter->Delete();
00327
00328 myFaceOrientationDataMapper->RemoveAllInputs();
00329 myFaceOrientationDataMapper->Delete();
00330
00331 myGrid->Delete();
00332
00333
00334
00335 }
00336 };
00337 }
00338
00339
00340
00341 static int FirstEdgeIds[] = {0};
00342 static int LastEdgeIds[] = {1};
00343
00344 static int FirstTriangleIds[] = {0,1,2};
00345 static int LastTriangleIds[] = {1,2,0};
00346
00347 static int FirstQuadrangleIds[] = {0,1,2,3};
00348 static int LastQuadrangleIds[] = {1,2,3,0};
00349
00350 static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
00351 static int LastTetrahedronIds[] = {1,2,0,0,1,2};
00352
00353 static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
00354 static int LastPyramidIds[] = {1,2,3,0,0,1,2,3};
00355
00356 static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
00357 static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5};
00358
00359 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
00360 static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7};
00361
00362
00363
00370 class BusyLocker
00371 {
00372 public:
00374 BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
00376 ~BusyLocker() { myBusy = false; }
00377 private:
00378 bool& myBusy;
00379 };
00380
00387 class IdEditItem: public QTableWidgetItem
00388 {
00389 public:
00390 IdEditItem(const QString& text );
00391 ~IdEditItem();
00392
00393 QWidget* createEditor() const;
00394 };
00395
00396 IdEditItem::IdEditItem(const QString& text )
00397 : QTableWidgetItem(text, QTableWidgetItem::UserType+100)
00398 {
00399 }
00400
00401 IdEditItem::~IdEditItem()
00402 {
00403 }
00404
00405 QWidget* IdEditItem::createEditor() const
00406 {
00407 QLineEdit *aLineEdit = new QLineEdit(text(), tableWidget());
00408 aLineEdit->setValidator( new SMESHGUI_IdValidator(tableWidget(), 1) );
00409 return aLineEdit;
00410 }
00411
00412
00413
00414
00415
00416 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
00417 const int theType )
00418 : QDialog( SMESH::GetDesktop( theModule ) ),
00419 mySMESHGUI( theModule ),
00420 mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
00421 myType( theType ),
00422 myBusy( false )
00423 {
00424 setModal( false );
00425 setAttribute( Qt::WA_DeleteOnClose, true );
00426
00427 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
00428 (SUIT_Session::session()->activeApplication());
00429
00430 mySimulation = new SMESH::TElementSimulation (anApp);
00431 mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
00432
00433 QString anElementName;
00434
00435 switch ( myType ) {
00436 case QUAD_EDGE:
00437 anElementName = QString("QUADRATIC_EDGE");
00438 break;
00439 case QUAD_TRIANGLE:
00440 anElementName = QString("QUADRATIC_TRIANGLE");
00441 break;
00442 case QUAD_QUADRANGLE:
00443 anElementName = QString("QUADRATIC_QUADRANGLE");
00444 break;
00445 case QUAD_TETRAHEDRON:
00446 anElementName = QString("QUADRATIC_TETRAHEDRON");
00447 break;
00448 case QUAD_PYRAMID:
00449 anElementName = QString("QUADRATIC_PYRAMID");
00450 break;
00451 case QUAD_PENTAHEDRON:
00452 anElementName = QString("QUADRATIC_PENTAHEDRON");
00453 break;
00454 case QUAD_HEXAHEDRON:
00455 anElementName = QString("QUADRATIC_HEXAHEDRON");
00456 break;
00457 default:
00458 myType = QUAD_EDGE;
00459 anElementName = QString("QUADRATIC_EDGE");
00460 }
00461
00462 QString iconName = tr(QString("ICON_DLG_%1").arg(anElementName).toLatin1().data());
00463 QString caption = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
00464 QString argumentsGrTitle = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
00465 QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
00466
00467 QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
00468 QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
00469
00470 setWindowTitle(caption);
00471
00472 setSizeGripEnabled(true);
00473
00474 QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
00475 aDialogLayout->setSpacing(SPACING);
00476 aDialogLayout->setMargin(MARGIN);
00477
00478
00479 GroupConstructors = new QGroupBox(constructorGrTitle, this);
00480 QButtonGroup* ButtonGroup = new QButtonGroup(this);
00481 QHBoxLayout* aGroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
00482 aGroupConstructorsLayout->setSpacing(SPACING);
00483 aGroupConstructorsLayout->setMargin(MARGIN);
00484
00485 myRadioButton1 = new QRadioButton(GroupConstructors);
00486 myRadioButton1->setIcon(image0);
00487 aGroupConstructorsLayout->addWidget(myRadioButton1);
00488 ButtonGroup->addButton(myRadioButton1, 0);
00489
00490
00491 GroupArguments = new QGroupBox(argumentsGrTitle, this);
00492 QGridLayout* aGroupArgumentsLayout = new QGridLayout(GroupArguments);
00493 aGroupArgumentsLayout->setSpacing(SPACING);
00494 aGroupArgumentsLayout->setMargin(MARGIN);
00495
00496 QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
00497 mySelectButton = new QPushButton(GroupArguments);
00498 mySelectButton->setIcon(image1);
00499 myCornerNodes = new QLineEdit(GroupArguments);
00500
00501 myTable = new QTableWidget(GroupArguments);
00502
00503 myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
00504
00505 aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0);
00506 aGroupArgumentsLayout->addWidget(mySelectButton, 0, 1);
00507 aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2);
00508 aGroupArgumentsLayout->addWidget(myTable, 1, 0, 1, 3);
00509 aGroupArgumentsLayout->addWidget(myReverseCB, 2, 0, 1, 3);
00510
00511
00512 GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
00513 GroupGroups->setCheckable( true );
00514 QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
00515 GroupGroupsLayout->setSpacing(SPACING);
00516 GroupGroupsLayout->setMargin(MARGIN);
00517
00518 TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
00519 ComboBox_GroupName = new QComboBox( GroupGroups );
00520 ComboBox_GroupName->setEditable( true );
00521
00522 GroupGroupsLayout->addWidget( TextLabel_GroupName );
00523 GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
00524
00525
00526 GroupButtons = new QGroupBox(this);
00527 QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
00528 aGroupButtonsLayout->setSpacing(SPACING);
00529 aGroupButtonsLayout->setMargin(MARGIN);
00530
00531 buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
00532 buttonOk->setAutoDefault(true);
00533 buttonOk->setDefault(true);
00534 buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
00535 buttonApply->setAutoDefault(true);
00536 buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
00537 buttonCancel->setAutoDefault(true);
00538 buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
00539 buttonHelp->setAutoDefault(true);
00540
00541 aGroupButtonsLayout->addWidget(buttonOk);
00542 aGroupButtonsLayout->addSpacing(10);
00543 aGroupButtonsLayout->addWidget(buttonApply);
00544 aGroupButtonsLayout->addSpacing(10);
00545 aGroupButtonsLayout->addStretch();
00546 aGroupButtonsLayout->addWidget(buttonCancel);
00547 aGroupButtonsLayout->addWidget(buttonHelp);
00548
00549
00550 aDialogLayout->addWidget(GroupConstructors);
00551 aDialogLayout->addWidget(GroupArguments);
00552 aDialogLayout->addWidget(GroupGroups);
00553 aDialogLayout->addWidget(GroupButtons);
00554
00555 Init();
00556 }
00557
00558
00559
00560
00561
00562 SMESHGUI_AddQuadraticElementDlg::~SMESHGUI_AddQuadraticElementDlg()
00563 {
00564 delete mySimulation;
00565 }
00566
00567
00568
00569
00570
00571 void SMESHGUI_AddQuadraticElementDlg::Init()
00572 {
00573 myRadioButton1->setChecked(true);
00574 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
00575
00576
00577 GroupGroups->setChecked( false );
00578
00579 myActor = 0;
00580
00581 int aNumRows;
00582
00583 switch (myType) {
00584 case QUAD_EDGE:
00585 aNumRows = 1;
00586 myNbCorners = 2;
00587 myHelpFileName = "adding_quadratic_elements_page.html#?";
00588 break;
00589 case QUAD_TRIANGLE:
00590 aNumRows = 3;
00591 myNbCorners = 3;
00592 myHelpFileName = "adding_quadratic_elements_page.html#?";
00593 break;
00594 case QUAD_QUADRANGLE:
00595 aNumRows = 4;
00596 myNbCorners = 4;
00597 myHelpFileName = "adding_quadratic_elements_page.html#?";
00598 break;
00599 case QUAD_TETRAHEDRON:
00600 aNumRows = 6;
00601 myNbCorners = 4;
00602 myHelpFileName = "adding_quadratic_elements_page.html#?";
00603 break;
00604 case QUAD_PYRAMID:
00605 aNumRows = 8;
00606 myNbCorners = 5;
00607 myHelpFileName = "adding_quadratic_elements_page.html#?";
00608 break;
00609 case QUAD_PENTAHEDRON:
00610 aNumRows = 9;
00611 myNbCorners = 6;
00612 myHelpFileName = "adding_quadratic_elements_page.html#?";
00613 break;
00614 case QUAD_HEXAHEDRON:
00615 aNumRows = 12;
00616 myNbCorners = 8;
00617 myHelpFileName = "adding_quadratic_elements_page.html#?";
00618 break;
00619 }
00620
00621 myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
00622
00623
00624 myTable->setColumnCount(3);
00625 myTable->setRowCount(aNumRows);
00626
00627 QStringList aColLabels;
00628 aColLabels.append(tr("SMESH_FIRST"));
00629 aColLabels.append(tr("SMESH_MIDDLE"));
00630 aColLabels.append(tr("SMESH_LAST"));
00631 myTable->setHorizontalHeaderLabels(aColLabels);
00632
00633 for ( int col = 0; col < myTable->columnCount(); col++ )
00634 myTable->setColumnWidth(col, 80);
00635
00636
00637
00638
00639 myTable->setEnabled( false );
00640
00641 for ( int row = 0; row < myTable->rowCount(); row++ )
00642 {
00643 myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
00644 myTable->item( row, 0 )->setFlags(0);
00645
00646 IdEditItem* anEditItem = new IdEditItem( "" );
00647 anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
00648 myTable->setItem(row, 1, anEditItem);
00649
00650 myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
00651 myTable->item( row, 2 )->setFlags(0);
00652 }
00653
00654
00655 connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners()));
00656 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
00657 connect(myTable, SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
00658 connect(myTable, SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
00659 connect(myCornerNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
00660 connect(myReverseCB, SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
00661
00662 connect(buttonOk, SIGNAL(clicked()), SLOT(ClickOnOk()));
00663 connect(buttonCancel, SIGNAL(clicked()), SLOT(ClickOnCancel()));
00664 connect(buttonApply, SIGNAL(clicked()), SLOT(ClickOnApply()));
00665 connect(buttonHelp, SIGNAL(clicked()), SLOT(ClickOnHelp()));
00666
00667 connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
00668 connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
00669 connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
00670
00671
00672 SMESH::SetPointRepresentation(true);
00673
00674 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00675 aViewWindow->SetSelectionMode( NodeSelection );
00676
00677 SetEditCorners();
00678 }
00679
00680
00681
00682
00683
00684 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
00685 {
00686 if( !isValid() )
00687 return;
00688
00689 if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
00690 return;
00691
00692 BusyLocker lock( myBusy );
00693
00694 std::vector<vtkIdType> anIds;
00695
00696 switch (myType) {
00697 case QUAD_EDGE:
00698 anIds.push_back(myTable->item(0, 0)->text().toInt());
00699 anIds.push_back(myTable->item(0, 2)->text().toInt());
00700 anIds.push_back(myTable->item(0, 1)->text().toInt());
00701 break;
00702 case QUAD_TRIANGLE:
00703 case QUAD_QUADRANGLE:
00704 case QUAD_TETRAHEDRON:
00705 case QUAD_PYRAMID:
00706 case QUAD_PENTAHEDRON:
00707 case QUAD_HEXAHEDRON:
00708 for ( int row = 0; row < myNbCorners; row++ )
00709 anIds.push_back(myTable->item(row, 0)->text().toInt());
00710 for ( int row = 0; row < myTable->rowCount(); row++ )
00711 anIds.push_back(myTable->item(row, 1)->text().toInt());
00712 break;
00713 }
00714 if ( myReverseCB->isChecked())
00715 SMESH::ReverseConnectivity( anIds, myType );
00716
00717 int aNumberOfIds = anIds.size();
00718 SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
00719 anArrayOfIdeces->length( aNumberOfIds );
00720
00721 for (int i = 0; i < aNumberOfIds; i++)
00722 anArrayOfIdeces[i] = anIds[ i ];
00723
00724 bool addToGroup = GroupGroups->isChecked();
00725 QString aGroupName;
00726
00727 SMESH::SMESH_GroupBase_var aGroup;
00728 int idx = 0;
00729 if( addToGroup ) {
00730 aGroupName = ComboBox_GroupName->currentText();
00731 for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
00732 QString aName = ComboBox_GroupName->itemText( i );
00733 if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
00734 idx = i;
00735 }
00736 if ( idx > 0 ) {
00737 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
00738 if ( !aGeomGroup->_is_nil() ) {
00739 int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
00740 tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
00741 tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
00742 if ( res == 1 ) return;
00743 }
00744 aGroup = myGroups[idx-1];
00745 }
00746 }
00747
00748 SMESH::ElementType anElementType;
00749 long anElemId = -1;
00750 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
00751 switch (myType) {
00752 case QUAD_EDGE:
00753 anElementType = SMESH::EDGE;
00754 anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
00755 case QUAD_TRIANGLE:
00756 case QUAD_QUADRANGLE:
00757 anElementType = SMESH::FACE;
00758 anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
00759 case QUAD_TETRAHEDRON:
00760 case QUAD_PYRAMID:
00761 case QUAD_PENTAHEDRON:
00762 case QUAD_HEXAHEDRON:
00763 anElementType = SMESH::VOLUME;
00764 anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
00765 default: break;
00766 }
00767
00768 if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
00769 SMESH::SMESH_Group_var aGroupUsed;
00770 if ( aGroup->_is_nil() ) {
00771
00772 aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
00773 if ( !aGroupUsed->_is_nil() ) {
00774 myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
00775 ComboBox_GroupName->addItem( aGroupName );
00776 }
00777 }
00778 else {
00779 SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
00780 if ( !aGeomGroup->_is_nil() ) {
00781 aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
00782 if ( !aGroupUsed->_is_nil() && idx > 0 ) {
00783 myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
00784 SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
00785 }
00786 }
00787 else
00788 aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
00789 }
00790
00791 if ( !aGroupUsed->_is_nil() ) {
00792 SMESH::long_array_var anIdList = new SMESH::long_array;
00793 anIdList->length( 1 );
00794 anIdList[0] = anElemId;
00795 aGroupUsed->Add( anIdList.inout() );
00796 }
00797 }
00798
00799 SALOME_ListIO aList; aList.Append( myActor->getIO() );
00800 mySelector->ClearIndex();
00801 mySelectionMgr->setSelectedObjects( aList, false );
00802
00803 mySimulation->SetVisibility(false);
00804 SMESH::UpdateView();
00805
00806 UpdateTable();
00807 SetEditCorners();
00808
00809 updateButtons();
00810
00811 SMESHGUI::Modified();
00812 }
00813
00814
00815
00816
00817
00818 void SMESHGUI_AddQuadraticElementDlg::ClickOnOk()
00819 {
00820 ClickOnApply();
00821 ClickOnCancel();
00822 }
00823
00824
00825
00826
00827
00828 void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
00829 {
00830 mySelectionMgr->clearSelected();
00831 mySimulation->SetVisibility(false);
00832 SMESH::SetPointRepresentation(false);
00833 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00834 aViewWindow->SetSelectionMode( ActorSelection );
00835 disconnect(mySelectionMgr, 0, this, 0);
00836 mySMESHGUI->ResetState();
00837 reject();
00838 }
00839
00840
00841
00842
00843
00844 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
00845 {
00846 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
00847 if (app)
00848 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
00849 else {
00850 QString platform;
00851 #ifdef WIN32
00852 platform = "winapplication";
00853 #else
00854 platform = "application";
00855 #endif
00856 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
00857 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
00858 arg(app->resourceMgr()->stringValue("ExternalBrowser",
00859 platform)).
00860 arg(myHelpFileName));
00861 }
00862 }
00863
00864
00865
00866
00867
00868 void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
00869 {
00870 if (myBusy) return;
00871 BusyLocker lock( myBusy );
00872
00873 mySimulation->SetVisibility(false);
00874
00875
00876 SMDS_Mesh* aMesh = 0;
00877 if (myActor)
00878 aMesh = myActor->GetObject()->GetMesh();
00879
00880 if (aMesh) {
00881 TColStd_MapOfInteger newIndices;
00882
00883 QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
00884 bool allOk = true;
00885 for (int i = 0; i < aListId.count(); i++) {
00886 if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
00887 {
00888 newIndices.Add( n->GetID() );
00889 }
00890 else
00891 {
00892 allOk = false;
00893 break;
00894 }
00895 }
00896
00897 mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
00898 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00899 aViewWindow->highlight( myActor->getIO(), true, true );
00900
00901 if ( sender() == myCornerNodes )
00902 UpdateTable( allOk );
00903 }
00904
00905 updateButtons();
00906 displaySimulation();
00907 }
00908
00909
00910
00911
00912
00913 void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
00914 {
00915 if (myBusy) return;
00916 BusyLocker lock( myBusy );
00917
00918 QString aCurrentEntry = myEntry;
00919
00920 if ( myIsEditCorners )
00921 {
00922
00923 myActor = 0;
00924
00925 myCornerNodes->setText("");
00926
00927 if (!GroupButtons->isEnabled())
00928 return;
00929
00930 mySimulation->SetVisibility(false);
00931
00932
00933 SALOME_ListIO aList;
00934 mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
00935
00936 if (aList.Extent() != 1)
00937 {
00938 UpdateTable();
00939 updateButtons();
00940 return;
00941 }
00942
00943 Handle(SALOME_InteractiveObject) anIO = aList.First();
00944 myEntry = anIO->getEntry();
00945 myMesh = SMESH::GetMeshByIO(anIO);
00946 if (myMesh->_is_nil()) {
00947 updateButtons();
00948 return;
00949 }
00950
00951 myActor = SMESH::FindActorByEntry(anIO->getEntry());
00952
00953 }
00954
00955
00956 if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
00957 SMESH::ElementType anElementType;
00958 switch ( myType ) {
00959 case QUAD_EDGE:
00960 anElementType = SMESH::EDGE; break;
00961 case QUAD_TRIANGLE:
00962 case QUAD_QUADRANGLE:
00963 anElementType = SMESH::FACE; break;
00964 case QUAD_TETRAHEDRON:
00965 case QUAD_PYRAMID:
00966 case QUAD_PENTAHEDRON:
00967 case QUAD_HEXAHEDRON:
00968 anElementType = SMESH::VOLUME; break;
00969 }
00970 myGroups.clear();
00971 ComboBox_GroupName->clear();
00972 ComboBox_GroupName->addItem( QString() );
00973 SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
00974 for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
00975 SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
00976 if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
00977 QString aGroupName( aGroup->GetName() );
00978 if ( !aGroupName.isEmpty() ) {
00979 myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
00980 ComboBox_GroupName->addItem( aGroupName );
00981 }
00982 }
00983 }
00984 }
00985
00986 if (!myActor) {
00987 updateButtons();
00988 return;
00989 }
00990
00991
00992 QString aString = "";
00993 int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
00994
00995 if ( myIsEditCorners )
00996 {
00997 myCornerNodes->setText(aString);
00998
00999 UpdateTable();
01000 }
01001 else if ( myTable->isEnabled() && nbNodes == 1 )
01002 {
01003 int theRow = myTable->currentRow(), theCol = myTable->currentColumn();
01004 if ( theCol == 1 )
01005 myTable->item(theRow, 1)->setText(aString);
01006 }
01007
01008 updateButtons();
01009 displaySimulation();
01010 }
01011
01012
01013
01014
01015
01016 void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
01017 {
01018 if ( IsValid() )
01019 {
01020 SMESH::TElementSimulation::TVTKIds anIds;
01021
01022
01023 int anID;
01024 bool ok;
01025 int aDisplayMode = VTK_SURFACE;
01026
01027 if ( myType == QUAD_EDGE )
01028 {
01029 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
01030 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
01031 anID = myTable->item(0, 1)->text().toInt(&ok);
01032 if (!ok) anID = myTable->item(0, 0)->text().toInt();
01033 anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
01034 aDisplayMode = VTK_WIREFRAME;
01035 }
01036 else
01037 {
01038 for ( int row = 0; row < myNbCorners; row++ )
01039 anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
01040
01041 for ( int row = 0; row < myTable->rowCount(); row++ )
01042 {
01043 anID = myTable->item(row, 1)->text().toInt(&ok);
01044 if (!ok) {
01045 anID = myTable->item(row, 0)->text().toInt();
01046 aDisplayMode = VTK_WIREFRAME;
01047 }
01048 anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
01049 }
01050 }
01051
01052 mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
01053 }
01054 else
01055 {
01056 mySimulation->SetVisibility(false);
01057 }
01058 SMESH::UpdateView();
01059 }
01060
01061
01062
01063
01064
01065 void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
01066 {
01067 myCornerNodes->setFocus();
01068 myIsEditCorners = true;
01069 SelectionIntoArgument();
01070 updateButtons();
01071 }
01072
01073
01074
01075
01076
01077 void SMESHGUI_AddQuadraticElementDlg::DeactivateActiveDialog()
01078 {
01079 if (GroupConstructors->isEnabled()) {
01080 GroupConstructors->setEnabled(false);
01081 GroupArguments->setEnabled(false);
01082 GroupButtons->setEnabled(false);
01083 mySimulation->SetVisibility(false);
01084 mySMESHGUI->ResetState();
01085 mySMESHGUI->SetActiveDialogBox(0);
01086 }
01087 }
01088
01089
01090
01091
01092
01093 void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
01094 {
01095
01096 mySMESHGUI->EmitSignalDeactivateDialog();
01097
01098 GroupConstructors->setEnabled(true);
01099 GroupArguments->setEnabled(true);
01100 GroupButtons->setEnabled(true);
01101
01102 SMESH::SetPointRepresentation(true);
01103
01104 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
01105 aViewWindow->SetSelectionMode( NodeSelection );
01106 SelectionIntoArgument();
01107 }
01108
01109
01110
01111
01112
01113 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
01114 {
01115 if (GroupConstructors->isEnabled())
01116 return;
01117 ActivateThisDialog();
01118 }
01119
01120
01121
01122
01123
01124 void SMESHGUI_AddQuadraticElementDlg::closeEvent (QCloseEvent*)
01125 {
01126
01127 ClickOnCancel();
01128 }
01129
01130
01131
01132
01133
01134 void SMESHGUI_AddQuadraticElementDlg::hideEvent (QHideEvent*)
01135 {
01136 if (!isMinimized())
01137 ClickOnCancel();
01138 }
01139
01140
01141
01142
01143
01144 void SMESHGUI_AddQuadraticElementDlg::onReverse (int state)
01145 {
01146 mySimulation->SetVisibility(false);
01147 displaySimulation();
01148 updateButtons();
01149 }
01150
01151
01152
01153
01154
01155
01156 bool SMESHGUI_AddQuadraticElementDlg::IsValid()
01157 {
01158 SMDS_Mesh* aMesh = 0;
01159 if (myActor)
01160 aMesh = myActor->GetObject()->GetMesh();
01161 if (!aMesh)
01162 return false;
01163
01164 bool ok;
01165
01166 for ( int row = 0; row < myTable->rowCount(); row++ )
01167 {
01168 int anID = myTable->item(row, 1)->text().toInt(&ok);
01169 if ( !ok )
01170 return false;
01171
01172 const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
01173 if ( !aNode )
01174 return false;
01175 }
01176
01177 return true;
01178 }
01179
01180
01181
01182
01183
01184 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
01185 {
01186 QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
01187
01188 if ( aListCorners.count() == myNbCorners && theConersValidity )
01189 {
01190 myTable->setEnabled( true );
01191
01192
01193 for ( int row = 0; row < myTable->rowCount(); row++ )
01194 myTable->item( row, 1 )->setText("");
01195
01196 int* aFirstColIds;
01197 int* aLastColIds;
01198
01199 switch (myType) {
01200 case QUAD_EDGE:
01201 aFirstColIds = FirstEdgeIds;
01202 aLastColIds = LastEdgeIds;
01203 break;
01204 case QUAD_TRIANGLE:
01205 aFirstColIds = FirstTriangleIds;
01206 aLastColIds = LastTriangleIds;
01207 break;
01208 case QUAD_QUADRANGLE:
01209 aFirstColIds = FirstQuadrangleIds;
01210 aLastColIds = LastQuadrangleIds;
01211 break;
01212 case QUAD_TETRAHEDRON:
01213 aFirstColIds = FirstTetrahedronIds;
01214 aLastColIds = LastTetrahedronIds;
01215 break;
01216 case QUAD_PYRAMID:
01217 aFirstColIds = FirstPyramidIds;
01218 aLastColIds = LastPyramidIds;
01219 break;
01220 case QUAD_PENTAHEDRON:
01221 aFirstColIds = FirstPentahedronIds;
01222 aLastColIds = LastPentahedronIds;
01223 break;
01224 case QUAD_HEXAHEDRON:
01225 aFirstColIds = FirstHexahedronIds;
01226 aLastColIds = LastHexahedronIds;
01227 break;
01228 }
01229
01230
01231 for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
01232 myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
01233
01234 for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
01235 myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
01236 }
01237 else
01238 {
01239
01240 for ( int row = 0; row < myTable->rowCount(); row++ )
01241 for ( int col = 0; col < myTable->columnCount(); col++ )
01242 if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
01243
01244 myTable->setEnabled( false );
01245 }
01246 }
01247
01248
01249
01250
01251
01252
01253 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
01254 {
01255 myIsEditCorners = false;
01256 displaySimulation();
01257 updateButtons();
01258 }
01259
01260
01261
01262
01263
01264
01265 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
01266 {
01267 myIsEditCorners = false;
01268 displaySimulation();
01269 updateButtons();
01270 }
01271
01272
01273
01274
01275
01276 void SMESHGUI_AddQuadraticElementDlg::keyPressEvent( QKeyEvent* e )
01277 {
01278 QDialog::keyPressEvent( e );
01279 if ( e->isAccepted() )
01280 return;
01281
01282 if ( e->key() == Qt::Key_F1 ) {
01283 e->accept();
01284 ClickOnHelp();
01285 }
01286 }
01287
01288 void SMESHGUI_AddQuadraticElementDlg::updateButtons()
01289 {
01290 bool valid = IsValid();
01291 buttonOk->setEnabled( valid );
01292 buttonApply->setEnabled( valid );
01293 }
01294
01295
01296
01297
01298
01299 bool SMESHGUI_AddQuadraticElementDlg::isValid()
01300 {
01301 if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
01302 SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
01303 return false;
01304 }
01305 return true;
01306 }