Salome HOME
Merge from V5_1_main branch 24/11/2010
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
index 61db43a743c9f3572afcd70dd31ce045bf6c12ee..0ae03d0c56940461a82c0f666b4e44288b204ec2 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  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
@@ -19,6 +19,7 @@
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESH_Mesh.cxx
 //  Author : Yves FRICAUD, OCC
 #include "SMDS_SpacePosition.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 
-#include <TopExp_Explorer.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_OutOfRange.hxx>
 #include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS_Iterator.hxx>
 
 #include "utilities.h"
@@ -58,6 +61,7 @@ SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
 {
   myScript = new SMESHDS_Script(theIsEmbeddedMode);
   myCurSubMesh = 0;
+  SetPersistentId(theMeshID);
 }
 
 //=======================================================================
@@ -66,6 +70,28 @@ bool SMESHDS_Mesh::IsEmbeddedMode()
   return myIsEmbeddedMode;
 }
 
+//================================================================================
+/*!
+ * \brief Store ID persistent during lifecycle
+ */
+//================================================================================
+
+void SMESHDS_Mesh::SetPersistentId(int id)
+{
+  if (NbNodes() == 0)
+    myPersistentID = id;
+}
+//================================================================================
+/*!
+ * \brief Return ID persistent during lifecycle
+ */
+//================================================================================
+
+int SMESHDS_Mesh::GetPersistentId() const
+{
+  return myPersistentID;
+}
+
 //=======================================================================
 //function : ShapeToMesh
 //purpose  : 
@@ -87,8 +113,11 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
       }
     }
     // - sub-meshes
-    myIndexToShape.Clear();
+    TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
+    for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
+      delete i_sm->second;
     myShapeIndexToSubMesh.clear();
+    myIndexToShape.Clear();
     // - groups on geometry
     set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
     while ( gr != myGroups.end() ) {
@@ -245,6 +274,30 @@ void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int de
   myScript->Renumber( isNodes, startID, deltaID );
 }
 
+//=======================================================================
+//function : Add0DElement
+//purpose  :
+//=======================================================================
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
+{
+  SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
+  if (anElem) myScript->Add0DElement(ID, nodeID);
+  return anElem;
+}
+
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
+                                  (const SMDS_MeshNode * node, int ID)
+{
+  return Add0DElementWithID(node->GetID(), ID);
+}
+
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
+{
+  SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
+  if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
+  return anElem;
+}
+
 //=======================================================================
 //function :AddEdgeWithID
 //purpose  : 
@@ -257,21 +310,21 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
 }
 
 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                          const SMDS_MeshNode * n2, 
-                                          int ID)
+                                           const SMDS_MeshNode * n2, 
+                                           int ID)
 {
   return AddEdgeWithID(n1->GetID(),
-                      n2->GetID(),
-                      ID);
+                       n2->GetID(),
+                       ID);
 }
 
 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
-                                    const SMDS_MeshNode * n2)
+                                     const SMDS_MeshNode * n2)
 {
   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
   if(anElem) myScript->AddEdge(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID());
+                               n1->GetID(), 
+                               n2->GetID());
   return anElem;
 }
 
@@ -287,25 +340,25 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
-                                          const SMDS_MeshNode * n2,
-                                          const SMDS_MeshNode * n3, 
-                                          int ID)
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3, 
+                                           int ID)
 {
   return AddFaceWithID(n1->GetID(),
-                      n2->GetID(),
-                      n3->GetID(),
-                      ID);
+                       n2->GetID(),
+                       n3->GetID(),
+                       ID);
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2,
-                                     const SMDS_MeshNode * n3)
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(),
-                              n3->GetID());
+                               n1->GetID(), 
+                               n2->GetID(),
+                               n3->GetID());
   return anElem;
 }
 
