Salome HOME
0020978: EDF 1475 SMESH: Convert linear to quadratic on a submesh
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index c78fd71d155839f51a1477276c1d20c09d8a9c4f..18e7669cb899cbc3890c5c263dff4a6de98b29f4 100644 (file)
@@ -89,6 +89,7 @@
 #include <SMESH_Client.hxx>
 #include <SMESH_Actor.h>
 #include <SMESH_ScalarBarActor.h>
+#include <SMESH_ActorUtils.h>
 #include <SMESH_TypeFilter.hxx>
 #include "SMESH_ControlsDef.hxx"
 
 #include <SALOME_ListIO.hxx>
 #include <SALOME_ListIteratorOfListIO.hxx>
 
+#ifndef DISABLE_PLOT2DVIEWER
+#include <SPlot2d_ViewModel.h>
+#include <SPlot2d_Histogram.h>
+#endif
+
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
     else if ( theCommandID == 111 ) {
       filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
     }
+    else if ( theCommandID == 140 ) {
+      filter.append( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
+    }
 
     QString anInitialPath = "";
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
               }
               break;
             }
+          case 140:
+            {
+              // STL format
+              aMeshes->length( 1 );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toLatin1().constData() );
+              if ( aMeshes[0]->_is_nil() ) {
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
+              }
+              break;
+            }
           }
         }
         catch ( const SALOME::SALOME_Exception& S_ex ) {
             // obj has been published in study. Its refcount has been incremented.
             // It is safe to decrement its refcount
             // so that it will be destroyed when the entry in study will be removed
-            aMeshes[i]->Destroy();
+            aMeshes[i]->UnRegister();
 #endif
           }
           else {
         aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)";
       }
       break;
-    case 140:
     case 141:
       {
         // export STL
         /*
           there must be check on others mesh elements not equal triangles
         */
-        if (aMesh->NbTriangles() < 1) {
-          SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_STL1").arg(aMeshName));
-          return;
-        }
-        if (!(aMesh->NbElements() - aMesh->NbTriangles())) {
-          int aRet = SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_STL2").arg(aMeshName),
-             QObject::tr("SMESH_BUT_YES"),
-             QObject::tr("SMESH_BUT_NO"), 0, 1);
-          if (aRet != 0)
-            return;
-        }
+//         if (aMesh->NbTriangles() < 1) {
+//           SUIT_MessageBox::warning
+//             (SMESHGUI::desktop(),
+//              QObject::tr("SMESH_WRN_WARNING"),
+//              QObject::tr("SMESH_EXPORT_STL1").arg(aMeshName));
+//           return;
+//         }
+//         if (!(aMesh->NbElements() - aMesh->NbTriangles())) {
+//           int aRet = SUIT_MessageBox::warning
+//             (SMESHGUI::desktop(),
+//              QObject::tr("SMESH_WRN_WARNING"),
+//              QObject::tr("SMESH_EXPORT_STL2").arg(aMeshName),
+//              QObject::tr("SMESH_BUT_YES"),
+//              QObject::tr("SMESH_BUT_NO"), 0, 1);
+//           if (aRet != 0)
+//             return;
+//         }
 
         aFilterMapSTL.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 ); // 1 - ASCII mode
         aFilterMapSTL.insert( QObject::tr( "STL_BIN_FILES_FILTER" )   + " (*.stl)", 0 ); // 0 - Binary mode
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
       anInitialPath = QDir::currentPath();
 
-    if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 140 && theCommandID != 141) {
+    if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 141) {
       if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath();
       aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), anInitialPath + QString("/") + aMeshName,
                                             aFilter, aTitle, false);
     }
