0020918: EDF 1447 SMESH: Mesh common borders

fix event management
This commit is contained in:
eap 2010-11-30 15:24:11 +00:00
parent 48f2666c4d
commit dcd45204f2

View File

@ -138,6 +138,25 @@ namespace // INTERNAL STUFF
}
};
//================================================================================
/*!
* \brief Comparator of sub-meshes
*/
struct _SubLess
{
bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const
{
if ( sm1 == sm2 ) return false;
if ( !sm1 || !sm2 ) return sm1 < sm2;
const TopoDS_Shape& s1 = sm1->GetSubShape();
const TopoDS_Shape& s2 = sm2->GetSubShape();
TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType();
TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType();
if ( t1 == t2)
return (sm1 < sm2);
return t1 < t2; // to have: face < edge
}
};
//================================================================================
/*!
* \brief Container of data dedicated to one source mesh
*/
@ -147,10 +166,10 @@ namespace // INTERNAL STUFF
StdMeshers_Import_1D::TNodeNodeMap _n2n;
StdMeshers_Import_1D::TElemElemMap _e2e;
set< SMESH_subMesh*> _subM; // submeshes relating to this srcMesh
set< SMESH_subMesh*> _copyMeshSubM; // submeshes requesting mesh copying
set< SMESH_subMesh*> _copyGroupSubM; // submeshes requesting mesh copying
set< SMESH_subMesh*> _computedSubM;
set< SMESH_subMesh*, _SubLess > _subM; // submeshes relating to this srcMesh
set< SMESH_subMesh*, _SubLess > _copyMeshSubM; // submeshes requesting mesh copying
set< SMESH_subMesh*, _SubLess > _copyGroupSubM; // submeshes requesting mesh copying
set< SMESH_subMesh*, _SubLess > _computedSubM;
SMESHDS_SubMesh* _importMeshSubDS; // submesh storing a copy of _srcMesh
int _importMeshSubID; // id of _importMeshSubDS
@ -197,10 +216,30 @@ namespace // INTERNAL STUFF
if ( toCopyGroups ) _copyGroupSubM.insert( sm );
else _copyGroupSubM.erase( sm );
}
void addComputed( SMESH_subMesh* sm )
{
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
/*complexShapeFirst=*/true);
while ( smIt->more() )
{
sm = smIt->next();
switch ( sm->GetSubShape().ShapeType() )
{
case TopAbs_EDGE:
case TopAbs_FACE:
_subM.insert( sm );
if ( !sm->IsEmpty() )
_computedSubM.insert( sm );
case TopAbs_VERTEX:
break;
default:;
}
}
}
};
//================================================================================
/*!
* Listener notified on events of an imported submesh
* Listener notified on events relating to imported submesh
*/
class _Listener : public SMESH_subMeshEventListener
{
@ -213,11 +252,32 @@ namespace // INTERNAL STUFF
// return poiter to a static listener
static _Listener* get() { static _Listener theListener; return &theListener; }
static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh);
static void storeImportSubmesh(SMESH_subMesh* importSub,
const SMESH_Mesh* srcMesh,
const StdMeshers_ImportSource1D* srcHyp);
virtual void ProcessEvent(const int event,
const int eventType,
SMESH_subMesh* subMesh,
SMESH_subMeshEventListenerData* data,
const SMESH_Hypothesis* hyp);
void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data );
void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub );
// mark sm as missing src hyp with valid groups
static void waitHypModification(SMESH_subMesh* sm)
{
sm->SetEventListener
(get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
}
};
//--------------------------------------------------------------------------------
/*!
* \brief Find or create ImportData for given meshes
*/
static _ImportData* getImportData(const SMESH_Mesh* srcMesh,
_ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh,
SMESH_Mesh* tgtMesh)
{
list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
@ -231,13 +291,12 @@ namespace // INTERNAL STUFF
//--------------------------------------------------------------------------------
/*!
* \brief Remember an imported mesh and groups
* \param smDS - submesh DS holding the imported mesh
* \param sm - submesh computed by Import algo
* \param srcMeshDS - source mesh
* \brief Remember an imported sub-mesh and set needed even listeners
* \param importSub - submesh computed by Import algo
* \param srcMesh - source mesh
* \param srcHyp - ImportSource hypothesis
*/
static _ImportData* storeImportSubmesh(SMESH_subMesh* importSub,
void _Listener::storeImportSubmesh(SMESH_subMesh* importSub,
const SMESH_Mesh* srcMesh,
const StdMeshers_ImportSource1D* srcHyp)
{
@ -251,41 +310,24 @@ namespace // INTERNAL STUFF
data->mySubMeshes.push_back( smToNotify );
importSub->SetEventListener( get(), data, smToListen );
// remeber the submesh
// remeber the submesh importSub and its sub-submeshes
_ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
iData->_subM.insert( importSub );
iData->trackHypParams( importSub, srcHyp );
if ( !importSub->IsEmpty() )
iData->_computedSubM.insert( importSub );
iData->addComputed( importSub );
if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
{
SMESH_Mesh* tgtMesh = importSub->GetFather();
iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
}
if ( !importSub->IsEmpty() )
iData->_computedSubM.insert( importSub );
return iData;
}
//--------------------------------------------------------------------------------
/*!
* \brief mark sm as missing src hyp with valid groups
*/
static void waitHypModification(SMESH_subMesh* sm)
{
sm->SetEventListener
(get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
}
//--------------------------------------------------------------------------------
/*!
* \brief Remove imported mesh and/or groups as soon as no more imported submeshes
* remain computed
* \brief Remove imported mesh and/or groups if needed
* \param sm - submesh loosing Import algo
* \param data - data holding imported groups
*/
void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
{
list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
list< _ImportData >::iterator d = dList.begin();
@ -303,12 +345,11 @@ namespace // INTERNAL STUFF
}
//--------------------------------------------------------------------------------
/*!
* \brief Remove imported mesh and/or groups and
* clear all submeshes with common source mesh
* \brief Clear submeshes and remove imported mesh and/or groups if necessary
* \param sm - cleared submesh
* \param data - data holding imported groups
*/
void clearSubmesh( SMESH_subMesh* sm, _ListenerData* data )
void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub)
{
list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
list< _ImportData >::iterator d = dList.begin();
@ -318,7 +359,7 @@ namespace // INTERNAL STUFF
if ( (*d)._computedSubM.erase( sm ) )
{
bool copyMesh = !d->_copyMeshSubM.empty();
if ( copyMesh )
if ( copyMesh || clearAllSub )
{
// remove imported mesh and groups
d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
@ -326,10 +367,10 @@ namespace // INTERNAL STUFF
if ( data )
d->removeGroups( sm, data->_srcHyp );
// clear submeshes
// clear the rest submeshes
if ( !d->_computedSubM.empty() )
{
set< SMESH_subMesh*> subs;
set< SMESH_subMesh*, _SubLess> subs;
subs.swap( d->_computedSubM ); // avoid recursion via events
while ( !subs.empty() )
{
@ -339,13 +380,14 @@ namespace // INTERNAL STUFF
d->removeGroups( sm, hypData->_srcHyp );
subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
if ( subM->GetSubShape().ShapeType() == TopAbs_FACE )
subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
}
}
}
else
{
sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
}
if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
}
if ( data )
d->trackHypParams( sm, data->_srcHyp );
@ -357,7 +399,7 @@ namespace // INTERNAL STUFF
/*!
* \brief Remove imported mesh and/or groups
*/
virtual void ProcessEvent(const int event,
void _Listener::ProcessEvent(const int event,
const int eventType,
SMESH_subMesh* subMesh,
SMESH_subMeshEventListenerData* data,
@ -369,6 +411,8 @@ namespace // INTERNAL STUFF
if ( SMESH_subMesh::MODIF_HYP == event &&
SMESH_subMesh::ALGO_EVENT == eventType )
{
// re-call SetEventListener() to take into account valid parameters
// of ImportSource hypothesis
SMESH_Gen* gen = subMesh->GetFather()->GetGen();
if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
algo->SetEventListener( subMesh );
@ -381,19 +425,34 @@ namespace // INTERNAL STUFF
{
switch ( event ) {
case SMESH_subMesh::CLEAN:
clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data );
// source mesh cleaned -> clean target mesh
clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, /*all=*/true );
break;
case SMESH_subMesh::COMPUTE:
if ( subMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
data->mySubMeshes.front()->ComputeStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
case SMESH_subMesh::SUBMESH_COMPUTED: {
// source mesh computed -> reset FAILED state of Import submeshes to
// READY_TO_COMPUTE
SMESH_Mesh* srcMesh = subMesh->GetFather();
if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 )
{
SMESH_Mesh* m = data->mySubMeshes.front()->GetFather();
if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1))
{
sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED );
sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
}
}
break;
}
default:;
}
}
}
else // event of Import submesh
{
bool removeImport = false;
// find out what happens: import hyp modified or removed
bool removeImport = false, modifHyp = false;
if ( SMESH_subMesh::ALGO_EVENT == eventType )
modifHyp = true;
if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
{
removeImport = true;
@ -411,10 +470,10 @@ namespace // INTERNAL STUFF
// treate removal of Import algo from subMesh
removeSubmesh( subMesh, (_ListenerData*) data );
}
else if ( subMesh->IsEmpty() )
else if ( modifHyp )
{
// treate modification of ImportSource hypothesis
clearSubmesh( subMesh, (_ListenerData*) data );
clearSubmesh( subMesh, (_ListenerData*) data, /*all=*/false );
}
else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
SMESH_subMesh::COMPUTE_EVENT == eventType )
@ -435,7 +494,6 @@ namespace // INTERNAL STUFF
}
}
}
}; // class _Listener
//================================================================================
/*!
@ -527,7 +585,7 @@ namespace // INTERNAL STUFF
_ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
iData->_computedSubM.insert( importedSM );
iData->addComputed( importedSM );
if ( iData->_computedSubM.size() != iData->_subM.size() )
return 0; // not all submeshes computed yet
@ -829,17 +887,6 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh,
n2n->clear();
e2e->clear();
{
cout << "IMPORT SubMesh " << endl << " Elems:";
SMDS_ElemIteratorPtr eIt = tgtSubMesh->GetElements();
while ( eIt->more() )
cout << " " << eIt->next()->GetID();
cout << endl << " Nodes:";
SMDS_NodeIteratorPtr nIt = tgtSubMesh->GetNodes();
while ( nIt->more() )
cout << " " << nIt->next()->GetID();
cout << endl;
}
// Remember created groups in order to remove them as soon as the srcHyp is
// modified or something other similar happens. Store them in a hypothesis
// as it stores its values anyway