Salome HOME
Fix regressions caused by improvements
[modules/smesh.git] / src / SMESHDS / SMESHDS_SubMesh.cxx
index 32073bb50bb9e179eca45bf9f615772fc798acc3..04a0021fc0fc2ef501ec1209d7c075c485fe3e8f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -6,7 +6,7 @@
 // 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.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -46,8 +46,6 @@ using namespace std;
 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
-  myElements.clear();
-  myNodes.clear();
   myIndex = index;
   myUnusedIdNodes = 0;
   myUnusedIdElements = 0;
@@ -65,88 +63,83 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh()
 
 //=======================================================================
 //function : AddElement
-//purpose  : 
+//purpose  :
 //=======================================================================
+
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
   if (!IsComplexSubmesh())
+  {
+    if ( ME->GetType() == SMDSAbs_Node )
     {
-      if ( ME->GetType() == SMDSAbs_Node )
+      AddNode( static_cast< const SMDS_MeshNode* >( ME ));
+      return;
+    }
+    int oldShapeId = ME->getshapeId();
+    if ( oldShapeId > 0 )
+    {
+      if (oldShapeId != myIndex)
       {
-        AddNode( static_cast< const SMDS_MeshNode* >( ME ));
-        return;
+        throw SALOME_Exception
+          (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
-      //MESSAGE("in " << myIndex << " AddElement "<< ME->GetID());
-      int oldShapeId = ME->getshapeId();
-      if ( oldShapeId > 0 )
+      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 >= myElements.size())
         {
-          if (oldShapeId != myIndex)
-            {
-              MESSAGE("add element in subshape already belonging to another subshape "
-                << ME->GetID() << " " << oldShapeId << " " << myIndex);
-              throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape"));
-            }
-          else
-            {
-              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 >= myElements.size())
-                    {
-                      MESSAGE("out of bounds " << idInSubShape << " " << myElements.size());
-                      throw SALOME_Exception(LOCALIZED("out of bounds"));
-                    }
-                  if (ME != myElements[idInSubShape])
-                    {
-                      MESSAGE("not the same element");
-                      throw SALOME_Exception(LOCALIZED("not the same element"));
-                    }
-                  MESSAGE("already done, OK, nothing to do");
-                  return;
-                }
-            }
+          throw SALOME_Exception(LOCALIZED("out of bounds"));
         }
-
-      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-      elem->setShapeId(myIndex);
-      elem->setIdInShape(myElements.size());
-      myElements.push_back(ME);
+        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);
+  }
 }
 
 //=======================================================================
 //function : RemoveElement
-//purpose  : 
+//purpose  :
 //=======================================================================