-    else if(theCommandID == 140 || theCommandID == 141) { // Export to STL
+    else if(theCommandID == 141) { // Export to STL
       QStringList filters;
       QMap<QString, int>::const_iterator it = aFilterMapSTL.begin();
       for ( ; it != aFilterMapSTL.end(); ++it )
         case 123:
           aMesh->ExportUNV( aFilename.toLatin1().data() );
           break;
-        case 140:
         case 141:
           aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL );
           break;
     if( aMainObject->_is_nil() )
       return;
 
-    aMainObject->SetAutoColor( true );
-
-    QList<SALOMEDS::Color> aReservedColors;
+    aMainObject->SetAutoColor( true ); // mesh groups are re-colored here
 
     SMESH::ListOfGroups aListOfGroups = *aMainObject->GetGroups();
     for( int i = 0, n = aListOfGroups.length(); i < n; i++ )
     {
       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
-      SALOMEDS::Color aCurrentColor = aGroupObject->GetColor();
-
-      SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
-      aGroupObject->SetColor( aColor );
-      aReservedColors.append( aColor );
-
+      SALOMEDS::Color aColor = aGroupObject->GetColor();
       _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject);
       if (aGroupSObject) {
         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) {
     }
   }
 
+#ifndef DISABLE_PLOT2DVIEWER
+ void PlotDistribution() {
+   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+   if( !app )
+     return;
+
+   LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+   SALOME_ListIO selected;
+   if ( aSel )
+     aSel->selectedObjects( selected );
+    
+   if ( selected.Extent() == 1 ) {
+     Handle(SALOME_InteractiveObject) anIO = selected.First();
+     if ( anIO->hasEntry() ) {
+       //Find Actor by entry before getting Plot2d viewer,
+       //because after call getViewManager( Plot2d_Viewer::Type(), true ) active window is Plot2d Viewer
+       SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+
+       SUIT_ViewManager* aViewManager = app->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary
+
+       if( !aViewManager )
+         return;
+       
+       SPlot2d_Viewer* aView = dynamic_cast<SPlot2d_Viewer*>(aViewManager->getViewModel());
+       if ( !aView )
+         return;
+
+       Plot2d_ViewFrame* aPlot = aView->getActiveViewFrame();
+       if ( !aPlot )
+         return;
+
+       if ( anActor && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+         SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
+         QString functorName = functorToString( anActor->GetFunctor());
+         QString aHistogramName("%1 : %2");
+         aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName);
+         aHistogram->setName(aHistogramName);
+         aHistogram->setHorTitle(functorName);
+         aHistogram->setVerTitle(QObject::tr("DISTRIBUTION_NB_ENT"));
+         aPlot->displayObject(aHistogram, true);
+       }
+     }
+   }
+ }
+#endif //DISABLE_PLOT2DVIEWER
+
   void DisableAutoColor(){
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
           anActor->SetControlMode(aControl);
           anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
           SMESH::RepaintCurrentView();
+#ifndef DISABLE_PLOT2DVIEWER
+          if(anActor->GetPlot2Histogram()) {
+            SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
+            QString functorName = functorToString( anActor->GetFunctor());
+            QString aHistogramName("%1 : %2");
+            aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName);
+            aHistogram->setName(aHistogramName);
+            aHistogram->setHorTitle(functorName);
+            SMESH::ProcessIn2DViewers(anActor);
+          }
+#endif
         }
       }
     }
       return;
 
     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
-    SUIT_ViewManager* vm = anApp->activeViewManager();
-    int nbSf = vm ? vm->getViewsCount() : 0;
 
