X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_MeshCell.cxx;h=7ee9c920811b5e1cfd7ed65c6c765833bb89e53a;hp=7175ae5d457c3cd80695fcea22172c7f9845942e;hb=19fe2e412fa1cb1fd33d7a2580b2483280db811e;hpb=dbd1374aa8aeac32c368b8f6add841e0bd90f807 diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx index 7175ae5d4..7ee9c9208 100644 --- a/src/SMDS/SMDS_MeshCell.cxx +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -18,21 +18,384 @@ // #include "SMDS_MeshCell.hxx" -#include "utilities.h" -int SMDS_MeshCell::nbCells = 0; +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" -SMDS_MeshCell::SMDS_MeshCell() : - SMDS_MeshElement(-1) +#include + +#include + +#include + +#include + +namespace +{ + /*! + * \brief Cell type features + */ + struct CellProps + { + SMDSAbs_EntityType myEntity; + SMDSAbs_ElementType myType; + SMDSAbs_GeometryType myGeom; + bool myIsPoly; + bool myIsQuadratic; + int myNbCornerNodes; + int myNbNodes; + int myNbEdges; + int myNbFaces; + + CellProps() : + myEntity( SMDSEntity_Last ), myType( SMDSAbs_All ), myGeom( SMDSGeom_NONE ), + myIsPoly( 0 ), myNbCornerNodes( 0 ), + myNbNodes( 0 ), myNbEdges( 0 ), myNbFaces ( 0 ) + { + } + void Set( SMDSAbs_EntityType Entity, + SMDSAbs_ElementType Type, + SMDSAbs_GeometryType Geom, + bool IsPoly, + int NbCornerNodes, + int NbNodes, + int NbEdges, + int NbFaces) + { + myEntity = Entity; + myType = Type; + myGeom = Geom; + myIsPoly = IsPoly; + myIsQuadratic = ( NbNodes > NbCornerNodes ); + myNbCornerNodes = NbCornerNodes; + myNbNodes = NbNodes; + myNbEdges = NbEdges; + myNbFaces = NbFaces; + } + }; + + //! return vector a CellProps + const CellProps& getCellProps( VTKCellType vtkType ) + { + static std::vector< CellProps > theCellProps; + if ( theCellProps.empty() ) + { + theCellProps.resize( VTK_NUMBER_OF_CELL_TYPES ); + CellProps* p = & theCellProps[0]; + p[ VTK_VERTEX ]. + Set( SMDSEntity_0D, SMDSAbs_0DElement, SMDSGeom_POINT, + /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 ); + p[ VTK_LINE ]. + Set( SMDSEntity_Edge, SMDSAbs_Edge, SMDSGeom_EDGE, + /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/2,/*nbE=*/1,/*nbF=*/0 ); + p[ VTK_QUADRATIC_EDGE ]. + Set( SMDSEntity_Quad_Edge, SMDSAbs_Edge, SMDSGeom_EDGE, + /*isPoly=*/0,/*nbCN=*/2,/*nbN=*/3,/*nbE=*/1,/*nbF=*/0 ); + p[ VTK_TRIANGLE ]. + Set( SMDSEntity_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, + /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/3,/*nbE=*/3,/*nbF=*/1 ); + p[ VTK_QUADRATIC_TRIANGLE ]. + Set( SMDSEntity_Quad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, + /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/6,/*nbE=*/3,/*nbF=*/1 ); + p[ VTK_BIQUADRATIC_TRIANGLE ]. + Set( SMDSEntity_BiQuad_Triangle, SMDSAbs_Face, SMDSGeom_TRIANGLE, + /*isPoly=*/0,/*nbCN=*/3,/*nbN=*/7,/*nbE=*/3,/*nbF=*/1 ); + p[ VTK_QUAD]. + Set( SMDSEntity_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, + /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/4,/*nbF=*/1 ); + p[ VTK_QUADRATIC_QUAD]. + Set( SMDSEntity_Quad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, + /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/8,/*nbE=*/4,/*nbF=*/1 ); + p[ VTK_BIQUADRATIC_QUAD]. + Set( SMDSEntity_BiQuad_Quadrangle, SMDSAbs_Face, SMDSGeom_QUADRANGLE, + /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/9,/*nbE=*/4,/*nbF=*/1 ); + p[ VTK_POLYGON ]. + Set( SMDSEntity_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON, + /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 ); + p[ VTK_QUADRATIC_POLYGON ]. + Set( SMDSEntity_Quad_Polygon, SMDSAbs_Face, SMDSGeom_POLYGON, + /*isPoly=*/1,/*nbCN=*/-2,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/1 ); + p[ VTK_TETRA ]. + Set( SMDSEntity_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA, + /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/4,/*nbE=*/6,/*nbF=*/4 ); + p[ VTK_QUADRATIC_TETRA ]. + Set( SMDSEntity_Quad_Tetra, SMDSAbs_Volume, SMDSGeom_TETRA, + /*isPoly=*/0,/*nbCN=*/4,/*nbN=*/10,/*nbE=*/6,/*nbF=*/4 ); + p[ VTK_PYRAMID ]. + Set( SMDSEntity_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID, + /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/5,/*nbE=*/8,/*nbF=*/5 ); + p[ VTK_QUADRATIC_PYRAMID]. + Set( SMDSEntity_Quad_Pyramid, SMDSAbs_Volume, SMDSGeom_PYRAMID, + /*isPoly=*/0,/*nbCN=*/5,/*nbN=*/13,/*nbE=*/8,/*nbF=*/5 ); + p[ VTK_HEXAHEDRON ]. + Set( SMDSEntity_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, + /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/8,/*nbE=*/12,/*nbF=*/6 ); + p[ VTK_QUADRATIC_HEXAHEDRON ]. + Set( SMDSEntity_Quad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, + /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/20,/*nbE=*/12,/*nbF=*/6 ); + p[ VTK_TRIQUADRATIC_HEXAHEDRON ]. + Set( SMDSEntity_TriQuad_Hexa, SMDSAbs_Volume, SMDSGeom_HEXA, + /*isPoly=*/0,/*nbCN=*/8,/*nbN=*/27,/*nbE=*/12,/*nbF=*/6 ); + p[ VTK_WEDGE ]. + Set( SMDSEntity_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, + /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/6,/*nbE=*/9,/*nbF=*/5 ); + p[ VTK_QUADRATIC_WEDGE ]. + Set( SMDSEntity_Quad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, + /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/15,/*nbE=*/9,/*nbF=*/5 ); + p[ VTK_BIQUADRATIC_QUADRATIC_WEDGE ]. + Set( SMDSEntity_BiQuad_Penta, SMDSAbs_Volume, SMDSGeom_PENTA, + /*isPoly=*/0,/*nbCN=*/6,/*nbN=*/21,/*nbE=*/9,/*nbF=*/5 ); + p[ VTK_HEXAGONAL_PRISM]. + Set( SMDSEntity_Hexagonal_Prism, SMDSAbs_Volume, SMDSGeom_HEXAGONAL_PRISM, + /*isPoly=*/0,/*nbCN=*/12,/*nbN=*/12,/*nbE=*/18,/*nbF=*/8 ); + p[ VTK_POLYHEDRON ]. + Set( SMDSEntity_Polyhedra, SMDSAbs_Volume, SMDSGeom_POLYHEDRA, + /*isPoly=*/1,/*nbCN=*/-1,/*nbN=*/-1,/*nbE=*/-1,/*nbF=*/-1 ); + p[ VTK_POLY_VERTEX]. + Set( SMDSEntity_Ball, SMDSAbs_Ball, SMDSGeom_BALL, + /*isPoly=*/0,/*nbCN=*/1,/*nbN=*/1,/*nbE=*/0,/*nbF=*/0 ); + } + return theCellProps[ vtkType ]; + + } // getCellProps() + + //! return vector a CellProps + const CellProps& getCellProps( SMDSAbs_EntityType entity ) + { + return getCellProps( SMDS_MeshCell::toVtkType( entity )); + } + +} // namespace + +void SMDS_MeshCell::InitStaticMembers() { - nbCells++; - myVtkID = -1; + getCellProps( SMDSEntity_Ball ); + toVtkOrder( SMDSEntity_Ball ); + reverseSmdsOrder( SMDSEntity_Ball, 1 ); + interlacedSmdsOrder( SMDSEntity_Ball, 1 ); + fromVtkOrder( SMDSEntity_Ball ); } -SMDS_MeshCell::~SMDS_MeshCell() +void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, int theNbNodes, ... ) { - nbCells--; + 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& 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 ); + int vtkID = getGrid()->InsertNextLinkedCell( vtkType, theNbNodes, vtkIds ); + setVtkID( vtkID ); +} + +void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, + const std::vector& 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 ); + int vtkID = getGrid()->InsertNextLinkedCell( vtkType, nodes.size(), &vtkIds[0] ); + setVtkID( vtkID ); } + +void SMDS_MeshCell::init( SMDSAbs_EntityType theEntity, + const std::vector& vtkNodeIds ) +{ + int vtkType = toVtkType( theEntity ); + int 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 = 0; + getGrid()->GetCellPoints( GetVtkID(), npts, pts ); + if ( theNbNodes != npts ) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << theNbNodes); + return false; + } + const std::vector& 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 *pts, npts; + getGrid()->GetCellPoints( GetVtkID(), npts, pts ); + 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( 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( 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, *pts; + getGrid()->GetCellPoints( GetVtkID(), npts, pts ); + const std::vector& 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 ( GetVtkType() == VTK_POLYHEDRON ) + return static_cast< const SMDS_MeshVolume* >( this )->SMDS_MeshVolume::GetNodeIndex( node ); + + vtkIdType npts, *pts; + getGrid()->GetCellPoints( GetVtkID(), npts, pts ); + for ( vtkIdType i = 0; i < npts; ++i ) + if ( pts[i] == node->GetVtkID() ) + { + const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( GetVtkType() )); + return interlace.empty() ? i : interlace[i]; + } + return -1; +} + //================================================================================ /*! * \brief Return VTKCellType corresponding to SMDSAbs_EntityType @@ -262,7 +625,7 @@ const std::vector& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13,15,16,17}; reverseInterlaces[SMDSEntity_BiQuad_Penta].assign( &ids[0], &ids[0]+18 ); } - { + { const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); } @@ -348,14 +711,7 @@ const std::vector& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType) { - static std::vector< SMDSAbs_EntityType > smdsTypes; - if ( smdsTypes.empty() ) - { - smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last ); - for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS ) - smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS ); - } - return smdsTypes[ vtkType ]; + return getCellProps( vtkType ).myEntity; } //================================================================================ @@ -364,7 +720,7 @@ SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType) */ //================================================================================ -SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType) +SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_GeometryType geomType) { switch ( geomType ) { case SMDSGeom_POINT: return SMDSAbs_0DElement; @@ -395,46 +751,45 @@ SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType) */ //================================================================================ -SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType) +SMDSAbs_ElementType SMDS_MeshCell::ElemType(SMDSAbs_EntityType entityType) { - switch ( entityType ) { - case SMDSEntity_Node: return SMDSAbs_Node; + return getCellProps( entityType ).myType; +} + +SMDSAbs_GeometryType SMDS_MeshCell::GeomType( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myGeom; +} - case SMDSEntity_0D: return SMDSAbs_0DElement; +bool SMDS_MeshCell::IsPoly( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myIsPoly; +} - case SMDSEntity_Edge: - case SMDSEntity_Quad_Edge: return SMDSAbs_Edge; +bool SMDS_MeshCell::IsQuadratic( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myIsQuadratic; +} - case SMDSEntity_Triangle: - case SMDSEntity_Quad_Triangle: - case SMDSEntity_BiQuad_Triangle: - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: return SMDSAbs_Face; - - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - case SMDSEntity_BiQuad_Penta: - case SMDSEntity_Hexagonal_Prism: - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume; +int SMDS_MeshCell::NbCornerNodes( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myNbCornerNodes; +} - case SMDSEntity_Ball: return SMDSAbs_Ball; +int SMDS_MeshCell::NbNodes( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myNbNodes; +} - case SMDSEntity_Last:; - } - return SMDSAbs_All; +int SMDS_MeshCell::NbEdges( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myNbEdges; } +int SMDS_MeshCell::NbFaces( SMDSAbs_EntityType entityType ) +{ + return getCellProps( entityType ).myNbFaces; +} //================================================================================ /*!