Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/smesh.git] / src / SMDS / SMDS_VtkFace.cxx
diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx
new file mode 100644 (file)
index 0000000..80644c7
--- /dev/null
@@ -0,0 +1,301 @@
+// Copyright (C) 2010-2012  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.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+using namespace std;
+
+SMDS_VtkFace::SMDS_VtkFace()
+{
+}
+
+SMDS_VtkFace::SMDS_VtkFace(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+
+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;
+    default:
+      aType = VTK_POLYGON;
+      break;
+  }
+  myVtkID = grid->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]);
+  mesh->setMyModified();
+}
+
+bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      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();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+void SMDS_VtkFace::Print(std::ostream & OS) const
+{
+  OS << "face <" << GetID() << "> : ";
+}
+
+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:
+      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;
+  }
+  return nbEdges;
+}
+
+int SMDS_VtkFace::NbFaces() const
+{
+  return 1;
+}
+
+int SMDS_VtkFace::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  return nbPoints;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode*
+SMDS_VtkFace::GetNode(const int ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( this->myVtkID, npts, pts );
+  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
+}
+
+bool SMDS_VtkFace::IsQuadratic() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  // TODO quadratic polygons ?
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TRIANGLE:
+    case VTK_QUADRATIC_QUAD:
+    case VTK_BIQUADRATIC_QUAD:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+bool SMDS_VtkFace::IsPoly() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return (aVtkType == VTK_POLYGON);
+}
+
+bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int rankFirstMedium = 0;
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_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;
+  }
+  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)
+        {
+          //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 =");
+  MESSAGE("======================================================");
+  return false;
+}
+
+int SMDS_VtkFace::NbCornerNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int       nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  vtkIdType aVtkType = grid->GetCellType(myVtkID);
+  if ( aVtkType != VTK_POLYGON )
+    return nbPoints <= 4 ? nbPoints : nbPoints / 2;
+  return nbPoints;
+}
+
+SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return SMDS_MeshCell::toSmdsType( VTKCellType( aVtkType ));
+}
+
+SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  switch ( aVtkType ) {
+  case VTK_TRIANGLE:
+  case VTK_QUADRATIC_TRIANGLE:
+    return SMDSGeom_TRIANGLE;
+  case VTK_QUAD:
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    return SMDSGeom_QUADRANGLE;
+  case VTK_POLYGON:
+    return SMDSGeom_POLYGON;
+  default:;
+  }
+  return SMDSGeom_NONE;
+}
+
+vtkIdType SMDS_VtkFace::GetVtkType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return aVtkType;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      MESSAGE("ERROR : Iterator not implemented")
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor
+void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  grid->RemoveReferenceToCell(pts[0], myVtkID);
+  pts[0] = node->getVtkId();
+  node->AddInverseElement(this),
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+}