Salome HOME
PR: adjust points number
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index cd0196c3cd954c6a12859e90965186fd8c4eaf13..1fbe8d3242dfeed12b3baa2fd118fe8fd394c99e 100644 (file)
 #include "SMDS_QuadraticEdge.hxx"
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SpacePosition.hxx"
 
 #include <vtkUnstructuredGrid.h>
+#include <vtkUnsignedCharArray.h>
 
 #include <algorithm>
 #include <map>
@@ -47,7 +49,7 @@ using namespace std;
 #include <sys/sysinfo.h>
 #endif
 
-// number of added entitis to check memory after
+// number of added entities to check memory after
 #define CHECKMEMORY_INTERVAL 1000
 
 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
@@ -115,15 +117,23 @@ SMDS_Mesh::SMDS_Mesh()
          myHasConstructionEdges(false), myHasConstructionFaces(false),
          myHasInverseElements(true),
          myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
-         myNodePool(0), myVolumePool(0)
+         myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
 {
   myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
   MESSAGE("myMeshId=" << myMeshId);
+  MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
+  MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
+  MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
+  MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
+  MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
+  MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
   myNodeIDFactory->SetMesh(this);
   myElementIDFactory->SetMesh(this);
   _meshList.push_back(this);
   myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
-  myVolumePool = new ObjectPool<SMDS_VolumeVtkNodes>(SMDS_Mesh::chunkSize);
+  myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+  myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+  myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
 
   myNodes.clear();
   myCells.clear();
@@ -150,6 +160,8 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
          myHasConstructionEdges(false), myHasConstructionFaces(false),
          myHasInverseElements(true),
          myNodePool(parent->myNodePool),
+         myEdgePool(parent->myEdgePool),
+         myFacePool(parent->myFacePool),
          myVolumePool(parent->myVolumePool)
 {
 }
@@ -288,10 +300,17 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
   if ( !n1 || !n2 ) return 0;
+  SMDS_MeshEdge * edge = 0;
 
-  //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  //MESSAGE("AddEdgeWithID " << ID)
-  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
+  // --- retreive nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getId());
+  nodeIds.push_back(n2->getId());
+
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  edge = edgevtk;
   adjustmyCellsCapacity(ID);
   myCells[ID] = edge;
   myInfo.myNbEdges++;
@@ -339,7 +358,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
     //MESSAGE("AddFaceWithID " << ID)
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
 
   if (face && !registerElement(ID, face)) {
     RemoveElement(face, false);
@@ -558,7 +577,17 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n3->getId()); // order SMDS-->VTK
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n4->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
     adjustmyCellsCapacity(ID);
     myCells[ID] = volume;
     myInfo.myNbTetras++;
@@ -649,7 +678,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n5->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
     adjustmyCellsCapacity(ID);
     myCells[ID] = volume;
     myInfo.myNbPyramids++;
@@ -745,7 +785,19 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n6->getId());
+    nodeIds.push_back(n5->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
     adjustmyCellsCapacity(ID);
     myCells[ID] = volume;
     myInfo.myNbPrisms++;
@@ -853,20 +905,19 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    // --- retreive nodes ID
+    // --- retrieve nodes ID
     vector<vtkIdType> nodeIds;
     nodeIds.clear();
     nodeIds.push_back(n1->getId());
-    nodeIds.push_back(n2->getId());
-    nodeIds.push_back(n3->getId());
     nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
     nodeIds.push_back(n5->getId());
-    nodeIds.push_back(n6->getId());
-    nodeIds.push_back(n7->getId());
     nodeIds.push_back(n8->getId());
+    nodeIds.push_back(n7->getId());
+    nodeIds.push_back(n6->getId());
 
-    //volume = new SMDS_VolumeVtkNodes(nodeIds, this);
-    SMDS_VolumeVtkNodes *volvtk = myVolumePool->getNew();
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
     volvtk->init(nodeIds, this);
     volume = volvtk;
     adjustmyCellsCapacity(ID);
@@ -1168,7 +1219,7 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
   element->myMeshId = myMeshId;
 
   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
-  assert(cell);
+  MYASSERT(cell);
   int vtkId = cell->getVtkId();  
   if (vtkId == -1)
     vtkId = myElementIDFactory->SetInVtkGrid(element);
@@ -1198,18 +1249,22 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  if (ID <0 || ID >= myNodes.size())
-    return NULL;
+  if (ID < 0 || ID >= myNodes.size())
+  {
+    MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
+    return 0;
+  }
   return (const SMDS_MeshNode *)myNodes[ID];
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This methode do not bind a
+///Create a triangle and add it to the current mesh. This method do not bind an
 ///ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                                           const SMDS_MeshNode * node2,
-                                          const SMDS_MeshNode * node3)
+                                          const SMDS_MeshNode * node3,
+                                          int ID)
 {
   if ( !node1 || !node2 || !node3) return 0;
 //  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -1220,7 +1275,7 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
     edge2=FindEdgeOrCreate(node2,node3);
     edge3=FindEdgeOrCreate(node3,node1);
 
-    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
+    //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
     adjustmyCellsCapacity(ID);
     myCells[ID] = face;
@@ -1229,8 +1284,17 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
   }
   else
   {
-    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+    nodeIds.push_back(node3->getId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    face = facevtk;
     adjustmyCellsCapacity(ID);
     myCells[ID] = face;
     myInfo.myNbTriangles++;
@@ -1267,8 +1331,18 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
   }
   else
   {
-      //MESSAGE("createQuadrangle " << ID);
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+    nodeIds.push_back(node3->getId());
+    nodeIds.push_back(node4->getId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    face = facevtk;
     adjustmyCellsCapacity(ID);
     myCells[ID] = face;
     myInfo.myNbQuadrangles++;
@@ -1369,6 +1443,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
                                    const SMDS_MeshNode    * nodes[],
                                    const int                nbnodes)
 {
+  MYASSERT(0); // REVOIR LES TYPES
   // keep current nodes of elem
   set<const SMDS_MeshElement*> oldNodes;
   SMDS_ElemIteratorPtr itn = element->nodesIterator();
@@ -1390,7 +1465,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   }
   case SMDSAbs_Edge: {
     if ( nbnodes == 2 ) {
-      if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
+      if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
         Ok = edge->ChangeNodes( nodes[0], nodes[1] );
     }
     else if ( nbnodes == 3 ) {
@@ -1604,7 +1679,14 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
     //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     adjustmyCellsCapacity(ID);
-    toReturn=new SMDS_MeshEdge(node1,node2);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+
+    SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+    edgevtk->init(nodeIds, this);
+    toReturn = edgevtk;
     myCells[ID] = toReturn;
     myInfo.myNbEdges++;
   }
@@ -1702,7 +1784,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
   if(toReturn==NULL) {
-    toReturn = createTriangle(node1,node2,node3);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn = createTriangle(node1,node2,node3, ID);
   }
   return toReturn;
 }
@@ -1886,7 +1969,10 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
   if ((IDelem < 0) || IDelem >= myCells.size())
-      return 0;
+  {
+    MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+    return 0;
+  }
   return myCells[IDelem];
 }
 
@@ -2435,7 +2521,9 @@ static set<const SMDS_MeshElement*> * intersectionOfSets(
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the list of finit elements owning the given element
+/// Return the list of finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
@@ -2447,16 +2535,24 @@ static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement *
         int i=0;
         while(itNodes->more())
         {
-                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+          const SMDS_MeshElement* node = itNodes->next();
+          MYASSERT(node);
+                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
 
                 //initSet[i]=set<const SMDS_MeshElement*>();
                 while(itFe->more())
-                  initSet[i].insert(itFe->next());
+                {
+                  const SMDS_MeshElement* elem = itFe->next();
+                  MYASSERT(elem);
+                  initSet[i].insert(elem);
+
+                }
 
                 i++;
         }
         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        MESSAGE("nb elems " << i << " intersection " << retSet->size());
         delete [] initSet;
         return retSet;
 }
@@ -2571,8 +2667,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
 
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
-///@param removedElems contains all removed elements
-///@param removedNodes contains all removed nodes
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
@@ -2580,6 +2676,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
                               list<const SMDS_MeshElement *>& removedNodes,
                               bool                            removenodes)
 {
+  MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
   // get finite elements built on elem
   set<const SMDS_MeshElement*> * s1;
   if (elem->GetType() == SMDSAbs_0DElement ||
@@ -2632,7 +2729,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     switch((*it)->GetType())
     {
     case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happen");
+      MYASSERT("Internal Error: This should not happen");
       break;
     case SMDSAbs_0DElement:
       myCells[(*it)->GetID()] = 0;  // -PR- ici ou dans myElementIDFactory->ReleaseID ?
@@ -2654,6 +2751,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
     removedElems.push_back( (*it) );
     myElementIDFactory->ReleaseID((*it)->GetID());
+    MYASSERT("problem delete elem")
     delete (*it);
     it++;
   }
@@ -2669,6 +2767,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
       myInfo.myNbNodes--;
       myNodeIDFactory->ReleaseID((*it)->GetID());
       removedNodes.push_back( (*it) );
+      MYASSERT("problem delete node")
       delete *it;
       it++;
     }
@@ -2684,22 +2783,27 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
+  int elemId = elem->GetID();
+  MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
   SMDSAbs_ElementType aType = elem->GetType();
+  SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
   if (aType == SMDSAbs_Node) {
     // only free node can be removed by this method
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
+    const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
     if (!itFe->more()) { // free node
-      myNodes[elem->GetID()] = 0;
+      myNodes[elemId] = 0;
       myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID(elem->GetID());
-      delete elem;
+      myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+      myNodeIDFactory->ReleaseID(elemId);
     }
   } else {
     if (hasConstructionEdges() || hasConstructionFaces())
       // this methods is only for meshes without descendants
       return;
 
+    int vtkid = this->fromSmdsToVtk(elemId);
+
     // Remove element from <InverseElements> of its nodes
     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
     while (itn->more()) {
@@ -2709,28 +2813,34 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
     }
 
     // in meshes without descendants elements are always free
-    switch (aType) {
+     switch (aType) {
     case SMDSAbs_0DElement:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.remove(elem);
+      delete elem;
       break;
     case SMDSAbs_Edge:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.RemoveEdge(elem);
+      myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
       break;
     case SMDSAbs_Face:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.RemoveFace(elem);
+      myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
       break;
     case SMDSAbs_Volume:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.RemoveVolume(elem);
+      myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
       break;
     default:
       break;
     }
-    myElementIDFactory->ReleaseID(elem->GetID());
-    delete elem;
+    myElementIDFactory->ReleaseID(elemId);
+
+    this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+    // --- to do: keep vtkid in a list of reusable cells
   }
 }
 
@@ -3478,3 +3588,9 @@ void SMDS_Mesh::incrementCellsCapacity(int nbCells)
   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
   myNodes.resize(val +nbCells, 0);
 }
+
+void SMDS_Mesh::adjustStructure()
+{
+  myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
+}
+