Salome HOME
Update copyright notes (for 2010)
[modules/smesh.git] / src / SMESHDS / SMESHDS_Mesh.cxx
index c1d3cc45c57837ba80a211819b53d54db8c78341..091e4f70cf8c6e0acabe1e1affd326b563297d3e 100644 (file)
@@ -1,55 +1,66 @@
-//  SMESH SMESHDS : management of mesh data and SMESH document
+//  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
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
 //
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
 //
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
+//  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
 //  Module : SMESH
 //  $Header: 
-
+//
 #include "SMESHDS_Mesh.hxx"
 
 #include "SMESHDS_Group.hxx"
 #include "SMDS_VertexPosition.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
+#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"
 
 using namespace std;
 
+/*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 ) 
+  {
+    return S1.IsSame( S2 );
+  }*/
+
 //=======================================================================
 //function : Create
 //purpose  : 
 //=======================================================================
 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
+  myMeshID(theMeshID),
   myIsEmbeddedMode(theIsEmbeddedMode),
-  myMeshID(theMeshID)
+  myCurSubID(-1)
 {
   myScript = new SMESHDS_Script(theIsEmbeddedMode);
+  myCurSubMesh = 0;
 }
 
 //=======================================================================
@@ -68,7 +79,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
   {
     // removal of a shape to mesh, delete ...
     // - hypotheses
-    myShapeToHypothesis.clear();
+    myShapeToHypothesis.Clear();
     // - shape indices in SMDS_Position of nodes
     map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
     for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
@@ -79,8 +90,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() ) {
@@ -103,18 +117,22 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
 //=======================================================================
 
 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
-       const SMESHDS_Hypothesis * H)
+                                 const SMESHDS_Hypothesis * H)
 {
-       list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
+  if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
+    list<const SMESHDS_Hypothesis *> aList;
+    myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
+  }
+  list<const SMESHDS_Hypothesis *>& alist =
+    myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
 
-       //Check if the Hypothesis is still present
-       list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
+  //Check if the Hypothesis is still present
+  list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
 
-       for (; ith!=alist.end(); ith++)
-               if (H == *ith) return false;
+  if (alist.end() != ith) return false;
 
-       alist.push_back(H);
-       return true;
+  alist.push_back(H);
+  return true;
 }
 
 //=======================================================================
@@ -122,22 +140,20 @@ bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
 //purpose  : 
 //=======================================================================
 
-bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
-       const SMESHDS_Hypothesis * H)
+bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape &       S,
+                                    const SMESHDS_Hypothesis * H)
 {
-       ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
-       if(its!=myShapeToHypothesis.end())
-       {
-               list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
-
-               for (; ith!=(*its).second.end(); ith++)
-                       if (H == *ith)
-                       {
-                               (*its).second.erase(ith);
-                               return true;
-                       }
-       }
-       return false;
+  if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
+  {
+    list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
+    list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
+    if (ith != alist.end())
+    {
+      alist.erase(ith);
+      return true;
+    }
+  }
+  return false;
 }
 
 //=======================================================================
@@ -235,6 +251,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  : 
@@ -247,21 +287,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;
 }
 
@@ -277,25 +317,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;
 }
 
@@ -311,29 +351,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;
 }
 
@@ -349,29 +389,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;
 }
 
@@ -387,33 +427,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;
 }
 
@@ -429,37 +469,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;
 }
 
@@ -475,45 +515,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;
 }
 
@@ -642,6 +682,8 @@ static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
     }
   }
 
+  const bool deleted=true;
+
   // Rm from sub-meshes
   // Element should belong to only one sub-mesh
   map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
