diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 8d545cc58..52a7553e6 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -713,6 +713,8 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, } } } + + ret = CheckHypothesesOnSubMeshes(subMesh, anHyp, event); } HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty GetMeshDS()->Modified(); @@ -1002,6 +1004,58 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const return anHyp; } +//================================================================================ +/*! + * \brief Iterates hypotesis for all sub-meshes of the given sub-mesh and checks + algo state with the given event. The goal is to address hypothesis those are + not directly affected by changing of an algorithm of the given sub-shape. + It is essential to rebuild propagation chains of such hypotheses, otherwise the chains + are being cleared after editing of the algorithm and never rebuilt again. + * \param subMesh - the main sub-mesh to check sub-meshes of + * \param anHyp - the hypothesis changed on the given sub-mesh, we need to skip it from checking + * \param event - the given event + * \retval SMESH_Hypothesis::Hypothesis_Status - number of unique hypos in aHypList + */ +//================================================================================ +SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh::CheckHypothesesOnSubMeshes( + SMESH_subMesh* subMesh, + const SMESH_Hypothesis* anHyp, + const SMESH_subMesh::algo_event event) const +{ + SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::Hypothesis_Status::HYP_OK; + + SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false, false); + while (smIt->more()) + { + SMESH_subMesh* sm = smIt->next(); + SMESH_Algo* algo = sm->GetAlgo(); + if (!algo) + continue; + + const TopoDS_Shape& aSubShape = sm->GetSubShape(); + const auto& usedHyps = _meshDS->GetHypothesis(aSubShape); + if (usedHyps.empty()) + continue; + + for (const auto* usedHyp : usedHyps) + { + MESSAGE("usedHyp->GetID() = " << usedHyp->GetID() << "; usedHyp->GetName() = " << usedHyp->GetName()); + SMESH_Hypothesis* hyp = GetHypothesis(usedHyp->GetID()); + if (hyp == anHyp) + continue; + + const SMESH_Hypothesis::Hypothesis_Status ret2 = subMesh->SubMeshesAlgoStateEngine(event, hyp, true); + if (ret2 > ret) + { + ret = ret2; + break; + } + } + } + + return ret; +} + //============================================================================= /*! * diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index f9cc2e913..8820c3abe 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -175,6 +175,11 @@ class SMESH_EXPORT SMESH_Mesh SMESH_Hypothesis * GetHypothesis(const int aHypID) const; + SMESH_Hypothesis::Hypothesis_Status CheckHypothesesOnSubMeshes( + SMESH_subMesh* subMesh, + const SMESH_Hypothesis* anHyp, + const SMESH_subMesh::algo_event event) const; + const std::list & GetLog(); void ClearLog(); diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index d8fc7522c..56b0f53ed 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -34,15 +34,13 @@ #include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" +#include "SMESHDS_Mesh.hxx" #include #include #include #include -#define DBGMSG(txt) \ - // cout << txt << endl; - using namespace std; namespace { @@ -258,7 +256,7 @@ namespace { */ bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh ) { - DBGMSG( "buildPropagationChain from " << theMainSubMesh->GetId() ); + MESSAGE( "buildPropagationChain from " << theMainSubMesh->GetId() ); const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape(); if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; @@ -353,7 +351,7 @@ namespace { if ( anOppE.IsNull() ) continue; if ( nbSide != 4 ) { - DBGMSG( nbSide << " sides in wire #" << mesh->GetMeshDS()->ShapeToIndex( itA.Value() ) << " - SKIP" ); + MESSAGE( nbSide << " sides in wire #" << mesh->GetMeshDS()->ShapeToIndex( itA.Value() ) << " - SKIP" ); continue; } } @@ -375,7 +373,7 @@ namespace { chain.push_back( oppSM ); oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); oppData->SetState( IN_CHAIN ); - DBGMSG( "set IN_CHAIN on " << oppSM->GetId() ); + MESSAGE( "set IN_CHAIN on " << oppSM->GetId() ); if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK ) // make oppSM check algo state if ( SMESH_Algo* algo = oppSM->GetAlgo() ) @@ -383,12 +381,12 @@ namespace { } else { oppData->SetState( LAST_IN_CHAIN ); - DBGMSG( "set LAST_IN_CHAIN on " << oppSM->GetId() ); + MESSAGE( "set LAST_IN_CHAIN on " << oppSM->GetId() ); } } else if ( oppData->State() == LAST_IN_CHAIN ) // anOppE breaks other chain { - DBGMSG( "encounters LAST_IN_CHAIN on " << oppSM->GetId() ); + MESSAGE( "encounters LAST_IN_CHAIN on " << oppSM->GetId() ); oppData->AddSource( theMainSubMesh ); } } // loop on face ancestors @@ -405,7 +403,7 @@ namespace { */ bool clearPropagationChain( SMESH_subMesh* subMesh ) { - DBGMSG( "clearPropagationChain from " << subMesh->GetId() ); + MESSAGE( "clearPropagationChain from " << subMesh->GetId() ); if ( PropagationMgrData* data = findData( subMesh )) { switch ( data->State() ) { @@ -490,7 +488,7 @@ namespace { void PropagationMgr::Set(SMESH_subMesh * submesh) { if ( findData( submesh )) return; - DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() ); + MESSAGE( "PropagationMgr::Set() on " << submesh->GetId() ); PropagationMgrData* data = new PropagationMgrData(); submesh->SetEventListener( getListener(), data, submesh ); @@ -522,7 +520,7 @@ namespace { { TopoDS_Shape edge = sm->GetSubShape(); edge = edge.Oriented( data->myForward ? TopAbs_FORWARD : TopAbs_REVERSED ); - DBGMSG( " GetSource() = edge " << sm->GetId() << " REV = " << (!data->myForward)); + MESSAGE(" GetSource() = edge " << sm->GetId() << " REV = " << (!data->myForward)); isPropagOfDistribution = false; if ( PropagationMgrData* data = findData( sm )) isPropagOfDistribution = data->myIsPropagOfDistribution; @@ -551,7 +549,7 @@ namespace { return; if ( eventType != SMESH_subMesh::ALGO_EVENT ) return; - DBGMSG( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() ); + MESSAGE( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() << "; hyp->GetName(): " << hyp->GetName()); bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() || StdMeshers_PropagOfDistribution::GetName() == hyp->GetName() ); @@ -570,7 +568,7 @@ namespace { if ( event == SMESH_subMesh::ADD_HYP || event == SMESH_subMesh::ADD_FATHER_HYP ) // add local or propagation hyp { - DBGMSG( "ADD_HYP propagation to WAIT_PROPAG_HYP " << subMesh->GetId() ); + MESSAGE( "ADD_HYP propagation to WAIT_PROPAG_HYP " << subMesh->GetId() ); // build propagation chain buildPropagationChain( subMesh ); } @@ -579,11 +577,19 @@ namespace { case HAS_PROPAG_HYP: { // propag hyp on this submesh // -------------------------------------------------------- switch ( event ) { + case SMESH_subMesh::ADD_FATHER_ALGO: + { + MESSAGE("HAS_PROPAG_HYP propagation to ADD_FATHER_ALGO " << subMesh->GetId()); + + // Rebuild propagation chain after an algo was added on father submesh + buildPropagationChain(subMesh); + break; + } case SMESH_subMesh::REMOVE_HYP: case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp if ( isPropagHyp && !getProagationHyp( subMesh )) { - DBGMSG( "REMOVE_HYP propagation from HAS_PROPAG_HYP " << subMesh->GetId() ); + MESSAGE( "REMOVE_HYP propagation from HAS_PROPAG_HYP " << subMesh->GetId() ); // clear propagation chain clearPropagationChain( subMesh ); } @@ -592,7 +598,7 @@ namespace { default: //case SMESH_subMesh::MODIF_HYP: // hyp modif // clear mesh in a chain - DBGMSG( "MODIF_HYP on HAS_PROPAG_HYP " << subMesh->GetId() ); + MESSAGE( "MODIF_HYP on HAS_PROPAG_HYP " << subMesh->GetId() ); SMESH_subMeshIteratorPtr smIt = data->GetChain(); while ( smIt->more() ) { SMESH_subMesh* smInChain = smIt->next(); @@ -607,12 +613,12 @@ namespace { // -------------------------------------------------------- if ( event == SMESH_subMesh::ADD_HYP ) { // add local hypothesis if ( isPropagHyp ) { // propagation hyp added - DBGMSG( "ADD_HYP propagation on IN_CHAIN " << subMesh->GetId() ); + MESSAGE( "ADD_HYP propagation on IN_CHAIN " << subMesh->GetId() ); // collision - do nothing } else { // 1D hyp added // rebuild propagation chain - DBGMSG( "ADD_HYP 1D on IN_CHAIN " << subMesh->GetId() ); + MESSAGE( "ADD_HYP 1D on IN_CHAIN " << subMesh->GetId() ); SMESH_subMesh* sourceSM = data->GetSource(); clearPropagationChain( sourceSM ); buildPropagationChain( sourceSM ); @@ -624,7 +630,7 @@ namespace { // -------------------------------------------------------- if ( event == SMESH_subMesh::REMOVE_HYP ) { // remove local hyp // rebuild propagation chain - DBGMSG( "REMOVE_HYP 1D from LAST_IN_CHAIN " << subMesh->GetId() ); + MESSAGE( "REMOVE_HYP 1D from LAST_IN_CHAIN " << subMesh->GetId() ); list sourceSM = data->mySubMeshes; clearPropagationChain( subMesh ); SMESH_subMeshIteratorPtr smIt = iterate( sourceSM.begin(), sourceSM.end()); @@ -634,6 +640,7 @@ namespace { return; } case MEANINGLESS_LAST: { + MESSAGE("MEANINGLESS_LAST"); break; } } // switch by SubMeshState