using namespace std;
#include "SMESH_subMesh.hxx"
+
+#include "SMESH_subMeshEventListener.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_Hypothesis.hxx"
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
} // 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;
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;
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))
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 ))
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);
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;
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);
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 ))
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);
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 ))
{
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;
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);
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);
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 ))
{
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
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?
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);
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;
SMESH_Algo *algo = 0;
bool ret = true;
SMESH_Hypothesis::Hypothesis_Status hyp_status;
+ algo_state oldAlgoState = (algo_state) GetAlgoState();
switch (_computeState)
{
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;
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:
{
MESSAGE("***** verify compute state *****");
_computeState = NOT_READY;
+ SetAlgoState(MISSING_HYP);
break;
}
// check submeshes needed
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 );
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
_computeState = READY_TO_COMPUTE;
+ else
+ SetAlgoState(MISSING_HYP);
}
break;
case SUBMESH_COMPUTED: // nothing to do
ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
if (ret)
_computeState = READY_TO_COMPUTE;
+ else
+ SetAlgoState(MISSING_HYP);
}
break;
case SUBMESH_COMPUTED: // nothing to do
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;
}
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
}
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 );
+ }
+}