+SMESH_Hypothesis::Hypothesis_Status
+ SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp)
+{
+ // MESSAGE("SMESH_subMesh::AlgoStateEngine");
+ //SCRUTE(_algoState);
+ //SCRUTE(event);
+
+ SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
+
+ // **** les retour des evenement shape sont significatifs
+ // (add ou remove fait ou non)
+ // le retour des evenement father n'indiquent pas que add ou remove fait
+ int dim = SMESH_Gen::GetShapeDim(_subShape);
+
+ if (dim < 1)
+ {
+ _algoState = HYP_OK;
+ if (event == ADD_HYP || event == ADD_ALGO)
+ return SMESH_Hypothesis::HYP_BAD_DIM; // do not allow to assign any hyp
+ else
+ return SMESH_Hypothesis::HYP_OK;
+ }
+
+ SMESH_Gen* gen =_father->GetGen();
+// bool ret = false;
+ int oldAlgoState = _algoState;
+ bool modifiedHyp = false; // if set to true, force event MODIF_ALGO_STATE
+ // in ComputeStateEngine
+
+ // ----------------------
+ // check mesh conformity
+ // ----------------------
+ if (event == ADD_ALGO)
+ {
+ if (IsApplicableHypotesis( anHyp ) &&
+ !_father->IsNotConformAllowed() &&
+ !IsConform( static_cast< SMESH_Algo* >( anHyp )))
+ return SMESH_Hypothesis::HYP_NOTCONFORM;
+ }
+
+ // ----------------------------------
+ // add a hypothesis to DS if possible
+ // ----------------------------------
+ if (event == ADD_HYP || event == ADD_ALGO)
+ {
+ if ( ! CanAddHypothesis( anHyp ))
+ return SMESH_Hypothesis::HYP_BAD_DIM;
+
+ if ( GetSimilarAttached( _subShape, anHyp ) )
+ return SMESH_Hypothesis::HYP_ALREADY_EXIST;
+
+ if ( !_meshDS->AddHypothesis(_subShape, anHyp))
+ return SMESH_Hypothesis::HYP_ALREADY_EXIST;
+ }
+
+ // --------------------------
+ // remove a hypothesis from DS
+ // --------------------------
+ if (event == REMOVE_HYP || event == REMOVE_ALGO)
+ {
+ if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
+ return SMESH_Hypothesis::HYP_OK; // nothing changes
+ }
+
+ // ------------------
+ // analyse algo state
+ // ------------------
+ if (!IsApplicableHypotesis( anHyp ))
+ return ret; // not applicable hypotheses do not change algo state
+
+ switch (_algoState)
+ {
+
+ // ----------------------------------------------------------------------
+
+ case NO_ALGO:
+ switch (event) {
+ case ADD_HYP:
+ break;
+ case ADD_ALGO: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ break;
+ }
+ case REMOVE_HYP:
+ break;
+ case REMOVE_ALGO:
+ break;
+ case ADD_FATHER_HYP:
+ break;
+ case ADD_FATHER_ALGO: { // Algo just added in father
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo == anHyp ) {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ }
+ break;
+ }
+ case REMOVE_FATHER_HYP:
+ break;
+ case REMOVE_FATHER_ALGO: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if (algo)
+ {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ }
+ break;
+ }
+ default:
+ ASSERT(0);
+ break;
+ }
+ break;
+
+ // ----------------------------------------------------------------------
+
+ case MISSING_HYP:
+ switch (event)
+ {
+ case ADD_HYP: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo->CheckHypothesis((*_father),_subShape, ret ))
+ SetAlgoState(HYP_OK);
+ if (SMESH_Hypothesis::IsStatusFatal( ret ))
+ _meshDS->RemoveHypothesis(_subShape, anHyp);
+ else if (!_father->IsUsedHypothesis( anHyp, _subShape ))
+ {
+ _meshDS->RemoveHypothesis(_subShape, anHyp);
+ ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+ }
+ break;
+ }
+ case ADD_ALGO: { //already existing algo : on father ?
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ break;
+ }
+ case REMOVE_HYP:
+ break;
+ case REMOVE_ALGO: { // perhaps a father algo applies ?
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if (algo == NULL) // no more algo applying on subShape...
+ {
+ SetAlgoState(NO_ALGO);
+ }
+ else
+ {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ }
+ break;
+ }
+ case ADD_FATHER_HYP: {
+ SMESH_Algo* 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);
+ ASSERT( algo );
+ if ( algo == anHyp ) {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ }
+ break;
+ }
+ case REMOVE_FATHER_HYP: // nothing to do
+ break;
+ case REMOVE_FATHER_ALGO: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if (algo == NULL) // no more applying algo on father
+ {
+ SetAlgoState(NO_ALGO);
+ }
+ else
+ {
+ if ( algo->CheckHypothesis((*_father),_subShape , aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ }
+ break;
+ }
+ default:
+ ASSERT(0);
+ break;
+ }
+ break;
+
+ // ----------------------------------------------------------------------
+
+ case HYP_OK:
+ switch (event)
+ {
+ case ADD_HYP: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if (!algo->CheckHypothesis((*_father),_subShape, ret ))
+ {
+ MESSAGE("two applying algo on the same shape not allowed");
+ _meshDS->RemoveHypothesis(_subShape, anHyp);
+ if ( !SMESH_Hypothesis::IsStatusFatal( ret ))
+ // ret should be fatal: anHyp was not added
+ ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+ }
+ else if (SMESH_Hypothesis::IsStatusFatal( ret ))
+ {
+ _meshDS->RemoveHypothesis(_subShape, anHyp);
+ }
+ else if (!_father->IsUsedHypothesis( anHyp, _subShape ))
+ {
+ _meshDS->RemoveHypothesis(_subShape, anHyp);
+ ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+ }
+ else
+ {
+ modifiedHyp = true;
+ }
+ break;
+ }
+ case ADD_ALGO: { //already existing algo : on father ?
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ modifiedHyp = true;
+ break;
+ }
+ case REMOVE_HYP: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ modifiedHyp = true;
+ break;
+ }
+ case REMOVE_ALGO: { // perhaps a father algo applies ?
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if (algo == NULL) // no more algo applying on subShape...
+ {
+ SetAlgoState(NO_ALGO);
+ }
+ else
+ {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ // check if same algo remains
+ if ( anHyp != algo && strcmp( anHyp->GetName(), algo->GetName()) )
+ modifiedHyp = true;
+ }
+ break;
+ }
+ case ADD_FATHER_HYP: { // new father hypothesis ?
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ {
+ SetAlgoState(HYP_OK);
+ if (_father->IsUsedHypothesis( anHyp, _subShape )) // new Hyp
+ modifiedHyp = true;
+ }
+ else
+ SetAlgoState(MISSING_HYP);
+ break;
+ }
+ case ADD_FATHER_ALGO: { // a new algo on father
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if ( algo == anHyp ) {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ modifiedHyp = true;
+ }
+ break;
+ }
+ case REMOVE_FATHER_HYP: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ ASSERT(algo);
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ // is there the same local hyp or maybe a new father algo applied?
+ if ( !GetSimilarAttached( _subShape, anHyp ) )
+ modifiedHyp = true;
+ break;
+ }
+ case REMOVE_FATHER_ALGO: {
+ SMESH_Algo* algo = gen->GetAlgo((*_father), _subShape);
+ if (algo == NULL) // no more applying algo on father
+ {
+ SetAlgoState(NO_ALGO);
+ }
+ else
+ {
+ if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
+ SetAlgoState(HYP_OK);
+ else
+ SetAlgoState(MISSING_HYP);
+ // is there the same local algo or maybe a new father algo applied?
+ if ( !GetSimilarAttached( _subShape, anHyp ))
+ modifiedHyp = true;
+ }
+ break;
+ }
+ default:
+ ASSERT(0);
+ break;
+ }
+ break;
+
+ // ----------------------------------------------------------------------
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ // ----------------------------------------
+ // check concurent hypotheses on ansestors
+ // ----------------------------------------
+ if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
+ (event == ADD_FATHER_HYP ||
+ event == ADD_FATHER_ALGO ||
+ event == REMOVE_FATHER_HYP ||
+ event == REMOVE_FATHER_ALGO ||
+ event == REMOVE_ALGO ||
+ event == REMOVE_HYP))
+ {
+ ret = CheckConcurentHypothesis( anHyp->GetType() );
+ }
+
+ if ((_algoState != oldAlgoState) || modifiedHyp)
+ int retc = ComputeStateEngine(MODIF_ALGO_STATE);
+
+ return ret;
+}