1 // Copyright (C) 2010-2016 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, or (at your option) any later version.
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"
22 #include "SMDS_Mesh.hxx"
23 #include "SMDS_VtkCellIterator.hxx"
25 #include <utilities.h>
31 #include <boost/make_shared.hpp>
36 * \brief Cell type features
40 SMDSAbs_EntityType myEntity;
41 SMDSAbs_ElementType myType;
42 SMDSAbs_GeometryType myGeom;
51 myEntity( SMDSEntity_Last ), myType( SMDSAbs_All ), myGeom( SMDSGeom_NONE ),
52 myIsPoly( 0 ), myNbCornerNodes( 0 ),
53 myNbNodes( 0 ), myNbEdges( 0 ), myNbFaces ( 0 )
56 void Set( SMDSAbs_EntityType Entity,
57 SMDSAbs_ElementType Type,
58 SMDSAbs_GeometryType Geom,
69 myIsQuadratic = ( NbNodes > NbCornerNodes );
70 myNbCornerNodes = NbCornerNodes;
77 static std::vector< CellProps > theCellProps;
79 //! initialize theCellProps
82 theCellProps.resize( VTK_NUMBER_OF_CELL_TYPES );
83 CellProps* p = & theCellProps[0];
85 Set( SMDSEntity_0D, SMDSAbs_0DElement, SMDSGeom_POINT,
86 /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 );
88 Set( SMDSEntity_Edge, SMDSAbs_Edge, SMDSGeom_EDGE,
89 /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/2,/*nbE=*/1,/*nbF=*/0 );
90 p[ VTK_QUADRATIC_EDGE ].
91 Set( SMDSEntity_Quad_Edge, SMDSAbs_Edge, SMDSGeom_EDGE,
92 /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/3,/*nbE=*/1,/*nbF=*/0 );
94 Set( SMDSEntity_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE,
95 /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/3,/*nbE=*/3,/*nbF=*/1 );
96 p[ VTK_QUADRATIC_TRIANGLE ].
97 Set( SMDSEntity_Quad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE,
98 /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/6,/*nbE=*/3,/*nbF=*/1 );
99 p[ VTK_BIQUADRATIC_TRIANGLE ].
100 Set( SMDSEntity_BiQuad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE,
101 /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/7,/*nbE=*/3,/*nbF=*/1 );
103 Set( SMDSEntity_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE,
104 /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/4,/*nbF=*/1 );
105 p[ VTK_QUADRATIC_QUAD].
106 Set( SMDSEntity_Quad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE,
107 /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/8,/*nbE=*/4,/*nbF=*/1 );
108 p[ VTK_BIQUADRATIC_QUAD].
109 Set( SMDSEntity_BiQuad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE,
110 /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/9,/*nbE=*/4,/*nbF=*/1 );
112 Set( SMDSEntity_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON,
113 /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 );
114 p[ VTK_QUADRATIC_POLYGON ].
115 Set( SMDSEntity_Quad_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON,
116 /*isPoly=*/1,/*nbCN=*/-2,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 );
118 Set( SMDSEntity_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA,
119 /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/6,/*nbF=*/4 );
120 p[ VTK_QUADRATIC_TETRA ].
121 Set( SMDSEntity_Quad_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA,
122 /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/10,/*nbE=*/6,/*nbF=*/4 );
124 Set( SMDSEntity_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID,
125 /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/5,/*nbE=*/8,/*nbF=*/5 );
126 p[ VTK_QUADRATIC_PYRAMID].
127 Set( SMDSEntity_Quad_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID,
128 /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/13,/*nbE=*/8,/*nbF=*/5 );
130 Set( SMDSEntity_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA,
131 /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/8,/*nbE=*/12,/*nbF=*/6 );
132 p[ VTK_QUADRATIC_HEXAHEDRON ].
133 Set( SMDSEntity_Quad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA,
134 /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/20,/*nbE=*/12,/*nbF=*/6 );
135 p[ VTK_TRIQUADRATIC_HEXAHEDRON ].
136 Set( SMDSEntity_TriQuad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA,
137 /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/27,/*nbE=*/12,/*nbF=*/6 );
139 Set( SMDSEntity_Penta, SMDSAbs_Volume, SMDSGeom_PENTA,
140 /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/6,/*nbE=*/9,/*nbF=*/5 );
141 p[ VTK_QUADRATIC_WEDGE ].
142 Set( SMDSEntity_Quad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA,
143 /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/15,/*nbE=*/9,/*nbF=*/5 );
144 p[ VTK_BIQUADRATIC_QUADRATIC_WEDGE ].
145 Set( SMDSEntity_BiQuad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA,
146 /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/21,/*nbE=*/9,/*nbF=*/5 );
147 p[ VTK_HEXAGONAL_PRISM].
148 Set( SMDSEntity_Hexagonal_Prism, SMDSAbs_Volume, SMDSGeom_HEXAGONAL_PRISM,
149 /*isPoly=*/0,/*nbCN=*/12,/*nbN=*/12,/*nbE=*/18,/*nbF=*/8 );
151 Set( SMDSEntity_Polyhedra, SMDSAbs_Volume, SMDSGeom_POLYHEDRA,
152 /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/-1 );
154 Set( SMDSEntity_Ball, SMDSAbs_Ball, SMDSGeom_BALL,
155 /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 );
158 //! return vector a CellProps
159 const CellProps& getCellProps( VTKCellType vtkType )
161 return theCellProps[ vtkType ];
164 //! return vector a CellProps
165 const CellProps& getCellProps( SMDSAbs_EntityType entity )
167 return getCellProps( SMDS_MeshCell::toVtkType( entity ));
171 static std::vector< VTKCellType > theVtkTypes; //!< VTK types by SMDS ones
175 theVtkTypes.resize( SMDSEntity_Last+1, VTK_EMPTY_CELL );
176 theVtkTypes[ SMDSEntity_Node ] = VTK_VERTEX;
177 theVtkTypes[ SMDSEntity_0D ] = VTK_VERTEX;
178 theVtkTypes[ SMDSEntity_Edge ] = VTK_LINE;
179 theVtkTypes[ SMDSEntity_Quad_Edge ] = VTK_QUADRATIC_EDGE;
180 theVtkTypes[ SMDSEntity_Triangle ] = VTK_TRIANGLE;
181 theVtkTypes[ SMDSEntity_Quad_Triangle ] = VTK_QUADRATIC_TRIANGLE;
182 theVtkTypes[ SMDSEntity_BiQuad_Triangle ] = VTK_BIQUADRATIC_TRIANGLE;
183 theVtkTypes[ SMDSEntity_Quadrangle ] = VTK_QUAD;
184 theVtkTypes[ SMDSEntity_Quad_Quadrangle ] = VTK_QUADRATIC_QUAD;
185 theVtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
186 theVtkTypes[ SMDSEntity_Polygon ] = VTK_POLYGON;
187 theVtkTypes[ SMDSEntity_Quad_Polygon ] = VTK_QUADRATIC_POLYGON;
188 theVtkTypes[ SMDSEntity_Tetra ] = VTK_TETRA;
189 theVtkTypes[ SMDSEntity_Quad_Tetra ] = VTK_QUADRATIC_TETRA;
190 theVtkTypes[ SMDSEntity_Pyramid ] = VTK_PYRAMID;
191 theVtkTypes[ SMDSEntity_Quad_Pyramid ] = VTK_QUADRATIC_PYRAMID;
192 theVtkTypes[ SMDSEntity_Hexa ] = VTK_HEXAHEDRON;
193 theVtkTypes[ SMDSEntity_Quad_Hexa ] = VTK_QUADRATIC_HEXAHEDRON;
194 theVtkTypes[ SMDSEntity_TriQuad_Hexa ] = VTK_TRIQUADRATIC_HEXAHEDRON;
195 theVtkTypes[ SMDSEntity_Penta ] = VTK_WEDGE;
196 theVtkTypes[ SMDSEntity_Quad_Penta ] = VTK_QUADRATIC_WEDGE;
197 theVtkTypes[ SMDSEntity_BiQuad_Penta ] = VTK_BIQUADRATIC_QUADRATIC_WEDGE;
198 theVtkTypes[ SMDSEntity_Hexagonal_Prism ] = VTK_HEXAGONAL_PRISM;
199 theVtkTypes[ SMDSEntity_Polyhedra ] = VTK_POLYHEDRON;
200 //theVtkTypes[ SMDSEntity_Quad_Polyhedra ] = ;
201 theVtkTypes[ SMDSEntity_Ball ] = VTK_POLY_VERTEX;
205 //! indices to transform cell connectivity from SMDS to VTK
206 static std::vector< std::vector< int > > theToVtkInterlaces;
208 void initToVtkInterlaces()
210 theToVtkInterlaces.resize( SMDSEntity_Last+1 );
212 // const int ids[] = {0};
213 // theToVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
214 // theToVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
217 // const int ids[] = {0,1};
218 // theToVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
221 // const int ids[] = {0,1,2};
222 // theToVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
225 // const int ids[] = {0,1,2};
226 // theToVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
229 // const int ids[] = {0,1,2,3,4,5};
230 // theToVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
233 // const int ids[] = {0,1,2,3};
234 // theToVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
237 // const int ids[] = {0,1,2,3,4,5,6,7};
238 // theToVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
241 // const int ids[] = {0,1,2,3,4,5,6,7,8};
242 // theToVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
245 const int ids[] = {0,2,1,3};
246 theToVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
249 const int ids[] = {0,2,1,3,6,5,4,7,9,8};
250 theToVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
253 const int ids[] = {0,3,2,1,4};
254 theToVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
257 const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
258 theToVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
261 const int ids[] = {0,3,2,1,4,7,6,5};
262 theToVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
265 const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
266 theToVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
269 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};
270 theToVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
273 const int ids[] = {0,1,2,3,4,5};
274 theToVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
277 const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // TODO: check
278 theToVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
281 const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};// TODO: check
282 theToVtkInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
285 const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
286 theToVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
291 //! indices to reverse an SMDS cell
292 static std::vector< std::vector< int > > theReverseInterlaces;
294 void initReverseInterlaces()
296 theReverseInterlaces.resize( SMDSEntity_Last+1 );
298 const int ids[] = {0};
299 theReverseInterlaces[SMDSEntity_0D ].assign( &ids[0], &ids[0]+1 );
300 theReverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
301 theReverseInterlaces[SMDSEntity_Ball].assign( &ids[0], &ids[0]+1 );
304 const int ids[] = {1,0};
305 theReverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
308 const int ids[] = {1,0,2};
309 theReverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
312 const int ids[] = {0,2,1};
313 theReverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
316 const int ids[] = {0,2,1,5,4,3};
317 theReverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
320 const int ids[] = {0,2,1,5,4,3,6};
321 theReverseInterlaces[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
324 const int ids[] = {0,3,2,1};
325 theReverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
328 const int ids[] = {0,3,2,1,7,6,5,4};
329 theReverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
332 const int ids[] = {0,3,2,1,7,6,5,4,8};
333 theReverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
336 const int ids[] = {0,2,1,3};
337 theReverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
340 const int ids[] = {0,2,1,3,6,5,4,7,9,8};
341 theReverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
344 const int ids[] = {0,3,2,1,4};
345 theReverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
348 const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
349 theReverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
352 const int ids[] = {0,3,2,1,4,7,6,5};
353 theReverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
356 const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
357 theReverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
360 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};
361 theReverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
364 const int ids[] = {0,2,1,3,5,4};
365 theReverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
368 const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13};
369 theReverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
372 const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17};
373 theReverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 );
376 const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
377 theReverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
382 //! indices to set nodes of a quadratic 1D or 2D element in interlaced order
383 static std::vector< std::vector< int > > theQuadInterlace;
385 void initQuadInterlace()
387 theQuadInterlace.resize( SMDSEntity_Last+1 );
389 const int ids[] = {0,2,1};
390 theQuadInterlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
393 const int ids[] = {0,3,1,4,2,5,6};
394 theQuadInterlace[SMDSEntity_Quad_Triangle ].assign( &ids[0], &ids[0]+6 );
395 theQuadInterlace[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
398 const int ids[] = {0,4,1,5,2,6,3,7,8};
399 theQuadInterlace[SMDSEntity_Quad_Quadrangle ].assign( &ids[0], &ids[0]+8 );
400 theQuadInterlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
405 //! indices to transform cell connectivity from VTK to SMDS
406 static std::vector< std::vector<int> > theFromVtkInterlaces;
408 void initFromVtkInterlaces()
410 theFromVtkInterlaces.resize( SMDSEntity_Last+1 );
411 for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
413 const std::vector<int> & toVtk = SMDS_MeshCell::toVtkOrder( SMDSAbs_EntityType( iSMDS ));
414 std::vector<int> & toSmds = theFromVtkInterlaces[ iSMDS ];
415 toSmds.resize( toVtk.size() );
416 for ( size_t i = 0; i < toVtk.size(); ++i )
417 toSmds[ toVtk[i] ] = i;
423 void SMDS_MeshCell::InitStaticMembers()
427 initToVtkInterlaces();
428 initReverseInterlaces();
430 initFromVtkInterlaces();
433 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, int theNbNodes, ... )
435 ASSERT( getCellProps( theEntity ).myNbNodes == theNbNodes ||
436 getCellProps( theEntity ).myIsPoly);
439 va_start( vl, theNbNodes );
441 vtkIdType vtkIds[ VTK_CELL_SIZE ];
442 typedef const SMDS_MeshNode* node_t;
444 const std::vector<int>& interlace = toVtkOrder( theEntity );
445 if ((int) interlace.size() == theNbNodes )
447 const SMDS_MeshNode* nodes[ VTK_CELL_SIZE ];
448 for ( int i = 0; i < theNbNodes; i++ )
449 nodes[i] = va_arg( vl, node_t );
451 for ( int i = 0; i < theNbNodes; i++ )
452 vtkIds[i] = nodes[ interlace[i] ]->GetVtkID();
456 for ( int i = 0; i < theNbNodes; i++ )
457 vtkIds[i] = va_arg( vl, node_t )->GetVtkID();
461 int vtkType = toVtkType( theEntity );
462 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, theNbNodes, vtkIds );
466 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
467 const std::vector<const SMDS_MeshNode*>& nodes )
469 std::vector< vtkIdType > vtkIds( nodes.size() );
470 for ( size_t i = 0; i < nodes.size(); ++i )
471 vtkIds[i] = nodes[i]->GetVtkID();
473 int vtkType = toVtkType( theEntity );
474 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, nodes.size(), &vtkIds[0] );
478 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
479 const std::vector<vtkIdType>& vtkNodeIds )
481 int vtkType = toVtkType( theEntity );
482 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, vtkNodeIds.size(),
483 const_cast< vtkIdType* > ( &vtkNodeIds[0] ));
487 bool SMDS_MeshCell::ChangeNodes(const SMDS_MeshNode* nodes[], const int theNbNodes)
491 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
492 if ( theNbNodes != npts )
494 MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << theNbNodes);
497 const std::vector<int>& interlace = toVtkOrder((VTKCellType) GetVtkType() );
498 if ((int) interlace.size() != theNbNodes )
499 for ( int i = 0; i < theNbNodes; i++ )
501 pts[i] = nodes[i]->GetVtkID();
504 for ( int i = 0; i < theNbNodes; i++ )
506 pts[i] = nodes[ interlace[i] ]->GetVtkID();
512 ///////////////////////////////////////////////////////////////////////////////
513 ///Return The number of nodes owned by the current element
514 ///////////////////////////////////////////////////////////////////////////////
515 int SMDS_MeshCell::NbNodes() const
517 if ( GetVtkType() == VTK_POLYHEDRON )
518 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbNodes();
519 vtkIdType *pts, npts;
520 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
524 int SMDS_MeshCell::NbFaces() const
526 if ( GetVtkType() == VTK_POLYHEDRON )
527 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbFaces();
528 return getCellProps( GetVtkType() ).myNbFaces;
531 int SMDS_MeshCell::NbEdges() const
533 switch ( GetEntityType() )
535 case SMDSEntity_Polyhedra:
536 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbEdges();
537 case SMDSEntity_Polygon:
539 case SMDSEntity_Quad_Polygon:
540 return NbNodes() / 2;
543 return getCellProps( GetVtkType() ).myNbEdges;
546 int SMDS_MeshCell::NbCornerNodes() const
548 switch ( GetVtkType() )
551 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbCornerNodes();
554 case VTK_QUADRATIC_POLYGON:
555 return NbNodes() / 2;
558 return getCellProps( GetVtkType() ).myNbCornerNodes;
561 ///////////////////////////////////////////////////////////////////////////////
562 /// Create an iterator which iterate on nodes owned by the element.
563 ///////////////////////////////////////////////////////////////////////////////
564 SMDS_ElemIteratorPtr SMDS_MeshCell::nodesIterator() const
566 if ( GetVtkType() == VTK_POLYHEDRON )
567 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodesIterator();
569 return boost::make_shared< SMDS_VtkCellIterator<> >( GetMesh(), GetVtkID(), GetEntityType());
572 ///////////////////////////////////////////////////////////////////////////////
573 /// Create an iterator which iterate on nodes owned by the element.
574 ///////////////////////////////////////////////////////////////////////////////
575 SMDS_NodeIteratorPtr SMDS_MeshCell::nodeIterator() const
577 if ( GetVtkType() == VTK_POLYHEDRON )
578 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodeIterator();
580 return SMDS_NodeIteratorPtr
581 (new SMDS_VtkCellIterator<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
584 SMDS_NodeIteratorPtr SMDS_MeshCell::interlacedNodesIterator() const
586 bool canInterlace = ( GetType() == SMDSAbs_Face || GetType() == SMDSAbs_Edge );
587 return canInterlace ? nodesIteratorToUNV() : nodeIterator();
590 SMDS_NodeIteratorPtr SMDS_MeshCell::nodesIteratorToUNV() const
592 return SMDS_NodeIteratorPtr
593 (new SMDS_VtkCellIteratorToUNV<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
596 SMDSAbs_ElementType SMDS_MeshCell::GetType() const
598 return getCellProps( GetVtkType() ).myType;
601 SMDSAbs_EntityType SMDS_MeshCell::GetEntityType() const
603 return toSmdsType( (VTKCellType) GetVtkType() );
606 SMDSAbs_GeometryType SMDS_MeshCell::GetGeomType() const
608 return getCellProps( GetVtkType() ).myGeom;
611 VTKCellType SMDS_MeshCell::GetVtkType() const
613 return (VTKCellType) getGrid()->GetCellType( GetVtkID() );
616 bool SMDS_MeshCell::IsPoly() const
618 return getCellProps( GetVtkType() ).myIsPoly;
621 bool SMDS_MeshCell::IsQuadratic() const
623 return getCellProps( GetVtkType() ).myIsQuadratic;
626 const SMDS_MeshNode* SMDS_MeshCell::GetNode(const int ind) const
628 if ( GetVtkType() == VTK_POLYHEDRON )
629 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNode( ind );
631 vtkIdType npts, *pts;
632 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
633 const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( GetVtkType() ));
634 return GetMesh()->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ ind ]]);
637 int SMDS_MeshCell::GetNodeIndex( const SMDS_MeshNode* node ) const
639 if ( GetVtkType() == VTK_POLYHEDRON )
640 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node );
642 vtkIdType npts, *pts;
643 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
644 for ( vtkIdType i = 0; i < npts; ++i )
645 if ( pts[i] == node->GetVtkID() )
647 const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() ));
648 return interlace.empty() ? i : interlace[i];
653 //================================================================================
655 * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
657 //================================================================================
659 VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
661 return theVtkTypes[ smdsType ];
664 //================================================================================
666 * \brief Return indices to transform cell connectivity from SMDS to VTK
667 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
669 //================================================================================
671 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
673 return theToVtkInterlaces[ smdsType ];
676 //================================================================================
678 * \brief Return indices to reverse an SMDS cell of given type.
679 * nbNodes is useful for polygons
680 * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
682 //================================================================================
684 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
685 const size_t nbNodes)
687 if ( smdsType == SMDSEntity_Polygon )
689 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
691 theReverseInterlaces[ smdsType ].resize( nbNodes );
692 for ( size_t i = 0; i < nbNodes; ++i )
693 theReverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
696 else if ( smdsType == SMDSEntity_Quad_Polygon )
698 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
700 // e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
701 theReverseInterlaces[ smdsType ].resize( nbNodes );
703 theReverseInterlaces[ smdsType ][pos++] = 0;
704 for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
705 theReverseInterlaces[ smdsType ][pos++] = i;
706 for ( int i = nbNodes - 1, nb = nbNodes / 2; i >= nb; --i ) // 7,6,5,4
707 theReverseInterlaces[ smdsType ][pos++] = i;
711 return theReverseInterlaces[ smdsType ];
714 //================================================================================
716 * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
717 * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
719 //================================================================================
721 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
722 const size_t nbNodes)
724 if ( smdsType == SMDSEntity_Quad_Polygon )
726 if ( theQuadInterlace[smdsType].size() != nbNodes )
728 theQuadInterlace[smdsType].resize( nbNodes );
729 for ( size_t i = 0; i < nbNodes / 2; ++i )
731 theQuadInterlace[smdsType][i*2+0] = i;
732 theQuadInterlace[smdsType][i*2+1] = i + nbNodes / 2;
736 return theQuadInterlace[smdsType];
739 //================================================================================
741 * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
743 //================================================================================
745 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
747 return getCellProps( vtkType ).myEntity;
750 //================================================================================
752 * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
754 //================================================================================
756 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType)
758 switch ( geomType ) {
759 case SMDSGeom_POINT: return SMDSAbs_0DElement;
761 case SMDSGeom_EDGE: return SMDSAbs_Edge;
763 case SMDSGeom_TRIANGLE:
764 case SMDSGeom_QUADRANGLE:
765 case SMDSGeom_POLYGON: return SMDSAbs_Face;
768 case SMDSGeom_PYRAMID:
771 case SMDSGeom_HEXAGONAL_PRISM:
772 case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
774 case SMDSGeom_BALL: return SMDSAbs_Ball;
776 case SMDSGeom_NONE: ;
781 //================================================================================
783 * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
785 //================================================================================
787 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_EntityType entityType)
789 return getCellProps( entityType ).myType;
792 SMDSAbs_GeometryType SMDS_MeshCell::GeomType( SMDSAbs_EntityType entityType )
794 return getCellProps( entityType ).myGeom;
797 bool SMDS_MeshCell::IsPoly( SMDSAbs_EntityType entityType )
799 return getCellProps( entityType ).myIsPoly;
802 bool SMDS_MeshCell::IsQuadratic( SMDSAbs_EntityType entityType )
804 return getCellProps( entityType ).myIsQuadratic;
807 int SMDS_MeshCell::NbCornerNodes( SMDSAbs_EntityType entityType )
809 return getCellProps( entityType ).myNbCornerNodes;
812 int SMDS_MeshCell::NbNodes( SMDSAbs_EntityType entityType )
814 return getCellProps( entityType ).myNbNodes;
817 int SMDS_MeshCell::NbEdges( SMDSAbs_EntityType entityType )
819 return getCellProps( entityType ).myNbEdges;
822 int SMDS_MeshCell::NbFaces( SMDSAbs_EntityType entityType )
824 return getCellProps( entityType ).myNbFaces;
827 //================================================================================
829 * \brief Return indices to transform cell connectivity from VTK to SMDS
830 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
832 //================================================================================
834 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
836 return theFromVtkInterlaces[ smdsType ];
839 //================================================================================
841 * \brief Return indices to transform cell connectivity from SMDS to VTK
842 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
844 //================================================================================
846 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
848 return toVtkOrder( toSmdsType( vtkType ));
851 //================================================================================
853 * \brief Return indices to transform cell connectivity from VTK to SMDS
854 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
856 //================================================================================
858 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
860 return fromVtkOrder( toSmdsType( vtkType ));