Salome HOME
Unicode support
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index 28df5fdbfaef7aff9e6b8a3a28e154cd365ad5f6..493b734bb144759ea436447652610fc438a5af65 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #undef HAVE_FINITE            // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
 #endif
 #include "Python.h"
+
 //  SMESH includes
 #include "SMESHGUI.h"
+#include "SMESHGUI_Add0DElemsOnAllNodesDlg.h"
 #include "SMESHGUI_AddMeshElementDlg.h"
 #include "SMESHGUI_AddQuadraticElementDlg.h"
 #include "SMESHGUI_BuildCompoundDlg.h"
 #include "SMESHGUI_ClippingDlg.h"
 #include "SMESHGUI_ComputeDlg.h"
 #include "SMESHGUI_ConvToQuadOp.h"
+#include "SMESHGUI_CopyMeshDlg.h"
 #include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
 #include "SMESHGUI_DeleteGroupDlg.h"
 #include "SMESHGUI_Displayer.h"
-#include "SMESHGUI_MergeDlg.h"
+#include "SMESHGUI_DuplicateNodesDlg.h"
 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
 #include "SMESHGUI_ExtrusionDlg.h"
+#include "SMESHGUI_FieldSelectorWdg.h"
 #include "SMESHGUI_FileInfoDlg.h"
 #include "SMESHGUI_FileValidator.h"
 #include "SMESHGUI_FilterDlg.h"
@@ -53,6 +57,7 @@
 #include "SMESHGUI_Make2DFrom3DOp.h"
 #include "SMESHGUI_MakeNodeAtPointDlg.h"
 #include "SMESHGUI_Measurements.h"
+#include "SMESHGUI_MergeDlg.h"
 #include "SMESHGUI_MeshInfo.h"
 #include "SMESHGUI_MeshOp.h"
 #include "SMESHGUI_MeshOrderOp.h"
 #include "SMESHGUI_RemoveElementsDlg.h"
 #include "SMESHGUI_RemoveNodesDlg.h"
 #include "SMESHGUI_RenumberingDlg.h"
+#include "SMESHGUI_ReorientFacesDlg.h"
 #include "SMESHGUI_RevolutionDlg.h"
 #include "SMESHGUI_RotationDlg.h"
+#include "SMESHGUI_ScaleDlg.h"
 #include "SMESHGUI_Selection.h"
 #include "SMESHGUI_SewingDlg.h"
 #include "SMESHGUI_SingleEditDlg.h"
 #include "SMESHGUI_SmoothingDlg.h"
 #include "SMESHGUI_SymmetryDlg.h"
 #include "SMESHGUI_TranslationDlg.h"
-#include "SMESHGUI_ScaleDlg.h"
 #include "SMESHGUI_TransparencyDlg.h"
-#include "SMESHGUI_DuplicateNodesDlg.h"
-#include "SMESHGUI_CopyMeshDlg.h"
-#include "SMESHGUI_ReorientFacesDlg.h"
 
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_GroupUtils.h"
 #include "SMESHGUI_FilterUtils.h"
+#include "SMESHGUI_GroupUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+#include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_PatternUtils.h"
+#include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_HypothesesUtils.h"
 
 #include <SMESH_version.h>
 
-#include <SMESH_Client.hxx>
+#include "SMESH_ControlsDef.hxx"
 #include <SMESH_Actor.h>
-#include <SMESH_ScalarBarActor.h>
 #include <SMESH_ActorUtils.h>
+#include <SMESH_Client.hxx>
+#include <SMESH_ScalarBarActor.h>
 #include <SMESH_TypeFilter.hxx>
-#include "SMESH_ControlsDef.hxx"
 
 // SALOME GUI includes
-#include <SalomeApp_Tools.h>
-#include <SalomeApp_Study.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_CheckFileDlg.h>
 #include <SalomeApp_DataObject.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_Tools.h>
 
 #include <LightApp_DataOwner.h>
+#include <LightApp_NameDlg.h>
 #include <LightApp_Preferences.h>
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_UpdateFlags.h>
-#include <LightApp_NameDlg.h>
 
-#include <SVTK_ViewWindow.h>
-#include <SVTK_ViewModel.h>
 #include <SVTK_ViewManager.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 
 #include <VTKViewer_Algorithm.h>
 
-#include <SUIT_MessageBox.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_FileDlg.h>
+#include <PyInterp_Interp.h>
+
 #include <SUIT_Desktop.h>
+#include <SUIT_FileDlg.h>
+#include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
 #include <SUIT_Session.h>
 
 #include <QtxPopupMgr.h>
 #include <boost/shared_ptr.hpp>
 
 // VTK includes
-#include <vtkCamera.h>
-#include <vtkRenderer.h>
-#include <vtkPlane.h>
 #include <vtkCallbackCommand.h>
+#include <vtkCamera.h>
 #include <vtkLookupTable.h>
+#include <vtkPlane.h>
+#include <vtkRenderer.h>
 
 // SALOME KERNEL includes
-#include <SALOMEDS_Study.hxx>
-#include <SALOMEDSClient_StudyBuilder.hxx>
-#include <SALOMEDSClient_SComponent.hxx>
 #include <SALOMEDSClient_ClientFactory.hxx>
 #include <SALOMEDSClient_IParameters.hxx>
+#include <SALOMEDSClient_SComponent.hxx>
+#include <SALOMEDSClient_StudyBuilder.hxx>
+#include <SALOMEDS_Study.hxx>
+#include <SALOMEDS_SObject.hxx>
 
 // OCCT includes
 #include <Standard_ErrorHandler.hxx>
 #include <NCollection_DataMap.hxx>
 
+#include <Basics_Utils.hxx>
+
 //To disable automatic genericobj management, the following line should be commented.
-//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+//Otherwise, it should be uncommented.
+//Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
 #define WITHGENERICOBJ
 
-//namespace{
+// Below macro, when uncommented, switches on simplified (more performant) algorithm
+// of auto-color picking up
+#define SIMPLE_AUTOCOLOR
+
+namespace
+{
   // Declarations
   //=============================================================
   void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh,
 
   void Control( int theCommandID );
 
-
   // Definitions
-  //=============================================================
+  //================================================================================
+  /*!
+   * \brief Reads meshes from file
+   */
+  //================================================================================
+
   void ImportMeshesFromFile( SMESH::SMESH_Gen_ptr theComponentMesh,
                              int theCommandID )
   {
     std::string myExtension;
 
     if ( theCommandID == 113 ) {
-      filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.med)" );
+      filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.*med)" );
       filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
     }
     else if ( theCommandID == 112 ) {
       filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
     }
     else if ( theCommandID == 115 ) {
-      filter.append( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
+      filter.append( QObject::tr( "STL_FILES_FILTER" ) + " (*.stl)" );
     }
     else if ( theCommandID == 116 ) {
       filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
       anInitialPath = QDir::currentPath();
 
-    QStringList filenames = SUIT_FileDlg::getOpenFileNames( SMESHGUI::desktop(),
-                                                            anInitialPath,
-                                                            filter,
-                                                            QObject::tr( "SMESH_IMPORT_MESH" ) );
+    QStringList filenames;
+    bool toCreateGroups = true;
+
+    // if ( theCommandID == 118 ) { // GMF
+    //   SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg
+    //     ( SMESHGUI::desktop(), true, QObject::tr("SMESH_REQUIRED_GROUPS"), true, true );
+    //   fd->setWindowTitle( QObject::tr( "SMESH_IMPORT_MESH" ) );
+    //   fd->setNameFilters( filter );
+    //   fd->SetChecked( true );
+    //   if ( fd->exec() )
+    //     filenames << fd->selectedFile();
+    //   toCreateGroups = fd->IsChecked();
+
+    //   delete fd;
+    // }
+    // else
+    {
+      filenames = SUIT_FileDlg::getOpenFileNames( SMESHGUI::desktop(),
+                                                  anInitialPath,
+                                                  filter,
+                                                  QObject::tr( "SMESH_IMPORT_MESH" ) );
+    }
     if ( filenames.count() > 0 ) {
       SUIT_OverrideCursor wc;
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
             {
               // UNV format
               aMeshes->length( 1 );
-              aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toLatin1().constData() );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toUtf8().constData() );
               if ( aMeshes[0]->_is_nil() )
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
             {
               // MED format
               SMESH::DriverMED_ReadStatus res;
-              aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toLatin1().constData(), res );
+              aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toUtf8().constData(), res );
               if ( res != SMESH::DRS_OK ) {
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
             {
               // STL format
               aMeshes->length( 1 );
-              aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toLatin1().constData() );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toUtf8().constData() );
               if ( aMeshes[0]->_is_nil() ) {
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
             {
               // CGNS format
               SMESH::DriverMED_ReadStatus res;
-              aMeshes = theComponentMesh->CreateMeshesFromCGNS( filename.toLatin1().constData(), res );
+              aMeshes = theComponentMesh->CreateMeshesFromCGNS( filename.toUtf8().constData(), res );
               if ( res != SMESH::DRS_OK ) {
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
             {
               // SAUV format
               SMESH::DriverMED_ReadStatus res;
-              aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toLatin1().constData(), res );
+              aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toUtf8().constData(), res );
               if ( res != SMESH::DRS_OK ) {
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
               // GMF format
               SMESH::ComputeError_var res;
               aMeshes->length( 1 );
-              aMeshes[0] = theComponentMesh->CreateMeshesFromGMF( filename.toLatin1().constData(), res.out() );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromGMF( filename.toUtf8().constData(),
+                                                                  toCreateGroups,
+                                                                  res.out() );
               if ( res->code != SMESH::DRS_OK ) {
                 errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
                                arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res->code ).toLatin1().data() ) ) );
               SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
 
             anEntryList.append( aMeshSO->GetID().c_str() );
-
-#ifdef WITHGENERICOBJ
-            // 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]->UnRegister();
-#endif
           }
           else {
             isEmpty = true;
     if ( isDAT )
     {
       format = "DAT";
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Quadrangle );
-      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
-      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
-      notSupportedElemTypes.push_back( SMESH::Entity_Tetra );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Tetra );
-      notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Hexa );
-      notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
-      notSupportedElemTypes.push_back( SMESH::Entity_Penta );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
-      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
-      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
       notSupportedElemTypes.push_back( SMESH::Entity_0D );
       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
     }
     {
       format = "CGNS";
       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
     }
     else if ( isSAUV )
     {
       format = "SAUV";
       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
       notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
       notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
     {
       format = "GMF";
       notSupportedElemTypes.push_back( SMESH::Entity_0D );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Quadrangle );
       notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
-      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Hexa );
       notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
       notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
     if ( !presentNotSupported.empty() )
     {
       QString typeNames;
-      const char* typeMsg[SMESH::Entity_Last] = { "SMESH_NODES",
-        "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES","SMESH_TRIANGLES",
-        "SMESH_QUADRATIC_TRIANGLES","SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES",
-        "SMESH_BIQUADRATIC_QUADRANGLES","SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS",
+      const char* typeMsg[SMESH::Entity_Last] = {
+        "SMESH_NODES", "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES",
+        "SMESH_TRIANGLES", "SMESH_QUADRATIC_TRIANGLES", "SMESH_BIQUADRATIC_TRIANGLES",
+        "SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES", "SMESH_BIQUADRATIC_QUADRANGLES",
+        "SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS",
         "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
         "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
         "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
     if ( resMgr )
       toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
     bool toOverwrite = true;
+    bool toFindOutDim = true;
 
     QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH");
     QString anInitialPath = "";
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
       anInitialPath = QDir::currentPath();
 
+    QList< QPair< GEOM::ListOfFields_var, QString > > aFieldList;
+
     // Get a file name to write in and additional otions
     if ( isUNV || isDAT || isGMF ) // Export w/o options
     {
       else if ( isGMF )
         aFilter = QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)" +
           ";;" +  QObject::tr( "GMF_BINARY_FILES_FILTER" )  + " (*.meshb)";
-      if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath();
+     if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath();
       aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(),
                                             anInitialPath + QString("/") + aMeshName,
                                             aFilter, aTitle, false);
         if (it.value() == SMESH::MED_V2_2)
           aDefaultFilter = it.key();
       }
+      QStringList checkBoxes;
+      checkBoxes << QObject::tr("SMESH_AUTO_GROUPS") << QObject::tr("SMESH_AUTO_DIM");
 
-      SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg
-        ( SMESHGUI::desktop(), false, QObject::tr("SMESH_AUTO_GROUPS"), true, true );
+      SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
+      QList< QWidget* > wdgList;
+      if ( fieldSelWdg->GetAllFeilds( aMeshList, aFieldList ))
+        wdgList.append( fieldSelWdg );
+
+      SalomeApp_CheckFileDlg* fd =
+        new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true, wdgList );
       fd->setWindowTitle( aTitle );
       fd->setNameFilters( filters );
-      fd->selectNameFilter(aDefaultFilter);
-      fd->SetChecked(toCreateGroups);
+      fd->selectNameFilter( aDefaultFilter );
+      fd->SetChecked( toCreateGroups, 0 );
+      fd->SetChecked( toFindOutDim,   1 );
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
       fd->selectFile(aMeshName);
           if( !toOverwrite ) {
             // can't append to an existing using other format
             SMESH::MED_VERSION aVersion = SMESH::MED_V2_1;
-            bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toLatin1().constData(), aVersion );
+            bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toUtf8().constData(), aVersion );
             if( !isVersionOk || aVersion != aFormat ) {
               int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
                                                   QObject::tr("SMESH_WRN_WARNING"),
             }
 
             QStringList aMeshNamesCollisionList;
