X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHDS%2FSMESHDS_SubMesh.cxx;h=73007402cebf090d4fd869b6ac36bfb84e90fb65;hp=4a086e3b7073fc8d84be84192fe8c158b8302076;hb=refs%2Ftags%2FV9_7_0a1;hpb=b7a7d49664daa32e1befb558280e13ed0bde37c9 diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 4a086e3b7..73007402c 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.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 // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -28,24 +28,58 @@ // #include "SMESHDS_SubMesh.hxx" -#include "SMESHDS_Mesh.hxx" -#include "SMDS_SetIterator.hxx" #include "SMDS_ElementFactory.hxx" +#include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Mesh.hxx" #include +namespace +{ + typedef const SMDS_MeshElement* PElem; + typedef const SMDS_MeshNode* PNode; + + typedef SMDS_SetIterator< PElem, PElem const *, + SMDS::SimpleAccessor< PElem, PElem const * >, + SMDS::NonNullFilter< PElem > > EArrayIterator; + + typedef SMDS_SetIterator< PNode, PNode const *, + SMDS::SimpleAccessor< PNode, PNode const * >, + SMDS::NonNullFilter< PNode > > NArrayIterator; + + int ind1st( SMDSAbs_ElementType t ) + { + return t == SMDSAbs_Node; + } + + //======================================================================= + //class : _MyElemIteratorFromNodeIterator + //======================================================================= + class _MyElemIteratorFromNodeIterator : public SMDS_ElemIterator + { + SMDS_NodeIteratorPtr myItr; + public: + _MyElemIteratorFromNodeIterator(SMDS_NodeIteratorPtr nodeItr): myItr( nodeItr ) {} + bool more() { return myItr->more(); } + const SMDS_MeshElement* next() { return myItr->next(); } + }; +} + //================================================================================ /*! * \brief Constructor */ //================================================================================ -SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index) +SMESHDS_SubMesh::SMESHDS_SubMesh(const SMESHDS_Mesh *parent, int index) + : SMDS_ElementHolder( parent ) { myParent = parent; myIndex = index; myNbElements = 0; myNbNodes = 0; + my1stElemNode[0] = my1stElemNode[1] = 0; } //================================================================================ @@ -81,9 +115,15 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) (LOCALIZED("add element in subshape already belonging to a subshape")); } } + else + { + ++myNbElements; + } elem->setShapeID( myIndex ); - myNbElements++; + + // remember element with smallest ID to optimize iteration on them + add( elem ); } } @@ -94,7 +134,7 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem ) { - if ( !elem || elem->IsNull() || elem->getshapeId() != myIndex ) + if ( myNbElements == 0 || !elem || elem->IsNull() || elem->getshapeId() != myIndex ) { return false; } @@ -102,6 +142,23 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem ) { elem->setShapeID( 0 ); myNbElements--; + + const SMDS_MeshElement* & elem1st = my1stElemNode[ ind1st( elem->GetType() )]; + if ( elem1st == elem ) + { + if ( myNbElements > 0 ) + { + SMDS_ElemIteratorPtr it = myParent->shapeElementsIterator( myIndex, 1, elem1st ); + if ( it->more() ) + elem1st = it->next(); + else + throw SALOME_Exception(LOCALIZED("invalid myNbElements")); + } + else + { + elem1st = 0; + } + } return true; } return false; @@ -124,8 +181,14 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) (LOCALIZED("a node being in sub-mesh is added to another sub-mesh")); return; // already in } + else + { + ++myNbNodes; + } N->setShapeID( myIndex ); - myNbNodes++; + + // remember node with smallest ID to optimize iteration on them + add( N ); } } @@ -136,7 +199,7 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) { - if ( !N || N->getshapeId() != myIndex ) + if ( myNbNodes == 0 || !N || N->getshapeId() != myIndex ) { return false; } @@ -144,6 +207,24 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) { N->setShapeID( 0 ); myNbNodes--; + + const SMDS_MeshElement* & node1st = my1stElemNode[ ind1st( SMDSAbs_Node )]; + if ( node1st == N ) + { + if ( myNbNodes > 0 ) + { + SMDS_NodeIteratorPtr it = + myParent->shapeNodesIterator( myIndex, 1, static_cast< PNode >( node1st )); + if ( it->more() ) + node1st = it->next(); + else + throw SALOME_Exception(LOCALIZED("invalid myNbNodes")); + } + else + { + node1st = 0; + } + } return true; } return false; @@ -154,12 +235,12 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) //purpose : //======================================================================= -int SMESHDS_SubMesh::NbElements() const +smIdType SMESHDS_SubMesh::NbElements() const { if ( !IsComplexSubmesh() ) return myNbElements; - int nbElems = 0; + smIdType nbElems = 0; TSubMeshSet::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbElements(); @@ -172,12 +253,12 @@ int SMESHDS_SubMesh::NbElements() const //purpose : //======================================================================= -int SMESHDS_SubMesh::NbNodes() const +smIdType SMESHDS_SubMesh::NbNodes() const { if ( !IsComplexSubmesh() ) return myNbNodes; - int nbElems = 0; + smIdType nbElems = 0; TSubMeshSet::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbNodes(); @@ -185,49 +266,6 @@ int SMESHDS_SubMesh::NbNodes() const return nbElems; } -/*! - * Template class used for iteration on vector of elements which can resize - * during iteration. The iterator returns only elements present upon its creation. - */ -template class MySetIterator : public SMDS_Iterator -{ -protected: - int _iCur, _iEnd, _iDelta; - const TSET& _table; -public: - MySetIterator(const TSET& table, bool reverse): _table( table ) - { - if ( reverse ) - { - _iCur = _table.size()-1; - _iEnd = -1; - _iDelta = -1; - } - else - { - _iCur = 0; - _iEnd = _table.size(); - _iDelta = 1; - } - if ( more() && !_table[ _iCur ]) - next(); - } - - virtual bool more() - { - return ( _iEnd - _iCur ) * _iDelta > 0; - } - - virtual ELEM next() - { - ELEM e = more() ? _table[ _iCur ] : 0; - _iCur += _iDelta; - while ( more() && !_table[ _iCur ]) - _iCur += _iDelta; - return e; - } -}; - // ===================== // class MyIterator // ===================== @@ -301,7 +339,13 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - return myParent->shapeElementsIterator( myIndex, myNbElements ); + const SMDS_MeshElement* const * elem1st = & my1stElemNode[ ind1st( SMDSAbs_All )]; + if ( myNbElements < 2 ) + { + return boost::make_shared< EArrayIterator >( elem1st, elem1st + myNbElements ); + } + + return myParent->shapeElementsIterator( myIndex, myNbElements, *elem1st ); } //======================================================================= @@ -314,7 +358,14 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return myParent->shapeNodesIterator( myIndex, myNbNodes ); + PNode const * node1st = + reinterpret_cast< PNode const* >( & my1stElemNode[ ind1st( SMDSAbs_Node )] ); + if ( myNbNodes < 2 ) + { + return boost::make_shared< NArrayIterator >( node1st, node1st + myNbNodes ); + } + + return myParent->shapeNodesIterator( myIndex, myNbNodes, *node1st ); } //======================================================================= @@ -438,6 +489,8 @@ void SMESHDS_SubMesh::Clear() myNbElements = 0; myNbNodes = 0; + my1stElemNode[0] = my1stElemNode[1] = 0; + if ( NbSubMeshes() > 0 ) { SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator(); @@ -447,3 +500,43 @@ void SMESHDS_SubMesh::Clear() } } } + +//======================================================================= +//function : getElements +//purpose : Return iterator on all elements and nodes during compacting +//======================================================================= + +SMDS_ElemIteratorPtr SMESHDS_SubMesh::getElements() +{ + if ( IsComplexSubmesh() ) // return nothing + boost::make_shared< EArrayIterator >( & my1stElemNode[0], & my1stElemNode[0] ); + + typedef std::vector< SMDS_ElemIteratorPtr > TIterVec; + TIterVec iterVec(2); + iterVec[0] = GetElements(); + iterVec[1].reset( new _MyElemIteratorFromNodeIterator( GetNodes() )); + + return boost::make_shared< SMDS_IteratorOnIterators< PElem, TIterVec > >( iterVec ); +} + +//======================================================================= +//function : tmpClear +//purpose : clean up after compacting +//======================================================================= + +void SMESHDS_SubMesh::tmpClear() +{ + my1stElemNode[0] = my1stElemNode[1] = 0; +} + +//======================================================================= +//function : add +//purpose : update my1stElemNode +//======================================================================= + +void SMESHDS_SubMesh::add( const SMDS_MeshElement* elem ) +{ + const SMDS_MeshElement* & oldElem = my1stElemNode[ ind1st( elem->GetType() )]; + if ( !oldElem || oldElem->GetID() > elem->GetID() ) + oldElem = elem; +}