Salome HOME
0022108: EDF 2547 SMESH: Duplicate elements only
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
index 0709265bf2aab9c7d49509f93d010808abad7b76..d157a2c49105dd754c293a3847405ee08b1d62be 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013  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
 #define NOMINMAX
 #endif
 
+// A macro used in SMESH_TryCatch.hxx,
+// it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
+#define SMY_OWN_CATCH \
+  catch ( SALOME::SALOME_Exception & e ) { throw e; }
+
 #include "SMESH_MeshEditor_i.hxx"
 
-#include "DriverMED_R_SMESHDS_Mesh.h"
-#include "DriverMED_W_SMESHDS_Mesh.h"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_ElemIterator.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_MeshVolume.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
-#include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
-#include "SMESHDS_Command.hxx"
-#include "SMESHDS_CommandType.hxx"
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESH_ControlsDef.hxx"
 #include "SMESH_Filter_i.hxx"
-#include "SMESH_Filter_i.hxx"
-#include "SMESH_Gen_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Group.hxx"
 #include "SMESH_Group_i.hxx"
-#include "SMESH_Group_i.hxx"
-#include "SMESH_MEDMesh_i.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MeshAlgos.hxx"
 #include "SMESH_MeshPartDS.hxx"
 #include "SMESH_MesherHelper.hxx"
-#include "SMESH_PreMeshInfo.hxx"
-#include "SMESH_PythonDump.hxx"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_subMesh_i.hxx"
-#include "SMESH_subMesh_i.hxx"
 
-#include "utilities.h"
-#include "Utils_ExceptHandlers.hxx"
-#include "Utils_CorbaException.hxx"
+#include <utilities.h>
+#include <Utils_ExceptHandlers.hxx>
+#include <Utils_CorbaException.hxx>
+#include <SALOMEDS_wrap.hxx>
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRep_Tool.hxx>
@@ -93,6 +87,8 @@
 #include <sstream>
 #include <limits>
 
+#include "SMESH_TryCatch.hxx" // include after OCCT headers!
+
 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
@@ -112,7 +108,7 @@ namespace MeshEditor_I {
     SMDSAbs_ElementType myPreviewType; // type to show
     //!< Constructor
     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
-      _isShapeToMesh = (_id =_studyId =_idDoc = 0);
+      _isShapeToMesh = (_id =_studyId = 0);
       _myMeshDS  = new SMESHDS_Mesh( _id, true );
       myPreviewType = previewElements;
     }
@@ -278,13 +274,23 @@ namespace MeshEditor_I {
                   TIDSortedElemSet&         aMap,
                   const SMDSAbs_ElementType aType = SMDSAbs_All )
   {
-    for (int i=0; i<IDs.length(); i++) {
-      CORBA::Long ind = IDs[i];
-      const SMDS_MeshElement * elem =
-        (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
-      if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
-        aMap.insert( aMap.end(), elem );
-    }
+    SMDS_MeshElement::NonNullFilter filter1;
+    SMDS_MeshElement::TypeFilter    filter2( aType );
+    SMDS_MeshElement::Filter &      filter =
+      ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
+
+    if ( aType == SMDSAbs_Node )
+      for (int i=0; i<IDs.length(); i++) {
+        const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
+        if ( filter( elem ))
+          aMap.insert( aMap.end(), elem );
+      }
+    else
+      for (int i=0; i<IDs.length(); i++) {
+        const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
+        if ( filter( elem ))
+          aMap.insert( aMap.end(), elem );
+      }
   }
   //================================================================================
   /*!
@@ -470,6 +476,23 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
   getEditor().GetError().reset();
   getEditor().CrearLastCreated();
 }
+
+//================================================================================
+/*!
+ * \brief Increment mesh modif time and optionally record that the performed
+ *        modification may influence futher mesh re-compute.
+ *  \param [in] isReComputeSafe - true if the modification does not infulence
+ *              futher mesh re-compute
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
+{
+  myMesh->GetMeshDS()->Modified();
+  if ( !isReComputeSafe )
+    myMesh->SetIsModified( true );
+}
+
 //================================================================================
 /*!
  * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
@@ -508,16 +531,6 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
   return myPreviewMesh;
 }
 
-//================================================================================
-/*!
- * \brief Now does nothing
- */
-//================================================================================
-
-// void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
-// {
-// }
-
 //================================================================================
 /*!
  * Return data of mesh edition preview
@@ -525,7 +538,9 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
 //================================================================================
 
 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
-{
+  throw (SALOME::SALOME_Exception)
+{ 
+  SMESH_TRY;
   const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
 
   if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
@@ -543,9 +558,6 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
     else {
       aMeshDS = getEditor().GetMeshDS();
     }
-    int nbEdges = aMeshDS->NbEdges();
-    int nbFaces = aMeshDS->NbFaces();
-    int nbVolum = aMeshDS->NbVolumes();
     myPreviewData = new SMESH::MeshPreviewStruct();
     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
 
@@ -555,23 +567,23 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
       if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
         previewType = aPreviewMesh->myPreviewType;
         switch ( previewType ) {
-        case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
-        case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
-        case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
+        case SMDSAbs_Edge  : break;
+        case SMDSAbs_Face  : break;
+        case SMDSAbs_Volume: break;
         default:;
+          if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
         }
       }
 
-    myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
+    myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
     int i = 0, j = 0;
     SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
 
     while ( itMeshElems->more() ) {
       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
-      SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
+      SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
       while ( itElemNodes->more() ) {
-        const SMDS_MeshNode* aMeshNode =
-          static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
+        const SMDS_MeshNode* aMeshNode = itElemNodes->next();
         int aNodeID = aMeshNode->GetID();
         TNodesMap::iterator anIter = nodesMap.find(aNodeID);
         if ( anIter == nodesMap.end() ) {
@@ -588,12 +600,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
       // filling the elements types
       SMDSAbs_ElementType aType = aMeshElem->GetType();
       bool               isPoly = aMeshElem->IsPoly();
-
       myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
-      myPreviewData->elementTypes[i].isPoly = isPoly;
+      myPreviewData->elementTypes[i].isPoly           = isPoly;
       myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
       i++;
-
     }
     myPreviewData->nodesXYZ.length( j );
 
@@ -603,8 +613,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
     for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
       myPreviewData->elementConnectivities[i] = *aConnIter;
   }
-
   return myPreviewData._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -615,13 +627,19 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
 //================================================================================
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
+
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
   myLastCreatedNodes->length( aSeq.Length() );
   for (int i = 1; i <= aSeq.Length(); i++)
     myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
+
   return myLastCreatedNodes._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -632,23 +650,44 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
 //================================================================================
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
+
   const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
   myLastCreatedElems->length( aSeq.Length() );
   for ( int i = 1; i <= aSeq.Length(); i++ )
     myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
+
   return myLastCreatedElems._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
+
+//=======================================================================
+//function : ClearLastCreated
+//purpose  : Clears sequences of last created elements and nodes 
+//=======================================================================
+
+void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  getEditor().CrearLastCreated();
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
 /*
  * Returns description of an error/warning occured during the last operation
+ * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
  */
 //=======================================================================
 
 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::ComputeError_var errOut = new SMESH::ComputeError;
   SMESH_ComputeErrorPtr&  errIn  = getEditor().GetError();
   if ( errIn && !errIn->IsOK() )
@@ -664,7 +703,10 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
     errOut->subShapeID = -1;
     errOut->hasBadMesh = false;
   }
+
   return errOut._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -709,6 +751,11 @@ SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_arr
   return anIDSourceVar._retn();
 }
 
+bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
+{
+  return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
+}
+
 void SMESH_MeshEditor_i::deleteAuxIDSources()
 {
   std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
@@ -725,7 +772,9 @@ void SMESH_MeshEditor_i::deleteAuxIDSources()
 
 CORBA::Boolean
 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   list< int > IdList;
@@ -738,10 +787,12 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 
   // Remove Elements
   bool ret = getEditor().Remove( IdList, false );
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfElements.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
+
+  declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -751,7 +802,9 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   list< int > IdList;
@@ -762,10 +815,12 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
 
   bool ret = getEditor().Remove( IdList, true );
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfNodes.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
+
+  declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -775,10 +830,11 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-
   // Update Python script
   TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
 
@@ -794,12 +850,13 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
 
   int nbNodesBefore = myMesh->NbNodes();
   getEditor().Remove( IdList, true );
-  myMesh->GetMeshDS()->Modified();
-  if ( IdList.size() )
-    myMesh->SetIsModified( true );
   int nbNodesAfter = myMesh->NbNodes();
 
+  declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
   return nbNodesBefore - nbNodesAfter;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -808,9 +865,10 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
  */
 //=============================================================================
 
-CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
-                                        CORBA::Double y, CORBA::Double z)
+CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
@@ -819,9 +877,11 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
   TPythonDump() << "nodeID = " << this << ".AddNode( "
                 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/false );
   return N->GetID();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -831,7 +891,9 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
@@ -840,12 +902,11 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
   // Update Python script
   TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/false );
 
-  if (elem)
-    return elem->GetID();
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -858,6 +919,7 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   if ( diameter < std::numeric_limits<double>::min() )
@@ -870,12 +932,10 @@ CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diam
   TPythonDump() << "ballElem = "
                 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
-
-  if (elem)
-    return elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -887,7 +947,9 @@ CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diam
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -915,10 +977,10 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
                   <<n1<<", "<<n2<<", "<<n12<<" ])";
   }
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -929,7 +991,9 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -943,35 +1007,29 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
     nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
 
   SMDS_MeshElement* elem = 0;
