Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index cd5e4315cd56773fa48ff6a1f6752525ebadff1d..c819ce0977fd9f9dbd2d84577bd5bc146479e314 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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
@@ -103,7 +103,7 @@ class SMESH_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< SMESH_subMesh >
  */
 //=============================================================================
 
-SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
+SMESH_Mesh::SMESH_Mesh(int               theLocalId,
                        SMESH_Gen*        theGen,
                        bool              theIsEmbeddedMode,
                        SMESHDS_Document* theDocument):
@@ -112,15 +112,33 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
   if(MYDEBUG) MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
   _id            = theLocalId;
   _gen           = theGen;
-  _myDocument    = theDocument;
-  _myMeshDS      = theDocument->NewMesh(theIsEmbeddedMode,theLocalId);
+  _document    = theDocument;
+  _meshDS      = theDocument->NewMesh(theIsEmbeddedMode,theLocalId);
   _isShapeToMesh = false;
   _isAutoColor   = false;
   _isModified    = false;
   _shapeDiagonal = 0.0;
   _callUp        = NULL;
-  _myMeshDS->ShapeToMesh( PseudoShape() );
+  _meshDS->ShapeToMesh( PseudoShape() );
   _subMeshHolder = new SubMeshHolder;
+
+  // assure unique persistent ID
+  if ( _document->NbMeshes() > 1 )
+  {
+    std::set< int > ids;
+    for ( _document->InitMeshesIterator(); _document->MoreMesh(); )
+    {
+      SMESHDS_Mesh * meshDS =_document->NextMesh();
+      if ( meshDS != _meshDS )
+        ids.insert( meshDS->GetPersistentId() );
+    }
+
+    if ( ids.count( _meshDS->GetPersistentId() ))
+    {
+      int uniqueID = *ids.rbegin() + 1;
+      _meshDS->SetPersistentId( uniqueID );
+    }
+  }
 }
 
 //================================================================================
@@ -134,8 +152,8 @@ SMESH_Mesh::SMESH_Mesh():
   _groupId( 0 ),
   _nbSubShapes( 0 ),
   _isShapeToMesh( false ),
-  _myDocument( 0 ),
-  _myMeshDS( 0 ),
+  _document( 0 ),
+  _meshDS( 0 ),
   _gen( 0 ),
   _isAutoColor( false ),
   _isModified( false ),
@@ -176,9 +194,9 @@ SMESH_Mesh::~SMESH_Mesh()
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::~SMESH_Mesh");
 
-  if ( _myDocument ) // avoid destructing _myMeshDS from ~SMESH_Gen()
-    _myDocument->RemoveMesh( _id );
-  _myDocument = 0;
+  if ( _document ) // avoid destructing _meshDS from ~SMESH_Gen()
+    _document->RemoveMesh( _id );
+  _document = 0;
 
   // remove self from studyContext
   if ( _gen )
@@ -187,7 +205,7 @@ SMESH_Mesh::~SMESH_Mesh()
     studyContext->mapMesh.erase( _id );
   }
 
-  _myMeshDS->ClearMesh();
+  _meshDS->ClearMesh();
 
   // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study
   //   Notify event listeners at least that something happens
@@ -208,13 +226,13 @@ SMESH_Mesh::~SMESH_Mesh()
   if ( _callUp) delete _callUp;
   _callUp = 0;
 
-  if ( _myMeshDS ) {
-    // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
+  if ( _meshDS ) {
+    // delete _meshDS, in a thread in order not to block closing a study with large meshes
 #ifndef WIN32
-    boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS ));
+    boost::thread aThread(boost::bind( & deleteMeshDS, _meshDS ));
 #else
     pthread_t thread;
-    int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_myMeshDS);
+    int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS);
 #endif
   }
 }
@@ -227,7 +245,7 @@ SMESH_Mesh::~SMESH_Mesh()
 
 bool SMESH_Mesh::MeshExists( int meshId ) const
 {
-  return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false;
+  return _document ? bool( _document->GetMesh( meshId )) : false;
 }
 
 //================================================================================
@@ -262,11 +280,11 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
   if ( !aShape.IsNull() && _isShapeToMesh ) {
     if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change
-         _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
+         _meshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
       throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
   }
   // clear current data
-  if ( !_myMeshDS->ShapeToMesh().IsNull() )
+  if ( !_meshDS->ShapeToMesh().IsNull() )
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
@@ -275,7 +293,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
     std::map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
     while ( i_gr != _mapGroup.end() ) {
       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
-        _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
+        _meshDS->RemoveGroup( i_gr->second->GetGroupDS() );
         delete i_gr->second;
         _mapGroup.erase( i_gr++ );
       }
@@ -286,7 +304,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
     // clear SMESHDS
     TopoDS_Shape aNullShape;
-    _myMeshDS->ShapeToMesh( aNullShape );
+    _meshDS->ShapeToMesh( aNullShape );
 
     _shapeDiagonal = 0.0;
   }
