Salome HOME
Merge from V6_5_BR 05/06/2012
[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; //VTK_POLY_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   }
72   return vtkTypes[ smdsType ];
73 }
74
75 //================================================================================
76 /*!
77  * \brief Return indices to transform cell connectivity from SMDS to VTK
78  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
79  */
80 //================================================================================
81
82 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
83 {
84   static std::vector< std::vector< int > > toVtkInterlaces;
85   if ( toVtkInterlaces.empty() )
86   {
87     toVtkInterlaces.resize( SMDSEntity_Last+1 );
88     // {
89     //   const int ids[] = {0};
90     //   toVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
91     //   toVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
92     // }
93     // {
94     //   const int ids[] = {0,1};
95     //   toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
96     // }
97     // {
98     //   const int ids[] = {0,1,2};
99     //   toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
100     // }
101     // {
102     //   const int ids[] = {0,1,2};
103     //   toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
104     // }
105     // {
106     //   const int ids[] = {0,1,2,3,4,5};
107     //   toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
108     // }
109     // {
110     //   const int ids[] = {0,1,2,3};
111     //   toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
112     // }
113     // {
114     //   const int ids[] = {0,1,2,3,4,5,6,7};
115     //   toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
116     // }
117     // {
118     //   const int ids[] = {0,1,2,3,4,5,6,7,8};
119     //   toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
120     // }
121     {
122       const int ids[] = {0,2,1,3};
123       toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
124     }
125     {
126       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
127       toVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
128     }
129     {
130       const int ids[] = {0,3,2,1,4};
131       toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
132     }
133     {
134       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
135       toVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
136     }
137     {
138       const int ids[] = {0,3,2,1,4,7,6,5};
139       toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
140     }
141     {
142       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
143       toVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
144     }
145     {
146       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};
147       toVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
148     }
149     {
150       const int ids[] = {0,1,2,3,4,5};
151       toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
152     }
153     {
154       const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
155       toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
156     }
157     {
158       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
159       toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
160     }
161   }
162   return toVtkInterlaces[smdsType];
163 }
164
165 //================================================================================
166 /*!
167  * \brief Return indices to reverse an SMDS cell of given type
168  * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
169  */
170 //================================================================================
171
172 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
173 {
174   static std::vector< std::vector< int > > reverseInterlaces;
175   if ( reverseInterlaces.empty() )
176   {
177     reverseInterlaces.resize( SMDSEntity_Last+1 );
178     {
179       const int ids[] = {0};
180       reverseInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
181       reverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
182     }
183     {
184       const int ids[] = {1,0};
185       reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
186     }
187     {
188       const int ids[] = {1,0,2};
189       reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
190     }
191     {
192       const int ids[] = {0,2,1};
193       reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
194     }
195     {
196       const int ids[] = {0,2,1,5,4,3};
197       reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
198     }
199     {
200       const int ids[] = {0,3,2,1};
201       reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
202     }
203     {
204       const int ids[] = {0,3,2,1,7,6,5,4};
205       reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
206     }
207     {
208       const int ids[] = {0,3,2,1,7,6,5,4,8};
209       reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
210     }
211     {
212       const int ids[] = {0,2,1,3};
213       reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
214     }
215     {
216       const int ids[] = {0,2,1,3,6,5,4,7,9,8};
217       reverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
218     }
219     {
220       const int ids[] = {0,3,2,1,4};
221       reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
222     }
223     {
224       const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
225       reverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
226     }
227     {
228       const int ids[] = {0,3,2,1,4,7,6,5};
229       reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
230     }
231     {
232       const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
233       reverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
234     }
235     {
236       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};
237       reverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
238     }
239     {
240       const int ids[] = {0,2,1,3,5,4};
241       reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
242     }
243     {
244       const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13};
245       reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
246     }
247     {
248       const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
249       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
250     }
251   }
252   return reverseInterlaces[smdsType];
253 }
254
255 //================================================================================
256 /*!
257  * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
258  * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
259  */
260 //================================================================================
261
262 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
263 {
264   static std::vector< std::vector< int > > interlace;
265   if ( interlace.empty() )
266   {
267     interlace.resize( SMDSEntity_Last+1 );
268     {
269       const int ids[] = {0,2,1};
270       interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
271     }
272     {
273       const int ids[] = {0,3,1,4,2,5};
274       interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
275     }
276     {
277       const int ids[] = {0,4,1,5,2,6,3,7,8};
278       interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
279       interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
280     }
281   }
282   return interlace[smdsType];
283 }
284
285 //================================================================================
286 /*!
287  * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
288  */
289 //================================================================================
290
291 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
292 {
293   static std::vector< SMDSAbs_EntityType > smdsTypes;
294   if ( smdsTypes.empty() )
295   {
296     smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last );
297     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
298       smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS );
299   }
300   return smdsTypes[ vtkType ];
301 }
302
303 //================================================================================
304 /*!
305  * \brief Return indices to transform cell connectivity from VTK to SMDS
306  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
307  */
308 //================================================================================
309
310 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
311 {
312   static std::vector< std::vector<int> > fromVtkInterlaces;
313   if ( fromVtkInterlaces.empty() )
314   {
315     fromVtkInterlaces.resize( SMDSEntity_Last+1 );
316     for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
317     {
318       const std::vector<int> & toVtk = toVtkOrder( SMDSAbs_EntityType( iSMDS ));
319       std::vector<int> &      toSmds = fromVtkInterlaces[ iSMDS ];
320       toSmds.resize( toVtk.size() );
321       for ( size_t i = 0; i < toVtk.size(); ++i )
322         toSmds[ toVtk[i] ] = i;
323     }
324   }
325   return fromVtkInterlaces[ smdsType ];
326 }
327
328 //================================================================================
329 /*!
330  * \brief Return indices to transform cell connectivity from SMDS to VTK
331  * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
332  */
333 //================================================================================
334
335 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
336 {
337   return toVtkOrder( toSmdsType( vtkType ));
338 }
339
340 //================================================================================
341 /*!
342  * \brief Return indices to transform cell connectivity from VTK to SMDS
343  * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
344  */
345 //================================================================================
346
347 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
348 {
349   return fromVtkOrder( toSmdsType( vtkType ));
350 }