Salome HOME
Debug
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index dffb7c5a09fddc34bb50c6ace677db46018b532e..a74ddb487b39cf2b97b4f26000a0d6a1567304b4 100644 (file)
@@ -37,6 +37,7 @@
 #include "DriverMED_R_SMESHDS_Mesh.h"
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "SMDS_VolumeTool.hxx"
+#include "SMDS_ElemIterator.hxx"
 #include "SMESHDS_Command.hxx"
 #include "SMESHDS_CommandType.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
@@ -64,6 +65,7 @@
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Compound.hxx>
 
@@ -93,9 +95,10 @@ int SMESH_Mesh_i::myIdGenerator = 0;
 //=============================================================================
 
 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
-                           SMESH_Gen_i*            gen_i,
-                           CORBA::Long studyId )
-: SALOME::GenericObj_i( thePOA )
+                            SMESH_Gen_i*            gen_i,
+                            CORBA::Long             studyId,
+                            SALOME::Notebook_ptr    theNotebook )
+: SALOME_ParameterizedObject( theNotebook )
 {
   MESSAGE("SMESH_Mesh_i");
   _impl = NULL;
@@ -203,6 +206,7 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
   Unexpect aCatch(SALOME_SalomeException);
   try {
     _impl->Clear();
+    CheckGeomGroupModif(); // issue 20145
   }
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
@@ -414,9 +418,11 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubS
   Unexpect aCatch(SALOME_SalomeException);
   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
 
-  if ( !SMESH_Hypothesis::IsStatusFatal(status) )
+  if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
     _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
                                  aSubShapeObject, anHyp );
+    StoreDependencies( GetNotebook() );
+  }
 
   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
 
@@ -519,41 +525,40 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
  */
 //=============================================================================
 
-SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
-                                 SMESH::SMESH_Hypothesis_ptr anHyp)
+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)
+  if(MYDEBUG) MESSAGE("removeHypothesis()");
+  // **** proposer liste de subShape (selection multiple)
 
-       if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
-               THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                       SALOME::BAD_PARAM);
+  if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
+    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::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;
+    //use PseudoShape in case if mesh has no shape
+    if(HasShapeToMesh())
+      myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
+    else
+      myLocSubShape = _impl->GetShapeToMesh();
 
-       SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
-       try
-       {
-                TopoDS_Shape myLocSubShape;
-                //use PseudoShape in case if mesh has no shape
-                if(HasShapeToMesh())
-                  myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
-                else
-                  myLocSubShape = _impl->GetShapeToMesh();
-                
-                int hypId = myHyp->GetId();
-               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 status;
+    int hypId = myHyp->GetId();
+    status = _impl->RemoveHypothesis(myLocSubShape, hypId);
+//     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
+//       _mapHypo.erase( hypId );
+  }
+  catch(SALOME_Exception & S_ex)
+  {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return status;
 }
 
 //=============================================================================
@@ -563,14 +568,13 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Ob
 //=============================================================================
 
 SMESH::ListOfHypothesis *
-       SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
+        SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
 throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if (MYDEBUG) MESSAGE("GetHypothesisList");
   if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
-    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                                SALOME::BAD_PARAM);
+    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
 
   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
 
@@ -585,7 +589,7 @@ throw(SALOME::SALOME_Exception)
     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[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
     }
 
     aList->length( i );
@@ -603,14 +607,14 @@ throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
-                                                 const char*           theName )
+                                                  const char*           theName )
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   MESSAGE("SMESH_Mesh_i::GetSubMesh");
   if (CORBA::is_nil(aSubShapeObject))
     THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                                SALOME::BAD_PARAM);
+                                 SALOME::BAD_PARAM);
 
   SMESH::SMESH_subMesh_var subMesh;
   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
@@ -664,7 +668,10 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
       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() );
+        aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
+
+//       if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
+//         aSubShapeObject = theSubMesh->GetSubShape();
 
       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
 
