Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/smesh.git] / src / SMDS / SMDS_MeshCell.cxx
1 // Copyright (C) 2010-2012  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_Quadrangle ]        = VTK_QUAD;
55     vtkTypes[ SMDSEntity_Quad_Quadrangle ]   = VTK_QUADRATIC_QUAD;
56     vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
57     vtkTypes[ SMDSEntity_Polygon ]           = VTK_POLYGON;
58     //vtkTypes[ SMDSEntity_Quad_Polygon ]      = ;
59     vtkTypes[ SMDSEntity_Tetra ]             = VTK_TETRA;
60     vtkTypes[ SMDSEntity_Quad_Tetra ]        = VTK_QUADRATIC_TETRA;
61     vtkTypes[ SMDSEntity_Pyramid ]           = VTK_PYRAMID;
62     vtkTypes[ SMDSEntity_Quad_Pyramid ]      = VTK_QUADRATIC_PYRAMID;
63     vtkTypes[ SMDSEntity_Hexa ]              = VTK_HEXAHEDRON;
64     vtkTypes[ SMDSEntity_Quad_Hexa ]         = VTK_QUADRATIC_HEXAHEDRON;
65     vtkTypes[ SMDSEntity_TriQuad_Hexa ]      = VTK_TRIQUADRATIC_HEXAHEDRON;
66     vtkTypes[ SMDSEntity_Penta ]             = VTK_WEDGE;
67     vtkTypes[ SMDSEntity_Quad_Penta ]        = VTK_QUADRATIC_WEDGE;
68     vtkTypes[ SMDSEntity_Hexagonal_Prism ]   = VTK_HEXAGONAL_PRISM;
69     vtkTypes[ SMDSEntity_Polyhedra ]         = VTK_POLYHEDRON;
70     //vtkTypes[ SMDSEntity_Quad_Polyhedra ]    = ;
71     vtkTypes[ SMDSEntity_Ball ]              = VTK_POLY_VERTEX;
72   }
73   return vtkTypes[ smdsType ];
74 }
75
76 //================================================================================
77 /*!
78  * \brief Return indices to transform cell connectivity from SMDS to VTK
79  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
80  */
81 //================================================================================
82
83 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
84 {
85   static std::vector< std::vector< int > > toVtkInterlaces;
86   if ( toVtkInterlaces.empty() )
87   {
88     toVtkInterlaces.resize( SMDSEntity_Last+1 );
89     // {
90     //   const int ids[] = {0};
91     //   toVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
92     //   toVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
93     // }
94     // {
95     //   const int ids[] = {0,1};
96     //   toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
97     // }
98     // {
99     //   const int ids[] = {0,1,2};
100     //   toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
101     // }
102     // {
103     //   const int ids[] = {0,1,2};
104     //   toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
105     // }
106     // {
107     //   const int ids[] = {0,1,2,3,4,5};
108     //   toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
109     // }
110     // {
111     //   const int ids[] = {0,1,2,3};
112     //   toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
113     // }
114     // {
115     //   const int ids[] = {0,1,2,3,4,5,6,7};
116     //   toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
117     // }
118     // {
119     //   const int ids[] = {0,1,2,3,4,5,6,7,8};
120     //   toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
121     // }
122     {
123       const int ids[] = {0,2,1,3};
124       toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
125     }
126     {
127       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
128       toVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
129     }
130     {
131       const int ids[] = {0,3,2,1,4};
132       toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
133     }
134     {
135       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
136       toVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
137     }
138     {
139       const int ids[] = {0,3,2,1,4,7,6,5};
140       toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
141     }
142     {
143       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
144       toVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
145     }
146     {
147       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};
148       toVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
149     }
150     {
151       const int ids[] = {0,1,2,3,4,5};
152       toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
153     }
154     {
155       const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
156       toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
157     }
158     {
159       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
160       toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
161     }
162   }
163   return toVtkInterlaces[smdsType];
164 }
165
166 //================================================================================
167 /*!
168  * \brief Return indices to reverse an SMDS cell of given type
169  * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
170  */
171 //================================================================================
172
173 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
174 {
175   static std::vector< std::vector< int > > reverseInterlaces;
176   if ( reverseInterlaces.empty() )
177   {
178     reverseInterlaces.resize( SMDSEntity_Last+1 );
179     {
180       const int ids[] = {0};
181       reverseInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
182       reverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
183       reverseInterlaces[SMDSEntity_Ball].assign( &ids[0], &ids[0]+1 );
184     }
185     {
186       const int ids[] = {1,0};
187       reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
188     }
189     {
190       const int ids[] = {1,0,2};
191       reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
192     }
193     {
194       const int ids[] = {0,2,1};
195       reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
196     }
197     {
198       const int ids[] = {0,2,1,5,4,3};
199       reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
200     }
201     {
202       const int ids[] = {0,3,2,1};
203       reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
204     }
205     {
206       const int ids[] = {0,3,2,1,7,6,5,4};
207       reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
208     }
209     {
210       const int ids[] = {0,3,2,1,7,6,5,4,8};
211       reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
212     }
213     {
214       const int ids[] = {0,2,1,3};
215       reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
216     }
217     {
218       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
219       reverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
220     }
221     {
222       const int ids[] = {0,3,2,1,4};
223       reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
224     }
225     {
226       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
227       reverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
228     }
229     {
230       const int ids[] = {0,3,2,1,4,7,6,5};
231       reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
232     }
233     {
234       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
235       reverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
236     }
237     {
238       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};
239       reverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
240     }
241     {
242       const int ids[] = {0,2,1,3,5,4};
243       reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
244     }
245     {
246       const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13};
247       reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
248     }
249     {
250       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
251       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
252     }
253   }
254   return reverseInterlaces[smdsType];
255 }
256
257 //================================================================================
258 /*!
259  * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
260  * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
261  */
262 //================================================================================
263
264 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
265 {
266   static std::vector< std::vector< int > > interlace;
267   if ( interlace.empty() )
268   {
269     interlace.resize( SMDSEntity_Last+1 );
270     {
271       const int ids[] = {0,2,1};
272       interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
273     }
274     {
275       const int ids[] = {0,3,1,4,2,5};
276       interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
277     }
278     {
279       const int ids[] = {0,4,1,5,2,6,3,7,8};
280       interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
281       interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
282     }
283   }
284   return interlace[smdsType];
285 }
286
287 //================================================================================
288 /*!
289  * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
290  */
291 //================================================================================
292
293 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
294 {
295   static std::vector< SMDSAbs_EntityType > smdsTypes;
296   if ( smdsTypes.empty() )
297   {
298     smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last );
299     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
300       smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS );
301   }
302   return smdsTypes[ vtkType ];
303 }
304
305 //================================================================================
306 /*!
307  * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
308  */
309 //================================================================================
310
311 SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType)
312 {
313   switch ( geomType ) {
314   case SMDSGeom_POINT:     return SMDSAbs_0DElement;
315
316   case SMDSGeom_EDGE:      return SMDSAbs_Edge; 
317
318   case SMDSGeom_TRIANGLE:
319   case SMDSGeom_QUADRANGLE:
320   case SMDSGeom_POLYGON:   return SMDSAbs_Face;
321
322   case SMDSGeom_TETRA:
323   case SMDSGeom_PYRAMID:
324   case SMDSGeom_HEXA:
325   case SMDSGeom_PENTA:
326   case SMDSGeom_HEXAGONAL_PRISM:
327   case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
328
329   case SMDSGeom_BALL:      return SMDSAbs_Ball;
330
331   case SMDSGeom_NONE: ;
332   }
333   return SMDSAbs_All;
334 }
335
336 //================================================================================
337 /*!
338  * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
339  */
340 //================================================================================
341
342 SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType)
343 {
344   switch ( entityType ) {
345   case SMDSEntity_Node:           return SMDSAbs_Node;
346
347   case SMDSEntity_0D:             return SMDSAbs_0DElement;
348
349   case SMDSEntity_Edge:
350   case SMDSEntity_Quad_Edge:      return SMDSAbs_Edge;
351
352   case SMDSEntity_Triangle:
353   case SMDSEntity_Quad_Triangle:
354   case SMDSEntity_Quadrangle:
355   case SMDSEntity_Quad_Quadrangle:
356   case SMDSEntity_BiQuad_Quadrangle:
357   case SMDSEntity_Polygon:
358   case SMDSEntity_Quad_Polygon:   return SMDSAbs_Face;
359
360   case SMDSEntity_Tetra:
361   case SMDSEntity_Quad_Tetra:
362   case SMDSEntity_Pyramid:
363   case SMDSEntity_Quad_Pyramid:
364   case SMDSEntity_Hexa:
365   case SMDSEntity_Quad_Hexa:
366   case SMDSEntity_TriQuad_Hexa:
367   case SMDSEntity_Penta:
368   case SMDSEntity_Quad_Penta:
369   case SMDSEntity_Hexagonal_Prism:
370   case SMDSEntity_Polyhedra:
371   case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume;
372
373   case SMDSEntity_Ball:           return SMDSAbs_Ball;
374
375   case SMDSEntity_Last:;
376   }
377   return SMDSAbs_All;
378 }
379
380
381 //================================================================================
382 /*!
383  * \brief Return indices to transform cell connectivity from VTK to SMDS
384  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
385  */
386 //================================================================================
387
388 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
389 {
390   static std::vector< std::vector<int> > fromVtkInterlaces;
391   if ( fromVtkInterlaces.empty() )
392   {
393     fromVtkInterlaces.resize( SMDSEntity_Last+1 );
394     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
395     {
396       const std::vector<int> & toVtk = toVtkOrder( SMDSAbs_EntityType( iSMDS ));
397       std::vector<int> &      toSmds = fromVtkInterlaces[ iSMDS ];
398       toSmds.resize( toVtk.size() );
399       for ( size_t i = 0; i < toVtk.size(); ++i )
400         toSmds[ toVtk[i] ] = i;
401     }
402   }
403   return fromVtkInterlaces[ smdsType ];
404 }
405
406 //================================================================================
407 /*!
408  * \brief Return indices to transform cell connectivity from SMDS to VTK
409  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
410  */
411 //================================================================================
412
413 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
414 {
415   return toVtkOrder( toSmdsType( vtkType ));
416 }
417
418 //================================================================================
419 /*!
420  * \brief Return indices to transform cell connectivity from VTK to SMDS
421  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
422  */
423 //================================================================================
424
425 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
426 {
427   return fromVtkOrder( toSmdsType( vtkType ));
428 }