1 // Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SMDS_MeshCell.hxx"
21 #include "utilities.h"
23 int SMDS_MeshCell::nbCells = 0;
25 SMDS_MeshCell::SMDS_MeshCell() :
32 SMDS_MeshCell::~SMDS_MeshCell()
36 //================================================================================
38 * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
40 //================================================================================
42 VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
44 static std::vector< VTKCellType > vtkTypes;
45 if ( vtkTypes.empty() )
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 ] = ;
72 return vtkTypes[ smdsType ];
75 //================================================================================
77 * \brief Return indices to transform cell connectivity from SMDS to VTK
78 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
80 //================================================================================
82 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
84 static std::vector< std::vector< int > > toVtkInterlaces;
85 if ( toVtkInterlaces.empty() )
87 toVtkInterlaces.resize( SMDSEntity_Last+1 );
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 );
94 // const int ids[] = {0,1};
95 // toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
98 // const int ids[] = {0,1,2};
99 // toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
102 // const int ids[] = {0,1,2};
103 // toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
106 // const int ids[] = {0,1,2,3,4,5};
107 // toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
110 // const int ids[] = {0,1,2,3};
111 // toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
114 // const int ids[] = {0,1,2,3,4,5,6,7};
115 // toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
118 // const int ids[] = {0,1,2,3,4,5,6,7,8};
119 // toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
122 const int ids[] = {0,2,1,3};
123 toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
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 );
130 const int ids[] = {0,3,2,1,4};
131 toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
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 );
138 const int ids[] = {0,3,2,1,4,7,6,5};
139 toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
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 );
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 );
150 const int ids[] = {0,1,2,3,4,5};
151 toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
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 );
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 );
162 return toVtkInterlaces[smdsType];
165 //================================================================================
167 * \brief Return indices to reverse an SMDS cell of given type
168 * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
170 //================================================================================
172 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
174 static std::vector< std::vector< int > > reverseInterlaces;
175 if ( reverseInterlaces.empty() )
177 reverseInterlaces.resize( SMDSEntity_Last+1 );
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 );
184 const int ids[] = {1,0};
185 reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
188 const int ids[] = {1,0,2};
189 reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
192 const int ids[] = {0,2,1};
193 reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
196 const int ids[] = {0,2,1,5,4,3};
197 reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
200 const int ids[] = {0,3,2,1};
201 reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
204 const int ids[] = {0,3,2,1,7,6,5,4};
205 reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
208 const int ids[] = {0,3,2,1,7,6,5,4,8};
209 reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
212 const int ids[] = {0,2,1,3};
213 reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
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 );
220 const int ids[] = {0,3,2,1,4};
221 reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
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 );
228 const int ids[] = {0,3,2,1,4,7,6,5};
229 reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
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 );
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 );
240 const int ids[] = {0,2,1,3,5,4};
241 reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
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 );
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 );
252 return reverseInterlaces[smdsType];
255 //================================================================================
257 * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
258 * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
260 //================================================================================
262 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
264 static std::vector< std::vector< int > > interlace;
265 if ( interlace.empty() )
267 interlace.resize( SMDSEntity_Last+1 );
269 const int ids[] = {0,2,1};
270 interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
273 const int ids[] = {0,3,1,4,2,5};
274 interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
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 );
282 return interlace[smdsType];
285 //================================================================================
287 * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
289 //================================================================================
291 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
293 static std::vector< SMDSAbs_EntityType > smdsTypes;
294 if ( smdsTypes.empty() )
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 );
300 return smdsTypes[ vtkType ];
303 //================================================================================
305 * \brief Return indices to transform cell connectivity from VTK to SMDS
306 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
308 //================================================================================
310 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
312 static std::vector< std::vector<int> > fromVtkInterlaces;
313 if ( fromVtkInterlaces.empty() )
315 fromVtkInterlaces.resize( SMDSEntity_Last+1 );
316 for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
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;
325 return fromVtkInterlaces[ smdsType ];
328 //================================================================================
330 * \brief Return indices to transform cell connectivity from SMDS to VTK
331 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
333 //================================================================================
335 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
337 return toVtkOrder( toSmdsType( vtkType ));
340 //================================================================================
342 * \brief Return indices to transform cell connectivity from VTK to SMDS
343 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
345 //================================================================================
347 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
349 return fromVtkOrder( toSmdsType( vtkType ));