@@ -655,9 +697,9 @@ static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
     {
       bool removed = false;
       if ( isNode )
-        removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
+        removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
       else
-        removed = (*SubIt).second->RemoveElement( *elIt );
+        removed = (*SubIt).second->RemoveElement( *elIt, deleted );
 
       if (removed)
       {
@@ -679,6 +721,23 @@ static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
 //=======================================================================
 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
 {
+  if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
+  {
+    SMESHDS_SubMesh* subMesh=0;
+    map<int,SMESHDS_SubMesh*>::iterator SubIt =
+      myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
+    if ( SubIt != myShapeIndexToSubMesh.end() )
+      subMesh = SubIt->second;
+    else
+      SubIt = myShapeIndexToSubMesh.begin();
+    for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
+        subMesh = SubIt->second;
+
+    RemoveFreeNode( n, subMesh, true);
+    return;
+  }
+    
   myScript->RemoveNode(n->GetID());
   
   list<const SMDS_MeshElement *> removedElems;
@@ -694,13 +753,15 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
 //function : RemoveFreeNode
 //purpose  : 
 //=======================================================================
-void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * subMesh)
+void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
+                                  SMESHDS_SubMesh *     subMesh,
+                                  bool                  fromGroups)
 {
   myScript->RemoveNode(n->GetID());
 
   // Rm from group
   // Node can belong to several groups
-  if (!myGroups.empty()) {
+  if (fromGroups && !myGroups.empty()) {
     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
     for (; GrIt != myGroups.end(); GrIt++) {
       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
@@ -711,7 +772,8 @@ void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, SMESHDS_SubMesh * sub
 
   // Rm from sub-mesh
   // Node should belong to only one sub-mesh
-  subMesh->RemoveNode(n);
+  if( subMesh )
+    subMesh->RemoveNode(n,/*deleted=*/false);
 
   SMDS_Mesh::RemoveFreeElement(n);
 }
@@ -727,7 +789,18 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
     return;
   }
+  if (!hasConstructionEdges() && !hasConstructionFaces())
+  {
+    SMESHDS_SubMesh* subMesh=0;
+    map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
+    for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
+        subMesh = SubIt->second;
 
+    RemoveFreeElement( elt, subMesh, true);
+    return;
+  }
   myScript->RemoveElement(elt->GetID());
 
   list<const SMDS_MeshElement *> removedElems;
@@ -742,7 +815,9 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
 //function : RemoveFreeElement
 //purpose  : 
 //========================================================================
-void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh)
+void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
+                                     SMESHDS_SubMesh *        subMesh,
+                                     bool                     fromGroups)
 {
   if (elt->GetType() == SMDSAbs_Node) {
     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
@@ -757,22 +832,50 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMe
 
   // Rm from group
   // Node can belong to several groups
-  if (!myGroups.empty()) {
+  if ( fromGroups && !myGroups.empty() ) {
     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
     for (; GrIt != myGroups.end(); GrIt++) {
       SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
-      if (!group || group->IsEmpty()) continue;
-      group->SMDSGroup().Remove(elt);
+      if (group && !group->IsEmpty())
+        group->SMDSGroup().Remove(elt);
     }
   }
 
   // Rm from sub-mesh
   // Element should belong to only one sub-mesh
-  subMesh->RemoveElement(elt);
+  if( subMesh )
+    subMesh->RemoveElement(elt, /*deleted=*/false);
 
   SMDS_Mesh::RemoveFreeElement(elt);
 }
 
+//================================================================================
+/*!
+ * \brief Remove all data from the mesh
+ */
+//================================================================================
+
+void SMESHDS_Mesh::ClearMesh()
+{
+  myScript->ClearMesh();
+  SMDS_Mesh::Clear();
+
+  // clear submeshes
+  map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
+  for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
+    sub->second->Clear();
+
+  // clear groups
+  TGroups::iterator group, groupEnd = myGroups.end();
+  for ( group = myGroups.begin(); group != groupEnd; ++group ) {
+    if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
+      SMDSAbs_ElementType groupType = g->GetType();
+      g->Clear();
+      g->SetType( groupType );
+    }
+  }
+}
+
 //================================================================================
 /*!
  * \brief return submesh by shape
@@ -839,6 +942,22 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
   return false;
 }
 
+namespace {
+
+  //================================================================================
+  /*!
+   * \brief Creates a node position in volume
+   */
+  //================================================================================
+
+  inline SMDS_PositionPtr volumePosition(int volId)
+  {
+    SMDS_SpacePosition* pos = new SMDS_SpacePosition();
+    pos->SetShapeId( volId );
+    return SMDS_PositionPtr(pos);
+  }
+}
+
 //=======================================================================
 //function : SetNodeOnVolume
 //purpose  : 
@@ -846,7 +965,8 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Shell & S)
 {
-  add( aNode, getSubmesh(S) );
+  if ( add( aNode, getSubmesh(S) ))
+    aNode->SetPosition ( volumePosition( myCurSubID ));
 }
 //=======================================================================
 //function : SetNodeOnVolume