+
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
 {
   if (!ME)
-    {
-      MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
-      return false;
-    }
-  //MESSAGE("-----------------> RemoveElement "<< ME->GetID() << " " << isElemDeleted);
+  {
+    MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
+    return false;
+  }
   if (!IsComplexSubmesh())
-    {
-      if ( ME->getshapeId() != myIndex )
-        return false;
-      int idInSubShape = ME->getIdInShape();
-      //MESSAGE("in "<< myIndex << " RemoveElement " << ME->GetID() << " " << idInSubShape << " " << myUnusedIdElements);
-      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-      elem->setShapeId(0);
-      elem->setIdInShape(-1);
-      if ((idInSubShape >= 0) && (idInSubShape < myElements.size()))
-        {
-          myElements[idInSubShape] = 0; // this vector entry is no more used
-          myUnusedIdElements++;
-          return true;
-        }
+  {
+    if ( ME->getshapeId() != myIndex )
       return false;
-      //  }
+    int idInSubShape = ME->getIdInShape();
+    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+    elem->setShapeId(0);
+    elem->setIdInShape(-1);
+    if ((idInSubShape >= 0) && (idInSubShape < 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;
+  }
   MESSAGE("Try to remove an element from a complex submesh ");
   return false;
 }
@@ -155,55 +148,57 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele
 //function : AddNode
 //purpose  : 
 //=======================================================================
+
 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 {
   if ( !IsComplexSubmesh() )
+  {
+    const int idInSubShape = N->getIdInShape();
+    const int shapeId      = N->getshapeId();
+    if ((shapeId > 0) && (idInSubShape >= 0))
     {
-      int idInSubShape = N->getIdInShape();
-      int shapeId = N->getshapeId();
-      if ((shapeId > 0) && (idInSubShape >= 0))
-        {
-//           MESSAGE("========== AddNode already belonging to other subShape " << N->GetID());
-          // OK for vertex nodes
-          throw SALOME_Exception(LOCALIZED("add node in subshape already belonging to a subshape"));
-        }
-      SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
-      node->setShapeId(myIndex);
-      node->setIdInShape(myNodes.size());
-      myNodes.push_back(N);
-      //MESSAGE("in "<< myIndex << " AddNode " << node->GetID());
+      if ( shapeId != myIndex )
+        throw SALOME_Exception
+          (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
+      if ( idInSubShape >= 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
     }
-  //MESSAGE("try to add node in a complex submesh " << N->GetID());
+    SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
+    node->setShapeId(myIndex);
+    node->setIdInShape(myNodes.size());
+    myNodes.push_back(N);
+  }
 }
 
 //=======================================================================
 //function : RemoveNode
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 {
   if (!IsComplexSubmesh())
-    {
-      // if (!isNodeDeleted) // alive node has valid ID and can be found
-      // {
-      if ( N->getshapeId() != myIndex )
-        return false;
-      int idInSubShape = N->getIdInShape();
-      //int shapeId = N->getshapeId();
-      //MESSAGE("in "<< myIndex << " RemoveNode " << shapeId << " " << idInSubShape << " " << N->GetID());
-      SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
-      node->setShapeId(0);
-      node->setIdInShape(-1);
-      if ((idInSubShape >= 0) && (idInSubShape < myNodes.size()))
-        {
-          myNodes[idInSubShape] = 0; // this vector entry is no more used
-          myUnusedIdNodes++;
-          return true;
-        }
+  {
+    if ( N->getshapeId() != myIndex )
       return false;
-      // }
+    int idInSubShape = N->getIdInShape();
+    SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
+    node->setShapeId(0);
+    node->setIdInShape(-1);
+    if ((idInSubShape >= 0) && (idInSubShape < 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;
+  }
   MESSAGE("Try to remove a node from a complex submesh");
   return false;
 }
@@ -212,9 +207,9 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 //function : NbElements
 //purpose  : 
 //=======================================================================
+
 int SMESHDS_SubMesh::NbElements() const
 {
-  //MESSAGE(this << " NbElements " << IsComplexSubmesh() << " " << myElements.size() - myUnusedIdElements);
   if ( !IsComplexSubmesh() )
     return myElements.size() - myUnusedIdElements;
 
@@ -233,7 +228,6 @@ int SMESHDS_SubMesh::NbElements() const
 
 int SMESHDS_SubMesh::NbNodes() const
 {
-  //MESSAGE(this << " NbNodes " << IsComplexSubmesh() << " " << myNodes.size() - myUnusedIdNodes);
   if ( !IsComplexSubmesh() )
     return myNodes.size() - myUnusedIdNodes;
 
@@ -382,29 +376,52 @@ bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
   if (!ME)
     return false;
 
-  if (IsComplexSubmesh())
-    {
-      set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
-      for (; aSubIt != mySubMeshes.end(); aSubIt++)
-        if ((*aSubIt)->Contains(ME))
-          return true;
-      return false;
-    }
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    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 < myNodes.size()))
-        if (myNodes[idInShape] == ME)
-          return true;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < myNodes.size()))
+      if (myNodes[idInShape] == ME)
+        return true;
+  }
   else
-    {
-      int idInShape = ME->getIdInShape();
-      if ((idInShape >= 0) && (idInShape < myElements.size()))
-        if (myElements[idInShape] == ME)
-          return true;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < myElements.size()))
+      if (myElements[idInShape] == ME)
+        return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : IsQuadratic
+//purpose  : Return true if my 1st element is quadratic
+//=======================================================================
+
+bool SMESHDS_SubMesh::IsQuadratic() const
+{
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    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();
+
   return false;
 }
 
@@ -469,14 +486,17 @@ SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
 
 void SMESHDS_SubMesh::Clear()
 {
-  myElements.clear();
-  myNodes.clear();
+  clearVector( myElements );
+  clearVector( myNodes );
   myUnusedIdNodes = 0;
   myUnusedIdElements = 0;
-  SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
-  while ( sub->more() ) {
-    if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
-      sm->Clear();
+  if ( NbSubMeshes() > 0 )
+  {
+    SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
+    while ( sub->more() ) {
+      if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
+        sm->Clear();
+    }
   }
 }
 
@@ -484,53 +504,38 @@ int SMESHDS_SubMesh::getSize()
 {
   int c = NbNodes();
   int d = NbElements();
-  //cerr << "SMESHDS_SubMesh::NbNodes " << c << endl;
-  //cerr << "SMESHDS_SubMesh::NbElements " << d << endl;
   return c+d;
 }
 
 void SMESHDS_SubMesh::compactList()
 {
-  //MESSAGE("compactList old: nodes " << myNodes.size() << " elements " << myElements.size());
-  //stringstream a;
-  //stringstream b;
-  //stringstream c;
-  //stringstream d;
-
-  std::vector<const SMDS_MeshElement*> newElems;
-  newElems.clear();
-  for (int i = 0; i < myElements.size(); i++)
-    if (myElements[i])
+  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);
-        //a << elem->GetID() << " ";
-        //b << elem->GetID() << " ";
       }
-    //else
-    //  a << "_ ";
-  myElements.swap(newElems);
-  myUnusedIdElements = 0;
-  //MESSAGE("in " << myIndex << " oldElems " << a.str());
-  //MESSAGE("in " << myIndex << " newElems " << b.str());
+    myElements.swap(newElems);
+    myUnusedIdElements = 0;
+  }
 
-  std::vector<const SMDS_MeshNode*> newNodes;
-  newNodes.clear();
-  for (int i = 0; i < myNodes.size(); i++)
-    if (myNodes[i])
+  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);
-        //c << node->GetID() << " ";
-        //d << node->GetID() << " ";
       }
-    //else
-    //  c << "_ ";
-  myNodes.swap(newNodes);
-  myUnusedIdNodes = 0;
-  //MESSAGE("in " << myIndex << " oldNodes " << c.str());
-  //MESSAGE("in " << myIndex << " newNodes " << d.str());
-  //MESSAGE("compactList new: nodes " << myNodes.size() << " elements " << myElements.size());
+    myNodes.swap(newNodes);
+    myUnusedIdNodes = 0;
+  }
 }