Salome HOME
PR: fix QuadToTriaAdaptor
[modules/smesh.git] / src / SMDS / SMDS_VtkFace.cxx
1 #include "SMDS_VtkFace.hxx"
2 #include "SMDS_MeshNode.hxx"
3 #include "SMDS_Mesh.hxx"
4 #include "SMDS_VtkCellIterator.hxx"
5
6 #include "utilities.h"
7
8 #include <vector>
9
10 using namespace std;
11
12 SMDS_VtkFace::SMDS_VtkFace()
13 {
14 }
15
16 SMDS_VtkFace::SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
17 {
18   init(nodeIds, mesh);
19 }
20
21 SMDS_VtkFace::~SMDS_VtkFace()
22 {
23 }
24
25 void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
26 {
27   SMDS_MeshFace::init();
28   vtkUnstructuredGrid* grid = mesh->getGrid();
29   myMeshId = mesh->getMeshId();
30   vtkIdType aType = VTK_TRIANGLE;
31   switch (nodeIds.size())
32   {
33     case 3:
34       aType = VTK_TRIANGLE;
35       break;
36     case 4:
37       aType = VTK_QUAD;
38       break;
39     case 6:
40       aType = VTK_QUADRATIC_TRIANGLE;
41       break;
42     case 8:
43       aType = VTK_QUADRATIC_QUAD;
44       break;
45     default:
46       aType = VTK_POLYGON;
47       break;
48   }
49   myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
50   mesh->setMyModified();
51   //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID);
52 }
53
54 void SMDS_VtkFace::initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
55 {
56   SMDS_MeshFace::init();
57   vtkUnstructuredGrid* grid = mesh->getGrid();
58   myMeshId = mesh->getMeshId();
59   myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), &nodeIds[0]);
60   mesh->setMyModified();
61 }
62
63 bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
64 {
65   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
66   vtkIdType npts = 0;
67   vtkIdType* pts = 0;
68   grid->GetCellPoints(myVtkID, npts, pts);
69   if (nbNodes != npts)
70     {
71       MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
72       return false;
73     }
74   for (int i = 0; i < nbNodes; i++)
75     {
76       pts[i] = nodes[i]->getVtkId();
77     }
78   SMDS_Mesh::_meshList[myMeshId]->setMyModified();
79   return true;
80 }
81
82 void SMDS_VtkFace::Print(std::ostream & OS) const
83 {
84   OS << "face <" << GetID() << "> : ";
85 }
86
87 int SMDS_VtkFace::NbEdges() const
88 {
89   // TODO quadratic polygons ?
90   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
91   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
92   int nbEdges = 3;
93   switch (aVtkType)
94   {
95     case VTK_TRIANGLE:
96     case VTK_QUADRATIC_TRIANGLE:
97       nbEdges = 3;
98       break;
99     case VTK_QUAD:
100     case VTK_QUADRATIC_QUAD:
101       nbEdges = 4;
102       break;
103     case VTK_POLYGON:
104     default:
105       nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
106       break;
107   }
108   return nbEdges;
109 }
110
111 int SMDS_VtkFace::NbFaces() const
112 {
113   return 1;
114 }
115
116 int SMDS_VtkFace::NbNodes() const
117 {
118   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
119   int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
120   return nbPoints;
121 }
122
123 /*!
124  * \brief Return node by its index
125  * \param ind - node index
126  * \retval const SMDS_MeshNode* - the node
127  */
128 const SMDS_MeshNode*
129 SMDS_VtkFace::GetNode(const int ind) const
130 {
131   return SMDS_MeshElement::GetNode(ind); // --- a optimiser !
132 }
133
134 bool SMDS_VtkFace::IsQuadratic() const
135 {
136   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
137   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
138   // TODO quadratic polygons ?
139   switch (aVtkType)
140   {
141     case VTK_QUADRATIC_TRIANGLE:
142     case VTK_QUADRATIC_QUAD:
143       return true;
144       break;
145     default:
146       return false;
147   }
148 }
149
150 bool SMDS_VtkFace::IsPoly() const
151 {
152   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
153   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
154   return (aVtkType == VTK_POLYGON);
155 }
156
157 bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
158 {
159   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
160   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
161   int rankFirstMedium = 0;
162   switch (aVtkType)
163   {
164     case VTK_QUADRATIC_TRIANGLE:
165       rankFirstMedium = 3; // medium nodes are of rank 3,4,5
166       break;
167     case VTK_QUADRATIC_QUAD:
168       rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
169       break;
170     default:
171       //MESSAGE("wrong element type " << aVtkType);
172       return false;
173   }
174   vtkIdType npts = 0;
175   vtkIdType* pts = 0;
176   grid->GetCellPoints(myVtkID, npts, pts);
177   vtkIdType nodeId = node->getVtkId();
178   for (int rank = 0; rank < npts; rank++)
179     {
180       if (pts[rank] == nodeId)
181         {
182           //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
183           if (rank < rankFirstMedium)
184             return false;
185           else
186             return true;
187         }
188     }
189   //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
190   MESSAGE("======================================================");
191   MESSAGE("= IsMediumNode: node does not belong to this element =");
192   MESSAGE("======================================================");
193   return false;
194 }
195
196 SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const
197 {
198   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
199   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
200   SMDSAbs_EntityType aType = SMDSEntity_Polygon;
201   switch (aVtkType)
202   {
203     case VTK_TRIANGLE:
204       aType = SMDSEntity_Triangle;
205       break;
206     case VTK_QUAD:
207       aType = SMDSEntity_Quadrangle;
208       break;
209     case VTK_QUADRATIC_TRIANGLE:
210       aType = SMDSEntity_Quad_Triangle;
211       break;
212     case VTK_QUADRATIC_QUAD:
213       aType = SMDSEntity_Quad_Quadrangle;
214       break;
215     default:
216       aType = SMDSEntity_Polygon;
217   }
218   return aType;
219 }
220
221 vtkIdType SMDS_VtkFace::GetVtkType() const
222 {
223   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
224   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
225   return aVtkType;
226 }
227
228 SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const
229 {
230   switch (type)
231   {
232     case SMDSAbs_Node:
233       return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
234     default:
235       MESSAGE("ERROR : Iterator not implemented")
236       ;
237       return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
238   }
239 }
240
241 SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const
242 {
243   return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
244 }
245
246 SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const
247 {
248   return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
249 }
250
251 //! change only the first node, used for temporary triangles in quadrangle to triangle adaptor
252 void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node)
253 {
254   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
255   vtkIdType npts = 0;
256   vtkIdType* pts = 0;
257   grid->GetCellPoints(myVtkID, npts, pts);
258   grid->RemoveReferenceToCell(pts[0], myVtkID);
259   pts[0] = node->getVtkId();
260   node->AddInverseElement(this),
261   SMDS_Mesh::_meshList[myMeshId]->setMyModified();
262 }