-  if (NbNodes == 3) {
-    elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
-  }
-  else if (NbNodes == 4) {
-    elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
-  }
-  else if (NbNodes == 6) {
-    elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                                nodes[4], nodes[5]);
-  }
-  else if (NbNodes == 8) {
-    elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                                nodes[4], nodes[5], nodes[6], nodes[7]);
-  }
-  else if (NbNodes == 9) {
-    elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                                nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
-  }
-  else if (NbNodes > 2) {
-    elem = getMeshDS()->AddPolygonalFace(nodes);
+  switch (NbNodes) {
+  case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
+  case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
+  case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                      nodes[4], nodes[5]); break;
+  case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                      nodes[4], nodes[5], nodes[6]); break;
+  case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                      nodes[4], nodes[5], nodes[6], nodes[7]); break;
+  case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                      nodes[4], nodes[5], nodes[6], nodes[7],
+                                      nodes[8] ); break;
+  default: elem = getMeshDS()->AddPolygonalFace(nodes);
   }
 
   // Update Python script
   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -981,7 +1039,9 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
  */
 //=============================================================================
 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -994,8 +1054,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   // Update Python script
   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
 
-  myMesh->GetMeshDS()->Modified();
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1006,7 +1069,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -1047,10 +1112,10 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if(elem)
-    return myMesh->SetIsModified( true ), elem->GetID();
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -1061,7 +1126,9 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
 //=============================================================================
 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
                                                      const SMESH::long_array & Quantities)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbNodes = IDsOfNodes.length();
@@ -1083,9 +1150,12 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
                 << IDsOfNodes << ", " << Quantities << " )";
-  myMesh->GetMeshDS()->Modified();
 
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1095,7 +1165,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
 //=============================================================================
 
 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   int NbFaces = IdsOfFaces.length();
@@ -1117,9 +1189,12 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
                 << IdsOfFaces << " )";
-  myMesh->GetMeshDS()->Modified();
 
-  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1139,12 +1214,14 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
                                                const char*               theGroupName)
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESH::SMESH_IDSource_var result;
   TPythonDump pyDump;
 
   TIDSortedElemSet elements, elems0D;
+  prepareIdSource( theObject );
   if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     getEditor().Create0DElementsOnAllNodes( elements, elems0D );
 
@@ -1191,6 +1268,9 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
          << theObject << ", '" << theGroupName << "' )";
 
   return result._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1205,7 +1285,7 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_TRY;
 
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
@@ -1222,6 +1302,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI
   mesh->SetNodeOnVertex( node, VertexID );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1238,7 +1320,7 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
                                        CORBA::Double paramOnEdge)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_TRY;
 
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
@@ -1260,6 +1342,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1277,8 +1361,7 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
                                        CORBA::Double u, CORBA::Double v)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
   if ( !node )
@@ -1310,6 +1393,8 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
 
   mesh->SetNodeOnFace( node, FaceID, u, v );
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1324,8 +1409,7 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
   if ( !node )
@@ -1341,7 +1425,7 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID
 
   mesh->SetNodeInVolume( node, SolidID );
 
-  // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1349,7 +1433,6 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID
  * \brief Bind an element to a shape
  * \param ElementID - element ID
  * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
- * \retval boolean - false if ElementID or ShapeID is invalid
  */
 //=============================================================================
 
@@ -1357,14 +1440,13 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
                                                CORBA::Long ShapeID)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   SMESHDS_Mesh * mesh = getMeshDS();
   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
   if ( !elem )
     THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
 
-  if ( mesh->MaxShapeIndex() < ShapeID )
+  if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
     THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
 
   TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
@@ -1377,6 +1459,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
   mesh->SetMeshElementOnShape( elem, ShapeID );
 
   myMesh->SetIsModified( true );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -1387,7 +1471,9 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
 
 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
                                                CORBA::Long NodeID2)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
@@ -1399,11 +1485,13 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".InverseDiag( "
                 << NodeID1 << ", " << NodeID2 << " )";
 
-
   int ret =  getEditor().InverseDiag ( n1, n2 );
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return ret;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1414,7 +1502,9 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
 
 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
                                               CORBA::Long NodeID2)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
@@ -1429,12 +1519,12 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 
   bool stat = getEditor().DeleteDiag ( n1, n2 );
 
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/!stat );
 
   return stat;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
@@ -1444,7 +1534,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   for (int i = 0; i < IDsOfElements.length(); i++)
@@ -1457,13 +1549,12 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
   // Update Python script
   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
 
-  myMesh->GetMeshDS()->Modified();
-  if ( IDsOfElements.length() )
-    myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
   return true;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -1472,18 +1563,26 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
 //=============================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump; // suppress dump in Reorient()
 
+  prepareIdSource( theObject );
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = Reorient(anElementsId);
 
   // Update Python script
   aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -1503,11 +1602,11 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
                                            const SMESH::PointStruct& thePoint)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   initData(/*deleteSearchers=*/false);
 
   TIDSortedElemSet elements;
+  prepareIdSource( the2Dgroup );
   if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
     THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
 
@@ -1532,14 +1631,14 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
         if ( myMesh->NbFaces() == 0 )
           THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
 
-        theElementSearcher = myEditor.GetElementSearcher();
+        theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
       }
       else
       {
         typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
         SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
 
-        theElementSearcher = myEditor.GetElementSearcher(elemsIt);
+        theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
       }
     }
     // find a face
@@ -1560,8 +1659,7 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
   int nbReori = getEditor().Reorient2D( elements, dirVec, face );
 
   if ( nbReori ) {
-    myMesh->SetIsModified( true );
-    myMesh->GetMeshDS()->Modified();
+    declareMeshModified( /*isReComputeSafe=*/false );
   }
   TPythonDump() << this << ".Reorient2D( "
                 << the2Dgroup << ", "
@@ -1570,17 +1668,23 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
                 << thePoint << " )";
 
   return nbReori;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=============================================================================
 /*!
- *
+ * \brief Fuse neighbour triangles into quadrangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfElements,
                                               SMESH::NumericalFunctor_ptr Criterion,
                                               CORBA::Double               MaxAngle)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1601,27 +1705,31 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
 
 
   bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
 
+  declareMeshModified( /*isReComputeSafe=*/!stat );
   return stat;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
- *
+ * \brief Fuse neighbour triangles into quadrangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr   theObject,
                                                     SMESH::NumericalFunctor_ptr Criterion,
                                                     CORBA::Double               MaxAngle)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in TriToQuad()
+
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
 
@@ -1633,17 +1741,22 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
                << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
 
   return isDone;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
- *
+ * \brief Split quadrangles into triangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
                                               SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1663,27 +1776,30 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
 
   CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
 
+  declareMeshModified( /*isReComputeSafe=*/false );
   return stat;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
- *
+ * \brief Split quadrangles into triangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
                                                     SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in QuadToTri()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
 
@@ -1693,18 +1809,49 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr
   // Update Python script
   aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/false );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
+//================================================================================
+/*!
+ * \brief Split each of quadrangles into 4 triangles.
+ *  \param [in] theObject - theQuads Container of quadrangles to split.
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  TIDSortedElemSet faces;
+  prepareIdSource( theObject );
+  if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
+       faces.empty() )
+    THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
+
+  getEditor().QuadTo4Tri( faces );
+  TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
 
 //=============================================================================
 /*!
- *
+ * \brief Split quadrangles into triangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
                                               CORBA::Boolean            Diag13)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1716,28 +1863,30 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
                 << IDsOfElements << ", " << Diag13 << " )";
 
   CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
-  myMesh->GetMeshDS()->Modified();
-  if ( stat )
-    myMesh->SetIsModified( true ); // issue 0020693
-
-
 
+  declareMeshModified( /*isReComputeSafe=*/ !stat );
   return stat;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
- *
+ * \brief Split quadrangles into triangles.
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
                                                     CORBA::Boolean            Diag13)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in SplitQuad()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
 
@@ -1745,18 +1894,29 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
   aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
                << theObject << ", " << Diag13 << " )";
 
+  declareMeshModified( /*isReComputeSafe=*/!isDone );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 
 //=============================================================================
 /*!
- *  BestSplit
+ * Find better splitting of the given quadrangle.
+ *  \param IDOfQuad  ID of the quadrangle to be splitted.
+ *  \param Criterion A criterion to choose a diagonal for splitting.
+ *  \return 1 if 1-3 diagonal is better, 2 if 2-4
+ *          diagonal is better, 0 if error occurs.
  */
 //=============================================================================
+
 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
                                            SMESH::NumericalFunctor_ptr Criterion)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
@@ -1770,9 +1930,12 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
     else
       aCrit.reset(new SMESH::Controls::AspectRatio());
 
-    return getEditor().BestSplit(quad, aCrit);
+    int id = getEditor().BestSplit(quad, aCrit);
+    declareMeshModified( /*isReComputeSafe=*/ id < 1 );
   }
-  return -1;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -1785,23 +1948,21 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
                                                 CORBA::Short              methodFlags)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   initData();
 
+  prepareIdSource( elems );
   SMESH::long_array_var anElementsId = elems->GetIDs();
   TIDSortedElemSet elemSet;
   arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
 
   getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
-  myMesh->GetMeshDS()->Modified();
-
-
-//   if ( myLastCreatedElems.length() ) - it does not influence Compute()
-//     myMesh->SetIsModified( true ); // issue 0020693
+  declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
 
   TPythonDump() << this << ".SplitVolumesIntoTetra( "
                 << elems << ", " << methodFlags << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -1815,6 +1976,7 @@ SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
                            CORBA::Long                            MaxNbOfIterations,
                            CORBA::Double                          MaxAspectRatio,
                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
                  MaxAspectRatio, Method, false );
@@ -1832,6 +1994,7 @@ SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsO
                                      CORBA::Long                            MaxNbOfIterations,
                                      CORBA::Double                          MaxAspectRatio,
                                      SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
                  MaxAspectRatio, Method, true );
@@ -1849,6 +2012,7 @@ SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                                  CORBA::Long                            MaxNbOfIterations,
                                  CORBA::Double                          MaxAspectRatio,
                                  SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, false);
