From 46252cb81bf57bfd9aef669eb9bb7ab67beae28e Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 10 Sep 2007 14:24:01 +0000 Subject: [PATCH] PAL16774,PAL16631(SALOME crash after a mesh computation that failed because of lack of memory) Catch exceptions during visualization --- src/SMESHGUI/SMESHGUI.cxx | 111 +++---------- src/SMESHGUI/SMESHGUI_ComputeDlg.cxx | 47 +++--- src/SMESHGUI/SMESHGUI_VTKUtils.cxx | 232 ++++++++++++++++++++++++--- src/SMESHGUI/SMESHGUI_VTKUtils.h | 1 + src/SMESHGUI/SMESH_msg_en.po | 7 + 5 files changed, 262 insertions(+), 136 deletions(-) diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 6a6910a1c..5b422fc17 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1290,22 +1290,27 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) extractContainers( sel_objects, to_process ); - if (vtkwnd) { - SALOME_ListIteratorOfListIO It( to_process ); - for (; It.More(); It.Next()) { - Handle(SALOME_InteractiveObject) IOS = It.Value(); - if (IOS->hasEntry()) { - SMESH::UpdateView(anAction, IOS->getEntry()); - if (anAction == SMESH::eDisplayOnly) - anAction = SMESH::eDisplay; - } - } - } + try { + if (vtkwnd) { + SALOME_ListIteratorOfListIO It( to_process ); + for (; It.More(); It.Next()) { + Handle(SALOME_InteractiveObject) IOS = It.Value(); + if (IOS->hasEntry()) { + SMESH::UpdateView(anAction, IOS->getEntry()); + if (anAction == SMESH::eDisplayOnly) + anAction = SMESH::eDisplay; + } + } + } - // PAL13338 + PAL15161 --> - if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy) /*&& !automaticUpdate()*/ ) - SMESH::UpdateView(); - // PAL13338 + PAL15161 <-- + // PAL13338 + PAL15161 --> + if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) + SMESH::UpdateView(); + // PAL13338 + PAL15161 <-- + } + catch (...) { // PAL16774 (Crash after display of many groups) + SMESH::OnVisuException(); + } if (anAction == SMESH::eErase) { SALOME_ListIO l1; @@ -1364,82 +1369,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (checkLock(aStudy)) break; startOperation( 701 ); -// LightApp_SelectionMgr *Sel = selectionMgr(); -// SALOME_ListIO selected; Sel->selectedObjects( selected ); - -// int nbSel = selected.Extent(); -// if (nbSel != 1) { -// SUIT_MessageBox::warn1(desktop(), -// tr("SMESH_WRN_WARNING"), -// tr("SMESH_WRN_NO_AVAILABLE_DATA"), -// tr("SMESH_BUT_OK")); -// break; -// } - -// SMESH::SMESH_Mesh_var aMesh; -// SMESH::SMESH_subMesh_var aSubMesh; -// Handle(SALOME_InteractiveObject) IObject = selected.First(); -// if (IObject->hasEntry()) { -// _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry()); -// GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj ); -// if ( aShapeObject->_is_nil() ) { -// // imported mesh -// break; -// } -// if ( aMeshSObj ) { -// aMesh = SMESH::SObjectToInterface(aMeshSObj); -// aSubMesh = SMESH::SObjectToInterface(aMeshSObj); -// if ( !aSubMesh->_is_nil() ) -// aMesh = aSubMesh->GetFather(); - -// if (!aMesh->_is_nil()) { -// SMESH::algo_error_array_var errors = GetSMESHGen()->GetAlgoState(aMesh,aShapeObject); -// if ( errors->length() > 0 ) { -// SUIT_MessageBox::warn1(desktop(), -// tr("SMESH_WRN_WARNING"), -// SMESH::GetMessageOnAlgoStateErrors( errors.in() ), -// tr("SMESH_BUT_OK")); -// break; -// } - -// try { -// if (GetSMESHGen()->Compute(aMesh, aShapeObject)) -// SMESH::ModifiedMesh(aMeshSObj, true); -// else -// SUIT_MessageBox::warn1(desktop(), -// tr("SMESH_WRN_WARNING"), -// tr("SMESH_WRN_COMPUTE_FAILED"), -// tr("SMESH_BUT_OK")); -// } -// catch(const SALOME::SALOME_Exception & S_ex){ -// SalomeApp_Tools::QtCatchCorbaException(S_ex); -// } - -// updateObjBrowser(); - -// if (automaticUpdate()) { -// SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(this, /*create*/true); -// if (aVTKView) { -// CORBA::Long anId = aStudy->StudyId(); -// TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry()); -// if (aVisualObj) { -// aVisualObj->Update(); -// SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry()); -// if (!anActor) { -// anActor = SMESH::CreateActor(aStudy, IObject->getEntry()); -// if (anActor) { -// SMESH::DisplayActor(aVTKView, anActor); //apo -// SMESH::FitAll(); -// } -// } -// SMESH::RepaintCurrentView(); -// Sel->setSelectedObjects( selected ); -// } -// } -// } -// } -// } -// } } break; diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 6c856bb78..cc8506198 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -35,6 +35,7 @@ #include "SMESHGUI_HypothesesUtils.h" #include "SMDS_SetIterator.hxx" +#include #include "GEOMBase.h" #include "GEOM_Actor.h" @@ -67,6 +68,8 @@ #include #include +#include + // QT Includes #include #include @@ -814,6 +817,9 @@ void SMESHGUI_ComputeOp::startOperation() } SUIT_OverrideCursor aWaitCursor; try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif if (gen->Compute(aMesh, myMainShape)) computeFailed = false; } @@ -822,6 +828,9 @@ void SMESHGUI_ComputeOp::startOperation() //SalomeApp_Tools::QtCatchCorbaException(S_ex); } try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif anErrors = gen->GetComputeErrors( aMesh, myMainShape ); // if ( anErrors->length() == 0 ) { // SUIT_MessageBox::warn1(desktop(), @@ -843,33 +852,28 @@ void SMESHGUI_ComputeOp::startOperation() { SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0); update( UF_ObjBrowser | UF_Model ); + Sel->setSelectedObjects( selected ); // SHOW MESH - // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) { - if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) // NPAL16631 + // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) + if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) { try { - SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(getSMESHGUI(), true); - if (aVTKView) { - int anId = study()->id(); - TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry()); - if (aVisualObj) { - aVisualObj->Update(); - SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry()); - if (!anActor) { - anActor = SMESH::CreateActor(studyDS(), IObject->getEntry()); - if (anActor) { - SMESH::DisplayActor(aVTKView, anActor); //apo - SMESH::FitAll(); - } - } - SMESH::RepaintCurrentView(); - Sel->setSelectedObjects( selected ); - } - } +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + SMESH::UpdateView(eDisplay, IObject->getEntry()); } catch (...) { - memoryLack = true; +#ifdef _DEBUG_ + cout << "Exception thrown during mesh visualization" << endl; +#endif + if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? + SMESH::OnVisuException(); + } + else { + memoryLack = true; + } } } } @@ -899,6 +903,7 @@ void SMESHGUI_ComputeOp::startOperation() } else if ( noError ) { + SUIT_OverrideCursor aWaitCursor; myDlg->myFullInfo->SetInfoByMesh( aMesh ); myDlg->myFullInfo->show(); myDlg->myBriefInfo->hide(); diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index f86da0094..89bb22f5a 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -25,10 +25,12 @@ #include "SMESHGUI.h" #include "SMESH_Actor.h" #include "SMESH_ObjectDef.h" +#include #include #include #include +#include #include #include @@ -55,9 +57,11 @@ // VTK #include #include +#include // OCCT #include +#include // STL #include @@ -69,10 +73,100 @@ namespace SMESH { typedef map TVisualObjCont; static TVisualObjCont VISUAL_OBJ_CONT; + //================================================================================ + /*! + * \brief Remove VisualObj and its actor from all views + */ + //================================================================================ + + void RemoveVisualObjectWithActors( const char* theEntry ) + { + SalomeApp_Application* app = dynamic_cast + ( SUIT_Session::session()->activeApplication() ); + SUIT_ViewManager* aViewManager = + app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0; + if ( aViewManager ) { + QPtrVector views = aViewManager->getViews(); + for ( int iV = 0; iV < views.count(); ++iV ) { + if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) { + if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) + vtkWnd->RemoveActor(actor); + actor->Delete(); + } + } + SalomeApp_Study* aStudy = dynamic_cast( aViewManager->study() ); + int aStudyId = aStudy->id(); + TVisualObjCont::key_type aKey(aStudyId,theEntry); + TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); + if(anIter != VISUAL_OBJ_CONT.end()) { + // for unknown reason, object destructor is not called, so clear object manually + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetPoints(0); + } + VISUAL_OBJ_CONT.erase(aKey); + } + } + //================================================================================ + /*! + * \brief Remove all VisualObjs and their actors from all views + */ + //================================================================================ + + void RemoveAllObjectsWithActors() + { + SalomeApp_Application* app = dynamic_cast + ( SUIT_Session::session()->activeApplication() ); + SUIT_ViewManager* aViewManager = + app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0; + if ( aViewManager ) { + QPtrVector views = aViewManager->getViews(); + for ( int iV = 0; iV < views.count(); ++iV ) { + if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) { + vtkRenderer *aRenderer = vtkWnd->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *actor = dynamic_cast(anAct)){ + vtkWnd->RemoveActor(actor); + actor->Delete(); + } + } + } + } + TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin(); + for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) { + // for unknown reason, object destructor is not called, so clear object manually + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetPoints(0); + } + VISUAL_OBJ_CONT.clear(); + } + } + //================================================================================ + /*! + * \brief Notify the user on problems during visualization + */ + //================================================================================ + + void OnVisuException() + { + SUIT_MessageBox::warn1 (SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_VISU_PROBLEM"), + QObject::tr("SMESH_BUT_OK")); + } + //================================================================================ + /*! + * \brief Returns an updated visual object + */ + //================================================================================ + TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){ TVisualObjPtr aVisualObj; + TVisualObjCont::key_type aKey(theStudyId,theEntry); try{ - TVisualObjCont::key_type aKey(theStudyId,theEntry); +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); if(anIter != VISUAL_OBJ_CONT.end()){ aVisualObj = anIter->second; @@ -92,10 +186,8 @@ namespace SMESH { SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); if(!aMesh->_is_nil()){ aVisualObj.reset(new SMESH_MeshObj(aMesh)); - aVisualObj->Update(); TVisualObjCont::value_type aValue(aKey,aVisualObj); VISUAL_OBJ_CONT.insert(aValue); - return aVisualObj; } //Try narrow to SMESH_Group interafce SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj); @@ -108,10 +200,8 @@ namespace SMESH { TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj)); - aVisualObj->Update(); TVisualObjCont::value_type aValue(aKey,aVisualObj); VISUAL_OBJ_CONT.insert(aValue); - return aVisualObj; } } //Try narrow to SMESH_subMesh interafce @@ -125,10 +215,8 @@ namespace SMESH { TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj)); - aVisualObj->Update(); TVisualObjCont::value_type aValue(aKey,aVisualObj); VISUAL_OBJ_CONT.insert(aValue); - return aVisualObj; } } } @@ -137,7 +225,48 @@ namespace SMESH { } }catch(...){ INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!"); + return TVisualObjPtr(); } + // Update object + bool objModified = false; + if ( aVisualObj ) { + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + objModified = aVisualObj->Update(); + } + catch (...) { +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::GetVisualObj()" << endl; +#endif + OnVisuException(); + RemoveVisualObjectWithActors( theEntry ); // remove this object + aVisualObj.reset(); + } + } + + if ( objModified ) { + // PAL16631. Mesurements showed that to show aVisualObj in shading mode, + // ~10 times more memory is used than it occupies. + // Warn the user if there is less free memory than 30 sizes of a grid + int freeMB = SMDS_Mesh::CheckMemory(true); + int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024; + if ( freeMB > 0 && usedMB * 30 > freeMB ) { + int continu = SUIT_MessageBox::warn2 + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), + QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"), + 1, 0, 1); + if ( !continu ) { + // remove the corresponding actors from all views + RemoveVisualObjectWithActors( theEntry ); + aVisualObj.reset(); + } + } + } + return aVisualObj; } @@ -212,28 +341,72 @@ namespace SMESH { void RepaintCurrentView() { if (SVTK_ViewWindow* wnd = GetCurrentVtkView()) - { - wnd->getRenderer()->Render(); - wnd->Repaint(false); + { + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + wnd->getRenderer()->Render(); + wnd->Repaint(false); + } + catch (...) { + OnVisuException(); +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" << endl; +#endif } + } } void RepaintViewWindow(SVTK_ViewWindow* theWindow) { - theWindow->getRenderer()->Render(); - theWindow->Repaint(); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + theWindow->getRenderer()->Render(); + theWindow->Repaint(); + } + catch (...) { + OnVisuException(); +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow)" << endl; +#endif + } } void RenderViewWindow(SVTK_ViewWindow* theWindow) { - theWindow->getRenderer()->Render(); - theWindow->Repaint(); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + theWindow->getRenderer()->Render(); + theWindow->Repaint(); + } + catch (...) { + OnVisuException(); +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow)" << endl; +#endif + } } void FitAll(){ if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){ - wnd->onFitAll(); - wnd->Repaint(); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + wnd->onFitAll(); + wnd->Repaint(); + } + catch (...) { + OnVisuException(); +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::FitAll()" << endl; +#endif + } } } @@ -306,8 +479,19 @@ namespace SMESH { void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){ if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){ - vtkWnd->AddActor(theActor); - vtkWnd->Repaint(); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + vtkWnd->AddActor(theActor); + vtkWnd->Repaint(); + } + catch (...) { + OnVisuException(); +#ifdef _DEBUG_ + cout << "Exception in SMESHGUI_VTKUtils::DisplayActor()" << endl; +#endif + } } } @@ -330,7 +514,6 @@ namespace SMESH { } } - void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry) { if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){ @@ -425,11 +608,12 @@ namespace SMESH { { _PTR(Study) aStudy = GetActiveStudyDocument(); CORBA::Long anId = aStudy->StudyId(); - TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry()); - if( aVisualObj ) - aVisualObj->Update(); - if ( theDisplay ) - UpdateView(SMESH::eDisplay,theIO->getEntry()); + if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) { + // if( aVisualObj ) + // aVisualObj->Update(); -> PAL16631, already done in GetVisualObj() + if ( theDisplay ) + UpdateView(SMESH::eDisplay,theIO->getEntry()); + } } diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index 94d2c1348..e1ecbc897 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -61,6 +61,7 @@ namespace SMESH { TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry); + void OnVisuException(); // PAL16631 //---------------------------------------------------------------------------- SVTK_ViewWindow* GetViewWindow(const SalomeApp_Module* theModule = NULL, diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index 5722e5951..67fbe6a0b 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -1386,6 +1386,13 @@ msgstr "Select an object" msgid "SMESH_AUTO_GROUPS" msgstr "Automatically create groups" +msgid "SMESH_CONTINUE_MESH_VISUALIZATION" +msgstr "It seems that there is not enouth memory to show the mesh.\n" + "Do you wish to continue visualization?" + +msgid "SMESH_VISU_PROBLEM" +msgstr "Mesh visualization failed, probably due to lack of memory" + #---------------------------------------------------- msgid "SMESHGUI_FilterLibraryDlg::ADD_TO_TLT" -- 2.39.2