-            SMESH::string_array_var aMeshNames = SMESHGUI::GetSMESHGen()->GetMeshNames( aFilename.toLatin1().constData() );
+            SMESH::string_array_var aMeshNames = SMESHGUI::GetSMESHGen()->GetMeshNames( aFilename.toUtf8().constData() );
             for( int i = 0, n = aMeshNames->length(); i < n; i++ ) {
               QString anExistingMeshName( aMeshNames[ i ] );
               for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
           }
         }
       }
-      toCreateGroups = fd->IsChecked();
+      toCreateGroups = fd->IsChecked(0);
+      toFindOutDim   = fd->IsChecked(1);
+      fieldSelWdg->GetSelectedFeilds();
+      if ( !fieldSelWdg->parent() )
+        delete fieldSelWdg;
       delete fd;
     }
     else
           {
             SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
-            if ( aMeshOrGroup->_is_equivalent( aMeshItem ))
-              aMeshItem->ExportToMEDX( aFilename.toLatin1().data(), toCreateGroups,
-                                       aFormat, toOverwrite && aMeshIndex == 0 );
+            const GEOM::ListOfFields&       fields = aFieldList[ aMeshIndex ].first.in();
+            const QString&            geoAssFields = aFieldList[ aMeshIndex ].second;
+            const bool                   hasFields = ( fields.length() || !geoAssFields.isEmpty() );
+            if ( !hasFields && aMeshOrGroup->_is_equivalent( aMeshItem ))
+              aMeshItem->ExportToMEDX( aFilename.toUtf8().data(), toCreateGroups,
+                                       aFormat, toOverwrite && aMeshIndex == 0, toFindOutDim );
             else
-              aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toLatin1().data(), toCreateGroups,
-                                          aFormat, toOverwrite && aMeshIndex == 0 );
+              aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toUtf8().data(), toCreateGroups,
+                                          aFormat, toOverwrite && aMeshIndex == 0, toFindOutDim,
+                                          fields, geoAssFields.toLatin1().data() );
           }
         }
         else if ( isSAUV )
           {
             SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first );
             if( !aMeshItem->_is_nil() )
-              aMeshItem->ExportSAUV( aFilename.toLatin1().data(), toCreateGroups );
+              aMeshItem->ExportSAUV( aFilename.toUtf8().data(), toCreateGroups );
           }
         }
         else if ( isDAT )
         {
           if ( aMeshOrGroup->_is_equivalent( aMesh ))
-            aMesh->ExportDAT( aFilename.toLatin1().data() );
+            aMesh->ExportDAT( aFilename.toUtf8().data() );
           else
-            aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toLatin1().data() );
+            aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toUtf8().data() );
         }
         else if ( isUNV )
         {
           if ( aMeshOrGroup->_is_equivalent( aMesh ))
-            aMesh->ExportUNV( aFilename.toLatin1().data() );
+            aMesh->ExportUNV( aFilename.toUtf8().data() );
           else
-            aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toLatin1().data() );
+            aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toUtf8().data() );
         }
         else if ( isSTL )
         {
           if ( aMeshOrGroup->_is_equivalent( aMesh ))
-            aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL );
+            aMesh->ExportSTL( aFilename.toUtf8().data(), aIsASCII_STL );
           else
-            aMesh->ExportPartToSTL( aMeshOrGroup, aFilename.toLatin1().data(), aIsASCII_STL );
+            aMesh->ExportPartToSTL( aMeshOrGroup, aFilename.toUtf8().data(), aIsASCII_STL );
         }
         else if ( isCGNS )
         {
             SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
             aMeshItem->ExportCGNS( aMeshOrGroup,
-                                   aFilename.toLatin1().data(),
+                                   aFilename.toUtf8().data(),
                                    toOverwrite && aMeshIndex == 0 );
           }
         }
         else if ( isGMF )
         {
-          aMesh->ExportGMF( aMeshOrGroup, aFilename.toLatin1().data() );
+          toCreateGroups = true;
+          aMesh->ExportGMF( aMeshOrGroup, aFilename.toUtf8().data(), toCreateGroups );
         }
       }
       catch (const SALOME::SALOME_Exception& S_ex){
     }
   }
 
-  void AutoColor(){
+  void AutoColor()
+  {
     SALOME_ListIO selected;
     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
     if( !app )
     if( aMainObject->_is_nil() )
       return;
 
+    SUIT_OverrideCursor wc;
+
     aMainObject->SetAutoColor( true ); // mesh groups are re-colored here
 
+    QList<SALOMEDS::Color> aReservedColors;
+
     SMESH::ListOfGroups aListOfGroups = *aMainObject->GetGroups();
     for( int i = 0, n = aListOfGroups.length(); i < n; i++ )
     {
       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
-      SALOMEDS::Color aColor = aGroupObject->GetColor();
+      //SALOMEDS::Color aColor = aGroupObject->GetColor();
+
+#ifdef SIMPLE_AUTOCOLOR   // simplified algorithm for auto-colors
+      SALOMEDS::Color aColor = SMESHGUI::getPredefinedUniqueColor();
+#else                     // old algorithm  for auto-colors
+      SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
+      aReservedColors.append( aColor );
+#endif                    // SIMPLE_AUTOCOLOR
+      aGroupObject->SetColor( aColor );
+
       _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject);
       if (aGroupSObject) {
         QColor c;
     SMESH::RepaintCurrentView();
   }
 
+  void OverallMeshQuality() {
+    SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+    LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    if ( selected.IsEmpty() ) return;
+    SALOME_ListIteratorOfListIO It( selected );
+    for ( ; It.More(); It.Next() ) {
+      SMESHGUI_CtrlInfoDlg* ctrlDlg = new SMESHGUI_CtrlInfoDlg( SMESHGUI::desktop() );
+      ctrlDlg->showInfo( It.Value() );
+      ctrlDlg->show();
+    }
+  }
+
   QString functorToString( SMESH::Controls::FunctorPtr f )
   {
     QString type = QObject::tr( "UNKNOWN_CONTROL" );
               vtkLookupTable* lookupTable =
                 static_cast<vtkLookupTable*>(aScalarBarActor->GetLookupTable());
               double * minmax = lookupTable->GetRange();
+              bool isLogarithmic = lookupTable->GetScale() == VTK_SCALE_LOG10;
               std::vector<int>    nbEvents;
               std::vector<double> funValues;
-              aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax );
+              aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax, isLogarithmic );
               QString anInitialPath = "";
               if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
                 anInitialPath = QDir::currentPath();
     }
   }
 
+  void sortChildren(){
+    LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel ) {
+      aSel->selectedObjects( selected );
+
+      if(selected.Extent()){
+        Handle(SALOME_InteractiveObject) anIObject = selected.First();
+        _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+        _PTR(SObject) aSObj = aStudy->FindObjectID(anIObject->getEntry());
+        if (aSObj) {
+          if ( aStudy->GetUseCaseBuilder()->SortChildren( aSObj, true/*AscendingOrder*/ ) ) {
+            SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+          }
+        }
+      }
+    }
+  }
+
   void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap)
   {
     SALOME_ListIO selected;
         return;
       }
       case 1132: {
-        vtkFloatingPointType color[3];
+        double color[3];
         QColor faceColor, edgeColor, nodeColor, elem0dColor, ballColor;
         QColor orientationColor, outlineColor, volumeColor;
         int deltaF = 0, deltaV = 0;
         int elem0dSize   = 1;
         int ballSize     = 1;
+        double ballScale = 1.0;
         int edgeWidth    = 1;
         int outlineWidth = 1;
-        vtkFloatingPointType shrinkCoef = 0.0;
-        vtkFloatingPointType orientationScale = 0.0;
+        double shrinkCoef = 0.0;
+        double orientationScale = 0.0;
         bool orientation3d = false;
         VTK::MarkerType markerType = VTK::MT_NONE;
         VTK::MarkerScale markerScale = VTK::MS_NONE;
             anActor->GetBallColor( color[0], color[1], color[2] );
             ballColor.setRgbF( color[0], color[1], color[2] );
             ballSize = qMax( (int)anActor->GetBallSize(), 1 ); // minimum allowed size is 1
+            ballScale = qMax( (double)anActor->GetBallScale(), 1e-2 ); // minimum allowed scale is 1e-2
             // outlines: color
             anActor->GetOutlineColor( color[0], color[1], color[2] );
             outlineColor.setRgbF( color[0], color[1], color[2] );
         // balls: color, size
         dlg.setBallColor( ballColor );
         dlg.setBallSize( ballSize );
+        dlg.setBallScale( ballScale );
         // orientation: color, scale, 3d flag
         dlg.setOrientationColor( orientationColor );
         dlg.setOrientationSize( int( orientationScale * 100. ) );
           elem0dSize       = dlg.elem0dSize();
           ballColor        = dlg.ballColor();
           ballSize         = dlg.ballSize();
+          ballScale        = dlg.ballScale();
           orientationColor = dlg.orientationColor();
           orientationScale = dlg.orientationSize() / 100.;
           orientation3d    = dlg.orientation3d();
             // balls: color, size
             anActor->SetBallColor( ballColor.redF(), ballColor.greenF(), ballColor.blueF() );
             anActor->SetBallSize( ballSize );
+            anActor->SetBallScale( ballScale );
             // orientation: color, scale, 3d flag
             anActor->SetFacesOrientationColor( orientationColor.redF(), orientationColor.greenF(), orientationColor.blueF() );
             anActor->SetFacesOrientationScale( orientationScale );
             aControl = SMESH_Actor::eCoincidentElems3D;
             break;
           }
-            
+
           anActor->SetControlMode(aControl);
           anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
           SMESH::RepaintCurrentView();
 
 
   bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO,
-                   MeshObjectType                           theType,
+                   SMESH::MeshObjectType                           theType,
                    const QString                            theInTypeName,
                    QString &                                theOutTypeName)
   {
 
     QString aTypeName;
     if (
-        CheckOIType ( theIO, HYPOTHESIS,    "Hypothesis", aTypeName ) ||
-        CheckOIType ( theIO, ALGORITHM,     "Algorithm",  aTypeName ) ||
-        CheckOIType ( theIO, MESH,          "Mesh",       aTypeName ) ||
-        CheckOIType ( theIO, SUBMESH,       "SubMesh",    aTypeName ) ||
-        CheckOIType ( theIO, GROUP,         "Group",      aTypeName )
+        CheckOIType ( theIO, SMESH::HYPOTHESIS,    "Hypothesis", aTypeName ) ||
+        CheckOIType ( theIO, SMESH::ALGORITHM,     "Algorithm",  aTypeName ) ||
+        CheckOIType ( theIO, SMESH::MESH,          "Mesh",       aTypeName ) ||
+        CheckOIType ( theIO, SMESH::SUBMESH,       "SubMesh",    aTypeName ) ||
+        CheckOIType ( theIO, SMESH::GROUP,         "Group",      aTypeName )
         )
       return aTypeName;
 
     QString RefType = CheckTypeObject(selected.First());
     SALOME_ListIteratorOfListIO It(selected);
     for ( ; It.More(); It.Next())
-      {
-        Handle(SALOME_InteractiveObject) IObject = It.Value();
-        QString Type = CheckTypeObject(IObject);
-        if (Type.compare(RefType) != 0)
-          return "Heterogeneous Selection";
-      }
+    {
+      Handle(SALOME_InteractiveObject) IObject = It.Value();
+      QString Type = CheckTypeObject(IObject);
+      if (Type.compare(RefType) != 0)
+        return "Heterogeneous Selection";
+    }
 
     return RefType;
   }
 
+} //namespace
 
-  void SMESHGUI::OnEditDelete()
-  {
-    // VSR 17/11/04: check if all objects selected belong to SMESH component --> start
-    LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
-    SALOME_ListIO selected; aSel->selectedObjects( selected, QString::null, false );
+void SMESHGUI::OnEditDelete()
+{
+  // VSR 17/11/04: check if all objects selected belong to SMESH component --> start
+  LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+  SALOME_ListIO selected; aSel->selectedObjects( selected, QString::null, false );
 
-    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-    _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
-    _PTR(GenericAttribute) anAttr;
-    _PTR(AttributeIOR) anIOR;
-
-    int objectCount = 0;
-    QString aNameList;
-    QString aParentComponent = QString::null;
-    Handle(SALOME_InteractiveObject) anIO;
-    for( SALOME_ListIteratorOfListIO anIt( selected ); anIt.More(); anIt.Next() )
-    {
-      anIO = anIt.Value();
-      QString cur = anIO->getComponentDataType();
-      _PTR(SObject) aSO = aStudy->FindObjectID(anIO->getEntry());
-      if (aSO) {
-        // check if object is reference
-        _PTR(SObject) aRefSObj;
-        aNameList.append("\n    - ");
-        if ( aSO->ReferencedObject( aRefSObj ) ) {
-          QString aRefName = QString::fromStdString ( aRefSObj->GetName() );
-          aNameList.append( aRefName );
-          cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() );
-        }
-        else
-          aNameList.append(anIO->getName());
-        objectCount++;
-      }
+  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+  _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeIOR) anIOR;
 
-      if( aParentComponent.isNull() )
-        aParentComponent = cur;
-      else if( !aParentComponent.isEmpty() && aParentComponent!=cur )
-        aParentComponent = "";
+  int objectCount = 0;
+  QString aNameList;
+  QString aParentComponent = QString::null;
+  Handle(SALOME_InteractiveObject) anIO;
+  for( SALOME_ListIteratorOfListIO anIt( selected ); anIt.More(); anIt.Next() )
+  {
+    anIO = anIt.Value();
+    QString cur = anIO->getComponentDataType();
+    _PTR(SObject) aSO = aStudy->FindObjectID(anIO->getEntry());
+    if (aSO) {
+      // check if object is reference
+      _PTR(SObject) aRefSObj;
+      aNameList.append("\n    - ");
+      if ( aSO->ReferencedObject( aRefSObj ) ) {
+        QString aRefName = QString::fromStdString ( aRefSObj->GetName() );
+        aNameList.append( aRefName );
+        cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() );
+      }
+      else
+        aNameList.append(anIO->getName());
+      objectCount++;
     }
 
-    if ( objectCount == 0 )
-      return; // No Valid Objects Selected
+    if( aParentComponent.isNull() )
+      aParentComponent = cur;
+    else if( !aParentComponent.isEmpty() && aParentComponent!=cur )
+      aParentComponent = "";
+  }
 
