Salome HOME
GetElementType method added
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index 9f1f9009968941fb7c867d8bc30c456300f16fbe..22bde5e382bbfc837bd79dfa91f64ad505f019cf 100644 (file)
 //  Module : SMESH
 //  $Header$
 
-using namespace std;
 #include "SMESH_Mesh_i.hxx"
 #include "SMESH_subMesh_i.hxx"
 #include "SMESH_MEDMesh_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Filter_i.hxx"
 
 #include "Utils_CorbaException.hxx"
+#include "Utils_ExceptHandlers.hxx"
 #include "utilities.h"
 
 #include "SALOME_NamingService.hxx"
@@ -42,11 +44,111 @@ using namespace std;
 #include "SMESHDS_Command.hxx"
 #include "SMESHDS_CommandType.hxx"
 #include "SMESH_MeshEditor_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "DriverMED_R_SMESHDS_Mesh.h"
+
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
 
 #include <string>
 #include <iostream>
+#include <sstream>
+
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
+
+using namespace std;
+
+int SMESH_Mesh_i::myIdGenerator = 0;
+
+//=============================================================================
+/*!
+ *  Constructor
+ */
+//=============================================================================
 
-//**** SMESHDS en champ
+SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
+                           SMESH_Gen_i*            gen_i,
+                           CORBA::Long studyId )
+: SALOME::GenericObj_i( thePOA )
+{
+  INFOS("SMESH_Mesh_i");
+  _impl = NULL;
+  _gen_i = gen_i;
+  _id = myIdGenerator++;
+  _studyId = studyId;
+  thePOA->activate_object( this );
+}
+
+//=============================================================================
+/*!
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH_Mesh_i::~SMESH_Mesh_i()
+{
+  INFOS("~SMESH_Mesh_i");
+  map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
+  for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
+    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
+    if ( aGroup ) {
+
+      // this method is colled from destructor of group (PAL6331)
+      //_impl->RemoveGroup( aGroup->GetLocalID() );
+      
+      aGroup->Destroy();
+    }
+  }
+  _mapGroups.clear();
+}
+
+//=============================================================================
+/*!
+ *  SetShape
+ *
+ *  Associates <this> mesh with <theShape> and puts a reference  
+ *  to <theShape> into the current study; 
+ *  the previous shape is substituted by the new one.
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
+    throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  try {
+    _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+}
+
+//=======================================================================
+//function : GetShapeToMesh
+//purpose  : 
+//=======================================================================
+
+GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
+    throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  GEOM::GEOM_Object_var aShapeObj;
+  try {
+    TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
+    if ( !S.IsNull() )
+      aShapeObj = _gen_i->ShapeToGeomObject( S );
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return aShapeObj._retn();
+}
 
 //=============================================================================
 /*!
@@ -54,39 +156,129 @@ using namespace std;
  */
 //=============================================================================
 
-SMESH_Mesh_i::SMESH_Mesh_i()
+static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
 {
-       MESSAGE("SMESH_Mesh_i: default constructor, not for use");
-       ASSERT(0);
-};
+  SMESH::DriverMED_ReadStatus res;
+  switch (theStatus)
+  {
+  case DriverMED_R_SMESHDS_Mesh::DRS_OK:
+    res = SMESH::DRS_OK; break;
+  case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
+    res = SMESH::DRS_EMPTY; break;
+  case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
+    res = SMESH::DRS_WARN_RENUMBER; break;
+  case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
+    res = SMESH::DRS_WARN_SKIP_ELEM; break;
+  case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
+  default:
+    res = SMESH::DRS_FAIL; break;
+  }
+  return res;
+}
 
 //=============================================================================
 /*!
- *  Constructor
+ *  ImportMEDFile
+ *
+ *  Imports mesh data from MED file
  */
 //=============================================================================
 
-SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i * gen_i,
-       GEOM::GEOM_Gen_ptr geomEngine, CORBA::Long studyId, int localId)
+SMESH::DriverMED_ReadStatus
+SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
+  throw ( SALOME::SALOME_Exception )
 {
-       MESSAGE("SMESH_Mesh_i");
-       _gen_i = gen_i;
-       _id = localId;
-       _geom = GEOM::GEOM_Gen::_narrow(geomEngine);
-       _studyId = studyId;
+  Unexpect aCatch(SALOME_SalomeException);
+  int status;
+  try {
+    status = importMEDFile( theFileName, theMeshName );
+  }
+  catch( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }  
+  catch ( ... ) {
+    THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
+  }
+
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() ) {
+    // publishing of the groups in the study (sub-meshes are out of scope of MED import)
+    map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
+    for (; it != _mapGroups.end(); it++ ) {
+      SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_duplicate( it->second );
+      _gen_i->PublishGroup( aStudy, _this(), aGroup,
+                           GEOM::GEOM_Object::_nil(), aGroup->GetName());
+    }
+  }
+  return ConvertDriverMEDReadStatus(status);
 }
 
 //=============================================================================
 /*!
- *  Destructor
+ *  ImportUNVFile
+ *
+ *  Imports mesh data from MED file
  */
 //=============================================================================
 
-SMESH_Mesh_i::~SMESH_Mesh_i()
+int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
+  throw ( SALOME::SALOME_Exception )
+{
+  // Read mesh with name = <theMeshName> into SMESH_Mesh
+  _impl->UNVToMesh( theFileName );
+
+  return 1;
+}
+
+//=============================================================================
+/*!
+ *  ImportSTLFile
+ *
+ *  Imports mesh data from STL file
+ */
+//=============================================================================
+int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
+  throw ( SALOME::SALOME_Exception )
+{
+  // Read mesh with name = <theMeshName> into SMESH_Mesh
+  _impl->STLToMesh( theFileName );
+
+  return 1;
+}
+
+//=============================================================================
+/*!
+ *  importMEDFile
+ *
+ *  Imports mesh data from MED file
+ */
+//=============================================================================
+
+int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
 {
-       MESSAGE("~SMESH_Mesh_i");
-       // ****
-};
+  // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
+  int status = _impl->MEDToMesh( theFileName, theMeshName );
+
+  // Create group servants, if any groups were imported
+  list<int> aGroupIds = _impl->GetGroupIds();
+  for ( list<int>::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) {
+    SMESH_Group_i* aGroupImpl     = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it );
+
+    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+    SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
+    aGroupImpl->Register();
+    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+
+    SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
+    _mapGroups[*it]               = SMESH::SMESH_Group::_duplicate( aGroup );
+
+    // register CORBA object for persistence
+    int nextId = _gen_i->RegisterObject( aGroup );
+    if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+  }
+
+  return status;
+}
 
 //=============================================================================
 /*!
@@ -94,35 +286,67 @@ SMESH_Mesh_i::~SMESH_Mesh_i()
  */
 //=============================================================================
 
-CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
-       SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception)
+static SMESH::Hypothesis_Status ConvertHypothesisStatus
+                         (SMESH_Hypothesis::Hypothesis_Status theStatus)
 {
-       MESSAGE("AddHypothesis");
-       // **** proposer liste de subShape (selection multiple)
+  SMESH::Hypothesis_Status res;
+  switch (theStatus)
+  {
+  case SMESH_Hypothesis::HYP_OK:
+    res = SMESH::HYP_OK; break;
+  case SMESH_Hypothesis::HYP_MISSING:
+    res = SMESH::HYP_MISSING; break;
+  case SMESH_Hypothesis::HYP_CONCURENT:
+    res = SMESH::HYP_CONCURENT; break;
+  case SMESH_Hypothesis::HYP_BAD_PARAMETER:
+    res = SMESH::HYP_BAD_PARAMETER; break;
+  case SMESH_Hypothesis::HYP_INCOMPATIBLE:
+    res = SMESH::HYP_INCOMPATIBLE; break;
+  case SMESH_Hypothesis::HYP_NOTCONFORM:
+    res = SMESH::HYP_NOTCONFORM; break;
+  case SMESH_Hypothesis::HYP_ALREADY_EXIST:
+    res = SMESH::HYP_ALREADY_EXIST; break;
+  case SMESH_Hypothesis::HYP_BAD_DIM:
+    res = SMESH::HYP_BAD_DIM; break;
+  default:
+    res = SMESH::HYP_UNKNOWN_FATAL;
+  }
+  return res;
+}
 
-       GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
-       if (CORBA::is_nil(mySubShape))
-               THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                       SALOME::BAD_PARAM);
+//=============================================================================
+/*!
+ *  AddHypothesis
+ *
+ *  calls internal addHypothesis() and then adds a reference to <anHyp> under 
+ *  the SObject actually having a reference to <aSubShape>.
+ *  NB: For this method to work, it is necessary to add a reference to sub-shape first.
+ */
+//=============================================================================
 
-       SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
-       if (CORBA::is_nil(myHyp))
-               THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
-                       SALOME::BAD_PARAM);
-       bool ret = false;
-       try
-       {
-               TopoDS_Shape myLocSubShape =
-                       _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
-               int hypId = myHyp->GetId();
-               ret = _impl->AddHypothesis(myLocSubShape, hypId);
-       }
-       catch(SALOME_Exception & S_ex)
-       {
-               THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
-       }
-       return ret;
-};
+SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                                     SMESH::SMESH_Hypothesis_ptr anHyp)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
+
+  if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+    _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
+                                 aSubShapeObject, anHyp );
+
+  if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
+
+  // Update Python script
+  TCollection_AsciiString aStr ("status = ");
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".AddHypothesis(";
+  SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", ";
+  SMESH_Gen_i::AddObject(aStr, anHyp) += ")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  return ConvertHypothesisStatus(status);
+}
 
 //=============================================================================
 /*!
@@ -130,367 +354,268 @@ CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
  */
 //=============================================================================
 
-CORBA::Boolean
-       SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape,
-       SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception)
+SMESH_Hypothesis::Hypothesis_Status
+  SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
+                              SMESH::SMESH_Hypothesis_ptr anHyp)
 {
-       MESSAGE("RemoveHypothesis");
+  if(MYDEBUG) MESSAGE("addHypothesis");
+
+  if (CORBA::is_nil(aSubShapeObject))
+    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+                                 SALOME::BAD_PARAM);
+
+  SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
+  if (CORBA::is_nil(myHyp))
+    THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
+                                 SALOME::BAD_PARAM);
+
+  SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
+  try
+  {
+    TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
+    int hypId = myHyp->GetId();
+    status = _impl->AddHypothesis(myLocSubShape, hypId);
+    if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
+      _mapHypo[hypId] = myHyp;
+      // assure there is a corresponding submesh
+      if ( !_impl->IsMainShape( myLocSubShape )) {
+        int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
+        if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
+          createSubMesh( aSubShapeObject );
+      }
+    }
+  }
+  catch(SALOME_Exception & S_ex)
+  {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return status;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                                        SMESH::SMESH_Hypothesis_ptr anHyp)
+     throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
+
+  if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+    _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
+                                      aSubShapeObject, anHyp );
+
+  // Update Python script
+  TCollection_AsciiString aStr ("status = ");
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveHypothesis(";
+  SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", ";
+  SMESH_Gen_i::AddObject(aStr, anHyp) += ")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  return ConvertHypothesisStatus(status);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                 SMESH::SMESH_Hypothesis_ptr anHyp)
+{
+       if(MYDEBUG) MESSAGE("removeHypothesis()");
        // **** proposer liste de subShape (selection multiple)
 
-       GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
-       if (CORBA::is_nil(mySubShape))
+       if (CORBA::is_nil(aSubShapeObject))
                THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
                        SALOME::BAD_PARAM);
 
        SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
        if (CORBA::is_nil(myHyp))
-               THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
+         THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
                        SALOME::BAD_PARAM);
 
