Salome HOME
0022100: EDF 2413 SMESH: Take into account TRIA7
[modules/smesh.git] / src / SMDS / SMDS_MeshCell.cxx
1 // Copyright (C) 2010-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "SMDS_MeshCell.hxx"
21 #include "utilities.h"
22
23 int SMDS_MeshCell::nbCells = 0;
24
25 SMDS_MeshCell::SMDS_MeshCell() :
26   SMDS_MeshElement(-1)
27 {
28   nbCells++;
29   myVtkID = -1;
30 }
31
32 SMDS_MeshCell::~SMDS_MeshCell()
33 {
34   nbCells--;
35 }
36 //================================================================================
37 /*!
38  * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
39  */
40 //================================================================================
41
42 VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
43 {
44   static std::vector< VTKCellType > vtkTypes;
45   if ( vtkTypes.empty() )
46   {
47     vtkTypes.resize( SMDSEntity_Last+1, VTK_EMPTY_CELL );
48     vtkTypes[ SMDSEntity_Node ]              = VTK_VERTEX;
49     vtkTypes[ SMDSEntity_0D ]                = VTK_VERTEX;
50     vtkTypes[ SMDSEntity_Edge ]              = VTK_LINE;
51     vtkTypes[ SMDSEntity_Quad_Edge ]         = VTK_QUADRATIC_EDGE;
52     vtkTypes[ SMDSEntity_Triangle ]          = VTK_TRIANGLE;
53     vtkTypes[ SMDSEntity_Quad_Triangle ]     = VTK_QUADRATIC_TRIANGLE;
54     vtkTypes[ SMDSEntity_BiQuad_Triangle ]   = VTK_BIQUADRATIC_TRIANGLE;
55     vtkTypes[ SMDSEntity_Quadrangle ]        = VTK_QUAD;
56     vtkTypes[ SMDSEntity_Quad_Quadrangle ]   = VTK_QUADRATIC_QUAD;
57     vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
58     vtkTypes[ SMDSEntity_Polygon ]           = VTK_POLYGON;
59     //vtkTypes[ SMDSEntity_Quad_Polygon ]      = ;
60     vtkTypes[ SMDSEntity_Tetra ]             = VTK_TETRA;
61     vtkTypes[ SMDSEntity_Quad_Tetra ]        = VTK_QUADRATIC_TETRA;
62     vtkTypes[ SMDSEntity_Pyramid ]           = VTK_PYRAMID;
63     vtkTypes[ SMDSEntity_Quad_Pyramid ]      = VTK_QUADRATIC_PYRAMID;
64     vtkTypes[ SMDSEntity_Hexa ]              = VTK_HEXAHEDRON;
65     vtkTypes[ SMDSEntity_Quad_Hexa ]         = VTK_QUADRATIC_HEXAHEDRON;
66     vtkTypes[ SMDSEntity_TriQuad_Hexa ]      = VTK_TRIQUADRATIC_HEXAHEDRON;
67     vtkTypes[ SMDSEntity_Penta ]             = VTK_WEDGE;
68     vtkTypes[ SMDSEntity_Quad_Penta ]        = VTK_QUADRATIC_WEDGE;
69     vtkTypes[ SMDSEntity_Hexagonal_Prism ]   = VTK_HEXAGONAL_PRISM;
70     vtkTypes[ SMDSEntity_Polyhedra ]         = VTK_POLYHEDRON;
71     //vtkTypes[ SMDSEntity_Quad_Polyhedra ]    = ;
72     vtkTypes[ SMDSEntity_Ball ]              = VTK_POLY_VERTEX;
73   }
74   return vtkTypes[ smdsType ];
75 }
76
77 //================================================================================
78 /*!
79  * \brief Return indices to transform cell connectivity from SMDS to VTK
80  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
81  */
82 //================================================================================
83
84 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
85 {
86   static std::vector< std::vector< int > > toVtkInterlaces;
87   if ( toVtkInterlaces.empty() )
88   {
89     toVtkInterlaces.resize( SMDSEntity_Last+1 );
90     // {
91     //   const int ids[] = {0};
92     //   toVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
93     //   toVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
94     // }
95     // {
96     //   const int ids[] = {0,1};
97     //   toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
98     // }
99     // {
100     //   const int ids[] = {0,1,2};
101     //   toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
102     // }
103     // {
104     //   const int ids[] = {0,1,2};
105     //   toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
106     // }
107     // {
108     //   const int ids[] = {0,1,2,3,4,5};
109     //   toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
110     // }
111     // {
112     //   const int ids[] = {0,1,2,3};
113     //   toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
114     // }
115     // {
116     //   const int ids[] = {0,1,2,3,4,5,6,7};
117     //   toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
118     // }
119     // {
120     //   const int ids[] = {0,1,2,3,4,5,6,7,8};
121     //   toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
122     // }
123     {
124       const int ids[] = {0,2,1,3};
125       toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
126     }
127     {
128       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
129       toVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
130     }
131     {
132       const int ids[] = {0,3,2,1,4};
133       toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
134     }
135     {
136       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
137       toVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
138     }
139     {
140       const int ids[] = {0,3,2,1,4,7,6,5};
141       toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
142     }
143     {
144       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
145       toVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
146     }
147     {
148       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 21,23,24,22,20,25,26};
149       toVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
150     }
151     {
152       const int ids[] = {0,1,2,3,4,5};
153       toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
154     }
155     {
156       const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
157       toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
158     }
159     {
160       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
161       toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
162     }
163   }
164   return toVtkInterlaces[smdsType];
165 }
166
167 //================================================================================
168 /*!
169  * \brief Return indices to reverse an SMDS cell of given type
170  * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
171  */
172 //================================================================================
173
174 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
175 {
176   static std::vector< std::vector< int > > reverseInterlaces;
177   if ( reverseInterlaces.empty() )
178   {
179     reverseInterlaces.resize( SMDSEntity_Last+1 );
180     {
181       const int ids[] = {0};
182       reverseInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
183       reverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
184       reverseInterlaces[SMDSEntity_Ball].assign( &ids[0], &ids[0]+1 );
185     }
186     {
187       const int ids[] = {1,0};
188       reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
189     }
190     {
191       const int ids[] = {1,0,2};
192       reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
193     }
194     {
195       const int ids[] = {0,2,1};
196       reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
197     }
198     {
199       const int ids[] = {0,2,1,5,4,3};
200       reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
201     }
202     {
203       const int ids[] = {0,2,1,5,4,3,6};
204       reverseInterlaces[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
205     }
206     {
207       const int ids[] = {0,3,2,1};
208       reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
209     }
210     {
211       const int ids[] = {0,3,2,1,7,6,5,4};
212       reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
213     }
214     {
215       const int ids[] = {0,3,2,1,7,6,5,4,8};
216       reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
217     }
218     {
219       const int ids[] = {0,2,1,3};
220       reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
221     }
222     {
223       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
224       reverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
225     }
226     {
227       const int ids[] = {0,3,2,1,4};
228       reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
229     }
230     {
231       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
232       reverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
233     }
234     {
235       const int ids[] = {0,3,2,1,4,7,6,5};
236       reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
237     }
238     {
239       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
240       reverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
241     }
242     {
243       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 20,24,23,22,21,25,26};
244       reverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
245     }
246     {
247       const int ids[] = {0,2,1,3,5,4};
248       reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
249     }
250     {
251       const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13};
252       reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
253     }
254     {
255       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
256       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
257     }
258   }
259   return reverseInterlaces[smdsType];
260 }
261
262 //================================================================================
263 /*!
264  * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
265  * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
266  */
267 //================================================================================
268
269 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
270 {
271   static std::vector< std::vector< int > > interlace;
272   if ( interlace.empty() )
273   {
274     interlace.resize( SMDSEntity_Last+1 );
275     {
276       const int ids[] = {0,2,1};
277       interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
278     }
279     {
280       const int ids[] = {0,3,1,4,2,5,6};
281       interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
282       interlace[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
283     }
284     {
285       const int ids[] = {0,4,1,5,2,6,3,7,8};
286       interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
287       interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
288     }
289   }
290   return interlace[smdsType];
291 }
292
293 //================================================================================
294 /*!
295  * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
296  */
297 //================================================================================
298
299 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
300 {
301   static std::vector< SMDSAbs_EntityType > smdsTypes;
302   if ( smdsTypes.empty() )
303   {
304     smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last );
305     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
306       smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS );
307   }
308   return smdsTypes[ vtkType ];
309 }
310
311 //================================================================================
312 /*!
313  * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
314  */
315 //================================================================================
316
317 SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType)
318 {
319   switch ( geomType ) {
320   case SMDSGeom_POINT:     return SMDSAbs_0DElement;
321
322   case SMDSGeom_EDGE:      return SMDSAbs_Edge; 
323
324   case SMDSGeom_TRIANGLE:
325   case SMDSGeom_QUADRANGLE:
326   case SMDSGeom_POLYGON:   return SMDSAbs_Face;
327
328   case SMDSGeom_TETRA:
329   case SMDSGeom_PYRAMID:
330   case SMDSGeom_HEXA:
331   case SMDSGeom_PENTA:
332   case SMDSGeom_HEXAGONAL_PRISM:
333   case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
334
335   case SMDSGeom_BALL:      return SMDSAbs_Ball;
336
337   case SMDSGeom_NONE: ;
338   }
339   return SMDSAbs_All;
340 }
341
342 //================================================================================
343 /*!
344  * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
345  */
346 //================================================================================
347
348 SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType)
349 {
350   switch ( entityType ) {
351   case SMDSEntity_Node:           return SMDSAbs_Node;
352
353   case SMDSEntity_0D:             return SMDSAbs_0DElement;
354
355   case SMDSEntity_Edge:
356   case SMDSEntity_Quad_Edge:      return SMDSAbs_Edge;
357
358   case SMDSEntity_Triangle:
359   case SMDSEntity_Quad_Triangle:
360   case SMDSEntity_BiQuad_Triangle:
361   case SMDSEntity_Quadrangle:
362   case SMDSEntity_Quad_Quadrangle:
363   case SMDSEntity_BiQuad_Quadrangle:
364   case SMDSEntity_Polygon:
365   case SMDSEntity_Quad_Polygon:   return SMDSAbs_Face;
366
367   case SMDSEntity_Tetra:
368   case SMDSEntity_Quad_Tetra:
369   case SMDSEntity_Pyramid:
370   case SMDSEntity_Quad_Pyramid:
371   case SMDSEntity_Hexa:
372   case SMDSEntity_Quad_Hexa:
373   case SMDSEntity_TriQuad_Hexa:
374   case SMDSEntity_Penta:
375   case SMDSEntity_Quad_Penta:
376   case SMDSEntity_Hexagonal_Prism:
377   case SMDSEntity_Polyhedra:
378   case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume;
379
380   case SMDSEntity_Ball:           return SMDSAbs_Ball;
381
382   case SMDSEntity_Last:;
383   }
384   return SMDSAbs_All;
385 }
386
387
388 //================================================================================
389 /*!
390  * \brief Return indices to transform cell connectivity from VTK to SMDS
391  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
392  */
393 //================================================================================
394
395 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
396 {
397   static std::vector< std::vector<int> > fromVtkInterlaces;
398   if ( fromVtkInterlaces.empty() )
399   {
400     fromVtkInterlaces.resize( SMDSEntity_Last+1 );
401     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
402     {
403       const std::vector<int> & toVtk = toVtkOrder( SMDSAbs_EntityType( iSMDS ));
404       std::vector<int> &      toSmds = fromVtkInterlaces[ iSMDS ];
405       toSmds.resize( toVtk.size() );
406       for ( size_t i = 0; i < toVtk.size(); ++i )
407         toSmds[ toVtk[i] ] = i;
408     }
409   }
410   return fromVtkInterlaces[ smdsType ];
411 }
412
413 //================================================================================
414 /*!
415  * \brief Return indices to transform cell connectivity from SMDS to VTK
416  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
417  */
418 //================================================================================
419
420 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
421 {
422   return toVtkOrder( toSmdsType( vtkType ));
423 }
424
425 //================================================================================
426 /*!
427  * \brief Return indices to transform cell connectivity from VTK to SMDS
428  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
429  */
430 //================================================================================
431
432 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
433 {
434   return fromVtkOrder( toSmdsType( vtkType ));
435 }