@@ -294,9 +312,9 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
   // set a new geometry
   if ( !aShape.IsNull() )
   {
-    _myMeshDS->ShapeToMesh(aShape);
+    _meshDS->ShapeToMesh(aShape);
     _isShapeToMesh = true;
-    _nbSubShapes = _myMeshDS->MaxShapeIndex();
+    _nbSubShapes = _meshDS->MaxShapeIndex();
 
     // fill map of ancestors
     fillAncestorsMap(aShape);
@@ -305,7 +323,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
   {
     _isShapeToMesh = false;
     _shapeDiagonal = 0.0;
-    _myMeshDS->ShapeToMesh( PseudoShape() );
+    _meshDS->ShapeToMesh( PseudoShape() );
   }
   _isModified = false;
 }
@@ -318,7 +336,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
 TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
 {
-  return _myMeshDS->ShapeToMesh();
+  return _meshDS->ShapeToMesh();
 }
 
 //=======================================================================
@@ -411,7 +429,7 @@ void SMESH_Mesh::Clear()
   if ( HasShapeToMesh() ) // remove all nodes and elements
   {
     // clear mesh data
-    _myMeshDS->ClearMesh();
+    _meshDS->ClearMesh();
 
     // update compute state of submeshes
     if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
@@ -474,7 +492,7 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
   _isShapeToMesh = false;
 
   DriverUNV_R_SMDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
@@ -486,7 +504,7 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
   {
     SMDS_MeshGroup*   aGroup = gr2names->first;
     const std::string& aName = gr2names->second;
-    SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _myMeshDS, aGroup->GetType() );
+    SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _meshDS, aGroup->GetType() );
     aGroupDS->SMDSGroup() = std::move( *aGroup );
     aGroupDS->SetStoreName( aName.c_str() );
     AddGroup( aGroupDS );
@@ -507,7 +525,7 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
   _isShapeToMesh = false;
 
   DriverMED_R_SMESHDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetMeshId(-1);
   myReader.SetFile(theFileName);
   myReader.SetMeshName(theMeshName);
@@ -532,8 +550,8 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
     }
   }
 
-  _myMeshDS->Modified();
-  _myMeshDS->CompactMesh();
+  _meshDS->Modified();
+  _meshDS->CompactMesh();
 
   return (int) status;
 }
@@ -550,7 +568,7 @@ std::string SMESH_Mesh::STLToMesh(const char* theFileName)
   _isShapeToMesh = false;
 
   DriverSTL_R_SMDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
@@ -574,7 +592,7 @@ int SMESH_Mesh::CGNSToMesh(const char*  theFileName,
 #ifdef WITH_CGNS
 
   DriverCGNS_Read myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(theMeshIndex);
   res = myReader.Perform();
@@ -597,7 +615,7 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
                                             bool        theMakeRequiredGroups)
 {
   DriverGMF_Read myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMakeRequiredGroups( theMakeRequiredGroups );
   myReader.Perform();
@@ -618,9 +636,8 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
 SMESH_Hypothesis::Hypothesis_Status
 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
                           int                  anHypId,
-                          std::string*         anError  ) throw(SALOME_Exception)
+                          std::string*         anError  )
 {
-  Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
 
   if ( anError )
@@ -713,9 +730,8 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
 
 SMESH_Hypothesis::Hypothesis_Status
 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
-                             int                    anHypId) throw( SALOME_Exception )
+                             int                    anHypId)
 {
-  Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
 
   StudyContextStruct *sc = _gen->GetStudyContext();
@@ -784,9 +800,8 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
 
 const std::list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
-  return _myMeshDS->GetHypothesis(aSubShape);
+  return _meshDS->GetHypothesis(aSubShape);
 }
 
 //=======================================================================
