PAL13473 (Build repetitive mesh):

1) add methods to track non hierarchical dependencies
	between submeshes
	2) preview a case that an algo can be not assigned because a shape
	mismatches algo's expectations
	3) fix pb that algo state can not change at MODIF_HYP event
This commit is contained in:
eap 2006-12-06 15:53:25 +00:00
parent 03ad183b77
commit 9388a801df

View File

@ -28,6 +28,8 @@
using namespace std;
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_Hypothesis.hxx"
@ -532,8 +534,8 @@ SMESH_Hypothesis::Hypothesis_Status
return SMESH_Hypothesis::HYP_OK;
}
SMESH_Gen* gen =_father->GetGen();
// bool ret = false;
SMESH_Gen* gen =_father->GetGen();
SMESH_Algo* algo = 0;
int oldAlgoState = _algoState;
bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
// in ComputeStateEngine
@ -653,7 +655,7 @@ SMESH_Hypothesis::Hypothesis_Status
} // Serve Propagation of 1D hypothesis
else // event == REMOVE_ALGO
{
SMESH_Algo* algo = dynamic_cast<SMESH_Algo*> (anHyp);
algo = dynamic_cast<SMESH_Algo*> (anHyp);
if (!algo->NeedDescretBoundary())
{
// clean all mesh in the tree of the current submesh;
@ -682,10 +684,14 @@ SMESH_Hypothesis::Hypothesis_Status
case ADD_HYP:
break;
case ADD_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) {
_meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret;
}
else
SetAlgoState(MISSING_HYP);
break;
@ -697,7 +703,7 @@ SMESH_Hypothesis::Hypothesis_Status
case ADD_FATHER_HYP:
break;
case ADD_FATHER_ALGO: { // Algo just added in father
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo == anHyp ) {
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret))
@ -710,7 +716,7 @@ SMESH_Hypothesis::Hypothesis_Status
case REMOVE_FATHER_HYP:
break;
case REMOVE_FATHER_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if (algo)
{
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
@ -732,7 +738,7 @@ SMESH_Hypothesis::Hypothesis_Status
switch (event)
{
case ADD_HYP: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, ret ))
SetAlgoState(HYP_OK);
@ -746,10 +752,14 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case ADD_ALGO: { //already existing algo : on father ?
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
SetAlgoState(HYP_OK);
else if ( algo->IsStatusFatal( aux_ret )) {
_meshDS->RemoveHypothesis(_subShape, anHyp);
ret = aux_ret;
}
else
SetAlgoState(MISSING_HYP);
break;
@ -757,7 +767,7 @@ SMESH_Hypothesis::Hypothesis_Status
case REMOVE_HYP:
break;
case REMOVE_ALGO: { // perhaps a father algo applies ?
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if (algo == NULL) // no more algo applying on subShape...
{
SetAlgoState(NO_ALGO);
@ -772,16 +782,16 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case ADD_FATHER_HYP: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
SetAlgoState(HYP_OK);
else
SetAlgoState(MISSING_HYP);
}
break;
}
case ADD_FATHER_ALGO: { // new father algo
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT( algo );
if ( algo == anHyp ) {
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
@ -794,7 +804,7 @@ SMESH_Hypothesis::Hypothesis_Status
case REMOVE_FATHER_HYP: // nothing to do
break;
case REMOVE_FATHER_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if (algo == NULL) // no more applying algo on father
{
SetAlgoState(NO_ALGO);
@ -820,7 +830,7 @@ SMESH_Hypothesis::Hypothesis_Status
switch (event)
{
case ADD_HYP: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if (!algo->CheckHypothesis((*_father),_subShape, ret ))
{
@ -843,7 +853,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case ADD_ALGO: { //already existing algo : on father ?
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// check if algo changes
SMESH_HypoFilter f;
@ -860,7 +870,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case REMOVE_HYP: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
SetAlgoState(HYP_OK);
@ -870,7 +880,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case REMOVE_ALGO: { // perhaps a father algo applies ?
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if (algo == NULL) // no more algo applying on subShape...
{
SetAlgoState(NO_ALGO);
@ -888,7 +898,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case ADD_FATHER_HYP: { // new father hypothesis ?
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
{
@ -900,7 +910,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case ADD_FATHER_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if ( algo == anHyp ) { // a new algo on father
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// check if algo changes
@ -919,7 +929,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case REMOVE_FATHER_HYP: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
ASSERT(algo);
if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
// is there the same local hyp or maybe a new father algo applied?
@ -931,7 +941,7 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
case REMOVE_FATHER_ALGO: {
SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
algo = gen->GetAlgo((*_father), _subShape);
if (algo == NULL) // no more applying algo on father
{
SetAlgoState(NO_ALGO);
@ -961,7 +971,16 @@ SMESH_Hypothesis::Hypothesis_Status
break;
}
if ((_algoState != oldAlgoState) || modifiedHyp)
if ( _algoState != oldAlgoState )
{
if (_algoState == HYP_OK )
algo->SetEventListener( this );
if ( oldAlgoState == HYP_OK )
DeleteOwnListeners();
}
NotifyListenersOnEvent( event, ALGO_EVENT, anHyp );
if (_algoState != oldAlgoState || modifiedHyp)
ComputeStateEngine(MODIF_ALGO_STATE);
return ret;
@ -1187,6 +1206,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
SMESH_Algo *algo = 0;
bool ret = true;
SMESH_Hypothesis::Hypothesis_Status hyp_status;
algo_state oldAlgoState = (algo_state) GetAlgoState();
switch (_computeState)
{
@ -1201,10 +1221,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
algo = gen->GetAlgo((*_father), _subShape);
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
if (event == MODIF_ALGO_STATE && _algoState == HYP_OK)
if (algo)
{
_computeState = READY_TO_COMPUTE;
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
_computeState = READY_TO_COMPUTE;
}
if ( _computeState == READY_TO_COMPUTE )
SetAlgoState(HYP_OK);
else
SetAlgoState(MISSING_HYP);
break;
case COMPUTE: // nothing to do
break;
@ -1239,14 +1265,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
algo = gen->GetAlgo((*_father), _subShape);
if (algo && !algo->NeedDescretBoundary())
CleanDependsOn(); // clean sub-meshes with event CLEAN
if (event == MODIF_HYP)
break; // nothing else to do when MODIF_HYP
_computeState = NOT_READY;
if (algo)
{
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
if (ret) {
SetAlgoState(HYP_OK); // it might be KO if BAD_PARAM_VALUE
_computeState = READY_TO_COMPUTE;
}
else
SetAlgoState(MISSING_HYP);
}
break;
case COMPUTE:
@ -1258,6 +1286,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
{
MESSAGE("***** verify compute state *****");
_computeState = NOT_READY;
SetAlgoState(MISSING_HYP);
break;
}
// check submeshes needed
@ -1290,6 +1319,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
if (!ret)
{
MESSAGE("problem in algo execution: failed to compute");
// release ALGO from responsibilty of partially built mesh
RemoveSubMeshElementsAndNodes();
_computeState = FAILED_TO_COMPUTE;
if (!algo->NeedDescretBoundary())
UpdateSubMeshState( FAILED_TO_COMPUTE );
@ -1325,6 +1356,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
_computeState = READY_TO_COMPUTE;
else
SetAlgoState(MISSING_HYP);
}
break;
case SUBMESH_COMPUTED: // nothing to do
@ -1371,6 +1404,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
_computeState = READY_TO_COMPUTE;
else
SetAlgoState(MISSING_HYP);
}
break;
case SUBMESH_COMPUTED: // nothing to do
@ -1456,6 +1491,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
break;
}
if ( _algoState != oldAlgoState )
{
if (_algoState == HYP_OK && algo )
algo->SetEventListener( this );
if ( oldAlgoState == HYP_OK )
DeleteOwnListeners();
}
NotifyListenersOnEvent( event, COMPUTE_EVENT );
//SCRUTE(_computeState);
return ret;
}
@ -1624,11 +1668,9 @@ bool SMESH_subMesh::IsMeshComputed() const
TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
for ( ; exp.More(); exp.Next() )
{
SMESHDS_SubMesh * subMeshDS = _meshDS->MeshElements( exp.Current() );
if ( subMeshDS != NULL &&
(subMeshDS->GetElements()->more() || subMeshDS->GetNodes()->more())) {
SMESHDS_SubMesh * smDS = _meshDS->MeshElements( exp.Current() );
if ( smDS && ( smDS->NbElements() || smDS->NbNodes()))
return true;
}
}
}
else
@ -1751,3 +1793,139 @@ SMESH_Hypothesis::Hypothesis_Status
}
return SMESH_Hypothesis::HYP_OK;
}
//================================================================================
/*!
* \brief Sets an event listener and its data to a submesh
* \param listener - the listener to store
* \param data - the listener data to store
* \param where - the submesh to store the listener and it's data
* \param deleteListener - if true then the listener will be deleted as
* it is removed from where submesh
*
* It remembers the submesh where it puts the listener in order to delete
* them when HYP_OK algo_state is lost
* After being set, event listener is notified on each event of where submesh.
*/
//================================================================================
void SMESH_subMesh::SetEventListener(EventListener* listener,
EventListenerData* data,
SMESH_subMesh* where)
{
if ( listener && where ) {
where->SetEventListener( listener, data );
myOwnListeners.push_back( make_pair( where, listener ));
}
}
//================================================================================
/*!
* \brief Sets an event listener and its data to a submesh
* \param listener - the listener to store
* \param data - the listener data to store
*
* After being set, event listener is notified on each event of a submesh.
*/
//================================================================================
void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* data)
{
myEventListeners.insert( make_pair( listener, data ));
}
//================================================================================
/*!
* \brief Return an event listener data
* \param listener - the listener whose data is
* \retval EventListenerData* - found data, maybe NULL
*/
//================================================================================
EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const
{
map< EventListener*, EventListenerData* >::const_iterator l_d =
myEventListeners.find( listener );
if ( l_d != myEventListeners.end() )
return l_d->second;
return 0;
}
//================================================================================
/*!
* \brief Notify stored event listeners on the occured event
* \param event - algo_event or compute_event itself
* \param eventType - algo_event or compute_event
* \param subMesh - the submesh where the event occures
* \param data - listener data stored in the subMesh
* \param hyp - hypothesis, if eventType is algo_event
*/
//================================================================================
void SMESH_subMesh::NotifyListenersOnEvent( const int event,
const event_type eventType,
SMESH_Hypothesis* hyp)
{
map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin();
for ( ; l_d != myEventListeners.end(); ++l_d )
l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp );
}
//================================================================================
/*!
* \brief Unregister the listener and delete listener's data
* \param listener - the event listener
*/
//================================================================================
void SMESH_subMesh::DeleteEventListener(EventListener* listener)
{
map< EventListener*, EventListenerData* >::iterator l_d =
myEventListeners.find( listener );
if ( l_d != myEventListeners.end() ) {
delete l_d->first;
delete l_d->second;
myEventListeners.erase( l_d );
}
}
//================================================================================
/*!
* \brief Delete event listeners depending on algo of this submesh
*/
//================================================================================
void SMESH_subMesh::DeleteOwnListeners()
{
list< pair< SMESH_subMesh*, EventListener* > >::iterator sm_l;
for ( sm_l = myOwnListeners.begin(); sm_l != myOwnListeners.end(); ++sm_l)
sm_l->first->DeleteEventListener( sm_l->second );
myOwnListeners.clear();
}
//================================================================================
/*!
* \brief Do something on a certain event
* \param event - algo_event or compute_event itself
* \param eventType - algo_event or compute_event
* \param subMesh - the submesh where the event occures
* \param data - listener data stored in the subMesh
* \param hyp - hypothesis, if eventType is algo_event
*
* The base implementation translates CLEAN event to the subMesh
* stored in listener data
*/
//================================================================================
void SMESH_subMeshEventListener::ProcessEvent(const int event,
const int eventType,
SMESH_subMesh* subMesh,
EventListenerData* data,
SMESH_Hypothesis* /*hyp*/)
{
if ( event == SMESH_subMesh::CLEAN && eventType == SMESH_subMesh::COMPUTE_EVENT )
if ( data && !data->mySubMeshes.empty() ) {
ASSERT( data->mySubMeshes.front() != subMesh );
data->mySubMeshes.front()->ComputeStateEngine( event );
}
}