X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHDS%2FSMESHDS_SubMesh.cxx;h=ce820acbf49b83e0db6ab2f647268db869b66863;hp=915ab0cdcb2278bb7ae32e840e9c6d3dd1ee62f5;hb=2f529dcd2629679dadcca3047583bfcf28ca7b1a;hpb=b0a908c0d20341651771d0249fb10882f54b2aad diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 915ab0cdc..ce820acbf 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -27,15 +27,44 @@ // $Header: // #include "SMESHDS_SubMesh.hxx" -#include "SMESHDS_Mesh.hxx" -#include "utilities.h" +#include "SMDS_ElementFactory.hxx" +#include "SMDS_IteratorOnIterators.hxx" #include "SMDS_SetIterator.hxx" -#include -#include +#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; -using namespace std; + 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(); } + }; +} //================================================================================ /*! @@ -43,14 +72,14 @@ using namespace std; */ //================================================================================ -SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index) +SMESHDS_SubMesh::SMESHDS_SubMesh(const SMESHDS_Mesh *parent, int index) + : SMDS_ElementHolder( parent ) { myParent = parent; - myElements.clear(); - myNodes.clear(); myIndex = index; - myUnusedIdNodes = 0; - myUnusedIdElements = 0; + myNbElements = 0; + myNbNodes = 0; + my1stElemNode[0] = my1stElemNode[1] = 0; } //================================================================================ @@ -65,165 +94,148 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh() //======================================================================= //function : AddElement -//purpose : +//purpose : //======================================================================= -void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) +void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * elem) { if (!IsComplexSubmesh()) + { + if ( elem->GetType() == SMDSAbs_Node ) + { + AddNode( static_cast< const SMDS_MeshNode* >( elem )); + return; + } + int oldShapeId = elem->GetShapeID(); + if ( oldShapeId > 0 ) { - if ( ME->GetType() == SMDSAbs_Node ) + if (oldShapeId != myIndex) { - AddNode( static_cast< const SMDS_MeshNode* >( ME )); - return; + throw SALOME_Exception + (LOCALIZED("add element in subshape already belonging to a subshape")); } - int oldShapeId = ME->getshapeId(); - if ( oldShapeId > 0 ) - { - if (oldShapeId != myIndex) - { - MESSAGE("add element in subshape already belonging to another subshape " - << ME->GetID() << " " << oldShapeId << " " << myIndex); - throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape")); - } - else - { - int idInSubShape = ME->getIdInShape(); - if (idInSubShape >= 0) - { - MESSAGE("add element in subshape already belonging to that subshape " - << ME->GetID() << " " << oldShapeId << " " << idInSubShape); - // check if ok: do nothing if ok - if (idInSubShape >= myElements.size()) - { - MESSAGE("out of bounds " << idInSubShape << " " << myElements.size()); - throw SALOME_Exception(LOCALIZED("out of bounds")); - } - if (ME != myElements[idInSubShape]) - { - MESSAGE("not the same element"); - throw SALOME_Exception(LOCALIZED("not the same element")); - } - MESSAGE("already done, OK, nothing to do"); - return; - } - } - } - - SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); - elem->setShapeId(myIndex); - elem->setIdInShape(myElements.size()); - myElements.push_back(ME); } + + elem->setShapeID( myIndex ); + myNbElements++; + + // remember element with smallest ID to optimize iteration on them + add( elem ); + } } //======================================================================= //function : RemoveElement -//purpose : +//purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted) +bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * elem ) { - if (!ME) + if ( myNbElements == 0 || !elem || elem->IsNull() || elem->getshapeId() != myIndex ) { - MESSAGE("-----------------> Remove Null Element " << isElemDeleted); return false; } - if (!IsComplexSubmesh()) + if ( !IsComplexSubmesh() ) { - if ( ME->getshapeId() != myIndex ) - return false; - int idInSubShape = ME->getIdInShape(); - SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); - elem->setShapeId(0); - elem->setIdInShape(-1); - if ((idInSubShape >= 0) && (idInSubShape < myElements.size())) + elem->setShapeID( 0 ); + myNbElements--; + + const SMDS_MeshElement* & elem1st = my1stElemNode[ ind1st( elem->GetType() )]; + if ( elem1st == elem ) { - myElements[idInSubShape] = 0; // this vector entry is no more used - if ( ++myUnusedIdElements == (int) myElements.size() ) + 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 { - clearVector( myElements ); - myUnusedIdElements = 0; + elem1st = 0; } - return true; } - return false; + return true; } - MESSAGE("Try to remove an element from a complex submesh "); return false; } //======================================================================= //function : AddNode -//purpose : +//purpose : //======================================================================= void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) { if ( !IsComplexSubmesh() ) { - const int idInSubShape = N->getIdInShape(); - const int shapeId = N->getshapeId(); - if ((shapeId > 0) && (idInSubShape >= 0)) + const int shapeId = N->getshapeId(); + if ( shapeId > 0 ) { if ( shapeId != myIndex ) throw SALOME_Exception (LOCALIZED("a node being in sub-mesh is added to another sub-mesh")); - if ( idInSubShape >= myNodes.size() || myNodes[ idInSubShape ] != N ) - throw SALOME_Exception - (LOCALIZED("a node with wrong idInSubShape is re-added to the same sub-mesh")); return; // already in } - SMDS_MeshNode* node = (SMDS_MeshNode*)(N); - node->setShapeId(myIndex); - node->setIdInShape(myNodes.size()); - myNodes.push_back(N); + N->setShapeID( myIndex ); + myNbNodes++; + + // remember node with smallest ID to optimize iteration on them + add( N ); } } //======================================================================= //function : RemoveNode -//purpose : +//purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted) +bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) { - if (!IsComplexSubmesh()) + if ( myNbNodes == 0 || !N || N->getshapeId() != myIndex ) { - if ( N->getshapeId() != myIndex ) - return false; - int idInSubShape = N->getIdInShape(); - SMDS_MeshNode* node = (SMDS_MeshNode*) (N); - node->setShapeId(0); - node->setIdInShape(-1); - if ((idInSubShape >= 0) && (idInSubShape < myNodes.size())) + return false; + } + if ( !IsComplexSubmesh() ) + { + N->setShapeID( 0 ); + myNbNodes--; + + const SMDS_MeshElement* & node1st = my1stElemNode[ ind1st( SMDSAbs_Node )]; + if ( node1st == N ) { - myNodes[idInSubShape] = 0; // this vector entry is no more used - if ( ++myUnusedIdNodes == (int) myNodes.size() ) + if ( myNbNodes > 0 ) { - clearVector( myNodes ); - myUnusedIdNodes = 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; + return true; } - MESSAGE("Try to remove a node from a complex submesh"); return false; } //======================================================================= //function : NbElements -//purpose : +//purpose : //======================================================================= int SMESHDS_SubMesh::NbElements() const { if ( !IsComplexSubmesh() ) - return myElements.size() - myUnusedIdElements; + return myNbElements; int nbElems = 0; - set::const_iterator it = mySubMeshes.begin(); + TSubMeshSet::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbElements(); @@ -232,69 +244,32 @@ int SMESHDS_SubMesh::NbElements() const //======================================================================= //function : NbNodes -//purpose : +//purpose : //======================================================================= int SMESHDS_SubMesh::NbNodes() const { if ( !IsComplexSubmesh() ) - return myNodes.size() - myUnusedIdNodes; + return myNbNodes; int nbElems = 0; - set::const_iterator it = mySubMeshes.begin(); + TSubMeshSet::const_iterator it = mySubMeshes.begin(); for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbNodes(); return nbElems; } -/*! - * template class used for iteration on submesh elements. Interface of iterator remains - * unchanged after redesign of SMDS to avoid modification everywhere in SMESH. - * instances are stored in shared_ptr for automatic destruction. - * Container is copied for iteration, because original can be modified - * by addition of elements, for instance, and then reallocated (vector) - */ -template class MySetIterator : public SMDS_Iterator -{ -protected: - typename TSET::const_iterator _it, _end; - TSET _table; -public: - MySetIterator(const TSET& table) - { - _table = table; - _it = _table.begin(); - _end = _table.end(); - while ((_it != _end) && (*_it == 0)) - _it++; - } - - virtual bool more() - { - while ((_it != _end) && (*_it == 0)) - _it++; - return (_it != _end); - } - - virtual ELEM next() - { - ELEM e = *_it; - _it++; - return e; - } -}; - // ===================== // class MyIterator // ===================== template class MyIterator : public SMDS_Iterator { - public: - MyIterator (const set& theSubMeshes) - : mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false) - {} +public: + MyIterator (const TSubMeshSet& theSubMeshes) + : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ) + {} bool more() { while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd) @@ -312,14 +287,14 @@ template class MyIterator : public SMDS_Iterator elem = myElemIt->next(); return elem; } - protected: +protected: virtual boost::shared_ptr< SMDS_Iterator > - getElements(const SMESHDS_SubMesh*) const = 0; + getElements(const SMESHDS_SubMesh*) const = 0; - private: - bool myMore; - set::const_iterator mySubIt, mySubEnd; - boost::shared_ptr< SMDS_Iterator > myElemIt; +private: + bool myMore; + TSubMeshSet::const_iterator mySubIt, mySubEnd; + boost::shared_ptr< SMDS_Iterator > myElemIt; }; // ===================== @@ -328,8 +303,8 @@ template class MyIterator : public SMDS_Iterator class MyElemIterator: public MyIterator { - public: - MyElemIterator (const set& theSubMeshes) +public: + MyElemIterator (const TSubMeshSet& theSubMeshes) :MyIterator( theSubMeshes ) {} SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const { return theSubMesh->GetElements(); } @@ -341,28 +316,35 @@ class MyElemIterator: public MyIterator class MyNodeIterator: public MyIterator { - public: - MyNodeIterator (const set& theSubMeshes) +public: + MyNodeIterator (const TSubMeshSet& theSubMeshes) :MyIterator( theSubMeshes ) {} SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const { return theSubMesh->GetNodes(); } }; - + //======================================================================= //function : GetElements -//purpose : +//purpose : //======================================================================= SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const { if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - return SMDS_ElemIteratorPtr(new MySetIterator >(myElements)); + + 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 ); } //======================================================================= //function : GetNodes -//purpose : +//purpose : //======================================================================= SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const @@ -370,7 +352,14 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return SMDS_NodeIteratorPtr(new MySetIterator >(myNodes)); + 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 ); } //======================================================================= @@ -380,40 +369,46 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const { - // DO NOT TRY TO FIND A REMOVED ELEMENT !! - //if ( IsComplexSubmesh() || !ME ) - if (!ME) + if ( !ME || ME->IsNull() ) return false; - if (IsComplexSubmesh()) - { - set::const_iterator aSubIt = mySubMeshes.begin(); - for (; aSubIt != mySubMeshes.end(); aSubIt++) - if ((*aSubIt)->Contains(ME)) - return true; - return false; - } + if ( IsComplexSubmesh() ) + { + TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin(); + for (; aSubIt != mySubMeshes.end(); aSubIt++) + if ((*aSubIt)->Contains(ME)) + return true; + return false; + } + return ME->getshapeId() == myIndex; +} - if (ME->GetType() == SMDSAbs_Node) - { - int idInShape = ME->getIdInShape(); - if ((idInShape >= 0) && (idInShape < myNodes.size())) - if (myNodes[idInShape] == ME) - return true; - } - else - { - int idInShape = ME->getIdInShape(); - if ((idInShape >= 0) && (idInShape < myElements.size())) - if (myElements[idInShape] == ME) - return true; - } - return false; +//======================================================================= +//function : IsQuadratic +//purpose : Return true if my 1st element is quadratic +//======================================================================= + +bool SMESHDS_SubMesh::IsQuadratic() const +{ + if ( IsComplexSubmesh() ) + { + TSubMeshSet::const_iterator aSubIt = mySubMeshes.begin(); + for (; aSubIt != mySubMeshes.end(); aSubIt++) + if ((*aSubIt)->IsQuadratic()) + return true; + return false; + } + + if ( myNbElements == 0 ) + return false; + + SMDS_ElemIteratorPtr it = GetElements(); + return it->more() && it->next()->IsQuadratic(); } //======================================================================= //function : AddSubMesh -//purpose : +//purpose : //======================================================================= void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh ) @@ -444,7 +439,7 @@ void SMESHDS_SubMesh::RemoveAllSubmeshes() //======================================================================= //function : ContainsSubMesh -//purpose : +//purpose : //======================================================================= bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const @@ -454,15 +449,13 @@ bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const //======================================================================= //function : GetSubMeshIterator -//purpose : +//purpose : //======================================================================= SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const { - typedef set::const_iterator TIterator; - return SMESHDS_SubMeshIteratorPtr - ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(), - mySubMeshes.end())); + typedef SMDS_SetIterator< const SMESHDS_SubMesh*, TSubMeshSet::const_iterator > TIterator; + return boost::make_shared< TIterator >( mySubMeshes.begin(), mySubMeshes.end()); } //======================================================================= @@ -472,10 +465,26 @@ SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const void SMESHDS_SubMesh::Clear() { - clearVector( myElements ); - clearVector( myNodes ); - myUnusedIdNodes = 0; - myUnusedIdElements = 0; + if ( myParent && myParent->NbNodes() > 0 ) + { + if ( myNbElements > 0 ) + for ( SMDS_ElemIteratorPtr it = GetElements(); it->more(); ) + { + const SMDS_MeshElement * elem = it->next(); + elem->setShapeID( 0 ); + } + if ( myNbNodes > 0 ) + for ( SMDS_NodeIteratorPtr it = GetNodes(); it->more(); ) + { + const SMDS_MeshNode * elem = it->next(); + elem->setShapeID( 0 ); + } + } + + myNbElements = 0; + myNbNodes = 0; + my1stElemNode[0] = my1stElemNode[1] = 0; + if ( NbSubMeshes() > 0 ) { SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator(); @@ -486,42 +495,42 @@ void SMESHDS_SubMesh::Clear() } } -int SMESHDS_SubMesh::getSize() +//======================================================================= +//function : getElements +//purpose : Return iterator on all elements and nodes during compacting +//======================================================================= + +SMDS_ElemIteratorPtr SMESHDS_SubMesh::getElements() { - int c = NbNodes(); - int d = NbElements(); - return c+d; + 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 ); } -void SMESHDS_SubMesh::compactList() +//======================================================================= +//function : tmpClear +//purpose : clean up after compacting +//======================================================================= + +void SMESHDS_SubMesh::tmpClear() { - if ( myUnusedIdElements > 0 ) - { - std::vector newElems; - newElems.reserve( myElements.size() - myUnusedIdElements ); - for (size_t i = 0; i < myElements.size(); i++) - if (myElements[i]) - { - SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i]; - elem->setIdInShape(newElems.size()); - newElems.push_back(elem); - } - myElements.swap(newElems); - myUnusedIdElements = 0; - } + my1stElemNode[0] = my1stElemNode[1] = 0; +} - if ( myUnusedIdNodes > 0 ) - { - std::vector newNodes; - newNodes.reserve( myNodes.size() - myUnusedIdNodes ); - for (size_t i = 0; i < myNodes.size(); i++) - if (myNodes[i]) - { - SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i]; - node->setIdInShape(newNodes.size()); - newNodes.push_back(node); - } - myNodes.swap(newNodes); - myUnusedIdNodes = 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; }