@@ -829,7 +844,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh *   aSubM
 
   {
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-    const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
+    const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(aSubShape);
     std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
     for ( ; hyp != hypList.end(); hyp++ ) {
       const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
@@ -850,7 +865,7 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh *   aSubM
     for ( ; smIt != ancestors.end(); smIt++ )
     {
       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
-      const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
+      const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(curSh);
       std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
       for ( ; hyp != hypList.end(); hyp++ ) {
         const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
@@ -922,7 +937,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *                    aSubMesh,
   // get hypos from aSubShape
   {
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-    const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
+    const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
     {
       const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
@@ -951,7 +966,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *                    aSubMesh,
     for ( ; smIt != ancestors.end(); smIt++ )
     {
       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
-      const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
+      const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(curSh);
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
       {
         const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
@@ -993,10 +1008,9 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
  */
 //=============================================================================
 
-const std::list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
+const std::list<SMESHDS_Command*> & SMESH_Mesh::GetLog()
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetScript()->GetCommands();
+  return _meshDS->GetScript()->GetCommands();
 }
 
 //=============================================================================
@@ -1004,10 +1018,9 @@ const std::list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
  * 
  */
 //=============================================================================
-void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
+void SMESH_Mesh::ClearLog()
 {
-  Unexpect aCatch(SalomeException);
-  _myMeshDS->GetScript()->Clear();
+  _meshDS->GetScript()->Clear();
 }
 
 //=============================================================================
@@ -1017,9 +1030,8 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
 //=============================================================================
 
 SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
-  throw(SALOME_Exception)
 {
-  int index = _myMeshDS->ShapeToIndex(aSubShape);
+  int index = _meshDS->ShapeToIndex(aSubShape);
   if ( !index && aSubShape.IsNull() )
     return 0;
 
@@ -1029,10 +1041,10 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
     TopoDS_Iterator it( aSubShape );
     if ( it.More() )
     {
-      index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
+      index = _meshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
       // fill map of Ancestors
       while ( _nbSubShapes < index )
-        fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes ));
+        fillAncestorsMap( _meshDS->IndexToShape( ++_nbSubShapes ));
     }
   }
   // if ( !index )
@@ -1041,7 +1053,7 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
   SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index );
   if ( !aSubMesh )
   {
-    aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
+    aSubMesh = new SMESH_subMesh(index, this, _meshDS, aSubShape);
     _subMeshHolder->Add( index, aSubMesh );
 
     // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes
@@ -1070,9 +1082,8 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
 //=============================================================================
 
 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
-  int index = _myMeshDS->ShapeToIndex(aSubShape);
+  int index = _meshDS->ShapeToIndex(aSubShape);
   return GetSubMeshContaining( index );
 }
 
@@ -1084,10 +1095,8 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
 //=============================================================================
 
 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const
-throw(SALOME_Exception)
 {
   SMESH_subMesh *aSubMesh = _subMeshHolder->Get( aShapeID );
-
   return aSubMesh;
 }
 
@@ -1099,7 +1108,6 @@ throw(SALOME_Exception)
 
 std::list<SMESH_subMesh*>
 SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
   std::list<SMESH_subMesh*> found;
 
@@ -1165,7 +1173,7 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
   // algorithm parameter
   if (algo)
   {
-    // look trough hypotheses used by algo
+    // look through hypotheses used by algo
     const SMESH_HypoFilter* hypoKind;
     if (( hypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() ))) {
       std::list <const SMESHDS_Hypothesis * > usedHyps;
@@ -1184,16 +1192,15 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
 
 void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
 {
-  Unexpect aCatch(SalomeException);
 
   if ( !GetMeshDS()->IsUsedHypothesis( hyp ))
     return;
 
-  int nbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() );
+  smIdType nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() );
   if ( hyp && _callUp && !_callUp->IsLoaded() ) // for not loaded mesh (#16648)
   {
     _callUp->HypothesisModified( hyp->GetID(), /*updateIcons=*/true );
-    nbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() ); // after loading mesh
+    nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); // after loading mesh
   }
 
   SMESH_Algo *algo;
@@ -1263,7 +1270,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
   HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
   GetMeshDS()->Modified();
 
-  int newNbEntities = ( _myMeshDS->NbNodes() + _myMeshDS->NbElements() );
+  smIdType newNbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() );
   if ( hyp && _callUp )
     _callUp->HypothesisModified( hyp->GetID(), newNbEntities != nbEntities );
 }
@@ -1273,15 +1280,13 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
  *  Auto color functionality
  */
 //=============================================================================
-void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception)
+void SMESH_Mesh::SetAutoColor(bool theAutoColor)
 {
-  Unexpect aCatch(SalomeException);
   _isAutoColor = theAutoColor;
 }
 
-bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception)
+bool SMESH_Mesh::GetAutoColor()
 {
-  Unexpect aCatch(SalomeException);
   return _isAutoColor;
 }
 
@@ -1400,72 +1405,47 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 
 //================================================================================
 /*!
- * \brief Export the mesh to a med file
- *  \param [in] file - name of the MED file
- *  \param [in] theMeshName - name of this mesh
- *  \param [in] theAutoGroups - boolean parameter for creating/not creating
- *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
- *              the typical use is auto_groups=false.
- *  \param [in] theMinor - define the minor version (y, where version is x.y.z) of MED file format.
- *              The theMinor must be between 0 and the current minor version of MED file library.
- *              If theMinor is equal to -1, the minor version is not changed (default).
- *              The major version (x, where version is x.y.z) cannot be changed.
- *  \param [in] meshPart - mesh data to export
- *  \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either
- *              - 1D if all mesh nodes lie on OX coordinate axis, or
- *              - 2D if all mesh nodes lie on XOY coordinate plane, or
- *              - 3D in the rest cases.
- *              If \a theAutoDimension is \c false, the space dimension is always 3.
- *  \param [in] theAddODOnVertices - to create 0D elements on all vertices
- *  \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413)
- *  \param [in] ZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero
- *              within a given tolerance, the coordinate is set to zero.
- *              If \a ZTolerance is negative, the node coordinates are kept as is.
- *  \return int - mesh index in the file
+ * \brief Export the mesh to a writer
  */
 //================================================================================
 