@@ -321,29 +374,29 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int I
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
-                                          const SMDS_MeshNode * n2,
-                                          const SMDS_MeshNode * n3,
-                                          const SMDS_MeshNode * n4, 
-                                          int ID)
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4, 
+                                           int ID)
 {
   return AddFaceWithID(n1->GetID(),
-                      n2->GetID(),
-                      n3->GetID(),
-                      n4->GetID(),
-                      ID);
+                       n2->GetID(),
+                       n3->GetID(),
+                       n4->GetID(),
+                       ID);
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
-                                    const SMDS_MeshNode * n2,
-                                    const SMDS_MeshNode * n3,
-                                    const SMDS_MeshNode * n4)
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(), 
-                              n3->GetID(),
-                              n4->GetID());
+                               n1->GetID(), 
+                               n2->GetID(), 
+                               n3->GetID(),
+                               n4->GetID());
   return anElem;
 }
 
@@ -359,29 +412,29 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
-                                              const SMDS_MeshNode * n2,
-                                              const SMDS_MeshNode * n3,
-                                              const SMDS_MeshNode * n4, 
-                                              int ID)
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4, 
+                                               int ID)
 {
   return AddVolumeWithID(n1->GetID(), 
-                        n2->GetID(), 
-                        n3->GetID(),
-                        n4->GetID(),
-                        ID);
+                         n2->GetID(), 
+                         n3->GetID(),
+                         n4->GetID(),
+                         ID);
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                        const SMDS_MeshNode * n2,
-                                        const SMDS_MeshNode * n3,
-                                        const SMDS_MeshNode * n4)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), 
-                                n2->GetID(), 
-                                n3->GetID(),
-                                n4->GetID());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID());
   return anElem;
 }
 
@@ -397,33 +450,33 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
-                                              const SMDS_MeshNode * n2,
-                                              const SMDS_MeshNode * n3,
-                                              const SMDS_MeshNode * n4,
-                                              const SMDS_MeshNode * n5, 
-                                              int ID)
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5, 
+                                               int ID)
 {
   return AddVolumeWithID(n1->GetID(), 
-                        n2->GetID(), 
-                        n3->GetID(),
-                        n4->GetID(), 
-                        n5->GetID(),
-                        ID);
+                         n2->GetID(), 
+                         n3->GetID(),
+                         n4->GetID(), 
+                         n5->GetID(),
+                         ID);
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                        const SMDS_MeshNode * n2,
-                                        const SMDS_MeshNode * n3,
-                                        const SMDS_MeshNode * n4,
-                                        const SMDS_MeshNode * n5)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), 
-                                n2->GetID(), 
-                                n3->GetID(),
-                                n4->GetID(), 
-                                n5->GetID());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID());
   return anElem;
 }
 
@@ -439,37 +492,37 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
-                                              const SMDS_MeshNode * n2,
-                                              const SMDS_MeshNode * n3,
-                                              const SMDS_MeshNode * n4,
-                                              const SMDS_MeshNode * n5,
-                                              const SMDS_MeshNode * n6, 
-                                              int ID)
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5,
+                                               const SMDS_MeshNode * n6, 
+                                               int ID)
 {
   return AddVolumeWithID(n1->GetID(), 
-                        n2->GetID(), 
-                        n3->GetID(),
-                        n4->GetID(), 
-                        n5->GetID(), 
-                        n6->GetID(),
-                        ID);
+                         n2->GetID(), 
+                         n3->GetID(),
+                         n4->GetID(), 
+                         n5->GetID(), 
+                         n6->GetID(),
+                         ID);
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                        const SMDS_MeshNode * n2,
-                                        const SMDS_MeshNode * n3,
-                                        const SMDS_MeshNode * n4,
-                                        const SMDS_MeshNode * n5,
-                                        const SMDS_MeshNode * n6)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5,
+                                         const SMDS_MeshNode * n6)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), 
-                                n2->GetID(), 
-                                n3->GetID(),
-                                n4->GetID(), 
-                                n5->GetID(), 
-                                n6->GetID());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID(), 
+                                 n6->GetID());
   return anElem;
 }
 
