Salome HOME
introduce biquadratic quadratic pentahedron (18 nodes)
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index d70ff4bcdf59aebdf0e0fbcaf26a83f0033fae89..5a0be6428be41fc6512043af7385faf6a1d8324f 100644 (file)
@@ -56,7 +56,7 @@
 #include <iterator>
 using namespace std;
 
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
 #include <sys/sysinfo.h>
 #endif
 
@@ -77,7 +77,7 @@ int SMDS_Mesh::chunkSize = 1024;
 
 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 {
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
   struct sysinfo si;
   int err = sysinfo( &si );
   if ( err )
@@ -383,7 +383,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
   if ( !n1 || !n2 ) return 0;
   SMDS_MeshEdge * edge = 0;
 
-  // --- retreive nodes ID
+  // --- retrieve nodes ID
   vector<vtkIdType> nodeIds;
   nodeIds.clear();
   nodeIds.push_back(n1->getVtkId());
@@ -2458,6 +2458,49 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode
   return NULL;
 }
 
+//================================================================================
+/*!
+ * \brief Return elements including all given nodes
+ *  \param [in] nodes - nodes to find elements around
+ *  \param [out] foundElems - the found elements
+ *  \param [in] type - type of elements to find
+ *  \return int - a number of found elements
+ */
+//================================================================================
+
+int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
+                                  std::vector<const SMDS_MeshElement *>&    foundElems,
+                                  const SMDSAbs_ElementType                 type)
+{
+  // chose a node with minimal number of inverse elements
+  const SMDS_MeshNode* n0 = nodes[0];
+  int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
+  for ( size_t i = 1; i < nodes.size(); ++i )
+    if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
+    {
+      n0 = nodes[i];
+      minNbInverse = n0->NbInverseElements( type );
+    }
+
+  foundElems.clear();
+  if ( n0 )
+  {
+    foundElems.reserve( minNbInverse );
+    SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
+    while ( eIt->more() )
+    {
+      const SMDS_MeshElement* e = eIt->next();
+      bool includeAll = true;
+      for ( size_t i = 0; i < nodes.size() &&  includeAll; ++i )
+        if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
+          includeAll = false;
+      if ( includeAll )
+        foundElems.push_back( e );
+    }
+  }
+  return foundElems.size();
+}
+
 //=======================================================================
 //function : DumpNodes
 //purpose  :
@@ -2570,6 +2613,13 @@ int SMDS_Mesh::NbNodes() const
   return myInfo.NbNodes();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of elements
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbElements() const
+{
+  return myInfo.NbElements();
+}
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of 0D elements
 ///////////////////////////////////////////////////////////////////////////////
@@ -2812,7 +2862,7 @@ namespace {
     IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
                      const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
                      const int                        totalNb)
-      :myIDFact( fact ),
+      :myIDFact( const_cast<SMDS_MeshElementIDFactory&>(fact) ),
        myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
        myType( type ),
        myElem(0)
@@ -3226,7 +3276,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
           if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
             myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
           else {
-            ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
+            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
             delete (*it);
           }
           break;
@@ -3241,7 +3291,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
           if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
             myFacePool->destroy((SMDS_VtkFace*) vtkElem);
           else {
-            ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
+            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
             delete (*it);
           }
           break;
@@ -3256,7 +3306,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
           if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
             myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
           else {
-            ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
+            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
             delete (*it);
           }
           break;
@@ -3271,7 +3321,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
           if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
             myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
           else {
-            ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
+            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
             delete (*it);
           }
           break;
@@ -3322,22 +3372,24 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
   int elemId = elem->GetID();
-  int vtkId = elem->getVtkId();
+  int  vtkId = elem->getVtkId();
   SMDSAbs_ElementType aType = elem->GetType();