-void SMESH_Mesh::ExportMED(const char *        file,
-                           const char*         theMeshName,
-                           bool                theAutoGroups,
-                           int                 theVersion,
-                           const SMESHDS_Mesh* meshPart,
-                           bool                theAutoDimension,
-                           bool                theAddODOnVertices,
-                           double              theZTolerance,
-                           bool                theAllElemsToGroup)
-throw(SALOME_Exception)
+void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter,
+                                  const char*               theMeshName,
+                                  bool                      theAutoGroups,
+                                  const SMESHDS_Mesh*       theMeshPart,
+                                  bool                      theAutoDimension,
+                                  bool                      theAddODOnVertices,
+                                  double                    theZTolerance,
+                                  bool                      theSaveNumbers)
 {
-  MESSAGE("MED_VERSION:"<< theVersion);
+  Driver_Mesh::Status status = Driver_Mesh::DRS_OK;
+
   SMESH_TRY;
 
-  DriverMED_W_SMESHDS_Mesh myWriter;
-  myWriter.SetFile         ( file , theVersion);
-  myWriter.SetMesh         ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
-  myWriter.SetAutoDimension( theAutoDimension );
-  myWriter.AddODOnVertices ( theAddODOnVertices );
-  myWriter.SetZTolerance   ( theZTolerance );
+  theWriter.SetMesh         ( theMeshPart ? (SMESHDS_Mesh*) theMeshPart : _meshDS   );
+  theWriter.SetAutoDimension( theAutoDimension );
+  theWriter.AddODOnVertices ( theAddODOnVertices );
+  theWriter.SetZTolerance   ( theZTolerance );
+  theWriter.SetSaveNumbers  ( theSaveNumbers );
   if ( !theMeshName )
-    myWriter.SetMeshId     ( _id         );
+    theWriter.SetMeshId     ( _id         );
   else {
-    myWriter.SetMeshId     ( -1          );
-    myWriter.SetMeshName   ( theMeshName );
+    theWriter.SetMeshId     ( -1          );
+    theWriter.SetMeshName   ( theMeshName );
   }
 
   if ( theAutoGroups ) {
-    myWriter.AddGroupOfNodes();
-    myWriter.AddGroupOfEdges();
-    myWriter.AddGroupOfFaces();
-    myWriter.AddGroupOfVolumes();
-    myWriter.AddGroupOf0DElems();
-    myWriter.AddGroupOfBalls();
+    theWriter.AddGroupOfNodes();
+    theWriter.AddGroupOfEdges();
+    theWriter.AddGroupOfFaces();
+    theWriter.AddGroupOfVolumes();
+    theWriter.AddGroupOf0DElems();
+    theWriter.AddGroupOfBalls();
   }
-  if ( theAllElemsToGroup )
-    myWriter.AddAllToGroup();
 
   // Pass groups to writer. Provide unique group names.
   //set<string> aGroupNames; // Corrected for Mantis issue 0020028
-  if ( !meshPart )
+  if ( !theMeshPart )
   {
     std::map< SMDSAbs_ElementType, std::set<std::string> > aGroupNames;
     char aString [256];
@@ -1486,60 +1466,79 @@ throw(SALOME_Exception)
           aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
         }
         aGroupDS->SetStoreName( aGroupName.c_str() );
-        myWriter.AddGroup( aGroupDS );
+        theWriter.AddGroup( aGroupDS );
       }
     }
   }
   // Perform export
-  myWriter.Perform();
+  status = theWriter.Perform();
 
   SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("MED");
 }
 
 //================================================================================
 /*!
- * \brief Export the mesh to a SAUV file
+ * Same as SMESH_Mesh::ExportMED except for \a file and \a theVersion
  */
 //================================================================================
 