@@ -485,45 +538,45 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
-                                              const SMDS_MeshNode * n2,
-                                              const SMDS_MeshNode * n3,
-                                              const SMDS_MeshNode * n4,
-                                              const SMDS_MeshNode * n5,
-                                              const SMDS_MeshNode * n6,
-                                              const SMDS_MeshNode * n7,
-                                              const SMDS_MeshNode * n8, 
-                                              int ID)
+                                               const SMDS_MeshNode * n2,
+                                               const SMDS_MeshNode * n3,
+                                               const SMDS_MeshNode * n4,
+                                               const SMDS_MeshNode * n5,
+                                               const SMDS_MeshNode * n6,
+                                               const SMDS_MeshNode * n7,
+                                               const SMDS_MeshNode * n8, 
+                                               int ID)
 {
   return AddVolumeWithID(n1->GetID(), 
-                        n2->GetID(), 
-                        n3->GetID(),
-                        n4->GetID(), 
-                        n5->GetID(), 
-                        n6->GetID(), 
-                        n7->GetID(), 
-                        n8->GetID(),
-                        ID);
+                         n2->GetID(), 
+                         n3->GetID(),
+                         n4->GetID(), 
+                         n5->GetID(), 
+                         n6->GetID(), 
+                         n7->GetID(), 
+                         n8->GetID(),
+                         ID);
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                        const SMDS_MeshNode * n2,
-                                        const SMDS_MeshNode * n3,
-                                        const SMDS_MeshNode * n4,
-                                        const SMDS_MeshNode * n5,
-                                        const SMDS_MeshNode * n6,
-                                        const SMDS_MeshNode * n7,
-                                        const SMDS_MeshNode * n8)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5,
+                                         const SMDS_MeshNode * n6,
+                                         const SMDS_MeshNode * n7,
+                                         const SMDS_MeshNode * n8)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), 
-                                n2->GetID(), 
-                                n3->GetID(),
-                                n4->GetID(), 
-                                n5->GetID(), 
-                                n6->GetID(), 
-                                n7->GetID(), 
-                                n8->GetID());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID(), 
+                                 n6->GetID(), 
+                                 n7->GetID(), 
+                                 n8->GetID());
   return anElem;
 }
 