@@ -1866,6 +2030,7 @@ SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr
                                            CORBA::Long                            MaxNbOfIterations,
                                            CORBA::Double                          MaxAspectRatio,
                                            SMESH::SMESH_MeshEditor::Smooth_Method Method)
+  throw (SALOME::SALOME_Exception)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, true);
@@ -1885,7 +2050,9 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
                            CORBA::Double                          MaxAspectRatio,
                            SMESH::SMESH_MeshEditor::Smooth_Method Method,
                            bool                                   IsParametric)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -1907,9 +2074,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
   getEditor().Smooth(elements, fixedNodes, method,
                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true ); // issue 0020693
-
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
 
   // Update Python script
   TPythonDump() << "isDone = " << this << "."
@@ -1921,8 +2086,10 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
 
   return true;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -1937,11 +2104,14 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                                  CORBA::Double                          MaxAspectRatio,
                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
                                  bool                                   IsParametric)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;  // suppress dump in smooth()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
                                   MaxAspectRatio, Method, IsParametric);
@@ -1956,8 +2126,10 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                     "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
 
   return isDone;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -1966,13 +2138,16 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
 //=============================================================================
 
 void SMESH_MeshEditor_i::RenumberNodes()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   // Update Python script
   TPythonDump() << this << ".RenumberNodes()";
 
   getMeshDS()->Renumber( true );
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
 
 //=============================================================================
 /*!
@@ -1981,11 +2156,15 @@ void SMESH_MeshEditor_i::RenumberNodes()
 //=============================================================================
 
 void SMESH_MeshEditor_i::RenumberElements()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   // Update Python script
   TPythonDump() << this << ".RenumberElements()";
 
   getMeshDS()->Renumber( false );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -1995,11 +2174,16 @@ void SMESH_MeshEditor_i::RenumberElements()
 //=======================================================================
 
 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   if ( !groupIDs )
     return 0;
   myMesh_i->CreateGroupServants();
   return myMesh_i->GetGroups( *groupIDs );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -2015,7 +2199,9 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
                                   CORBA::Double             theTolerance,
                                   const bool                theMakeGroups,
                                   const SMDSAbs_ElementType theElementType)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TIDSortedElemSet inElements, copyElements;
@@ -2037,11 +2223,13 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
   ::SMESH_MeshEditor::PGroupIDs groupIds =
       getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
                                  theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
-  myMesh->GetMeshDS()->Modified();
 
-  //  myMesh->SetIsModified( true ); -- it does not influence Compute()
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -2054,6 +2242,7 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement
                                        CORBA::Double             theAngleInRadians,
                                        CORBA::Long               theNbOfSteps,
                                        CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweep( "
@@ -2082,6 +2271,7 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
                                             CORBA::Double            theAngleInRadians,
                                             CORBA::Long              theNbOfSteps,
                                             CORBA::Double            theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -2092,7 +2282,7 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
                                                theTolerance,
                                                true);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepMakeGroups( "
                 << theIDsOfElements        << ", "
                 << theAxis                   << ", "
@@ -2113,6 +2303,7 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject
                                              CORBA::Double             theAngleInRadians,
                                              CORBA::Long               theNbOfSteps,
                                              CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject( "
@@ -2122,6 +2313,7 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject
                   << theNbOfSteps << ", "
                   << theTolerance << " )";
   }
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   rotationSweep(anElementsId,
                 theAxis,
@@ -2141,6 +2333,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje
                                                CORBA::Double             theAngleInRadians,
                                                CORBA::Long               theNbOfSteps,
                                                CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject1D( "
@@ -2150,6 +2343,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje
                   << TVar( theNbOfSteps      ) << ", "
                   << TVar( theTolerance      ) << " )";
   }
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   rotationSweep(anElementsId,
                 theAxis,
@@ -2170,6 +2364,7 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje
                                                CORBA::Double             theAngleInRadians,
                                                CORBA::Long               theNbOfSteps,
                                                CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject2D( "
@@ -2179,6 +2374,7 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje
                   << TVar( theNbOfSteps      ) << ", "
                   << TVar( theTolerance      ) << " )";
   }
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   rotationSweep(anElementsId,
                 theAxis,
@@ -2200,9 +2396,11 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                   CORBA::Double             theAngleInRadians,
                                                   CORBA::Long               theNbOfSteps,
                                                   CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -2211,7 +2409,7 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                theTolerance,
                                                true);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObjectMakeGroups( "
                 << theObject << ", "
                 << theAxis << ", "
@@ -2233,9 +2431,11 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                     CORBA::Double             theAngleInRadians,
                                                     CORBA::Long               theNbOfSteps,
                                                     CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -2245,7 +2445,7 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                true,
                                                SMDSAbs_Edge);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
                 << theObject                 << ", "
                 << theAxis                   << ", "
@@ -2267,9 +2467,11 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                     CORBA::Double             theAngleInRadians,
                                                     CORBA::Long               theNbOfSteps,
                                                     CORBA::Double             theTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -2279,7 +2481,7 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                true,
                                                SMDSAbs_Face);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
                 << theObject                 << ", "
                 << theAxis                   << ", "
@@ -2302,47 +2504,42 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
                                    CORBA::Long               theNbOfSteps,
                                    bool                      theMakeGroups,
                                    const SMDSAbs_ElementType theElementType)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-  try {
-#ifdef NO_CAS_CATCH
-    OCC_CATCH_SIGNALS;
-#endif
-    TIDSortedElemSet elements, copyElements;
-    arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
-
-    const SMESH::PointStruct * P = &theStepVector.PS;
-    gp_Vec stepVec( P->x, P->y, P->z );
-
-    TIDSortedElemSet* workElements = & elements;
-
-    SMDSAbs_ElementType aType = SMDSAbs_Face;
-    if (theElementType == SMDSAbs_Node)
-    {
-      aType = SMDSAbs_Edge;
-    }
-    if ( myIsPreviewMode ) {
-      SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
-      getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
-      workElements = & copyElements;
-      theMakeGroups = false;
-    }
-
-    TElemOfElemListMap aHystory;
-    ::SMESH_MeshEditor::PGroupIDs groupIds = 
-        getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+  TIDSortedElemSet elements, copyElements;
+  arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
 
-    myMesh->GetMeshDS()->Modified();
+  const SMESH::PointStruct * P = &theStepVector.PS;
+  gp_Vec stepVec( P->x, P->y, P->z );
 
-    return theMakeGroups ? getGroups(groupIds.get()) : 0;
+  TIDSortedElemSet* workElements = & elements;
 
-  } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
+  SMDSAbs_ElementType aType = SMDSAbs_Face;
+  if (theElementType == SMDSAbs_Node)
+  {
+    aType = SMDSAbs_Edge;
   }
-  return 0;
-}
+  if ( myIsPreviewMode ) {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
+    workElements = & copyElements;
+    theMakeGroups = false;
+  }
+
+  TElemOfElemListMap aHystory;
+  ::SMESH_MeshEditor::PGroupIDs groupIds = 
+      getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
+
+  return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=======================================================================
 //function : ExtrusionSweep
@@ -2352,6 +2549,7 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
                                         const SMESH::DirStruct &  theStepVector,
                                         CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
   if (!myIsPreviewMode) {
@@ -2368,6 +2566,7 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
                                           const SMESH::DirStruct &  theStepVector,
                                           CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
   if (!myIsPreviewMode) {
@@ -2384,7 +2583,9 @@ void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElem
 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
                                               const SMESH::DirStruct &  theStepVector,
                                               CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
   if (!myIsPreviewMode) {
@@ -2401,7 +2602,9 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObjec
 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
   if ( !myIsPreviewMode ) {
@@ -2418,7 +2621,9 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObj
 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
   if ( !myIsPreviewMode ) {
@@ -2435,7 +2640,9 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj
 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
   if ( !myIsPreviewMode ) {
@@ -2453,13 +2660,14 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
                                              const SMESH::DirStruct&  theStepVector,
                                              CORBA::Long              theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2475,13 +2683,14 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
                                                const SMESH::DirStruct&  theStepVector,
                                                CORBA::Long              theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
                 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2497,14 +2706,16 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                    const SMESH::DirStruct&   theStepVector,
                                                    CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << theNbOfSteps << " )";
   }
@@ -2520,14 +2731,16 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
                                                  theNbOfSteps, true, SMDSAbs_Node);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2543,14 +2756,16 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
                                                  theNbOfSteps, true, SMDSAbs_Edge);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2566,14 +2781,16 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
                                                  theNbOfSteps, true, SMDSAbs_Face);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
                 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
@@ -2593,7 +2810,9 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements
                                       CORBA::Long               theExtrFlags,
                                       CORBA::Double             theSewTolerance,
                                       const bool                theMakeGroups)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TIDSortedElemSet elements;
@@ -2607,7 +2826,12 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements
       getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
                                   theMakeGroups, theExtrFlags, theSewTolerance);
 
+  declareMeshModified( /*isReComputeSafe=*/true );
+
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -2620,6 +2844,7 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle
                                            CORBA::Long               theNbOfSteps,
                                            CORBA::Long               theExtrFlags,
                                            CORBA::Double             theSewTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << "stepVector = " << theStepVector;
@@ -2648,6 +2873,7 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO
                                                 CORBA::Long              theNbOfSteps,
                                                 CORBA::Long              theExtrFlags,
                                                 CORBA::Double            theSewTolerance)
+  throw (SALOME::SALOME_Exception)
 {
   if (!myIsPreviewMode) {
     TPythonDump() << "stepVector = " << theStepVector;
@@ -2662,7 +2888,7 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO
                                                      true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".AdvancedExtrusionMakeGroups("
                 << theIDsOfElements
                 << ", stepVector, "
@@ -2713,7 +2939,9 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
                                        const bool                  theMakeGroups,
                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
                                        const SMDSAbs_ElementType   theElementType)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   MESSAGE("extrusionAlongPath");
   initData();
 
@@ -2753,7 +2981,8 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
       getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
                                     theHasAngles, angles, false,
                                     theHasRefPoint, refPnt, theMakeGroups );