-    SALOME_ListIteratorOfListIO It(selected);
-
-    aStudyBuilder->NewCommand();  // There is a transaction
-    for( ; It.More(); It.Next()){ // loop on selected IO's
-      Handle(SALOME_InteractiveObject) IObject = It.Value();
-      if(IObject->hasEntry()) {
-        _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
-
-        // disable removal of "SMESH" component object
-        if(aSO->FindAttribute(anAttr, "AttributeIOR")){
-          anIOR = anAttr;
-          if ( engineIOR() == anIOR->Value().c_str() )
-            continue;
-        }
-        //Check the referenced object
-        _PTR(SObject) aRefSObject;
-        if ( aSO && aSO->ReferencedObject( aRefSObject ) )
-          aSO = aRefSObject; // Delete main Object instead of reference
-
-        // put the whole hierarchy of sub-objects of the selected SO into a list and
-        // then treat them all starting from the deepest objects (at list back)
-
-        std::list< _PTR(SObject) > listSO;
-        listSO.push_back( aSO );
-        std::list< _PTR(SObject) >::iterator itSO = listSO.begin();
-        for ( ; itSO != listSO.end(); ++itSO ) {
-          _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
-          for (it->InitEx(false); it->More(); it->Next())
-            listSO.push_back( it->Value() );
-        }
-
-        // treat SO's in the list starting from the back
-
-        std::list< _PTR(SObject) >::reverse_iterator ritSO = listSO.rbegin();
-        for ( ; ritSO != listSO.rend(); ++ritSO ) {
-          _PTR(SObject) SO = *ritSO;
-          if ( !SO ) continue;
-          std::string anEntry = SO->GetID();
-
-          /** Erase graphical object **/
-          if(SO->FindAttribute(anAttr, "AttributeIOR") && vm ){
-            QVector<SUIT_ViewWindow*> aViews = vm->getViews();
-            for(int i = 0; i < nbSf; i++){
-              SUIT_ViewWindow *sf = aViews[i];
-              if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
-                SMESH::RemoveActor(sf,anActor);
-              }
-            }
+      SALOME_ListIteratorOfListIO It(selected);
+      
+      aStudyBuilder->NewCommand();  // There is a transaction
+      for( ; It.More(); It.Next()){ // loop on selected IO's
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        if(IObject->hasEntry()) {
+          _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
+          
+          // disable removal of "SMESH" component object
+          if(aSO->FindAttribute(anAttr, "AttributeIOR")){
+            anIOR = anAttr;
+            if ( engineIOR() == anIOR->Value().c_str() )
+              continue;
           }
-
-          /** Remove an object from data structures **/
-          SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
-          SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
-          if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
-            SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
-            aMesh->RemoveGroup( aGroup );
+          //Check the referenced object
+          _PTR(SObject) aRefSObject;
+          if ( aSO && aSO->ReferencedObject( aRefSObject ) )
+            aSO = aRefSObject; // Delete main Object instead of reference
+          
+          // put the whole hierarchy of sub-objects of the selected SO into a list and
+          // then treat them all starting from the deepest objects (at list back)
+          
+          std::list< _PTR(SObject) > listSO;
+          listSO.push_back( aSO );
+          std::list< _PTR(SObject) >::iterator itSO = listSO.begin();
+          for ( ; itSO != listSO.end(); ++itSO ) {
+            _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
+            for (it->InitEx(false); it->More(); it->Next())
+              listSO.push_back( it->Value() );
           }
-          else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
-            SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-            aMesh->RemoveSubMesh( aSubMesh );
-
-            _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
-            if (aMeshSO)
-              SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
+          
+          // treat SO's in the list starting from the back
+          
+          std::list< _PTR(SObject) >::reverse_iterator ritSO = listSO.rbegin();
+          for ( ; ritSO != listSO.rend(); ++ritSO ) {
+            _PTR(SObject) SO = *ritSO;
+            if ( !SO ) continue;
+            std::string anEntry = SO->GetID();
+            
+            /** Erase graphical object **/
+          if(SO->FindAttribute(anAttr, "AttributeIOR")){
+            ViewManagerList aViewMenegers = anApp->viewManagers();
+            ViewManagerList::const_iterator it = aViewMenegers.begin();
+            for( ; it != aViewMenegers.end(); it++) {         
+              SUIT_ViewManager* vm = *it;
+              int nbSf = vm ? vm->getViewsCount() : 0;
+              if(vm) {
+                QVector<SUIT_ViewWindow*> aViews = vm->getViews();
+                for(int i = 0; i < nbSf; i++){
+                  SUIT_ViewWindow *sf = aViews[i];
+                  if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
+                    SMESH::RemoveActor(sf,anActor);
+                  }
+                }
+              }
+            }
           }
-          else {
-            IObject = new SALOME_InteractiveObject
-              ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
-            QString objType = CheckTypeObject(IObject);
-            if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
-              SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
-              aStudyBuilder->RemoveObjectWithChildren( SO );
+            /** Remove an object from data structures **/
+            SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
+            SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
+            if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
+              SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
+              aMesh->RemoveGroup( aGroup );
             }
-            else {// default action: remove SObject from the study
-              // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
-              //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
-              //op->start();
-              aStudyBuilder->RemoveObjectWithChildren( SO );
-              //op->finish();
+            else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
+              SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+              aMesh->RemoveSubMesh( aSubMesh );
+              
+              _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
+              if (aMeshSO)
+                SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
             }
-          }
-        } /* listSO back loop */
-      } /* IObject->hasEntry() */
-    } /* more/next */
+            else {
+              IObject = new SALOME_InteractiveObject
+                ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
+              QString objType = CheckTypeObject(IObject);
+              if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
+                SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+                aStudyBuilder->RemoveObjectWithChildren( SO );
+              }
+              else {// default action: remove SObject from the study
+                // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
+                //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
+                //op->start();
+                aStudyBuilder->RemoveObjectWithChildren( SO );
+                //op->finish();
+              }
+            }
+          } /* listSO back loop */
+        } /* IObject->hasEntry() */
+      } /* more/next */
+    
     aStudyBuilder->CommitCommand();
 
     /* Clear any previous selection */
