[bos #43370] Swich Composite Side to Wire Discretization. Fixed when a propagation chain weren't rebuilt after changing an algorithm on father mesh.

This commit is contained in:
Konstantin Leontev 2024-11-26 17:30:52 +00:00
parent f33241e70b
commit ea86803a14
3 changed files with 84 additions and 18 deletions

View File

@ -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 HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
GetMeshDS()->Modified(); GetMeshDS()->Modified();
@ -1002,6 +1004,58 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
return anHyp; 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;
}
//============================================================================= //=============================================================================
/*! /*!
* *

View File

@ -175,6 +175,11 @@ class SMESH_EXPORT SMESH_Mesh
SMESH_Hypothesis * GetHypothesis(const int aHypID) const; 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<SMESHDS_Command*> & GetLog(); const std::list<SMESHDS_Command*> & GetLog();
void ClearLog(); void ClearLog();

View File

@ -34,15 +34,13 @@
#include "SMESH_HypoFilter.hxx" #include "SMESH_HypoFilter.hxx"
#include "SMESH_Mesh.hxx" #include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx" #include "SMESH_subMesh.hxx"
#include "SMESHDS_Mesh.hxx"
#include <BRepTools_WireExplorer.hxx> #include <BRepTools_WireExplorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#define DBGMSG(txt) \
// cout << txt << endl;
using namespace std; using namespace std;
namespace { namespace {
@ -258,7 +256,7 @@ namespace {
*/ */
bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh ) bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh )
{ {
DBGMSG( "buildPropagationChain from " << theMainSubMesh->GetId() ); MESSAGE( "buildPropagationChain from " << theMainSubMesh->GetId() );
const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape(); const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape();
if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
@ -353,7 +351,7 @@ namespace {
if ( anOppE.IsNull() ) if ( anOppE.IsNull() )
continue; continue;
if ( nbSide != 4 ) { 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; continue;
} }
} }
@ -375,7 +373,7 @@ namespace {
chain.push_back( oppSM ); chain.push_back( oppSM );
oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
oppData->SetState( IN_CHAIN ); 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 ) if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK )
// make oppSM check algo state // make oppSM check algo state
if ( SMESH_Algo* algo = oppSM->GetAlgo() ) if ( SMESH_Algo* algo = oppSM->GetAlgo() )
@ -383,12 +381,12 @@ namespace {
} }
else { else {
oppData->SetState( LAST_IN_CHAIN ); 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 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 ); oppData->AddSource( theMainSubMesh );
} }
} // loop on face ancestors } // loop on face ancestors
@ -405,7 +403,7 @@ namespace {
*/ */
bool clearPropagationChain( SMESH_subMesh* subMesh ) bool clearPropagationChain( SMESH_subMesh* subMesh )
{ {
DBGMSG( "clearPropagationChain from " << subMesh->GetId() ); MESSAGE( "clearPropagationChain from " << subMesh->GetId() );
if ( PropagationMgrData* data = findData( subMesh )) if ( PropagationMgrData* data = findData( subMesh ))
{ {
switch ( data->State() ) { switch ( data->State() ) {
@ -490,7 +488,7 @@ namespace {
void PropagationMgr::Set(SMESH_subMesh * submesh) void PropagationMgr::Set(SMESH_subMesh * submesh)
{ {
if ( findData( submesh )) return; if ( findData( submesh )) return;
DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() ); MESSAGE( "PropagationMgr::Set() on " << submesh->GetId() );
PropagationMgrData* data = new PropagationMgrData(); PropagationMgrData* data = new PropagationMgrData();
submesh->SetEventListener( getListener(), data, submesh ); submesh->SetEventListener( getListener(), data, submesh );
@ -522,7 +520,7 @@ namespace {
{ {
TopoDS_Shape edge = sm->GetSubShape(); TopoDS_Shape edge = sm->GetSubShape();
edge = edge.Oriented( data->myForward ? TopAbs_FORWARD : TopAbs_REVERSED ); 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; isPropagOfDistribution = false;
if ( PropagationMgrData* data = findData( sm )) if ( PropagationMgrData* data = findData( sm ))
isPropagOfDistribution = data->myIsPropagOfDistribution; isPropagOfDistribution = data->myIsPropagOfDistribution;
@ -551,7 +549,7 @@ namespace {
return; return;
if ( eventType != SMESH_subMesh::ALGO_EVENT ) if ( eventType != SMESH_subMesh::ALGO_EVENT )
return; return;
DBGMSG( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() ); MESSAGE( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() << "; hyp->GetName(): " << hyp->GetName());
bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() || bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() ||
StdMeshers_PropagOfDistribution::GetName() == hyp->GetName() ); StdMeshers_PropagOfDistribution::GetName() == hyp->GetName() );
@ -570,7 +568,7 @@ namespace {
if ( event == SMESH_subMesh::ADD_HYP || if ( event == SMESH_subMesh::ADD_HYP ||
event == SMESH_subMesh::ADD_FATHER_HYP ) // add local or propagation 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 // build propagation chain
buildPropagationChain( subMesh ); buildPropagationChain( subMesh );
} }
@ -579,11 +577,19 @@ namespace {
case HAS_PROPAG_HYP: { // propag hyp on this submesh case HAS_PROPAG_HYP: { // propag hyp on this submesh
// -------------------------------------------------------- // --------------------------------------------------------
switch ( event ) { 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_HYP:
case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
if ( isPropagHyp && !getProagationHyp( subMesh )) 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 // clear propagation chain
clearPropagationChain( subMesh ); clearPropagationChain( subMesh );
} }
@ -592,7 +598,7 @@ namespace {
default: default:
//case SMESH_subMesh::MODIF_HYP: // hyp modif //case SMESH_subMesh::MODIF_HYP: // hyp modif
// clear mesh in a chain // 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(); SMESH_subMeshIteratorPtr smIt = data->GetChain();
while ( smIt->more() ) { while ( smIt->more() ) {
SMESH_subMesh* smInChain = smIt->next(); SMESH_subMesh* smInChain = smIt->next();
@ -607,12 +613,12 @@ namespace {
// -------------------------------------------------------- // --------------------------------------------------------
if ( event == SMESH_subMesh::ADD_HYP ) { // add local hypothesis if ( event == SMESH_subMesh::ADD_HYP ) { // add local hypothesis
if ( isPropagHyp ) { // propagation hyp added 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 // collision - do nothing
} }
else { // 1D hyp added else { // 1D hyp added
// rebuild propagation chain // 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(); SMESH_subMesh* sourceSM = data->GetSource();
clearPropagationChain( sourceSM ); clearPropagationChain( sourceSM );
buildPropagationChain( sourceSM ); buildPropagationChain( sourceSM );
@ -624,7 +630,7 @@ namespace {
// -------------------------------------------------------- // --------------------------------------------------------
if ( event == SMESH_subMesh::REMOVE_HYP ) { // remove local hyp if ( event == SMESH_subMesh::REMOVE_HYP ) { // remove local hyp
// rebuild propagation chain // rebuild propagation chain
DBGMSG( "REMOVE_HYP 1D from LAST_IN_CHAIN " << subMesh->GetId() ); MESSAGE( "REMOVE_HYP 1D from LAST_IN_CHAIN " << subMesh->GetId() );
list<SMESH_subMesh*> sourceSM = data->mySubMeshes; list<SMESH_subMesh*> sourceSM = data->mySubMeshes;
clearPropagationChain( subMesh ); clearPropagationChain( subMesh );
SMESH_subMeshIteratorPtr smIt = iterate( sourceSM.begin(), sourceSM.end()); SMESH_subMeshIteratorPtr smIt = iterate( sourceSM.begin(), sourceSM.end());
@ -634,6 +640,7 @@ namespace {
return; return;
} }
case MEANINGLESS_LAST: { case MEANINGLESS_LAST: {
MESSAGE("MEANINGLESS_LAST");
break; break;
} }
} // switch by SubMeshState } // switch by SubMeshState