@@ -531,8 +584,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddPolygonalFace
 //purpose  : 
 //=======================================================================
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
-                                                     const int        ID)
+SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
+                                                     const int               ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
   if (anElem) {
@@ -542,8 +595,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
-                             (std::vector<const SMDS_MeshNode*> nodes,
-                              const int                         ID)
+                             (const std::vector<const SMDS_MeshNode*>& nodes,
+                              const int                                ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
   if (anElem) {
@@ -558,7 +611,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
-                             (std::vector<const SMDS_MeshNode*> nodes)
+                             (const std::vector<const SMDS_MeshNode*>& nodes)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
   if (anElem) {
@@ -576,9 +629,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
 //function : AddPolyhedralVolume
 //purpose  : 
 //=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
-                                                          std::vector<int> quantities,
-                                                          const int        ID)
+SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
+                                                          const std::vector<int>& quantities,
+                                                          const int               ID)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
   if (anElem) {
@@ -588,9 +641,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
-                               (std::vector<const SMDS_MeshNode*> nodes,
-                                std::vector<int>                  quantities,
-                                const int                         ID)
+                               (const std::vector<const SMDS_MeshNode*>& nodes,
+                                const std::vector<int>&                  quantities,
+                                const int                                ID)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
   if (anElem) {
@@ -605,8 +658,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
-                               (std::vector<const SMDS_MeshNode*> nodes,
-                                std::vector<int>                  quantities)
+                               (const std::vector<const SMDS_MeshNode*>& nodes,
+                                const std::vector<int>&                  quantities)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
   if (anElem) {
@@ -701,7 +754,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
     else
       SubIt = myShapeIndexToSubMesh.begin();
     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
-      if ( SubIt->second->Contains( n ))
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
         subMesh = SubIt->second;
 
     RemoveFreeNode( n, subMesh, true);
@@ -764,7 +817,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     SMESHDS_SubMesh* subMesh=0;
     map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
-      if ( SubIt->second->Contains( elt ))
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
         subMesh = SubIt->second;
 
     RemoveFreeElement( elt, subMesh, true);
@@ -1032,7 +1085,7 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
 //=======================================================================
 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
 {
-       return myShape;
+        return myShape;
 }
 
 //=======================================================================
@@ -1043,15 +1096,13 @@ TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
 
 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
 {
-  if ( myShape.IsSame( theShape ))
+  if ( myIndexToShape.Contains(theShape) )
     return true;
 
-  for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
-    if (myIndexToShape.Contains( it.Value() ) ||
-        IsGroupOfSubShapes( it.Value() ))
+  for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
+    if (IsGroupOfSubShapes( it.Value() ))
       return true;
-  }
-  
+
   return false;
 }
 
@@ -1116,7 +1167,7 @@ SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
 //=======================================================================
 SMESHDS_Script* SMESHDS_Mesh::GetScript()
 {
-       return myScript;
+        return myScript;
 }
 
 //=======================================================================
@@ -1125,7 +1176,7 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript()
 //=======================================================================
 void SMESHDS_Mesh::ClearScript()
 {
-       myScript->Clear();
+        myScript->Clear();
 }
 
 //=======================================================================
@@ -1134,9 +1185,9 @@ void SMESHDS_Mesh::ClearScript()
 //=======================================================================
 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
 {
-       if (myShape.IsNull()) MESSAGE("myShape is NULL");
-       int Index = myIndexToShape.FindIndex(S);
-       return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
+        if (myShape.IsNull()) MESSAGE("myShape is NULL");
+        int Index = myIndexToShape.FindIndex(S);
+        return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
 }
 
 //=======================================================================
@@ -1175,7 +1226,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
                                      TopAbs_ShapeEnum    type)
 {
   int aMainIndex = 0;
-  if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
+  if ( IsGroupOfSubShapes( S ))
   {
     aMainIndex = myIndexToShape.Add( S );
     bool all = ( type == TopAbs_SHAPE );
@@ -1208,7 +1259,26 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
 //=======================================================================
 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
 {
-       return myIndexToShape.FindKey(ShapeIndex);
+  try
+  {
+    return myIndexToShape.FindKey(ShapeIndex);
+  }
+  catch ( Standard_OutOfRange )
+  {
+  }
+  static TopoDS_Shape nullShape;
+  return nullShape;
+}
+
+//================================================================================
+/*!
+ * \brief Return max index of sub-mesh
+ */
+//================================================================================
+
+int SMESHDS_Mesh::MaxSubMeshIndex() const
+{
+  return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
 }
 
 //=======================================================================
@@ -1324,8 +1394,8 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
 {
   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
   if(anElem) myScript->AddEdge(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(),
+                               n1->GetID(), 
+                               n2->GetID(),
                                n12->GetID());
   return anElem;
 }
@@ -1340,9 +1410,9 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                            int ID)
 {
   return AddEdgeWithID(n1->GetID(),
-                      n2->GetID(),
+                       n2->GetID(),
                        n12->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1359,7 +1429,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), n2->GetID(), n3->GetID(),
+                               n1->GetID(), n2->GetID(), n3->GetID(),
                                n12->GetID(), n23->GetID(), n31->GetID());
   return anElem;
 }
@@ -1390,7 +1460,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 {
   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
                        n12->GetID(), n23->GetID(), n31->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1409,7 +1479,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                               n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
   return anElem;
 }
@@ -1442,7 +1512,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 {
   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1463,8 +1533,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
-                                n12->GetID(), n23->GetID(), n31->GetID(),
+                                 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                                 n12->GetID(), n23->GetID(), n31->GetID(),
                                  n14->GetID(), n24->GetID(), n34->GetID());
   return anElem;
 }
@@ -1482,7 +1552,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order tetrahedron of 10 nodes
@@ -1548,7 +1618,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
                                  n15,n25,n35,n45);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order pyramid of 13 nodes
@@ -1625,7 +1695,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                  n45,n56,n64,n14,n25,n36);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order Pentahedron with 15 nodes
@@ -1713,7 +1783,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                  n56,n67,n78,n85,n15,n26,n37,n48);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order Hexahedrons with 20 nodes