-void SMESH_Mesh::ExportSAUV(const char *file, 
-                            const char* theMeshName, 
-                            bool theAutoGroups)
-  throw(SALOME_Exception)
+MEDCoupling::MCAuto<MEDCoupling::DataArrayByte>
+SMESH_Mesh::ExportMEDCoupling(const char*         theMeshName,
+                              bool                theAutoGroups,
+                              const SMESHDS_Mesh* theMeshPart,
+                              bool                theAutoDimension,
+                              bool                theAddODOnVertices,
+                              double              theZTolerance,
+                              bool                theSaveNumbers)
 {
-  std::string medfilename(file);
-  medfilename += ".med";
-  std::string cmd;
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python3 ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-  ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, /*minor=*/-1,
-            /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false,
-            /*zTol=*/-1, /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python3 ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python3 ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
+  DriverMED_W_SMESHDS_Mesh_Mem writer;
+  this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension,
+                          theAddODOnVertices, theZTolerance, theSaveNumbers);
+  return writer.getData();
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to a med file
+ *  \param [in] theFile - name of the MED file
+ *  \param [in] theMeshName - name of this mesh
+ *  \param [in] theAutoGroups - boolean parameter for creating/not creating
+ *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
+ *              the typical use is auto_groups=false.
+ *  \param [in] theVersion - define the minor (xy, where version is x.y.z) of MED file format.
+ *              If theVersion is equal to -1, the minor version is not changed (default).
+ *  \param [in] theMeshPart - mesh data to export
+ *  \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either
+ *              - 1D if all mesh nodes lie on OX coordinate axis, or
+ *              - 2D if all mesh nodes lie on XOY coordinate plane, or
+ *              - 3D in the rest cases.
+ *              If \a theAutoDimension is \c false, the space dimension is always 3.
+ *  \param [in] theAddODOnVertices - to create 0D elements on all vertices
+ *  \param [in] theZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero
+ *              within a given tolerance, the coordinate is set to zero.
+ *              If \a ZTolerance is negative, the node coordinates are kept as is.
+ *  \param [in] theSaveNumbers : enable saving numbers of nodes and cells.
+ *  \return int - mesh index in the file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportMED(const char *        theFile,
+                           const char*         theMeshName,
+                           bool                theAutoGroups,
+                           int                 theVersion,
+                           const SMESHDS_Mesh* theMeshPart,
+                           bool                theAutoDimension,
+                           bool                theAddODOnVertices,
+                           double              theZTolerance,
+                           bool                theSaveNumbers)
+{
+  MESSAGE("MED_VERSION:"<< theVersion);
+  DriverMED_W_SMESHDS_Mesh writer;
+  writer.SetFile( theFile, theVersion );
+  this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, theAddODOnVertices, theZTolerance, theSaveNumbers );
 }
 
 //================================================================================
@@ -1549,14 +1548,23 @@ void SMESH_Mesh::ExportSAUV(const char *file,
 //================================================================================
 
 void SMESH_Mesh::ExportDAT(const char *        file,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart,
+                           const bool          renumber)
 {
-  Unexpect aCatch(SalomeException);
-  DriverDAT_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
-  myWriter.SetMeshId(_id);
-  myWriter.Perform();
+  Driver_Mesh::Status status;
+  SMESH_TRY;
+
+  DriverDAT_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS );
+  writer.SetMeshId(_id);
+  writer.SetRenumber( renumber );
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("DAT");
 }
 
 //================================================================================
@@ -1566,14 +1574,17 @@ void SMESH_Mesh::ExportDAT(const char *        file,
 //================================================================================
 
 void SMESH_Mesh::ExportUNV(const char *        file,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart,
+                           const bool          renumber)
 {
-  Unexpect aCatch(SalomeException);
-  DriverUNV_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
-  myWriter.SetMeshId(_id);
-  //  myWriter.SetGroups(_mapGroup);
+  Driver_Mesh::Status status;
+
+  SMESH_TRY;
+  DriverUNV_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS );
+  writer.SetMeshId(_id);
+  writer.SetRenumber( renumber );
 
   // pass group names to SMESHDS
   if ( !meshPart )
@@ -1585,11 +1596,16 @@ void SMESH_Mesh::ExportUNV(const char *        file,
       if ( aGroupDS ) {
         std::string aGroupName = aGroup->GetName();
         aGroupDS->SetStoreName( aGroupName.c_str() );
-        myWriter.AddGroup( aGroupDS );
+        writer.AddGroup( aGroupDS );
       }
     }
   }
-  myWriter.Perform();
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("UNV");
 }
 
 //================================================================================
@@ -1601,16 +1617,23 @@ void SMESH_Mesh::ExportUNV(const char *        file,
 void SMESH_Mesh::ExportSTL(const char *        file,
                            const bool          isascii,
                            const char *        name,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart)
 {
-  Unexpect aCatch(SalomeException);
-  DriverSTL_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetIsAscii( isascii );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
-  myWriter.SetMeshId(_id);
-  if ( name ) myWriter.SetName( name );
-  myWriter.Perform();
+  Driver_Mesh::Status status;
+  SMESH_TRY;
+
+  DriverSTL_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetIsAscii( isascii );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS);
+  writer.SetMeshId(_id);
+  if ( name ) writer.SetName( name );
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("STL");
 }
 
 //================================================================================