@@ -1508,8 +1582,8 @@ LightApp_Module( "SMESH" )
 SMESHGUI::~SMESHGUI()
 {
 #ifdef WITHGENERICOBJ
-  SMESH::GetFilterManager()->Destroy();
-  SMESH::GetMeasurements()->Destroy();
+  SMESH::GetFilterManager()->UnRegister();
+  SMESH::GetMeasurements()->UnRegister();
 #endif
   SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
   SMESH::GetMeasurements() = SMESH::Measurements::_nil();
@@ -1799,6 +1873,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 113:                                     // IMPORT
   case 112:
   case 111:
+  case 140:
     {
       if(checkLock(aStudy)) break;
       ::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
@@ -1830,7 +1905,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 124:
   case 125:
   case 126:
-  case 140:
   case 141:
     {
       ::ExportMeshToFile(theCommandID);
@@ -1849,6 +1923,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         if( anIO->hasEntry() ) {
           if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
             anActor->SetControlMode( SMESH_Actor::eNone );
+#ifndef DISABLE_PLOT2DVIEWER
+            SMESH::ProcessIn2DViewers(anActor,SMESH::RemoveFrom2dViewer);
+#endif
           }
         }
       }
@@ -1859,20 +1936,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
       break;
     }
-  case 202:
+  case 2021:
     {
       // dump control distribution data to the text file
       ::SaveDistribution();
       break;
     }
 
-  case 203:
+  case 2022:
     {
       // show/ distribution
       ::ShowDistribution();
       break;
     }
 
+#ifndef DISABLE_PLOT2DVIEWER
+  case 2023:
+    {
+      // plot distribution
+      ::PlotDistribution();
+      break;
+    }
+#endif
+
     // Auto-color
   case 1136:
     ::AutoColor();
@@ -1967,7 +2053,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       if( theCommandID==302 )
       {
-       MESSAGE("anAction = SMESH::eDisplayOnly");
+        MESSAGE("anAction = SMESH::eDisplayOnly");
         startOperation( myEraseAll );
       }
 
@@ -1980,17 +2066,17 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         if (vtkwnd) {
           SALOME_ListIteratorOfListIO It( to_process );
           for ( ; It.More(); It.Next()) {
-               MESSAGE("---");
+                MESSAGE("---");
             Handle(SALOME_InteractiveObject) IOS = It.Value();
             if (IOS->hasEntry()) {
-               MESSAGE("---");
+                MESSAGE("---");
               if (!SMESH::UpdateView(anAction, IOS->getEntry())) {
                 SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
                 break; // PAL16774 (Crash after display of many groups)
               }
               if (anAction == SMESH::eDisplayOnly)
               {
-               MESSAGE("anAction = SMESH::eDisplayOnly");
+                MESSAGE("anAction = SMESH::eDisplayOnly");
                 anAction = SMESH::eDisplay;
               }
             }
@@ -1999,7 +2085,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
         // PAL13338 + PAL15161 -->
         if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) {
-               MESSAGE("anAction = SMESH::eDisplayOnly");
+                MESSAGE("anAction = SMESH::eDisplayOnly");
           SMESH::UpdateView();
           SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
         }
@@ -2010,7 +2096,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if (anAction == SMESH::eErase) {
-       MESSAGE("anAction == SMESH::eErase");
+        MESSAGE("anAction == SMESH::eErase");
         SALOME_ListIO l1;
         aSel->setSelectedObjects( l1 );
       }
@@ -2783,7 +2869,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IOS);
       if ( aMesh->_is_nil()) continue;
       try {
-        SMESH::UpdateView(SMESH::eErase, IOS->getEntry());
+        SMESH::RemoveVisualObjectWithActors(IOS->getEntry(), true);
         aMesh->Clear();
         _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh);
         SMESH::ModifiedMesh( aMeshSObj, false, true);