-    if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() )  {
-      SUIT_MessageBox::warning( SMESHGUI::desktop(),
-                                QObject::tr("ERR_ERROR"),
-                                QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) );
-      return;
-    }
-    // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
-    if (SUIT_MessageBox::warning
-        (SMESHGUI::desktop(),
-         QObject::tr("SMESH_WRN_WARNING"),
-         QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ),
-         SUIT_MessageBox::Yes | SUIT_MessageBox::No,
-         SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes)
-      return;
+  if ( objectCount == 0 )
+    return; // No Valid Objects Selected
 
-    SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() )  {
+    SUIT_MessageBox::warning( SMESHGUI::desktop(),
+                              QObject::tr("ERR_ERROR"),
+                              QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) );
+    return;
+  }
+  // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
+  if (SUIT_MessageBox::warning
+      (SMESHGUI::desktop(),
+       QObject::tr("SMESH_WRN_WARNING"),
+       QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ),
+       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+       SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes)
+    return;
 
-    // Put the whole hierarchy of sub-objects of the selected SO's into a list and
-    // then treat them all starting from the deepest objects (at list back)
-    std::list< _PTR(SObject) > listSO;
-    SALOME_ListIteratorOfListIO It(selected);
-    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
-
-        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() );
-        }
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+
+  // Put the whole hierarchy of sub-objects of the selected SO's into a list and
+  // then treat them all starting from the deepest objects (at list back)
+  std::list< _PTR(SObject) > listSO;
+  SALOME_ListIteratorOfListIO It(selected);
+  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
+
+      listSO.push_back( aSO );
+      std::list< _PTR(SObject) >::iterator itSO = --listSO.end();
+      for ( ; itSO != listSO.end(); ++itSO ) {
+        _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
+        for (it->InitEx(false); it->More(); it->Next())
+          listSO.push_back( it->Value() );
       }
     }
-    // Check if none of objects to delete is referred from outside
-    std::list< _PTR(SObject) >::reverse_iterator ritSO;
-    for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
-    {
-      _PTR(SObject) SO = *ritSO;
-      if ( !SO ) continue;
-      std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
-      for (size_t i = 0; i < aReferences.size(); i++) {
-        _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
-        std::string type = aComponent->ComponentDataType();
-        if ( type != "SMESH" )
-        {
-          SUIT_MessageBox::warning( anApp->desktop(),
-                                    QObject::tr("WRN_WARNING"),
-                                    QObject::tr("DEP_OBJECT") );
-          return; // outside SMESH, there is an object depending on a SMESH object 
-        }
+  }
+  // Check if none of objects to delete is referred from outside
+  std::list< _PTR(SObject) >::reverse_iterator ritSO;
+  for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+  {
+    _PTR(SObject) SO = *ritSO;
+    if ( !SO ) continue;
+    std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
+    for (size_t i = 0; i < aReferences.size(); i++) {
+      _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
+      std::string type = aComponent->ComponentDataType();
+      if ( type != "SMESH" )
+      {
+        SUIT_MessageBox::warning( anApp->desktop(),
+                                  QObject::tr("WRN_WARNING"),
+                                  QObject::tr("DEP_OBJECT") );
+        return; // outside SMESH, there is an object depending on a SMESH object
       }
     }
+  }
 
-    // Treat SO's in the list starting from the back
-    aStudyBuilder->NewCommand();  // There is a transaction
-    for ( ritSO = listSO.rbegin(); 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);
-              }
-            }
-          }
-        }
-      }
-      /** 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 if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
-        SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-        aMesh->RemoveSubMesh( aSubMesh );
+  // Call mesh->Clear() to prevent loading mesh from file caused by hypotheses removal
+  for( It.Initialize( selected ); It.More(); It.Next()) // loop on selected IO's
+  {
+    Handle(SALOME_InteractiveObject) IObject = It.Value();
+    SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface< SMESH::SMESH_Mesh >( IObject );
+    if ( !mesh->_is_nil() )
+      mesh->Clear();
+  }
+
+  // Treat SO's in the list starting from the back
+  aStudyBuilder->NewCommand();  // There is a transaction
+  for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+  {
+    _PTR(SObject) SO = *ritSO;
+    if ( !SO ) continue;
+    std::string anEntry = SO->GetID();
 
-        _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
-        if (aMeshSO)
-          SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
+    /** Erase graphical object and remove all its data **/
+    if(SO->FindAttribute(anAttr, "AttributeIOR")) {
+      SMESH::RemoveVisualObjectWithActors( anEntry.c_str(), true);
+    }
+    /** 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 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);
+    }
+    else {
+      Handle(SALOME_InteractiveObject) 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 {
-        Handle(SALOME_InteractiveObject) 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();
-        }
+      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 */
+    }
+  } /* listSO back loop */
 
-    aStudyBuilder->CommitCommand();
+  aStudyBuilder->CommitCommand();
 
-    /* Clear any previous selection */
-    SALOME_ListIO l1;
-    aSel->setSelectedObjects( l1 );
+  /* Clear any previous selection */
+  SALOME_ListIO l1;
+  aSel->setSelectedObjects( l1 );
 