-  myMesh->GetMeshDS()->Modified();
+
+  declareMeshModified( /*isReComputeSafe=*/true );
   theError = convExtrError( error );
 
   if ( theMakeGroups ) {
@@ -2764,13 +2993,16 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
     return getGroups( & groupIDs );
   }
   return 0;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=======================================================================
 //function : extrusionAlongPathX
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
                                         SMESH::SMESH_IDSource_ptr  Path,
@@ -2783,7 +3015,9 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
                                         bool                       MakeGroups,
                                         const SMDSAbs_ElementType  ElementType,
                                         SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
 
   initData();
@@ -2827,7 +3061,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
     error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
                                              HasAngles, angles, LinearVariation,
                                              HasRefPoint, refPnt, MakeGroups );
-    myMesh->GetMeshDS()->Modified();
+    declareMeshModified( /*isReComputeSafe=*/true );
   }
   else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
   {
@@ -2845,7 +3079,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
     error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
                                              HasAngles, angles, LinearVariation,
                                              HasRefPoint, refPnt, MakeGroups );
-    myMesh->GetMeshDS()->Modified();
+    declareMeshModified( /*isReComputeSafe=*/true );
   }
   else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
   {
@@ -2869,13 +3103,16 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
     return getGroups( & groupIDs );
   }
   return EmptyGr;
-}
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
 
 //=======================================================================
 //function : ExtrusionAlongPath
 //purpose  :
 //=======================================================================
+
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -2885,6 +3122,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
                                        const SMESH::double_array & theAngles,
                                        CORBA::Boolean              theHasRefPoint,
                                        const SMESH::PointStruct &  theRefPoint)
+  throw (SALOME::SALOME_Exception)
 {
   MESSAGE("ExtrusionAlongPath");
   if ( !myIsPreviewMode ) {
@@ -2919,6 +3157,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
 //function : ExtrusionAlongPathObject
 //purpose  :
 //=======================================================================
+
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -2928,6 +3167,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
                                              const SMESH::double_array & theAngles,
                                              CORBA::Boolean              theHasRefPoint,
                                              const SMESH::PointStruct &  theRefPoint)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
@@ -2944,6 +3184,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
   }
   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionAlongPath( anElementsId,
                       thePathMesh,
@@ -2962,6 +3203,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
 //function : ExtrusionAlongPathObject1D
 //purpose  :
 //=======================================================================
+
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -2971,6 +3213,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theOb
                                                const SMESH::double_array & theAngles,
                                                CORBA::Boolean              theHasRefPoint,
                                                const SMESH::PointStruct &  theRefPoint)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
@@ -2987,6 +3230,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theOb
                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
   }
   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionAlongPath( anElementsId,
                       thePathMesh,
@@ -3006,6 +3250,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theOb
 //function : ExtrusionAlongPathObject2D
 //purpose  :
 //=======================================================================
+
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
                                                SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -3015,6 +3260,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theOb
                                                const SMESH::double_array & theAngles,
                                                CORBA::Boolean              theHasRefPoint,
                                                const SMESH::PointStruct &  theRefPoint)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
@@ -3031,6 +3277,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theOb
                   << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
   }
   SMESH::SMESH_MeshEditor::Extrusion_Error anError;
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionAlongPath( anElementsId,
                       thePathMesh,
@@ -3051,6 +3298,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theOb
 //function : ExtrusionAlongPathMakeGroups
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -3061,6 +3309,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theI
                                                  CORBA::Boolean             theHasRefPoint,
                                                  const SMESH::PointStruct&  theRefPoint,
                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -3101,6 +3350,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theI
 //function : ExtrusionAlongPathObjectMakeGroups
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -3111,9 +3361,11 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                    CORBA::Boolean             theHasRefPoint,
                                    const SMESH::PointStruct&  theRefPoint,
                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -3153,6 +3405,7 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
 //function : ExtrusionAlongPathObject1DMakeGroups
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -3163,9 +3416,11 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                      CORBA::Boolean             theHasRefPoint,
                                      const SMESH::PointStruct&  theRefPoint,
                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -3206,6 +3461,7 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
 //function : ExtrusionAlongPathObject2DMakeGroups
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                      SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -3216,9 +3472,11 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                      CORBA::Boolean             theHasRefPoint,
                                      const SMESH::PointStruct&  theRefPoint,
                                      SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( theObject );
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -3255,11 +3513,11 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
   return aGroups;
 }
 
-
 //=======================================================================
 //function : ExtrusionAlongPathObjX
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
                        SMESH::SMESH_IDSource_ptr  Path,
@@ -3272,9 +3530,11 @@ ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
                        CORBA::Boolean             MakeGroups,
                        SMESH::ElementType         ElemType,
                        SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
+  prepareIdSource( Object );
   SMESH::long_array_var anElementsId = Object->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
                                                       Path,
@@ -3313,11 +3573,11 @@ ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
   return aGroups;
 }
 
-
 //=======================================================================
 //function : ExtrusionAlongPathX
 //purpose  :
 //=======================================================================
+
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
                     SMESH::SMESH_IDSource_ptr  Path,
@@ -3330,6 +3590,7 @@ ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
                     CORBA::Boolean             MakeGroups,
                     SMESH::ElementType         ElemType,
                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -3370,7 +3631,6 @@ ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
   return aGroups;
 }
 
-
 //================================================================================
 /*!
  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
@@ -3442,7 +3702,6 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMes
   return aResult._retn();
 }
 
-
 //=======================================================================
 //function : mirror
 //purpose  :
@@ -3455,7 +3714,9 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
                            CORBA::Boolean                      theCopy,
                            bool                                theMakeGroups,
                            ::SMESH_Mesh*                       theTargetMesh)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
@@ -3504,11 +3765,13 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
     }
     else
     {
-      myMesh->GetMeshDS()->Modified();
-      myMesh->SetIsModified( true );
+      declareMeshModified( /*isReComputeSafe=*/false );
     }
   }
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -3520,6 +3783,7 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElem
                                 const SMESH::AxisStruct &           theAxis,
                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                 CORBA::Boolean                      theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".Mirror( "
@@ -3546,6 +3810,7 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObj
                                       const SMESH::AxisStruct &           theAxis,
                                       SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                       CORBA::Boolean                      theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".MirrorObject( "
@@ -3558,6 +3823,7 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObj
 
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
 
+  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     mirror(elements, theAxis, theMirrorType, theCopy, false);
 }
@@ -3571,6 +3837,7 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsOfElements,
                                      const SMESH::AxisStruct&            theMirror,
                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -3582,7 +3849,7 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsO
     aGroups = mirror(elements, theMirror, theMirrorType, true, true);
   }
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".MirrorMakeGroups( "
                 << theIDsOfElements              << ", "
                 << theMirror                     << ", "
@@ -3600,17 +3867,19 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           theObject,
                                            const SMESH::AxisStruct&            theMirror,
                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
+  prepareIdSource( theObject );
   if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = mirror(elements, theMirror, theMirrorType, true, true);
 
   if (!myIsPreviewMode)
   {
-    DumpGroupsList(aPythonDump,aGroups);
+    dumpGroupsList(aPythonDump,aGroups);
     aPythonDump << this << ".MirrorObjectMakeGroups( "
                 << theObject                     << ", "
                 << theMirror                     << ", "
@@ -3630,6 +3899,7 @@ SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfE
                                    SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                    CORBA::Boolean                      theCopyGroups,
                                    const char*                         theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
@@ -3677,6 +3947,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           the
                                          SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                          CORBA::Boolean                      theCopyGroups,
                                          const char*                         theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
@@ -3688,6 +3959,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           the
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
     TIDSortedElemSet elements;
+    prepareIdSource( theObject );
     if ( mesh_i &&
          idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
@@ -3723,7 +3995,9 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
                               CORBA::Boolean            theCopy,
                               bool                      theMakeGroups,
                               ::SMESH_Mesh*             theTargetMesh)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   if ( theTargetMesh )
@@ -3761,12 +4035,14 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
     }
     else
     {
-      myMesh->GetMeshDS()->Modified();
-      myMesh->SetIsModified( true );
+      declareMeshModified( /*isReComputeSafe=*/false );
     }
   }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -3777,6 +4053,7 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
                                    const SMESH::DirStruct &  theVector,
                                    CORBA::Boolean            theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if (!myIsPreviewMode) {
     TPythonDump() << this << ".Translate( "
@@ -3799,6 +4076,7 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
                                          const SMESH::DirStruct &  theVector,
                                          CORBA::Boolean            theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if (!myIsPreviewMode) {
     TPythonDump() << this << ".TranslateObject( "
@@ -3810,6 +4088,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
 
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
   
+  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     translate(elements, theVector, theCopy, false);
 }
@@ -3822,6 +4101,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
                                         const SMESH::DirStruct&  theVector)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -3832,7 +4112,7 @@ SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElement
     aGroups = translate(elements,theVector,true,true);
   }
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".TranslateMakeGroups( "
                 << theIDsOfElements << ", "
                 << theVector        << " )";
@@ -3848,16 +4128,18 @@ SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElement
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                               const SMESH::DirStruct&   theVector)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
+  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = translate(elements, theVector, true, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".TranslateObjectMakeGroups( "
                 << theObject << ", "
                 << theVector << " )";
@@ -3875,6 +4157,7 @@ SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
                                       const SMESH::DirStruct&  theVector,
                                       CORBA::Boolean           theCopyGroups,
                                       const char*              theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
@@ -3921,7 +4204,9 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
                                             const SMESH::DirStruct&   theVector,
                                             CORBA::Boolean            theCopyGroups,
                                             const char*               theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
   { // open new scope to dump "MakeMesh" command
@@ -3932,6 +4217,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
 
     TIDSortedElemSet elements;
+    prepareIdSource( theObject );
     if ( mesh_i &&
       idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
@@ -3952,6 +4238,9 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i->GetGroups();
 
   return mesh._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -3966,7 +4255,9 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
                            CORBA::Boolean            theCopy,
                            bool                      theMakeGroups,
                            ::SMESH_Mesh*             theTargetMesh)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   if ( theTargetMesh )
@@ -3998,18 +4289,14 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
 
   if ( theCopy && !myIsPreviewMode)
   {
-    if ( theTargetMesh )
-    {
-      theTargetMesh->GetMeshDS()->Modified();
-    }
-    else
-    {
-      myMesh->GetMeshDS()->Modified();
-      myMesh->SetIsModified( true );
-    }
+    if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
+    else                 declareMeshModified( /*isReComputeSafe=*/false );
   }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4021,6 +4308,7 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
                                 const SMESH::AxisStruct & theAxis,
                                 CORBA::Double             theAngle,
                                 CORBA::Boolean            theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if (!myIsPreviewMode) {
     TPythonDump() << this << ".Rotate( "
@@ -4046,6 +4334,7 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
                                       const SMESH::AxisStruct & theAxis,
                                       CORBA::Double             theAngle,
                                       CORBA::Boolean            theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".RotateObject( "
@@ -4056,6 +4345,7 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
   }
   TIDSortedElemSet elements;
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
+  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     rotate(elements,theAxis,theAngle,theCopy,false);
 }
@@ -4069,6 +4359,7 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
                                      const SMESH::AxisStruct& theAxis,
                                      CORBA::Double            theAngle)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
@@ -4080,7 +4371,7 @@ SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
     aGroups = rotate(elements,theAxis,theAngle,true,true);
   }
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotateMakeGroups( "
                 << theIDsOfElements << ", "
                 << theAxis          << ", "
@@ -4098,16 +4389,18 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                            const SMESH::AxisStruct&  theAxis,
                                            CORBA::Double             theAngle)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
+  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = rotate(elements, theAxis, theAngle, true, true);
 
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotateObjectMakeGroups( "
                 << theObject        << ", "
                 << theAxis          << ", "
@@ -4127,7 +4420,9 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
                                    CORBA::Double            theAngleInRadians,
                                    CORBA::Boolean           theCopyGroups,
                                    const char*              theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::SMESH_Mesh_var mesh;
   SMESH_Mesh_i* mesh_i;
 
@@ -4162,6 +4457,9 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
     mesh_i->GetGroups();
 
   return mesh._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4175,7 +4473,9 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
                                          CORBA::Double             theAngleInRadians,
                                          CORBA::Boolean            theCopyGroups,
                                          const char*               theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::SMESH_Mesh_var mesh;
   SMESH_Mesh_i* mesh_i;
 
@@ -4187,6 +4487,7 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
 
     TIDSortedElemSet elements;
+    prepareIdSource( theObject );
     if (mesh_i &&
         idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
@@ -4209,6 +4510,9 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i->GetGroups();
 
   return mesh._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4223,7 +4527,9 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
                           CORBA::Boolean             theCopy,
                           bool                       theMakeGroups,
                           ::SMESH_Mesh*              theTargetMesh)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
   if ( theScaleFact.length() < 1 )
     THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
@@ -4234,6 +4540,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
     theCopy = false;
 
   TIDSortedElemSet elements;
+  prepareIdSource( theObject );
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
   if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     return 0;
@@ -4270,18 +4577,13 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
 
   if ( theCopy && !myIsPreviewMode )
   {
-    if ( theTargetMesh )
-    {
-      theTargetMesh->GetMeshDS()->Modified();
-    }
-    else
-    {
-      myMesh->GetMeshDS()->Modified();
-      myMesh->SetIsModified( true );
-    }
+    if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
+    else                 declareMeshModified( /*isReComputeSafe=*/false );
   }
-
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4293,6 +4595,7 @@ void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr  theObject,
                                const SMESH::PointStruct&  thePoint,
                                const SMESH::double_array& theScaleFact,
                                CORBA::Boolean             theCopy)
+  throw (SALOME::SALOME_Exception)
 {
   if ( !myIsPreviewMode ) {
     TPythonDump() << this << ".Scale( "
@@ -4314,12 +4617,13 @@ SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                     const SMESH::PointStruct&  thePoint,
                                     const SMESH::double_array& theScaleFact)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
   SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
   if (!myIsPreviewMode) {
-    DumpGroupsList(aPythonDump, aGroups);
+    dumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".Scale("
                 << theObject            << ","
                 << thePoint             << ","
@@ -4340,6 +4644,7 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
                                   const SMESH::double_array& theScaleFact,
                                   CORBA::Boolean             theCopyGroups,
                                   const char*                theMeshName)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
@@ -4379,7 +4684,9 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
 
 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
                                               SMESH::array_of_long_array_out GroupsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
@@ -4399,19 +4706,25 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tol
   }
   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
                 << Tolerance << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
 //function : FindCoincidentNodesOnPart
 //purpose  :
 //=======================================================================
+
 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
                                                    CORBA::Double                  Tolerance,
                                                    SMESH::array_of_long_array_out GroupsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TIDSortedNodeSet nodes;
+  prepareIdSource( theObject );
   idSourceToNodeSet( theObject, getMeshDS(), nodes );
 
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
@@ -4433,6 +4746,8 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr
   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
                 <<theObject<<", "
                 << Tolerance << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //================================================================================
@@ -4447,10 +4762,13 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
                              CORBA::Double                  theTolerance,
                              SMESH::array_of_long_array_out theGroupsOfNodes,
                              const SMESH::ListOfIDSources&  theExceptSubMeshOrGroups)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TIDSortedNodeSet nodes;
+  prepareIdSource( theObject );
   idSourceToNodeSet( theObject, getMeshDS(), nodes );
 
   for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
@@ -4481,6 +4799,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
                 << theObject<<", "
                 << theTolerance << ", "
                 << theExceptSubMeshOrGroups << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -4489,7 +4809,9 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
 //=======================================================================
 
 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -4518,23 +4840,29 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
   getEditor().MergeNodes( aListOfListOfNodes );
 
   aTPythonDump <<  "])";
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+
+  declareMeshModified( /*isReComputeSafe=*/false );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
 //function : FindEqualElements
 //purpose  :
 //=======================================================================
+
 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
                                            SMESH::array_of_long_array_out GroupsOfElementsID)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
   if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
   {
     TIDSortedElemSet elems;
+    prepareIdSource( theObject );
     idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
 
     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
@@ -4558,6 +4886,8 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObj
     TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
                   <<theObject<<" )";
   }
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -4566,7 +4896,9 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObj
 //=======================================================================
 
 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   TPythonDump aTPythonDump;
@@ -4589,10 +4921,12 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO
   }
 
   getEditor().MergeElements(aListOfListOfElementsID);
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+
+  declareMeshModified( /*isReComputeSafe=*/true );
 
   aTPythonDump << "] )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -4601,14 +4935,18 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO
 //=======================================================================
 
 void SMESH_MeshEditor_i::MergeEqualElements()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   getEditor().MergeEqualElements();
 
-  myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/true );
 
   TPythonDump() << this << ".MergeEqualElements()";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -4621,7 +4959,9 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
                                             CORBA::Double x,
                                             CORBA::Double y,
                                             CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData(/*deleteSearchers=*/false);
 
   const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
@@ -4659,10 +4999,11 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
     // Update Python script
     TPythonDump() << "isDone = " << this << ".MoveNode( "
                   << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
-    myMesh->GetMeshDS()->Modified();
-    myMesh->SetIsModified( true );
+    declareMeshModified( /*isReComputeSafe=*/false );
   }
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return true;
 }
 
@@ -4675,16 +5016,19 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
                                                   CORBA::Double y,
                                                   CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
 
   if ( !theNodeSearcher ) {
-    theNodeSearcher = myEditor.GetNodeSearcher();
+    theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
   }
   gp_Pnt p( x,y,z );
   if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
     return node->GetID();
 
+  SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
@@ -4699,7 +5043,9 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
                                                        CORBA::Double y,
                                                        CORBA::Double z,
                                                        CORBA::Long   theNodeID)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   // We keep theNodeSearcher until any mesh modification:
   // 1) initData() deletes theNodeSearcher at any edition,
   // 2) TSearchersDeleter - at any mesh compute event and mesh change
@@ -4713,7 +5059,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
   if ( !node ) // preview moving node
   {
     if ( !theNodeSearcher ) {
-      theNodeSearcher = myEditor.GetNodeSearcher();
+      theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
     }
     gp_Pnt p( x,y,z );
     node = theNodeSearcher->FindClosestTo( p );
@@ -4754,11 +5100,13 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
                   << ", " << nodeID << " )";
 
-    myMesh->GetMeshDS()->Modified();
-    myMesh->SetIsModified( true );
+    declareMeshModified( /*isReComputeSafe=*/false );
   }
 
   return nodeID;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4773,13 +5121,15 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double      x,
                                                            CORBA::Double      y,
                                                            CORBA::Double      z,
                                                            SMESH::ElementType type)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var res = new SMESH::long_array;
   vector< const SMDS_MeshElement* > foundElems;
 
   theSearchersDeleter.Set( myMesh );
   if ( !theElementSearcher ) {
-    theElementSearcher = myEditor.GetElementSearcher();
+    theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
   }
   theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
                                            SMDSAbs_ElementType( type ),
@@ -4796,6 +5146,9 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double      x,
                   << type << " )";
 
   return res._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4811,7 +5164,9 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID
                                              CORBA::Double             y,
                                              CORBA::Double             z,
                                              SMESH::ElementType        type)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var res = new SMESH::long_array;
   
   SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
@@ -4839,7 +5194,7 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID
     typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
     SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
 
-    theElementSearcher = myEditor.GetElementSearcher(elemsIt);
+    theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
   }
 
   vector< const SMDS_MeshElement* > foundElems;
@@ -4860,8 +5215,11 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID
                   << type << " )";
 
   return res._retn();
-  
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
+
 //=======================================================================
 //function : GetPointState
 //purpose  : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
@@ -4871,12 +5229,17 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID
 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
                                                CORBA::Double y,
                                                CORBA::Double z)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   theSearchersDeleter.Set( myMesh );
   if ( !theElementSearcher ) {
-    theElementSearcher = myEditor.GetElementSearcher();
+    theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
   }
   return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
@@ -4917,7 +5280,9 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
                                    CORBA::Long LastNodeID2,
                                    CORBA::Boolean CreatePolygons,
                                    CORBA::Boolean CreatePolyedrs)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -4960,10 +5325,11 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
                                        CreatePolyedrs) );
 
 
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
-
+  declareMeshModified( /*isReComputeSafe=*/false );
   return error;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_MeshEditor::Sew_Error(0);
 }
 
 
@@ -4978,7 +5344,9 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                                           CORBA::Long LastNodeID1,
                                           CORBA::Long FirstNodeID2,
                                           CORBA::Long SecondNodeID2)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -5015,11 +5383,11 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                                        true,
                                        false, false) );
 
-
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
-
+  declareMeshModified( /*isReComputeSafe=*/false );
   return error;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_MeshEditor::Sew_Error(0);
 }
 
 
@@ -5036,7 +5404,9 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                                     CORBA::Long LastNodeIDOnSide,
                                     CORBA::Boolean CreatePolygons,
                                     CORBA::Boolean CreatePolyedrs)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -5076,11 +5446,11 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                                        CreatePolygons,
                                        CreatePolyedrs) );
 
-
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
-
+  declareMeshModified( /*isReComputeSafe=*/false );
   return error;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_MeshEditor::Sew_Error(0);
 }
 
 
@@ -5096,7 +5466,9 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                                     CORBA::Long NodeID1OfSide2ToMerge,
                                     CORBA::Long NodeID2OfSide1ToMerge,
                                     CORBA::Long NodeID2OfSide2ToMerge)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   SMESHDS_Mesh* aMesh = getMeshDS();
@@ -5132,11 +5504,11 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                                          aSecondNode1ToMerge,
                                          aSecondNode2ToMerge));
 
-
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
-
+  declareMeshModified( /*isReComputeSafe=*/false );
   return error;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_MeshEditor::Sew_Error(0);
 }
 
 //================================================================================
@@ -5150,7 +5522,9 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
 
 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
                                                    const SMESH::long_array& newIDs)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
@@ -5173,24 +5547,46 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
   MESSAGE("ChangeElementNodes");
   bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
 
-  myMesh->GetMeshDS()->Modified();
-  if ( res )
-    myMesh->SetIsModified( true );
+  declareMeshModified( /*isReComputeSafe=*/ !res );
 
   return res;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
-//function : ConvertToQuadratic
-//purpose  :
+/*!
+ * \brief Makes a part of the mesh quadratic or bi-quadratic
+ */
 //=======================================================================
 
-void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
+void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean            theForce3d,
+                                            CORBA::Boolean            theToBiQuad,
+                                            SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
 {
-  getEditor().ConvertToQuadratic(theForce3d);
-  TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+  SMESH_TRY;
+  TIDSortedElemSet elems;
+  bool elemsOK;
+  if ( !( elemsOK = CORBA::is_nil( theObject )))
+  {
+    prepareIdSource( theObject );
+    elemsOK =  idSourceToSet( theObject, getMeshDS(), elems,
+                              SMDSAbs_All, /*emptyIfIsMesh=*/true );
+  }
+  if ( elemsOK )
+  {
+    if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
+      THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
+
+    if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
+    else                 getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
+
+    declareMeshModified( /*isReComputeSafe=*/false );
+  }
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -5199,14 +5595,26 @@ void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
 //=======================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
+  throw (SALOME::SALOME_Exception)
 {
   CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
   TPythonDump() << this << ".ConvertFromQuadratic()";
-  myMesh->GetMeshDS()->Modified();
-  if ( isDone )
-    myMesh->SetIsModified( true );
+  declareMeshModified( /*isReComputeSafe=*/!isDone );
   return isDone;
 }
+
+//=======================================================================
+//function : ConvertToQuadratic
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
+  throw (SALOME::SALOME_Exception)
+{
+  convertToQuadratic( theForce3d, false );
+  TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
+}
+
 //================================================================================
 /*!
  * \brief Makes a part of the mesh quadratic
@@ -5217,28 +5625,22 @@ void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean            theF
                                                   SMESH::SMESH_IDSource_ptr theObject)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-  TPythonDump pyDump;
-  TIDSortedElemSet elems;
-  if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
-  {
-    if ( elems.empty() )
-    {
-      ConvertToQuadratic( theForce3d );
-    }
-    else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
-    {
-      THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
-    }
-    else
-    {
-      getEditor().ConvertToQuadratic(theForce3d, elems);
-    }
-  }
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+  convertToQuadratic( theForce3d, false, theObject );
+  TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
+}
 
-  pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
+//================================================================================
+/*!
+ * \brief Makes a part of the mesh bi-quadratic
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean            theForce3d,
+                                              SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
+{
+  convertToQuadratic( theForce3d, true, theObject );
+  TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
 }
 
 //================================================================================
@@ -5250,9 +5652,12 @@ void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean            theF
 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_TRY;
+
   TPythonDump pyDump;
+
   TIDSortedElemSet elems;
+  prepareIdSource( theObject );
   if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
   {
     if ( elems.empty() )
@@ -5268,10 +5673,11 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th
       getEditor().ConvertFromQuadratic(elems);
     }
   }
-  myMesh->GetMeshDS()->Modified();
-  myMesh->SetIsModified( true );
+  declareMeshModified( /*isReComputeSafe=*/false );
 
   pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=======================================================================
@@ -5281,10 +5687,10 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th
 
 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
 {
-  SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
-  SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
-  SALOMEDS::Study_var study = gen->GetCurrentStudy();
-  SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
+  SMESH_Gen_i*              gen = SMESH_Gen_i::GetSMESHGen();
+  SMESH::SMESH_Mesh_var    mesh = gen->CreateEmptyMesh();
+  SALOMEDS::Study_var     study = gen->GetCurrentStudy();
+  SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
   gen->SetName( meshSO, theMeshName, "Mesh" );
   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
 
@@ -5292,16 +5698,16 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
 }
 
 //=======================================================================
-//function : DumpGroupsList
+//function : dumpGroupsList
 //purpose  :
 //=======================================================================
-void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython,
+
+void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump &               theDumpPython,
                                         const SMESH::ListOfGroups * theGroupList)
 {
-  bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
-  if(isDumpGroupList) {
+  bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
+  if ( isDumpGroupList )
     theDumpPython << theGroupList << " = ";
-  }
 }
 
 //================================================================================
@@ -5311,6 +5717,7 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPytho
   \return unique name
 */
 //================================================================================
+
 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
 {
   SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
@@ -5331,11 +5738,99 @@ string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
   int index = 0;
 
   while (!groupNames.insert(name).second)
-    name = SMESH_Comment( thePrefix ) << "_" << index;
+    name = SMESH_Comment( thePrefix ) << "_" << index++;
 
   return name;
 }
 
+//================================================================================
+/*!
+ * \brief Prepare SMESH_IDSource for work
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
+{
+  if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
+  {
+    SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
+    filter->SetMesh( mesh );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Duplicates given elements, i.e. creates new elements based on the 
+ *        same nodes as the given ones.
+ * \param theElements - container of elements to duplicate.
+ * \param theGroupName - a name of group to contain the generated elements.
+ *                    If a group with such a name already exists, the new elements
+ *                    are added to the existng group, else a new group is created.
+ *                    If \a theGroupName is empty, new elements are not added 
+ *                    in any group.
+ * \return a group where the new elements are added. NULL if theGroupName == "".
+ * \sa DoubleNode()
+ */
+//================================================================================
+
+SMESH::SMESH_Group_ptr
+SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
+                                   const char*               theGroupName)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH::SMESH_Group_var newGroup;
+
+  SMESH_TRY;
+  initData();
+
+  TPythonDump pyDump;
+
+  TIDSortedElemSet elems;
+  prepareIdSource( theElements );
+  if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
+  {
+    getEditor().DoubleElements( elems );
+
+    if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
+    {
+      // group type
+      SMESH::ElementType type =
+        SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
+      // find existing group
+      SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
+      for ( size_t i = 0; i < groups->length(); ++i )
+        if ( groups[i]->GetType() == type )
+        {
+          CORBA::String_var name = groups[i]->GetName();
+          if ( strcmp( name, theGroupName ) == 0 ) {
+            newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
+            break;
+          }
+        }
+      // create a new group
+      if ( newGroup->_is_nil() )
+        newGroup = myMesh_i->CreateGroup( type, theGroupName );
+      // fill newGroup
+      if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
+      {
+        SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
+        const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
+        for ( int i = 1; i <= aSeq.Length(); i++ )
+          groupDS->SMDSGroup().Add( aSeq(i) );
+      }
+    }
+  }
+  // python dump
+  if ( !newGroup->_is_nil() )
+    pyDump << newGroup << " = ";
+  pyDump << this << ".DoubleElements( "
+         << theElements << ", " << "'" << theGroupName <<"')";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return newGroup._retn();
+}
+
 //================================================================================
 /*!
   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -5350,7 +5845,9 @@ string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
 
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
                                                 const SMESH::long_array& theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   list< int > aListOfNodes;
@@ -5364,14 +5861,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode
 
   bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
 
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   // Update Python script
   TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
 
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5387,7 +5885,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode
 
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeId,
                                                const SMESH::long_array& theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::long_array_var aNodes = new SMESH::long_array;
   aNodes->length( 1 );
   aNodes[ 0 ] = theNodeId;
@@ -5399,6 +5899,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeI
   pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
 
   return done;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5414,7 +5917,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeI
 
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
                                                    SMESH::SMESH_GroupBase_ptr theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
     return false;
 
@@ -5435,8 +5940,12 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr th
   pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
 
   return done;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
+//================================================================================
 /*!
  * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
  * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
@@ -5445,10 +5954,14 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr th
  * \return a new group with newly created nodes
  * \sa DoubleNodeGroup()
  */
+//================================================================================
+
 SMESH::SMESH_Group_ptr
 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
                                         SMESH::SMESH_GroupBase_ptr theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::SMESH_Group_var aNewGroup;
 
   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
@@ -5484,6 +5997,9 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
          << theModifiedElems << " )";
 
   return aNewGroup._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5499,10 +6015,11 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
 
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
                                                     const SMESH::ListOfGroups& theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-
   std::list< int > aNodes;
   int i, n, j, m;
   for ( i = 0, n = theNodes.length(); i < n; i++ )
@@ -5530,15 +6047,14 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t
 
   bool aResult = getEditor().DoubleNodes( aNodes, anElems );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
+  declareMeshModified( /*isReComputeSafe=*/false );
 
   TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
 
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5555,6 +6071,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t
 SMESH::SMESH_Group_ptr
 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
                                          const SMESH::ListOfGroups& theModifiedElems )
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::SMESH_Group_var aNewGroup;
 
@@ -5598,11 +6115,11 @@ SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
                                                    const SMESH::long_array& theNodesNot,
                                                    const SMESH::long_array& theAffectedElems )
-
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-
   SMESHDS_Mesh* aMeshDS = getMeshDS();
   TIDSortedElemSet anElems, aNodes, anAffected;
   arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
@@ -5611,15 +6128,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE
 
   bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
   // Update Python script
   TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
                 << theNodesNot << ", " << theAffectedElems << " )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5639,8 +6156,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE
 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
                                                             const SMESH::long_array& theNodesNot,
                                                             GEOM::GEOM_Object_ptr    theShape )
-
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
 
@@ -5652,15 +6170,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_ar
   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
   bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
                 << theNodesNot << ", " << theShape << " )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5675,10 +6193,13 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_ar
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
-                                                       SMESH::SMESH_GroupBase_ptr theNodesNot,
-                                                       SMESH::SMESH_GroupBase_ptr theAffectedElems)
+CORBA::Boolean
+SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
+                                        SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                        SMESH::SMESH_GroupBase_ptr theAffectedElems)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
     return false;
 
@@ -5693,17 +6214,18 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt
 
   bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
                 << theNodesNot << ", " << theAffectedElems << " )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
+//================================================================================
 /*!
  * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
  * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
@@ -5714,10 +6236,13 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt
  * \return a new group with newly created elements
  * \sa DoubleNodeElemGroup()
  */
+//================================================================================
+
 SMESH::SMESH_Group_ptr
 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
                                            SMESH::SMESH_GroupBase_ptr theNodesNot,
                                            SMESH::SMESH_GroupBase_ptr theAffectedElems)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump pyDump;
   SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
@@ -5735,13 +6260,28 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
   return elemGroup._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
+ * \param theElems - group of of elements (edges or faces) to be replicated
+ * \param theNodesNot - group of nodes not to replicated
+ * \param theAffectedElems - group of elements to which the replicated nodes
+ *        should be associated to.
+ * \return a new group with newly created elements
+ * \sa DoubleNodeElemGroup()
+ */
+//================================================================================
+
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
                                             SMESH::SMESH_GroupBase_ptr theNodesNot,
                                             SMESH::SMESH_GroupBase_ptr theAffectedElems,
                                             CORBA::Boolean             theElemGroupNeeded,
                                             CORBA::Boolean             theNodeGroupNeeded)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
   SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
   aTwoGroups->length( 2 );
@@ -5761,14 +6301,12 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
 
   bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
 
-  myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   TPythonDump pyDump;
 
   if ( aResult )
   {
-    myMesh->SetIsModified( true );
-
     // Create group with newly created elements
     CORBA::String_var elemGroupName = theElems->GetName();
     string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
@@ -5804,6 +6342,9 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
   aTwoGroups[0] = aNewElemGroup._retn();
   aTwoGroups[1] = aNewNodeGroup._retn();
   return aTwoGroups._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5819,11 +6360,13 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
-                                                               SMESH::SMESH_GroupBase_ptr theNodesNot,
-                                                               GEOM::GEOM_Object_ptr      theShape )
-
+CORBA::Boolean
+SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
+                                                SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                                GEOM::GEOM_Object_ptr      theShape )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
     return false;
 
@@ -5839,27 +6382,25 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_Grou
   bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
 
 
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
                 << theNodesNot << ", " << theShape << " )";
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
 /*!
-  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
-  This method provided for convenience works as DoubleNodes() described above.
-  \param theElems - list of groups of elements (edges or faces) to be replicated
-  \param theNodesNot - list of groups of nodes not to replicated
-  \param theAffectedElems - group of elements to which the replicated nodes
-  should be associated to.
-  \return TRUE if operation has been completed successfully, FALSE otherwise
-  \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
-*/
+ * \brief Re-load elements from a list of groups into a TIDSortedElemSet
+ *  \param [in] theGrpList - groups
+ *  \param [in] theMeshDS -  mesh
+ *  \param [out] theElemSet - set of elements
+ *  \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
+ */
 //================================================================================
 
 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
@@ -5879,10 +6420,26 @@ static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
   }
 }
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
-                                                        const SMESH::ListOfGroups& theNodesNot,
-                                                        const SMESH::ListOfGroups& theAffectedElems)
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+  This method provided for convenience works as DoubleNodes() described above.
+  \param theElems - list of groups of elements (edges or faces) to be replicated
+  \param theNodesNot - list of groups of nodes not to replicated
+  \param theAffectedElems - group of elements to which the replicated nodes
+  should be associated to.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
+*/
+//================================================================================
+
+CORBA::Boolean
+SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
+                                         const SMESH::ListOfGroups& theNodesNot,
+                                         const SMESH::ListOfGroups& theAffectedElems)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
 
@@ -5894,15 +6451,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroup
 
   bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
                 << &theNodesNot << ", " << &theAffectedElems << " )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -5922,6 +6479,7 @@ SMESH::SMESH_Group_ptr
 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
                                             const SMESH::ListOfGroups& theNodesNot,
                                             const SMESH::ListOfGroups& theAffectedElems)
+  throw (SALOME::SALOME_Exception)
 {
   TPythonDump pyDump;
   SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
@@ -5939,13 +6497,28 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
   return elemGroup._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
+  \param theElems - list of groups of elements (edges or faces) to be replicated
+  \param theNodesNot - list of groups of nodes not to replicated
+  \param theAffectedElems - group of elements to which the replicated nodes
+  should be associated to.
+ * \return a new group with newly created elements
+ * \sa DoubleNodeElemGroups()
+ */
+//================================================================================
+
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
                                              const SMESH::ListOfGroups& theNodesNot,
                                              const SMESH::ListOfGroups& theAffectedElems,
                                              CORBA::Boolean             theElemGroupNeeded,
                                              CORBA::Boolean             theNodeGroupNeeded)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
   SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
   aTwoGroups->length( 2 );
@@ -5961,13 +6534,11 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems
 
   bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
 
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
-  myMesh->GetMeshDS()->Modified();
   TPythonDump pyDump;
   if ( aResult )
   {
-    myMesh->SetIsModified( true );
-
     // Create group with newly created elements
     CORBA::String_var elemGroupName = theElems[0]->GetName();
     string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
@@ -6003,6 +6574,9 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems
   aTwoGroups[0] = aNewElemGroup._retn();
   aTwoGroups[1] = aNewNodeGroup._retn();
   return aTwoGroups._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -6023,7 +6597,9 @@ CORBA::Boolean
 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
                                                  const SMESH::ListOfGroups& theNodesNot,
                                                  GEOM::GEOM_Object_ptr      theShape )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
 
@@ -6035,20 +6611,21 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE
   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
   bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
 
-
-  myMesh->GetMeshDS()->Modified();
-  if ( aResult )
-    myMesh->SetIsModified( true );
-
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
                 << &theNodesNot << ", " << theShape << " )";
+
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
 /*!
-  \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
+  \brief Identify the elements that will be affected by node duplication (actual
+         duplication is not performed.
   This method is the first step of DoubleNodeElemGroupsInRegion.
   \param theElems - list of groups of elements (edges or faces) to be replicated
   \param theNodesNot - list of groups of nodes not to replicated
@@ -6057,13 +6634,15 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE
          The replicated nodes should be associated to affected elements.
   \return groups of affected elements
   \sa DoubleNodeElemGroupsInRegion()
- */
+*/
 //================================================================================
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
                                                 const SMESH::ListOfGroups& theNodesNot,
                                                 GEOM::GEOM_Object_ptr      theShape )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   MESSAGE("AffectedElemGroupsInRegion");
   SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
   bool isEdgeGroup = false;
@@ -6087,80 +6666,74 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
   bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
 
 
-  myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
+
   TPythonDump pyDump;
   if (aResult)
