Salome HOME
IMP 23373: [CEA 1170] Optimization of a 3D mesh using MG-Tetra
[modules/smesh.git] / src / SMDS / SMDS_VtkFace.cxx
index 56787bda0c232b07520ca874f95269b23a248763..724a7ec211588565a55d5e698bb22567c54cf1d7 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2010-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // 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
@@ -44,44 +44,37 @@ SMDS_VtkFace::~SMDS_VtkFace()
 void SMDS_VtkFace::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
 {
   SMDS_MeshFace::init();
-  vtkUnstructuredGrid* grid = mesh->getGrid();
   myMeshId = mesh->getMeshId();
   vtkIdType aType = VTK_TRIANGLE;
   switch (nodeIds.size())
   {
-    case 3:
-      aType = VTK_TRIANGLE;
-      break;
-    case 4:
-      aType = VTK_QUAD;
-      break;
-    case 6:
-      aType = VTK_QUADRATIC_TRIANGLE;
-      break;
-    case 8:
-      aType = VTK_QUADRATIC_QUAD;
-      break;
-    case 9:
-      aType = VTK_BIQUADRATIC_QUAD;
-      break;
-    case 7:
-      aType = VTK_BIQUADRATIC_TRIANGLE;
-      break;
-    default:
-      aType = VTK_POLYGON;
-      break;
+    case 3:  aType = VTK_TRIANGLE;            break;
+    case 4:  aType = VTK_QUAD;                break;
+    case 6:  aType = VTK_QUADRATIC_TRIANGLE;  break;
+    case 8:  aType = VTK_QUADRATIC_QUAD;      break;
+    case 9:  aType = VTK_BIQUADRATIC_QUAD;    break;
+    case 7:  aType = VTK_BIQUADRATIC_TRIANGLE;break;
+    default: aType = VTK_POLYGON;
   }
-  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
   mesh->setMyModified();
-  //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID);
 }
 
 void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
 {
   SMDS_MeshFace::init();
-  vtkUnstructuredGrid* grid = mesh->getGrid();
   myMeshId = mesh->getMeshId();
-  myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  vtkIdType aType = VTK_POLYGON;
+  myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  mesh->setMyModified();
+}
+
+void SMDS_VtkFace::initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshFace::init();
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_QUADRATIC_POLYGON;
+  myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
   mesh->setMyModified();
 }
 
@@ -92,14 +85,14 @@ bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
   vtkIdType* pts = 0;
   grid->GetCellPoints(myVtkID, npts, pts);
   if (nbNodes != npts)
-    {
-      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
-      return false;
-    }
+  {
+    MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+    return false;
+  }
   for (int i = 0; i < nbNodes; i++)
-    {
-      pts[i] = nodes[i]->getVtkId();
-    }
+  {
+    pts[i] = nodes[i]->getVtkId();
+  }
   SMDS_Mesh::_meshList[myMeshId]->setMyModified();
   return true;
 }
@@ -111,26 +104,28 @@ void SMDS_VtkFace::Print(std::ostream & OS) const
 
 int SMDS_VtkFace::NbEdges() const
 {
-  // TODO quadratic polygons ?
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
   int nbEdges = 3;
   switch (aVtkType)
   {
-    case VTK_TRIANGLE:
-    case VTK_QUADRATIC_TRIANGLE:
-    case VTK_BIQUADRATIC_TRIANGLE:
-      nbEdges = 3;
-      break;
-    case VTK_QUAD:
-    case VTK_QUADRATIC_QUAD:
-    case VTK_BIQUADRATIC_QUAD:
-      nbEdges = 4;
-      break;
-    case VTK_POLYGON:
-    default:
-      nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
-      break;
+  case VTK_TRIANGLE:
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_TRIANGLE:
+    nbEdges = 3;
+    break;
+  case VTK_QUAD:
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    nbEdges = 4;
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbEdges = NbNodes() / 2;
+    break;
+  case VTK_POLYGON:
+  default:
+    nbEdges = NbNodes();
+    break;
   }
   return nbEdges;
 }