-       bool ret = false;
+       SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
        try
        {
-               TopoDS_Shape myLocSubShape =
-                       _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
+               TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
                int hypId = myHyp->GetId();
-               ret = _impl->RemoveHypothesis(myLocSubShape, hypId);
+               status = _impl->RemoveHypothesis(myLocSubShape, hypId);
+                if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+                  _mapHypo.erase( hypId );
        }
        catch(SALOME_Exception & S_ex)
        {
                THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
        }
-       return ret;
-};
+       return status;
+}
 
-/**
- *@TODO Not implemented
+//=============================================================================
+/*!
+ *  
  */
+//=============================================================================
+
 SMESH::ListOfHypothesis *
-       SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Shape_ptr aSubShape)
+       SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
 throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("GetHypothesisList: Not implemented");
-       return NULL;
-};
+  Unexpect aCatch(SALOME_SalomeException);
+  if (MYDEBUG) MESSAGE("GetHypothesisList");
+  if (CORBA::is_nil(aSubShapeObject))
+    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+                                SALOME::BAD_PARAM);
+  
+  SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
+
+  try {
+    TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
+    const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
+    int i = 0, n = aLocalList.size();
+    aList->length( n );
+
+    for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
+      SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
+      if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
+       aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
+    }
+
+    aList->length( i );
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  
+  return aList._retn();
+}
 
 //=============================================================================
 /*!
  *  
  */
 //=============================================================================
-SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetElementsOnShape(GEOM::
-       GEOM_Shape_ptr aSubShape) throw(SALOME::SALOME_Exception)
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                                 const char*           theName ) 
+     throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::GetElementsOnShape");
-       GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape);
-       if (CORBA::is_nil(mySubShape))
-               THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                       SALOME::BAD_PARAM);
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_Mesh_i::GetSubMesh");
+  if (CORBA::is_nil(aSubShapeObject))
+    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+                                SALOME::BAD_PARAM);
+  
+  SMESH::SMESH_subMesh_var subMesh;
+  SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
+  try {
+    TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
+    
+    //Get or Create the SMESH_subMesh object implementation
+    
+    int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
+    subMesh = getSubMesh( subMeshId );
+
+    // create a new subMesh object servant if there is none for the shape
+    if ( subMesh->_is_nil() )
+      subMesh = createSubMesh( aSubShapeObject );
+
+    if ( _gen_i->CanPublishInStudy( subMesh )) {
+      SALOMEDS::SObject_var aSO =
+        _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
+                               subMesh, aSubShapeObject, theName );
+      if ( !aSO->_is_nil()) {
+        // Update Python script
+        TCollection_AsciiString aStr (aSO->GetID());
+        aStr += " = ";
+        SMESH_Gen_i::AddObject(aStr, _this()) += ".GetSubMesh(";
+        SMESH_Gen_i::AddObject(aStr, aSubShapeObject) += ", \"";
+        aStr += (char*)theName;
+        aStr += "\")";
+
+        SMESH_Gen_i::AddToCurrentPyScript(aStr);
+      }
+    }
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return subMesh._retn();
+}
 
-       int subMeshId = 0;
-       try
-       {
-               SMESH_subMesh_i *subMeshServant;
-               TopoDS_Shape myLocSubShape
-                       = _gen_i->_ShapeReader->GetShape(_geom, mySubShape);
-
-               //Get or Create the SMESH_subMesh object implementation
-
-               ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
-               subMeshId = mySubMesh->GetId();
-
-               // create a new subMesh object servant if there is none for the shape
-
-               if (_mapSubMesh.find(subMeshId) != _mapSubMesh.end())
-               {
-                       ASSERT(_mapSubMesh_i.find(subMeshId) != _mapSubMesh_i.end());
-                       subMeshServant = _mapSubMesh_i[subMeshId];
-               }
-               else
-               {
-                       // create and activate the CORBA servant of Mesh
-                       subMeshServant = new SMESH_subMesh_i(_gen_i, this, subMeshId);
-                       SMESH::SMESH_subMesh_var subMesh
-                               = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
-                       _mapSubMesh[subMeshId] = mySubMesh;
-                       _mapSubMesh_i[subMeshId] = subMeshServant;
-                       _mapSubMeshIor[subMeshId]
-                               = SMESH::SMESH_subMesh::_duplicate(subMesh);
-               }
-       }
-       catch(SALOME_Exception & S_ex)
-       {
-               THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
-       }
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
 
