+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::onCancel()
+{
+ QObject* curDlg = sender();
+ if ( curDlg == computeDlg() && 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<int,int>::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<int>& theModes )
+{
+ myPreviewMode->clear();
+ QList<int>::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 myPreviewMode->currentId();
+}
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
+ : SMESHGUI_BaseComputeOp()
+{
+}
+
+
+//================================================================================
+/*!
+ * \brief Desctructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_EvaluateOp::startOperation()
+{
+ SMESHGUI_BaseComputeOp::evaluateDlg();
+ SMESHGUI_BaseComputeOp::startOperation();
+ evaluateMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
+{
+ return evaluateDlg();
+}
+
+//================================================================================
+/*!
+ * \brief evaluaateMesh()
+*/
+//================================================================================
+
+void SMESHGUI_BaseComputeOp::evaluateMesh()
+{
+ // EVALUATE MESH
+
+ SMESH::MemoryReserve aMemoryReserve;
+
+ SMESH::compute_error_array_var aCompErrors;
+ QString aHypErrors;
+
+ bool evaluateFailed = true, memoryLack = false;
+ SMESH::long_array_var aRes;
+
+ _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+ bool hasShape = myMesh->HasShapeToMesh();
+ bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
+ if ( shapeOK && aMeshSObj )
+ {
+ myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+ SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+ SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
+ if ( errors->length() > 0 ) {
+ aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
+ }
+ SUIT_OverrideCursor aWaitCursor;
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ aRes = gen->Evaluate(myMesh, myMainShape);
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ }
+
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ }
+ }
+
+ if ( memoryLack )
+ aMemoryReserve.release();
+
+ evaluateFailed = ( aCompErrors->length() > 0 );
+ myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED"));
+
+ // SHOW ERRORS
+
+ bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
+ bool noHypoError = ( aHypErrors.isEmpty() );
+
+ //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+ //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+ bool isShowResultDlg = true;
+ //if( noHypoError )
+ //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 || !noHypoError )
+ // isShowResultDlg = true;
+ //else
+ //{
+ // isShowResultDlg = false;
+ // commit();
+ //}
+ //break;
+ //default: // show the result dialog after each mesh computation
+ //isShowResultDlg = true;
+ //}
+
+ // SHOW RESULTS
+ if ( isShowResultDlg )
+ showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors,
+ noHypoError, aHypErrors);
+}
+
+
+void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
+ 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 = evaluateDlg();
+ aCompDlg->myMemoryLackGroup->hide();
+
+ if ( theMemoryLack )
+ {
+ aCompDlg->myMemoryLackGroup->show();
+ aCompDlg->myFullInfo->hide();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else if ( theNoCompError && theNoHypoError )
+ {
+ aCompDlg->myFullInfo->SetMeshInfo( theRes );
+ aCompDlg->myFullInfo->show();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else
+ {
+ QTableWidget* tbl = aCompDlg->myTable;
+ aCompDlg->myBriefInfo->SetMeshInfo( theRes );
+ aCompDlg->myBriefInfo->show();
+ aCompDlg->myFullInfo->hide();
+
+ if ( theNoHypoError ) {
+ aCompDlg->myHypErrorGroup->hide();
+ }
+ else {
+ aCompDlg->myHypErrorGroup->show();
+ aCompDlg->myHypErrorLabel->setText( theHypErrors );
+ }
+
+ if ( theNoCompError ) {
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else {
+ aCompDlg->myCompErrorGroup->show();
+
+ aCompDlg->myPublishBtn->hide();
+ aCompDlg->myShowBtn->hide();
+
+ // fill table of errors
+ tbl->setRowCount( theCompErrors->length() );
+ if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+ else tbl->showColumn( COL_SHAPE );
+ tbl->setColumnWidth( COL_ERROR, 200 );
+
+ bool hasBadMesh = false;
+ for ( int row = 0; row < theCompErrors->length(); ++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 ) );
+ else tbl->item( row, COL_ALGO )->setText( text );
+
+ text = SMESH::errorText( err.code, err.comment.in() );
+ if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_ERROR )->setText( text );
+
+ text = QString("%1").arg( err.subShapeID );
+ if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPEID )->setText( text );
+
+ text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
+ if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+ else tbl->item( row, COL_SHAPE )->setText( text );
+
+ text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+ 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
+ }
+ }
+ // show dialog and wait, becase Compute can be invoked from Preview operation
+ //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
+ aCompDlg->show();
+}
+
+
+//================================================================================
+/*!
+ * \brief Gets dialog of evaluate operation
+ * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation