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 #include "SMESHGUI_SingleEditDlg.h"
00028
00029 #include "SMESHGUI.h"
00030 #include "SMESHGUI_Utils.h"
00031 #include "SMESHGUI_VTKUtils.h"
00032 #include "SMESHGUI_MeshUtils.h"
00033
00034 #include <SMESH_Actor.h>
00035 #include <SMDS_Mesh.hxx>
00036
00037
00038 #include <LightApp_SelectionMgr.h>
00039 #include <LightApp_Application.h>
00040 #include <SUIT_ResourceMgr.h>
00041 #include <SUIT_MessageBox.h>
00042 #include <SUIT_Desktop.h>
00043 #include <SUIT_Session.h>
00044
00045 #include <SVTK_Selector.h>
00046 #include <SVTK_ViewWindow.h>
00047 #include <SALOME_ListIO.hxx>
00048
00049
00050 #include <TColStd_MapOfInteger.hxx>
00051 #include <TColStd_IndexedMapOfInteger.hxx>
00052
00053
00054 #include <QVBoxLayout>
00055 #include <QHBoxLayout>
00056 #include <QLineEdit>
00057 #include <QPushButton>
00058 #include <QGroupBox>
00059 #include <QLabel>
00060 #include <QValidator>
00061 #include <QKeyEvent>
00062
00063 #define SPACING 6
00064 #define MARGIN 11
00065
00072 class BusyLocker
00073 {
00074 public:
00076 BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
00078 ~BusyLocker() { myBusy = false; }
00079 private:
00080 bool& myBusy;
00081 };
00082
00089
00090
00091
00092
00093 SMESHGUI_SingleEditDlg
00094 ::SMESHGUI_SingleEditDlg(SMESHGUI* theModule)
00095 : QDialog(SMESH::GetDesktop(theModule)),
00096 mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
00097 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
00098 mySMESHGUI(theModule)
00099 {
00100 setModal(false);
00101
00102 QVBoxLayout* aDlgLay = new QVBoxLayout(this);
00103 aDlgLay->setMargin(MARGIN);
00104 aDlgLay->setSpacing(SPACING);
00105
00106 QWidget* aMainFrame = createMainFrame (this);
00107 QWidget* aBtnFrame = createButtonFrame(this);
00108
00109 aDlgLay->addWidget(aMainFrame);
00110 aDlgLay->addWidget(aBtnFrame);
00111
00112 Init();
00113 }
00114
00115
00116
00117
00118
00119 QWidget* SMESHGUI_SingleEditDlg::createMainFrame (QWidget* theParent)
00120 {
00121 QGroupBox* aMainGrp = new QGroupBox(tr("EDGE_BETWEEN"), theParent);
00122 QHBoxLayout* aLay = new QHBoxLayout(aMainGrp);
00123 aLay->setMargin(MARGIN);
00124 aLay->setSpacing(SPACING);
00125
00126 QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
00127
00128 QLabel* aLab = new QLabel(tr("SMESH_EDGE"), aMainGrp);
00129 QPushButton* aBtn = new QPushButton(aMainGrp);
00130 aBtn->setIcon(aPix);
00131 myEdge = new QLineEdit(aMainGrp);
00132 myEdge->setValidator(new QRegExpValidator(QRegExp("[\\d]*-[\\d]*"), this));
00133
00134 aLay->addWidget(aLab);
00135 aLay->addWidget(aBtn);
00136 aLay->addWidget(myEdge);
00137
00138 return aMainGrp;
00139 }
00140
00141
00142
00143
00144
00145 QWidget* SMESHGUI_SingleEditDlg::createButtonFrame (QWidget* theParent)
00146 {
00147 QGroupBox* aFrame = new QGroupBox(theParent);
00148
00149 myOkBtn = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aFrame);
00150 myApplyBtn = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
00151 myCloseBtn = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
00152 myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), aFrame);
00153
00154 QHBoxLayout* aLay = new QHBoxLayout(aFrame);
00155 aLay->setMargin(MARGIN);
00156 aLay->setSpacing(SPACING);
00157
00158 aLay->addWidget(myOkBtn);
00159 aLay->addSpacing(10);
00160 aLay->addWidget(myApplyBtn);
00161 aLay->addSpacing(10);
00162 aLay->addStretch();
00163 aLay->addWidget(myCloseBtn);
00164 aLay->addWidget(myHelpBtn);
00165
00166 return aFrame;
00167 }
00168
00169
00170
00171
00172
00173 bool SMESHGUI_SingleEditDlg::isValid (const bool theMess) const
00174 {
00175 int id1, id2;
00176 return getNodeIds(myEdge->text(), id1, id2);
00177 }
00178
00179
00180
00181
00182
00183 bool SMESHGUI_SingleEditDlg::getNodeIds (const QString& theStr,
00184 int& theId1, int& theId2) const
00185 {
00186 if (!theStr.contains('-'))
00187 return false;
00188
00189 bool ok1, ok2;
00190 QString str1 = theStr.section('-', 0, 0, QString::SectionSkipEmpty);
00191 QString str2 = theStr.section('-', 1, 1, QString::SectionSkipEmpty);
00192 theId1 = str1.toInt(&ok1);
00193 theId2 = str2.toInt(&ok2);
00194
00195 return ok1 & ok2;
00196 }
00197
00198
00199
00200
00201
00202 SMESHGUI_SingleEditDlg::~SMESHGUI_SingleEditDlg()
00203 {
00204 }
00205
00206
00207
00208
00209
00210 void SMESHGUI_SingleEditDlg::Init()
00211 {
00212 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
00213 myBusy = false;
00214 myActor = 0;
00215
00216
00217 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
00218 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
00219 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
00220 connect(myHelpBtn, SIGNAL(clicked()), SLOT(onHelp()));
00221
00222
00223 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
00224 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
00225 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
00226 connect(myEdge, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
00227
00228 myOkBtn->setEnabled(false);
00229 myApplyBtn->setEnabled(false);
00230 setEnabled(true);
00231
00232
00233 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00234 aViewWindow->SetSelectionMode(EdgeOfCellSelection);
00235
00236 onSelectionDone();
00237 }
00238
00239
00240
00241
00242
00243
00244 void SMESHGUI_SingleEditDlg::onOk()
00245 {
00246 if (onApply())
00247 onClose();
00248 }
00249
00250
00251
00252
00253
00254 void SMESHGUI_SingleEditDlg::onClose()
00255 {
00256 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00257 aViewWindow->SetSelectionMode(ActorSelection);
00258
00259 disconnect(mySelectionMgr, 0, this, 0);
00260 disconnect(mySMESHGUI, 0, this, 0);
00261 mySMESHGUI->ResetState();
00262 reject();
00263 }
00264
00265
00266
00267
00268
00269 void SMESHGUI_SingleEditDlg::onHelp()
00270 {
00271 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
00272 if (app)
00273 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
00274 else {
00275 QString platform;
00276 #ifdef WIN32
00277 platform = "winapplication";
00278 #else
00279 platform = "application";
00280 #endif
00281 SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
00282 tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
00283 arg(app->resourceMgr()->stringValue("ExternalBrowser",
00284 platform)).
00285 arg(myHelpFileName));
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 static bool findTriangles (const SMDS_MeshNode * theNode1,
00296 const SMDS_MeshNode * theNode2,
00297 const SMDS_MeshElement*& theTria1,
00298 const SMDS_MeshElement*& theTria2)
00299 {
00300 if (!theNode1 || !theNode2) return false;
00301
00302 theTria1 = theTria2 = 0;
00303
00304 std::set< const SMDS_MeshElement* > emap;
00305 SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator();
00306 while (it->more()) {
00307 const SMDS_MeshElement* elem = it->next();
00308 if (elem->GetType() == SMDSAbs_Face && elem->NbNodes() == 3)
00309 emap.insert(elem);
00310 }
00311 it = theNode2->GetInverseElementIterator();
00312 while (it->more()) {
00313 const SMDS_MeshElement* elem = it->next();
00314 if (elem->GetType() == SMDSAbs_Face &&
00315 emap.find(elem) != emap.end())
00316 {
00317 if (theTria1) {
00318 theTria2 = elem;
00319 break;
00320 } else {
00321 theTria1 = elem;
00322 }
00323 }
00324 }
00325 return (theTria1 && theTria2);
00326 }
00327
00328
00329
00330
00331
00332 void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
00333 {
00334 if (myBusy) return;
00335 BusyLocker lock(myBusy);
00336
00337 myOkBtn->setEnabled(false);
00338 myApplyBtn->setEnabled(false);
00339
00340
00341 if(myActor){
00342 if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
00343 Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
00344 SALOME_ListIO aList;
00345 aList.Append(anIO);
00346 mySelectionMgr->setSelectedObjects(aList,false);
00347
00348 TColStd_IndexedMapOfInteger selectedIndices;
00349 TColStd_MapOfInteger newIndices;
00350 mySelector->GetIndex(anIO,selectedIndices);
00351
00352 int id1, id2;
00353 if ( !getNodeIds(myEdge->text(), id1, id2) )
00354 return;
00355
00356 const SMDS_MeshNode* aNode1 = aMesh->FindNode( id1 );
00357 const SMDS_MeshNode* aNode2 = aMesh->FindNode( id2 );
00358
00359 if ( !aNode1 || !aNode2 || aNode1 == aNode2 )
00360 return;
00361
00362
00363 const SMDS_MeshElement* tria1;
00364 const SMDS_MeshElement* tria2;
00365
00366 if ( findTriangles(aNode1,aNode2,tria1,tria2) )
00367 {
00368 newIndices.Add(tria1->GetID());
00369
00370 const SMDS_MeshNode* a3Nodes[3];
00371 SMDS_ElemIteratorPtr it;
00372 int edgeInd = 2, i;
00373 for (i = 0, it = tria1->nodesIterator(); it->more(); i++) {
00374 a3Nodes[ i ] = static_cast<const SMDS_MeshNode*>(it->next());
00375 if (i > 0 && ( (a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2) ||
00376 (a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1) ) ) {
00377 edgeInd = i - 1;
00378 break;
00379 }
00380 }
00381 newIndices.Add(-edgeInd-1);
00382
00383 myOkBtn->setEnabled(true);
00384 myApplyBtn->setEnabled(true);
00385 }
00386 mySelector->AddOrRemoveIndex(anIO,newIndices, false);
00387 SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true );
00388 }
00389 }
00390 }
00391
00392
00393
00394
00395
00396 void SMESHGUI_SingleEditDlg::onSelectionDone()
00397 {
00398 if (myBusy) return;
00399 BusyLocker lock(myBusy);
00400
00401 int anId1 = 0, anId2 = 0;
00402
00403 myOkBtn->setEnabled(false);
00404 myApplyBtn->setEnabled(false);
00405
00406 SALOME_ListIO aList;
00407 mySelectionMgr->selectedObjects(aList);
00408
00409 if (aList.Extent() != 1) {
00410 myEdge->clear();
00411 return;
00412 }
00413
00414 Handle(SALOME_InteractiveObject) anIO = aList.First();
00415 myActor = SMESH::FindActorByEntry(anIO->getEntry());
00416 if(myActor){
00417 TVisualObjPtr aVisualObj = myActor->GetObject();
00418 if(SMDS_Mesh* aMesh = aVisualObj->GetMesh())
00419 {
00420 const SMDS_MeshElement* tria[2];
00421 if( SMESH::GetEdgeNodes( mySelector, aVisualObj, anId1, anId2 ) >= 1 &&
00422 findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) )
00423 {
00424 QString aText = QString("%1-%2").arg(anId1).arg(anId2);
00425 myEdge->setText(aText);
00426
00427 myOkBtn->setEnabled(true);
00428 myApplyBtn->setEnabled(true);
00429 }
00430 else
00431 {
00432 myEdge->clear();
00433 }
00434 }
00435 }
00436 }
00437
00438
00439
00440
00441
00442 void SMESHGUI_SingleEditDlg::onDeactivate()
00443 {
00444 setEnabled(false);
00445 }
00446
00447
00448
00449
00450
00451 void SMESHGUI_SingleEditDlg::enterEvent (QEvent*)
00452 {
00453 if (!isEnabled()) {
00454 mySMESHGUI->EmitSignalDeactivateDialog();
00455 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
00456 aViewWindow->SetSelectionMode(EdgeOfCellSelection);
00457 setEnabled(true);
00458 }
00459 }
00460
00461
00462
00463
00464
00465 void SMESHGUI_SingleEditDlg::closeEvent (QCloseEvent*)
00466 {
00467 onClose();
00468 }
00469
00470
00471
00472
00473
00474 void SMESHGUI_SingleEditDlg::hideEvent (QHideEvent*)
00475 {
00476 if (!isMinimized())
00477 onClose();
00478 }
00479
00480
00481
00482
00483
00484 bool SMESHGUI_SingleEditDlg::onApply()
00485 {
00486 if (mySMESHGUI->isActiveStudyLocked())
00487 return false;
00488
00489 if (!isValid(true))
00490 return false;
00491
00492
00493 SALOME_ListIO aList;
00494 mySelectionMgr->selectedObjects(aList);
00495
00496 SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(aList.First());
00497
00498 if (aMesh->_is_nil()) {
00499 SUIT_MessageBox::information(SMESH::GetDesktop(mySMESHGUI),
00500 tr("SMESH_ERROR"),
00501 tr("SMESHG_NO_MESH"));
00502 return false;
00503 }
00504
00505 SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
00506 int anId1= 0, anId2 = 0;
00507 if (aMeshEditor->_is_nil() || !getNodeIds(myEdge->text(), anId1, anId2))
00508 return false;
00509
00510
00511 bool aResult = process(aMeshEditor.in(), anId1, anId2);
00512
00513
00514 if (aResult) {
00515 mySelector->ClearIndex();
00516 mySelectionMgr->setSelectedObjects(aList, false);
00517 onSelectionDone();
00518 SMESH::UpdateView();
00519 SMESHGUI::Modified();
00520 }
00521
00522 return aResult;
00523 }
00524
00525
00526
00527
00528
00529 void SMESHGUI_SingleEditDlg::keyPressEvent( QKeyEvent* e )
00530 {
00531 QDialog::keyPressEvent( e );
00532 if ( e->isAccepted() )
00533 return;
00534
00535 if ( e->key() == Qt::Key_F1 ) {
00536 e->accept();
00537 onHelp();
00538 }
00539 }
00540
00547 SMESHGUI_TrianglesInversionDlg
00548 ::SMESHGUI_TrianglesInversionDlg(SMESHGUI* theModule)
00549 : SMESHGUI_SingleEditDlg(theModule)
00550 {
00551 setWindowTitle(tr("CAPTION"));
00552 myHelpFileName = "diagonal_inversion_of_elements_page.html";
00553 }
00554
00555 SMESHGUI_TrianglesInversionDlg::~SMESHGUI_TrianglesInversionDlg()
00556 {
00557 }
00558
00559 bool SMESHGUI_TrianglesInversionDlg::process (SMESH::SMESH_MeshEditor_ptr theMeshEditor,
00560 const int theId1, const int theId2)
00561 {
00562 return theMeshEditor->InverseDiag(theId1, theId2);
00563 }
00564
00571 SMESHGUI_UnionOfTwoTrianglesDlg
00572 ::SMESHGUI_UnionOfTwoTrianglesDlg(SMESHGUI* theModule)
00573 : SMESHGUI_SingleEditDlg(theModule)
00574 {
00575 setWindowTitle(tr("CAPTION"));
00576 myHelpFileName = "uniting_two_triangles_page.html";
00577 }
00578
00579 SMESHGUI_UnionOfTwoTrianglesDlg::~SMESHGUI_UnionOfTwoTrianglesDlg()
00580 {
00581 }
00582
00583 bool SMESHGUI_UnionOfTwoTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theMeshEditor,
00584 const int theId1, const int theId2)
00585 {
00586 return theMeshEditor->DeleteDiag(theId1, theId2);
00587 }