-    SMESHGUI::GetSMESHGUI()->updateObjBrowser();
-  }
-//} namespace
+  SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+}
 
 extern "C" {
   SMESHGUI_EXPORT CAM_Module* createModule()
@@ -1839,8 +1927,7 @@ SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
  */
 //=============================================================================
 SMESHGUI::SMESHGUI() :
-SalomeApp_Module( "SMESH" ),
-LightApp_Module( "SMESH" )
+SalomeApp_Module( "SMESH" )
 {
   if ( CORBA::is_nil( myComponentSMESH ) )
   {
@@ -1875,10 +1962,6 @@ LightApp_Module( "SMESH" )
   myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
   myPriority = 0.0;
 
-  SMESH::GetFilterManager();
-  SMESH::GetPattern();
-  SMESH::GetMeasurements();
-
   /* load resources for all available meshers */
   SMESH::InitAvailableHypotheses();
 }
@@ -1890,12 +1973,6 @@ LightApp_Module( "SMESH" )
 //=============================================================================
 SMESHGUI::~SMESHGUI()
 {
-#ifdef WITHGENERICOBJ
-  SMESH::GetFilterManager()->UnRegister();
-  SMESH::GetMeasurements()->UnRegister();
-#endif
-  SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
-  SMESH::GetMeasurements() = SMESH::Measurements::_nil();
 }
 
 //=============================================================================
@@ -1930,6 +2007,103 @@ bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded)
   return autoUpdate && !exceeded;
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
+                                int* entities, bool* limitExceeded, int* hidden, long* nbElements )
+{
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  if ( !resMgr )
+    return false;
+
+  bool autoUpdate  = resMgr->booleanValue( "SMESH", "auto_update", false );
+  long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 );
+  bool incrementalLimit = resMgr->booleanValue( "SMESH", "incremental_limit", false );
+
+  SMESH::long_array_var info = theMesh->GetMeshInfo();
+  long nbOdElems = info[SMDSEntity_0D];
+  long nbEdges   = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
+  long nbFaces   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle] + 
+                   info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] + 
+                   info[SMDSEntity_Polygon];
+  long nbVolumes = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra] + 
+                   info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + 
+                   info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + 
+                   info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta] + 
+                   info[SMDSEntity_Polyhedra] + 
+                   info[SMDSEntity_Hexagonal_Prism];
+  long nbBalls   = info[SMDSEntity_Ball];
+
+  long requestedSize = nbOdElems + nbBalls + nbEdges + nbFaces + nbVolumes;
+  *nbElements = requestedSize;
+  
+  *entities = SMESH_Actor::eAllEntity;
+  *hidden   = 0;
+
+  bool exceeded = updateLimit > 0 && requestedSize > updateLimit;
+
+  if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded;
+
+  if ( incrementalLimit ) {
+    long total     = 0;
+
+    if ( nbOdElems > 0 ) {
+      if ( total + nbOdElems > updateLimit ) {
+        *entities = *entities & ~SMESH_Actor::e0DElements;
+        *hidden = *hidden | SMESH_Actor::e0DElements;
+      }
+      else
+        exceeded = false;
+    }
+    total += nbOdElems;
+
+    if ( nbEdges > 0 ) {
+      if ( total + nbEdges > updateLimit ) {
+        *entities = *entities & ~SMESH_Actor::eEdges;
+        *hidden = *hidden | SMESH_Actor::eEdges;
+      }
+      else
+        exceeded = false;
+    }
+    total += nbEdges;
+
+    if ( nbFaces > 0 ) {
+      if ( total + nbFaces > updateLimit ) {
+        *entities = *entities & ~SMESH_Actor::eFaces;
+        *hidden = *hidden | SMESH_Actor::eFaces;
+      }
+      else
+        exceeded = false;
+    }
+    total += nbFaces;
+
+    if ( nbVolumes > 0 ) {
+      if ( total + nbVolumes > updateLimit ) {
+        *entities = *entities & ~SMESH_Actor::eVolumes;
+        *hidden = *hidden | SMESH_Actor::eVolumes;
+      }
+      else
+        exceeded = false;
+    }
+    total += nbVolumes;
+
+    if ( nbBalls > 0 ) {
+      if ( total + nbBalls > updateLimit ) {
+        *entities = *entities & ~SMESH_Actor::eBallElem;
+        *hidden = *hidden | SMESH_Actor::eBallElem;
+      }
+      else
+        exceeded = false;
+    }
+    total += nbBalls;
+  }
+
+  return autoUpdate && !exceeded;
+}
+
 //=============================================================================
 /*!
  *
@@ -2335,6 +2509,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 214:                                     // UPDATE
     {
       if(checkLock(aStudy)) break;
+      SUIT_OverrideCursor wc;
       try {
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
@@ -2386,10 +2561,10 @@ 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)
@@ -2405,7 +2580,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();
         }
@@ -2528,7 +2703,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       else if ( theCommandID == 410 )
         aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
       else if ( theCommandID == 419 )
-        aDlg = new SMESHGUI_CuttingIntoTetraDlg(this);
+        aDlg = new SMESHGUI_SplitVolumesDlg(this);
       else
         aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
 
@@ -3009,6 +3184,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 4035:     // QUADRATIC TRIANGLE
   case 4036:     // QUADRATIC QUADRANGLE
   case 4136:     // BIQUADRATIC QUADRANGLE
+  case 4137:     // BIQUADRATIC TRIANGLE
   case 4037:     // QUADRATIC TETRAHEDRON
   case 4038:     // QUADRATIC PYRAMID
   case 4039:     // QUADRATIC PENTAHEDRON
@@ -3018,31 +3194,23 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
-        SMDSAbs_EntityType type;
+        SMDSAbs_EntityType type = SMDSEntity_Last;
 
         switch (theCommandID) {
-        case 4034:
-          type = SMDSEntity_Quad_Edge; break;
-        case 4035:
-          type = SMDSEntity_Quad_Triangle; break;
-        case 4036:
-          type = SMDSEntity_Quad_Quadrangle; break;
-        case 4136:
-          type = SMDSEntity_BiQuad_Quadrangle; break;
-        case 4037:
-          type = SMDSEntity_Quad_Tetra; break;
-        case 4038:
-          type = SMDSEntity_Quad_Pyramid; break;
-        case 4039:
-          type = SMDSEntity_Quad_Penta; break;
-        case 4040:
-          type = SMDSEntity_Quad_Hexa;
-        case 4140:
-          type = SMDSEntity_TriQuad_Hexa;
-          break;
-        default:;
+        case 4034: type = SMDSEntity_Quad_Edge; break;
+        case 4035: type = SMDSEntity_Quad_Triangle; break;
+        case 4036: type = SMDSEntity_Quad_Quadrangle; break;
+        case 4136: type = SMDSEntity_BiQuad_Quadrangle; break;
+        case 4137: type = SMDSEntity_BiQuad_Triangle; break;
+        case 4037: type = SMDSEntity_Quad_Tetra; break;
+        case 4038: type = SMDSEntity_Quad_Pyramid; break;
+        case 4039: type = SMDSEntity_Quad_Penta; break;
+        case 4040: type = SMDSEntity_Quad_Hexa; break;
+        case 4140: type = SMDSEntity_TriQuad_Hexa; break;
+        default: break;
         }
-         ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show();
+        if ( type != SMDSEntity_Last )
+          ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show();
       }
       else {
         SUIT_MessageBox::warning(SMESHGUI::desktop(),
@@ -3135,6 +3303,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
                                                     SUIT_MessageBox::No ) == SUIT_MessageBox::Yes;
           if( confirm ) {
             try {
+              SUIT_OverrideCursor wc;
               SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
               int removed = aMeshEditor->RemoveOrphanNodes();
               SUIT_MessageBox::information(SMESHGUI::desktop(),
@@ -3293,6 +3462,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
+  case 4070: // 0D_ON_ALL_NODES
+    startOperation( 4070 );
+    break;
+
   case 5105: // Library of selection filters
   {
     static QList<int> aTypes;
@@ -3350,6 +3523,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
           SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
           SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( aObject );
           if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) {
+            SUIT_OverrideCursor wc;
             ::Control( theCommandID );
             break;
           }
@@ -3366,8 +3540,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
                                tr( "NOT_A_VTK_VIEWER" ) );
     }
     break;
+  case 6032:
+    OverallMeshQuality();
+    break;
   case 9010:
     {
+      SUIT_OverrideCursor wc;
       LightApp_SelectionMgr* mgr = selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
@@ -3384,6 +3562,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case 9011:
     {
+      SUIT_OverrideCursor wc;
       LightApp_SelectionMgr* mgr = selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
@@ -3399,13 +3578,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case 501:
   case 502:
+  case 503:
+  case 504:
+  case 505:
     {
-      int page = theCommandID == 501 ? SMESHGUI_MeasureDlg::MinDistance : SMESHGUI_MeasureDlg::BoundingBox;
+      int page = SMESHGUI_MeasureDlg::MinDistance;
+      if ( theCommandID == 502 )
+        page = SMESHGUI_MeasureDlg::BoundingBox;
+      else if ( theCommandID == 503 )
+        page = SMESHGUI_MeasureDlg::Length;
+      else if ( theCommandID == 504 )
+        page = SMESHGUI_MeasureDlg::Area;
+      else if ( theCommandID == 505 )
+        page = SMESHGUI_MeasureDlg::Volume;
+
       EmitSignalDeactivateDialog();
       SMESHGUI_MeasureDlg* dlg = new SMESHGUI_MeasureDlg( SMESHGUI::desktop(), page );
       dlg->show();
       break;
     }
+  case 41:
+    ::sortChildren();
+    break;
+
   }
 
   anApp->updateActions(); //SRN: To update a Save button in the toolbar
@@ -3493,12 +3688,8 @@ void SMESHGUI::createPopupItem( const int id,
                                 const QString& theRule,
                                 const int pId )
 {
-  int parentId = pId;
-  if( pId!=-1 )
-    parentId = popupMgr()->actionId( action( pId ) );
-
   if( !popupMgr()->contains( popupMgr()->actionId( action( id ) ) ) )
-    popupMgr()->insert( action( id ), parentId, 0 );
+    popupMgr()->insert( action( id ), pId, 0 );
 
   QString lc = "$";        // VSR : instead of QtxPopupSelection::defEquality();
   QString dc = "selcount"; // VSR : insetad of QtxPopupSelection::defSelCountParam()
@@ -3549,13 +3740,13 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  142, "CGNS");
   createSMESHAction(  144, "SAUV");
   createSMESHAction(  146, "GMF" );
-  createSMESHAction(  124, "EXPORT_DAT" );
-  createSMESHAction(  125, "EXPORT_MED" );
-  createSMESHAction(  126, "EXPORT_UNV" );
-  createSMESHAction(  141, "EXPORT_STL" );
-  createSMESHAction(  143, "EXPORT_CGNS");
-  createSMESHAction(  145, "EXPORT_SAUV");
-  createSMESHAction(  147, "EXPORT_GMF" );
+  createSMESHAction(  124, "DAT" );
+  createSMESHAction(  125, "MED" );
+  createSMESHAction(  126, "UNV" );
+  createSMESHAction(  141, "STL" );
+  createSMESHAction(  143, "CGNS");
+  createSMESHAction(  145, "SAUV");
+  createSMESHAction(  147, "GMF" );
   createSMESHAction(  150, "FILE_INFO" );
   createSMESHAction(   33, "DELETE",          "ICON_DELETE", Qt::Key_Delete );
   createSMESHAction( 5105, "SEL_FILTER_LIB" );
@@ -3597,6 +3788,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 6029, "EQUAL_EDGE",      "ICON_EQUAL_EDGE",    0, true );
   createSMESHAction( 6030, "EQUAL_FACE",      "ICON_EQUAL_FACE",    0, true );
   createSMESHAction( 6031, "EQUAL_VOLUME",    "ICON_EQUAL_VOLUME",  0, true );
+  createSMESHAction( 6032, "OVERALL_MESH_QUALITY" );
   createSMESHAction( 6003, "FREE_BORDER",     "ICON_FREE_EDGE_2D",  0, true );
   createSMESHAction( 6004, "CONNECTION",      "ICON_CONNECTION",    0, true );
   createSMESHAction( 6005, "FREE_NODE",       "ICON_FREE_NODE",     0, true );
@@ -3627,6 +3819,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4035, "QUADRATIC_TRIANGLE",      "ICON_DLG_QUADRATIC_TRIANGLE" );
   createSMESHAction( 4036, "QUADRATIC_QUADRANGLE",    "ICON_DLG_QUADRATIC_QUADRANGLE" );
   createSMESHAction( 4136, "BIQUADRATIC_QUADRANGLE",  "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
+  createSMESHAction( 4137, "BIQUADRATIC_TRIANGLE",    "ICON_DLG_BIQUADRATIC_TRIANGLE" );
   createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON",   "ICON_DLG_QUADRATIC_TETRAHEDRON" );
   createSMESHAction( 4038, "QUADRATIC_PYRAMID",       "ICON_DLG_QUADRATIC_PYRAMID" );
   createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON",   "ICON_DLG_QUADRATIC_PENTAHEDRON" );
@@ -3647,6 +3840,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" );
   createSMESHAction( 4068, "SCALE",           "ICON_DLG_MESH_SCALE" );
   createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" );
+  createSMESHAction( 4070, "0D_ON_ALL_NODES", "ICON_0D_ON_ALL_NODES" );
   createSMESHAction(  407, "INV",             "ICON_DLG_MESH_DIAGONAL" );
   createSMESHAction(  408, "UNION2",          "ICON_UNION2TRI" );
   createSMESHAction(  409, "ORIENT",          "ICON_DLG_MESH_ORIENTATION" );
@@ -3699,11 +3893,16 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
   createSMESHAction( 502, "MEASURE_BND_BOX",  "ICON_MEASURE_BND_BOX" );
+  createSMESHAction( 503, "MEASURE_LENGTH",   "ICON_MEASURE_LENGTH" );
+  createSMESHAction( 504, "MEASURE_AREA",     "ICON_MEASURE_AREA" );
+  createSMESHAction( 505, "MEASURE_VOLUME",   "ICON_MEASURE_VOLUME" );
 
   createSMESHAction( 300, "HIDE" );
   createSMESHAction( 301, "SHOW" );
   createSMESHAction( 302, "DISPLAY_ONLY" );
 
+  createSMESHAction( 41, "SORT_CHILD_ITEMS" );
+
   // ----- create menu --------------
   int fileId    = createMenu( tr( "MEN_FILE" ),    -1,  1 ),
       editId    = createMenu( tr( "MEN_EDIT" ),    -1,  3 ),
@@ -3725,7 +3924,8 @@ void SMESHGUI::initialize( CAM_Application* app )
       addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
       removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
       renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
-      transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 );
+      transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 ),
+      basicPropId = createMenu( tr( "MEN_BASIC_PROPERTIES" ), measureId, -1, 10 );
 
   //createMenu( 111, importId, -1 );
   createMenu( 112, importId, -1 );
@@ -3806,9 +4006,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 6024, volumeId, -1 );
   createMenu( 6026, volumeId, -1 );
   createMenu( 6031, volumeId, -1 );
+  createMenu( separator(), ctrlId, -1 );
+  createMenu( 6032, ctrlId, -1 );
 
   createMenu( 4000, addId, -1 );
   createMenu( 4009, addId, -1 );
+  createMenu( 4070, addId, -1 );
   createMenu( 4008, addId, -1 );
   createMenu( 4010, addId, -1 );
   createMenu( 4021, addId, -1 );
@@ -3823,6 +4026,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( separator(), addId, -1 );
   createMenu( 4034, addId, -1 );
   createMenu( 4035, addId, -1 );
+  createMenu( 4137, addId, -1 );
   createMenu( 4036, addId, -1 );
   createMenu( 4136, addId, -1 );
   createMenu( 4037, addId, -1 );
@@ -3869,14 +4073,27 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( 501, measureId, -1 );
   createMenu( 502, measureId, -1 );
+  createMenu( 503, basicPropId, -1 );
+  createMenu( 504, basicPropId, -1 );
+  createMenu( 505, basicPropId, -1 );
   createMenu( 214, viewId, -1 );
 
   // ----- create toolbars --------------
-  int meshTb     = createTool( tr( "TB_MESH" ) ),
-      ctrlTb     = createTool( tr( "TB_CTRL" ) ),
-      addRemTb   = createTool( tr( "TB_ADD_REMOVE" ) ),
-      modifyTb   = createTool( tr( "TB_MODIFY" ) ),
-      dispModeTb = createTool( tr( "TB_DISP_MODE" ) );
+  int meshTb       = createTool( tr( "TB_MESH" ) ),
+      info         = createTool( tr( "TB_INFO" ) ),
+      groupTb      = createTool( tr( "TB_GROUP" ) ),
+      ctrl0dTb     = createTool( tr( "TB_CTRL0D" ) ),
+      ctrl1dTb     = createTool( tr( "TB_CTRL1D" ) ),
+      ctrl2dTb     = createTool( tr( "TB_CTRL2D" ) ),
+      ctrl3dTb     = createTool( tr( "TB_CTRL3D" ) ),
+      addElemTb    = createTool( tr( "TB_ADD" ) ),
+      addNonElemTb = createTool( tr( "TB_ADDNON" ) ),
+      remTb        = createTool( tr( "TB_REM" ) ),
+      renumbTb     = createTool( tr( "TB_RENUMBER" ) ),  
+      transformTb  = createTool( tr( "TB_TRANSFORM" ) ),  
+      modifyTb     = createTool( tr( "TB_MODIFY" ) ),
+      measuremTb     = createTool( tr( "TB_MEASUREM" ) ),
+      dispModeTb   = createTool( tr( "TB_DISP_MODE" ) );
 
   createTool( 702, meshTb );
   createTool( 703, meshTb );
@@ -3888,91 +4105,90 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 711, meshTb );
   createTool( 712, meshTb );
   createTool( 713, meshTb );
-  createTool( separator(), meshTb );
-  createTool( 801, meshTb );
-  createTool( 806, meshTb );
-  createTool( 802, meshTb );
-  createTool( 803, meshTb );
-  //createTool( 815, meshTb );
-  createTool( separator(), meshTb );
-  createTool( 900, meshTb );
+
+  createTool( 801, groupTb );
+  createTool( 806, groupTb );
+  createTool( 802, groupTb );
+  createTool( 803, groupTb );
+
+  createTool( 900, info );
   //createTool( 902, meshTb );
   //createTool( 903, meshTb ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
-  createTool( 904, meshTb );
-  createTool( separator(), meshTb );
-
-  createTool( 6005, ctrlTb );
-  createTool( 6028, ctrlTb );
-  createTool( separator(), ctrlTb );
-  createTool( 6002, ctrlTb );
-  createTool( 6003, ctrlTb );
-  createTool( 6001, ctrlTb );
-  createTool( 6004, ctrlTb );
-  createTool( 6029, ctrlTb );
-  createTool( separator(), ctrlTb );
-  createTool( 6021, ctrlTb );
-  createTool( 6025, ctrlTb );
-  createTool( 6027, ctrlTb );
-  createTool( 6018, ctrlTb );
-  createTool( 6019, ctrlTb );
-  createTool( 6011, ctrlTb );
-  createTool( 6012, ctrlTb );
-  createTool( 6013, ctrlTb );
-  createTool( 6014, ctrlTb );
-  createTool( 6015, ctrlTb );
-  createTool( 6016, ctrlTb );
-  createTool( 6022, ctrlTb );
-  createTool( 6030, ctrlTb );
-  createTool( separator(), ctrlTb );
-  createTool( 6017, ctrlTb );
-  createTool( 6009, ctrlTb );
-  createTool( 6023, ctrlTb );
-  createTool( 6024, ctrlTb );
-  createTool( 6026, ctrlTb );
-  createTool( 6031, ctrlTb );
-  createTool( separator(), ctrlTb );
-
-  createTool( 4000, addRemTb );
-  createTool( 4009, addRemTb );
-  createTool( 4008, addRemTb );
-  createTool( 4010, addRemTb );
-  createTool( 4021, addRemTb );
-  createTool( 4022, addRemTb );
-  createTool( 4023, addRemTb );
-  createTool( 4031, addRemTb );
-  createTool( 4032, addRemTb );
-  createTool( 4133, addRemTb );
-  createTool( 4134, addRemTb );
-  createTool( 4135, addRemTb );
-  createTool( 4033, addRemTb );
-  createTool( separator(), addRemTb );
-  createTool( 4034, addRemTb );
-  createTool( 4035, addRemTb );
-  createTool( 4036, addRemTb );
-  createTool( 4136, addRemTb );
-  createTool( 4037, addRemTb );
-  createTool( 4038, addRemTb );
-  createTool( 4039, addRemTb );
-  createTool( 4040, addRemTb );
-  createTool( 4140, addRemTb );
-  createTool( separator(), addRemTb );
-  createTool( 4041, addRemTb );
-  createTool( 4042, addRemTb );
-  createTool( 4044, addRemTb );
-  createTool( 4043, addRemTb );
-  createTool( separator(), addRemTb );
-  createTool( 4051, addRemTb );
-  createTool( 4052, addRemTb );
-  createTool( separator(), addRemTb );
-  createTool( 4061, addRemTb );
-  createTool( 4062, addRemTb );
-  createTool( 4063, addRemTb );
-  createTool( 4068, addRemTb );
-  createTool( 4064, addRemTb );
-  createTool( 4065, addRemTb );
-  createTool( 4066, addRemTb );
-  createTool( 4069, addRemTb );
-  createTool( separator(), addRemTb );
+  createTool( 904, info );
+
+  createTool( 6005, ctrl0dTb );
+  createTool( 6028, ctrl0dTb );
+
+  createTool( 6002, ctrl1dTb );
+  createTool( 6003, ctrl1dTb );
+  createTool( 6001, ctrl1dTb );
+  createTool( 6004, ctrl1dTb );
+  createTool( 6029, ctrl1dTb );
+
+  createTool( 6021, ctrl2dTb );
+  createTool( 6025, ctrl2dTb );
+  createTool( 6027, ctrl2dTb );
+  createTool( 6018, ctrl2dTb );
+  createTool( 6019, ctrl2dTb );
+  createTool( 6011, ctrl2dTb );
+  createTool( 6012, ctrl2dTb );
+  createTool( 6013, ctrl2dTb );
+  createTool( 6014, ctrl2dTb );
+  createTool( 6015, ctrl2dTb );
+  createTool( 6016, ctrl2dTb );
+  createTool( 6022, ctrl2dTb );
+  createTool( 6030, ctrl2dTb );
+
+  createTool( 6017, ctrl3dTb );
+  createTool( 6009, ctrl3dTb );
+  createTool( 6023, ctrl3dTb );
+  createTool( 6024, ctrl3dTb );
+  createTool( 6026, ctrl3dTb );
+  createTool( 6031, ctrl3dTb );
+
+  createTool( 4000, addElemTb );
+  createTool( 4009, addElemTb );
+  createTool( 4070, addElemTb );
+  createTool( 4008, addElemTb );
+  createTool( 4010, addElemTb );
+  createTool( 4021, addElemTb );
+  createTool( 4022, addElemTb );
+  createTool( 4023, addElemTb );
+  createTool( 4031, addElemTb );
+  createTool( 4032, addElemTb );
+  createTool( 4133, addElemTb );
+  createTool( 4134, addElemTb );
+  createTool( 4135, addElemTb );
+  createTool( 4033, addElemTb );
+
+  createTool( 4034, addNonElemTb );
+  createTool( 4035, addNonElemTb );
+  createTool( 4137, addNonElemTb );
+  createTool( 4036, addNonElemTb );
+  createTool( 4136, addNonElemTb );
+  createTool( 4037, addNonElemTb );
+  createTool( 4038, addNonElemTb );
+  createTool( 4039, addNonElemTb );
+  createTool( 4040, addNonElemTb );
+  createTool( 4140, addNonElemTb );
+
+  createTool( 4041, remTb );
+  createTool( 4042, remTb );
+  createTool( 4044, remTb );
+  createTool( 4043, remTb );
+
+  createTool( 4051, renumbTb );
+  createTool( 4052, renumbTb );
+
+
+  createTool( 4061, transformTb );
+  createTool( 4062, transformTb );
+  createTool( 4063, transformTb );
+  createTool( 4068, transformTb );
+  createTool( 4064, transformTb );
+  createTool( 4065, transformTb );
+  createTool( 4066, transformTb );
+  createTool( 4069, transformTb );
 
   createTool( 4067,modifyTb );
   createTool( 407, modifyTb );
@@ -3990,6 +4206,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 417, modifyTb );
   createTool( 418, modifyTb );
 
+  createTool( 501, measuremTb );  
+
   createTool( 214, dispModeTb );
 
   QString lc = "$";        // VSR : instead of QtxPopupSelection::defEquality();
@@ -3999,17 +4217,17 @@ void SMESHGUI::initialize( CAM_Application* app )
   QString OB = "'ObjectBrowser'",
           View = "'" + SVTK_Viewer::Type() + "'",
           pat = "'%1'",
-          mesh    = pat.arg( SMESHGUI_Selection::typeName( MESH ) ),
-          group   = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ),
-          hypo    = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ),
-          algo    = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ),
+          mesh    = pat.arg( SMESHGUI_Selection::typeName( SMESH::MESH ) ),
+          group   = pat.arg( SMESHGUI_Selection::typeName( SMESH::GROUP ) ),
+          hypo    = pat.arg( SMESHGUI_Selection::typeName( SMESH::HYPOTHESIS ) ),
+          algo    = pat.arg( SMESHGUI_Selection::typeName( SMESH::ALGORITHM ) ),
           elems   = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ).
-                       arg( SMESHGUI_Selection::typeName( SUBMESH ) ),
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH_VERTEX ) ).
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH_EDGE ) ).
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH_FACE ) ).
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH_SOLID ) ).
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH_COMPOUND ) ).
+                       arg( SMESHGUI_Selection::typeName( SMESH::SUBMESH ) ),
           subMesh = elems,
           mesh_part = mesh + " " + subMesh + " " + group,
           mesh_group = mesh + " " + group,
@@ -4046,6 +4264,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 214, OB, mesh_part );                   // UPDATE
   createPopupItem( 900, OB, mesh_part );                   // ADV_INFO
   createPopupItem( 904, OB, mesh_group );                  // FIND_ELEM
+  createPopupItem( 6032, OB, mesh_part );                  // CTRL_INFO
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 801, OB, mesh );                        // CREATE_GROUP
   createPopupItem( 806, OB, mesh );                        // CREATE_GEO_GROUP
@@ -4065,14 +4284,16 @@ void SMESHGUI::initialize( CAM_Application* app )
   QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
   QString only_one_2D        = only_one_non_empty + " && dim>1";
 
-  createPopupItem( 125, OB, mesh_group, multiple_non_empty );   // EXPORT_MED
-  createPopupItem( 126, OB, mesh_group, only_one_non_empty );   // EXPORT_UNV
-  createPopupItem( 141, OB, mesh_group, only_one_2D );          // EXPORT_STL
+  int anId = popupMgr()->insert( tr( "MEN_EXPORT" ), -1, -1 );        // EXPORT submenu
+  createPopupItem( 125, OB, mesh_group, multiple_non_empty, anId );   // EXPORT_MED
+  createPopupItem( 126, OB, mesh_group, only_one_non_empty, anId );   // EXPORT_UNV
+  createPopupItem( 141, OB, mesh_group, only_one_2D, anId );          // EXPORT_STL
 #ifdef WITH_CGNS
-  createPopupItem( 143, OB, mesh_group, multiple_non_empty );   // EXPORT_CGNS
+  createPopupItem( 143, OB, mesh_group, multiple_non_empty, anId );   // EXPORT_CGNS
 #endif
-  createPopupItem( 145, OB, mesh_group, multiple_non_empty );   // EXPORT_SAUV
-  createPopupItem( 147, OB, mesh_group, multiple_non_empty );   // EXPORT_GMF
+  createPopupItem( 145, OB, mesh_group, multiple_non_empty, anId );   // EXPORT_SAUV
+  createPopupItem( 147, OB, mesh_group, multiple_non_empty, anId );   // EXPORT_GMF
+  createPopupItem( 124, OB, mesh_group, multiple_non_empty, anId );   // EXPORT_DAT
   createPopupItem(  33, OB, mesh_part + " " + hyp_alg );        // DELETE
   createPopupItem( 813, OB, group );                            // DEL_GROUP with contents
   popupMgr()->insert( separator(), -1, 0 );
@@ -4085,6 +4306,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 214, View, mesh_part );  // UPDATE
   createPopupItem( 900, View, mesh_part );  // ADV_INFO
+  createPopupItem( 6032,View, mesh_part );  // CTRL_INFO
   createPopupItem( 904, View, mesh );       // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
 
@@ -4092,7 +4314,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 1137, OB + " " + View, mesh, "&& isAutoColor" );       // DISABLE_AUTO_COLOR
   popupMgr()->insert( separator(), -1, 0 );
 
-  int anId;
   QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" );
   QString aType = QString( "%1type in {%2}" ).arg( lc );
   aType = aType.arg( mesh_part );
@@ -4377,6 +4598,10 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), -1, -1 );
 
+  popupMgr()->insert( action( 41 ), -1, -1 );
+  popupMgr()->setRule( action( 41 ), "$component={'SMESH'} and client='ObjectBrowser' and isContainer and nbChildren>1", QtxPopupMgr::VisibleRule );
+  popupMgr()->insert( separator(), -1, -1 );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
            this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
 
@@ -4424,18 +4649,17 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
 
   // import Python module that manages SMESH plugins (need to be here because SalomePyQt API uses active module)
   PyGILState_STATE gstate = PyGILState_Ensure();
-  PyObject* pluginsmanager=PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager");
-  if(pluginsmanager==NULL)
+  PyObjWrapper pluginsmanager = PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager");
+  if ( !pluginsmanager ) {
     PyErr_Print();
-  else
-    {
-      PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str());
-      if(result==NULL)
-        PyErr_Print();
-      Py_XDECREF(result);
-    }
+  }
+  else {
+    PyObjWrapper result = PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str());
+    if ( !result )
+      PyErr_Print();
+  }
   PyGILState_Release(gstate);
-  // end of GEOM plugins loading
+  // end of SMESH plugins loading
 
   // Reset actions accelerator keys
   //action(111)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); // Import DAT
@@ -4531,7 +4755,7 @@ void SMESHGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& ti
     _PTR(Study) study = appStudy->studyDS();
     _PTR(SObject) obj = study->FindObjectID( io->getEntry() );
     if ( obj ) {
-      QString aName = QString( obj->GetName().c_str() );
+      QString aName = QString( QString::fromUtf8(obj->GetName().c_str()) );
       while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
           aName.remove( (aName.length() - 1), 1 );
       title = aName;
@@ -4547,6 +4771,7 @@ LightApp_Selection* SMESHGUI::createSelection() const
 void SMESHGUI::windows( QMap<int, int>& aMap ) const
 {
   aMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+  aMap.insert( SalomeApp_Application::WT_NoteBook, Qt::LeftDockWidgetArea );
   aMap.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
 }
 
@@ -4617,11 +4842,13 @@ void SMESHGUI::createPreferences()
   int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
 
   int autoUpdate = addPreference( tr( "PREF_AUTO_UPDATE" ), genTab, LightApp_Preferences::Auto, "SMESH", "auto_update" );
+  setPreferenceProperty( autoUpdate, "columns", 2 );
   int lim = addPreference( tr( "PREF_UPDATE_LIMIT" ), autoUpdate, LightApp_Preferences::IntSpin, "SMESH", "update_limit" );
   setPreferenceProperty( lim, "min",  0 );
   setPreferenceProperty( lim, "max",  100000000 );
   setPreferenceProperty( lim, "step", 1000 );
   setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
+  addPreference( tr( "PREF_INCREMENTAL_LIMIT" ), autoUpdate, LightApp_Preferences::Bool, "SMESH", "incremental_limit" );
 
   int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab );
   setPreferenceProperty( qaGroup, "columns", 2 );
@@ -4674,7 +4901,7 @@ void SMESHGUI::createPreferences()
   int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab );
   setPreferenceProperty( exportgroup, "columns", 2 );
   addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" );
-  addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" );
+  //addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" );
 
   int computeGroup = addPreference( tr( "PREF_GROUP_COMPUTE" ), genTab );
   setPreferenceProperty( computeGroup, "columns", 2 );
@@ -4691,7 +4918,7 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( notifyMode, "indexes", indices );
 
   int infoGroup = addPreference( tr( "PREF_GROUP_INFO" ), genTab );
-  setPreferenceProperty( infoGroup, "columns", 4 );
+  setPreferenceProperty( infoGroup, "columns", 2 );
   int elemInfo = addPreference( tr( "PREF_ELEM_INFO" ), infoGroup, LightApp_Preferences::Selector, "SMESH", "mesh_elem_info" );
   modes.clear();
   modes.append( tr( "PREF_ELEM_INFO_SIMPLE" ) );
@@ -4706,6 +4933,16 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( nodesLim, "max", 10000000 );
   setPreferenceProperty( nodesLim, "step", 10000 );
   setPreferenceProperty( nodesLim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
+  int ctrlLim = addPreference( tr( "PREF_CTRL_LIMIT" ), infoGroup, LightApp_Preferences::IntSpin, "SMESH", "info_controls_limit" );
+  setPreferenceProperty( ctrlLim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
+  setPreferenceProperty( ctrlLim, "min", 0 );
+  setPreferenceProperty( ctrlLim, "max", 10000000 );
+  setPreferenceProperty( ctrlLim, "step", 1000 );
+  addPreference( tr( "PREF_ELEM_INFO_GRP_DETAILS" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "elem_info_grp_details" );
+  addPreference( tr( "PREF_DUMP_BASE_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_base" );
+  addPreference( tr( "PREF_DUMP_ELEM_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_elem" );
+  addPreference( tr( "PREF_DUMP_ADD_INFO"  ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_add" );
+  addPreference( tr( "PREF_DUMP_CTRL_INFO" ), infoGroup, LightApp_Preferences::Bool, "SMESH", "info_dump_ctrl" );
 
   int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab );
   setPreferenceProperty( segGroup, "columns", 2 );
@@ -4752,7 +4989,7 @@ void SMESHGUI::createPreferences()
   int previewGroup = addPreference( tr( "SMESH_PREF_GROUP_PREVIEW" ), genTab );
   setPreferenceProperty( previewGroup, "columns", 2 );
   int chunkSize = addPreference( tr( "PREF_PREVIEW_CHUNK_SIZE" ), previewGroup, LightApp_Preferences::IntSpin, "SMESH", "preview_actor_chunk_size" );
-  setPreferenceProperty( chunkSize, "min",  0 );
+  setPreferenceProperty( chunkSize, "min",  1 );
   setPreferenceProperty( chunkSize, "max",  1000 );
   setPreferenceProperty( chunkSize, "step", 50 );
 
@@ -4802,6 +5039,7 @@ void SMESHGUI::createPreferences()
   addPreference( tr( "PREF_BALL_COLOR" ), elemGroup, LightApp_Preferences::Color, "SMESH", "ball_elem_color" );
   addPreference( tr( "PREF_OUTLINE"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" );
   addPreference( tr( "PREF_WIREFRAME"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "wireframe_color" );
+  addPreference( tr( "PREF_PREVIEW_COLOR"  ), elemGroup, LightApp_Preferences::BiColor, "SMESH", "preview_color" );
 
 
   int grpGroup = addPreference( tr( "PREF_GROUP_GROUPS" ), meshTab );
@@ -4814,6 +5052,8 @@ void SMESHGUI::createPreferences()
                              LightApp_Preferences::IntSpin, "SMESH", "elem0d_size");
   int ballSize = addPreference(tr("PREF_BALL_SIZE"), elemGroup,
                              LightApp_Preferences::IntSpin, "SMESH", "ball_elem_size");
+  double ballScale = addPreference(tr("PREF_BALL_SCALE"), elemGroup,
+                             LightApp_Preferences::DblSpin, "SMESH", "ball_elem_scale");
   int elemW  = addPreference(tr("PREF_WIDTH"), elemGroup,
                              LightApp_Preferences::IntSpin, "SMESH", "element_width");
   int outW  = addPreference(tr("PREF_OUTLINE_WIDTH"), elemGroup,
@@ -4827,6 +5067,10 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( ballSize, "min", 1 );
   setPreferenceProperty( ballSize, "max", 10 );
 
+  setPreferenceProperty( ballScale, "min", 1e-2 );
+  setPreferenceProperty( ballScale, "max", 1e7 );
+  setPreferenceProperty( ballScale, "step", 0.5 );
+
   setPreferenceProperty( elemW, "min", 1 );
   setPreferenceProperty( elemW, "max", 5 );
 
@@ -4836,6 +5080,15 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( shrink, "min", 0 );
   setPreferenceProperty( shrink, "max", 100 );
 
+  int numGroup = addPreference( tr( "PREF_GROUP_NUMBERING" ), meshTab );
+  setPreferenceProperty( numGroup, "columns", 2 );
+  
+  addPreference( tr( "PREF_NUMBERING_NODE" ), numGroup, LightApp_Preferences::Color, "SMESH", "numbering_node_color" );
+  addVtkFontPref( tr( "PREF_NUMBERING_FONT" ), numGroup, "numbering_node_font", true );
+
+  addPreference( tr( "PREF_NUMBERING_ELEM" ), numGroup, LightApp_Preferences::Color, "SMESH", "numbering_elem_color" );
+  addVtkFontPref( tr( "PREF_NUMBERING_FONT" ), numGroup, "numbering_elem_font", true );
+
   int orientGroup = addPreference( tr( "PREF_GROUP_FACES_ORIENTATION" ), meshTab );
   setPreferenceProperty( orientGroup, "columns", 1 );
 
@@ -5022,6 +5275,12 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
       QString val = aResourceMgr->stringValue( "SMESH", name );
       myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() );
     }
+    else if ( name == QString( "numbering_node_color" ) || name == QString( "numbering_node_font" ) ) {
+      SMESH::UpdateFontProp( this );    
+    }
+    else if ( name == QString( "numbering_elem_color" ) || name == QString( "numbering_elem_font" ) ) {
+      SMESH::UpdateFontProp( this );
+    }
 
     if(aWarning.size() != 0){
       aWarning += "The default values are applied instead.";
@@ -5131,9 +5390,12 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
     case 904: // Find element
       op = new SMESHGUI_FindElemByPointOp();
       break;
-    case 4067: // make mesh pass through point
+    case 4067: // Make mesh pass through point
       op = new SMESHGUI_MakeNodeAtPointOp();
       break;
+    case 4070: // Create 0D elements on all nodes
+      op = new SMESHGUI_Add0DElemsOnAllNodesOp();
+      break;
     default:
     break;
   }
@@ -5215,9 +5477,9 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
   return aSColor;
 }
 
-const char gSeparator = '_'; // character used to separate parameter names
-const char gDigitsSep = ':'; // character used to separate numeric parameter values (color = r:g:b)
-const char gPathSep   = '|'; // character used to separate paths
+const char* gSeparator = "_"; // character used to separate parameter names
+const char* gDigitsSep = ":"; // character used to separate numeric parameter values (color = r:g:b)
+const char* gPathSep   = "|"; // character used to separate paths
 
 /*!
  * \brief Store visual parameters
@@ -5227,6 +5489,9 @@ const char gPathSep   = '|'; // character used to separate paths
  */
 void SMESHGUI::storeVisualParameters (int savePoint)
 {
+  // localizing
+  Kernel_Utils::Localizer loc;
+
   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
   if (!appStudy || !appStudy->studyDS())
     return;
@@ -5310,13 +5575,34 @@ void SMESHGUI::storeVisualParameters (int savePoint)
           aPropertyName += gSeparator;
           aPropertyName += QString::number( anId );
 
-          QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData();
-          aPropertyValue += gDigitsSep;
-          aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData();
+          QString aPropertyValue = QString::number( (int)aPlane->PlaneMode ).toLatin1().constData();
           aPropertyValue += gDigitsSep;
-          aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData();
+          aPropertyValue += QString::number( aPlane->IsOpenGLClipping ).toLatin1().constData();
           aPropertyValue += gDigitsSep;
-          aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData();
+          if ( aPlane->PlaneMode == SMESH::Absolute ) {
+            aPropertyValue += QString::number( aPlane->myAbsoluteOrientation ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->X ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->Y ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->Z ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->Dx ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->Dy ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->Dz ).toLatin1().constData();
+          }
+          else if ( aPlane->PlaneMode == SMESH::Relative ) {
+            aPropertyValue += QString::number( (int)aPlane->myRelativeOrientation ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData();
+            aPropertyValue += gDigitsSep;
+            aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData();
+          }
 
           ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() );
         }
