Salome HOME
Merge branch 'V9_9_BR'
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.cxx
index 26c9ec1287225d59a1c242ff9f876e8f9b9a33c6..9c6c494fed5a3c7d6d696183ed9835eb18964647 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -72,7 +72,7 @@ namespace
  */
 //================================================================================
 
-SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
+SMESHDS_SubMesh::SMESHDS_SubMesh(const SMESHDS_Mesh *parent, int index)
   : SMDS_ElementHolder( parent )
 {
   myParent = parent;
@@ -115,9 +115,12 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
           (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
     }
+    else
+    {
+      ++myNbElements;
+    }
 
     elem->setShapeID( myIndex );
-    myNbElements++;
 
     // remember element with smallest ID to optimize iteration on them
     add( elem );
@@ -131,7 +134,7 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
 
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem )
 {
-  if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex )
+  if ( myNbElements == 0 || !elem || elem->IsNull() || elem->getshapeId() != myIndex )
   {
     return false;
   }
@@ -142,8 +145,20 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem )
 
     const SMDS_MeshElement* & elem1st = my1stElemNode[ ind1st( elem->GetType() )];
     if ( elem1st == elem )
-      elem1st = 0;
-
+    {
+      if ( myNbElements > 0 )
+      {
+        SMDS_ElemIteratorPtr it = myParent->shapeElementsIterator( myIndex, 1, elem1st );
+        if ( it->more() )
+          elem1st = it->next();
+        else
+          throw SALOME_Exception(LOCALIZED("invalid myNbElements"));
+      }
+      else
+      {
+        elem1st = 0;
+      }
+    }
     return true;
   }
   return false;
@@ -166,8 +181,11 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
           (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
       return; // already in
     }
+    else
+    {
+      ++myNbNodes;
+    }
     N->setShapeID( myIndex );
-    myNbNodes++;
 
     // remember node with smallest ID to optimize iteration on them
     add( N );
@@ -181,7 +199,7 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 {
-  if ( !N || N->getshapeId() != myIndex )
+  if ( myNbNodes == 0 || !N || N->getshapeId() != myIndex )
   {
     return false;
   }
@@ -192,8 +210,21 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 
     const SMDS_MeshElement* & node1st = my1stElemNode[ ind1st( SMDSAbs_Node )];
     if ( node1st == N )
-      node1st = 0;
-
+    {
+      if ( myNbNodes > 0 )
+      {
+        SMDS_NodeIteratorPtr it =
+          myParent->shapeNodesIterator( myIndex, 1, static_cast< PNode >( node1st ));
+        if ( it->more() )
+          node1st = it->next();
+        else
+          throw SALOME_Exception(LOCALIZED("invalid myNbNodes"));
+      }
+      else
+      {
+        node1st = 0;
+      }
+    }
     return true;
   }
   return false;
@@ -204,12 +235,12 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 //purpose  :
 //=======================================================================
 
-int SMESHDS_SubMesh::NbElements() const
+smIdType SMESHDS_SubMesh::NbElements() const
 {
   if ( !IsComplexSubmesh() )
     return myNbElements;
 
-  int nbElems = 0;
+  smIdType nbElems = 0;
   TSubMeshSet::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbElements();
@@ -222,12 +253,12 @@ int SMESHDS_SubMesh::NbElements() const
 //purpose  :
 //=======================================================================
 
-int SMESHDS_SubMesh::NbNodes() const
+smIdType SMESHDS_SubMesh::NbNodes() const
 {
   if ( !IsComplexSubmesh() )
     return myNbNodes;
 
-  int nbElems = 0;
+  smIdType nbElems = 0;
   TSubMeshSet::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbNodes();
@@ -309,9 +340,9 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
 
   const SMDS_MeshElement* const * elem1st = & my1stElemNode[ ind1st( SMDSAbs_All )];
-  if ( myNbElements == 1 )
+  if ( myNbElements < 2 )
   {
-    return boost::make_shared< EArrayIterator >( elem1st, elem1st+1 );
+    return boost::make_shared< EArrayIterator >( elem1st, elem1st + myNbElements );
   }
 
   return myParent->shapeElementsIterator( myIndex, myNbElements, *elem1st );
@@ -329,9 +360,9 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
 
   PNode const * node1st =
     reinterpret_cast< PNode const* >( & my1stElemNode[ ind1st( SMDSAbs_Node )] );
-  if ( myNbNodes == 1 )
+  if ( myNbNodes < 2 )
   {
-    return boost::make_shared< NArrayIterator >( node1st, node1st+1 );
+    return boost::make_shared< NArrayIterator >( node1st, node1st + myNbNodes );
   }
 
   return myParent->shapeNodesIterator( myIndex, myNbNodes, *node1st );
@@ -459,6 +490,7 @@ void SMESHDS_SubMesh::Clear()
   myNbElements = 0;
   myNbNodes = 0;
   my1stElemNode[0] = my1stElemNode[1] = 0;
+
   if ( NbSubMeshes() > 0 )
   {
     SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();