Salome HOME
[bos #40653][CEA] New mesh import export formats with meshio.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index ed565252426d746af3557ea0e1fee848b67f02ab..5f1d4549a0704076c63ebd7755a371544b2e5cdc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_MG_ADAPTDRIVER.h"
 #include "SMESHGUI_HomardAdaptDlg.h"
 #include "SMESHGUI_Make2DFrom3DOp.h"
+#include "SMESHGUI_MakeFull2DFrom3DOp.h"
 #include "SMESHGUI_MakeNodeAtPointDlg.h"
 #include "SMESHGUI_Measurements.h"
 #include "SMESHGUI_MergeDlg.h"
 #include "SMESHGUI_MeshInfo.h"
+#include "SMESHGUI_Meshio.h"
 #include "SMESHGUI_MeshOp.h"
 #include "SMESHGUI_MeshOrderOp.h"
 #include "SMESHGUI_MeshPatternDlg.h"
@@ -97,6 +99,8 @@
 #include "SMESHGUI_SymmetryDlg.h"
 #include "SMESHGUI_TranslationDlg.h"
 #include "SMESHGUI_TransparencyDlg.h"
+#include "SMESHGUI_CreateDualMeshDlg.h"
+#include "SMESHGUI_CreateDualMeshOp.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
 
@@ -210,6 +214,7 @@ namespace
   void Control( int theCommandID );
 
   // Definitions
+
   //================================================================================
   /*!
    * \brief Reads meshes from file
@@ -248,6 +253,12 @@ namespace
       filter.append( QObject::tr( "GMF_ASCII_FILES_FILTER" ) + " (*.mesh)"  );
       filter.append( QObject::tr( "GMF_BINARY_FILES_FILTER") + " (*.meshb)" );
     }
+    else if (theCommandID == SMESHOp::OpImportMESHIO) {
+      if (!SMESHGUI_Meshio::IsMeshioInstalled())
+        return;
+
+      filter = SMESHGUI_Meshio::GetImportFileFilter();
+    }
 
     QString anInitialPath = "";
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
@@ -363,11 +374,20 @@ namespace
               }
               break;
             }
+          case SMESHOp::OpImportMESHIO:
+            {
+              aMeshes = SMESHGUI_Meshio::ImportMesh(theComponentMesh, filename, errors);
+              break;
+            }
           }
         }
         catch ( const SALOME::SALOME_Exception& S_ex ) {
-          errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
-                         arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
+          const QString exText(S_ex.details.text);
+          if (exText.startsWith("MESHIO"))
+            errors.append('\n' + exText);
+          else
+            errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                          arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
         }
 
         for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ )
@@ -437,8 +457,14 @@ namespace
                          theCommandID == SMESHOp::OpPopupExportCGNS );
     const bool isGMF = ( theCommandID == SMESHOp::OpExportGMF ||
                          theCommandID == SMESHOp::OpPopupExportGMF );
+    const bool isMESHIO = (theCommandID == SMESHOp::OpExportMESHIO);
 
-    const bool multiMeshSupported = ( isMED || isCGNS ); // file can hold several meshes
+    if (isMESHIO && !SMESHGUI_Meshio::IsMeshioInstalled())
+    {
+      return;
+    }
+
+    const bool multiMeshSupported = isMED || isCGNS || isMESHIO; // file can hold several meshes
     if ( selected.Extent() == 0 || ( selected.Extent() > 1 && !multiMeshSupported ))
       return;
     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
@@ -514,7 +540,7 @@ namespace
     SMESH::SMESH_Mesh_var            aMesh = aMeshOrGroup->GetMesh();
     QString                      aMeshName = (*aMeshIter).second;
 
-    if ( isMED || isCGNS ) // formats where group names must be unique
+    if (isMED || isCGNS || isMESHIO) // formats where group names must be unique
     {
       // check for equal group names within each mesh
       for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
@@ -624,6 +650,7 @@ namespace
     // Get parameters of export operation
 
     QString aFilename;
+    QString aSelectedFilter; // for meshio to get a filter selected by user
     int aFormat =-1;         // for MED version used for write
     bool isOkToWrite = true; // to check MED file version compatibility before adding a mesh in an existing file
 
@@ -869,6 +896,14 @@ namespace
         delete zTolWdg;
       delete fd;
     }
+    else if (isMESHIO)
+    {
+      if (SMESHGUI_Meshio::CheckMeshCount(aMeshList))
+      {
+        aFilename = SMESHGUI_Meshio::GetFileName(aSelectedFilter);
+        MESSAGE("aSelectedFilter: " << aSelectedFilter.toStdString());
+      }
+    }
     else
     {
       return;
@@ -951,16 +986,28 @@ namespace
           toCreateGroups = true;
           aMesh->ExportGMF( aMeshOrGroup, aFilename.toUtf8().data(), toCreateGroups );
         }
+        else if (isMESHIO)
+        {
+          SMESHGUI_Meshio::ExportMesh(aMeshList, aFilename, aSelectedFilter);
+        }
       }
       catch (const SALOME::SALOME_Exception& S_ex)
       {
         wc.suspend();
+        const QString exText(S_ex.details.text);
+
         if ( S_ex.details.type == SALOME::COMM && // communicate about too large mesh
              strncmp( "format=", S_ex.details.sourceFile.in(), 7 ) == 0 )
 
           SUIT_MessageBox::critical(SMESHGUI::desktop(),
                                     QObject::tr("SMESH_WRN_WARNING"),
                                     QObject::tr(S_ex.details.text.in() ));
+        else if (exText.startsWith("MESHIO"))
+        {
+          SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                   QObject::tr("SMESH_WRN_WARNING"),
+                                   QObject::tr("SMESH_EXPORT_FAILED_SHORT") + "\n\n" + exText);
+        }
         else
           SUIT_MessageBox::warning(SMESHGUI::desktop(),
                                    QObject::tr("SMESH_WRN_WARNING"),
@@ -1118,6 +1165,8 @@ namespace
       type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
     else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) )
       type = QObject::tr( "WARP_ELEMENTS" );
+    else if (dynamic_cast<SMESH::Controls::Warping3D*>(f.get()))
+      type = QObject::tr("WARP_3D_ELEMENTS");
     else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) )
       type = QObject::tr( "TAPER_ELEMENTS" );
     else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) )
@@ -1160,6 +1209,8 @@ namespace
       type = QObject::tr( "EQUAL_VOLUME" );
     else if ( dynamic_cast< SMESH::Controls::NodeConnectivityNumber* >( f.get() ) )
       type = QObject::tr( "NODE_CONNECTIVITY_NB" );
+    else if ( dynamic_cast< SMESH::Controls::ScaledJacobian* >( f.get() ) )
+      type = QObject::tr( "SCALED_JACOBIAN" );
     return type;
   }
 
@@ -1775,7 +1826,9 @@ namespace
     ActionControl.Bind( SMESHOp::OpMaxElementLength2D,    SMESH_Actor::eMaxElementLength2D );
     ActionControl.Bind( SMESHOp::OpEqualFace,             SMESH_Actor::eCoincidentElems2D );
     ActionControl.Bind( SMESHOp::OpAspectRatio3D,         SMESH_Actor::eAspectRatio3D );
+    ActionControl.Bind( SMESHOp::OpWarping3D,             SMESH_Actor::eWarping3D );
     ActionControl.Bind( SMESHOp::OpVolume,                SMESH_Actor::eVolume3D );
+    ActionControl.Bind( SMESHOp::OpScaledJacobian,        SMESH_Actor::eScaledJacobian );
     ActionControl.Bind( SMESHOp::OpMaxElementLength3D,    SMESH_Actor::eMaxElementLength3D );
     ActionControl.Bind( SMESHOp::OpBareBorderVolume,      SMESH_Actor::eBareBorderVolume );
     ActionControl.Bind( SMESHOp::OpOverConstrainedVolume, SMESH_Actor::eOverConstrainedVolume );
@@ -2142,7 +2195,7 @@ SMESHGUI::SMESHGUI() : SalomeApp_Module( "SMESH" )
   {
     CORBA::Boolean anIsEmbeddedMode;
     myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode);
-     
+
     //MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode);
 
     //  0019923: EDF 765 SMESH : default values of hypothesis
@@ -2551,6 +2604,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   SVTK_ViewWindow* vtkwnd = dynamic_cast<SVTK_ViewWindow*>( view );
 
   //QAction* act = action( theCommandID );
+  bool logAction(false);
 
   switch (theCommandID) {
   case SMESHOp::OpDelete:
@@ -2563,6 +2617,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpImportSTL:
   case SMESHOp::OpImportCGNS:
   case SMESHOp::OpImportGMF:
+  case SMESHOp::OpImportMESHIO:
   case SMESHOp::OpPopupImportDAT:
   case SMESHOp::OpPopupImportUNV:
   case SMESHOp::OpPopupImportMED:
@@ -2599,6 +2654,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpExportSTL:
   case SMESHOp::OpExportCGNS:
   case SMESHOp::OpExportGMF:
+  case SMESHOp::OpExportMESHIO:
   case SMESHOp::OpPopupExportDAT:
   case SMESHOp::OpPopupExportMED:
   case SMESHOp::OpPopupExportUNV:
@@ -2868,6 +2924,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     break;
   case SMESHOp::OpCopyMesh:
     {
+      logAction = true;
       if (isStudyLocked()) break;
       EmitSignalDeactivateDialog();
       ( new SMESHGUI_CopyMeshDlg( this ) )->show();
@@ -3051,7 +3108,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   // Adaptation - end
   case SMESHOp::OpSplitBiQuadratic:
   case SMESHOp::OpConvertMeshToQuadratic:
+  case SMESHOp::OpCreateDualMesh:
   case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D
+  case SMESHOp::OpCreate2DElements: // create full 2D mesh from 3D
   case SMESHOp::OpReorientFaces:
   case SMESHOp::OpCreateGeometryGroup:
     {
@@ -3691,6 +3750,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case SMESHOp::OpTranslation:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3706,6 +3766,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case SMESHOp::OpRotation:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3721,6 +3782,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case SMESHOp::OpSymmetry:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3736,6 +3798,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
   case SMESHOp::OpScale:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3752,6 +3815,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case SMESHOp::OpOffset:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3768,6 +3832,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case SMESHOp::OpSewing:
     {
+      logAction = true;
       if(isStudyLocked()) break;
       if ( warnOnGeomModif() )
         break; // action forbidden as geometry modified
@@ -3898,7 +3963,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpMaxElementLength2D:
   case SMESHOp::OpEqualFace:
   case SMESHOp::OpAspectRatio3D:
+  case SMESHOp::OpWarping3D:
   case SMESHOp::OpVolume:
+  case SMESHOp::OpScaledJacobian:
   case SMESHOp::OpMaxElementLength3D:
   case SMESHOp::OpBareBorderVolume:
   case SMESHOp::OpOverConstrainedVolume:
@@ -3995,6 +4062,14 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   anApp->updateActions(); //SRN: To update a Save button in the toolbar
   //updateObjBrowser();
+  if(logAction)
+  {
+    QAction* anAction = action( theCommandID );
+    CAM_Application::logStructuredUserEvent( "Mesh",
+                                             "Operation",
+                                             anAction->text(),
+                                             "activated" );
+  }
   return true;
 }
 
@@ -4123,6 +4198,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpImportCGNS, "IMPORT_CGNS" );
 #endif
   createSMESHAction( SMESHOp::OpImportGMF,  "IMPORT_GMF"  );
+  createSMESHAction( SMESHOp::OpImportMESHIO,  "IMPORT_MESHIO" );
   createSMESHAction( SMESHOp::OpPopupImportUNV, "IMPORT_UNV");
   createSMESHAction( SMESHOp::OpPopupImportMED, "IMPORT_MED");
   createSMESHAction( SMESHOp::OpPopupImportSTL, "IMPORT_STL"  );
@@ -4139,6 +4215,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpExportCGNS, "CGNS");
 #endif
   createSMESHAction( SMESHOp::OpExportGMF,      "GMF" );
+  createSMESHAction( SMESHOp::OpExportMESHIO,   "EXPORT_MESHIO" );
   createSMESHAction( SMESHOp::OpPopupExportDAT, "DAT" );
   createSMESHAction( SMESHOp::OpPopupExportMED, "MED" );
   createSMESHAction( SMESHOp::OpPopupExportUNV, "UNV" );
@@ -4205,11 +4282,13 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpMaxElementLength2D,    "MAX_ELEMENT_LENGTH_2D",   "ICON_MAX_ELEMENT_LENGTH_2D",   0, true );
   createSMESHAction( SMESHOp::OpEqualFace,             "EQUAL_FACE",              "ICON_EQUAL_FACE",    0, true );
   createSMESHAction( SMESHOp::OpAspectRatio3D,         "ASPECT_3D",               "ICON_ASPECT_3D",     0, true );
+  createSMESHAction( SMESHOp::OpWarping3D,             "WARP_3D",                 "ICON_WARP",          0, true);
   createSMESHAction( SMESHOp::OpVolume,                "VOLUME_3D",               "ICON_VOLUME_3D",     0, true );
   createSMESHAction( SMESHOp::OpMaxElementLength3D,    "MAX_ELEMENT_LENGTH_3D",   "ICON_MAX_ELEMENT_LENGTH_3D",   0, true );
   createSMESHAction( SMESHOp::OpBareBorderVolume,      "BARE_BORDER_VOLUME",      "ICON_BARE_BORDER_VOLUME",      0, true );
   createSMESHAction( SMESHOp::OpOverConstrainedVolume, "OVER_CONSTRAINED_VOLUME", "ICON_OVER_CONSTRAINED_VOLUME", 0, true );
   createSMESHAction( SMESHOp::OpEqualVolume,           "EQUAL_VOLUME",            "ICON_EQUAL_VOLUME",  0, true );
+  createSMESHAction( SMESHOp::OpScaledJacobian,        "SCALED_JACOBIAN",         "ICON_SCALED_JACOBIAN",         0, true );
   createSMESHAction( SMESHOp::OpOverallMeshQuality,    "OVERALL_MESH_QUALITY",    "ICON_OVL_MESH_QUALITY" );
 
   createSMESHAction( SMESHOp::OpNode,                   "NODE",            "ICON_DLG_NODE" );
@@ -4275,7 +4354,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpRevolution,             "REVOLUTION",      "ICON_REVOLUTION" );
   createSMESHAction( SMESHOp::OpPatternMapping,         "MAP",             "ICON_MAP" );
   createSMESHAction( SMESHOp::OpConvertMeshToQuadratic, "CONV_TO_QUAD",    "ICON_CONV_TO_QUAD" );
+  createSMESHAction( SMESHOp::OpCreateDualMesh,         "CREATE_DUAL_MESH","ICON_CREATE_DUAL_MESH" );
   createSMESHAction( SMESHOp::OpCreateBoundaryElements, "2D_FROM_3D",      "ICON_2D_FROM_3D" );
+  createSMESHAction( SMESHOp::OpCreate2DElements,    "2D_FROM_3D_ELEMENTS","ICON_2D_FROM_3D_ELEMENTS" );
 
   createSMESHAction( SMESHOp::OpReset,               "RESET" );
   createSMESHAction( SMESHOp::OpScalarBarProperties, "SCALAR_BAR_PROP" );
@@ -4347,9 +4428,9 @@ void SMESHGUI::initialize( CAM_Application* app )
                << SMESHOp::OpMinimumAngle << SMESHOp::OpWarpingAngle << SMESHOp::OpSkew
                << SMESHOp::OpMaxElementLength2D << SMESHOp::OpBareBorderFace
                << SMESHOp::OpOverConstrainedFace << SMESHOp::OpEqualFace                // face controls
-               << SMESHOp::OpAspectRatio3D << SMESHOp::OpVolume
+               << SMESHOp::OpAspectRatio3D << SMESHOp::OpVolume << SMESHOp::OpWarping3D
                << SMESHOp::OpMaxElementLength3D << SMESHOp::OpBareBorderVolume
-               << SMESHOp::OpOverConstrainedVolume << SMESHOp::OpEqualVolume;           // volume controls
+               << SMESHOp::OpOverConstrainedVolume << SMESHOp::OpEqualVolume << SMESHOp::OpScaledJacobian; // volume controls
   QActionGroup* aCtrlGroup = new QActionGroup( application()->desktop() );
   aCtrlGroup->setExclusive( true );
   for( int i = 0; i < aCtrlActions.size(); i++ )
@@ -4384,6 +4465,7 @@ void SMESHGUI::initialize( CAM_Application* app )
       transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 ),
       basicPropId = createMenu( tr( "MEN_BASIC_PROPERTIES" ), measureId, -1, 10 );
 
+  // Import menu
   //createMenu( SMESHOp::OpImportDAT, importId, -1 );
   createMenu( SMESHOp::OpImportUNV,  importId, -1 );
   createMenu( SMESHOp::OpImportMED,  importId, -1 );
@@ -4392,6 +4474,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpImportCGNS, importId, -1 );
 #endif
   createMenu( SMESHOp::OpImportGMF,  importId, -1 );
+  createMenu( SMESHOp::OpImportMESHIO,  importId, -1 ); // formats supported by meshio lib
+
+  // Export menu
   createMenu( SMESHOp::OpExportDAT,  exportId, -1 );
   createMenu( SMESHOp::OpExportMED,  exportId, -1 );
   createMenu( SMESHOp::OpExportUNV,  exportId, -1 );
@@ -4400,6 +4485,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpExportCGNS, exportId, -1 );
 #endif
   createMenu( SMESHOp::OpExportGMF,  exportId, -1 );
+  createMenu( SMESHOp::OpExportMESHIO,  exportId, -1 ); // formats supported by meshio lib
   createMenu( separator(), fileId, 10 );
 
   createMenu( SMESHOp::OpDelete, editId, -1 );
@@ -4411,6 +4497,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpEditMeshOrSubMesh,    meshId, -1 );
   createMenu( SMESHOp::OpBuildCompoundMesh,    meshId, -1 );
   createMenu( SMESHOp::OpCopyMesh,             meshId, -1 );
+  createMenu( SMESHOp::OpCreateDualMesh,       meshId, -1 );
   createMenu( separator(),                     meshId, -1 );
   createMenu( SMESHOp::OpCompute,              meshId, -1 );
   createMenu( SMESHOp::OpPreCompute,           meshId, -1 );
@@ -4459,11 +4546,13 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpEqualFace,             faceId,   -1 );
   createMenu( SMESHOp::OpDeflection2D,          faceId,   -1 );
   createMenu( SMESHOp::OpAspectRatio3D,         volumeId, -1 );
+  createMenu( SMESHOp::OpWarping3D,             volumeId, -1 );
   createMenu( SMESHOp::OpVolume,                volumeId, -1 );
   createMenu( SMESHOp::OpMaxElementLength3D,    volumeId, -1 );
   createMenu( SMESHOp::OpBareBorderVolume,      volumeId, -1 );
   createMenu( SMESHOp::OpOverConstrainedVolume, volumeId, -1 );
   createMenu( SMESHOp::OpEqualVolume,           volumeId, -1 );
+  createMenu( SMESHOp::OpScaledJacobian,        volumeId, -1 );
   createMenu( separator(),                      ctrlId,   -1 );
   createMenu( SMESHOp::OpReset,                 ctrlId,   -1 );
   createMenu( separator(),                      ctrlId,   -1 );
@@ -4524,6 +4613,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 );
   createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 );
+  createMenu( SMESHOp::OpCreate2DElements,       modifyId, -1 );
   createMenu( SMESHOp::OpExtrusion,              modifyId, -1 );
   createMenu( SMESHOp::OpExtrusionAlongAPath,    modifyId, -1 );
   createMenu( SMESHOp::OpRevolution,             modifyId, -1 );
@@ -4616,11 +4706,13 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   int ctrl3dTb = createTool( tr( "TB_CTRL3D" ), QString( "SMESHVolumeControlsToolbar" ) ) ;
   createTool( SMESHOp::OpAspectRatio3D,         ctrl3dTb );
+  createTool( SMESHOp::OpWarping3D,             ctrl3dTb );
   createTool( SMESHOp::OpVolume,                ctrl3dTb );
   createTool( SMESHOp::OpMaxElementLength3D,    ctrl3dTb );
   createTool( SMESHOp::OpBareBorderVolume,      ctrl3dTb );
   createTool( SMESHOp::OpOverConstrainedVolume, ctrl3dTb );
   createTool( SMESHOp::OpEqualVolume,           ctrl3dTb );
+  createTool( SMESHOp::OpScaledJacobian,        ctrl3dTb );
 
   int addElemTb = createTool( tr( "TB_ADD" ), QString( "SMESHAddElementToolbar" ) ) ;
   createTool( SMESHOp::OpNode,              addElemTb );
@@ -4676,6 +4768,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   int modifyTb = createTool( tr( "TB_MODIFY" ), QString( "SMESHModificationToolbar" ) ) ;
   createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb );
   createTool( SMESHOp::OpCreateBoundaryElements, modifyTb );
+  createTool( SMESHOp::OpCreate2DElements,       modifyTb );
   createTool( SMESHOp::OpExtrusion,              modifyTb );
   createTool( SMESHOp::OpExtrusionAlongAPath,    modifyTb );
   createTool( SMESHOp::OpRevolution,             modifyTb );
@@ -4814,6 +4907,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 #endif
   createPopupItem( SMESHOp::OpPopupExportGMF,  OB, mesh_group, only_one_non_empty, anId );
   createPopupItem( SMESHOp::OpPopupExportDAT,  OB, mesh_group, only_one_non_empty, anId );
+  createPopupItem( SMESHOp::OpExportMESHIO,    OB, mesh_group, only_one_non_empty, anId );
 
   anId = popupMgr()->insert( tr( "MEN_IMPORT" ), -1, -1 );        // IMPORT submenu
   createPopupItem( SMESHOp::OpPopupImportMED,  OB, smesh, "", anId );
@@ -5078,6 +5172,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( SMESHOp::OpAspectRatio3D ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( SMESHOp::OpAspectRatio3D ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert ( action( SMESHOp::OpWarping3D ), aSubId, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpWarping3D ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpWarping3D), "controlMode = 'eWarping3D'", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert ( action( SMESHOp::OpVolume ), aSubId, -1 );
   popupMgr()->setRule( action( SMESHOp::OpVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( SMESHOp::OpVolume ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
@@ -5098,6 +5196,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( SMESHOp::OpEqualVolume ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( SMESHOp::OpEqualVolume ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert ( action( SMESHOp::OpScaledJacobian  ), aSubId, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpScaledJacobian ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpScaledJacobian ), "controlMode = 'eScaledJacobian'", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( SMESHOp::OpShowScalarBar ), anId, -1 );
@@ -6025,6 +6127,12 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
   case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D
     op = new SMESHGUI_Make2DFrom3DOp();
     break;
+  case SMESHOp::OpCreateDualMesh:
+    op = new SMESHGUI_CreateDualMeshOp();
+    break;
+  case SMESHOp::OpCreate2DElements:
+    op = new SMESHGUI_MakeFull2DFrom3DOp();
+    break;
   case SMESHOp::OpReorientFaces:
     op = new SMESHGUI_ReorientFacesOp();
     break;