@@ -2793,7 +2879,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
         {
           _PTR(SObject) so = anIter->Value();
-          SMESH::UpdateView(SMESH::eErase, so->GetID().c_str());
+          SMESH::RemoveVisualObjectWithActors(so->GetID().c_str(), true);
         }
       }
       catch (const SALOME::SALOME_Exception& S_ex){
@@ -3319,8 +3405,11 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  419, "SPLIT_TO_TETRA",  "ICON_SPLIT_TO_TETRA" );
   createSMESHAction(  200, "RESET" );
   createSMESHAction(  201, "SCALAR_BAR_PROP" );
-  createSMESHAction(  202, "SAVE_DISTRIBUTION" );
-  createSMESHAction(  203, "SHOW_DISTRIBUTION","",0, true );
+  createSMESHAction(  2021, "SAVE_DISTRIBUTION" );
+  createSMESHAction(  2022, "SHOW_DISTRIBUTION","",0, true );
+#ifndef DISABLE_PLOT2DVIEWER
+  createSMESHAction(  2023, "PLOT_DISTRIBUTION" );
+#endif
   createSMESHAction(  211, "WIRE",           "ICON_WIRE", 0, true );
   createSMESHAction(  212, "SHADE",          "ICON_SHADE", 0, true );
   createSMESHAction(  213, "SHRINK",         "ICON_SHRINK", 0, true );
@@ -3391,11 +3480,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 111, importId, -1 );
   createMenu( 112, importId, -1 );
   createMenu( 113, importId, -1 );
+  createMenu( 140, importId, -1 );
 
   createMenu( 121, exportId, -1 );
   createMenu( 122, exportId, -1 );
   createMenu( 123, exportId, -1 );
-  createMenu( 140, exportId, -1 ); // export to stl STL
+  createMenu( 141, exportId, -1 ); // export to stl STL
 
   createMenu( separator(), fileId, 10 );
 
@@ -3487,10 +3577,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4061, transfId, -1 );
   createMenu( 4062, transfId, -1 );
   createMenu( 4063, transfId, -1 );
+  createMenu( 4068, transfId, -1 );
   createMenu( 4064, transfId, -1 );
   createMenu( 4065, transfId, -1 );
   createMenu( 4066, transfId, -1 );
-  createMenu( 4068, transfId, -1 );
   createMenu( 4069, transfId, -1 );
 
   createMenu( 4067,modifyId, -1 );
@@ -3598,10 +3688,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 4061, addRemTb );
   createTool( 4062, addRemTb );
   createTool( 4063, addRemTb );
+  createTool( 4068, addRemTb );
   createTool( 4064, addRemTb );
   createTool( 4065, addRemTb );
   createTool( 4066, addRemTb );
-  createTool( 4068, addRemTb );
   createTool( 4069, addRemTb );
   createTool( separator(), addRemTb );
 
@@ -3676,7 +3766,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 900, OB, mesh_group );                  // ADV_INFO
   //createPopupItem( 902, OB, mesh );                        // STD_INFO
   createPopupItem( 903, OB, mesh_group );                  // WHAT_IS
-  createPopupItem( 904, OB, mesh_group );                  // FIND_ELEM
+  createPopupItem( 904, OB, mesh );                        // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 801, OB, mesh );                        // CREATE_GROUP
   createPopupItem( 806, OB, mesh );                        // CREATE_GEO_GROUP
@@ -3688,8 +3778,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 4043, OB, mesh );                       // CLEAR_MESH
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( 417, OB, mesh/*, "&& " + hasElems*/);       // convert to quadratic
-  createPopupItem( 418, OB, mesh/*, "&& " + hasVolumes*/);     // create 2D mesh on 3D
+  createPopupItem( 417, OB, mesh + " " + subMesh );         // convert to quadratic
+  createPopupItem( 418, OB, mesh/*, "&& " + hasVolumes*/);  // create 2D mesh on 3D
   popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