-       ASSERT(_mapSubMeshIor.find(subMeshId) != _mapSubMeshIor.end());
-       return SMESH::SMESH_subMesh::_duplicate(_mapSubMeshIor[subMeshId]);
-}
-
-/**
- * Translate the UpdateAll SMESHDS_Command to a set of SMESH::log_command.
- * As the input log need to be resized, it is realocated.
- * @param logBlock The log where to insert created commands
- * @param index The place where to insert created commands in log. It is updated
- * with the place to put new elements.
- * @return The realocated and resized log.
- * @TODO Add support for other type of elements
- */
-SMESH::log_array_var SMESH_Mesh_i::
-       createUpdateAllCommand(SMESH::log_array_var log, int * index)
-{
-       MESSAGE("SMESH_Mesh_i::createUpdateAllCommand");
-       SMESH::log_array_var aLog=new SMESH::log_array(log->length()+3);
-       aLog->length(log->length()+3);
-       
-       for(int i=0;i<*index;i++)
-       {               
-               aLog[i]=log[i];
-       }
-       
-       log->length(0);
-       int id=*index;
-               
-       //Remove all elements
-       aLog[id].commandType=SMESH::REMOVE_ALL;
-       id++;
-       
-       //Export nodes
-       aLog[id].commandType=SMESH::ADD_NODE;
-       aLog[id].number=_impl->GetMeshDS()->NbNodes();
-
-       double * nodesCoordinates=_impl->GetMeshDS()->getNodesCoordinates();
-       aLog[id].coords=SMESH::double_array(
-               aLog[id].number*3,
-               aLog[id].number*3,
-               nodesCoordinates);
-
-       long * nodesID=_impl->GetMeshDS()->getNodesID();
-       aLog[id].indexes=SMESH::long_array(
-               aLog[id].number,
-               aLog[id].number,
-               nodesID);
-
-       id++;
-       
-       MESSAGE("Export edges");
-       //Export edges
-       aLog[id].commandType=SMESH::ADD_EDGE;
-       aLog[id].number=_impl->GetMeshDS()->NbEdges();  
-       aLog[id].coords.length(0);
-
-       long * edgesIndices=_impl->GetMeshDS()->getEdgesIndices();
-       aLog[id].indexes=SMESH::long_array(
-               aLog[id].number*3,
-               aLog[id].number*3,
-               edgesIndices);
-
-       id++;
-       
-       MESSAGE("Export triangles");
-       //Export triangles
-       aLog[id].commandType=SMESH::ADD_TRIANGLE;
-       aLog[id].number=_impl->GetMeshDS()->NbTriangles();      
-       aLog[id].coords.length(0);
-
-       long * triasIndices=_impl->GetMeshDS()->getTrianglesIndices();
-       aLog[id].indexes=SMESH::long_array(
-               aLog[id].number*4,
-               aLog[id].number*4,
-               triasIndices);
-
-       (*index)=id;
-       return aLog;
-}
-
-/**
- * Return the log of the current mesh. CORBA wrap of the SMESH::GetLog method
- * with a special treatment for SMESHDS_UpdateAll commands
- * @param clearAfterGet Tell if the log must be cleared after being returned
- * @return the log
+void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
+     throw (SALOME::SALOME_Exception)
+{
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
+  if ( theSubMesh->_is_nil() )
+    return;
+
+  GEOM::GEOM_Object_var aSubShapeObject;
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() )  {
+    // Remove submesh's SObject
+    SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
+    if ( !anSO->_is_nil() ) {
+      long aTag = SMESH_Gen_i::GetRefOnShapeTag(); 
+      SALOMEDS::SObject_var anObj, aRef;
+      if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
+       aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
+
+      aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
+
+      // Update Python script
+      TCollection_AsciiString aStr;
+      SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveSubMesh(";
+      aStr += anSO->GetID();
+      aStr += ")";
+
+      SMESH_Gen_i::AddToCurrentPyScript(aStr);
+    }
+  }
+
+  removeSubMesh( theSubMesh, aSubShapeObject.in() );
+}
+
+//=============================================================================
+/*!
+ *  ElementTypeString
  */
-SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
-       throw(SALOME::SALOME_Exception)
-{
-       MESSAGE("SMESH_Mesh_i::GetLog");
-
-       SMESH::log_array_var aLog;
-       /*try
-       {*/
-               list < SMESHDS_Command * >logDS = _impl->GetLog();
-               aLog = new SMESH::log_array;
-               int indexLog = 0;
-               int lg = logDS.size();
-               MESSAGE("Number of command in the log: "<<lg);
-               aLog->length(lg);
-               list < SMESHDS_Command * >::iterator its = logDS.begin();
-               while (its != logDS.end())
-               {
-                       SMESHDS_Command *com = *its;
-                       int comType = com->GetType();
-                       //SCRUTE(comType);
-                       int lgcom = com->GetNumber();
-                       //SCRUTE(lgcom);
-                       const list < int >&intList = com->GetIndexes();
-                       int inum = intList.size();
-                       //SCRUTE(inum);
-                       list < int >::const_iterator ii = intList.begin();
-                       const list < double >&coordList = com->GetCoords();
-                       int rnum = coordList.size();
-                       //SCRUTE(rnum);
-                       list < double >::const_iterator ir = coordList.begin();
-                       aLog[indexLog].commandType = comType;
-                       if(comType==SMESHDS_UpdateAll)
-                       {
-                               aLog=createUpdateAllCommand(aLog, &indexLog);
-                       }
-                       else
-                       {
-                               aLog[indexLog].number = lgcom;
-                               aLog[indexLog].coords.length(rnum);
-                               aLog[indexLog].indexes.length(inum);
-                               for (int i = 0; i < rnum; i++)
-                               {
-                                       aLog[indexLog].coords[i] = *ir;
-                                       //MESSAGE(" "<<i<<" "<<ir.Value());
-                                       ir++;
-                               }
-                               for (int i = 0; i < inum; i++)
-                               {
-                                       aLog[indexLog].indexes[i] = *ii;
-                                       //MESSAGE(" "<<i<<" "<<ii.Value());
-                                       ii++;
-                               }
-                               indexLog++;
-                       }
-                       its++;
-               }
-               if (clearAfterGet) _impl->ClearLog();
-               return aLog._retn();
-       /*}
-       catch(SALOME_Exception & S_ex)
-       {
-               THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
-       }*/
-}
-
-//  SMESH::string_array* SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
-//    throw (SALOME::SALOME_Exception)
-//  {
-//    MESSAGE("SMESH_Mesh_i::GetLog");
-
-//    SMESH::string_array_var aLog;
-//    try
-//      {
-//        const SMESHDS_ListOfCommand& logDS =_impl->GetLog();
-//        aLog = new SMESH::string_array;
-//        int logSize = 0;
-//        int indexLog = 0;
-//        int lg = logDS.Extent();
-//        SCRUTE(lg);
-//        SMESHDS_ListIteratorOfListOfCommand its(logDS);
-//        while(its.More())
-//        {
-//      Handle(SMESHDS_Command) com = its.Value();
-//      int comType = com->GetType();
-//      SCRUTE(comType);
-//      int lgcom = com->GetNumber();
-//      SCRUTE(lgcom);
-//      logSize += lgcom;
-//      aLog->length(logSize);
-//      SCRUTE(logSize);
-//      const TColStd_ListOfInteger& intList = com->GetIndexes();
-//      TColStd_ListIteratorOfListOfInteger ii(intList);
-//      const TColStd_ListOfReal& coordList = com->GetCoords();
-//      TColStd_ListIteratorOfListOfReal ir(coordList);
-//      for (int icom = 1; icom <= lgcom; icom++)
-//        {
-//          ostringstream S;
-//          switch (comType)
-//            {
-//            case SMESHDS_AddNode:
-//          S << "AddNode " << ii.Value(); ii.Next();
-//          S << " " << ir.Value(); ir.Next(); 
-//          S << " " << ir.Value(); ir.Next();
-//          S << " " << ir.Value(); ir.Next();
-//          break;
-//            case SMESHDS_AddEdge:
-//          S << "AddEdge " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddTriangle:
-//          S << "AddFace " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddQuadrangle:
-//          S << "AddFace " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddTetrahedron:
-//          S << "AddVolume " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddPyramid:
-//          S << "AddVolume " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddPrism:
-//          S << "AddVolume " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_AddHexahedron:
-//          S << "AddVolume " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          S << " " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_RemoveNode:
-//          S << "RemoveNode " << ii.Value(); ii.Next();
-//          break;
-//            case SMESHDS_RemoveElement:
-//          S << "RemoveElement " << ii.Value(); ii.Next();
-//          break;
-//            default:
-//          ASSERT(0);
-//          break;
-//            }
-//          string ch = S.str();
-//          SCRUTE(ch);
-//          aLog[indexLog++] = CORBA::string_dup(ch.c_str());
-//        }
-//      its.Next();
-//        }
-//        if (clearAfterGet) _impl->ClearLog();
-//      }
-//    catch (SALOME_Exception& S_ex)
-//      {
-//        THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
-//      }
-//    return aLog._retn();
-//  }
+//=============================================================================
+inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
+{
+  TCollection_AsciiString aStr;
+  switch (theElemType) {
+  case SMESH::ALL:
+    aStr = "SMESH.ALL";
+    break;
+  case SMESH::NODE:
+    aStr = "SMESH.NODE";
+    break;
+  case SMESH::EDGE:
+    aStr = "SMESH.EDGE";
+    break;
+  case SMESH::FACE:
+    aStr = "SMESH.FACE";
+    break;
+  case SMESH::VOLUME:
+    aStr = "SMESH.VOLUME";
+    break;
+  default:
+    break;
+  }
+  return aStr;
+}
 
 //=============================================================================
 /*!
@@ -498,22 +623,333 @@ SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
  */
 //=============================================================================
 
