22372: EDF 2758 SMESH: Create/Manage groups on a mesh composed of nodes and balls

Cash elements in case of small meshes
This commit is contained in:
eap 2013-11-13 14:38:10 +00:00
parent 1f4550c491
commit 530e2aa3f8
2 changed files with 85 additions and 15 deletions

View File

@ -25,8 +25,8 @@
//
#include "SMESHDS_GroupOnFilter.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMESHDS_Mesh.hxx"
#include <numeric>
#include <limits>
@ -116,7 +116,7 @@ bool SMESHDS_GroupOnFilter::IsEmpty()
bool SMESHDS_GroupOnFilter::Contains (const int theID)
{
return myPredicate ? myPredicate->IsSatisfy( theID ) : false;
return myPredicate && myPredicate->IsSatisfy( theID );
}
//================================================================================
@ -127,7 +127,7 @@ bool SMESHDS_GroupOnFilter::Contains (const int theID)
bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem)
{
return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false;
return myPredicate && myPredicate->IsSatisfy( elem->GetID() );
}
//================================================================================
@ -138,18 +138,33 @@ namespace // Iterator
SMESH_PredicatePtr myPredicate;
SMDS_ElemIteratorPtr myElemIt;
const SMDS_MeshElement* myNextElem;
size_t myNbToFind, myNbFound;
size_t myNbToFind, myNbFound, myTotalNb;
vector< const SMDS_MeshElement*>& myFoundElems;
bool & myFoundElemsOK;
TIterator( const SMESH_PredicatePtr& filter,
SMDS_ElemIteratorPtr& elems,
size_t nbToFind):
size_t nbToFind,
size_t totalNb,
vector< const SMDS_MeshElement*>& foundElems,
bool & foundElemsOK):
myPredicate( filter ),
myElemIt( elems ),
myNextElem( 0 ),
myNbToFind( nbToFind ),
myNbFound( 0 )
myNbFound( 0 ),
myTotalNb( totalNb ),
myFoundElems( foundElems ),
myFoundElemsOK( foundElemsOK )
{
myFoundElemsOK = false;
next();
}
~TIterator()
{
if ( !myFoundElemsOK )
clearVector( myFoundElems );
}
virtual bool more()
{
return myNextElem;
@ -160,14 +175,51 @@ namespace // Iterator
myNbFound += bool( res );
myNextElem = 0;
if ( myNbFound < myNbToFind )
{
while ( myElemIt->more() && !myNextElem )
{
myNextElem = myElemIt->next();
if ( !myPredicate->IsSatisfy( myNextElem->GetID() ))
myNextElem = 0;
}
if ( myNextElem )
myFoundElems.push_back( myNextElem );
else
keepOrClearElemVec();
}
else
{
keepOrClearElemVec();
}
return res;
}
void keepOrClearElemVec()
{
if ( myNbFound == myTotalNb )
{
myFoundElemsOK = false; // all elems are OK, no need to keep them
}
else
{
// nb of bytes used for myFoundElems
size_t vecMemSize = myFoundElems.size() * sizeof( SMDS_MeshElement* ) / sizeof(char);
size_t aMB = 1024 * 1024;
if ( vecMemSize < aMB )
{
myFoundElemsOK = true; // < 1 MB - do not clear
}
else
{
int freeRamMB = SMDS_Mesh::CheckMemory( /*doNotRaise=*/true );
if ( freeRamMB < 0 )
myFoundElemsOK = true; // hope it's OK
else
myFoundElemsOK = ( freeRamMB * aMB > 10 * vecMemSize );
}
}
if ( !myFoundElemsOK )
clearVector( myFoundElems );
}
};
struct TEmptyIterator : public SMDS_ElemIterator
@ -186,8 +238,9 @@ namespace // Iterator
SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
{
size_t nbToFind = std::numeric_limits<size_t>::max();
size_t totalNb = GetMesh()->GetMeshInfo().NbElements( GetType() );
SMDS_ElemIteratorPtr elemIt;
SMDS_ElemIteratorPtr elemIt; // iterator on all elements to initialize TIterator
if ( myPredicate )
{
myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary
@ -195,8 +248,11 @@ SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
elemIt = GetMesh()->elementsIterator( GetType() );
if ( IsUpToDate() )
{
if ( myElementsOK )
return SMDS_ElemIteratorPtr( new SMDS_ElementVectorIterator( myElements.begin(),
myElements.end() ));
nbToFind = Extent();
if ( nbToFind == GetMesh()->GetMeshInfo().NbElements( GetType() ))
if ( nbToFind == totalNb )
return elemIt; // all elements are OK
for ( size_t i = 0; i < myNbElemToSkip; ++i )
elemIt->next(); // skip w/o check
@ -206,7 +262,11 @@ SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
{
elemIt = SMDS_ElemIteratorPtr( new TEmptyIterator );
}
return SMDS_ElemIteratorPtr ( new TIterator( myPredicate, elemIt, nbToFind ));
// the iterator fills myElements if all elements are checked
SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
return SMDS_ElemIteratorPtr
( new TIterator( myPredicate, elemIt, nbToFind, totalNb, me->myElements, me->myElementsOK ));
}
//================================================================================
@ -323,6 +383,8 @@ void SMESHDS_GroupOnFilter::setChanged(bool changed)
if ( changed && myMeshModifTime != 0 )
--myMeshModifTime;
if ( changed ) {
clearVector( myElements );
myElementsOK = false;
myNbElemToSkip = 0;
myMeshInfo.assign( SMDSEntity_Last, 0 );
}

View File

@ -76,8 +76,16 @@ class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase
const SMDS_MeshElement* setNbElemToSkip( SMDS_ElemIteratorPtr& elIt );
int getElementIds( void* ids, size_t idSize ) const;
// We use two ways of optimaization:
// 1) The case of little free memory. Remember nb of KO elements (myNbElemToSkip)
// to skip before the first OK element. As well remember total nb of OK
// elements (myMeshInfo) to stop iteration as all OK elements are found.
// 2) The case of enough free memory. Remember all OK elements (myElements).
SMESH_PredicatePtr myPredicate;
std::vector< int > myMeshInfo;
std::vector< const SMDS_MeshElement*> myElements;
bool myElementsOK;
size_t myMeshModifTime; // when myMeshInfo was updated
int myPredicateTic;
size_t myNbElemToSkip;