+  {
+    int lg = anAffected.size();
+    MESSAGE("lg="<< lg);
+    SMESH::long_array_var volumeIds = new SMESH::long_array;
+    volumeIds->length(lg);
+    SMESH::long_array_var faceIds = new SMESH::long_array;
+    faceIds->length(lg);
+    SMESH::long_array_var edgeIds = new SMESH::long_array;
+    edgeIds->length(lg);
+    int ivol = 0;
+    int iface = 0;
+    int iedge = 0;
+
+    TIDSortedElemSet::const_iterator eIt = anAffected.begin();
+    for (; eIt != anAffected.end(); ++eIt)
     {
-      myMesh->SetIsModified(true);
-
-      int lg = anAffected.size();
-      MESSAGE("lg="<< lg);
-      SMESH::long_array_var volumeIds = new SMESH::long_array;
-      volumeIds->length(lg);
-      SMESH::long_array_var faceIds = new SMESH::long_array;
-      faceIds->length(lg);
-      SMESH::long_array_var edgeIds = new SMESH::long_array;
-      edgeIds->length(lg);
-      int ivol = 0;
-      int iface = 0;
-      int iedge = 0;
-
-      TIDSortedElemSet::const_iterator eIt = anAffected.begin();
-      for (; eIt != anAffected.end(); ++eIt)
-        {
-          const SMDS_MeshElement* anElem = *eIt;
-          if (!anElem)
-            continue;
-          int elemId = anElem->GetID();
-          if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
-            volumeIds[ivol++] = elemId;
-          else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
-            faceIds[iface++] = elemId;
-          else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
-            edgeIds[iedge++] = elemId;
-        }
-      volumeIds->length(ivol);
-      faceIds->length(iface);
-      edgeIds->length(iedge);
-
-      aNewVolumeGroup->Add(volumeIds);
-      aNewFaceGroup->Add(faceIds);
-      aNewEdgeGroup->Add(edgeIds);
-      isVolumeGroup = (aNewVolumeGroup->Size() > 0);
-      isFaceGroup = (aNewFaceGroup->Size() > 0);
-      isEdgeGroup = (aNewEdgeGroup->Size() > 0);
+      const SMDS_MeshElement* anElem = *eIt;
+      if (!anElem)
+        continue;
+      int elemId = anElem->GetID();
+      if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
+        volumeIds[ivol++] = elemId;
+      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
+        faceIds[iface++] = elemId;
+      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
+        edgeIds[iedge++] = elemId;
     }
+    volumeIds->length(ivol);
+    faceIds->length(iface);
+    edgeIds->length(iedge);
+
+    aNewVolumeGroup->Add(volumeIds);
+    aNewFaceGroup->Add(faceIds);
+    aNewEdgeGroup->Add(edgeIds);
+    isVolumeGroup = (aNewVolumeGroup->Size() > 0);
+    isFaceGroup = (aNewFaceGroup->Size() > 0);
+    isEdgeGroup = (aNewEdgeGroup->Size() > 0);
+  }
 
   int nbGroups = 0;
-  if (isEdgeGroup)
-    nbGroups++;
-  if (isFaceGroup)
-    nbGroups++;
-  if (isVolumeGroup)
-    nbGroups++;
+  if (isEdgeGroup)   nbGroups++;
+  if (isFaceGroup)   nbGroups++;
+  if (isVolumeGroup) nbGroups++;
   aListOfGroups->length(nbGroups);
 
   int i = 0;
-  if (isEdgeGroup)
-    aListOfGroups[i++] = aNewEdgeGroup._retn();
-  if (isFaceGroup)
-    aListOfGroups[i++] = aNewFaceGroup._retn();
-  if (isVolumeGroup)
-    aListOfGroups[i++] = aNewVolumeGroup._retn();
+  if (isEdgeGroup)   aListOfGroups[i++] = aNewEdgeGroup._retn();
+  if (isFaceGroup)   aListOfGroups[i++] = aNewFaceGroup._retn();
+  if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
 
   // Update Python script
 
   pyDump << "[ ";
-  if (isEdgeGroup)
-    pyDump << aNewEdgeGroup << ", ";
-  if (isFaceGroup)
-    pyDump << aNewFaceGroup << ", ";
-  if (isVolumeGroup)
-    pyDump << aNewVolumeGroup << ", ";
+  if (isEdgeGroup)   pyDump << aNewEdgeGroup << ", ";
+  if (isFaceGroup)   pyDump << aNewFaceGroup << ", ";
+  if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
   pyDump << "] = ";
-  pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
+  pyDump << this << ".AffectedElemGroupsInRegion( "
+         << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
 
   return aListOfGroups._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -6172,38 +6745,57 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 //================================================================================
 
 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   bool aResult = getEditor().Make2DMeshFrom3D();
-  myMesh->GetMeshDS()->Modified();
+
   TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
+
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return false;
 }
 
 //================================================================================
 /*!
  * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
- * The list of groups must describe a partition of the mesh volumes.
+ * The list of groups must contain at least two groups. The groups have to be disjoint:
+ * no common element into two different groups.
  * The nodes of the internal faces at the boundaries of the groups are doubled.
- * In option, the internal faces are replaced by flat elements.
- * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * Optionally, the internal faces are replaced by flat elements.
+ * Triangles are transformed into prisms, and quadrangles into hexahedrons.
  * The flat elements are stored in groups of volumes.
+ * These groups are named according to the position of the group in the list:
+ * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
+ * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
+ * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
+ * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
  * @param theDomains - list of groups of volumes
  * @param createJointElems - if TRUE, create the elements
  * @return TRUE if operation has been completed successfully, FALSE otherwise
  */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
-                                                                 CORBA::Boolean createJointElems )
+CORBA::Boolean
+SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
+                                                  CORBA::Boolean             createJointElems )
   throw (SALOME::SALOME_Exception)
 {
-  initData();
+  bool aResult = false;
 
+  SMESH_TRY;
+  initData();
 
   SMESHDS_Mesh* aMeshDS = getMeshDS();
 
+  // MESSAGE("theDomains.length = "<<theDomains.length());
+  if ( theDomains.length() <= 1 )
+    THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
   vector<TIDSortedElemSet> domains;
   domains.clear();
 
@@ -6222,14 +6814,17 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::Li
     }
   }
 
-  bool aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
+  aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
   // TODO publish the groups of flat elements in study
 
-  myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
       << ", " << createJointElems << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return aResult;
 }
 
@@ -6245,11 +6840,13 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::Li
  */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
+CORBA::Boolean
+SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
-
   SMESHDS_Mesh* aMeshDS = getMeshDS();
 
   vector<TIDSortedElemSet> faceGroups;
@@ -6271,59 +6868,75 @@ CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH:
   bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
   // TODO publish the groups of flat elements in study
 
-  myMesh->GetMeshDS()->Modified();
+  declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
+  TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
   return aResult;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return false;
 }
 
+//================================================================================
 /*!
- *  \brief identify all the elements around a geom shape, get the faces delimiting the hole
- *  Build groups of volume to remove, groups of faces to replace on the skin of the object,
- *  groups of faces to remove inside the object, (idem edges).
- *  Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
+ *  \brief Identify all the elements around a geom shape, get the faces delimiting
+ *         the hole.
+ *
+ *  Build groups of volume to remove, groups of faces to replace on the skin of the
+ *  object, groups of faces to remove inside the object, (idem edges).
+ *  Build ordered list of nodes at the border of each group of faces to replace
+ *  (to be used to build a geom subshape).
  */
-void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
-                                        GEOM::GEOM_Object_ptr theShape,
-                                        const char* groupName,
-                                        const SMESH::double_array& theNodesCoords,
+//================================================================================
+
+void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double                  radius,
+                                        GEOM::GEOM_Object_ptr          theShape,
+                                        const char*                    groupName,
+                                        const SMESH::double_array&     theNodesCoords,
                                         SMESH::array_of_long_array_out GroupsOfNodes)
-throw (SALOME::SALOME_Exception)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
+
   initData();
   std::vector<std::vector<int> > aListOfListOfNodes;
   ::SMESH_MeshEditor aMeshEditor( myMesh );
 
   theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
   if ( !theNodeSearcher )
-    theNodeSearcher = aMeshEditor.GetNodeSearcher();
+    theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
 
   vector<double> nodesCoords;
   for (int i = 0; i < theNodesCoords.length(); i++)
-    {
-      nodesCoords.push_back( theNodesCoords[i] );
+  {
+    nodesCoords.push_back( theNodesCoords[i] );
   }
 
   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
-  aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
+  aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
+                             nodesCoords, aListOfListOfNodes);
 
   GroupsOfNodes = new SMESH::array_of_long_array;
   GroupsOfNodes->length( aListOfListOfNodes.size() );
   std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
   for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
-    {
-      vector<int>& aListOfNodes = *llIt;
-      vector<int>::iterator lIt = aListOfNodes.begin();;
-      SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
-      aGroup.length( aListOfNodes.size() );
-      for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
-        aGroup[ j ] = (*lIt);
-    }
+  {
+    vector<int>& aListOfNodes = *llIt;
+    vector<int>::iterator lIt = aListOfNodes.begin();;
+    SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
+    aGroup.length( aListOfNodes.size() );
+    for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
+      aGroup[ j ] = (*lIt);
+  }
   TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
-      << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
-}
+                << radius << ", "
+                << theShape
+                << ", '" << groupName << "', "
+                << theNodesCoords << " )";
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
 
 // issue 20749 ===================================================================
 /*!
@@ -6350,7 +6963,9 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
                                      CORBA::Boolean            toCopyElements,
                                      CORBA::Boolean            toCopyExistingBondary,
                                      SMESH::SMESH_Group_out    group)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
   initData();
 
   if ( dim > SMESH::BND_1DFROM2D )
@@ -6365,6 +6980,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
 
   TIDSortedElemSet elements;
   SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
+  prepareIdSource( idSource );
   if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
   {
     // mesh to fill in
@@ -6416,6 +7032,9 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
 
   group = group_var._retn();
   return mesh_var._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return SMESH::SMESH_Mesh::_nil();
 }
 
 //================================================================================
@@ -6444,8 +7063,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
                                                      SMESH::SMESH_Group_out group)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-
+  SMESH_TRY;
   initData();
 
   if ( dim > SMESH::BND_1DFROM2D )
@@ -6572,4 +7190,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
   mesh  = mesh_var._retn();
   group = group_var._retn();
   return nbAdded;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }