Back to index

salome-smesh  6.5.0
SMESHGUI_VTKUtils.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // SMESH SMESHGUI : GUI for SMESH component
00024 // File   : SMESHGUI_VTKUtils.cxx
00025 // Author : Open CASCADE S.A.S.
00026 // SMESH includes
00027 //
00028 #include "SMESHGUI_VTKUtils.h"
00029 
00030 #include "SMESHGUI.h"
00031 #include "SMESHGUI_Utils.h"
00032 #include "SMESHGUI_Filter.h"
00033 #include "SMESH_ControlsDef.hxx"
00034 
00035 #include <SMESH_Actor.h>
00036 #include <SMESH_ActorUtils.h>
00037 #include <SMESH_ObjectDef.h>
00038 #include <SMDS_Mesh.hxx>
00039 
00040 // SALOME GUI includes
00041 #include <SUIT_Desktop.h>
00042 #include <SUIT_Session.h>
00043 #include <SUIT_MessageBox.h>
00044 #include <SUIT_ViewManager.h>
00045 #include <SUIT_ResourceMgr.h>
00046 
00047 #include <SALOME_ListIO.hxx>
00048 #include <SALOME_ListIteratorOfListIO.hxx>
00049 
00050 #include <SVTK_Selector.h>
00051 #include <SVTK_ViewModel.h>
00052 #include <SVTK_ViewWindow.h>
00053 
00054 #include <VTKViewer_Algorithm.h>
00055 
00056 #include <LightApp_SelectionMgr.h>
00057 #include <SalomeApp_Application.h>
00058 #include <SalomeApp_Study.h>
00059 
00060 // SALOME KERNEL includes
00061 #include <utilities.h>
00062 
00063 // IDL includes
00064 #include <SALOMEconfig.h>
00065 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
00066 #include CORBA_CLIENT_HEADER(SMESH_Group)
00067 
00068 // VTK includes
00069 #include <vtkMath.h>
00070 #include <vtkRenderer.h>
00071 #include <vtkActorCollection.h>
00072 #include <vtkUnstructuredGrid.h>
00073 
00074 // OCCT includes
00075 #include <TColStd_IndexedMapOfInteger.hxx>
00076 #include <Standard_ErrorHandler.hxx>
00077 
00078 namespace SMESH
00079 {
00080   typedef std::map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
00081   static TVisualObjCont VISUAL_OBJ_CONT;
00082 
00083   //=============================================================================
00089   //=============================================================================
00090 
00091   struct MemoryReserve
00092   {
00093     char* myBuf;
00094     MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M
00095     void Free() { if (myBuf) { delete [] myBuf; myBuf = 0; }}
00096     ~MemoryReserve() { Free(); }
00097   };
00098   static MemoryReserve* theVISU_MemoryReserve = new MemoryReserve;
00099 
00100   //================================================================================
00104   //================================================================================
00105 
00106   void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews )
00107   {
00108     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
00109     if(!app)
00110       return;
00111     SalomeApp_Study* aStudy  = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
00112     if(!aStudy)
00113       return;
00114     ViewManagerList aList;
00115 
00116     if(fromAllViews) {
00117       app->viewManagers(SVTK_Viewer::Type() , aList);
00118     } else {
00119       SUIT_ViewManager* aVM = app->getViewManager(SVTK_Viewer::Type(), true);
00120       if(aVM)
00121         aList.append(aVM);
00122     }    
00123     bool actorRemoved = false;
00124     ViewManagerList::ConstIterator it = aList.begin();
00125     SUIT_ViewManager* aViewManager = 0;
00126     for( ; it!=aList.end();it++) {
00127       aViewManager = *it;
00128       QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
00129       for ( int iV = 0; iV < views.count(); ++iV ) {
00130         if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) {
00131           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
00132             vtkWnd->RemoveActor(actor);
00133             actorRemoved = true;
00134           }
00135           actor->Delete();
00136         }
00137       }
00138     }
00139     
00140     if (aViewManager ) {
00141       int aStudyId = aViewManager->study()->id();
00142       TVisualObjCont::key_type aKey(aStudyId,theEntry);
00143       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
00144       if(anIter != VISUAL_OBJ_CONT.end()) {
00145         // for unknown reason, object destructor is not called, so clear object manually
00146         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
00147         anIter->second->GetUnstructuredGrid()->SetPoints(0);
00148       }
00149       VISUAL_OBJ_CONT.erase(aKey);
00150     }
00151 
00152     if(actorRemoved)
00153       aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
00154   }
00155   //================================================================================
00159   //================================================================================
00160 
00161   void RemoveAllObjectsWithActors()
00162   {
00163     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
00164       ( SUIT_Session::session()->activeApplication() );
00165     if (!app) return;
00166     ViewManagerList viewMgrs = app->viewManagers();
00167     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
00168       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
00169       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type()) {
00170         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
00171         for ( int iV = 0; iV < views.count(); ++iV ) {
00172           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
00173             vtkRenderer *aRenderer = vtkWnd->getRenderer();
00174             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00175             vtkActorCollection *actors = aCopy.GetActors();
00176             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
00177               // size of actors changes inside the loop
00178               if (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
00179               {
00180                 vtkWnd->RemoveActor(actor);
00181                 actor->Delete();
00182               }
00183             }
00184           }
00185         }
00186       }
00187     }
00188     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
00189     for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
00190       // for unknown reason, object destructor is not called, so clear object manually
00191       anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
00192       anIter->second->GetUnstructuredGrid()->SetPoints(0);
00193     }
00194     VISUAL_OBJ_CONT.clear();
00195   }
00196 
00197   //================================================================================
00201   //================================================================================
00202 
00203   void RemoveVisuData(int studyID)
00204   {
00205     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
00206       ( SUIT_Session::session()->activeApplication() );
00207     if (!app) return;
00208     ViewManagerList viewMgrs = app->viewManagers();
00209     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
00210       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
00211       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type() &&
00212            aViewManager->study()->id() == studyID ) {
00213         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
00214         for ( int iV = 0; iV < views.count(); ++iV ) {
00215           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
00216             vtkRenderer *aRenderer = vtkWnd->getRenderer();
00217             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00218             vtkActorCollection *actors = aCopy.GetActors();
00219             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
00220               // size of actors changes inside the loop
00221               if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
00222               {
00223                 vtkWnd->RemoveActor(actor);
00224                 actor->Delete();
00225               }
00226             }
00227           }
00228         }
00229       }
00230     }
00231     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
00232     for ( ; anIter != VISUAL_OBJ_CONT.end(); ) {
00233       int curId = anIter->first.first;
00234       if ( curId == studyID ) {
00235         // for unknown reason, object destructor is not called, so clear object manually
00236         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
00237         anIter->second->GetUnstructuredGrid()->SetPoints(0);
00238         VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
00239       }
00240       else {
00241         anIter++;
00242       }
00243     }
00244   }
00245 
00246   //================================================================================
00250   //================================================================================
00251 
00252   void OnVisuException()
00253   {
00254     try {
00255 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00256       OCC_CATCH_SIGNALS;
00257 #endif
00258       // PAL16774 (Crash after display of many groups). Salome sometimes crashes just
00259       // after or at showing this message, so we do an additional check of available memory
00260 //       char* buf = new char[100*1024];
00261 //       delete [] buf;
00262       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
00263                                QObject::tr("SMESH_VISU_PROBLEM"));
00264     } catch (...) {
00265       // no more memory at all: last resort
00266       MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" <<
00267                       std::endl << "Try to remove all visual data..." );
00268       if (theVISU_MemoryReserve) {
00269         delete theVISU_MemoryReserve;
00270         theVISU_MemoryReserve = 0;
00271       }
00272       RemoveAllObjectsWithActors();
00273       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
00274                                QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
00275       MESSAGE_END ( "...done" );
00276     }
00277   }
00278   //================================================================================
00282   //================================================================================
00283 
00284   TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){
00285     TVisualObjPtr aVisualObj;
00286     TVisualObjCont::key_type aKey(theStudyId,theEntry);
00287     try{
00288 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00289       OCC_CATCH_SIGNALS;
00290 #endif
00291       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
00292       if(anIter != VISUAL_OBJ_CONT.end()){
00293         aVisualObj = anIter->second;
00294       }else{
00295         SalomeApp_Application* app =
00296           dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
00297         _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
00298         _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
00299         if(aSObj){
00300           _PTR(GenericAttribute) anAttr;
00301           if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
00302             _PTR(AttributeIOR) anIOR = anAttr;
00303             CORBA::String_var aVal = anIOR->Value().c_str();
00304             CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
00305             if(!CORBA::is_nil(anObj)){
00306               //Try narrow to SMESH_Mesh interface
00307               SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
00308               if(!aMesh->_is_nil()){
00309                 aVisualObj.reset(new SMESH_MeshObj(aMesh));
00310                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
00311                 VISUAL_OBJ_CONT.insert(aValue);
00312               }
00313               //Try narrow to SMESH_Group interface
00314               SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
00315               if(!aGroup->_is_nil()){
00316                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
00317                 if(!aFatherSObj) return aVisualObj;
00318                 aFatherSObj = aFatherSObj->GetFather();
00319                 if(!aFatherSObj) return aVisualObj;
00320                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
00321                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
00322                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
00323                   aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
00324                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
00325                   VISUAL_OBJ_CONT.insert(aValue);
00326                 }
00327               }
00328               //Try narrow to SMESH_subMesh interface
00329               SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
00330               if(!aSubMesh->_is_nil()){
00331                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
00332                 if(!aFatherSObj) return aVisualObj;
00333                 aFatherSObj = aFatherSObj->GetFather();
00334                 if(!aFatherSObj) return aVisualObj;
00335                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
00336                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
00337                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
00338                   aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
00339                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
00340                   VISUAL_OBJ_CONT.insert(aValue);
00341                 }
00342               }
00343             }
00344           }
00345         }
00346       }
00347     }catch(...){
00348       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
00349       return TVisualObjPtr();
00350     }
00351     // Update object
00352     bool objModified = false;
00353     if ( aVisualObj ) {
00354       try {
00355 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00356         OCC_CATCH_SIGNALS;
00357 #endif
00358         //MESSAGE("GetVisualObj");
00359         if (nulData)
00360                 objModified = aVisualObj->NulData();
00361         else
00362           objModified = aVisualObj->Update();
00363       }
00364       catch (...) {
00365 #ifdef _DEBUG_
00366         MESSAGE ( "Exception in SMESHGUI_VTKUtils::GetVisualObj()" );
00367 #endif
00368         RemoveVisualObjectWithActors( theEntry ); // remove this object
00369         OnVisuException();
00370         aVisualObj.reset();
00371       }
00372     }
00373 
00374     if ( objModified ) {
00375       // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode,
00376       // ~5 times more memory is used than it occupies.
00377       // Warn the user if there is less free memory than 30 sizes of a grid
00378       // TODO: estimate memory usage in other modes and take current mode into account
00379       int freeMB = SMDS_Mesh::CheckMemory(true);
00380       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
00381       MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" <<usedMB);
00382       if ( freeMB > 0 && usedMB * 5 > freeMB ) {
00383        bool continu = false;
00384        if ( usedMB * 3 > freeMB )
00385          // even dont try to show
00386          SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
00387                                   QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
00388        else
00389          // there is a chance to succeed
00390          continu = SUIT_MessageBox::warning
00391            (SMESHGUI::desktop(),
00392             QObject::tr("SMESH_WRN_WARNING"),
00393             QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
00394             SUIT_MessageBox::Yes | SUIT_MessageBox::No,
00395             SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
00396        if ( !continu ) {
00397          // remove the corresponding actors from all views
00398          RemoveVisualObjectWithActors( theEntry );
00399          aVisualObj.reset();
00400        }
00401       }
00402     }
00403 
00404     return aVisualObj;
00405   }
00406 
00407 
00412   SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
00413                                   bool createIfNotFound)
00414   {
00415     SalomeApp_Application* anApp;
00416     if (theModule)
00417       anApp = theModule->getApp();
00418     else
00419       anApp = dynamic_cast<SalomeApp_Application*>
00420         (SUIT_Session::session()->activeApplication());
00421 
00422     if (anApp) {
00423       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
00424         return aView;
00425 
00426       SUIT_ViewManager* aViewManager =
00427         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
00428       if (aViewManager) {
00429         if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
00430           if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
00431             aViewWindow->raise();
00432             aViewWindow->setFocus();
00433             return aView;
00434           }
00435         }
00436       }
00437     }
00438     return NULL;
00439   }
00440 
00441   SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
00442                                       SUIT_ViewWindow * theWindow)
00443   {
00444     if( !theMgr )
00445       return NULL;
00446 
00447     QVector<SUIT_ViewWindow*> views = theMgr->getViews();
00448     if( views.contains( theWindow ) )
00449       return GetVtkViewWindow( theWindow );
00450     else
00451       return NULL;
00452   }
00453 
00454   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
00455     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
00456   }
00457 
00458 /*  SUIT_ViewWindow* GetActiveWindow()
00459   {
00460     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
00461     if( !app )
00462       return NULL;
00463     SUIT_ViewManager* mgr = app->activeViewManager();
00464     if( mgr )
00465       return mgr->getActiveView();
00466     else
00467       return NULL;
00468   }*/
00469 
00470   SVTK_ViewWindow* GetCurrentVtkView(){
00471     return GetVtkViewWindow( GetActiveWindow() );
00472   }
00473 
00474 
00475   void RepaintCurrentView()
00476   {
00477     if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
00478     {
00479       try {
00480 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00481         OCC_CATCH_SIGNALS;
00482 #endif
00483         wnd->getRenderer()->Render();
00484         wnd->Repaint(false);
00485       }
00486       catch (...) {
00487 #ifdef _DEBUG_
00488         MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" );
00489 #endif
00490         OnVisuException();
00491       }
00492     }
00493   }
00494 
00495   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
00496   {
00497     try {
00498 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00499       OCC_CATCH_SIGNALS;
00500 #endif
00501       theWindow->getRenderer()->Render();
00502       theWindow->Repaint();
00503     }
00504     catch (...) {
00505 #ifdef _DEBUG_
00506       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow*)" );
00507 #endif
00508       OnVisuException();
00509     }
00510   }
00511 
00512   void RenderViewWindow(SVTK_ViewWindow* theWindow)
00513   {
00514     try {
00515 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00516       OCC_CATCH_SIGNALS;
00517 #endif
00518       theWindow->getRenderer()->Render();
00519       theWindow->Repaint();
00520     }
00521     catch (...) {
00522 #ifdef _DEBUG_
00523       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow*)" );
00524 #endif
00525       OnVisuException();
00526     }
00527   }
00528 
00529   void FitAll(){
00530     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
00531       try {
00532 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00533         OCC_CATCH_SIGNALS;
00534 #endif
00535         wnd->onFitAll();
00536         wnd->Repaint();
00537       }
00538       catch (...) {
00539 #ifdef _DEBUG_
00540         MESSAGE ( "Exception in SMESHGUI_VTKUtils::FitAll()" );
00541 #endif
00542         OnVisuException();
00543       }
00544     }
00545   }
00546 
00547 
00548   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
00549                                 const char* theEntry)
00550   {
00551     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
00552       vtkRenderer *aRenderer = aViewWindow->getRenderer();
00553       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00554       vtkActorCollection *aCollection = aCopy.GetActors();
00555       aCollection->InitTraversal();
00556       while(vtkActor *anAct = aCollection->GetNextActor()){
00557         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
00558           if(anActor->hasIO()){
00559             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
00560             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
00561               return anActor;
00562             }
00563           }
00564         }
00565       }
00566     }
00567     return NULL;
00568   }
00569 
00570 
00571   SMESH_Actor* FindActorByEntry(const char* theEntry){
00572     return FindActorByEntry(GetActiveWindow(),theEntry);
00573   }
00574 
00575 
00576   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
00577     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
00578     if( !app )
00579       return NULL;
00580 
00581     if(!CORBA::is_nil(theObject)){
00582       _PTR(Study) aStudy = GetActiveStudyDocument();
00583       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
00584       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
00585       if(aSObject){
00586         CORBA::String_var anEntry = aSObject->GetID().c_str();
00587         return FindActorByEntry(anEntry.in());
00588       }
00589     }
00590     return NULL;
00591   }
00592 
00593 
00594   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
00595                            const char* theEntry,
00596                            int theIsClear)
00597   {
00598     SMESH_Actor *anActor = NULL;
00599     CORBA::Long anId = theStudy->StudyId();
00600     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
00601       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
00602       if(aSObj){
00603         _PTR(GenericAttribute) anAttr;
00604         if(aSObj->FindAttribute(anAttr,"AttributeName")){
00605           _PTR(AttributeName) aName = anAttr;
00606           std::string aNameVal = aName->Value();
00607           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
00608         }
00609 
00610         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
00611         if(!CORBA::is_nil(aGroup) && anActor)
00612         {
00613          QColor c;int delta;
00614          SMESH::GetColor( "SMESH", "fill_color", c, delta, "0,170,255|-100"  );
00615           SALOMEDS::Color aColor = aGroup->GetColor();
00616           if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ))
00617           {
00618            aColor.R = (float)c.red() / 255.0;
00619            aColor.G = (float)c.green() / 255.0;
00620             aColor.B = (float)c.blue() / 255.0;
00621             aGroup->SetColor( aColor );
00622           }
00623           if( aGroup->GetType() == SMESH::NODE )
00624             anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
00625           else if( aGroup->GetType() == SMESH::EDGE )
00626             anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
00627           else if( aGroup->GetType() == SMESH::ELEM0D )
00628             anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
00629           else
00630             anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta );
00631         }
00632       }
00633     }
00634     MESSAGE("CreateActor " << anActor);
00635     if( anActor )
00636       if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
00637         aSMESHGUI->addActorAsObserver( anActor );
00638     return anActor;
00639   }
00640 
00641 
00642   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
00643     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
00644       try {
00645 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
00646         OCC_CATCH_SIGNALS;
00647 #endif
00648         MESSAGE("DisplayActor " << theActor);
00649         vtkWnd->AddActor(theActor);
00650         vtkWnd->Repaint();
00651       }
00652       catch (...) {
00653 #ifdef _DEBUG_
00654         MESSAGE ( "Exception in SMESHGUI_VTKUtils::DisplayActor()" );
00655 #endif
00656         OnVisuException();
00657       }
00658     }
00659   }
00660 
00661 
00662   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
00663     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
00664         MESSAGE("RemoveActor " << theActor);
00665       vtkWnd->RemoveActor(theActor);
00666       if(theActor->hasIO()){
00667         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
00668         if(anIO->hasEntry()){
00669           std::string anEntry = anIO->getEntry();
00670           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
00671           int aStudyId = aStudy->id();
00672           TVisualObjCont::key_type aKey(aStudyId,anEntry);
00673           VISUAL_OBJ_CONT.erase(aKey);
00674         }
00675       }
00676       theActor->Delete();
00677       vtkWnd->Repaint();
00678     }
00679   }
00680 
00681   //================================================================================
00685   //================================================================================
00686 
00687   bool noSmeshActors(SUIT_ViewWindow *theWnd)
00688   {
00689     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) {
00690       vtkRenderer *aRenderer = aViewWindow->getRenderer();
00691       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00692       vtkActorCollection *aCollection = aCopy.GetActors();
00693       aCollection->InitTraversal();
00694       while(vtkActor *anAct = aCollection->GetNextActor())
00695         if(dynamic_cast<SMESH_Actor*>(anAct))
00696           return false;
00697     }
00698     return true;
00699   }
00700 
00701   bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
00702   {
00703         //MESSAGE("UpdateView");
00704     bool OK = false;
00705     SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
00706     if (!aViewWnd)
00707       return OK;
00708 
00709     SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd);
00710     if (!vtkWnd)
00711       return OK;
00712 
00713     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
00714     
00715     if (!aStudy)
00716       return OK;
00717 
00718     {
00719       OK = true;
00720       vtkRenderer *aRenderer = aViewWnd->getRenderer();
00721       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00722       vtkActorCollection *aCollection = aCopy.GetActors();
00723       aCollection->InitTraversal();
00724 
00725       switch (theAction) {
00726       case eDisplayAll: {
00727         while (vtkActor *anAct = aCollection->GetNextActor()) {
00728           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
00729                 MESSAGE("--- display " << anActor);
00730             anActor->SetVisibility(true);
00731 
00732             if(anActor->hasIO()){
00733               Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
00734               if(anIO->hasEntry()){
00735                 aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState);
00736               }
00737             }
00738           }
00739         }
00740         break;
00741       }
00742       case eDisplayOnly:
00743       case eEraseAll: {
00744         //MESSAGE("---case eDisplayOnly");
00745         while (vtkActor *anAct = aCollection->GetNextActor()) {
00746           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
00747                 //MESSAGE("--- erase " << anActor);
00748             anActor->SetVisibility(false);
00749           }
00750         }
00751         aStudy->setVisibilityStateForAll(Qtx::HiddenState);
00752       }
00753       default: {
00754         if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
00755           switch (theAction) {
00756             case eDisplay:
00757             case eDisplayOnly:
00758                 //MESSAGE("--- display " << anActor);
00759               anActor->Update();
00760               anActor->SetVisibility(true);
00761               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
00762               aStudy->setVisibilityState(theEntry, Qtx::ShownState);
00763               break;
00764             case eErase:
00765                 //MESSAGE("--- erase " << anActor);
00766               anActor->SetVisibility(false);
00767               aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
00768               break;
00769           }
00770         } else {
00771           switch (theAction) {
00772           case eDisplay:
00773           case eDisplayOnly:
00774             {
00775                 //MESSAGE("---");
00776               SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
00777               _PTR(Study) aDocument = aStudy->studyDS();
00778               // Pass non-visual objects (hypotheses, etc.), return true in this case
00779               CORBA::Long anId = aDocument->StudyId();
00780               TVisualObjPtr aVisualObj;
00781               if ( (aVisualObj = GetVisualObj(anId,theEntry)) && aVisualObj->IsValid())
00782               {
00783                 if ((anActor = CreateActor(aDocument,theEntry,true))) {
00784                   bool needFitAll = noSmeshActors(theWnd); // fit for the first object only
00785                   DisplayActor(theWnd,anActor);
00786                   aStudy->setVisibilityState(theEntry, Qtx::ShownState);
00787                   // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
00788                   if (needFitAll) FitAll();
00789                 } else {
00790                   OK = false;
00791                 }
00792               }
00793               break;
00794             }
00795           }
00796         }
00797       }
00798       }
00799     }
00800     return OK;
00801   }
00802 
00803 
00804   bool UpdateView(EDisplaing theAction, const char* theEntry){
00805         //MESSAGE("UpdateView");
00806     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
00807     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
00808     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
00809     return UpdateView(aWnd,theAction,theEntry);
00810   }
00811 
00812   void UpdateView(){
00813     if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
00814       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
00815       SALOME_ListIO selected; mgr->selectedObjects( selected );
00816 
00817       if( selected.Extent() == 0){
00818         vtkRenderer* aRenderer = aWnd->getRenderer();
00819         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00820         vtkActorCollection *aCollection = aCopy.GetActors();
00821         aCollection->InitTraversal();
00822         while(vtkActor *anAct = aCollection->GetNextActor()){
00823           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
00824             if(anActor->hasIO())
00825               if (!Update(anActor->getIO(),anActor->GetVisibility()))
00826                 break; // avoid multiple warinings if visu failed
00827           }
00828         }
00829       }else{
00830         SALOME_ListIteratorOfListIO anIter( selected );
00831         for( ; anIter.More(); anIter.Next()){
00832           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
00833           if ( !Update(anIO,true) )
00834             break; // avoid multiple warinings if visu failed
00835         }
00836       }
00837       RepaintCurrentView();
00838     }
00839   }
00840 
00841 
00842   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
00843   {
00844         MESSAGE("Update");
00845     _PTR(Study) aStudy = GetActiveStudyDocument();
00846     CORBA::Long anId = aStudy->StudyId();
00847     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
00848       if ( theDisplay )
00849         UpdateView(SMESH::eDisplay,theIO->getEntry());
00850       return true;
00851     }
00852     return false;
00853   }
00854 
00855   bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
00856   {
00857         MESSAGE("UpdateNulData");
00858     _PTR(Study) aStudy = GetActiveStudyDocument();
00859     CORBA::Long anId = aStudy->StudyId();
00860     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
00861       if ( theDisplay )
00862         UpdateView(SMESH::eDisplay,theIO->getEntry());
00863       return true;
00864     }
00865     return false;
00866   }
00867 
00868   void UpdateSelectionProp( SMESHGUI* theModule ) {
00869     if( !theModule )
00870       return;
00871 
00872     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
00873     if( !app )
00874     {
00875       MESSAGE( "UpdateSelectionProp: Application is null" );
00876       return;
00877     }
00878 
00879     SUIT_ViewManager* vm = app->activeViewManager();
00880     if( !vm )
00881     {
00882       MESSAGE( "UpdateSelectionProp: View manager is null" );
00883       return;
00884     }
00885 
00886     QVector<SUIT_ViewWindow*> views = vm->getViews();
00887 
00888     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
00889     if( !mgr )
00890     {
00891       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
00892       return;
00893     }
00894 
00895     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
00896            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
00897            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
00898 
00899     int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
00900     int aLineWidth  = mgr->integerValue("SMESH", "element_width", 1);
00901     int maxSize = aElem0DSize;
00902     if (aElem0DSize > maxSize) maxSize = aElem0DSize;
00903     if (aLineWidth > maxSize) maxSize = aLineWidth;
00904 
00905     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
00906            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
00907            SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
00908 
00909     for ( int i=0, n=views.count(); i<n; i++ ){
00910       // update VTK viewer properties
00911       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
00912         // mesh element selection
00913         aVtkView->SetSelectionProp(aSelColor.red()/255.,
00914                                    aSelColor.green()/255.,
00915                                    aSelColor.blue()/255.);
00916         // tolerances
00917         aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
00918 
00919         // pre-selection
00920         aVtkView->SetPreselectionProp(aPreColor.red()/255.,
00921                                       aPreColor.green()/255.,
00922                                       aPreColor.blue()/255.);
00923         // update actors
00924         vtkRenderer* aRenderer = aVtkView->getRenderer();
00925         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00926         vtkActorCollection *aCollection = aCopy.GetActors();
00927         aCollection->InitTraversal();
00928         while(vtkActor *anAct = aCollection->GetNextActor()){
00929           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
00930             anActor->SetHighlightColor(aHiColor.red()/255.,
00931                                        aHiColor.green()/255.,
00932                                        aHiColor.blue()/255.);
00933             anActor->SetPreHighlightColor(aPreColor.red()/255.,
00934                                           aPreColor.green()/255.,
00935                                           aPreColor.blue()/255.);
00936           }
00937         }
00938       }
00939     }
00940   }
00941 
00942 
00943   //----------------------------------------------------------------------------
00944   SVTK_Selector*
00945   GetSelector(SUIT_ViewWindow *theWindow)
00946   {
00947     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
00948       return aWnd->GetSelector();
00949 
00950     return NULL;
00951   }
00952 
00953   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
00954                  SVTK_Selector* theSelector)
00955   {
00956     if (theSelector)
00957       theSelector->SetFilter(theFilter);
00958   }
00959 
00960   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
00961   {
00962     return theSelector->GetFilter(theId);
00963   }
00964 
00965   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
00966   {
00967     return theSelector->IsFilterPresent(theId);
00968   }
00969 
00970   void RemoveFilter(int theId, SVTK_Selector* theSelector)
00971   {
00972     theSelector->RemoveFilter(theId);
00973   }
00974 
00975   void RemoveFilters(SVTK_Selector* theSelector)
00976   {
00977     for ( int id = SMESH::NodeFilter; theSelector && id < SMESH::LastFilter; id++ )
00978       theSelector->RemoveFilter( id );
00979   }
00980 
00981   bool IsValid(SALOME_Actor* theActor, int theCellId,
00982                SVTK_Selector* theSelector)
00983   {
00984     return theSelector->IsValid(theActor,theCellId);
00985   }
00986 
00987 
00988   //----------------------------------------------------------------------------
00989   void SetPointRepresentation(bool theIsVisible){
00990     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
00991       vtkRenderer *aRenderer = aViewWindow->getRenderer();
00992       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00993       vtkActorCollection *aCollection = aCopy.GetActors();
00994       aCollection->InitTraversal();
00995       while(vtkActor *anAct = aCollection->GetNextActor()){
00996         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
00997           if(anActor->GetVisibility()){
00998             anActor->SetPointRepresentation(theIsVisible);
00999           }
01000         }
01001       }
01002       RepaintCurrentView();
01003     }
01004   }
01005 
01006 
01007   void SetPickable(SMESH_Actor* theActor){
01008     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
01009       int anIsAllPickable = (theActor == NULL);
01010       vtkRenderer *aRenderer = aWnd->getRenderer();
01011       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
01012       vtkActorCollection *aCollection = aCopy.GetActors();
01013       aCollection->InitTraversal();
01014       while(vtkActor *anAct = aCollection->GetNextActor()){
01015         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
01016           if(anActor->GetVisibility()){
01017             anActor->SetPickable(anIsAllPickable);
01018           }
01019         }
01020       }
01021       if(theActor)
01022         theActor->SetPickable(!anIsAllPickable);
01023       RepaintCurrentView();
01024     }
01025   }
01026 
01027 
01028   //----------------------------------------------------------------------------
01029   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
01030                              const Handle(SALOME_InteractiveObject)& theIO,
01031                              QString& theName)
01032   {
01033     theName = "";
01034     TColStd_IndexedMapOfInteger aMapIndex;
01035     theSelector->GetIndex(theIO,aMapIndex);
01036 
01037     for(int i = 1; i <= aMapIndex.Extent(); i++)
01038       theName += QString(" %1").arg(aMapIndex(i));
01039 
01040     return aMapIndex.Extent();
01041   }
01042 
01043   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
01044                                 const Handle(SALOME_InteractiveObject)& theIO,
01045                                 QString& theName)
01046   {
01047     theName = "";
01048     TColStd_IndexedMapOfInteger aMapIndex;
01049     theSelector->GetIndex(theIO,aMapIndex);
01050 
01051     typedef std::set<int> TIdContainer;
01052     TIdContainer anIdContainer;
01053     for( int i = 1; i <= aMapIndex.Extent(); i++)
01054       anIdContainer.insert(aMapIndex(i));
01055 
01056     TIdContainer::const_iterator anIter = anIdContainer.begin();
01057     for( ; anIter != anIdContainer.end(); anIter++)
01058       theName += QString(" %1").arg(*anIter);
01059 
01060     return aMapIndex.Extent();
01061   }
01062 
01063 
01064   int GetEdgeNodes(SVTK_Selector* theSelector,
01065                    const TVisualObjPtr& theVisualObject,
01066                    int& theId1,
01067                    int& theId2)
01068   {
01069     const SALOME_ListIO& selected = theSelector->StoredIObjects();
01070 
01071     if ( selected.Extent() != 1 )
01072       return -1;
01073 
01074     Handle(SALOME_InteractiveObject) anIO = selected.First();
01075     if ( anIO.IsNull() || !anIO->hasEntry() )
01076       return -1;
01077 
01078     TColStd_IndexedMapOfInteger aMapIndex;
01079     theSelector->GetIndex( anIO, aMapIndex );
01080     if ( aMapIndex.Extent() != 2 )
01081       return -1;
01082 
01083     int anObjId = -1, anEdgeNum = -1;
01084     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
01085       int aVal = aMapIndex( i );
01086       if ( aVal > 0 )
01087         anObjId = aVal;
01088       else
01089         anEdgeNum = abs( aVal ) - 1;
01090     }
01091 
01092     if ( anObjId == -1 || anEdgeNum == -1 )
01093       return -1;
01094 
01095     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
01096   }
01097 
01098   //----------------------------------------------------------------------------
01099   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
01100                              const Handle(SALOME_InteractiveObject)& theIO,
01101                              QString& theName)
01102   {
01103     theName = "";
01104     if(theIO->hasEntry()){
01105       if(FindActorByEntry(theIO->getEntry())){
01106         TColStd_IndexedMapOfInteger aMapIndex;
01107         theMgr->GetIndexes(theIO,aMapIndex);
01108         for(int i = 1; i <= aMapIndex.Extent(); i++){
01109           theName += QString(" %1").arg(aMapIndex(i));
01110         }
01111         return aMapIndex.Extent();
01112       }
01113     }
01114     return -1;
01115   }
01116 
01117   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
01118     theName = "";
01119     SALOME_ListIO selected; theMgr->selectedObjects( selected );
01120     if(selected.Extent() == 1){
01121       Handle(SALOME_InteractiveObject) anIO = selected.First();
01122       return GetNameOfSelectedNodes(theMgr,anIO,theName);
01123     }
01124     return -1;
01125   }
01126 
01127 
01128   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
01129                                 const Handle(SALOME_InteractiveObject)& theIO,
01130                                 QString& theName)
01131   {
01132     theName = "";
01133     if(theIO->hasEntry()){
01134       if(FindActorByEntry(theIO->getEntry())){
01135         TColStd_IndexedMapOfInteger aMapIndex;
01136         theMgr->GetIndexes(theIO,aMapIndex);
01137         typedef std::set<int> TIdContainer;
01138         TIdContainer anIdContainer;
01139         for( int i = 1; i <= aMapIndex.Extent(); i++)
01140           anIdContainer.insert(aMapIndex(i));
01141         TIdContainer::const_iterator anIter = anIdContainer.begin();
01142         for( ; anIter != anIdContainer.end(); anIter++){
01143           theName += QString(" %1").arg(*anIter);
01144         }
01145         return aMapIndex.Extent();
01146       }
01147     }
01148     return -1;
01149   }
01150 
01151 
01152   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
01153   {
01154     theName = "";
01155     SALOME_ListIO selected; theMgr->selectedObjects( selected );
01156 
01157     if( selected.Extent() == 1){
01158       Handle(SALOME_InteractiveObject) anIO = selected.First();
01159       return GetNameOfSelectedElements(theMgr,anIO,theName);
01160     }
01161     return -1;
01162   }
01163 
01164   int GetSelected(LightApp_SelectionMgr*       theMgr,
01165                   TColStd_IndexedMapOfInteger& theMap,
01166                   const bool                   theIsElement)
01167   {
01168     theMap.Clear();
01169     SALOME_ListIO selected; theMgr->selectedObjects( selected );
01170 
01171     if ( selected.Extent() == 1 )
01172     {
01173       Handle(SALOME_InteractiveObject) anIO = selected.First();
01174       if ( anIO->hasEntry() ) {
01175         theMgr->GetIndexes( anIO, theMap );
01176       }
01177     }
01178     return theMap.Extent();
01179   }
01180 
01181 
01182   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
01183   {
01184     SALOME_ListIO selected; theMgr->selectedObjects( selected );
01185 
01186     if ( selected.Extent() != 1 )
01187       return -1;
01188 
01189     Handle(SALOME_InteractiveObject) anIO = selected.First();
01190     if ( anIO.IsNull() || !anIO->hasEntry() )
01191       return -1;
01192 
01193     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
01194     if ( anActor == 0 )
01195       return -1;
01196 
01197     TColStd_IndexedMapOfInteger aMapIndex;
01198     theMgr->GetIndexes( anIO, aMapIndex );
01199     if ( aMapIndex.Extent() != 2 )
01200       return -1;
01201 
01202     int anObjId = -1, anEdgeNum = -1;
01203     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
01204       int aVal = aMapIndex( i );
01205       if ( aVal > 0 )
01206         anObjId = aVal;
01207       else
01208         anEdgeNum = abs( aVal );
01209     }
01210 
01211     if ( anObjId == -1 || anEdgeNum == -1 )
01212       return -1;
01213 
01214     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
01215   }
01216 
01217   void SetControlsPrecision( const long theVal )
01218   {
01219     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
01220     {
01221       vtkRenderer *aRenderer = aWnd->getRenderer();
01222       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
01223       vtkActorCollection *aCollection = aCopy.GetActors();
01224       aCollection->InitTraversal();
01225 
01226       while ( vtkActor *anAct = aCollection->GetNextActor())
01227       {
01228         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
01229         {
01230           anActor->SetControlsPrecision( theVal );
01231           anActor->SetControlMode( anActor->GetControlMode() );
01232         }
01233       }
01234 
01235     }
01236   }
01237 
01238   //----------------------------------------------------------------------------
01239   // internal function
01240   void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
01241                            vtkFloatingPointType theDirection[3],
01242                            vtkFloatingPointType theMinPnt[3],
01243                            vtkFloatingPointType& theMaxBoundPrj,
01244                            vtkFloatingPointType& theMinBoundPrj )
01245   {
01246     //Enlarge bounds in order to avoid conflicts of precision
01247     for(int i = 0; i < 6; i += 2){
01248       static double EPS = 1.0E-3;
01249       vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
01250       theBounds[i] -= aDelta;
01251       theBounds[i+1] += aDelta;
01252     }
01253 
01254     vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
01255                                                 {theBounds[1],theBounds[2],theBounds[4]},
01256                                                 {theBounds[0],theBounds[3],theBounds[4]},
01257                                                 {theBounds[1],theBounds[3],theBounds[4]},
01258                                                 {theBounds[0],theBounds[2],theBounds[5]},
01259                                                 {theBounds[1],theBounds[2],theBounds[5]}, 
01260                                                 {theBounds[0],theBounds[3],theBounds[5]}, 
01261                                                 {theBounds[1],theBounds[3],theBounds[5]}};
01262 
01263     int aMaxId = 0;
01264     theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
01265     theMinBoundPrj = theMaxBoundPrj;
01266     for(int i = 1; i < 8; i++){
01267       vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
01268       if(theMaxBoundPrj < aTmp){
01269         theMaxBoundPrj = aTmp;
01270         aMaxId = i;
01271       }
01272       if(theMinBoundPrj > aTmp){
01273         theMinBoundPrj = aTmp;
01274       }
01275     }
01276     vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
01277     theMinPnt[0] = aMinPnt[0];
01278     theMinPnt[1] = aMinPnt[1];
01279     theMinPnt[2] = aMinPnt[2];
01280   }
01281 
01282   // internal function
01283   void DistanceToPosition( vtkFloatingPointType theBounds[6],
01284                            vtkFloatingPointType theDirection[3],
01285                            vtkFloatingPointType theDist,
01286                            vtkFloatingPointType thePos[3] )
01287   {
01288     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
01289     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
01290     vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
01291     thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
01292     thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
01293     thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
01294   }
01295 
01296   // internal function (currently unused, left just in case)
01297   void PositionToDistance( vtkFloatingPointType theBounds[6],
01298                            vtkFloatingPointType theDirection[3],
01299                            vtkFloatingPointType thePos[3],
01300                            vtkFloatingPointType& theDist )
01301   {
01302     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
01303     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
01304     vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
01305     theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
01306   }
01307 
01308   bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
01309                                        vtkFloatingPointType theNormal[3],
01310                                        vtkFloatingPointType theDist,
01311                                        vtkFloatingPointType theBounds[6],
01312                                        vtkFloatingPointType theOrigin[3] )
01313   {
01314     bool anIsOk = false;
01315     theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
01316     theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
01317     std::list<vtkActor*>::iterator anIter = theActorList.begin();
01318     for( ; anIter != theActorList.end(); anIter++ ) {
01319       if( vtkActor* aVTKActor = *anIter ) {
01320         if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
01321           vtkFloatingPointType aBounds[6];
01322           anActor->GetUnstructuredGrid()->GetBounds( aBounds );
01323           theBounds[0] = std::min( theBounds[0], aBounds[0] );
01324           theBounds[1] = std::max( theBounds[1], aBounds[1] );
01325           theBounds[2] = std::min( theBounds[2], aBounds[2] );
01326           theBounds[3] = std::max( theBounds[3], aBounds[3] );
01327           theBounds[4] = std::min( theBounds[4], aBounds[4] );
01328           theBounds[5] = std::max( theBounds[5], aBounds[5] );
01329           anIsOk = true;
01330         }
01331       }
01332     }
01333 
01334     if( !anIsOk )
01335       return false;
01336 
01337     DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
01338     return true;
01339   }
01340 
01341 #ifndef DISABLE_PLOT2DVIEWER
01342   //================================================================================
01347   //================================================================================
01348 
01349   void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ) {
01350     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
01351       vtkRenderer *aRenderer = aViewWindow->getRenderer();
01352       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
01353       vtkActorCollection *aCollection = aCopy.GetActors();
01354       aCollection->InitTraversal();
01355       while(vtkActor *anAct = aCollection->GetNextActor()){
01356         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
01357           if(anActor->hasIO() && anActor->GetPlot2Histogram() ){
01358             ProcessIn2DViewers(anActor,RemoveFrom2dViewer);
01359           }
01360         }
01361       }
01362     }
01363   }
01364   
01365 #endif
01366 
01367 } // end of namespace SMESH