@@ -1572,7 +1579,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
     CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
     if ( CORBA::is_nil( groupObj )) return newShape;
     GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
-    
+
     // get indices of group items
     set<int> curIndices;
     GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
@@ -1598,13 +1605,24 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
   if ( newShape.IsNull() ) {
     // geom group becomes empty - return empty compound
     TopoDS_Compound compound;
-    BRep_Builder    builder;
-    builder.MakeCompound(compound);
+    BRep_Builder().MakeCompound(compound);
     newShape = compound;
   }
   return newShape;
 }
 
+namespace {
+  //=============================================================================
+  /*!
+   * \brief Storage of shape and index used in CheckGeomGroupModif()
+   */
+  //=============================================================================
+  struct TIndexedShape {
+    int          _index;
+    TopoDS_Shape _shape;
+    TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
+  };
+}
 //=============================================================================
 /*!
  * \brief Update objects depending on changed geom groups
@@ -1643,19 +1661,12 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
 
     if ( processedGroup ) { // update group indices
       list<TGeomGroupData>::iterator data2 = data;
-      for ( --data2; data2->_groupEntry != data->_groupEntry; --data2)
-        data->_indices = data2->_indices;
+      for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
+      data->_indices = data2->_indices;
     }
 
     // Update SMESH objects according to new GEOM group contents
 
-    SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
-    if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
-    {
-      // TODO
-      continue;
-    }
-
     SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
     if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
     {
@@ -1699,7 +1710,129 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
       }
       continue;
     }
-  }
+
+    SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
+    if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
+    {
+      // Remove groups and submeshes basing on removed sub-shapes
+
+      TopTools_MapOfShape newShapeMap;
+      TopoDS_Iterator shapeIt( newShape );
+      for ( ; shapeIt.More(); shapeIt.Next() )
+        newShapeMap.Add( shapeIt.Value() );
+
+      SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
+      for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
+      {
+        if ( newShapeMap.Contains( shapeIt.Value() ))
+          continue;
+        TopTools_IndexedMapOfShape oldShapeMap;
+        TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
+        for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
+        {
+          const TopoDS_Shape& oldShape = oldShapeMap(i);
+          int oldInd = meshDS->ShapeToIndex( oldShape );
+          // -- submeshes --
+          map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
+          if ( i_smIor != _mapSubMeshIor.end() ) {
+            RemoveSubMesh( i_smIor->second ); // one submesh per shape index
+          }
+          // --- groups ---
+          map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
+          for ( ; i_grp != _mapGroups.end(); ++i_grp )
+          {
+            // check if a group bases on oldInd shape
+            SMESHDS_GroupOnGeom* grpOnGeom = 0;
+            if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
+              grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
+            if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
+            { // remove
+              RemoveGroup( i_grp->second ); // several groups can base on same shape
+              i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
+            }
+          }
+        }
+      }
+      // Reassign hypotheses and update groups after setting the new shape to mesh
+
+      // collect anassigned hypotheses
+      typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
+      list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
+      TShapeHypList assignedHyps;
+      for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
+      {
+        const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
+        list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
+        if ( !hyps.empty() ) {
+          assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
+          for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
+            _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
+        }
+      }
+      // collect shapes supporting groups
+      typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
+      TShapeTypeList groupData;
+      const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
+      set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+      for ( ; grIt != groups.end(); ++grIt )
+      {
+        if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
+          groupData.push_back
+            ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
+      }
+      // set new shape to mesh -> DS of submeshes and geom groups is deleted
+      _impl->ShapeToMesh( newShape );
+      
+      // reassign hypotheses
+      TShapeHypList::iterator indS_hyps = assignedHyps.begin();
+      for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
+      {
+        TIndexedShape&                   geom = indS_hyps->first;
+        list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
+        int oldID = geom._index;
+        int newID = meshDS->ShapeToIndex( geom._shape );
+        if ( !newID )
+          continue;
+        if ( oldID == 1 ) { // main shape
+          newID = 1;
+          geom._shape = newShape;
+        }
+        for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
+          _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
+        // care of submeshes
+        SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
+        if ( newID != oldID ) {
+          _mapSubMesh   [ newID ] = newSubmesh;
+          _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
+          _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
+          _mapSubMesh.   erase(oldID);
+          _mapSubMesh_i. erase(oldID);
+          _mapSubMeshIor.erase(oldID);
+          _mapSubMesh_i [ newID ]->changeLocalId( newID );
+        }
+      }
+      // recreate groups
+      TShapeTypeList::iterator geomType = groupData.begin();
+      for ( ; geomType != groupData.end(); ++geomType )
+      {
+        const TIndexedShape& geom = geomType->first;
+        int oldID = geom._index;
+        if ( _mapGroups.find( oldID ) == _mapGroups.end() )
+          continue;
+        // get group name
+        SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
+        CORBA::String_var     name    = groupSO->GetName();
+        // update
+        SMESH_GroupBase_i* group_i    = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
+        int newID;
+        if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
+          group_i->changeLocalId( newID );
+      }
+
+      break; // everything has been updated
+
+    } // update mesh
+  } // loop on group data
 
   // Update icons
 
@@ -1847,20 +1980,37 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
 {
   MESSAGE("SMESH_Mesh_i::removeSubMesh()");
-  if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
+  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] );
+  if ( theSubShapeObject->_is_nil() )  // not published shape (IPAL13617)
+  {
+    CORBA::Long shapeId = theSubMesh->GetId();
+    if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
+    {
+      TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
+      if ( !S.IsNull() )
+      {
+        list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
+        list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
+        for ( ; hyp != hyps.end(); ++hyp )
+          _impl->RemoveHypothesis(S, (*hyp)->GetID());
+      }
     }
   }
-  catch( const SALOME::SALOME_Exception& ) {
-    INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
+  else
+  {
+    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!");
+    }
+    removeGeomGroupData( theSubShapeObject );
   }
-  removeGeomGroupData( theSubShapeObject );
-
   int subMeshId = theSubMesh->GetId();
 
   _mapSubMesh.erase(subMeshId);
@@ -1967,14 +2117,14 @@ throw(SALOME::SALOME_Exception)
       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++;
+        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++;
+        aLog[indexLog].indexes[i] = *ii;
+        //MESSAGE(" "<<i<<" "<<ii.Value());
+        ii++;
       }
       indexLog++;
       its++;
@@ -1998,7 +2148,7 @@ throw(SALOME::SALOME_Exception)
 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
-  // ****
+  _impl->ClearLog();
 }
 
 //=============================================================================
@@ -2155,8 +2305,8 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file)
 }
 
 void SMESH_Mesh_i::ExportToMED (const char* file,
-                               CORBA::Boolean auto_groups,
-                               SMESH::MED_VERSION theVersion)
+                                CORBA::Boolean auto_groups,
+                                SMESH::MED_VERSION theVersion)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -2171,20 +2321,20 @@ void SMESH_Mesh_i::ExportToMED (const char* file,
       aMeshName = aMeshSO->GetName();
       // 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());
+        {
+        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");
-       }
+        }
     }
   }
   // Update Python script
@@ -2201,7 +2351,7 @@ void SMESH_Mesh_i::ExportToMED (const char* file,
 }
 
 void SMESH_Mesh_i::ExportMED (const char* file,
-                             CORBA::Boolean auto_groups)
+                              CORBA::Boolean auto_groups)
   throw(SALOME::SALOME_Exception)
 {
   ExportToMED(file,auto_groups,SMESH::MED_V2_1);
@@ -2285,7 +2435,18 @@ CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return NbEdges() + NbFaces() + NbVolumes();
+  return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->Nb0DElements();
 }
 
 //=============================================================================
@@ -3220,15 +3381,72 @@ void SMESH_Mesh_i::checkGroupNames()
   }
 }
 
+//=============================================================================
+/*!
+ * \brief Get internal entry of mesh
+ */
+//=============================================================================
+char* SMESH_Mesh_i::GetEntry()
+{
+  int anId = 0;
+  SALOME::Notebook_ptr aNotebook = GetNotebook();
+  if( !CORBA::is_nil( aNotebook ) )
+  {
+    SALOMEDS::Study_ptr aStudy = aNotebook->GetStudy();
+    if( StudyContext* aStudyContext = GetGen()->GetStudyContext( aStudy->StudyId() ) )
+    {
+      CORBA::String_var anIOR = GetGen()->GetORB()->object_to_string( _this() );
+      anId = aStudyContext->findId( anIOR.in() );
+    }
+  }
+
+  char aBuf[100];
+  sprintf( aBuf, "%i", anId );
+  return CORBA::string_dup( aBuf );
+}
+
+//=============================================================================
+/*!
+ * \brief Get name of the component
+ */
+//=============================================================================
+char* SMESH_Mesh_i::GetComponent()
+{
+  return CORBA::string_dup( "SMESH" );
+}
+
+//=============================================================================
+/*!
+ * \brief Get validity status of mesh
+ */
+//=============================================================================
+CORBA::Boolean SMESH_Mesh_i::IsValid()
+{
+  return true;
+}
+
 //=============================================================================
 /*!
  * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
  */
 //=============================================================================
