X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_ProxyMesh.cxx;h=4c1a87ea4645c48fbec7e903f627d666d0fc61e3;hp=a28033fda4fe6c43d0bf337a5b1ec1ea1f66f75c;hb=b09372829929f8f561495d6c16527134971a1909;hpb=90e0893c89027a434e832eb72eeac85391b909e9 diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx index a28033fda..4c1a87ea4 100644 --- a/src/SMESH/SMESH_ProxyMesh.cxx +++ b/src/SMESH/SMESH_ProxyMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -32,15 +32,30 @@ #include #include +#include +#include + //================================================================================ /*! * \brief Constructor; mesh must be set by a descendant class */ //================================================================================ -SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0) +SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0), _subContainer(0) +{ +} +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +SMESH_ProxyMesh::SMESH_ProxyMesh(const SMESH_Mesh& mesh) + : _mesh( &mesh ), + _subContainer( new SubMesh( GetMeshDS() ) ) { } + //================================================================================ /*! * \brief Make a proxy mesh from components. Components become empty @@ -59,7 +74,7 @@ SMESH_ProxyMesh::SMESH_ProxyMesh(std::vector& components): takeTmpElemsInMesh( m ); - if ( !_mesh ) _mesh = m->_mesh; + if ( !_mesh && m->_mesh ) setMesh( *( m->_mesh )); if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes; if ( _subMeshes.size() < m->_subMeshes.size() ) @@ -101,6 +116,8 @@ SMESH_ProxyMesh::SMESH_ProxyMesh(std::vector& components): SMESH_ProxyMesh::~SMESH_ProxyMesh() { + delete _subContainer; + for ( size_t i = 0; i < _subMeshes.size(); ++i ) delete _subMeshes[i]; _subMeshes.clear(); @@ -111,6 +128,19 @@ SMESH_ProxyMesh::~SMESH_ProxyMesh() _elemsInMesh.clear(); } +//================================================================================ +/*! + * \brief Set mesh + */ +//================================================================================ + +void SMESH_ProxyMesh::setMesh(const SMESH_Mesh& mesh) +{ + _mesh = &mesh; + if ( _mesh ) + _subContainer = new SubMesh( GetMeshDS() ); +} + //================================================================================ /*! * \brief Returns index of a shape @@ -122,6 +152,19 @@ int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape)); } +//================================================================================ +/*! + * \brief Create a SubMesh + * \param [ino] index - shape index + * \return SubMesh* - new SubMesh + */ +//================================================================================ + +SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::newSubmesh(int index) const +{ + return new SubMesh( GetMeshDS(),index ); +} + //================================================================================ /*! * \brief Returns the submesh of a shape; it can be a proxy sub-mesh @@ -129,14 +172,24 @@ int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const //================================================================================ const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const +{ + return GetSubMesh( shapeIndex( shape )); +} + +//================================================================================ +/*! + * \brief Return a sub-mesh by a shape ID; it can be a proxy sub-mesh + */ +//================================================================================ + +const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const int shapeID) const { const SMESHDS_SubMesh* sm = 0; - size_t i = shapeIndex(shape); - if ( i < _subMeshes.size() ) - sm = _subMeshes[i]; + if ( 0 < shapeID && shapeID < (int)_subMeshes.size() ) + sm = _subMeshes[ shapeID ]; if ( !sm ) - sm = GetMeshDS()->MeshElements( i ); + sm = GetMeshDS()->MeshElements( shapeID ); return sm; } @@ -232,6 +285,62 @@ namespace return res; } }; + + //================================================================================ + /*! + * \brief Iterator returning unique elements from a vector and another iterator + */ + //================================================================================ + + class TUniqueIterator : public SMDS_ElemIterator + { + typedef boost::container::flat_set< const SMDS_MeshElement* > TElemSet; + typedef SMDS_SetIterator< const SMDS_MeshElement*, TElemSet::const_iterator > TSetIterator; + + TElemSet _uniqueElems; + TSetIterator* _iterator; + + public: + TUniqueIterator( const std::vector< const SMDS_MeshElement* >& elems, + const SMDS_ElemIteratorPtr& elemIterator ) + : _uniqueElems( elems.begin(), elems.end() ) + { + if ( elemIterator ) + while ( elemIterator->more() ) + _uniqueElems.insert( elemIterator->next() ); + + _iterator = new TSetIterator( _uniqueElems.begin(), _uniqueElems.end() ); + } + ~TUniqueIterator() + { + delete _iterator; + } + virtual bool more() + { + return _iterator->more(); + } + virtual const SMDS_MeshElement* next() + { + return _iterator->next(); + } + }; + + //================================================================================ + /*! + * \brief Return iterator on 2 element iterators + */ + //================================================================================ + + SMDS_ElemIteratorPtr iteratorOn2Iterators( SMDS_ElemIteratorPtr it1, SMDS_ElemIteratorPtr it2 ) + { + std::vector< SMDS_ElemIteratorPtr > iters; iters.reserve(2); + if ( it1 ) iters.push_back( it1 ); + if ( it2 ) iters.push_back( it2 ); + + typedef std::vector< SMDS_ElemIteratorPtr > TElemIterVector; + typedef SMDS_IteratorOnIterators TItersIter; + return SMDS_ElemIteratorPtr( new TItersIter( iters )); + } } //================================================================================ @@ -245,15 +354,15 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const if ( !_mesh->HasShapeToMesh() ) return SMDS_ElemIteratorPtr(); - _subContainer.RemoveAllSubmeshes(); + _subContainer->RemoveAllSubmeshes(); TopTools_IndexedMapOfShape FF; TopExp::MapShapes( shape, TopAbs_FACE, FF ); for ( int i = 1; i <= FF.Extent(); ++i ) if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i))) - _subContainer.AddSubMesh( sm ); + _subContainer->AddSubMesh( sm ); - return _subContainer.SMESHDS_SubMesh::GetElements(); + return _subContainer->SMESHDS_SubMesh::GetElements(); } //================================================================================ @@ -268,29 +377,23 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const if ( _mesh->HasShapeToMesh() ) return SMDS_ElemIteratorPtr(); - _subContainer.RemoveAllSubmeshes(); + _subContainer->RemoveAllSubmeshes(); for ( unsigned i = 0; i < _subMeshes.size(); ++i ) if ( _subMeshes[i] ) - _subContainer.AddSubMesh( _subMeshes[i] ); + _subContainer->AddSubMesh( _subMeshes[i] ); - if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted + if ( _subContainer->NbSubMeshes() == 0 ) // no elements substituted return GetMeshDS()->elementsIterator(SMDSAbs_Face); // if _allowedTypes is empty, only elements from _subMeshes are returned,... - SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements(); + SMDS_ElemIteratorPtr proxyIter = _subContainer->SMESHDS_SubMesh::GetElements(); if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() ) return proxyIter; // ... else elements filtered using allowedTypes are additionally returned SMDS_ElemIteratorPtr facesIter = GetMeshDS()->elementsIterator(SMDSAbs_Face); SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter )); - std::vector< SMDS_ElemIteratorPtr > iters(2); - iters[0] = proxyIter; - iters[1] = filterIter; - - typedef std::vector< SMDS_ElemIteratorPtr > TElemIterVector; - typedef SMDS_IteratorOnIterators TItersIter; - return SMDS_ElemIteratorPtr( new TItersIter( iters )); + return iteratorOn2Iterators( proxyIter, filterIter ); } //================================================================================ @@ -299,9 +402,9 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const */ //================================================================================ -int SMESH_ProxyMesh::NbFaces() const +smIdType SMESH_ProxyMesh::NbFaces() const { - int nb = 0; + smIdType nb = 0; if ( _mesh->HasShapeToMesh() ) { TopTools_IndexedMapOfShape FF; @@ -436,8 +539,14 @@ void SMESH_ProxyMesh::removeTmpElement( const SMDS_MeshElement* elem ) std::set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.find( elem ); if ( i != _elemsInMesh.end() ) { + std::vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() ); + GetMeshDS()->RemoveFreeElement( elem, 0 ); _elemsInMesh.erase( i ); + + for ( size_t i = 0; i < nodes.size(); ++i ) + if ( nodes[i]->GetID() > 0 && nodes[i]->NbInverseElements() == 0 ) + GetMeshDS()->RemoveFreeNode( nodes[i], 0, false ); } } else @@ -484,6 +593,91 @@ bool SMESH_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem ); } +//================================================================================ +/*! + * \brief Return iterator on inverse elements of a node that may be a proxy one + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetInverseElementIterator(const SMDS_MeshNode* node, + SMDSAbs_ElementType type) const +{ + typedef std::vector< const SMDS_MeshElement* > TElemVec; + TElemVec *elemVecPtr; + + TNodeElemVecMap& inverseElements = const_cast< TNodeElemVecMap& >( _inverseElements ); + if ( inverseElements.IsEmpty() && NbProxySubMeshes() > 0 ) + { + TElemVec elemVec; + for ( size_t i = 0; i < _subMeshes.size(); ++i ) + if ( _subMeshes[i] ) + for ( size_t j = 0; j < _subMeshes[i]->_elements.size(); ++j ) + { + const SMDS_MeshElement* e = _subMeshes[i]->_elements[j]; + for ( SMDS_NodeIteratorPtr nIt = e->nodeIterator(); nIt->more(); ) + { + const SMDS_MeshNode* n = nIt->next(); + elemVecPtr = inverseElements.ChangeSeek( n ); + if ( !elemVecPtr ) + elemVecPtr = inverseElements.Bound( n, elemVec ); + elemVecPtr->push_back( e ); + } + } + } + + SMDS_ElemIteratorPtr iter = node->GetInverseElementIterator( type ); + + if (( elemVecPtr = inverseElements.ChangeSeek( node ))) + { + if ( iter->more() ) + iter = boost::make_shared< TUniqueIterator >( *elemVecPtr, iter ); + else + iter = boost::make_shared< SMDS_ElementVectorIterator> ( elemVecPtr->begin(), + elemVecPtr->end() ); + } + + return iter; +} + +//================================================================================ +/*! + * \brief Check if a FACE has prisms on its both sides + * \param [in] smFace - sub-mesh of the FACE. NOT a proxy sub-mesh! + * \return bool - true if there are prisms on the two sides + */ +//================================================================================ + +bool SMESH_ProxyMesh::HasPrismsOnTwoSides( SMESHDS_SubMesh* smFace ) +{ + if ( !smFace || smFace->NbElements() == 0 ) + return false; + + SMDS_ElemIteratorPtr faces = smFace->GetElements(); + while ( faces->more() ) + { + const SMDS_MeshElement* f = faces->next(); + std::vector fNodes( f->begin_nodes(), f->end_nodes() ); + std::vector vols; + if ( SMDS_Mesh::GetElementsByNodes( fNodes, vols, SMDSAbs_Volume ) < 2 ) + return false; + return ( vols[0]->NbCornerNodes() == 2 * f->NbCornerNodes() && + vols[1]->NbCornerNodes() == 2 * f->NbCornerNodes() ); + } + return false; +} + +//================================================================================ +/*! + * \brief SubMesh Constructor + */ +//================================================================================ + +SMESH_ProxyMesh::SubMesh::SubMesh( const SMDS_Mesh* mesh, int index ) + : SMESHDS_SubMesh( static_cast( mesh ), index ), + _n2n(0) +{ +} + //================================================================================ /*! * \brief Return a proxy node or an input node @@ -521,7 +715,7 @@ void SMESH_ProxyMesh::SubMesh::Clear() */ //================================================================================ -int SMESH_ProxyMesh::SubMesh::NbElements() const +smIdType SMESH_ProxyMesh::SubMesh::NbElements() const { return _uvPtStructVec.empty() ? _elements.size() : _uvPtStructVec.size() - 1; } @@ -533,7 +727,7 @@ int SMESH_ProxyMesh::SubMesh::NbElements() const */ //================================================================================ -SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements(bool reverse) const +SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const { return SMDS_ElemIteratorPtr ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() )); @@ -546,7 +740,7 @@ SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements(bool reverse) const */ //================================================================================ -int SMESH_ProxyMesh::SubMesh::NbNodes() const +smIdType SMESH_ProxyMesh::SubMesh::NbNodes() const { return _uvPtStructVec.size(); } @@ -558,7 +752,7 @@ int SMESH_ProxyMesh::SubMesh::NbNodes() const */ //================================================================================ -SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes(bool reverse) const +SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes() const { if ( !_uvPtStructVec.empty() ) return SMDS_NodeIteratorPtr ( new SMDS_SetIterator