@@ -1624,7 +1647,9 @@ void SMESH_Mesh::ExportCGNS(const char *        file,
                             const char *        meshName,
                             const bool          groupElemsByType)
 {
+
   int res = Driver_Mesh::DRS_FAIL;
+  SMESH_TRY;
 
   // pass group names to SMESHDS
   std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
@@ -1638,22 +1663,27 @@ void SMESH_Mesh::ExportCGNS(const char *        file,
   }
 #ifdef WITH_CGNS
 
-  DriverCGNS_Write myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
-  myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+  DriverCGNS_Write writer;
+  writer.SetFile( file );
+  writer.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+  writer.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
   if ( meshName && meshName[0] )
-    myWriter.SetMeshName( meshName );
-  myWriter.SetElementsByType( groupElemsByType );
-  res = myWriter.Perform();
+    writer.SetMeshName( meshName );
+  writer.SetElementsByType( groupElemsByType );
+  res = writer.Perform();
   if ( res != Driver_Mesh::DRS_OK )
   {
-    SMESH_ComputeErrorPtr err = myWriter.GetError();
+    SMESH_ComputeErrorPtr err = writer.GetError();
     if ( err && !err->IsOK() && !err->myComment.empty() )
       throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() );
   }
 
 #endif
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( res == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("CGNS");
+
   if ( res != Driver_Mesh::DRS_OK )
     throw SALOME_Exception("Export failed");
 }
@@ -1668,12 +1698,20 @@ void SMESH_Mesh::ExportGMF(const char *        file,
                            const SMESHDS_Mesh* meshDS,
                            bool                withRequiredGroups)
 {
-  DriverGMF_Write myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
-  myWriter.SetExportRequiredGroups( withRequiredGroups );
+  Driver_Mesh::Status status;
+  SMESH_TRY;
 
-  myWriter.Perform();
+  DriverGMF_Write writer;
+  writer.SetFile( file );
+  writer.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+  writer.SetExportRequiredGroups( withRequiredGroups );
+
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("GMF");
 }
 
 //================================================================================
@@ -1756,10 +1794,9 @@ double SMESH_Mesh::GetComputeProgress() const
  */
 //================================================================================
 
-int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbNodes() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->NbNodes();
+  return _meshDS->NbNodes();
 }
 
 //================================================================================
@@ -1768,10 +1805,9 @@ int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::Nb0DElements() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().Nb0DElements();
+  return _meshDS->GetMeshInfo().Nb0DElements();
 }
 
 //================================================================================
@@ -1780,10 +1816,9 @@ int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbEdges(order);
+  return _meshDS->GetMeshInfo().NbEdges(order);
 }
 
 //================================================================================
@@ -1792,10 +1827,9 @@ int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbFaces(order);
+  return _meshDS->GetMeshInfo().NbFaces(order);
 }
 
 //================================================================================
@@ -1804,10 +1838,9 @@ int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTriangles(order);
+  return _meshDS->GetMeshInfo().NbTriangles(order);
 }
 
 //================================================================================
@@ -1816,10 +1849,9 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Excep
  */
 //================================================================================
 
-int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBiQuadTriangles() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBiQuadTriangles();
+  return _meshDS->GetMeshInfo().NbBiQuadTriangles();
 }
 
 //================================================================================
@@ -1828,10 +1860,9 @@ int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
+  return _meshDS->GetMeshInfo().NbQuadrangles(order);
 }
 
 //================================================================================
@@ -1840,10 +1871,9 @@ int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exc
  */
 //================================================================================
 
-int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBiQuadQuadrangles() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles();
+  return _meshDS->GetMeshInfo().NbBiQuadQuadrangles();
 }
 
 //================================================================================
@@ -1852,10 +1882,9 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolygons(order);
+  return _meshDS->GetMeshInfo().NbPolygons(order);
 }
 
 //================================================================================
@@ -1864,10 +1893,9 @@ int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Except
  */
 //================================================================================
 
-int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbVolumes(order);
+  return _meshDS->GetMeshInfo().NbVolumes(order);
 }
 
 //================================================================================
@@ -1876,10 +1904,9 @@ int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Excepti
  */
 //================================================================================
 
-int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTetras(order);
+  return _meshDS->GetMeshInfo().NbTetras(order);
 }
 
 //================================================================================
@@ -1888,10 +1915,9 @@ int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exceptio
  */
 //================================================================================
 
-int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbHexas(order);
+  return _meshDS->GetMeshInfo().NbHexas(order);
 }
 
 //================================================================================
@@ -1900,10 +1926,9 @@ int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTriQuadraticHexas() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTriQuadHexas();
+  return _meshDS->GetMeshInfo().NbTriQuadHexas();
 }
 
 //================================================================================
@@ -1912,10 +1937,9 @@ int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPyramids(order);
+  return _meshDS->GetMeshInfo().NbPyramids(order);
 }
 
 //================================================================================
@@ -1924,22 +1948,19 @@ int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Except
  */
 //================================================================================
 
-int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPrisms(order);
+  return _meshDS->GetMeshInfo().NbPrisms(order);
 }
 
-int SMESH_Mesh::NbQuadPrisms() const throw (SALOME_Exception)
+smIdType SMESH_Mesh::NbQuadPrisms() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbQuadPrisms();
+  return _meshDS->GetMeshInfo().NbQuadPrisms();
 }
 