@@ -143,8 +138,9 @@ int SMDS_VtkFace::NbFaces() const
 int SMDS_VtkFace::NbNodes() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
-  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
-  return nbPoints;
+  vtkIdType *pts, npts;
+  grid->GetCellPoints( myVtkID, npts, pts );
+  return npts;
 }
 
 /*!
@@ -161,6 +157,22 @@ SMDS_VtkFace::GetNode(const int ind) const
   return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
 }
 
+/*!
+ * \brief Check if a node belongs to the element
+ * \param node - the node to check
+ * \retval int - node index within the element, -1 if not found
+ */
+int SMDS_VtkFace::GetNodeIndex( const SMDS_MeshNode* node ) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( this->myVtkID, npts, pts );
+  for ( vtkIdType i = 0; i < npts; ++i )
+    if ( pts[i] == node->getVtkId() )
+      return i;
+  return -1;
+}
+
 bool SMDS_VtkFace::IsQuadratic() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
@@ -170,6 +182,7 @@ bool SMDS_VtkFace::IsQuadratic() const
   {
     case VTK_QUADRATIC_TRIANGLE:
     case VTK_QUADRATIC_QUAD:
+    case VTK_QUADRATIC_POLYGON:
     case VTK_BIQUADRATIC_QUAD:
     case VTK_BIQUADRATIC_TRIANGLE:
       return true;
@@ -183,43 +196,47 @@ bool SMDS_VtkFace::IsPoly() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
-  return (aVtkType == VTK_POLYGON);
+  return ( aVtkType == VTK_POLYGON || aVtkType == VTK_QUADRATIC_POLYGON );
 }
 
 bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
   int rankFirstMedium = 0;
   switch (aVtkType)
   {
-    case VTK_QUADRATIC_TRIANGLE:
-    case VTK_BIQUADRATIC_TRIANGLE:
-      rankFirstMedium = 3; // medium nodes are of rank 3,4,5
-      break;
-    case VTK_QUADRATIC_QUAD:
-    case VTK_BIQUADRATIC_QUAD:
-      rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
-      break;
-    default:
-      //MESSAGE("wrong element type " << aVtkType);
-      return false;
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_TRIANGLE:
+    rankFirstMedium = 3; // medium nodes are of rank 3,4,5
+    break;
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    rankFirstMedium = npts / 2;
+    break;
+  default:
+    //MESSAGE("wrong element type " << aVtkType);
+    return false;
   }
-  vtkIdType npts = 0;
-  vtkIdType* pts = 0;
-  grid->GetCellPoints(myVtkID, npts, pts);
   vtkIdType nodeId = node->getVtkId();
   for (int rank = 0; rank < npts; rank++)
+  {
+    if (pts[rank] == nodeId)
     {
-      if (pts[rank] == nodeId)
-        {
-          //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
-          if (rank < rankFirstMedium)
-            return false;
-          else
-            return true;
-        }
+      //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
+      if (rank < rankFirstMedium)
+        return false;
+      else
+        return true;
     }
+  }
   //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
   MESSAGE("======================================================");
   MESSAGE("= IsMediumNode: node does not belong to this element =");
@@ -230,10 +247,19 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
 int SMDS_VtkFace::NbCornerNodes() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
-  int       nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  int       nbPoints = NbNodes();
   vtkIdType aVtkType = grid->GetCellType(myVtkID);
-  if ( aVtkType != VTK_POLYGON )
-    return nbPoints <= 4 ? nbPoints : nbPoints / 2;
+  switch ( aVtkType )
+  {
+  case VTK_POLYGON:
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbPoints /= 2;
+    break;
+  default:
+    if ( nbPoints > 4 )
+      nbPoints /= 2;
+  }
   return nbPoints;
 }
 
@@ -257,7 +283,8 @@ SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
   case VTK_QUADRATIC_QUAD:
   case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE;
 
-  case VTK_POLYGON: return SMDSGeom_POLYGON;
+  case VTK_POLYGON:
+  case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON;
   default:;
   }
   return SMDSGeom_NONE;