-void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
+                                                 const char*         theName )
+     throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::ClearLog");
-       // ****
+  Unexpect aCatch(SALOME_SalomeException);
+  SMESH::SMESH_Group_var aNewGroup =
+    SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
+
+  if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
+    SALOMEDS::SObject_var aSO =
+      _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
+                           aNewGroup, GEOM::GEOM_Object::_nil(), theName);
+    if ( !aSO->_is_nil()) {
+      // Update Python script
+      TCollection_AsciiString aStr (aSO->GetID());
+      aStr += " = ";
+      SMESH_Gen_i::AddObject(aStr, _this()) += ".CreateGroup(";
+      aStr += ElementTypeString(theElemType) + ", \"" + (char*)theName + "\")";
+
+      SMESH_Gen_i::AddToCurrentPyScript(aStr);
+    }
+  }
+
+  return aNewGroup._retn();
 }
 
+
 //=============================================================================
 /*!
  *  
  */
 //=============================================================================
+SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
+                                                                const char*           theName,
+                                                                GEOM::GEOM_Object_ptr theGeomObj)
+     throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  SMESH::SMESH_GroupOnGeom_var aNewGroup;
+
+  TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
+  if ( !aShape.IsNull() ) {
+    aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
+      ( createGroup( theElemType, theName, aShape ));
+    if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
+      SALOMEDS::SObject_var aSO =
+        _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), 
+                             aNewGroup, theGeomObj, theName);
+      if ( !aSO->_is_nil()) {
+        // Update Python script
+        TCollection_AsciiString aStr (aSO->GetID());
+        aStr += " = ";
+        SMESH_Gen_i::AddObject(aStr, _this()) += ".CreateGroupFromGEOM(";
+        aStr += ElementTypeString(theElemType) + ", \"" + (char*)theName + "\", ";
+        SMESH_Gen_i::AddObject(aStr, theGeomObj) += ")";
+
+        SMESH_Gen_i::AddToCurrentPyScript(aStr);
+      }
+    }
+  }
+
+  return aNewGroup._retn();
+}
 
-CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
+     throw (SALOME::SALOME_Exception)
+{
+  if ( theGroup->_is_nil() )
+    return;
+
+  SMESH_GroupBase_i* aGroup =
+    dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
+  if ( !aGroup )
+    return;
+
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() )  {
+    SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
+
+    if ( !aGroupSO->_is_nil() ) {
+      // Update Python script
+      TCollection_AsciiString aStr;
+      SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveGroup(";
+      aStr += aGroupSO->GetID();
+      aStr += ")";
+
+      SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+      // Remove group's SObject
+      aStudy->NewBuilder()->RemoveObject( aGroupSO );
+    }
+  }
+
+  // Remove the group from SMESH data structures
+  removeGroup( aGroup->GetLocalID() );
+}
+
+//=============================================================================
+/*! RemoveGroupWithContents
+ *  Remove group with its contents
+ */ 
+//=============================================================================
+void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
+  throw (SALOME::SALOME_Exception)
+{
+  if ( theGroup->_is_nil() )
+    return;
+
+  SMESH_GroupBase_i* aGroup =
+    dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
+  if ( !aGroup )
+    return;
+  
+  SMESH::long_array_var anIds = aGroup->GetListOfID();
+  SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".RemoveGroupWithContents(";
+  SMESH_Gen_i::AddObject(aStr, theGroup) += ")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Remove contents
+  if ( aGroup->GetType() == SMESH::NODE )
+    aMeshEditor->RemoveNodes( anIds );
+  else
+    aMeshEditor->RemoveElements( anIds );
+
+  // Remove group
+  RemoveGroup( theGroup );
+
+  // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
+  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
+  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
+}
+
+//=============================================================================
+/*! UnionGroups
+ *  New group is created. All mesh elements that are 
+ *  present in initial groups are added to the new one
+ */
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                                  SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                                  const char* theName )
+  throw (SALOME::SALOME_Exception)
+{
+  try
+  {
+    if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
+         theGroup1->GetType() != theGroup2->GetType() )
+      return SMESH::SMESH_Group::_nil();
+
+    // Create Union
+    SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
+    if ( aResGrp->_is_nil() )
+      return SMESH::SMESH_Group::_nil();
+
+    SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
+    SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
+
+    TColStd_MapOfInteger aResMap;
+
+    for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
+      aResMap.Add( anIds1[ i1 ] );
+
+    for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
+      aResMap.Add( anIds2[ i2 ] );
+
+    SMESH::long_array_var aResIds = new SMESH::long_array;
+    aResIds->length( aResMap.Extent() );
+
+    int resI = 0;
+    TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
+    for( ; anIter.More(); anIter.Next() )
+      aResIds[ resI++ ] = anIter.Key();
+
+    aResGrp->Add( aResIds );
+
+    // Clear python lines, created by CreateGroup() and Add()
+    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+    _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+    _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+
+    // Update Python script
+    TCollection_AsciiString aStr;
+    SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
+    SMESH_Gen_i::AddObject(aStr, _this()) += ".UnionGroups(";
+    SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
+    SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
+    aStr += TCollection_AsciiString((char*)theName) + "\")";
+
+    SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+    return aResGrp._retn();
+  }
+  catch( ... )
+  {
+    return SMESH::SMESH_Group::_nil();
+  }
+}
+  
+//=============================================================================
+/*! IntersectGroups
+ *  New group is created. All mesh elements that are 
+ *  present in both initial groups are added to the new one.
+ */
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                                      SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                                      const char* theName )
+  throw (SALOME::SALOME_Exception)
+{
+  if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
+       theGroup1->GetType() != theGroup2->GetType() )
+    return SMESH::SMESH_Group::_nil();
+
+  // Create Intersection
+  SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
+  if ( aResGrp->_is_nil() )
+    return aResGrp;
+
+  SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
+  SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
+
+  TColStd_MapOfInteger aMap1;
+
+  for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
+    aMap1.Add( anIds1[ i1 ] );
+
+  TColStd_SequenceOfInteger aSeq;
+
+  for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
+    if ( aMap1.Contains( anIds2[ i2 ] ) )
+      aSeq.Append( anIds2[ i2 ] );
+
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( aSeq.Length() );
+
+  for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
+    aResIds[ resI ] = aSeq( resI + 1 );
+
+  aResGrp->Add( aResIds );
+
+  // Clear python lines, created by CreateGroup() and Add()
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".IntersectGroups(";
+  SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
+  SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
+  aStr += TCollection_AsciiString((char*)theName) + "\")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  return aResGrp._retn();
+}
+
+//=============================================================================
+/*! CutGroups
+ *  New group is created. All mesh elements that are present in 
+ *  main group but do not present in tool group are added to the new one 
+ */
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                                SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                                const char* theName )
+  throw (SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::GetId");
-       return _id;
+  if ( theGroup1->_is_nil() || theGroup2->_is_nil() || 
+       theGroup1->GetType() != theGroup2->GetType() )
+    return SMESH::SMESH_Group::_nil();
+
+  // Perform Cutting
+  SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
+  if ( aResGrp->_is_nil() )
+    return aResGrp;
+
+  SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
+  SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
+
+  TColStd_MapOfInteger aMap2;
+
+  for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
+    aMap2.Add( anIds2[ i2 ] );
+
+
+  TColStd_SequenceOfInteger aSeq;
+  for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
+    if ( !aMap2.Contains( anIds1[ i1 ] ) )
+      aSeq.Append( anIds1[ i1 ] );
+
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( aSeq.Length() );
+
+  for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
+    aResIds[ resI ] = aSeq( resI + 1 );  
+
+  aResGrp->Add( aResIds );
+
+  // Clear python lines, created by CreateGroup() and Add()
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, aResGrp) += " = ";
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".CutGroups(";
+  SMESH_Gen_i::AddObject(aStr, theGroup1) += ", ";
+  SMESH_Gen_i::AddObject(aStr, theGroup2) += ", \"";
+  aStr += TCollection_AsciiString((char*)theName) + "\")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  return aResGrp._retn();
 }
 
 //=============================================================================
@@ -522,21 +958,72 @@ CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 
-CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
 {
-       return _studyId;
+  if(MYDEBUG) MESSAGE( "createSubMesh" );
+  TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
+
+  ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
+  int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
+  SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
+  SMESH::SMESH_subMesh_var subMesh
+    = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
+
+  _mapSubMesh[subMeshId] = mySubMesh;
+  _mapSubMesh_i[subMeshId] = subMeshServant;
+  _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
+
+  // register CORBA object for persistence
+  int nextId = _gen_i->RegisterObject( subMesh );
+  if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
+
+  return subMesh._retn(); 
 }
 
+//=======================================================================
+//function : getSubMesh
+//purpose  : 
+//=======================================================================
+
+SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
+{
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
+  if ( it == _mapSubMeshIor.end() )
+    return SMESH::SMESH_subMesh::_nil();
+
+  return SMESH::SMESH_subMesh::_duplicate( (*it).second );
+}
+
+
 //=============================================================================
 /*!
  *  
  */
 //=============================================================================
 
-void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
+void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
+                                  GEOM::GEOM_Object_ptr    theSubShapeObject )
 {
-       MESSAGE("SMESH_Mesh_i::SetImpl");
-       _impl = impl;
+  MESSAGE("SMESH_Mesh_i::removeSubMesh()");
+  if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
+    return;
+
+  try {
+    SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
+    for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
+      removeHypothesis( theSubShapeObject, aHypList[i] );
+    }
+  }
+  catch( const SALOME::SALOME_Exception& ) {
+    INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
+  }
+
+  int subMeshId = theSubMesh->GetId();
+
+  _mapSubMesh.erase(subMeshId);
+  _mapSubMesh_i.erase(subMeshId);
+  _mapSubMeshIor.erase(subMeshId);
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
 }
 
 //=============================================================================