@@ -3712,7 +3802,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 900, View, mesh_group ); // ADV_INFO
   //createPopupItem( 902, View, mesh );       // STD_INFO
   createPopupItem( 903, View, mesh_group ); // WHAT_IS
-  createPopupItem( 904, View, mesh_group ); // FIND_ELEM
+  createPopupItem( 904, View, mesh );       // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
 
   createPopupItem( 1136, OB + " " + View, mesh, "&& (not isAutoColor)" ); // AUTO_COLOR
@@ -3947,19 +4037,24 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), anId, -1 );
 
-  popupMgr()->insert( action( 202 ), anId, -1 ); // SAVE_DISTRIBUTION
-  popupMgr()->setRule( action( 202 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+  aSubId = popupMgr()->insert( tr( "MEN_DISTRIBUTION_CTRL" ), anId, -1 ); // NODE CONTROLS
 
-  popupMgr()->insert( action( 203 ), anId, -1 ); // SHOW_DISTRIBUTION
-  popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
+  popupMgr()->insert( action( 2021 ), aSubId, -1 ); // SAVE_DISTRIBUTION
+  popupMgr()->setRule( action( 2021 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
 
+  popupMgr()->insert( action( 2022 ), aSubId, -1 ); // SHOW_DISTRIBUTION
+  popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
 
-  popupMgr()->insert( separator(), -1, -1 );
+#ifndef DISABLE_PLOT2DVIEWER
+  popupMgr()->insert( action( 2023 ), aSubId, -1 ); // PLOT_DISTRIBUTION
+  popupMgr()->setRule( action( 2023 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+#endif
 
   //-------------------------------------------------
   // Display / Erase
   //-------------------------------------------------
+  popupMgr()->insert( separator(), -1, -1 );
   QString aRule = "$component={'SMESH'} and ( type='Component' or (" + aClient + " and " +
     aType + " and " + aSelCount + " and " + anActiveVTK + " and " + isNotEmpty + " %1 ) )";
   popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY
@@ -4056,6 +4151,16 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
       GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
       updateObjBrowser(); // objects can be removed
     }
+  
+  // get all view currently opened in the study and connect their signals  to
+  // the corresponding slots of the class.
+  SUIT_Desktop* aDesk = study->application()->desktop();
+  if ( aDesk ) {
+    QList<SUIT_ViewWindow*> wndList = aDesk->windows();
+    SUIT_ViewWindow* wnd;
+    foreach ( wnd, wndList )
+      connectView( wnd );
+  }
 
   return res;
 }
@@ -4153,8 +4258,15 @@ void SMESHGUI::viewManagers( QStringList& list ) const
 
 void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
 {
-  if ( dynamic_cast<SVTK_ViewManager*>( mgr ) )
+  if ( dynamic_cast<SVTK_ViewManager*>( mgr ) ) {
     SMESH::UpdateSelectionProp( this );
+    
+    QVector<SUIT_ViewWindow*> aViews = mgr->getViews();
+    for(int i = 0; i < aViews.count() ; i++){
+      SUIT_ViewWindow *sf = aViews[i];
+      connectView( sf );
+    }
+  }
 }
 
 void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
@@ -5602,3 +5714,34 @@ void SMESHGUI::onHypothesisEdit( int result )
     SMESHGUI::Modified();
   updateObjBrowser( true );
 }
+
+
+/*!
+  \brief Signal handler closing(SUIT_ViewWindow*) of a view
+  \param pview view being closed
+*/
+void SMESHGUI::onViewClosed( SUIT_ViewWindow* pview ) {
+#ifndef DISABLE_PLOT2DVIEWER
+  //Crear all Plot2d Viewers if need.
+  SMESH::ClearPlot2Viewers(pview);
+#endif  
+}
+
+/*!
+  \brief Connects or disconnects signals about activating and cloning view on the module slots
+  \param pview view which is connected/disconnected
+*/
+void SMESHGUI::connectView( const SUIT_ViewWindow* pview ) {
+  if(!pview)
+    return;
+  
+  SUIT_ViewManager* viewMgr = pview->getViewManager();
+  if ( viewMgr ) {
+    disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+                this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+    
+    connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+             this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+  }
+}