+} // namespace
+
+void SMDS_MeshCell::InitStaticMembers()
+{
+ if ( theCellProps.empty() )
+ {
+ initCellProps();
+ initVtkTypes();
+ initToVtkInterlaces();
+ initReverseInterlaces();
+ initQuadInterlace();
+ initFromVtkInterlaces();
+ }
+}
+
+void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, int theNbNodes, ... )
+{
+ ASSERT( getCellProps( theEntity ).myNbNodes == theNbNodes ||
+ getCellProps( theEntity ).myIsPoly);
+
+ va_list vl;
+ va_start( vl, theNbNodes );
+
+ vtkIdType vtkIds[ VTK_CELL_SIZE ];
+ typedef const SMDS_MeshNode* node_t;
+
+ const std::vector<int>& interlace = toVtkOrder( theEntity );
+ if ((int) interlace.size() == theNbNodes )
+ {
+ const SMDS_MeshNode* nodes[ VTK_CELL_SIZE ];
+ for ( int i = 0; i < theNbNodes; i++ )
+ nodes[i] = va_arg( vl, node_t );
+
+ for ( int i = 0; i < theNbNodes; i++ )
+ vtkIds[i] = nodes[ interlace[i] ]->GetVtkID();
+ }
+ else
+ {
+ for ( int i = 0; i < theNbNodes; i++ )
+ vtkIds[i] = va_arg( vl, node_t )->GetVtkID();
+ }
+ va_end( vl );
+
+ int vtkType = toVtkType( theEntity );
+ vtkIdType vtkID = getGrid()->InsertNextLinkedCell( vtkType, theNbNodes, vtkIds );
+ setVtkID( vtkID );
+}
+
+void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
+ const std::vector<const SMDS_MeshNode*>& nodes )
+{
+ std::vector< vtkIdType > vtkIds( nodes.size() );
+ for ( size_t i = 0; i < nodes.size(); ++i )
+ vtkIds[i] = nodes[i]->GetVtkID();
+
+ int vtkType = toVtkType( theEntity );
+ vtkIdType vtkID = getGrid()->InsertNextLinkedCell( vtkType, nodes.size(), &vtkIds[0] );
+ setVtkID( vtkID );
+}
+
+void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity,
+ const std::vector<vtkIdType>& vtkNodeIds )
+{
+ int vtkType = toVtkType( theEntity );
+ vtkIdType vtkID = getGrid()->InsertNextLinkedCell( vtkType, vtkNodeIds.size(),
+ const_cast< vtkIdType* > ( &vtkNodeIds[0] ));
+ setVtkID( vtkID );
+}
+
+bool SMDS_MeshCell::ChangeNodes(const SMDS_MeshNode* nodes[], const int theNbNodes)
+{
+ vtkIdType npts = 0;
+ vtkIdType *pts(nullptr);
+ vtkIdType const *tmp(nullptr);
+ getGrid()->GetCellPoints( GetVtkID(), npts, tmp );
+ pts = const_cast<vtkIdType *>(tmp);
+ if ( theNbNodes != npts )
+ {
+ MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << theNbNodes);
+ return false;
+ }
+ const std::vector<int>& interlace = toVtkOrder((VTKCellType) GetVtkType() );
+ if ((int) interlace.size() != theNbNodes )
+ for ( int i = 0; i < theNbNodes; i++ )
+ {
+ pts[i] = nodes[i]->GetVtkID();
+ }
+ else
+ for ( int i = 0; i < theNbNodes; i++ )
+ {
+ pts[i] = nodes[ interlace[i] ]->GetVtkID();
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return The number of nodes owned by the current element
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_MeshCell::NbNodes() const
+{
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbNodes();
+ vtkIdType npts = getGrid()->GetCells()->GetCellSize( GetVtkID() );
+ return npts;
+}
+
+int SMDS_MeshCell::NbFaces() const
+{
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbFaces();
+ return getCellProps( GetVtkType() ).myNbFaces;
+}
+
+int SMDS_MeshCell::NbEdges() const
+{
+ switch ( GetEntityType() )
+ {
+ case SMDSEntity_Polyhedra:
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbEdges();
+ case SMDSEntity_Polygon:
+ return NbNodes();
+ case SMDSEntity_Quad_Polygon:
+ return NbNodes() / 2;
+ default:;
+ }
+ return getCellProps( GetVtkType() ).myNbEdges;
+}
+
+int SMDS_MeshCell::NbCornerNodes() const
+{
+ switch ( GetVtkType() )
+ {
+ case VTK_POLYHEDRON:
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::NbCornerNodes();
+ case VTK_POLYGON:
+ return NbNodes();
+ case VTK_QUADRATIC_POLYGON:
+ return NbNodes() / 2;
+ default:;
+ }
+ return getCellProps( GetVtkType() ).myNbCornerNodes;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create an iterator which iterate on nodes owned by the element.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_MeshCell::nodesIterator() const
+{
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodesIterator();
+
+ return boost::make_shared< SMDS_VtkCellIterator<> >( GetMesh(), GetVtkID(), GetEntityType());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create an iterator which iterate on nodes owned by the element.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_NodeIteratorPtr SMDS_MeshCell::nodeIterator() const
+{
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::nodeIterator();
+
+ return SMDS_NodeIteratorPtr
+ (new SMDS_VtkCellIterator<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
+}
+
+SMDS_NodeIteratorPtr SMDS_MeshCell::interlacedNodesIterator() const
+{
+ bool canInterlace = ( GetType() == SMDSAbs_Face || GetType() == SMDSAbs_Edge );
+ return canInterlace ? nodesIteratorToUNV() : nodeIterator();
+}
+
+SMDS_NodeIteratorPtr SMDS_MeshCell::nodesIteratorToUNV() const
+{
+ return SMDS_NodeIteratorPtr
+ (new SMDS_VtkCellIteratorToUNV<SMDS_NodeIterator>( GetMesh(), GetVtkID(), GetEntityType()));
+}
+
+SMDSAbs_ElementType SMDS_MeshCell::GetType() const
+{
+ return getCellProps( GetVtkType() ).myType;
+}
+
+SMDSAbs_EntityType SMDS_MeshCell::GetEntityType() const
+{
+ return toSmdsType( (VTKCellType) GetVtkType() );
+}
+
+SMDSAbs_GeometryType SMDS_MeshCell::GetGeomType() const
+{
+ return getCellProps( GetVtkType() ).myGeom;
+}
+
+VTKCellType SMDS_MeshCell::GetVtkType() const
+{
+ return (VTKCellType) getGrid()->GetCellType( GetVtkID() );
+}
+
+bool SMDS_MeshCell::IsPoly() const
+{
+ return getCellProps( GetVtkType() ).myIsPoly;
+}
+
+bool SMDS_MeshCell::IsQuadratic() const
+{
+ return getCellProps( GetVtkType() ).myIsQuadratic;
+}
+
+const SMDS_MeshNode* SMDS_MeshCell::GetNode(const int ind) const
+{
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNode( ind );
+
+ vtkIdType npts;
+ vtkIdType const *pts;
+ getGrid()->GetCellPoints( GetVtkID(), npts, pts );
+ const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( GetVtkType() ));
+ return GetMesh()->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ ind ]]);
+}
+
+int SMDS_MeshCell::GetNodeIndex( const SMDS_MeshNode* node ) const
+{
+ if ( !node || node->IsNull() )
+ return -1;
+
+ if ( GetVtkType() == VTK_POLYHEDRON )
+ return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node );
+
+ vtkIdType npts;
+ vtkIdType const *pts;
+ getGrid()->GetCellPoints( GetVtkID(), npts, pts );
+ for ( vtkIdType i = 0; i < npts; ++i )
+ if ( pts[i] == node->GetVtkID() )
+ {
+ const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() ));
+ return interlace.empty() ? i : interlace[i];
+ }
+ return -1;
+}
+
+//================================================================================
+/*!
+ * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
+ */
+//================================================================================
+
+VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
+{
+ return theVtkTypes[ smdsType ];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to transform cell connectivity from SMDS to VTK
+ * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
+{
+ return theToVtkInterlaces[ smdsType ];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to reverse an SMDS cell of given type.
+ * nbNodes is useful for polygons
+ * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
+ const size_t nbNodes)
+{