[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
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;
}
//=============================================================================
/*!
*

View File

@ -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<SMESHDS_Command*> & GetLog();
void ClearLog();

View File

@ -34,15 +34,13 @@
#include "SMESH_HypoFilter.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESHDS_Mesh.hxx"
#include <BRepTools_WireExplorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#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<SMESH_subMesh*> 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