@@ -545,10 +1032,123 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
  */
 //=============================================================================
 
-::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
+SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
+                                                      const char*         theName,
+                                                      const TopoDS_Shape& theShape )
+{
+  int anId;
+  SMESH::SMESH_GroupBase_var aGroup;
+  if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
+    SMESH_GroupBase_i* aGroupImpl;
+    if ( !theShape.IsNull() )
+      aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
+    else
+      aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
+
+    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+    SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
+    aGroupImpl->Register();
+    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+
+    aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
+    _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
+
+    // register CORBA object for persistence
+    int nextId = _gen_i->RegisterObject( aGroup );
+    if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+  }
+  return aGroup._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Mesh_i::removeGroup
+ *
+ * Should be called by ~SMESH_Group_i() 
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::removeGroup( const int theId )
+{
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );  
+  if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
+    _mapGroups.erase( theId );
+    _impl->RemoveGroup( theId );
+  }
+}
+
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
+throw(SALOME::SALOME_Exception)
+{
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
+  
+  SMESH::log_array_var aLog;
+  try{
+    list < SMESHDS_Command * >logDS = _impl->GetLog();
+    aLog = new SMESH::log_array;
+    int indexLog = 0;
+    int lg = logDS.size();
+    SCRUTE(lg);
+    aLog->length(lg);
+    list < SMESHDS_Command * >::iterator its = logDS.begin();
+    while(its != logDS.end()){
+      SMESHDS_Command *com = *its;
+      int comType = com->GetType();
+      //SCRUTE(comType);
+      int lgcom = com->GetNumber();
+      //SCRUTE(lgcom);
+      const list < int >&intList = com->GetIndexes();
+      int inum = intList.size();
+      //SCRUTE(inum);
+      list < int >::const_iterator ii = intList.begin();
+      const list < double >&coordList = com->GetCoords();
+      int rnum = coordList.size();
+      //SCRUTE(rnum);
+      list < double >::const_iterator ir = coordList.begin();
+      aLog[indexLog].commandType = comType;
+      aLog[indexLog].number = lgcom;
+      aLog[indexLog].coords.length(rnum);
+      aLog[indexLog].indexes.length(inum);
+      for(int i = 0; i < rnum; i++){
+       aLog[indexLog].coords[i] = *ir;
+       //MESSAGE(" "<<i<<" "<<ir.Value());
+       ir++;
+      }
+      for(int i = 0; i < inum; i++){
+       aLog[indexLog].indexes[i] = *ii;
+       //MESSAGE(" "<<i<<" "<<ii.Value());
+       ii++;
+      }
+      indexLog++;
+      its++;
+    }
+    if(clearAfterGet)
+      _impl->ClearLog();
+  }
+  catch(SALOME_Exception & S_ex){
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return aLog._retn();
+}
+
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::GetImpl()");
-       return *_impl;
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
+  // ****
 }
 
 //=============================================================================
@@ -557,10 +1157,10 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
  */
 //=============================================================================
 
-GEOM::GEOM_Gen_ptr SMESH_Mesh_i::GetGeomEngine()
+CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::GetGeomEngine");
-       return GEOM::GEOM_Gen::_duplicate(_geom);
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
+  return _id;
 }
 
 //=============================================================================
@@ -569,11 +1169,9 @@ GEOM::GEOM_Gen_ptr SMESH_Mesh_i::GetGeomEngine()
  */
 //=============================================================================
 
-void SMESH_Mesh_i::SetIor(SMESH::SMESH_Mesh_ptr myIor)
+CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("SMESH_Mesh_i::SetIor");
-       _myIor = SMESH::SMESH_Mesh::_duplicate(myIor);
-       ASSERT(!CORBA::is_nil(_myIor));
+  return _studyId;
 }
 
 //=============================================================================
@@ -582,13 +1180,25 @@ void SMESH_Mesh_i::SetIor(SMESH::SMESH_Mesh_ptr myIor)
  */
 //=============================================================================
 
-SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetIor()
+void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
 {
-       MESSAGE("SMESH_Mesh_i::GetIor");
-       ASSERT(!CORBA::is_nil(_myIor));
-       return SMESH::SMESH_Mesh::_duplicate(_myIor);
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
+  _impl = impl;
 }
 
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
+{
+  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
+  return *_impl;
+}
+
+
 //=============================================================================
 /*!
  *  
@@ -597,10 +1207,136 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetIor()
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 {
-       SMESH_MeshEditor_i *aMeshEditor =
-               new SMESH_MeshEditor_i(_impl->GetMeshDS());
-       SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
-       return aMesh._retn();
+  // Update Python script
+  TCollection_AsciiString aStr ("mesh_editor = ");
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".GetMeshEditor()";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Create MeshEditor
+  SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
+  SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
+  return aMesh._retn();
+}
+
+//=============================================================================
+/*!
+ *  Export in different formats
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::ExportToMED (const char* file, 
+                               CORBA::Boolean auto_groups, 
+                               SMESH::MED_VERSION theVersion)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportToMED(\"";
+  aStr += TCollection_AsciiString((char*)file) + "\", ";
+  aStr += TCollection_AsciiString((int)auto_groups) + ", ";
+  switch (theVersion) {
+  case SMESH::MED_V2_1:
+    aStr += "SMESH.MED_V2_1)";
+    break;
+  case SMESH::MED_V2_2:
+    aStr += "SMESH.MED_V2_2)";
+    break;
+  default:
+    aStr += TCollection_AsciiString(theVersion) + ")";
+    break;
+  }
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Perform Export
+  char* aMeshName = "Mesh";
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() ) {
+    SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
+    if ( !aMeshSO->_is_nil() ) {
+      aMeshName = aMeshSO->GetName();
+      //SCRUTE(file);
+      //SCRUTE(aMeshName);
+      //SCRUTE(aMeshSO->GetID());
+      
+      // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes 
+      if ( !aStudy->GetProperties()->IsLocked() ) 
+       {
+       SALOMEDS::GenericAttribute_var anAttr;
+       SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+       SALOMEDS::AttributeExternalFileDef_var aFileName;
+       anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
+       aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
+       ASSERT(!aFileName->_is_nil());
+        aFileName->SetValue(file);
+        SALOMEDS::AttributeFileType_var aFileType;
+        anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
+        aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
+        ASSERT(!aFileType->_is_nil());
+        aFileType->SetValue("FICHIERMED");
+       }
+    }
+  }
+  _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
+}
+
+void SMESH_Mesh_i::ExportMED (const char* file, 
+                             CORBA::Boolean auto_groups)
+  throw(SALOME::SALOME_Exception)
+{
+  ExportToMED(file,auto_groups,SMESH::MED_V2_1);
+}
+
+void SMESH_Mesh_i::ExportDAT (const char *file)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportDAT(\"";
+  aStr += TCollection_AsciiString((char*)file) + "\")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Perform Export
+  _impl->ExportDAT(file);
+}
+
+void SMESH_Mesh_i::ExportUNV (const char *file)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportUNV(\"";
+  aStr += TCollection_AsciiString((char*)file) + "\")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Perform Export
+  _impl->ExportUNV(file);
+}
+
+void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  // Update Python script
+  TCollection_AsciiString aStr;
+  SMESH_Gen_i::AddObject(aStr, _this()) += ".ExportToMED(\"";
+  aStr += TCollection_AsciiString((char*)file) + "\", ";
+  aStr += TCollection_AsciiString((int)isascii) + ")";
+
+  SMESH_Gen_i::AddToCurrentPyScript(aStr);
+
+  // Perform Export
+  _impl->ExportSTL(file, isascii);
 }
 
 //=============================================================================
@@ -611,9 +1347,10 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 
 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
 {
-       SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
-       SALOME_MED::MESH_var aMesh = aMedMesh->_this();
-       return aMesh._retn();
+  Unexpect aCatch(SALOME_SalomeException);
+  SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
+  SALOME_MED::MESH_var aMesh = aMedMesh->_this();
+  return aMesh._retn();
 }
 
 //=============================================================================
@@ -623,9 +1360,21 @@ SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbNodes();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbNodes();
 }
 
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return NbEdges() + NbFaces() + NbVolumes();
+}
+  
 //=============================================================================
 /*!
  *  
@@ -633,7 +1382,8 @@ CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbEdges();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbEdges();
 }
 
 //=============================================================================
@@ -643,17 +1393,26 @@ CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbFaces();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbFaces();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbTriangles();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbTriangles();
 }
 
 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbQuadrangles();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbQuadrangles();
+}
+
+CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbPolygons();
 }
 
 //=============================================================================
@@ -663,17 +1422,38 @@ CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbVolumes();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbVolumes();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbTetras();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbTetras();
 }
 
 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbHexas();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbHexas();
+}
+
+CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbPyramids();
+}
+
+CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbPrisms();
+}
+
+CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbPolyhedrons();
 }
 
 //=============================================================================
@@ -683,16 +1463,144 @@ CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
 {
-       return _impl->NbSubMesh();
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->NbSubMesh();
 }
 
+//=============================================================================
 /*!
- * Export mesh to a file
- * @param fileName file name where to export the file
- * @param fileType Currently it could be either "DAT", "UNV" or "MED".
+ *  
  */
-void SMESH_Mesh_i::Export(const char* fileName, const char* fileType)
-       throw (SALOME::SALOME_Exception)
+//=============================================================================
+char* SMESH_Mesh_i::Dump()
+{
+  std::ostringstream os;
+  _impl->Dump( os );
+  return CORBA::string_dup( os.str().c_str() );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+SMESH::long_array* SMESH_Mesh_i::GetIDs()
+{
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
+  int aMinId = aSMESHDS_Mesh->MinElementID();
+  int aMaxId =  aSMESHDS_Mesh->MaxElementID();
+
+  aResult->length(aMaxId - aMinId + 1);
+  
+  for (int i = 0, id = aMinId; id <= aMaxId; id++  )
+    aResult[i++] = id;
+  
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+SMESH::long_array* SMESH_Mesh_i::GetElementsId()
+     throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_Mesh_i::GetElementsId");
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
+
+  if ( aSMESHDS_Mesh == NULL )
+    return aResult._retn();
+
+  long nbElements = NbElements();
+  aResult->length( nbElements );
+  SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
+  for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
+    aResult[i] = anIt->next()->GetID();
+
+  return aResult._retn();
+}
+
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
+    throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetElementsByType");
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
+
+  if ( aSMESHDS_Mesh == NULL )
+    return aResult._retn();
+
+  long nbElements = NbElements();
+
+  // No sense in returning ids of elements along with ids of nodes:
+  // when theElemType == SMESH::ALL, return node ids only if
+  // there are no elements
+  if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
+    return GetNodesId();
+
+  aResult->length( nbElements );
+
+  int i = 0;
+
+  SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
+  while ( i < nbElements && anIt->more() ) {
+    const SMDS_MeshElement* anElem = anIt->next();
+    if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
+      aResult[i++] = anElem->GetID();
+  }
+
+  aResult->length( i );
+
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+SMESH::long_array* SMESH_Mesh_i::GetNodesId()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetNodesId");
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
+
+  if ( aSMESHDS_Mesh == NULL )
+    return aResult._retn();
+
+  long nbNodes = NbNodes();
+  aResult->length( nbNodes );
+  SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
+  for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
+    aResult[i] = anIt->next()->GetID();
+
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
+  throw (SALOME::SALOME_Exception)
 {
-       _impl->Export(fileName, fileType);
+  return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
 }