@@ -5367,9 +5653,11 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 
                   // Displayed entities
                   unsigned int aMode = aSmeshActor->GetEntityMode();
-                  bool isE = aMode & SMESH_Actor::eEdges;
-                  bool isF = aMode & SMESH_Actor::eFaces;
-                  bool isV = aMode & SMESH_Actor::eVolumes;
+                  bool isE  = aMode & SMESH_Actor::eEdges;
+                  bool isF  = aMode & SMESH_Actor::eFaces;
+                  bool isV  = aMode & SMESH_Actor::eVolumes;
+                  bool is0d = aMode & SMESH_Actor::e0DElements;
+                  bool isB  = aMode & SMESH_Actor::eBallElem;
 
                   QString modeStr ("e");
                   modeStr += gDigitsSep; modeStr += QString::number(isE);
@@ -5377,53 +5665,93 @@ void SMESHGUI::storeVisualParameters (int savePoint)
                   modeStr += gDigitsSep; modeStr += QString::number(isF);
                   modeStr += gDigitsSep; modeStr += "v";
                   modeStr += gDigitsSep; modeStr += QString::number(isV);
+                  modeStr += gDigitsSep; modeStr += "0d";
+                  modeStr += gDigitsSep; modeStr += QString::number(is0d);
+                  modeStr += gDigitsSep; modeStr += "b";
+                  modeStr += gDigitsSep; modeStr += QString::number(isB);
 
                   param = vtkParam + "Entities";
                   ip->setParameter(entry, param, modeStr.toLatin1().data());
 
-                  // Colors (surface:edge:)
-                  vtkFloatingPointType r, g, b;
+                  // Colors
+                  double r, g, b;
                   int delta;
 
                   aSmeshActor->GetSufaceColor(r, g, b, delta);
-                  QString colorStr ("surface");
-                  colorStr += gDigitsSep; colorStr += QString::number(r);
-                  colorStr += gDigitsSep; colorStr += QString::number(g);
-                  colorStr += gDigitsSep; colorStr += QString::number(b);
-
-                  colorStr += gDigitsSep; colorStr += "backsurface";
-                  colorStr += gDigitsSep; colorStr += QString::number(delta);
-
+                  QStringList colorStr;
+                  colorStr << "surface";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
+
+                  colorStr << "backsurface";
+                  colorStr << QString::number(delta);
+
+                  aSmeshActor->GetVolumeColor(r, g, b, delta);
+                  colorStr << "volume";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
+                  colorStr << QString::number(delta);
 
                   aSmeshActor->GetEdgeColor(r, g, b);
-                  colorStr += gDigitsSep; colorStr += "edge";
-                  colorStr += gDigitsSep; colorStr += QString::number(r);
-                  colorStr += gDigitsSep; colorStr += QString::number(g);
-                  colorStr += gDigitsSep; colorStr += QString::number(b);
+                  colorStr << "edge";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
 
                   aSmeshActor->GetNodeColor(r, g, b);
-                  colorStr += gDigitsSep; colorStr += "node";
-                  colorStr += gDigitsSep; colorStr += QString::number(r);
-                  colorStr += gDigitsSep; colorStr += QString::number(g);
-                  colorStr += gDigitsSep; colorStr += QString::number(b);
+                  colorStr << "node";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
 
                   aSmeshActor->GetOutlineColor(r, g, b);
-                  colorStr += gDigitsSep; colorStr += "outline";
-                  colorStr += gDigitsSep; colorStr += QString::number(r);
-                  colorStr += gDigitsSep; colorStr += QString::number(g);
-                  colorStr += gDigitsSep; colorStr += QString::number(b);
+                  colorStr << "outline";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
+
+                  aSmeshActor->Get0DColor(r, g, b);
+                  colorStr << "elem0d";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
+
+                  aSmeshActor->GetBallColor(r, g, b);
+                  colorStr << "ball";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
+
+                  aSmeshActor->GetFacesOrientationColor(r, g, b);
+                  colorStr << "orientation";
+                  colorStr << QString::number(r);
+                  colorStr << QString::number(g);
+                  colorStr << QString::number(b);
 
                   param = vtkParam + "Colors";
-                  ip->setParameter(entry, param, colorStr.toLatin1().data());
-
-                  // Sizes of lines and points
-                  QString sizeStr ("line");
-                  sizeStr += gDigitsSep; sizeStr += QString::number((int)aSmeshActor->GetLineWidth());
-                  sizeStr += gDigitsSep; sizeStr += "shrink";
-                  sizeStr += gDigitsSep; sizeStr += QString::number(aSmeshActor->GetShrinkFactor());
+                  ip->setParameter(entry, param, qPrintable(colorStr.join(gDigitsSep)));
+
+                  // Sizes
+                  QStringList sizeStr;
+                  sizeStr << "line";
+                  sizeStr << QString::number((int)aSmeshActor->GetLineWidth());
+                  sizeStr << "outline";
+                  sizeStr << QString::number((int)aSmeshActor->GetOutlineWidth());
+                  sizeStr << "elem0d";
+                  sizeStr << QString::number((int)aSmeshActor->Get0DSize());
+                  sizeStr << "ball";
+                  sizeStr << QString::number((int)aSmeshActor->GetBallSize());
+                  sizeStr << QString::number((double)aSmeshActor->GetBallScale());
+                  sizeStr << "shrink";
+                  sizeStr << QString::number(aSmeshActor->GetShrinkFactor());
+                  sizeStr << "orientation";
+                  sizeStr << QString::number(aSmeshActor->GetFacesOrientationScale());
+                  sizeStr << QString::number(aSmeshActor->GetFacesOrientation3DVectors());
 
                   param = vtkParam + "Sizes";
-                  ip->setParameter(entry, param, sizeStr.toLatin1().data());
+                  ip->setParameter(entry, param, qPrintable(sizeStr.join(gDigitsSep)));
 
                   // Point marker
                   QString markerStr;
@@ -5485,9 +5813,13 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 // data structures for clipping planes processing
 typedef struct {
   int Id;
-  vtkIdType Orientation;
-  vtkFloatingPointType Distance;
-  vtkFloatingPointType Angle[2];
+  int Mode;
+  bool isOpenGLClipping;
+  vtkIdType RelativeOrientation;
+  double Distance;
+  double Angle[2];
+  int AbsoluteOrientation;
+  double X, Y, Z, Dx, Dy, Dz;
 } TPlaneData;
 typedef std::list<TPlaneData>         TPlaneDataList;
 typedef std::map<int, TPlaneDataList> TPlaneDataMap;
@@ -5509,6 +5841,9 @@ typedef std::map<int, TPlaneInfoList> TPlaneInfoMap;
  */
 void SMESHGUI::restoreVisualParameters (int savePoint)
 {
+  // localizing
+  Kernel_Utils::Localizer loc;
+
   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
   if (!appStudy || !appStudy->studyDS())
     return;
@@ -5601,31 +5936,80 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
         continue;
 
       QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts );
-      if( aPropertyValueList.size() != 4 )
+      if( aPropertyValueList.size() != 6 && aPropertyValueList.size() != 9 )
         continue;
 
       TPlaneData aPlaneData;
       aPlaneData.Id = aClippingPlaneId;
 
       ok = false;
-      aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok );
+      aPlaneData.Mode = aPropertyValueList[0].toInt( &ok );
       if( !ok )
         continue;
-
+      
       ok = false;
-      aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok );
+      aPlaneData.isOpenGLClipping = aPropertyValueList[1].toInt( &ok );
       if( !ok )
         continue;
 
-      ok = false;
-      aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok );
-      if( !ok )
-        continue;
+      if ( (SMESH::Mode)aPlaneData.Mode == SMESH::Absolute )
+      {
+        ok = false;
+        aPlaneData.AbsoluteOrientation = aPropertyValueList[2].toInt( &ok );
+        if( !ok )
+          continue;
 
-      ok = false;
-      aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok );
-      if( !ok )
-        continue;
+        ok = false;
+        aPlaneData.X = aPropertyValueList[3].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Y = aPropertyValueList[4].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Z = aPropertyValueList[5].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Dx = aPropertyValueList[6].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Dy = aPropertyValueList[7].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Dz = aPropertyValueList[8].toDouble( &ok );
+        if( !ok )
+          continue;
+      }
+      else if ( (SMESH::Mode)aPlaneData.Mode == SMESH::Relative ) {
+        ok = false;
+        aPlaneData.RelativeOrientation = aPropertyValueList[2].toInt( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Distance = aPropertyValueList[3].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Angle[0] = aPropertyValueList[4].toDouble( &ok );
+        if( !ok )
+          continue;
+
+        ok = false;
+        aPlaneData.Angle[1] = aPropertyValueList[5].toDouble( &ok );
+        if( !ok )
+          continue;
+      }
 
       TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ];
       aPlaneDataList.push_back( aPlaneData );