-int SMESH_Mesh::NbBiQuadPrisms() const throw (SALOME_Exception)
+smIdType SMESH_Mesh::NbBiQuadPrisms() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBiQuadPrisms();
+  return _meshDS->GetMeshInfo().NbBiQuadPrisms();
 }
 
 
@@ -1949,10 +1970,9 @@ int SMESH_Mesh::NbBiQuadPrisms() const throw (SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbHexagonalPrisms() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbHexPrisms();
+  return _meshDS->GetMeshInfo().NbHexPrisms();
 }
 
 //================================================================================
@@ -1961,10 +1981,9 @@ int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPolyhedrons() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolyhedrons();
+  return _meshDS->GetMeshInfo().NbPolyhedrons();
 }
 
 //================================================================================
@@ -1973,10 +1992,9 @@ int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbBalls() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBalls() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBalls();
+  return _meshDS->GetMeshInfo().NbBalls();
 }
 
 //================================================================================
@@ -1985,10 +2003,9 @@ int SMESH_Mesh::NbBalls() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbSubMesh() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->NbSubMesh();
+  return _meshDS->NbSubMesh();
 }
 
 //================================================================================
@@ -2000,7 +2017,7 @@ int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
 
 int SMESH_Mesh::NbMeshes() const // nb meshes in the Study
 {
-  return _myDocument->NbMeshes();
+  return _document->NbMeshes();
 }
 
 //=======================================================================
@@ -2013,7 +2030,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const
   if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
 
   static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
-  return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
+  return GetHypothesis( _meshDS->ShapeToMesh(), filter, false );
 }
 
 //=======================================================================
@@ -2023,7 +2040,17 @@ bool SMESH_Mesh::IsNotConformAllowed() const
 
 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
 {
-  return theShape.IsSame(_myMeshDS->ShapeToMesh() );
+  return theShape.IsSame(_meshDS->ShapeToMesh() );
+}
+
+//=======================================================================
+//function : GetShapeByEntry
+//purpose  : return TopoDS_Shape by its study entry
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeByEntry(const std::string& entry) const
+{
+  return _callUp ? _callUp->GetShapeByEntry( entry ) : TopoDS_Shape();
 }
 
 //=============================================================================
@@ -2054,7 +2081,7 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
  */
 //================================================================================
 
-SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exception)
+SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS)
 {
   if ( !groupDS )
     throw SALOME_Exception(LOCALIZED ("SMESH_Mesh::AddGroup(): NULL SMESHDS_GroupBase"));
@@ -2088,7 +2115,7 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce
 bool SMESH_Mesh::SynchronizeGroups()
 {
   const size_t                            nbGroups = _mapGroup.size();
-  const std::set<SMESHDS_GroupBase*>&       groups = _myMeshDS->GetGroups();
+  const std::set<SMESHDS_GroupBase*>&       groups = _meshDS->GetGroups();
   std::set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
   for ( ; gIt != groups.end(); ++gIt )
   {
@@ -2215,13 +2242,13 @@ ostream& SMESH_Mesh::Dump(ostream& save)
     save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
     save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
     if ( NbFaces(order) > 0 ) {
-      int nb3 = NbTriangles(order);
-      int nb4 = NbQuadrangles(order);
+      smIdType nb3 = NbTriangles(order);
+      smIdType nb4 = NbQuadrangles(order);
       save << clause << ".1) Number of " << orderStr << " triangles:  \t" << nb3 << endl;
       save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
       if ( nb3 + nb4 !=  NbFaces(order) ) {
         std::map<int,int> myFaceMap;
-        SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
+        SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator();
         while( itFaces->more( ) ) {
           int nbNodes = itFaces->next()->NbNodes();
           if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
@@ -2236,17 +2263,17 @@ ostream& SMESH_Mesh::Dump(ostream& save)
     }
     save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
     if ( NbVolumes(order) > 0 ) {
-      int nb8 = NbHexas(order);
-      int nb4 = NbTetras(order);
-      int nb5 = NbPyramids(order);
-      int nb6 = NbPrisms(order);
+      smIdType nb8 = NbHexas(order);
+      smIdType nb4 = NbTetras(order);
+      smIdType nb5 = NbPyramids(order);
+      smIdType nb6 = NbPrisms(order);
       save << clause << ".1) Number of " << orderStr << " hexahedrons: \t" << nb8 << endl;
       save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
       save << clause << ".4) Number of " << orderStr << " pyramids:    \t" << nb5 << endl;
       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
         std::map<int,int> myVolumesMap;
-        SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
+        SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator();
         while( itVolumes->more( ) ) {
           int nbNodes = itVolumes->next()->NbNodes();
           if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
@@ -2270,9 +2297,9 @@ ostream& SMESH_Mesh::Dump(ostream& save)
 //purpose  : Returns type of mesh element with certain id
 //=======================================================================
 
-SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
+SMDSAbs_ElementType SMESH_Mesh::GetElementType( const smIdType id, const bool iselem )
 {
-  return _myMeshDS->GetElementType( id, iselem );
+  return _meshDS->GetElementType( id, iselem );
 }
 
 //=============================================================================
@@ -2323,7 +2350,7 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
 
 void SMESH_Mesh::ClearMeshOrder()
 {
-  _mySubMeshOrder.clear();
+  _subMeshOrder.clear();
 }
 
 //=============================================================================
@@ -2334,7 +2361,7 @@ void SMESH_Mesh::ClearMeshOrder()
 
 void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
 {
-  _mySubMeshOrder = theOrder;
+  _subMeshOrder = theOrder;
 }
 
 //=============================================================================
@@ -2345,7 +2372,7 @@ void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
 
 const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const
 {
-  return _mySubMeshOrder;
+  return _subMeshOrder;
 }
 
 //=============================================================================
@@ -2406,19 +2433,20 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
 
 bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
 {
-  if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
+  if ( _subMeshOrder.empty() || theListToSort.size() < 2 )
     return true;
-  
-  bool res = false;
-  std::vector<SMESH_subMesh*> onlyOrderedList, smVec;
 
-  // collect all ordered submeshes in one list as pointers
+
+  // collect all ordered sub-meshes in smVec as pointers
   // and get their positions within theListToSort
+
+  std::vector<SMESH_subMesh*> smVec;
   typedef std::vector<SMESH_subMesh*>::iterator TPosInList;
-  std::map< int, TPosInList > sortedPos;
+  std::map< size_t, size_t > sortedPos; // index in theListToSort to order
   TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
-  TListOfListOfInt::const_iterator      listIdsIt = _mySubMeshOrder.begin();
-  for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
+  TListOfListOfInt::const_iterator      listIdsIt = _subMeshOrder.begin();
+  bool needSort = false;
+  for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
     // convert sm ids to sm's
@@ -2431,6 +2459,7 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
         smVec.push_back( sm );
         if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->IsComplexSubmesh() )
         {
+          smVec.reserve( smVec.size() + sm->GetSubMeshDS()->NbSubMeshes() );
           SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator();
           while ( smdsIt->more() )
           {
@@ -2444,27 +2473,46 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
     // find smVec items in theListToSort
     for ( size_t i = 0; i < smVec.size(); ++i )
     {
-      TPosInList smPos = find( smBeg, smEnd, smVec[i] );
-      if ( smPos != smEnd ) {
-        sortedPos[ std::distance( smBeg, smPos )] = smPos;
-        if ( sortedPos.size() > onlyOrderedList.size() )
-          onlyOrderedList.push_back( smVec[i] );
+      TPosInList smPos = find( smBeg, smEnd, smVec[i] ); // position in theListToSort
+      if ( smPos != smEnd )
+      {
+        size_t posInList = std::distance( smBeg, smPos );
+        size_t     order = sortedPos.size();
+        sortedPos.insert( std::make_pair( posInList, order ));
+        if ( posInList != order )
+          needSort = true;
       }
     }
   }
-  if (onlyOrderedList.size() < 2)
-    return res;
-  res = true;
+  if ( ! needSort )
+    return false;
 
-  std::vector<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
-  std::vector<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
+  // set sm of sortedPos from theListToSort to front of orderedSM
+  // and the rest of theListToSort to orderedSM end
 
-  // iterate on ordered sub-meshes and insert them in detected positions
-  std::map< int, TPosInList >::iterator i_pos = sortedPos.begin();
-  for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
-    *(i_pos->second) = *onlyBIt;
+  std::vector<SMESH_subMesh*> orderedSM;
+  orderedSM.reserve( theListToSort.size() );
+  orderedSM.resize( sortedPos.size() );
 
-  return res;
+  size_t iPrev = 0;
+  sortedPos.insert( std::make_pair( theListToSort.size(), sortedPos.size() ));
+  for ( const auto & pos_order : sortedPos )
+  {
+    const size_t& posInList = pos_order.first;
+    const size_t&     order = pos_order.second;
+    if ( order < sortedPos.size() - 1 )
+      orderedSM[ order ] = theListToSort[ posInList ];
+
+    if ( iPrev < posInList )
+      orderedSM.insert( orderedSM.end(),
+                        theListToSort.begin() + iPrev,
+                        theListToSort.begin() + posInList );
+    iPrev = posInList + 1;
+  }
+
+  theListToSort.swap( orderedSM );
+
+  return true;
 }
 
 //================================================================================
@@ -2476,8 +2524,8 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
 bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore,
                             const SMESH_subMesh* smAfter ) const
 {
-  TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin();
-  for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
+  TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin();
+  for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
     int iB = -1, iA = -1, i = 0;