1 // Copyright (C) 2010-2019 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)
494 vtkIdType const *tmp(nullptr);
495 getGrid()->GetCellPoints( GetVtkID(), npts, tmp );
496 std::copy(tmp,tmp+npts,pts);
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();
525 vtkIdType const *pts;
526 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
530 int SMDS_MeshCell::NbFaces() const
532 if ( GetVtkType() == VTK_POLYHEDRON )
533 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbFaces();
534 return getCellProps( GetVtkType() ).myNbFaces;
537 int SMDS_MeshCell::NbEdges() const
539 switch ( GetEntityType() )
541 case SMDSEntity_Polyhedra:
542 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbEdges();
543 case SMDSEntity_Polygon:
545 case SMDSEntity_Quad_Polygon:
546 return NbNodes() / 2;
549 return getCellProps( GetVtkType() ).myNbEdges;
552 int SMDS_MeshCell::NbCornerNodes() const
554 switch ( GetVtkType() )
557 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbCornerNodes();
560 case VTK_QUADRATIC_POLYGON:
561 return NbNodes() / 2;
564 return getCellProps( GetVtkType() ).myNbCornerNodes;
567 ///////////////////////////////////////////////////////////////////////////////
568 /// Create an iterator which iterate on nodes owned by the element.
569 ///////////////////////////////////////////////////////////////////////////////
570 SMDS_ElemIteratorPtr SMDS_MeshCell::nodesIterator() const
572 if ( GetVtkType() == VTK_POLYHEDRON )
573 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodesIterator();
575 return boost::make_shared< SMDS_VtkCellIterator<> >( GetMesh(), GetVtkID(), GetEntityType());
578 ///////////////////////////////////////////////////////////////////////////////
579 /// Create an iterator which iterate on nodes owned by the element.
580 ///////////////////////////////////////////////////////////////////////////////
581 SMDS_NodeIteratorPtr SMDS_MeshCell::nodeIterator() const
583 if ( GetVtkType() == VTK_POLYHEDRON )
584 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodeIterator();
586 return SMDS_NodeIteratorPtr
587 (new SMDS_VtkCellIterator<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
590 SMDS_NodeIteratorPtr SMDS_MeshCell::interlacedNodesIterator() const
592 bool canInterlace = ( GetType() == SMDSAbs_Face || GetType() == SMDSAbs_Edge );
593 return canInterlace ? nodesIteratorToUNV() : nodeIterator();
596 SMDS_NodeIteratorPtr SMDS_MeshCell::nodesIteratorToUNV() const
598 return SMDS_NodeIteratorPtr
599 (new SMDS_VtkCellIteratorToUNV<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
602 SMDSAbs_ElementType SMDS_MeshCell::GetType() const
604 return getCellProps( GetVtkType() ).myType;
607 SMDSAbs_EntityType SMDS_MeshCell::GetEntityType() const
609 return toSmdsType( (VTKCellType) GetVtkType() );
612 SMDSAbs_GeometryType SMDS_MeshCell::GetGeomType() const
614 return getCellProps( GetVtkType() ).myGeom;
617 VTKCellType SMDS_MeshCell::GetVtkType() const
619 return (VTKCellType) getGrid()->GetCellType( GetVtkID() );
622 bool SMDS_MeshCell::IsPoly() const
624 return getCellProps( GetVtkType() ).myIsPoly;
627 bool SMDS_MeshCell::IsQuadratic() const
629 return getCellProps( GetVtkType() ).myIsQuadratic;
632 const SMDS_MeshNode* SMDS_MeshCell::GetNode(const int ind) const
634 if ( GetVtkType() == VTK_POLYHEDRON )
635 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNode( ind );
638 vtkIdType const *pts;
639 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
640 const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( GetVtkType() ));
641 return GetMesh()->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ ind ]]);
644 int SMDS_MeshCell::GetNodeIndex( const SMDS_MeshNode* node ) const
646 if ( !node || node->IsNull() )
649 if ( GetVtkType() == VTK_POLYHEDRON )
650 return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node );
653 vtkIdType const *pts;
654 getGrid()->GetCellPoints( GetVtkID(), npts, pts );
655 for ( vtkIdType i = 0; i < npts; ++i )
656 if ( pts[i] == node->GetVtkID() )
658 const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() ));
659 return interlace.empty() ? i : interlace[i];
664 //================================================================================
666 * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
668 //================================================================================
670 VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
672 return theVtkTypes[ smdsType ];
675 //================================================================================
677 * \brief Return indices to transform cell connectivity from SMDS to VTK
678 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
680 //================================================================================
682 const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
684 return theToVtkInterlaces[ smdsType ];
687 //================================================================================
689 * \brief Return indices to reverse an SMDS cell of given type.
690 * nbNodes is useful for polygons
691 * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
693 //================================================================================
695 const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
696 const size_t nbNodes)
698 if ( smdsType == SMDSEntity_Polygon )
700 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
702 theReverseInterlaces[ smdsType ].resize( nbNodes );
703 for ( size_t i = 0; i < nbNodes; ++i )
704 theReverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
707 else if ( smdsType == SMDSEntity_Quad_Polygon )
709 if ( theReverseInterlaces[ smdsType ].size() != nbNodes )
711 // e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
712 theReverseInterlaces[ smdsType ].resize( nbNodes );
714 theReverseInterlaces[ smdsType ][pos++] = 0;
715 for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
716 theReverseInterlaces[ smdsType ][pos++] = i;
717 for ( int i = nbNodes - 1, nb = nbNodes / 2; i >= nb; --i ) // 7,6,5,4
718 theReverseInterlaces[ smdsType ][pos++] = i;
722 return theReverseInterlaces[ smdsType ];
725 //================================================================================
727 * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
728 * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
730 //================================================================================
732 const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
733 const size_t nbNodes)
735 if ( smdsType == SMDSEntity_Quad_Polygon )
737 if ( theQuadInterlace[smdsType].size() != nbNodes )
739 theQuadInterlace[smdsType].resize( nbNodes );
740 for ( size_t i = 0; i < nbNodes / 2; ++i )
742 theQuadInterlace[smdsType][i*2+0] = i;
743 theQuadInterlace[smdsType][i*2+1] = i + nbNodes / 2;
747 return theQuadInterlace[smdsType];
750 //================================================================================
752 * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
754 //================================================================================
756 SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
758 return getCellProps( vtkType ).myEntity;
761 //================================================================================
763 * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
765 //================================================================================
767 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType)
769 switch ( geomType ) {
770 case SMDSGeom_POINT: return SMDSAbs_0DElement;
772 case SMDSGeom_EDGE: return SMDSAbs_Edge;
774 case SMDSGeom_TRIANGLE:
775 case SMDSGeom_QUADRANGLE:
776 case SMDSGeom_POLYGON: return SMDSAbs_Face;
779 case SMDSGeom_PYRAMID:
782 case SMDSGeom_HEXAGONAL_PRISM:
783 case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
785 case SMDSGeom_BALL: return SMDSAbs_Ball;
787 case SMDSGeom_NONE: ;
792 //================================================================================
794 * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
796 //================================================================================
798 SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_EntityType entityType)
800 return getCellProps( entityType ).myType;
803 SMDSAbs_GeometryType SMDS_MeshCell::GeomType( SMDSAbs_EntityType entityType )
805 return getCellProps( entityType ).myGeom;
808 bool SMDS_MeshCell::IsPoly( SMDSAbs_EntityType entityType )
810 return getCellProps( entityType ).myIsPoly;
813 bool SMDS_MeshCell::IsQuadratic( SMDSAbs_EntityType entityType )
815 return getCellProps( entityType ).myIsQuadratic;
818 int SMDS_MeshCell::NbCornerNodes( SMDSAbs_EntityType entityType )
820 return getCellProps( entityType ).myNbCornerNodes;
823 int SMDS_MeshCell::NbNodes( SMDSAbs_EntityType entityType )
825 return getCellProps( entityType ).myNbNodes;
828 int SMDS_MeshCell::NbEdges( SMDSAbs_EntityType entityType )
830 return getCellProps( entityType ).myNbEdges;
833 int SMDS_MeshCell::NbFaces( SMDSAbs_EntityType entityType )
835 return getCellProps( entityType ).myNbFaces;
838 //================================================================================
840 * \brief Return indices to transform cell connectivity from VTK to SMDS
841 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
843 //================================================================================
845 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
847 return theFromVtkInterlaces[ smdsType ];
850 //================================================================================
852 * \brief Return indices to transform cell connectivity from SMDS to VTK
853 * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
855 //================================================================================
857 const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
859 return toVtkOrder( toSmdsType( vtkType ));
862 //================================================================================
864 * \brief Return indices to transform cell connectivity from VTK to SMDS
865 * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
867 //================================================================================
869 const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
871 return fromVtkOrder( toSmdsType( vtkType ));