]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMESHDS/SMESHDS_SubMesh.cxx
Salome HOME
Revert "23418: [OCC] Mesh: Minimization of memory usage of SMESH"
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.cxx
index 4a086e3b7073fc8d84be84192fe8c158b8302076..89287301641073332320037784571d4cf499aa12 100644 (file)
 //  $Header: 
 //
 #include "SMESHDS_SubMesh.hxx"
-
 #include "SMESHDS_Mesh.hxx"
+
+#include "utilities.h"
 #include "SMDS_SetIterator.hxx"
-#include "SMDS_ElementFactory.hxx"
+#include <iostream>
+#include <cassert>
+
+using namespace std;
 
-#include <utilities.h>
 
 //================================================================================
 /*!
@@ -44,8 +47,8 @@ SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
   myIndex = index;
-  myNbElements = 0;
-  myNbNodes = 0;
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
 }
 
 //================================================================================
@@ -63,16 +66,16 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh()
 //purpose  :
 //=======================================================================
 
-void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
+void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
   if (!IsComplexSubmesh())
   {
-    if ( elem->GetType() == SMDSAbs_Node )
+    if ( ME->GetType() == SMDSAbs_Node )
     {
-      AddNode( static_cast< const SMDS_MeshNode* >( elem ));
+      AddNode( static_cast< const SMDS_MeshNode* >( ME ));
       return;
     }
-    int oldShapeId = elem->GetShapeID();
+    int oldShapeId = ME->getshapeId();
     if ( oldShapeId > 0 )
     {
       if (oldShapeId != myIndex)
@@ -80,10 +83,28 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
         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;
+      }
     }
 
-    elem->setShapeID( myIndex );
-    myNbElements++;
+    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+    elem->setShapeId(myIndex);
+    elem->setIdInShape(myElements.size());
+    myElements.push_back(ME);
   }
 }
 
@@ -92,17 +113,41 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem)
 //purpose  :
 //=======================================================================
 
-bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem )
+bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
 {
-  if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex )
+  if (!ME)
   {
     return false;
   }
-  if ( !IsComplexSubmesh() )
+  if (!IsComplexSubmesh())
   {
-    elem->setShapeID( 0 );
-    myNbElements--;
-    return true;
+    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;
   }
   return false;
 }
@@ -116,16 +161,22 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 {
   if ( !IsComplexSubmesh() )
   {
-    const int shapeId = N->getshapeId();
-    if ( shapeId > 0 )
+    const int idInSubShape = N->getIdInShape();
+    const int shapeId      = N->getshapeId();
+    if ((shapeId > 0) && (idInSubShape >= 0))
     {
       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
     }
-    N->setShapeID( myIndex );
-    myNbNodes++;
+    SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
+    node->setShapeId(myIndex);
+    node->setIdInShape(myNodes.size());
+    myNodes.push_back(N);
   }
 }
 
@@ -134,18 +185,38 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 //purpose  :
 //=======================================================================
 
-bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
+bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 {
-  if ( !N || N->getshapeId() != myIndex )
+  if (!IsComplexSubmesh())
   {
+    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;
   }
-  if ( !IsComplexSubmesh() )
-  {
-    N->setShapeID( 0 );
-    myNbNodes--;
-    return true;
-  }
   return false;
 }
 
@@ -157,10 +228,10 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 int SMESHDS_SubMesh::NbElements() const
 {
   if ( !IsComplexSubmesh() )
-    return myNbElements;
+    return myElements.size() - myUnusedIdElements;
 
   int nbElems = 0;
-  TSubMeshSet::const_iterator it = mySubMeshes.begin();
+  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbElements();
 
@@ -175,10 +246,10 @@ int SMESHDS_SubMesh::NbElements() const
 int SMESHDS_SubMesh::NbNodes() const
 {
   if ( !IsComplexSubmesh() )
-    return myNbNodes;
+    return myNodes.size() - myUnusedIdNodes;
 
   int nbElems = 0;
-  TSubMeshSet::const_iterator it = mySubMeshes.begin();
+  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbNodes();
 
@@ -235,7 +306,7 @@ public:
 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 {
 public:
-  MyIterator (const TSubMeshSet& theSubMeshes)
+  MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
     : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() )
   {}
   bool more()
@@ -260,9 +331,9 @@ protected:
   getElements(const SMESHDS_SubMesh*) const = 0;
 
 private:
-  bool                                      myMore;
-  TSubMeshSet::const_iterator               mySubIt, mySubEnd;
-  boost::shared_ptr< SMDS_Iterator<VALUE> > myElemIt;
+  bool                                        myMore;
+  set<const SMESHDS_SubMesh*>::const_iterator mySubIt, mySubEnd;
+  boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
 };
 
 // =====================
@@ -272,7 +343,7 @@ private:
 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
 {
 public:
-  MyElemIterator (const TSubMeshSet& theSubMeshes)
+  MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
     :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
   SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetElements(); }
@@ -285,7 +356,7 @@ public:
 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
 {
 public:
-  MyNodeIterator (const TSubMeshSet& theSubMeshes)
+  MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
     :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
   SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
   { return theSubMesh->GetNodes(); }
@@ -296,12 +367,13 @@ public:
 //purpose  :
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
+SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements( bool reverse ) const
 {
   if ( IsComplexSubmesh() )
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
 
-  return myParent->shapeElementsIterator( myIndex, myNbElements );
+  typedef MySetIterator< const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> > TIter;
+  return SMDS_ElemIteratorPtr( new TIter( myElements, reverse ));
 }
 
 //=======================================================================
@@ -309,12 +381,13 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
 //purpose  :
 //=======================================================================
 
-SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
+SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes( bool reverse ) const
 {
   if ( IsComplexSubmesh() )
     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
 
-  return myParent->shapeNodesIterator( myIndex, myNbNodes );
+  typedef MySetIterator< const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> > TIter;
+  return SMDS_NodeIteratorPtr( new TIter( myNodes, reverse ));
 }
 
 //=======================================================================
@@ -324,18 +397,35 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
 
 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
 {
-  if ( !ME || ME->IsNull() )
+  // DO NOT TRY TO FIND A REMOVED ELEMENT !!
+  //if ( IsComplexSubmesh() || !ME )
+  if (!ME)
     return false;
 
   if ( IsComplexSubmesh() )
   {
-    TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->Contains(ME))
         return true;
     return false;
   }
-  return ME->getshapeId() == myIndex;
+
+  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;
 }
 
 //=======================================================================
@@ -347,18 +437,18 @@ bool SMESHDS_SubMesh::IsQuadratic() const
 {
   if ( IsComplexSubmesh() )
   {
-    TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin();
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
     for (; aSubIt != mySubMeshes.end(); aSubIt++)
       if ((*aSubIt)->IsQuadratic())
         return true;
     return false;
   }
 
-  if ( myNbElements == 0 )
-    return false;
+  for ( size_t i = 0; i < myElements.size(); ++i )
+    if ( myElements[i] )
+      return myElements[i]->IsQuadratic();
 
-  SMDS_ElemIteratorPtr it = GetElements();
-  return it->more() && it->next()->IsQuadratic();
+  return false;
 }
 
 //=======================================================================
@@ -409,8 +499,10 @@ bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
 
 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
 {
-  typedef SMDS_SetIterator< const SMESHDS_SubMesh*, TSubMeshSet::const_iterator > TIterator;
-  return boost::make_shared< TIterator >( mySubMeshes.begin(), mySubMeshes.end());
+  typedef set<const SMESHDS_SubMesh*>::const_iterator TIterator;
+  return SMESHDS_SubMeshIteratorPtr
+    ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(),
+                                                                 mySubMeshes.end()));
 }
 
 //=======================================================================
@@ -422,22 +514,26 @@ void SMESHDS_SubMesh::Clear()
 {
   if ( myParent && myParent->NbNodes() > 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 );
-      }
+    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 );
+    }
   }
 
-  myNbElements = 0;
-  myNbNodes = 0;
+  clearVector( myElements );
+  clearVector( myNodes );
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
   if ( NbSubMeshes() > 0 )
   {
     SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
@@ -447,3 +543,71 @@ 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;
+}