-void SMESH_Mesh_i::SetParameters(const char* theParameters)
+void SMESH_Mesh_i::SetParameters( SALOME::Notebook_ptr theNotebook, const SALOME::StringArray& theParameters )
 {
-  SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
-                                               CORBA::string_dup(theParameters));
+  theNotebook->ClearDependencies( _this(), SALOME::Parameters );
+  std::list<std::string> aParams;
+  int n = theParameters.length();
+  for( int i=0; i<n; i++ )
+  {
+    std::string aParam = CORBA::string_dup( theParameters[i] );
+    aParams.push_back( aParam );
+    
+    SALOME::Parameter_ptr aParamPtr = theNotebook->GetParameter( aParam.c_str() );
+    if( !CORBA::is_nil( aParamPtr ) )
+      theNotebook->AddDependency( _this(), aParamPtr );
+  }
+  _impl->SetParameters( aParams );
+
+  UpdateStringAttribute( theParameters );
 }
 
 //=============================================================================
@@ -3236,33 +3454,136 @@ void SMESH_Mesh_i::SetParameters(const char* theParameters)
  * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
  */
 //=============================================================================
-char* SMESH_Mesh_i::GetParameters()
+SALOME::StringArray* SMESH_Mesh_i::GetParameters()
 {
-  SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
-  return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
+  std::list<std::string> aParams = _impl->GetParameters();
+  SALOME::StringArray_var aRes = new SALOME::StringArray();
+  aRes->length( aParams.size() );
+  std::list<std::string>::const_iterator it = aParams.begin(), last = aParams.end();
+  for( int i=0; it!=last; it++, i++ )
+    aRes[i] = CORBA::string_dup( it->c_str() );
+  return aRes._retn();
 }
 
 //=============================================================================
 /*!
- * \brief Returns list of notebook variables used for last Mesh operation
+ * \brief Update mesh according to the SALOME Notebook
  */
 //=============================================================================
-SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
+void SMESH_Mesh_i::Update( SALOME::Notebook_ptr theNotebook )
 {
-  SMESH::string_array_var aResult = new SMESH::string_array();
-  SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
-  if(gen) {
-    char *aParameters = GetParameters();
-    SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
-    if(!aStudy->_is_nil()) {
-      SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); 
-      if(aSections->length() > 0) {
-        SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
-        aResult->length(aVars.length());
-        for(int i = 0;i < aVars.length();i++)
-          aResult[i] = CORBA::string_dup( aVars[i]);
-      }
-    }
+}
+
+//=============================================================================
+/*!
+ * \brief Update string attribute of mesh
+ */
+//=============================================================================
+void SMESH_Mesh_i::UpdateStringAttribute( const SALOME::StringArray& theParameters )
+{
+  // implementation of the method has been temporarily changed
+  // previous implementation can be found in revision 1.23.2.7.2.2.2.6
+  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+
+  SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
+  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+  SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject( aStudy, SMESH::SMESH_Mesh::_narrow( _this() ) );
+  if( CORBA::is_nil( aSObject ) )
+    return;
+
+  SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute( aSObject, "AttributeString" );
+  SALOMEDS::AttributeString_var aStringAttrib = SALOMEDS::AttributeString::_narrow( anAttr );
+
+  std::string aCurrentString = aStringAttrib->Value();
+  std::string aString;
+  if( aCurrentString != "" )
+    aString = aCurrentString + "|";
+
+  for( int i = 0, n = theParameters.length(); i < n; i++ ) {
+    std::string aParameter = theParameters[i].in();
+    aString += aParameter;
+    if( i != n-1 )
+      aString += ":";
   }
-  return aResult._retn();
+
+  aStringAttrib->SetValue( aString.c_str() );
+  aStringAttrib->Destroy();
+}
+
+//=============================================================================
+/*!
+ * \brief Internal method for storing dependencies for mesh
+ */
+//=============================================================================
+void SMESH_Mesh_i::StoreDependenciesForShape( SALOME::Notebook_ptr theNotebook,
+                                              GEOM::GEOM_Object_ptr theShapeObject,
+                                              bool theIsStoreShape )
+{
+  SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theShapeObject );
+  for( int i = 0, n = aHypList->length(); i < n; i++ )
+  {
+    SMESH::SMESH_Hypothesis_ptr aHypothesis = aHypList[i];
+    if( CORBA::is_nil( aHypothesis ) )
+      continue;
+    SMESH::SMESH_Algo_ptr anAlgo = SMESH::SMESH_Algo::_narrow( aHypothesis );
+    if( !CORBA::is_nil( anAlgo ) ) // don't take into account algorithms
+      continue;
+    theNotebook->AddDependency( _this(), aHypothesis );
+  }
+
+  if( theIsStoreShape )
+    theNotebook->AddDependency( _this(), theShapeObject );
+}
+
+//=============================================================================
+/*!
+ * \brief Store dependencies for mesh
+ */
+//=============================================================================
+void SMESH_Mesh_i::StoreDependencies( SALOME::Notebook_ptr theNotebook )
+{
+  theNotebook->ClearDependencies( _this(), SALOME::Objects );
+
+  GEOM::GEOM_Object_ptr aShapeObject = GetShapeToMesh();
+  StoreDependenciesForShape( theNotebook, aShapeObject, true );
+
+  std::map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin(), itEnd = _mapSubMeshIor.end();
+  for( ; it != itEnd; it++ ) {
+    SMESH::SMESH_subMesh_ptr aSubMesh = it->second;
+    GEOM::GEOM_Object_ptr aSubShape = aSubMesh->GetSubShape();
+    StoreDependenciesForShape( theNotebook, aSubShape, false );
+  }
+}
+
+//=============================================================================
+/*!
+ * \brief Returns statistic of mesh elements
+ */
+//=============================================================================
+SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
+{
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if (!aMeshDS)
+    return aRes._retn();
+  const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+  return aRes._retn();
+}
+
+//=============================================================================
+/*!
+ * \brief Collect statistic of mesh elements given by iterator
+ */
+//=============================================================================
+void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
+                                   SMESH::long_array&         theInfo)
+{
+  if (!theItr) return;
+  while (theItr->more())
+    theInfo[ theItr->next()->GetEntityType() ]++;
 }