+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;
+
+ // Serve Propagation of 1D hypothesis
+ if (event == ADD_HYP) {
+ bool isPropagationOk = true;
+ string hypName = anHyp->GetName();
+
+ if (hypName == "Propagation") {
+ if (_subShape.ShapeType() == TopAbs_EDGE) {
+ isPropagationOk = _father->BuildPropagationChain(_subShape);
+ } else {
+ TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+ TopTools_MapOfShape aMap;
+ for (; exp.More(); exp.Next()) {
+ if (aMap.Add(exp.Current())) {
+ if (!_father->BuildPropagationChain(exp.Current())) {
+ isPropagationOk = false;
+ }
+ }
+ }
+ }
+ } else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated
+ if (_subShape.ShapeType() == TopAbs_EDGE) {
+ TopoDS_Shape aMainEdge;
+ if (_father->IsPropagatedHypothesis(_subShape, aMainEdge)) {
+ isPropagationOk = _father->RebuildPropagationChains();
+ } else if (_father->IsPropagationHypothesis(_subShape)) {
+ isPropagationOk = _father->BuildPropagationChain(_subShape);
+ } else {
+ }
+ }
+ } else {
+ }
+
+ if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+ ret = SMESH_Hypothesis::HYP_CONCURENT;
+ }
+ } // Serve Propagation of 1D hypothesis
+ }
+
+ // --------------------------
+ // remove a hypothesis from DS
+ // --------------------------
+ if (event == REMOVE_HYP || event == REMOVE_ALGO)
+ {
+ if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
+ return SMESH_Hypothesis::HYP_OK; // nothing changes
+
+ // Serve Propagation of 1D hypothesis
+ if (event == REMOVE_HYP) {
+ bool isPropagationOk = true;
+ string hypName = anHyp->GetName();
+
+ if (hypName == "Propagation") {
+ if (_subShape.ShapeType() == TopAbs_EDGE) {
+ if (!_father->RemovePropagationChain(_subShape)) {
+ return SMESH_Hypothesis::HYP_UNKNOWN_FATAL;
+ }
+ // rebuild propagation chains, because removing one
+ // chain can resolve concurention, existing before
+ isPropagationOk = _father->RebuildPropagationChains();
+ } else {
+ TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+ TopTools_MapOfShape aMap;
+ for (; exp.More(); exp.Next()) {
+ if (aMap.Add(exp.Current())) {
+ if (!_father->RemovePropagationChain(exp.Current())) {
+ return SMESH_Hypothesis::HYP_UNKNOWN_FATAL;
+ }
+ }
+ }
+ // rebuild propagation chains, because removing one
+ // chain can resolve concurention, existing before
+ if (!_father->RebuildPropagationChains()) {
+ isPropagationOk = false;
+ }
+ }
+ } else { // if (hypName == "Propagation")
+ if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated
+ {
+ if (_subShape.ShapeType() == TopAbs_EDGE) {
+ isPropagationOk = _father->RebuildPropagationChains();
+ if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT)
+ ret = SMESH_Hypothesis::HYP_CONCURENT;
+ }
+ }
+ }
+
+ if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+ ret = SMESH_Hypothesis::HYP_CONCURENT;
+ }
+ } // Serve Propagation of 1D hypothesis
+ }
+
+ // ------------------
+ // 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;
+ }
+
+ if ((_algoState != oldAlgoState) || modifiedHyp)
+ ComputeStateEngine(MODIF_ALGO_STATE);
+
+ return ret;
+}