mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-29 10:50:34 +05:00
21948: EDF SMESH : Memory is not freed when deleting a mesh
Optimize for large meshes
This commit is contained in:
parent
06544a5936
commit
1199fcd63c
@ -28,6 +28,9 @@
|
|||||||
#include "SMESHDS_Mesh.hxx"
|
#include "SMESHDS_Mesh.hxx"
|
||||||
#include "SMDS_SetIterator.hxx"
|
#include "SMDS_SetIterator.hxx"
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -40,9 +43,12 @@ SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int theID,
|
|||||||
const SMESHDS_Mesh* theMesh,
|
const SMESHDS_Mesh* theMesh,
|
||||||
const SMDSAbs_ElementType theType,
|
const SMDSAbs_ElementType theType,
|
||||||
const SMESH_PredicatePtr& thePredicate)
|
const SMESH_PredicatePtr& thePredicate)
|
||||||
: SMESHDS_GroupBase(theID,theMesh,theType), myMeshModifTime(0), myPredicateTic(0)
|
: SMESHDS_GroupBase(theID,theMesh,theType),
|
||||||
|
myMeshInfo( SMDSEntity_Last, 0 ),
|
||||||
|
myMeshModifTime(0),
|
||||||
|
myPredicateTic(0),
|
||||||
|
myNbElemToSkip(0)
|
||||||
{
|
{
|
||||||
setChanged();
|
|
||||||
SetPredicate( thePredicate );
|
SetPredicate( thePredicate );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +58,7 @@ SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int theID,
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate)
|
void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate )
|
||||||
{
|
{
|
||||||
myPredicate = thePredicate;
|
myPredicate = thePredicate;
|
||||||
++myPredicateTic;
|
++myPredicateTic;
|
||||||
@ -70,7 +76,36 @@ void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate
|
|||||||
int SMESHDS_GroupOnFilter::Extent() const
|
int SMESHDS_GroupOnFilter::Extent() const
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
return myElements.size();
|
return std::accumulate( myMeshInfo.begin(), myMeshInfo.end(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Checks emptyness
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
bool SMESHDS_GroupOnFilter::IsEmpty()
|
||||||
|
{
|
||||||
|
if ( IsUpToDate() )
|
||||||
|
{
|
||||||
|
return ( Extent() == 0 );
|
||||||
|
}
|
||||||
|
else // not up-to-date
|
||||||
|
{
|
||||||
|
setChanged();
|
||||||
|
SMDS_ElemIteratorPtr okElemIt = GetElements();
|
||||||
|
if ( !okElemIt->more() )
|
||||||
|
{
|
||||||
|
// no satisfying elements
|
||||||
|
setChanged( false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -95,6 +130,53 @@ bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem)
|
|||||||
return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false;
|
return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
namespace // Iterator
|
||||||
|
{
|
||||||
|
struct TIterator : public SMDS_ElemIterator
|
||||||
|
{
|
||||||
|
SMESH_PredicatePtr myPredicate;
|
||||||
|
SMDS_ElemIteratorPtr myElemIt;
|
||||||
|
const SMDS_MeshElement* myNextElem;
|
||||||
|
size_t myNbToFind, myNbFound;
|
||||||
|
TIterator( const SMESH_PredicatePtr& filter,
|
||||||
|
SMDS_ElemIteratorPtr& elems,
|
||||||
|
size_t nbToFind):
|
||||||
|
myPredicate( filter ),
|
||||||
|
myElemIt( elems ),
|
||||||
|
myNextElem( 0 ),
|
||||||
|
myNbToFind( nbToFind ),
|
||||||
|
myNbFound( 0 )
|
||||||
|
{
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
virtual bool more()
|
||||||
|
{
|
||||||
|
return myNextElem;
|
||||||
|
}
|
||||||
|
virtual const SMDS_MeshElement* next()
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* res = myNextElem;
|
||||||
|
myNbFound += bool( res );
|
||||||
|
myNextElem = 0;
|
||||||
|
if ( myNbFound < myNbToFind )
|
||||||
|
while ( myElemIt->more() && !myNextElem )
|
||||||
|
{
|
||||||
|
myNextElem = myElemIt->next();
|
||||||
|
if ( !myPredicate->IsSatisfy( myNextElem->GetID() ))
|
||||||
|
myNextElem = 0;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TEmptyIterator : public SMDS_ElemIterator
|
||||||
|
{
|
||||||
|
virtual bool more() { return false; }
|
||||||
|
virtual const SMDS_MeshElement* next() { return 0; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return iterator on all elements
|
* \brief Return iterator on all elements
|
||||||
@ -103,25 +185,83 @@ bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem)
|
|||||||
|
|
||||||
SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
|
SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
|
||||||
{
|
{
|
||||||
update();
|
size_t nbToFind = std::numeric_limits<size_t>::max();
|
||||||
return SMDS_ElemIteratorPtr
|
|
||||||
( new SMDS_ElementVectorIterator( myElements.begin(), myElements.end() ));
|
SMDS_ElemIteratorPtr elemIt;
|
||||||
|
if ( myPredicate )
|
||||||
|
{
|
||||||
|
myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary
|
||||||
|
|
||||||
|
elemIt = GetMesh()->elementsIterator( GetType() );
|
||||||
|
if ( IsUpToDate() )
|
||||||
|
{
|
||||||
|
nbToFind = Extent();
|
||||||
|
if ( nbToFind == GetMesh()->GetMeshInfo().NbElements( GetType() ))
|
||||||
|
return elemIt; // all elements are OK
|
||||||
|
for ( size_t i = 0; i < myNbElemToSkip; ++i )
|
||||||
|
elemIt->next(); // skip w/o check
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elemIt = SMDS_ElemIteratorPtr( new TEmptyIterator );
|
||||||
|
}
|
||||||
|
return SMDS_ElemIteratorPtr ( new TIterator( myPredicate, elemIt, nbToFind ));
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief return ID of theIndex-th element
|
* \brief Return info on sub-types of elements
|
||||||
* \param theIndex - index countered from 1
|
|
||||||
* \retval int - element ID
|
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
int SMESHDS_GroupOnFilter::GetID (const int theIndex)
|
std::vector< int > SMESHDS_GroupOnFilter::GetMeshInfo() const
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
if ( theIndex < 1 || theIndex > myElements.size() )
|
return myMeshInfo;
|
||||||
return -1;
|
}
|
||||||
return myElements[ theIndex-1 ]->GetID();
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Fill ids of elements. And return their number.
|
||||||
|
* \a ids must be pre-allocated using nb of elements of type == GetType()
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
int SMESHDS_GroupOnFilter::GetElementIds( int* ids ) const
|
||||||
|
{
|
||||||
|
SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
|
||||||
|
|
||||||
|
int* curID = ids;
|
||||||
|
SMDS_ElemIteratorPtr elIt = GetElements();
|
||||||
|
if ( elIt->more() )
|
||||||
|
{
|
||||||
|
if ( IsUpToDate() )
|
||||||
|
{
|
||||||
|
while ( elIt->more() )
|
||||||
|
*curID++ = elIt->next()->GetID();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
me->setChanged();
|
||||||
|
|
||||||
|
// find out nb of elements to skip w/o check before the 1st OK element
|
||||||
|
const SMDS_MeshElement* firstOkElem = me->setNbElemToSkip( elIt );
|
||||||
|
|
||||||
|
me->myMeshInfo.assign( SMDSEntity_Last, 0 );
|
||||||
|
me->myMeshInfo[ firstOkElem->GetEntityType() ]++;
|
||||||
|
*curID++ = firstOkElem->GetID();
|
||||||
|
while ( elIt->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* e = elIt->next();
|
||||||
|
me->myMeshInfo[ e->GetEntityType() ]++;
|
||||||
|
*curID++ = e->GetID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me->setChanged( false );
|
||||||
|
|
||||||
|
return curID - ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -154,23 +294,17 @@ bool SMESHDS_GroupOnFilter::IsUpToDate() const
|
|||||||
|
|
||||||
void SMESHDS_GroupOnFilter::update() const
|
void SMESHDS_GroupOnFilter::update() const
|
||||||
{
|
{
|
||||||
|
SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
|
||||||
if ( !IsUpToDate() )
|
if ( !IsUpToDate() )
|
||||||
{
|
{
|
||||||
SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
|
me->setChanged();
|
||||||
me->myElements.clear();
|
SMDS_ElemIteratorPtr elIt = GetElements();
|
||||||
if ( myPredicate )
|
if ( elIt->more() ) {
|
||||||
{
|
// find out nb of elements to skip w/o check before the 1st OK element
|
||||||
myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary
|
const SMDS_MeshElement* e = me->setNbElemToSkip( elIt );
|
||||||
me->myElements.reserve( GetMesh()->GetMeshInfo().NbElements(GetType()));
|
++me->myMeshInfo[ e->GetEntityType() ];
|
||||||
SMDS_ElemIteratorPtr elIt = GetMesh()->elementsIterator(GetType());
|
|
||||||
while ( elIt->more() )
|
while ( elIt->more() )
|
||||||
{
|
++me->myMeshInfo[ elIt->next()->GetEntityType() ];
|
||||||
const SMDS_MeshElement* e = elIt->next();
|
|
||||||
if ( myPredicate->IsSatisfy( e->GetID() ))
|
|
||||||
me->myElements.push_back( e );
|
|
||||||
}
|
|
||||||
vector< const SMDS_MeshElement*> elems( me->myElements.begin(), me->myElements.end() );
|
|
||||||
me->myElements.swap( elems );
|
|
||||||
}
|
}
|
||||||
me->setChanged( false );
|
me->setChanged( false );
|
||||||
}
|
}
|
||||||
@ -178,7 +312,7 @@ void SMESHDS_GroupOnFilter::update() const
|
|||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets myMeshModifTime according to modification state
|
* \brief Sets myMeshModifTime and clear fields according to modification state
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
@ -187,4 +321,31 @@ void SMESHDS_GroupOnFilter::setChanged(bool changed)
|
|||||||
myMeshModifTime = GetMesh()->GetMTime();
|
myMeshModifTime = GetMesh()->GetMTime();
|
||||||
if ( changed && myMeshModifTime != 0 )
|
if ( changed && myMeshModifTime != 0 )
|
||||||
--myMeshModifTime;
|
--myMeshModifTime;
|
||||||
|
if ( changed ) {
|
||||||
|
myNbElemToSkip = 0;
|
||||||
|
myMeshInfo.assign( SMDSEntity_Last, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Sets myNbElemToSkip
|
||||||
|
* \param okElemIt - iterator on OK elements
|
||||||
|
* \retval const SMDS_MeshElement* - the first OK element
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
const SMDS_MeshElement*
|
||||||
|
SMESHDS_GroupOnFilter::setNbElemToSkip( SMDS_ElemIteratorPtr& okElemIt )
|
||||||
|
{
|
||||||
|
// find out nb of elements to skip w/o check before the 1st OK element
|
||||||
|
const SMDS_MeshElement* firstOkElem = okElemIt->next();
|
||||||
|
if ( myNbElemToSkip == 0 )
|
||||||
|
{
|
||||||
|
SMDS_ElemIteratorPtr elemIt = GetMesh()->elementsIterator( GetType() );
|
||||||
|
myNbElemToSkip = 0;
|
||||||
|
while ( elemIt->next() != firstOkElem )
|
||||||
|
++myNbElemToSkip;
|
||||||
|
}
|
||||||
|
return firstOkElem;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,13 @@ class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase
|
|||||||
|
|
||||||
SMESH_PredicatePtr GetPredicate() const { return myPredicate; }
|
SMESH_PredicatePtr GetPredicate() const { return myPredicate; }
|
||||||
|
|
||||||
virtual int Extent() const;
|
std::vector< int > GetMeshInfo() const;
|
||||||
|
|
||||||
|
int GetElementIds( int* ids ) const;
|
||||||
|
|
||||||
|
virtual int Extent() const;
|
||||||
|
|
||||||
|
virtual bool IsEmpty();
|
||||||
|
|
||||||
virtual bool Contains (const int theID);
|
virtual bool Contains (const int theID);
|
||||||
|
|
||||||
@ -54,21 +60,21 @@ class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase
|
|||||||
|
|
||||||
virtual SMDS_ElemIteratorPtr GetElements() const;
|
virtual SMDS_ElemIteratorPtr GetElements() const;
|
||||||
|
|
||||||
virtual int GetID (const int theIndex);
|
virtual int GetTic() const;
|
||||||
|
|
||||||
virtual int GetTic() const;
|
bool IsUpToDate() const;
|
||||||
|
|
||||||
bool IsUpToDate() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void update() const;
|
void update() const;
|
||||||
void setChanged(bool changed=true);
|
void setChanged(bool changed=true);
|
||||||
|
const SMDS_MeshElement* setNbElemToSkip( SMDS_ElemIteratorPtr& elIt );
|
||||||
|
|
||||||
SMESH_PredicatePtr myPredicate;
|
SMESH_PredicatePtr myPredicate;
|
||||||
std::vector< const SMDS_MeshElement*> myElements;
|
std::vector< int > myMeshInfo;
|
||||||
unsigned long myMeshModifTime; // when myElements was filled
|
size_t myMeshModifTime; // when myMeshInfo was updated
|
||||||
int myPredicateTic;
|
int myPredicateTic;
|
||||||
|
size_t myNbElemToSkip;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user