X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_ComputeDlg.cxx;h=ccac8521a491fc77379083ce07e9c8819f0e220e;hb=01e646e9da75d2314a14c94b14c1130c1a374117;hp=6d7036a6336cdf48c807e0a754c61eff750ce5cb;hpb=a16c5a0b794f2d14d97fe6d3cd7c300fd58019a7;p=modules%2Fsmesh.git diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 6d7036a63..ccac8521a 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -29,6 +29,8 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_HypothesesUtils.h" +#include "SMESHGUI_MeshEditPreview.h" +#include "SMESH_ActorUtils.h" #include #include @@ -48,8 +50,10 @@ #include #include #include +#include // SALOME KERNEL includes +#include #include // OCCT includes @@ -82,10 +86,6 @@ // VTK includes #include -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Gen) - // STL includes #include #include @@ -107,7 +107,9 @@ static void addSeparator( QWidget* parent ) } } -enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, NB_COLUMNS }; +enum TCol { + COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS +}; //using namespace SMESH; @@ -125,7 +127,8 @@ namespace SMESH { char* myBuf; MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M - ~MemoryReserve() { delete [] myBuf; } + void release() { delete [] myBuf; myBuf = 0; } + ~MemoryReserve() { release(); } }; // ========================================================================================= @@ -266,8 +269,8 @@ namespace SMESH if ( !actor ) { actor = GEOM_Actor::New(); if ( actor ) { - actor->setInputShape(shape,0,0); - //actor->SetProperty(myProperty); + actor->SetShape(shape,0,0); + actor->SetProperty(myProperty); actor->SetShadingProperty(myProperty); actor->SetWireframeProperty(myProperty); actor->SetPreviewProperty(myProperty); @@ -429,7 +432,7 @@ namespace SMESH /*! * \brief Return a list of selected rows */ - bool getSelectedRows(QTableWidget* table, QList& rows) + int getSelectedRows(QTableWidget* table, QList& rows) { rows.clear(); QList selRanges = table->selectedRanges(); @@ -442,7 +445,7 @@ namespace SMESH if ( rows.isEmpty() && table->currentRow() > -1 ) rows.append( table->currentRow() ); - return !rows.isEmpty(); + return rows.count(); } } // namespace SMESH @@ -785,7 +788,8 @@ void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh) */ //======================================================================= -SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, OK/* | Help*/ ) +SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent ) + : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ ) { QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); aDlgLay->setMargin( 0 ); @@ -798,6 +802,16 @@ SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, OK/ aDlgLay->setStretchFactor(aMainFrame, 1); } +// ========================================================================================= +/*! + * \brief Destructor + */ +//======================================================================= + +SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg() +{ +} + //======================================================================= // function : createMainFrame() // purpose : Create frame containing dialog's fields @@ -842,11 +856,13 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) myTable = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup); myShowBtn = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup); myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup); + myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup); //myTable->setReadOnly( true ); // VSR: check myTable->setEditTriggers( QAbstractItemView::NoEditTriggers ); myTable->hideColumn( COL_PUBLISHED ); myTable->hideColumn( COL_SHAPEID ); + myTable->hideColumn( COL_BAD_MESH ); myTable->horizontalHeader()->setResizeMode( COL_ERROR, QHeaderView::Interactive ); QStringList headers; @@ -862,10 +878,11 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup); grpLayout->setSpacing(SPACING); grpLayout->setMargin(MARGIN); - grpLayout->addWidget( myTable, 0, 0, 3, 1 ); + grpLayout->addWidget( myTable, 0, 0, 4, 1 ); grpLayout->addWidget( myShowBtn, 0, 1 ); grpLayout->addWidget( myPublishBtn, 1, 1 ); - grpLayout->setRowStretch( 2, 1 ); + grpLayout->addWidget( myBadMeshBtn, 2, 1 ); + grpLayout->setRowStretch( 3, 1 ); // Hypothesis definition errors @@ -912,34 +929,33 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) */ //================================================================================ -SMESHGUI_ComputeOp::SMESHGUI_ComputeOp() +SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp() + : SMESHGUI_Operation(), + myCompDlg( 0 ) { - myDlg = new SMESHGUI_ComputeDlg; myTShapeDisplayer = new SMESH::TShapeDisplayer(); + myBadMeshDisplayer = 0; + //myHelpFileName = "/files/about_meshes.htm"; // V3 myHelpFileName = "about_meshes_page.html"; // V4 - - // connect signals and slots - connect(myDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape())); - connect(myDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape())); - connect(table(), SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged())); - connect(table(), SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged())); } -//======================================================================= -// function : startOperation() -// purpose : Init dialog fields, connect signals and slots, show dialog -//======================================================================= +//================================================================================ +/*! + * \brief Start operation + * \purpose Init dialog fields, connect signals and slots, show dialog + */ +//================================================================================ -void SMESHGUI_ComputeOp::startOperation() +void SMESHGUI_BaseComputeOp::startOperation() { - SMESHGUI_Operation::startOperation(); - - // check selection + // create compute dialog if not created before + computeDlg(); - SMESH::SMESH_Mesh_var aMesh; + myMesh = SMESH::SMESH_Mesh::_nil(); myMainShape = GEOM::GEOM_Object::_nil(); + // check selection LightApp_SelectionMgr *Sel = selectionMgr(); SALOME_ListIO selected; Sel->selectedObjects( selected ); @@ -952,16 +968,28 @@ void SMESHGUI_ComputeOp::startOperation() return; } - Handle(SALOME_InteractiveObject) IObject = selected.First(); - aMesh = SMESH::GetMeshByIO(IObject); - if (aMesh->_is_nil()) { + myIObject = selected.First(); + myMesh = SMESH::GetMeshByIO(myIObject); + if (myMesh->_is_nil()) { SUIT_MessageBox::warning(desktop(), tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_NO_AVAILABLE_DATA")); onCancel(); - return; + } + myMainShape = myMesh->GetShapeToMesh(); + SMESHGUI_Operation::startOperation(); +} + +//================================================================================ +/*! + * \brief computeMesh() +*/ +//================================================================================ + +void SMESHGUI_BaseComputeOp::computeMesh() +{ // COMPUTE MESH SMESH::MemoryReserve aMemoryReserve; @@ -971,15 +999,14 @@ void SMESHGUI_ComputeOp::startOperation() bool computeFailed = true, memoryLack = false; - _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh); - myMainShape = aMesh->GetShapeToMesh(); - bool hasShape = aMesh->HasShapeToMesh(); + _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); + bool hasShape = myMesh->HasShapeToMesh(); bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; if ( shapeOK && aMeshSObj ) { - myDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); + myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); - SMESH::algo_error_array_var errors = gen->GetAlgoState(aMesh,myMainShape); + SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape); if ( errors->length() > 0 ) { aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); } @@ -988,7 +1015,7 @@ void SMESHGUI_ComputeOp::startOperation() #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - if (gen->Compute(aMesh, myMainShape)) + if (gen->Compute(myMesh, myMainShape)) computeFailed = false; } catch(const SALOME::SALOME_Exception & S_ex){ @@ -998,7 +1025,7 @@ void SMESHGUI_ComputeOp::startOperation() #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - aCompErrors = gen->GetComputeErrors( aMesh, myMainShape ); + aCompErrors = gen->GetComputeErrors( myMesh, myMainShape ); // check if there are memory problems for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i ) memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB ); @@ -1009,7 +1036,7 @@ void SMESHGUI_ComputeOp::startOperation() // NPAL16631: if ( !memoryLack ) { - SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0); + SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0); update( UF_ObjBrowser | UF_Model ); // SHOW MESH @@ -1020,11 +1047,11 @@ void SMESHGUI_ComputeOp::startOperation() #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - SMESH::Update(IObject, true); + SMESH::Update(myIObject, true); } catch (...) { #ifdef _DEBUG_ - cout << "Exception thrown during mesh visualization" << endl; + MESSAGE ( "Exception thrown during mesh visualization" ); #endif if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? SMESH::OnVisuException(); @@ -1034,72 +1061,119 @@ void SMESHGUI_ComputeOp::startOperation() } } } - Sel->setSelectedObjects( selected ); + LightApp_SelectionMgr *Sel = selectionMgr(); + if ( Sel ) + { + SALOME_ListIO selected; + selected.Append( myIObject ); + Sel->setSelectedObjects( selected ); + } } } - myDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED")); - myDlg->myMemoryLackGroup->hide(); - // SHOW ERRORS + if ( memoryLack ) + aMemoryReserve.release(); + myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED")); + + // SHOW ERRORS + bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 ); bool noHypoError = ( aHypErrors.isEmpty() ); - if ( memoryLack ) + SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() ); + int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" ); + + bool isShowResultDlg = true; + switch( aNotifyMode ) { + case 0: // show the mesh computation result dialog NEVER + isShowResultDlg = false; + commit(); + break; + case 1: // show the mesh computation result dialog if there are some errors + if ( memoryLack || !noCompError || !noHypoError ) + isShowResultDlg = true; + else + { + isShowResultDlg = false; + commit(); + } + break; + default: // show the result dialog after each mesh computation + isShowResultDlg = true; + } + + // SHOW RESULTS + if ( isShowResultDlg ) + showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors ); +} + +void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, + const bool theNoCompError, + SMESH::compute_error_array_var& theCompErrors, + const bool theNoHypoError, + const QString& theHypErrors ) +{ + bool hasShape = myMesh->HasShapeToMesh(); + SMESHGUI_ComputeDlg* aCompDlg = computeDlg(); + aCompDlg->myMemoryLackGroup->hide(); + + if ( theMemoryLack ) { - myDlg->myMemoryLackGroup->show(); - myDlg->myFullInfo->hide(); - myDlg->myBriefInfo->hide(); - myDlg->myHypErrorGroup->hide(); - myDlg->myCompErrorGroup->hide(); + aCompDlg->myMemoryLackGroup->show(); + aCompDlg->myFullInfo->hide(); + aCompDlg->myBriefInfo->hide(); + aCompDlg->myHypErrorGroup->hide(); + aCompDlg->myCompErrorGroup->hide(); } - else if ( noCompError && noHypoError ) + else if ( theNoCompError && theNoHypoError ) { - myDlg->myFullInfo->SetInfoByMesh( aMesh ); - myDlg->myFullInfo->show(); - myDlg->myBriefInfo->hide(); - myDlg->myHypErrorGroup->hide(); - myDlg->myCompErrorGroup->hide(); + aCompDlg->myFullInfo->SetInfoByMesh( myMesh ); + aCompDlg->myFullInfo->show(); + aCompDlg->myBriefInfo->hide(); + aCompDlg->myHypErrorGroup->hide(); + aCompDlg->myCompErrorGroup->hide(); } else { - QTableWidget* tbl = myDlg->myTable; - myDlg->myBriefInfo->SetInfoByMesh( aMesh ); - myDlg->myBriefInfo->show(); - myDlg->myFullInfo->hide(); + QTableWidget* tbl = aCompDlg->myTable; + aCompDlg->myBriefInfo->SetInfoByMesh( myMesh ); + aCompDlg->myBriefInfo->show(); + aCompDlg->myFullInfo->hide(); - if ( noHypoError ) { - myDlg->myHypErrorGroup->hide(); + if ( theNoHypoError ) { + aCompDlg->myHypErrorGroup->hide(); } else { - myDlg->myHypErrorGroup->show(); - myDlg->myHypErrorLabel->setText( aHypErrors ); + aCompDlg->myHypErrorGroup->show(); + aCompDlg->myHypErrorLabel->setText( theHypErrors ); } - if ( noCompError ) { - myDlg->myCompErrorGroup->hide(); + if ( theNoCompError ) { + aCompDlg->myCompErrorGroup->hide(); } else { - myDlg->myCompErrorGroup->show(); + aCompDlg->myCompErrorGroup->show(); if ( !hasShape ) { - myDlg->myPublishBtn->hide(); - myDlg->myShowBtn->hide(); + aCompDlg->myPublishBtn->hide(); + aCompDlg->myShowBtn->hide(); } else { - myDlg->myPublishBtn->show(); - myDlg->myShowBtn->show(); + aCompDlg->myPublishBtn->show(); + aCompDlg->myShowBtn->show(); } // fill table of errors - tbl->setRowCount( aCompErrors->length() ); + tbl->setRowCount( theCompErrors->length() ); if ( !hasShape ) tbl->hideColumn( COL_SHAPE ); else tbl->showColumn( COL_SHAPE ); tbl->setColumnWidth( COL_ERROR, 200 ); - for ( int row = 0; row < aCompErrors->length(); ++row ) + bool hasBadMesh = false; + for ( int row = 0; row < theCompErrors->length(); ++row ) { - SMESH::ComputeError & err = aCompErrors[ row ]; + SMESH::ComputeError & err = theCompErrors[ row ]; QString text = err.algoName.in(); if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) ); @@ -1121,17 +1195,28 @@ void SMESHGUI_ComputeOp::startOperation() if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) ); else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled + text = err.hasBadMesh ? "hasBadMesh" : ""; + if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_BAD_MESH )->setText( text ); + if ( err.hasBadMesh ) hasBadMesh = true; + //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ??? tbl->resizeRowToContents( row ); } tbl->resizeColumnToContents( COL_ALGO ); tbl->resizeColumnToContents( COL_SHAPE ); + if ( hasBadMesh ) + aCompDlg->myBadMeshBtn->show(); + else + aCompDlg->myBadMeshBtn->hide(); + tbl->setCurrentCell(0,0); currentCellChanged(); // to update buttons } } - myDlg->show(); + // show dialog and wait, becase Compute can be invoked from Preview operation + aCompDlg->exec(); } //================================================================================ @@ -1140,10 +1225,19 @@ void SMESHGUI_ComputeOp::startOperation() */ //================================================================================ -void SMESHGUI_ComputeOp::stopOperation() +void SMESHGUI_BaseComputeOp::stopOperation() { SMESHGUI_Operation::stopOperation(); - myTShapeDisplayer->SetVisibility( false ); + if ( myTShapeDisplayer ) + myTShapeDisplayer->SetVisibility( false ); + if ( myBadMeshDisplayer ) { + myBadMeshDisplayer->SetVisibility( false ); + // delete it in order not to have problems at its destruction when the viewer + // where it worked is dead due to e.g. study closing + delete myBadMeshDisplayer; + myBadMeshDisplayer = 0; + } + myIObject.Nullify(); } //================================================================================ @@ -1152,7 +1246,7 @@ void SMESHGUI_ComputeOp::stopOperation() */ //================================================================================ -void SMESHGUI_ComputeOp::onPublishShape() +void SMESHGUI_BaseComputeOp::onPublishShape() { GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen(); SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy(); @@ -1195,19 +1289,54 @@ void SMESHGUI_ComputeOp::onPublishShape() currentCellChanged(); // to update buttons } +//================================================================================ +/*! + * \brief show mesh elements preventing computation of a submesh of current row + */ +//================================================================================ + +void SMESHGUI_BaseComputeOp::onShowBadMesh() +{ + myTShapeDisplayer->SetVisibility( false ); + QList rows; + if ( SMESH::getSelectedRows( table(), rows ) == 1 ) { + bool hasBadMesh = ( !table()->item(rows.front(), COL_BAD_MESH)->text().isEmpty() ); + if ( hasBadMesh ) { + int curSub = table()->item(rows.front(), COL_SHAPEID)->text().toInt(); + SMESHGUI* gui = getSMESHGUI(); + SMESH::SMESH_Gen_var gen = gui->GetSMESHGen(); + SVTK_ViewWindow* view = SMESH::GetViewWindow( gui ); + if ( myBadMeshDisplayer ) delete myBadMeshDisplayer; + myBadMeshDisplayer = new SMESHGUI_MeshEditPreview( view ); + SMESH::MeshPreviewStruct_var aMeshData = gen->GetBadInputElements(myMesh,curSub); + vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3); + vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1); + // delete property !!!!!!!!!! + vtkProperty* prop = vtkProperty::New(); + prop->SetLineWidth( aLineWidth * 3 ); + prop->SetPointSize( aPointSize * 3 ); + prop->SetColor( 250, 0, 250 ); + myBadMeshDisplayer->GetActor()->SetProperty( prop ); + myBadMeshDisplayer->SetData( aMeshData._retn() ); + } + } +} + //================================================================================ /*! * \brief SLOT called when a selected cell in table() changed */ //================================================================================ -void SMESHGUI_ComputeOp::currentCellChanged() +void SMESHGUI_BaseComputeOp::currentCellChanged() { myTShapeDisplayer->SetVisibility( false ); + if ( myBadMeshDisplayer ) + myBadMeshDisplayer->SetVisibility( false ); - bool publishEnable = 0, showEnable = 0, showOnly = 1; + bool publishEnable = 0, showEnable = 0, showOnly = 1, hasBadMesh = 0; QList rows; - SMESH::getSelectedRows( table(), rows ); + int nbSelected = SMESH::getSelectedRows( table(), rows ); int row; foreach ( row, rows ) { @@ -1225,9 +1354,13 @@ void SMESHGUI_ComputeOp::currentCellChanged() else { showEnable = true; } + + if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() ) + hasBadMesh = true; } - myDlg->myPublishBtn->setEnabled( publishEnable ); - myDlg->myShowBtn->setEnabled( showEnable ); + myCompDlg->myPublishBtn->setEnabled( publishEnable ); + myCompDlg->myShowBtn ->setEnabled( showEnable ); + myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 )); } //================================================================================ @@ -1236,7 +1369,7 @@ void SMESHGUI_ComputeOp::currentCellChanged() */ //================================================================================ -void SMESHGUI_ComputeOp::onPreviewShape() +void SMESHGUI_BaseComputeOp::onPreviewShape() { if ( myTShapeDisplayer ) { @@ -1264,9 +1397,95 @@ void SMESHGUI_ComputeOp::onPreviewShape() */ //================================================================================ +SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp() +{ + delete myCompDlg; + myCompDlg = 0; + delete myTShapeDisplayer; + if ( myBadMeshDisplayer ) + delete myBadMeshDisplayer; +} + +//================================================================================ +/*! + * \brief Gets dialog of compute operation + * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation + */ +//================================================================================ + +SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const +{ + if ( !myCompDlg ) + { + SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this; + me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() ); + // connect signals and slots + connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape())); + connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape())); + connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh())); + + QTableWidget* aTable = me->table(); + connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged())); + connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged())); + } + return myCompDlg; +} + +//================================================================================ +/*! + * \brief Return a table + */ +//================================================================================ + +QTableWidget* SMESHGUI_BaseComputeOp::table() +{ + return myCompDlg->myTable; +} + + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_ComputeOp::SMESHGUI_ComputeOp() + : SMESHGUI_BaseComputeOp() +{ +} + + +//================================================================================ +/*! + * \brief Desctructor +*/ +//================================================================================ + SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp() { - if ( myTShapeDisplayer ) delete myTShapeDisplayer; +} + +//================================================================================ +/*! + * \brief perform it's intention action: compute mesh + */ +//================================================================================ + +void SMESHGUI_ComputeOp::startOperation() +{ + SMESHGUI_BaseComputeOp::startOperation(); + computeMesh(); +} + +//================================================================================ +/*! + * \brief perform it's intention action: compute mesh + */ +//================================================================================ + +bool SMESHGUI_ComputeOp::onApply() +{ + return true; } //================================================================================ @@ -1278,27 +1497,415 @@ SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp() LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const { - return myDlg; + return computeDlg(); } //================================================================================ /*! - * \brief perform it's intention action: compute mesh + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp() + : SMESHGUI_BaseComputeOp(), + myDlg( 0 ), + myActiveDlg( 0 ), + myPreviewDisplayer( 0 ) +{ + myHelpFileName = "preview_meshes_page.html"; // V4 +} + +//================================================================================ +/*! + * \brief Destructor */ //================================================================================ -bool SMESHGUI_ComputeOp::onApply() +SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp() +{ + delete myDlg; + myDlg = 0; + myActiveDlg = 0; + if ( myPreviewDisplayer ) + delete myPreviewDisplayer; + myPreviewDisplayer = 0; +} + +//================================================================================ +/*! + * \brief Gets current dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const +{ + return myActiveDlg; +} + +//================================================================================ +/*! + * \brief perform it's intention action: prepare data + */ +//================================================================================ + +void SMESHGUI_PrecomputeOp::startOperation() +{ + if ( !myDlg ) + { + myDlg = new SMESHGUI_PrecomputeDlg( desktop() ); + + // connect signals + connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) ); + } + myActiveDlg = myDlg; + + // connect signal to compute dialog. which will be shown after Compute mesh operation + SMESHGUI_ComputeDlg* cmpDlg = computeDlg(); + if ( cmpDlg ) + { + // disconnect signals + disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) ); + disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) ); + disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) ); + disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) ); + disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) ); + + // connect signals + if( cmpDlg->testButtonFlags( QtxDialog::OK ) ) + connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) ); + if( cmpDlg->testButtonFlags( QtxDialog::Apply ) ) + connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) ); + if( cmpDlg->testButtonFlags( QtxDialog::Help ) ) + connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) ); + if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) ) + connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) ); + if( cmpDlg->testButtonFlags( QtxDialog::Close ) ) + connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) ); + } + + SMESHGUI_BaseComputeOp::startOperation(); + + myDlg->show(); +} + +//================================================================================ +/*! + * \brief Stops operation + */ +//================================================================================ + +void SMESHGUI_PrecomputeOp::stopOperation() +{ + if ( myPreviewDisplayer ) + { + myPreviewDisplayer->SetVisibility( false ); + delete myPreviewDisplayer; + myPreviewDisplayer = 0; + } + myMapShapeId.clear(); + SMESHGUI_BaseComputeOp::stopOperation(); +} + +//================================================================================ +/*! + * \brief perform it's intention action: reinitialise dialog + */ +//================================================================================ + +void SMESHGUI_PrecomputeOp::resumeOperation() +{ + if ( myActiveDlg == myDlg ) + initDialog(); + SMESHGUI_BaseComputeOp::resumeOperation(); +} + +void SMESHGUI_PrecomputeOp::initDialog() +{ + QList modes; + QMap modeMap; + _PTR(SObject) aHypRoot; + _PTR(GenericAttribute) anAttr; + int aPart = SMESH::Tag_RefOnAppliedAlgorithms; + + _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() ); + if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) ) + { + _PTR(ChildIterator) anIter = + SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot ); + for ( ; anIter->More(); anIter->Next() ) + { + _PTR(SObject) anObj = anIter->Value(); + _PTR(SObject) aRefObj; + if ( anObj->ReferencedObject( aRefObj ) ) + anObj = aRefObj; + else + continue; + + if ( anObj->FindAttribute( anAttr, "AttributeName" ) ) + { + CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject(); + if ( CORBA::is_nil( aVar ) ) + continue; + + SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); + if ( !algo->_is_nil() ) + { + modeMap[ SMESH::DIM_1D ] = 0; + modeMap[ SMESH::DIM_2D ] = 0; + } + else + { + algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); + if ( !algo->_is_nil() ) + modeMap[ SMESH::DIM_2D ] = 0; + } + } + } + } + if ( modeMap.contains( SMESH::DIM_1D ) ) + modes.append( SMESH::DIM_1D ); + if ( modeMap.contains( SMESH::DIM_2D ) ) + modes.append( SMESH::DIM_2D ); + + myDlg->setPreviewModes( modes ); +} + +//================================================================================ +/*! + * \brief perform it's intention action: + */ +//================================================================================ + +bool SMESHGUI_PrecomputeOp::onApply() { + QObject* obj = sender(); + if ( obj != myDlg && myActiveDlg == myDlg ) + return true; // just return from error messages + if ( myActiveDlg == myDlg ) + { + myDlg->hide(); + myMapShapeId.clear(); + myActiveDlg = computeDlg(); + computeMesh(); + } + return true; } //================================================================================ /*! - * \brief Return a table + * \brief perform it's intention action: compute mesh */ //================================================================================ -QTableWidget* SMESHGUI_ComputeOp::table() +void SMESHGUI_PrecomputeOp::onCancel() +{ + QObject* curDlg = sender(); + if ( curDlg == computeDlg() ) + { + if ( myActiveDlg == myDlg ) // return from error messages + myDlg->show(); + + return; + } + + if ( myActiveDlg == myDlg && !myMesh->_is_nil() && myMapShapeId.count() ) + { + // ask to remove already computed mesh elements + if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ), + tr( "CLEAR_SUBMESH_QUESTION" ), + tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 ) + { + // remove all submeshes for collected shapes + QMap::const_iterator it = myMapShapeId.constBegin(); + for ( ; it != myMapShapeId.constEnd(); ++it ) + myMesh->ClearSubMesh( *it ); + } + } + myMapShapeId.clear(); + SMESHGUI_BaseComputeOp::onCancel(); +} + +//================================================================================ +/*! + * \brief perform it's intention action: preview mesh + */ +//================================================================================ + +void SMESHGUI_PrecomputeOp::onPreview() +{ + if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() ) + return; + + _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); + if ( !aMeshSObj ) + return; + // Compute preview of mesh, + // i.e. compute mesh till indicated dimension + int dim = myDlg->getPreviewMode(); + + SMESH::MemoryReserve aMemoryReserve; + + SMESH::compute_error_array_var aCompErrors; + QString aHypErrors; + + bool computeFailed = true, memoryLack = false; + + SMESHGUI_ComputeDlg* aCompDlg = computeDlg(); + aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); + + SMESHGUI* gui = getSMESHGUI(); + SMESH::SMESH_Gen_var gen = gui->GetSMESHGen(); + SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape); + if ( errors->length() > 0 ) { + aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); + } + + SUIT_OverrideCursor aWaitCursor; + + SVTK_ViewWindow* view = SMESH::GetViewWindow( gui ); + if ( myPreviewDisplayer ) delete myPreviewDisplayer; + myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view ); + + SMESH::long_array_var aShapesId = new SMESH::long_array(); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + + SMESH::MeshPreviewStruct_var previewData = + gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId); + SMESH::MeshPreviewStruct* previewRes = previewData._retn(); + if ( previewRes && previewRes->nodesXYZ.length() > 0 ) + { + computeFailed = false; + myPreviewDisplayer->SetData( previewRes ); + // append shape indeces with computed mesh entities + for ( int i = 0, n = aShapesId->length(); i < n; i++ ) + myMapShapeId[ aShapesId[ i ] ] = 0; + } + else + myPreviewDisplayer->SetVisibility(false); + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + myPreviewDisplayer->SetVisibility(false); + } + + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + aCompErrors = gen->GetComputeErrors( myMesh, myMainShape ); + // check if there are memory problems + for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i ) + memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB ); + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + + if ( memoryLack ) + aMemoryReserve.release(); + + bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 ); + bool noHypoError = ( aHypErrors.isEmpty() ); + + SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui ); + int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" ); + + bool isShowError = true; + switch( aNotifyMode ) { + case 0: // show the mesh computation result dialog NEVER + isShowError = false; + break; + case 1: // show the mesh computation result dialog if there are some errors + default: // show the result dialog after each mesh computation + if ( !computeFailed && !memoryLack && noCompError && noHypoError ) + isShowError = false; + break; + } + + aWaitCursor.suspend(); + // SHOW ERRORS + if ( isShowError ) + { + myDlg->hide(); + aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED")); + showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors ); + } +} + + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent ) + : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ) +{ + setWindowTitle( tr( "CAPTION" ) ); + + setButtonText( OK, tr( "COMPUTE" ) ); + QFrame* main = mainFrame(); + + QVBoxLayout* layout = new QVBoxLayout( main ); + + QFrame* frame = new QFrame( main ); + layout->setMargin(0); layout->setSpacing(0); + layout->addWidget( frame ); + + QHBoxLayout* frameLay = new QHBoxLayout( frame ); + frameLay->setMargin(0); frameLay->setSpacing(SPACING); + + myPreviewMode = new QtxComboBox( frame ); + frameLay->addWidget( myPreviewMode ); + + myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame ); + frameLay->addWidget( myPreviewBtn ); + + connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) ); +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ + +SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg() +{ +} + +//================================================================================ +/*! + * \brief Sets available preview modes +*/ +//================================================================================ + +void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList& theModes ) +{ + myPreviewMode->clear(); + QList::const_iterator it = theModes.constBegin(); + for ( int i = 0; it != theModes.constEnd(); ++it, i++ ) + { + QString mode = QString( "PREVIEW_%1" ).arg( *it ); + myPreviewMode->addItem( tr( mode.toLatin1().data() ) ); + myPreviewMode->setId( i, *it ); + } + myPreviewBtn->setEnabled( !theModes.isEmpty() ); +} + +//================================================================================ +/*! + * \brief Returns current preview mesh mode +*/ +//================================================================================ + +int SMESHGUI_PrecomputeDlg::getPreviewMode() const { - return myDlg->myTable; + return myPreviewMode->currentId(); }