@@ -855,7 +975,8 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Solid & S)
 {
-  add( aNode, getSubmesh(S) );
+  if ( add( aNode, getSubmesh(S) ))
+    aNode->SetPosition ( volumePosition( myCurSubID ));
 }
 
 //=======================================================================
@@ -904,7 +1025,7 @@ void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
     map<int,SMESHDS_SubMesh*>::iterator it =
       myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
     if ( it != myShapeIndexToSubMesh.end() )
-      it->second->RemoveNode( aNode );
+      it->second->RemoveNode( aNode, /*deleted=*/false );
   }
 }
 
@@ -930,9 +1051,9 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
   if ( it != myShapeIndexToSubMesh.end() )
     if ( elem->GetType() == SMDSAbs_Node )
-      it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ));
+      it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ), /*deleted=*/false );
     else
-      it->second->RemoveElement( elem );
+      it->second->RemoveElement( elem, /*deleted=*/false );
 }
 
 //=======================================================================
@@ -941,7 +1062,7 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
 //=======================================================================
 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
 {
-       return myShape;
+        return myShape;
 }
 
 //=======================================================================
@@ -1009,14 +1130,14 @@ list<int> SMESHDS_Mesh::SubMeshIndices()
 //purpose  : 
 //=======================================================================
 
-const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
-       const TopoDS_Shape & S) const
+const list<const SMESHDS_Hypothesis*>&
+SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
 {
-       if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
-               return myShapeToHypothesis.find(S)->second;
+  if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
+     return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
 
-       static list<const SMESHDS_Hypothesis*> empty;
-       return empty;
+  static list<const SMESHDS_Hypothesis*> empty;
+  return empty;
 }
 
 //=======================================================================
@@ -1025,7 +1146,7 @@ const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
 //=======================================================================
 SMESHDS_Script* SMESHDS_Mesh::GetScript()
 {
-       return myScript;
+        return myScript;
 }
 
 //=======================================================================
@@ -1034,7 +1155,7 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript()
 //=======================================================================
 void SMESHDS_Mesh::ClearScript()
 {
-       myScript->Clear();
+        myScript->Clear();
 }
 
 //=======================================================================
@@ -1043,9 +1164,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();
 }
 
 //=======================================================================
@@ -1054,7 +1175,7 @@ bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
 //=======================================================================
 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
 {
-       return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
+  return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
 }
 
 //=======================================================================
@@ -1094,7 +1215,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
     if ( !aNewSub->IsComplexSubmesh() ) // is empty
     {
-      int shapeType = all ? myShape.ShapeType() : type;
+      int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
       int typeLimit = all ? TopAbs_VERTEX : type;
       for ( ; shapeType <= typeLimit; shapeType++ )
       {
@@ -1117,7 +1238,15 @@ 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;
 }
 
 //=======================================================================
@@ -1140,7 +1269,8 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
 //=======================================================================
 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
 {
-  add( aNode, getSubmesh( Index ));
+  if ( add( aNode, getSubmesh( Index )))
+    ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
 }
 
 //=======================================================================
@@ -1188,13 +1318,21 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
   add( anElement, getSubmesh( Index ));
 }
 
+//=======================================================================
+//function : ~SMESHDS_Mesh
+//purpose  : 
+//=======================================================================
 SMESHDS_Mesh::~SMESHDS_Mesh()
 {
+  // myScript
   delete myScript;
+  // submeshes
+  TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
+  for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
+    delete i_sm->second;
 }
 
 
-
 //********************************************************************
 //********************************************************************
 //********                                                   *********
@@ -1224,8 +1362,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;
 }
@@ -1240,9 +1378,9 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                            int ID)
 {
   return AddEdgeWithID(n1->GetID(),
-                      n2->GetID(),
+                       n2->GetID(),
                        n12->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1259,7 +1397,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;
 }
@@ -1290,7 +1428,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);
 }
 
 
@@ -1309,7 +1447,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;
 }
@@ -1342,7 +1480,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);
 }
 
 
@@ -1363,8 +1501,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;
 }
@@ -1382,7 +1520,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
@@ -1448,7 +1586,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
@@ -1525,7 +1663,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
@@ -1613,7 +1751,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