@@ -5745,96 +6129,289 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
             // Displayed entities
             else if (paramNameStr == "Entities") {
               QStringList mode = val.split(gDigitsSep, QString::SkipEmptyParts);
-              if (mode.count() == 6) {
-                if (mode[0] != "e" || mode[2]  != "f" || mode[4] != "v") {
-                  MESSAGE("Invalid order of data in Entities, must be: "
-                          "e:0/1:f:0/1:v:0/1");
-                }
-                else {
-                  unsigned int aMode = aSmeshActor->GetEntityMode();
-                  unsigned int aNewMode =
-                    (int(SMESH_Actor::eEdges  ) * mode[1].toInt()) |
-                    (int(SMESH_Actor::eFaces  ) * mode[3].toInt()) |
-                    (int(SMESH_Actor::eVolumes) * mode[5].toInt());
-                  if (aNewMode != aMode)
-                    aSmeshActor->SetEntityMode(aNewMode);
+              int aEntityMode = SMESH_Actor::eAllEntity;
+              for ( int i = 0; i < mode.count(); i+=2 ) {
+                if ( i < mode.count()-1 ) {
+                  QString type = mode[i];
+                  bool val = mode[i+1].toInt();
+                  if      ( type == "e" && !val )
+                    aEntityMode = aEntityMode & ~SMESH_Actor::eEdges;
+                  else if ( type == "f" && !val )
+                    aEntityMode = aEntityMode & ~SMESH_Actor::eFaces;
+                  else if ( type == "v" && !val )
+                    aEntityMode = aEntityMode & ~SMESH_Actor::eVolumes;
+                  else if ( type == "0d" && !val )
+                    aEntityMode = aEntityMode & ~SMESH_Actor::e0DElements;
+                  else if ( type == "b" && !val )
+                    aEntityMode = aEntityMode & ~SMESH_Actor::eBallElem;
                 }
               }
+              aSmeshActor->SetEntityMode( aEntityMode );
             }
             // Colors
             else if (paramNameStr == "Colors") {
               QStringList colors = val.split(gDigitsSep, QString::SkipEmptyParts);
-              if (colors.count() == 16 || colors.count() == 18 ) {
-                if (colors[0] != "surface" || colors[4]  != "backsurface" ||
-                    (colors[8] != "edge" && colors[6] != "edge" ) || (colors[12] != "node" && colors[10] != "node") ||
-                    (colors.count() == 18 && colors[14] != "outline")) {
-                  MESSAGE("Invalid order of data in Colors, must be: "
-                          "surface:r:g:b:backsurface:r:g:b:edge:r:g:b:node:r:g:b or surface:r:g:b:backsurface:delta:edge:r:g:b:node:r:g:b:outline:r:g:b");
+              QColor nodeColor;
+              QColor edgeColor;
+              QColor faceColor;
+              QColor volumeColor;
+              QColor elem0dColor;
+              QColor ballColor;
+              QColor outlineColor;
+              QColor orientationColor;
+              int deltaF;
+              int deltaV;
+              QColor c;
+              double r, g, b;
+              bool bOk;
+              // below lines are required to get default values for delta coefficients
+              // of backface color for faces and color of reversed volumes
+              SMESH::GetColor( "SMESH", "fill_color",   c, deltaF, "0,170,255|-100" );
+              SMESH::GetColor( "SMESH", "volume_color", c, deltaV, "255,0,170|-100" );
+              for ( int i = 0; i < colors.count(); i++ ) {
+                QString type = colors[i];
+                if ( type == "surface" ) {
+                  // face color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  faceColor.setRgbF( r, g, b );
+                  i += 3;
                 }
-                else {
-                  int delta = 0;
-                  float er,eg,eb;
-                  float nr,ng,nb;
-                  vtkFloatingPointType otr,otg,otb;
-                  //Old case backsurface color is independent
-                  if( colors.count() == 16 ) {
-                    QColor ffc;
-                    SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "0,170,255|-100" ) ;
-                    er = colors[9].toFloat();
-                    eg = colors[10].toFloat();
-                    eb = colors[11].toFloat();
-
-                    nr = colors[13].toFloat();
-                    ng = colors[14].toFloat();
-                    nb = colors[15].toFloat();
-                    SMESH::GetColor("SMESH", "outline_color", otr, otg, otb, QColor( 0, 70, 0 ) );
-                  } else {
-                    //New case backsurface color depends on surface color
-                    delta = colors[5].toInt();
-
-                    er = colors[7].toFloat();
-                    eg = colors[8].toFloat();
-                    eb = colors[9].toFloat();
-
-                    nr = colors[11].toFloat();
-                    ng = colors[12].toFloat();
-                    nb = colors[13].toFloat();
-
-                    otr = colors[15].toFloat();
-                    otg = colors[16].toFloat();
-                    otb = colors[17].toFloat();
-                  }
-                  aSmeshActor->SetSufaceColor(colors[1].toFloat(), colors[2].toFloat(), colors[3].toFloat(), delta);
-                  aSmeshActor->SetEdgeColor(er,eg,eb);
-                  aSmeshActor->SetNodeColor(nr,ng,nb);
-                  aSmeshActor->SetOutlineColor(otr,otg,otb);
+                else if ( type == "backsurface" ) {
+                  // backface color can be defined in several ways
+                  // - in old versions, it is set as rgb triple r:g:b - this was is unsupported now
+                  // - in latest versions, it is set as delta coefficient
+                  bool rgbOk = false, deltaOk;
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  int delta = colors[i+1].toInt( &deltaOk );
+                  i++;                                 // shift index
+                  if ( i+1 < colors.count() )          // index is shifted to 1
+                    g = colors[i+1].toDouble( &rgbOk );
+                  if ( rgbOk ) i++;                    // shift index
+                  if ( rgbOk && i+1 < colors.count() ) // index is shifted to 2
+                    b = colors[i+1].toDouble( &rgbOk );
+                  if ( rgbOk ) i++;
+                  // - as currently there's no way to set directly backsurface color as it was before,
+                  // we ignore old dump where r,g,b triple was set
+                  // - also we check that delta parameter is set properly
+                  if ( !rgbOk && deltaOk )
+                    deltaF = delta;
+                }
+                else if ( type == "volume" ) {
+                  // volume color is set by 4 values r:g:b:delta, where
+                  // - r,g,b - is a normal volume rgb color components
+                  // - delta - is a reversed volume color delta coefficient
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+4 >= colors.count() ) break;                  // format error
+                  int delta = colors[i+4].toInt( &bOk );
+                  if ( !bOk ) break;                                   // format error
+                  volumeColor.setRgbF( r, g, b );
+                  deltaV = delta;
+                  i += 4;
+                }
+                else if ( type == "edge" ) {
+                  // edge color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  edgeColor.setRgbF( r, g, b );
+                  i += 3;
+                }
+                else if ( type == "node" ) {
+                  // node color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  nodeColor.setRgbF( r, g, b );
+                  i += 3;
+                }
+                else if ( type == "elem0d" ) {
+                  // 0d element color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  elem0dColor.setRgbF( r, g, b );
+                  i += 3;
+                }
+                else if ( type == "ball" ) {
+                  // ball color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  ballColor.setRgbF( r, g, b );
+                  i += 3;
+                }
+                else if ( type == "outline" ) {
+                  // outline color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  outlineColor.setRgbF( r, g, b );
+                  i += 3;
+                }
+                else if ( type == "orientation" ) {
+                  // orientation color is set by 3 values r:g:b, where
+                  // - r,g,b - is rgb color components
+                  if ( i+1 >= colors.count() ) break;                  // format error
+                  r = colors[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= colors.count() ) break;                  // format error
+                  g = colors[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+3 >= colors.count() ) break;                  // format error
+                  b = colors[i+3].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  orientationColor.setRgbF( r, g, b );
+                  i += 3;
                 }
               }
+              // node color
+              if ( nodeColor.isValid() )
+                aSmeshActor->SetNodeColor( nodeColor.redF(), nodeColor.greenF(), nodeColor.blueF() );
+              // edge color
+              if ( edgeColor.isValid() )
+                aSmeshActor->SetEdgeColor( edgeColor.redF(), edgeColor.greenF(), edgeColor.blueF() );
+              // face color
+              if ( faceColor.isValid() )
+                aSmeshActor->SetSufaceColor( faceColor.redF(), faceColor.greenF(), faceColor.blueF(), deltaF );
+              // volume color
+              if ( volumeColor.isValid() )
+                aSmeshActor->SetVolumeColor( volumeColor.redF(), volumeColor.greenF(), volumeColor.blueF(), deltaV );
+              else if ( faceColor.isValid() ) // backward compatibility (no separate color for volumes)
+                aSmeshActor->SetVolumeColor( faceColor.redF(), faceColor.greenF(), faceColor.blueF(), deltaF );
+              // 0d element color
+              if ( elem0dColor.isValid() )
+                aSmeshActor->Set0DColor( elem0dColor.redF(), elem0dColor.greenF(), elem0dColor.blueF() );
+              // ball color
+              if ( ballColor.isValid() )
+                aSmeshActor->SetBallColor( ballColor.redF(), ballColor.greenF(), ballColor.blueF() );
+              // outline color
+              if ( outlineColor.isValid() )
+                aSmeshActor->SetOutlineColor( outlineColor.redF(), outlineColor.greenF(), outlineColor.blueF() );
+              // orientation color
+              if ( orientationColor.isValid() )
+                aSmeshActor->SetFacesOrientationColor( orientationColor.redF(), orientationColor.greenF(), orientationColor.blueF() );
             }
-            // Sizes of lines and points
+            // Sizes
             else if (paramNameStr == "Sizes") {
               QStringList sizes = val.split(gDigitsSep, QString::SkipEmptyParts);
-              if (sizes.count() == 4) {
-                if (sizes[0] != "line" || sizes[2] != "shrink") {
-                  MESSAGE("Invalid order of data in Sizes, must be: "
-                          "line:int:shrink:float");
+              bool bOk;
+              int lineWidth = -1;
+              int outlineWidth = -1;
+              int elem0dSize = -1;
+              int ballSize = -1;
+              double ballScale = -1.0;
+              double shrinkSize = -1;
+              double orientationSize = -1;
+              bool orientation3d = false;
+              for ( int i = 0; i < sizes.count(); i++ ) {
+                QString type = sizes[i];
+                if ( type == "line" ) {
+                  // line (wireframe) width is given as single integer value
+                  if ( i+1 >= sizes.count() ) break;                    // format error
+                  int v = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;  // format error
+                  lineWidth = v;
+                  i++;
                 }
-                else {
-                  aSmeshActor->SetLineWidth(sizes[1].toInt());
-                  aSmeshActor->SetShrinkFactor(sizes[3].toFloat());
+                if ( type == "outline" ) {
+                  // outline width is given as single integer value
+                  if ( i+1 >= sizes.count() ) break;                    // format error
+                  int v = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;  // format error
+                  outlineWidth = v;
+                  i++;
                 }
-              }
-              else if (sizes.count() == 6) { // just to support old format
-                if (sizes[0] != "line" || sizes[2]  != "node" || sizes[4] != "shrink") {
-                  MESSAGE("Invalid order of data in Sizes, must be: "
-                          "line:int:node:int:shrink:float");
+                else if ( type == "elem0d" ) {
+                  // 0d element size is given as single integer value
+                  if ( i+1 >= sizes.count() ) break;                    // format error
+                  int v = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;  // format error
+                  elem0dSize = v;
+                  i++;
+                }
+                else if ( type == "ball" ) {
+                  // balls are specified by two values: size:scale, where
+                  // - size - is a integer value specifying size
+                  // - scale - is a double value specifying scale factor
+                  if ( i+1 >= sizes.count() ) break;                       // format error
+                  int v1 = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;    // format error
+                  if ( i+2 >= sizes.count() ) break;                       // format error
+                  double v2 = sizes[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  ballSize = v1;
+                  ballScale = v2;
+                  i += 2;
+                }
+                else if ( type == "shrink" ) {
+                  // shrink factor is given as single floating point value
+                  if ( i+1 >= sizes.count() ) break;                          // format error
+                  double v = sizes[i+1].toDouble( &bOk ); if ( !bOk ) break;  // format error
+                  shrinkSize = v;
+                  i++;
                 }
-                else {
-                  aSmeshActor->SetLineWidth(sizes[1].toInt());
-                  //aSmeshActor->SetNodeSize(sizes[3].toInt()); // made obsolete
-                  aSmeshActor->SetShrinkFactor(sizes[5].toFloat());
+                else if ( type == "orientation" ) {
+                  // orientation vectors are specified by two values size:3d, where
+                  // - size - is a floating point value specifying scale factor
+                  // - 3d - is a boolean
+                  if ( i+1 >= sizes.count() ) break;                          // format error
+                  double v1 = sizes[i+1].toDouble( &bOk ); if ( !bOk ) break; // format error
+                  if ( i+2 >= sizes.count() ) break;                          // format error
+                  int v2 = sizes[i+2].toInt( &bOk ); if ( !bOk ) break;       // format error
+                  orientationSize = v1;
+                  orientation3d = (bool)v2;
+                  i += 2;
                 }
               }
+              // line (wireframe) width
+              if ( lineWidth > 0 )
+                aSmeshActor->SetLineWidth( lineWidth );
+              // outline width
+              if ( outlineWidth > 0 )
+                aSmeshActor->SetOutlineWidth( outlineWidth );
+              else if ( lineWidth > 0 ) // backward compatibility (no separate width for outlines)
+                aSmeshActor->SetOutlineWidth( lineWidth );
+              // 0d element size
+              if ( elem0dSize > 0 )
+                aSmeshActor->Set0DSize( elem0dSize );
+              // ball size
+              if ( ballSize > 0 )
+                aSmeshActor->SetBallSize( ballSize );
+              // ball scale
+              if ( ballScale > 0.0 )
+                aSmeshActor->SetBallScale( ballScale );
+              // shrink factor
+              if ( shrinkSize > 0 )
+                aSmeshActor->SetShrinkFactor( shrinkSize );
+              // orientation vectors
+              if ( orientationSize > 0 ) {
+                aSmeshActor->SetFacesOrientationScale( orientationSize );
+                aSmeshActor->SetFacesOrientation3DVectors( orientation3d );
+              }
             }
             // Point marker
             else if (paramNameStr == "PointMarker") {
@@ -5864,21 +6441,18 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
             // Clipping
             else if (paramNameStr.startsWith("ClippingPlane")) {
               QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
-              // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles)
+              // old format - val looks like "Off" or "1:0:0:0.5:0:0" 
+              // (mode(relative), is OpenGL clipping plane, orientation, distance, two angles)
+              // or "0:1:1:10.5:1.0:1.0:15.0:10.0:10.0" 
+              // (mode(absolute), is OpenGL clipping plane, orientation, base point(x, y, z), direction (dx, dy, dz))
               // new format - val looks like "Off" or "0" (plane id)
               // (note: in new format "Off" value is used only for consistency,
               //  so it is processed together with values in old format)
-              bool anIsOldFormat = ( vals.count() == 4 || val == "Off" );
+              bool anIsOldFormat = ( vals.count() == 6 || vals.count() == 9 || val == "Off" );
               if( anIsOldFormat ) {
                 if (paramNameStr == "ClippingPlane1" || val == "Off")
                   aSmeshActor->RemoveAllClippingPlanes();
                 if (val != "Off") {
-                  SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt();
-                  double aDistance = vals[1].toFloat();
-                  vtkFloatingPointType anAngle[2];
-                  anAngle[0] = vals[2].toFloat();
-                  anAngle[1] = vals[3].toFloat();
-
                   QList<SUIT_ViewManager*> lst;
                   getApp()->viewManagers(viewerTypStr, lst);
                   // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
@@ -5890,13 +6464,35 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
 
                     SMESH::TActorList anActorList;
                     anActorList.push_back( aSmeshActor );
-                    SMESH::OrientedPlane* aPlane =
-                      SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle);
+                    SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New( vtkView );
+                    aPlane->myViewWindow = vtkView;
+                    SMESH::Mode aMode = ( SMESH::Mode )vals[0].toInt();
+                    aPlane->PlaneMode = aMode;
+                    bool isOpenGLClipping = ( bool )vals[1].toInt();
+                    aPlane->IsOpenGLClipping = isOpenGLClipping;
+                    if ( aMode == SMESH::Absolute ) {
+                      aPlane->myAbsoluteOrientation = vals[2].toInt();
+                      aPlane->X = vals[3].toFloat();
+                      aPlane->Y = vals[4].toFloat();
+                      aPlane->Z = vals[5].toFloat();
+                      aPlane->Dx = vals[6].toFloat();
+                      aPlane->Dy = vals[7].toFloat();
+                      aPlane->Dz = vals[8].toFloat();
+                    }
+                    else if ( aMode == SMESH::Relative ) {
+                      aPlane->myRelativeOrientation = (SMESH::Orientation)vals[2].toInt();
+                      aPlane->myDistance = vals[3].toFloat();
+                      aPlane->myAngle[0] = vals[4].toFloat();
+                      aPlane->myAngle[1] = vals[5].toFloat();
+                    }
+
                     if( aPlane ) {
-                      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
-                      aClippingPlaneInfo.Plane = aPlane;
-                      aClippingPlaneInfo.ActorList = anActorList;
-                      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+                      if ( SMESHGUI_ClippingDlg::AddPlane( anActorList, aPlane ) ) {
+                        SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+                        aClippingPlaneInfo.Plane = aPlane;
+                        aClippingPlaneInfo.ActorList = anActorList;
+                        aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+                      }
                     }
                   }
                 }
@@ -6017,23 +6613,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
       for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) {
         const TPlaneData& aPlaneData = *anIter4;
         if( aPlaneData.Id == aPlaneId ) {
-          SMESH::OrientedPlane* aPlane =
-            SMESHGUI_ClippingDlg::AddPlane( anActorList,
-                                            aViewWindow,
-                                            (SMESH::Orientation)aPlaneData.Orientation,
-                                            aPlaneData.Distance,
-                                            aPlaneData.Angle );
+          SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New( aViewWindow );
+          aPlane->myViewWindow = aViewWindow;
+          aPlane->PlaneMode = (SMESH::Mode)aPlaneData.Mode;
+          aPlane->IsOpenGLClipping = aPlaneData.isOpenGLClipping;
+          if ( aPlane->PlaneMode == SMESH::Absolute ) {
+            aPlane->myAbsoluteOrientation = aPlaneData.AbsoluteOrientation;
+            aPlane->X = aPlaneData.X;
+            aPlane->Y = aPlaneData.Y;
+            aPlane->Z = aPlaneData.Z;
+            aPlane->Dx = aPlaneData.Dx;
+            aPlane->Dy = aPlaneData.Dy;
+            aPlane->Dz = aPlaneData.Dz;
+          }
+          else if ( aPlane->PlaneMode == SMESH::Relative ) {
+            aPlane->myRelativeOrientation = (SMESH::Orientation)aPlaneData.RelativeOrientation;
+            aPlane->myDistance = aPlaneData.Distance;
+            aPlane->myAngle[0] = aPlaneData.Angle[0];
+            aPlane->myAngle[1] = aPlaneData.Angle[1];
+          }
           if( aPlane ) {
-            SMESH::ClippingPlaneInfo aClippingPlaneInfo;
-            aClippingPlaneInfo.Plane = aPlane;
-            aClippingPlaneInfo.ActorList = anActorList;
-            aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+            if ( SMESHGUI_ClippingDlg::AddPlane( anActorList, aPlane ) ) {
+              SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+              aClippingPlaneInfo.Plane = aPlane;
+              aClippingPlaneInfo.ActorList = anActorList;
+              aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+            }
           }
           break;
         }
       }
+    
     }
   }
+  
 
   // update all VTK views
   QList<SUIT_ViewManager*> lst;
@@ -6042,6 +6655,14 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     SUIT_ViewModel* vmodel = (*it)->getViewModel();
     if (vmodel && vmodel->getType() == SVTK_Viewer::Type()) {
       SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) (*it)->getActiveView();
+      // set OpenGL clipping planes
+      VTK::ActorCollectionCopy aCopy( vtkView->getRenderer()->GetActors() );
+      vtkActorCollection* anAllActors = aCopy.GetActors();
+      anAllActors->InitTraversal();
+      while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+          anActor->SetOpenGLClippingPlane();
+      
       vtkView->getRenderer()->ResetCameraClippingRange();
       vtkView->Repaint();
     }
@@ -6055,7 +6676,7 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
   \param param parameter
   \return identifier of preferences
 */
-int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param )
+int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param, const bool needSize )
 {
   int tfont = addPreference( label, pId, LightApp_Preferences::Font, "SMESH", param );
 
@@ -6069,6 +6690,7 @@ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString
   setPreferenceProperty( tfont, "fonts", fam );
 
   int f = QtxFontEdit::Family | QtxFontEdit::Bold | QtxFontEdit::Italic | QtxFontEdit::Shadow;
+  if ( needSize ) f = f | QtxFontEdit::Size;
   setPreferenceProperty( tfont, "features", f );
 
   return tfont;
@@ -6113,7 +6735,7 @@ void SMESHGUI::message( const QString& msg )
       _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() );
       QString name;
       if ( obj )
-        name = obj->GetName().c_str();
+        name = QString::fromUtf8(obj->GetName().c_str());
       if ( name.isEmpty() )
         return;
       
@@ -6166,11 +6788,11 @@ bool SMESHGUI::renameAllowed( const QString& entry) const {
 
   // check type to prevent renaming of inappropriate objects
   int aType = SMESHGUI_Selection::type(qPrintable(entry), SMESH::GetActiveStudyDocument());
-  if (aType == MESH || aType == GROUP ||
-      aType == SUBMESH || aType == SUBMESH_COMPOUND ||
-      aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
-      aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX ||
-      aType == HYPOTHESIS || aType == ALGORITHM)
+  if (aType == SMESH::MESH || aType == SMESH::GROUP ||
+      aType == SMESH::SUBMESH || aType == SMESH::SUBMESH_COMPOUND ||
+      aType == SMESH::SUBMESH_SOLID || aType == SMESH::SUBMESH_FACE ||
+      aType == SMESH::SUBMESH_EDGE || aType == SMESH::SUBMESH_VERTEX ||
+      aType == SMESH::HYPOTHESIS || aType == SMESH::ALGORITHM)
     return true;
 
   return false;
@@ -6213,11 +6835,11 @@ bool SMESHGUI::renameObject( const QString& entry, const QString& name) {
       aName = anAttr;
       // check type to prevent renaming of inappropriate objects
       int aType = SMESHGUI_Selection::type( qPrintable(entry), SMESH::GetActiveStudyDocument() );
-      if (aType == MESH || aType == GROUP ||
-          aType == SUBMESH || aType == SUBMESH_COMPOUND ||
-          aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
-          aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX ||
-          aType == HYPOTHESIS || aType == ALGORITHM) {
+      if (aType == SMESH::MESH || aType == SMESH::GROUP ||
+          aType == SMESH::SUBMESH || aType == SMESH::SUBMESH_COMPOUND ||
+          aType == SMESH::SUBMESH_SOLID || aType == SMESH::SUBMESH_FACE ||
+          aType == SMESH::SUBMESH_EDGE || aType == SMESH::SUBMESH_VERTEX ||
+          aType == SMESH::HYPOTHESIS || aType == SMESH::ALGORITHM) {
         if ( !name.isEmpty() ) {
           SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), qPrintable(name) );
 
@@ -6238,3 +6860,32 @@ bool SMESHGUI::renameObject( const QString& entry, const QString& name) {
   }
   return false;
 }
+
+SALOMEDS::Color SMESHGUI::getPredefinedUniqueColor()
+{
+  static QList<QColor> colors;
+
+  if ( colors.isEmpty() ) {
+
+    for (int s = 0; s < 2 ; s++)
+    {
+      for (int v = 100; v >= 40; v = v - 20)
+      {
+        for (int h = 0; h < 359 ; h = h + 60)
+        {
+          colors.append(QColor::fromHsv(h, 255 - s * 127, v * 255 / 100));
+        }
+      }
+    }
+  }
+  static int currentColor = 0;
+
+  SALOMEDS::Color color;
+  color.R = (double)colors[currentColor].red()   / 255.0;
+  color.G = (double)colors[currentColor].green() / 255.0;
+  color.B = (double)colors[currentColor].blue()  / 255.0;
+
+  currentColor = (currentColor+1) % colors.count();
+
+  return color;
+}