1 // Copyright (C) 2010-2020 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=*/18,/*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()
425 if ( theCellProps.empty() )
429 initToVtkInterlaces();
430 initReverseInterlaces();
432 initFromVtkInterlaces();
436 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, int theNbNodes, ... )
438 ASSERT( getCellProps( theEntity ).myNbNodes == theNbNodes ||
439 getCellProps( theEntity ).myIsPoly);
442 va_start( vl, theNbNodes );
444 vtkIdType vtkIds[ VTK_CELL_SIZE ];
445 typedef const SMDS_MeshNode* node_t;
447 const std::vector<int>& interlace = toVtkOrder( theEntity );
448 if ((int) interlace.size() == theNbNodes )
450 const SMDS_MeshNode* nodes[ VTK_CELL_SIZE ];
451 for ( int i = 0; i < theNbNodes; i++ )
452 nodes[i] = va_arg( vl, node_t );
454 for ( int i = 0; i < theNbNodes; i++ )
455 vtkIds[i] = nodes[ interlace[i] ]->GetVtkID();
459 for ( int i = 0; i < theNbNodes; i++ )
460 vtkIds[i] = va_arg( vl, node_t )->GetVtkID();
464 int vtkType = toVtkType( theEntity );
465 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, theNbNodes, vtkIds );
469 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
470 const std::vector<const SMDS_MeshNode*>& nodes )
472 std::vector< vtkIdType > vtkIds( nodes.size() );
473 for ( size_t i = 0; i < nodes.size(); ++i )
474 vtkIds[i] = nodes[i]->GetVtkID();
476 int vtkType = toVtkType( theEntity );
477 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, nodes.size(), &vtkIds[0] );
481 void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
482 const std::vector<vtkIdType>& vtkNodeIds )
484 int vtkType = toVtkType( theEntity );
485 int vtkID = getGrid()->InsertNextLinkedCell( vtkType, vtkNodeIds.size(),
486 const_cast< vtkIdType* > ( &vtkNodeIds[0] ));
490 bool SMDS_MeshCell::ChangeNodes(const SMDS_MeshNode* nodes[], const int theNbNodes)
493 vtkIdType *pts(nullptr);
494 vtkIdType const *tmp(nullptr);
495 getGrid()->GetCellPoints( GetVtkID(), npts, tmp );
496 pts = const_cast<vtkIdType *>(tmp);
497 if ( theNbNodes != npts )
499 MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << theNbNodes);
502 const std::vector<int>& interlace = toVtkOrder((VTKCellType) GetVtkType() );
503 if ((int) interlace.size() != theNbNodes )
504 for ( int i = 0; i < theNbNodes; i++ )
506 pts[i] = nodes[i]->GetVtkID();
509 for ( int i = 0; i < theNbNodes; i++ )
511 pts[i] = nodes[ interlace[i] ]->GetVtkID();
517 ///////////////////////////////////////////////////////////////////////////////
518 ///Return The number of nodes owned by the current element
519 ///////////////////////////////////////////////////////////////////////////////
520 int SMDS_MeshCell::NbNodes() const
522 if ( GetVtkType() == VTK_POLYHEDRON )
523 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbNodes();
524 vtkIdType npts = getGrid()->GetCells()->GetCellSize( GetVtkID() );
528 int SMDS_MeshCell::NbFaces() const
530 if ( GetVtkType() == VTK_POLYHEDRON )
531 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbFaces();
532 return getCellProps( GetVtkType() ).myNbFaces;
535 int SMDS_MeshCell::NbEdges() const
537 switch ( GetEntityType() )
539 case SMDSEntity_Polyhedra:
540 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbEdges();
541 case SMDSEntity_Polygon:
543 case SMDSEntity_Quad_Polygon:
544 return NbNodes() / 2;
547 return getCellProps( GetVtkType() ).myNbEdges;
550 int SMDS_MeshCell::NbCornerNodes() const
552 switch ( GetVtkType() )
555 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbCornerNodes();
558 case VTK_QUADRATIC_POLYGON:
559 return NbNodes() / 2;
562 return getCellProps( GetVtkType() ).myNbCornerNodes;
565 ///////////////////////////////////////////////////////////////////////////////
566 /// Create an iterator which iterate on nodes owned by the element.
567 ///////////////////////////////////////////////////////////////////////////////
568 SMDS_ElemIteratorPtr SMDS_MeshCell::nodesIterator() const
570 if ( GetVtkType() == VTK_POLYHEDRON )
571 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodesIterator();
573 return boost::make_shared< SMDS_VtkCellIterator<> >( GetMesh(), GetVtkID(), GetEntityType());
576 ///////////////////////////////////////////////////////////////////////////////
577 /// Create an iterator which iterate on nodes owned by the element.
578 ///////////////////////////////////////////////////////////////////////////////
579 SMDS_NodeIteratorPtr SMDS_MeshCell::nodeIterator() const
581 if ( GetVtkType() == VTK_POLYHEDRON )
582 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodeIterator();
584 return SMDS_NodeIteratorPtr
585 (new SMDS_VtkCellIterator<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
588 SMDS_NodeIteratorPtr SMDS_MeshCell::interlacedNodesIterator() const
590 bool canInterlace = ( GetType() == SMDSAbs_Face || GetType() == SMDSAbs_Edge );
591 return canInterlace ? nodesIteratorToUNV() : nodeIterator();
594 SMDS_NodeIteratorPtr SMDS_MeshCell::nodesIteratorToUNV() const
596 return SMDS_NodeIteratorPtr
597 (new SMDS_VtkCellIteratorToUNV<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
600 SMDSAbs_ElementType SMDS_MeshCell::GetType() const
602 return getCellProps( GetVtkType() ).myType;
605 SMDSAbs_EntityType SMDS_MeshCell::GetEntityType() const
607 return toSmdsType( (VTKCellType) GetVtkType() );
610 SMDSAbs_GeometryType SMDS_MeshCell::GetGeomType() const
612 return getCellProps( GetVtkType() ).myGeom;
615 VTKCellType SMDS_MeshCell::GetVtkType() const
617 return (VTKCellType) getGrid()->GetCellType( GetVtkID() );
620 bool SMDS_MeshCell::IsPoly() const
622 return getCellProps( GetVtkType() ).myIsPoly;
625 bool SMDS_MeshCell::IsQuadratic() const
627 return getCellProps( GetVtkType() ).myIsQuadratic;
630 const SMDS_MeshNode* SMDS_MeshCell::GetNode(const int ind) const
632 if ( GetVtkType() == VTK_POLYHEDRON )
633 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNode( ind );
636 vtkIdType const *pts;
637 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
638 const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( GetVtkType() ));
639 return GetMesh()->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ ind ]]);
642 int SMDS_MeshCell::GetNodeIndex( const SMDS_MeshNode* node ) const
644 if ( !node || node->IsNull() )
647 if ( GetVtkType() == VTK_POLYHEDRON )
648 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node );
651 vtkIdType const *pts;
652 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
653 for ( vtkIdType i = 0; i < npts; ++i )
654 if ( pts[i] == node->GetVtkID() )
656 const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() ));
657 return interlace.empty() ? i : interlace[i];
662 //================================================================================
664 * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
666 //================================================================================
668 VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
670 return theVtkTypes[ smdsType ];
673 //================================================================================
675 * \brief Return indices to transform cell connectivity from SMDS to VTK
676 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
678 //================================================================================
680 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
682 return theToVtkInterlaces[ smdsType ];
685 //================================================================================
687 * \brief Return indices to reverse an SMDS cell of given type.
688 * nbNodes is useful for polygons
689 * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
691 //================================================================================
693 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
694 const size_t nbNodes)
696 if ( smdsType == SMDSEntity_Polygon )
698 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
700 theReverseInterlaces[ smdsType ].resize( nbNodes );
701 for ( size_t i = 0; i < nbNodes; ++i )
702 theReverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
705 else if ( smdsType == SMDSEntity_Quad_Polygon )
707 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
709 // e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
710 theReverseInterlaces[ smdsType ].resize( nbNodes );
712 theReverseInterlaces[ smdsType ][pos++] = 0;
713 for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
714 theReverseInterlaces[ smdsType ][pos++] = i;
715 for ( int i = nbNodes - 1, nb = nbNodes / 2; i >= nb; --i ) // 7,6,5,4
716 theReverseInterlaces[ smdsType ][pos++] = i;
720 return theReverseInterlaces[ smdsType ];
723 //================================================================================
725 * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
726 * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
728 //================================================================================
730 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
731 const size_t nbNodes)
733 if ( smdsType == SMDSEntity_Quad_Polygon )
735 if ( theQuadInterlace[smdsType].size() != nbNodes )
737 theQuadInterlace[smdsType].resize( nbNodes );
738 for ( size_t i = 0; i < nbNodes / 2; ++i )
740 theQuadInterlace[smdsType][i*2+0] = i;
741 theQuadInterlace[smdsType][i*2+1] = i + nbNodes / 2;
745 return theQuadInterlace[smdsType];
748 //================================================================================
750 * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
752 //================================================================================
754 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
756 return getCellProps( vtkType ).myEntity;
759 //================================================================================
761 * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
763 //================================================================================
765 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType)
767 switch ( geomType ) {
768 case SMDSGeom_POINT: return SMDSAbs_0DElement;
770 case SMDSGeom_EDGE: return SMDSAbs_Edge;
772 case SMDSGeom_TRIANGLE:
773 case SMDSGeom_QUADRANGLE:
774 case SMDSGeom_POLYGON: return SMDSAbs_Face;
777 case SMDSGeom_PYRAMID:
780 case SMDSGeom_HEXAGONAL_PRISM:
781 case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
783 case SMDSGeom_BALL: return SMDSAbs_Ball;
785 case SMDSGeom_NONE: ;
790 //================================================================================
792 * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
794 //================================================================================
796 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_EntityType entityType)
798 return getCellProps( entityType ).myType;
801 SMDSAbs_GeometryType SMDS_MeshCell::GeomType( SMDSAbs_EntityType entityType )
803 return getCellProps( entityType ).myGeom;
806 bool SMDS_MeshCell::IsPoly( SMDSAbs_EntityType entityType )
808 return getCellProps( entityType ).myIsPoly;
811 bool SMDS_MeshCell::IsQuadratic( SMDSAbs_EntityType entityType )
813 return getCellProps( entityType ).myIsQuadratic;
816 int SMDS_MeshCell::NbCornerNodes( SMDSAbs_EntityType entityType )
818 return getCellProps( entityType ).myNbCornerNodes;
821 int SMDS_MeshCell::NbNodes( SMDSAbs_EntityType entityType )
823 return getCellProps( entityType ).myNbNodes;
826 int SMDS_MeshCell::NbEdges( SMDSAbs_EntityType entityType )
828 return getCellProps( entityType ).myNbEdges;
831 int SMDS_MeshCell::NbFaces( SMDSAbs_EntityType entityType )
833 return getCellProps( entityType ).myNbFaces;
836 //================================================================================
838 * \brief Return indices to transform cell connectivity from VTK to SMDS
839 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
841 //================================================================================
843 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
845 return theFromVtkInterlaces[ smdsType ];
848 //================================================================================
850 * \brief Return indices to transform cell connectivity from SMDS to VTK
851 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
853 //================================================================================
855 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
857 return toVtkOrder( toSmdsType( vtkType ));
860 //================================================================================
862 * \brief Return indices to transform cell connectivity from VTK to SMDS
863 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
865 //================================================================================
867 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
869 return fromVtkOrder( toSmdsType( vtkType ));