-  SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
-  if (aType == SMDSAbs_Node) {
+  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<SMDS_MeshNode*>(todest);
-    SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
-    if (!itFe->more()) { // free node
+    if ( n->NbInverseElements() == 0 ) { // free node
       myNodes[elemId] = 0;
       myInfo.myNbNodes--;
       ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
-      ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( -1, -1, -1 ); // avoid reuse
+      ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( 0, -1, -1 ); // avoid reuse
       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
       myNodeIDFactory->ReleaseID(elemId, vtkId);
     }
-  } else {
+  }
+  else
+  {
     if (hasConstructionEdges() || hasConstructionFaces())
       // this methods is only for meshes without descendants
       return;
@@ -3387,7 +3439,7 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
     // --- to do: keep vtkid in a list of reusable cells
 
     if ( elem )
-      ((SMDS_MeshElement*) elem)->init( -1, -1, -1 ); // avoid reuse
+      ((SMDS_MeshElement*) elem)->init( 0, -1, -1 ); // avoid reuse
   }
 }
 
@@ -4158,7 +4210,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  :
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n2,
@@ -4186,7 +4238,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  :
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                             int n4, int n5, int n6,
@@ -4215,7 +4267,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 2d order Pentahedron with 15 nodes
+//purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
@@ -4282,6 +4334,146 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   return volvtk;
 }
 
+//=======================================================================
+//function : AddVolume
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6,
+                                      const SMDS_MeshNode * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n31,
+                                      const SMDS_MeshNode * n45,
+                                      const SMDS_MeshNode * n56,
+                                      const SMDS_MeshNode * n64,
+                                      const SMDS_MeshNode * n14,
+                                      const SMDS_MeshNode * n25,
+                                      const SMDS_MeshNode * n36,
+                                      const SMDS_MeshNode * n1245,
+                                      const SMDS_MeshNode * n2356,
+                                      const SMDS_MeshNode * n1346)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
+                               n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
+                                            int n4, int n5, int n6,
+                                            int n12,int n23,int n31,
+                                            int n45,int n56,int n64,
+                                            int n14,int n25,int n36,
+                                            int n1245, int n2356, int n1346, int ID)
+{
+  return SMDS_Mesh::AddVolumeWithID
+    ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346),
+     ID);
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Pentahedron (prism) with 18 nodes
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n31,
+                                            const SMDS_MeshNode * n45,
+                                            const SMDS_MeshNode * n56,
+                                            const SMDS_MeshNode * n64,
+                                            const SMDS_MeshNode * n14,
+                                            const SMDS_MeshNode * n25,
+                                            const SMDS_MeshNode * n36,
+                                            const SMDS_MeshNode * n1245,
+                                            const SMDS_MeshNode * n2356,
+                                            const SMDS_MeshNode * n1346,
+                                            int ID)
+{
+  if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
+      !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
+    return 0;
+  if(hasConstructionFaces()) {
+    // creation quadratic faces - not implemented
+    return 0;
+  }
+  // --- retrieve nodes ID
+  myNodeIds.resize(15);
+  myNodeIds[0] = n1->getVtkId();
+  myNodeIds[1] = n2->getVtkId();
+  myNodeIds[2] = n3->getVtkId();
+
+  myNodeIds[3] = n4->getVtkId();
+  myNodeIds[4] = n5->getVtkId();
+  myNodeIds[5] = n6->getVtkId();
+
+  myNodeIds[6] = n12->getVtkId();
+  myNodeIds[7] = n23->getVtkId();
+  myNodeIds[8] = n31->getVtkId();
+
+  myNodeIds[9] = n45->getVtkId();
+  myNodeIds[10] = n56->getVtkId();
+  myNodeIds[11] = n64->getVtkId();
+
+  myNodeIds[12] = n14->getVtkId();
+  myNodeIds[13] = n25->getVtkId();
+  myNodeIds[14] = n36->getVtkId();
+
+  myNodeIds[15] = n1245->getVtkId();
+  myNodeIds[16] = n2356->getVtkId();
+  myNodeIds[17] = n1346->getVtkId();
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(myNodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+  {
+    this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+    myVolumePool->destroy(volvtk);
+    return 0;
+  }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
+  myInfo.myNbBiQuadPrisms++;
+
+  //  if (!registerElement(ID, volvtk)) {
+  //    RemoveElement(volvtk, false);
+  //    volvtk = NULL;
+  //  }
+  return volvtk;
+}
+
 
 //=======================================================================
 //function : AddVolume