Salome HOME
23418: [OCC] Mesh: Minimization of memory usage of SMESH
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.cxx
index 89287301641073332320037784571d4cf499aa12..4a086e3b7073fc8d84be84192fe8c158b8302076 100644 (file)
 //  $Header: 
 //
 #include "SMESHDS_SubMesh.hxx"
 //  $Header: 
 //
 #include "SMESHDS_SubMesh.hxx"
-#include "SMESHDS_Mesh.hxx"
 
 
-#include "utilities.h"
+#include "SMESHDS_Mesh.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_SetIterator.hxx"
-#include <iostream>
-#include <cassert>
-
-using namespace std;
+#include "SMDS_ElementFactory.hxx"
 
 
+#include <utilities.h>
 
 //================================================================================
 /*!
 
 //================================================================================
 /*!
@@ -47,8 +44,8 @@ SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
   myIndex = index;
 {
   myParent = parent;
   myIndex = index;
-  myUnusedIdNodes = 0;
-  myUnusedIdElements = 0;
+  myNbElements = 0;
+  myNbNodes = 0;
 }
 
 //================================================================================
 }
 
 //================================================================================
@@ -66,16 +63,16 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh()
 //purpose  :
 //=======================================================================
 
 //purpose  :
 //=======================================================================
 
-void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
+void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
 {
   if (!IsComplexSubmesh())
   {
 {
   if (!IsComplexSubmesh())
   {
-    if ( ME->GetType() == SMDSAbs_Node )
+    if ( elem->GetType() == SMDSAbs_Node )
     {
     {
-      AddNode( static_cast< const SMDS_MeshNode* >( ME ));
+      AddNode( static_cast< const SMDS_MeshNode* >( elem ));
       return;
     }
       return;
     }
-    int oldShapeId = ME->getshapeId();
+    int oldShapeId = elem->GetShapeID();
     if ( oldShapeId > 0 )
     {
       if (oldShapeId != myIndex)
     if ( oldShapeId > 0 )
     {
       if (oldShapeId != myIndex)
@@ -83,28 +80,10 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
         throw SALOME_Exception
           (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
         throw SALOME_Exception
           (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
-      int idInSubShape = ME->getIdInShape();
-      if (idInSubShape >= 0)
-      {
-        MESSAGE("add element in subshape already belonging to that subshape "
-                << ME->GetID() << " " << oldShapeId << " " << idInSubShape);
-        // check if ok: do nothing if ok
-        if (idInSubShape >= (int)myElements.size())
-        {
-          throw SALOME_Exception(LOCALIZED("out of bounds"));
-        }
-        if (ME != myElements[idInSubShape])
-        {
-          throw SALOME_Exception(LOCALIZED("not the same element"));
-        }
-        return;
-      }
     }
 
     }
 
-    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-    elem->setShapeId(myIndex);
-    elem->setIdInShape(myElements.size());
-    myElements.push_back(ME);
+    elem->setShapeID( myIndex );
+    myNbElements++;
   }
 }
 
   }
 }
 
@@ -113,41 +92,17 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 //purpose  :
 //=======================================================================
 
 //purpose  :
 //=======================================================================
 
-bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
+bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem )
 {
 {
-  if (!ME)
+  if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex )
   {
     return false;
   }
   {
     return false;
   }
-  if (!IsComplexSubmesh())
+  if ( !IsComplexSubmesh() )
   {
   {
-    if ( ME->getshapeId() != myIndex ) // elem not in a pool can loose it's data already
-    {
-      if ( isElemDeleted )
-        for ( size_t i = 0; i < myElements.size(); ++i )
-          if ( myElements[i] == ME )
-          {
-            myElements[i] = 0;
-            ++myUnusedIdElements;
-            return true;
-          }
-      return false;
-    }
-    int idInSubShape = ME->getIdInShape();
-    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-    elem->setShapeId(0);
-    elem->setIdInShape(-1);
-    if ((idInSubShape >= 0) && (idInSubShape < (int) myElements.size()))
-    {
-      myElements[idInSubShape] = 0; // this vector entry is no more used
-      if ( ++myUnusedIdElements == (int) myElements.size() )
-      {
-        clearVector( myElements );
-        myUnusedIdElements = 0;
-      }
-      return true;
-    }
-    return false;
+    elem->setShapeID( 0 );
+    myNbElements--;
+    return true;
   }
   return false;
 }
   }
   return false;
 }
@@ -161,22 +116,16 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 {
   if ( !IsComplexSubmesh() )
   {
 {
   if ( !IsComplexSubmesh() )
   {
-    const int idInSubShape = N->getIdInShape();
-    const int shapeId      = N->getshapeId();
-    if ((shapeId > 0) && (idInSubShape >= 0))
+    const int shapeId = N->getshapeId();
+    if ( shapeId > 0 )
     {
       if ( shapeId != myIndex )
         throw SALOME_Exception
           (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
     {
       if ( shapeId != myIndex )
         throw SALOME_Exception
           (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
-      if ( idInSubShape >= (int)myNodes.size() || myNodes[ idInSubShape ] != N )
-        throw SALOME_Exception
-          (LOCALIZED("a node with wrong idInSubShape is re-added to the same sub-mesh"));
       return; // already in
     }
       return; // already in
     }
-    SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
-    node->setShapeId(myIndex);
-    node->setIdInShape(myNodes.size());
-    myNodes.push_back(N);
+    N->setShapeID( myIndex );
+    myNbNodes++;
   }
 }
 
   }
 }
 
@@ -185,38 +134,18 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 //purpose  :
 //=======================================================================
 
 //purpose  :
 //=======================================================================
 
-bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
+bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 {
 {
-  if (!IsComplexSubmesh())
+  if ( !N || N->getshapeId() != myIndex )
   {
   {
-    if ( N->getshapeId() != myIndex )
-    {
-      if ( isNodeDeleted )
-        for ( size_t i = 0; i < myNodes.size(); ++i )
-          if ( myNodes[i] == N )
-          {
-            myNodes[i] = 0;
-            ++myUnusedIdNodes;
-            return true;
-          }
-      return false;
-    }
-    int idInSubShape = N->getIdInShape();
-    SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
-    node->setShapeId(0);
-    node->setIdInShape(-1);
-    if ((idInSubShape >= 0) && (idInSubShape < (int) myNodes.size()))
-    {
-      myNodes[idInSubShape] = 0; // this vector entry is no more used
-      if ( ++myUnusedIdNodes == (int) myNodes.size() )
-      {
-        clearVector( myNodes );
-        myUnusedIdNodes = 0;
-      }
-      return true;
-    }
     return false;
   }
     return false;
   }
+  if ( !IsComplexSubmesh() )
+  {
+    N->setShapeID( 0 );
+    myNbNodes--;
+    return true;
+  }
   return false;
 }
 
   return false;
 }
 
@@ -228,10 +157,10 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 int SMESHDS_SubMesh::NbElements() const
 {
   if ( !IsComplexSubmesh() )
 int SMESHDS_SubMesh::NbElements() const
 {
   if ( !IsComplexSubmesh() )
-    return myElements.size() - myUnusedIdElements;
+    return myNbElements;
 
   int nbElems = 0;
 
   int nbElems = 0;
-  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
+  TSubMeshSet::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbElements();
 
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbElements();
 
@@ -246,10 +175,10 @@ int SMESHDS_SubMesh::NbElements() const
 int SMESHDS_SubMesh::NbNodes() const
 {
   if ( !IsComplexSubmesh() )
 int SMESHDS_SubMesh::NbNodes() const
 {
   if ( !IsComplexSubmesh() )
-    return myNodes.size() - myUnusedIdNodes;
+    return myNbNodes;
 
   int nbElems = 0;
 
   int nbElems = 0;
-  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
+  TSubMeshSet::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbNodes();
 
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbNodes();
 
@@ -306,7 +235,7 @@ public:
 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 {
 public:
 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 {
 public:
-  MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+  MyIterator (const TSubMeshSet& theSubMeshes)
     : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() )
   {}
   bool more()
     : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() )
   {}
   bool more()
@@ -331,9 +260,9 @@ protected:
   getElements(const SMESHDS_SubMesh*) const = 0;
 
 private:
   getElements(const SMESHDS_SubMesh*) const = 0;
 
 private:
-  bool                                        myMore;
-  set<const SMESHDS_SubMesh*>::const_iterator mySubIt, mySubEnd;
-  boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
+  bool                                      myMore;
+  TSubMeshSet::const_iterator               mySubIt, mySubEnd;
+  boost::shared_ptr< SMDS_Iterator<VALUE> > myElemIt;
 };
 
 // =====================
 };
 
 // =====================
@@ -343,7 +272,7 @@ private:
 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
 {
 public:
 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
 {
 public:
-  MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+  MyElemIterator (const TSubMeshSet& theSubMeshes)
     :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
   SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetElements(); }
     :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
   SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetElements(); }
@@ -356,7 +285,7 @@ public:
 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
 {
 public:
 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
 {
 public:
-  MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+  MyNodeIterator (const TSubMeshSet& theSubMeshes)
     :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
   SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetNodes(); }
     :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
   SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetNodes(); }
@@ -367,13 +296,12 @@ public:
 //purpose  :
 //=======================================================================
 
 //purpose  :
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements( bool reverse ) const
+SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
 {
   if ( IsComplexSubmesh() )
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
 
 {
   if ( IsComplexSubmesh() )
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
 
-  typedef MySetIterator< const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> > TIter;
-  return SMDS_ElemIteratorPtr( new TIter( myElements, reverse ));
+  return myParent->shapeElementsIterator( myIndex, myNbElements );
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -381,13 +309,12 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements( bool reverse ) const
 //purpose  :
 //=======================================================================
 
 //purpose  :
 //=======================================================================
 
-SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes( bool reverse ) const
+SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
 {
   if ( IsComplexSubmesh() )
     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
 
 {
   if ( IsComplexSubmesh() )
     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
 
-  typedef MySetIterator< const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> > TIter;
-  return SMDS_NodeIteratorPtr( new TIter( myNodes, reverse ));
+  return myParent->shapeNodesIterator( myIndex, myNbNodes );
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -397,35 +324,18 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes( bool reverse ) const
 
 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
 {
 
 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
 {
-  // DO NOT TRY TO FIND A REMOVED ELEMENT !!
-  //if ( IsComplexSubmesh() || !ME )
-  if (!ME)
+  if ( !ME || ME->IsNull() )
     return false;
 
   if ( IsComplexSubmesh() )
   {
     return false;
 
   if ( IsComplexSubmesh() )
   {
-    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->Contains(ME))
         return true;
     return false;
   }
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->Contains(ME))
         return true;
     return false;
   }
-
-  if (ME->GetType() == SMDSAbs_Node)
-  {
-    int idInShape = ME->getIdInShape();
-    if ((idInShape >= 0) && (idInShape < (int) myNodes.size()))
-      if (myNodes[idInShape] == ME)
-        return true;
-  }
-  else
-  {
-    int idInShape = ME->getIdInShape();
-    if ((idInShape >= 0) && (idInShape < (int) myElements.size()))
-      if (myElements[idInShape] == ME)
-        return true;
-  }
-  return false;
+  return ME->getshapeId() == myIndex;
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -437,18 +347,18 @@ bool SMESHDS_SubMesh::IsQuadratic() const
 {
   if ( IsComplexSubmesh() )
   {
 {
   if ( IsComplexSubmesh() )
   {
-    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->IsQuadratic())
         return true;
     return false;
   }
 
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->IsQuadratic())
         return true;
     return false;
   }
 
-  for ( size_t i = 0; i < myElements.size(); ++i )
-    if ( myElements[i] )
-      return myElements[i]->IsQuadratic();
+  if ( myNbElements == 0 )
+    return false;
 
 
-  return false;
+  SMDS_ElemIteratorPtr it = GetElements();
+  return it->more() && it->next()->IsQuadratic();
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -499,10 +409,8 @@ bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
 
 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
 {
 
 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
 {
-  typedef set<const SMESHDS_SubMesh*>::const_iterator TIterator;
-  return SMESHDS_SubMeshIteratorPtr
-    ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(),
-                                                                 mySubMeshes.end()));
+  typedef SMDS_SetIterator< const SMESHDS_SubMesh*, TSubMeshSet::const_iterator > TIterator;
+  return boost::make_shared< TIterator >( mySubMeshes.begin(), mySubMeshes.end());
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -514,26 +422,22 @@ void SMESHDS_SubMesh::Clear()
 {
   if ( myParent && myParent->NbNodes() > 0 )
   {
 {
   if ( myParent && myParent->NbNodes() > 0 )
   {
-    for ( size_t i = 0; i < myElements.size(); ++i )
-    {
-      if ( myElements[i] &&
-           myElements[i]->GetID() > 0 &&
-           myElements[i] == myParent->FindElement( myElements[i]->GetID() )) // not deleted
-        const_cast< SMDS_MeshElement* >( myElements[i] )->setShapeId( 0 );
-    }
-    for ( size_t i = 0; i < myNodes.size(); ++i )
-    {
-      if ( myNodes[i] &&
-           myNodes[i]->GetID() > 0 &&
-           myNodes[i] == myParent->FindNode( myNodes[i]->GetID() )) // not deleted
-        const_cast< SMDS_MeshNode* >( myNodes[i] )->setShapeId( 0 );
-    }
+    if ( myNbElements > 0 )
+      for ( SMDS_ElemIteratorPtr it = GetElements(); it->more(); )
+      {
+        const SMDS_MeshElement * elem = it->next();
+        elem->setShapeID( 0 );
+      }
+    if ( myNbNodes > 0 )
+      for ( SMDS_NodeIteratorPtr it = GetNodes(); it->more(); )
+      {
+        const SMDS_MeshNode * elem = it->next();
+        elem->setShapeID( 0 );
+      }
   }
 
   }
 
-  clearVector( myElements );
-  clearVector( myNodes );
-  myUnusedIdNodes = 0;
-  myUnusedIdElements = 0;
+  myNbElements = 0;
+  myNbNodes = 0;
   if ( NbSubMeshes() > 0 )
   {
     SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
   if ( NbSubMeshes() > 0 )
   {
     SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
@@ -543,71 +447,3 @@ void SMESHDS_SubMesh::Clear()
     }
   }
 }
     }
   }
 }
-
-int SMESHDS_SubMesh::getSize()
-{
-  int c = NbNodes();
-  int d = NbElements();
-  return c+d;
-}
-
-void SMESHDS_SubMesh::compactList()
-{
-  if ( myUnusedIdElements > 0 )
-  {
-    std::vector<const SMDS_MeshElement*> newElems;
-    newElems.reserve( myElements.size() - myUnusedIdElements );
-    for ( size_t i = 0; i < myElements.size(); i++)
-      if ( myElements[i] )
-      {
-        SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i];
-        elem->setIdInShape( newElems.size() );
-        newElems.push_back( elem );
-      }
-    myElements.swap(newElems);
-    myUnusedIdElements = 0;
-  }
-  else
-  {
-    std::vector<const SMDS_MeshElement*>( myElements ).swap( myElements );
-  }
-
-  if ( myUnusedIdNodes > 0 )
-  {
-    std::vector<const SMDS_MeshNode*> newNodes;
-    newNodes.reserve( myNodes.size() - myUnusedIdNodes );
-    for ( size_t i = 0; i < myNodes.size(); i++ )
-      if ( myNodes[i] )
-      {
-        SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i];
-        node->setIdInShape( newNodes.size() );
-        newNodes.push_back( node );
-      }
-    myNodes.swap(newNodes);
-    myUnusedIdNodes = 0;
-  }
-  else
-  {
-    std::vector<const SMDS_MeshNode*>( myNodes ).swap( myNodes );
-  }
-}
-
-//=======================================================================
-//function : GetElement
-//purpose  : Return an element by its IdInShape
-//=======================================================================
-
-const SMDS_MeshElement* SMESHDS_SubMesh::GetElement( size_t idInShape ) const
-{
-  return ( !IsComplexSubmesh() && idInShape < myElements.size() ) ? myElements[idInShape] : 0;
-}
-
-//=======================================================================
-//function : GetElement
-//purpose  : Return a node by its IdInShape
-//=======================================================================
-
-const SMDS_MeshNode* SMESHDS_SubMesh::GetNode( size_t idInShape ) const
-{
-  return ( !IsComplexSubmesh() && idInShape < myNodes.size() ) ? myNodes[idInShape] : 0;
-}