X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=8c2702a47b3e9121c6fdac9c43333ed5434be5a9;hp=7b6b7dac3545496e5d0c16e79d9f2bc52de4fb55;hb=897fdb92b6c3bd5cfc749bde222355992ecffc13;hpb=bfcfbc1ba9c6fb521332684332cccfae9a67d04c diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 7b6b7dac3..8c2702a47 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -47,13 +47,14 @@ #include #include #include +#include #include #include +#include #include #include -#include -#include #include +#include #include #include @@ -116,8 +117,6 @@ SMESH_subMesh::SMESH_subMesh(int Id, SMESH_subMesh::~SMESH_subMesh() { - MESSAGE("SMESH_subMesh::~SMESH_subMesh"); - // **** deleteOwnListeners(); } @@ -197,7 +196,10 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() SMESH_Algo* SMESH_subMesh::GetAlgo() const { if ( !_algo ) - ((SMESH_subMesh*)this)->_algo = _father->GetGen()->GetAlgo(*_father, _subShape); + { + SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this ); + me->_algo = _father->GetGen()->GetAlgo( me ); + } return _algo; } @@ -399,30 +401,6 @@ int SMESH_subMesh::computeCost() const return _computeCost; } -//============================================================================= -/*! - * - */ -//============================================================================= - -// bool SMESH_subMesh::SubMeshesReady() -// { -// bool subMeshesReady = true; -// SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true); -// while ( smIt->more() ) { -// SMESH_subMesh *sm = smIt->next(); -// bool computeOk = (sm->GetComputeState() == COMPUTE_OK || -// sm->GetComputeState() == READY_TO_COMPUTE); -// if (!computeOk) -// { -// subMeshesReady = false; -// SCRUTE(sm->GetId()); -// break; -// } -// } -// return subMeshesReady; -// } - //============================================================================= /*! * Construct dependence on first level subMeshes. complex shapes (compsolid, @@ -437,110 +415,42 @@ int SMESH_subMesh::computeCost() const const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() { - if (_dependenceAnalysed) + if ( _dependenceAnalysed || !_father->HasShapeToMesh() ) return _mapDepend; - //MESSAGE("SMESH_subMesh::DependsOn"); - int type = _subShape.ShapeType(); - //SCRUTE(type); switch (type) { case TopAbs_COMPOUND: + { + list< TopoDS_Shape > compounds( 1, _subShape ); + list< TopoDS_Shape >::iterator comp = compounds.begin(); + for ( ; comp != compounds.end(); ++comp ) { - //MESSAGE("compound"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next()) - { - insertDependence(exp.Current()); - } - for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next()) - { - if ( BRep_Tool::IsClosed(exp.Current() )) - insertDependence(exp.Current()); //only shell not in solid - else - for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next()) - insertDependence(expF.Current()); // issue 0020959: HEXA_3D fails on shell - - } - for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next()) - { - insertDependence(exp.Current()); - } - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next()) - { - insertDependence(exp.Current()); - } - for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX, TopAbs_EDGE); exp.More();exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_COMPSOLID: - { - //MESSAGE("compsolid"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_SHELL: - { - //MESSAGE("shell"); - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_WIRE: - { - //MESSAGE("wire"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_SOLID: - { - //MESSAGE("solid"); - if(_father->HasShapeToMesh()) { - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next()) + for ( TopoDS_Iterator sub( *comp ); sub.More(); sub.Next() ) + switch ( sub.Value().ShapeType() ) { - insertDependence(exp.Current()); + case TopAbs_COMPOUND: compounds.push_back( sub.Value() ); break; + case TopAbs_COMPSOLID: insertDependence( sub.Value(), TopAbs_SOLID ); break; + case TopAbs_SOLID: insertDependence( sub.Value(), TopAbs_SOLID ); break; + case TopAbs_SHELL: insertDependence( sub.Value(), TopAbs_FACE ); break; + case TopAbs_FACE: insertDependence( sub.Value(), TopAbs_FACE ); break; + case TopAbs_WIRE: insertDependence( sub.Value(), TopAbs_EDGE ); break; + case TopAbs_EDGE: insertDependence( sub.Value(), TopAbs_EDGE ); break; + case TopAbs_VERTEX: insertDependence( sub.Value(), TopAbs_VERTEX ); break; + default:; } - } - break; - } - case TopAbs_FACE: - { - //MESSAGE("face"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_EDGE: - { - //MESSAGE("edge"); - for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next()) - { - insertDependence(exp.Current()); - } - break; - } - case TopAbs_VERTEX: - { - break; - } - default: - { - break; } } + break; + case TopAbs_COMPSOLID: insertDependence( _subShape, TopAbs_SOLID ); break; + case TopAbs_SOLID: insertDependence( _subShape, TopAbs_FACE ); break; + case TopAbs_SHELL: insertDependence( _subShape, TopAbs_FACE ); break; + case TopAbs_FACE: insertDependence( _subShape, TopAbs_EDGE ); break; + case TopAbs_WIRE: insertDependence( _subShape, TopAbs_EDGE ); break; + case TopAbs_EDGE: insertDependence( _subShape, TopAbs_VERTEX ); break; + default:; + } _dependenceAnalysed = true; return _mapDepend; } @@ -568,15 +478,20 @@ namespace { */ //============================================================================= -void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape) +void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape, + TopAbs_ShapeEnum aSubType) { - SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape); - int cle = dependsOnMapKey( aSubMesh ); - if ( _mapDepend.find( cle ) == _mapDepend.end()) + TopExp_Explorer sub( aShape, aSubType ); + for ( ; sub.More(); sub.Next() ) { - _mapDepend[cle] = aSubMesh; - const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn(); - _mapDepend.insert( subMap.begin(), subMap.end() ); + SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() ); + int cle = dependsOnMapKey( aSubMesh ); + if ( _mapDepend.find( cle ) == _mapDepend.end()) + { + _mapDepend[cle] = aSubMesh; + const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn(); + _mapDepend.insert( subMap.begin(), subMap.end() ); + } } } @@ -668,11 +583,17 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, return false; } -//============================================================================= +//================================================================================ /*! - * + * \brief Treats modification of hypotheses definition + * \param [in] event - what happens + * \param [in] anHyp - a hypothesis + * \return SMESH_Hypothesis::Hypothesis_Status - a treatment result. + * + * Optional description of a problematic situation (if any) can be retrieved + * via GetComputeError(). */ -//============================================================================= +//================================================================================ SMESH_Hypothesis::Hypothesis_Status SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp) @@ -737,7 +658,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() )); filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 )); filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 )); - if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis(_subShape, filter, true )) + if ( SMESH_Algo * curAlgo = (SMESH_Algo*)_father->GetHypothesis( this, filter, true )) if ( !curAlgo->NeedDiscreteBoundary() ) algoRequiringCleaning = curAlgo; } @@ -751,7 +672,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( ! CanAddHypothesis( anHyp )) // check dimension return SMESH_Hypothesis::HYP_BAD_DIM; - if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) ) + if ( !anHyp->IsAuxiliary() && getSimilarAttached( _subShape, anHyp ) ) return SMESH_Hypothesis::HYP_ALREADY_EXIST; if ( !meshDS->AddHypothesis(_subShape, anHyp)) @@ -780,6 +701,9 @@ SMESH_Hypothesis::Hypothesis_Status if (!isApplicableHyp) return ret; // not applicable hypotheses do not change algo state + if (( algo = GetAlgo())) + algo->InitComputeError(); + switch (_algoState) { @@ -944,7 +868,7 @@ SMESH_Hypothesis::Hypothesis_Status // ret should be fatal: anHyp was not added ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; } - else if (!_father->IsUsedHypothesis( anHyp, this )) + else if (!_father->IsUsedHypothesis( anHyp, this )) ret = SMESH_Hypothesis::HYP_INCOMPATIBLE; if (SMESH_Hypothesis::IsStatusFatal( ret )) @@ -966,7 +890,7 @@ SMESH_Hypothesis::Hypothesis_Status f.Init( SMESH_HypoFilter::IsAlgo() ); f.And( SMESH_HypoFilter::IsApplicableTo( _subShape )); f.AndNot( SMESH_HypoFilter::Is( algo )); - const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( _subShape, f, true ); + const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( this, f, true ); if (prevAlgo && string(algo->GetName()) != string(prevAlgo->GetName()) ) modifiedHyp = true; @@ -1025,7 +949,7 @@ SMESH_Hypothesis::Hypothesis_Status f.Init( SMESH_HypoFilter::IsAlgo() ); f.And( SMESH_HypoFilter::IsApplicableTo( _subShape )); f.AndNot( SMESH_HypoFilter::Is( algo )); - const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( _subShape, f, true ); + const SMESH_Hypothesis* prevAlgo = _father->GetHypothesis( this, f, true ); if (prevAlgo && string(algo->GetName()) != string(prevAlgo->GetName()) ) modifiedHyp = true; @@ -1091,26 +1015,32 @@ SMESH_Hypothesis::Hypothesis_Status { // is algo hidden? SMESH_Gen* gen = _father->GetGen(); - TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); - for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) { - if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() )) + const std::vector< SMESH_subMesh * > & ancestors = GetAncestors(); + for ( size_t iA = 0; ( ret == SMESH_Hypothesis::HYP_OK && iA < ancestors.size()); ++iA ) { + if ( SMESH_Algo* upperAlgo = ancestors[ iA ]->GetAlgo() ) if ( !upperAlgo->NeedDiscreteBoundary() && !upperAlgo->SupportSubmeshes()) ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO; } // is algo hiding? if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDiscreteBoundary() && - !algo->SupportSubmeshes()) { + !algo->SupportSubmeshes()) + { TopoDS_Shape algoAssignedTo, otherAssignedTo; - gen->GetAlgo( *_father, _subShape, &algoAssignedTo ); + gen->GetAlgo( this, &algoAssignedTo ); map::reverse_iterator i_sm = _mapDepend.rbegin(); for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm ) - if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) && + if ( gen->GetAlgo( i_sm->second, &otherAssignedTo ) && SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo )) ret = SMESH_Hypothesis::HYP_HIDING_ALGO; } } + if ( _algo ) { // get an error description set by _algo->CheckHypothesis() + _computeError = _algo->GetComputeError(); + _algo->InitComputeError(); + } + bool stateChange = ( _algoState != oldAlgoState ); if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK @@ -1138,8 +1068,8 @@ SMESH_Hypothesis::Hypothesis_Status ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); } - if (stateChange || modifiedHyp) - ComputeStateEngine(MODIF_ALGO_STATE); + if ( stateChange || modifiedHyp ) + ComputeStateEngine( MODIF_ALGO_STATE ); _realComputeCost = ( _algoState == HYP_OK ) ? computeCost() : 0; @@ -1179,16 +1109,16 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) for (; itsub.More(); itsub.Next()) { // loop on adjacent subShapes - TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( itsub.Value() )); - for (; it.More(); it.Next()) + const std::vector< SMESH_subMesh * > & ancestors = GetAncestors(); + for ( size_t iA = 0; iA < ancestors.size(); ++iA ) { - const TopoDS_Shape& adjacent = it.Value(); + const TopoDS_Shape& adjacent = ancestors[ iA ]->GetSubShape(); if ( _subShape.IsSame( adjacent )) continue; if ( adjacent.ShapeType() != _subShape.ShapeType()) break; // check algo attached to smAdjacent - SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent); + SMESH_Algo * algo = ancestors[ iA ]->GetAlgo(); if (algo && !algo->NeedDiscreteBoundary() && algo->OnlyUnaryInput()) @@ -1210,14 +1140,24 @@ void SMESH_subMesh::setAlgoState(algo_state state) _algoState = state; } -//============================================================================= +//================================================================================ /*! + * \brief Send an event to sub-meshes + * \param [in] event - the event + * \param [in] anHyp - an hypothesis + * \param [in] exitOnFatal - to stop iteration on sub-meshes if a sub-mesh + * reports a fatal result + * \return SMESH_Hypothesis::Hypothesis_Status - the worst result * + * Optional description of a problematic situation (if any) can be retrieved + * via GetComputeError(). */ -//============================================================================= +//================================================================================ + SMESH_Hypothesis::Hypothesis_Status - SMESH_subMesh::SubMeshesAlgoStateEngine(int event, - SMESH_Hypothesis * anHyp) + SMESH_subMesh::SubMeshesAlgoStateEngine(int event, + SMESH_Hypothesis * anHyp, + bool exitOnFatal) { SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK; //EAP: a wire (dim==1) should notify edges (dim==1) @@ -1226,10 +1166,16 @@ SMESH_Hypothesis::Hypothesis_Status { SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); while ( smIt->more() ) { - SMESH_Hypothesis::Hypothesis_Status ret2 = - smIt->next()->AlgoStateEngine(event, anHyp); + SMESH_subMesh* sm = smIt->next(); + SMESH_Hypothesis::Hypothesis_Status ret2 = sm->AlgoStateEngine(event, anHyp); if ( ret2 > ret ) + { ret = ret2; + _computeError = sm->_computeError; + sm->_computeError.reset(); + if ( exitOnFatal && SMESH_Hypothesis::IsStatusFatal( ret )) + break; + } } } return ret; @@ -1320,48 +1266,32 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ ) void SMESH_subMesh::DumpAlgoState(bool isMain) { - // if (dim < 1) return; - if (isMain) - { - const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); - - map < int, SMESH_subMesh * >::const_iterator itsub; - for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) - { - SMESH_subMesh *sm = (*itsub).second; - sm->DumpAlgoState(false); - } - } - //int type = _subShape.ShapeType(); - MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) << - " type of shape " << _subShape.ShapeType()); - switch (_algoState) - { - case NO_ALGO: - MESSAGE(" AlgoState = NO_ALGO"); - break; - case MISSING_HYP: - MESSAGE(" AlgoState = MISSING_HYP"); - break; - case HYP_OK: - MESSAGE(" AlgoState = HYP_OK"); - break; - } - switch (_computeState) - { - case NOT_READY: - MESSAGE(" ComputeState = NOT_READY"); - break; - case READY_TO_COMPUTE: - MESSAGE(" ComputeState = READY_TO_COMPUTE"); - break; - case COMPUTE_OK: - MESSAGE(" ComputeState = COMPUTE_OK"); - break; - case FAILED_TO_COMPUTE: - MESSAGE(" ComputeState = FAILED_TO_COMPUTE"); - break; - } + if (isMain) + { + const map < int, SMESH_subMesh * >&subMeshes = DependsOn(); + + map < int, SMESH_subMesh * >::const_iterator itsub; + for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + { + SMESH_subMesh *sm = (*itsub).second; + sm->DumpAlgoState(false); + } + } + MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) << + " type of shape " << _subShape.ShapeType()); + switch (_algoState) + { + case NO_ALGO : MESSAGE(" AlgoState = NO_ALGO"); break; + case MISSING_HYP : MESSAGE(" AlgoState = MISSING_HYP"); break; + case HYP_OK : MESSAGE(" AlgoState = HYP_OK");break; + } + switch (_computeState) + { + case NOT_READY : MESSAGE(" ComputeState = NOT_READY");break; + case READY_TO_COMPUTE : MESSAGE(" ComputeState = READY_TO_COMPUTE");break; + case COMPUTE_OK : MESSAGE(" ComputeState = COMPUTE_OK");break; + case FAILED_TO_COMPUTE: MESSAGE(" ComputeState = FAILED_TO_COMPUTE");break; + } } //================================================================================ @@ -1555,7 +1485,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if ( !algo->NeedDiscreteBoundary() && !subFailed ) _computeError = SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH, - "Unexpected computed submesh",algo); + "Unexpected computed sub-mesh",algo); break; // goto exit } } @@ -1589,8 +1519,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { ret = algo->Compute((*_father), shape); } - if ( !_computeError || (/* !ret && */_computeError->IsOK() ) ) // algo can set _computeError of submesh - _computeError = algo->GetComputeError(); + // algo can set _computeError of submesh + _computeError = SMESH_ComputeError::Worst( _computeError, algo->GetComputeError() ); } catch ( ::SMESH_ComputeError& comperr ) { cout << " SMESH_ComputeError caught" << endl; @@ -1737,6 +1667,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) case CHECK_COMPUTE_STATE: if ( IsMeshComputed() ) _computeState = COMPUTE_OK; + else if ( _computeError && _computeError->IsKO() ) + _computeState = FAILED_TO_COMPUTE; break; default: ASSERT(0); @@ -1826,10 +1758,13 @@ bool SMESH_subMesh::ComputeStateEngine(int event) removeSubMeshElementsAndNodes(); break; case SUBMESH_COMPUTED: // allow retry compute - if (_algoState == HYP_OK) - _computeState = READY_TO_COMPUTE; - else - _computeState = NOT_READY; + if ( IsEmpty() ) // 23061 + { + if (_algoState == HYP_OK) + _computeState = READY_TO_COMPUTE; + else + _computeState = NOT_READY; + } break; case SUBMESH_RESTORED: ComputeSubMeshStateEngine( SUBMESH_RESTORED ); @@ -2035,47 +1970,41 @@ void SMESH_subMesh::ComputeSubMeshStateEngine(int event, const bool includeSelf) void SMESH_subMesh::updateDependantsState(const compute_event theEvent) { - TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); - for (; it.More(); it.Next()) + const std::vector< SMESH_subMesh * > & ancestors = GetAncestors(); + for ( size_t iA = 0; iA < ancestors.size(); ++iA ) { - const TopoDS_Shape& ancestor = it.Value(); - if ( SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor)) - aSubMesh->ComputeStateEngine( theEvent ); + ancestors[ iA ]->ComputeStateEngine( theEvent ); } } -//============================================================================= -/*! - * - */ -//============================================================================= +//======================================================================= +//function : cleanDependants +//purpose : +//======================================================================= void SMESH_subMesh::cleanDependants() { int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1; - TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); - for (; it.More(); it.Next()) + const std::vector< SMESH_subMesh * > & ancestors = GetAncestors(); + for ( size_t iA = 0; iA < ancestors.size(); ++iA ) { - const TopoDS_Shape& ancestor = it.Value(); - if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean ) { + const TopoDS_Shape& ancestor = ancestors[ iA ]->GetSubShape(); + if ( SMESH_Gen::GetShapeDim( ancestor ) == dimToClean ) + { // PAL8021. do not go upper than SOLID, else ComputeStateEngine(CLEAN) // will erase mesh on other shapes in a compound - if ( ancestor.ShapeType() >= TopAbs_SOLID ) { - SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); - if (aSubMesh && - !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners - aSubMesh->ComputeStateEngine(CLEAN); - } + if ( ancestor.ShapeType() >= TopAbs_SOLID && + !ancestors[ iA ]->IsEmpty() ) // prevent infinite CLEAN via event lesteners + ancestors[ iA ]->ComputeStateEngine(CLEAN); } } } -//============================================================================= -/*! - * - */ -//============================================================================= +//======================================================================= +//function : removeSubMeshElementsAndNodes +//purpose : +//======================================================================= void SMESH_subMesh::removeSubMeshElementsAndNodes() { @@ -2117,12 +2046,12 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, if ( mainShape.IsSame( _subShape )) return _subShape; - const bool ignoreAuxiliaryHyps = false; + const bool skipAuxHyps = false; list aUsedHyp = - theAlgo->GetUsedHypothesis( *_father, _subShape, ignoreAuxiliaryHyps ); // copy + theAlgo->GetUsedHypothesis( *_father, _subShape, skipAuxHyps ); // copy // put in a compound all shapes with the same hypothesis assigned - // and a good ComputState + // and a good ComputeState TopoDS_Compound aCompound; BRep_Builder aBuilder; @@ -2130,11 +2059,13 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, theSubs.clear(); - TopExp_Explorer anExplorer( mainShape, _subShape.ShapeType() ); - for ( ; anExplorer.More(); anExplorer.Next() ) + SMESH_subMeshIteratorPtr smIt = _father->GetSubMesh( mainShape )->getDependsOnIterator(false); + while ( smIt->more() ) { - const TopoDS_Shape& S = anExplorer.Current(); - SMESH_subMesh* subMesh = _father->GetSubMesh( S ); + SMESH_subMesh* subMesh = smIt->next(); + const TopoDS_Shape& S = subMesh->_subShape; + if ( S.ShapeType() != this->_subShape.ShapeType() ) + continue; theSubs.push_back( subMesh ); if ( subMesh == this ) { @@ -2142,12 +2073,14 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, } else if ( subMesh->GetComputeState() == READY_TO_COMPUTE ) { - SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S ); - if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo - anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps + SMESH_Algo* anAlgo = subMesh->GetAlgo(); + if (( anAlgo->IsSameName( *theAlgo )) && // same algo + ( anAlgo->GetUsedHypothesis( *_father, S, skipAuxHyps ) == aUsedHyp )) // same hyps + { aBuilder.Add( aCompound, S ); - if ( !subMesh->SubMeshesComputed() ) - theSubComputed = false; + if ( !subMesh->SubMeshesComputed() ) + theSubComputed = false; + } } } @@ -2288,7 +2221,7 @@ void SMESH_subMesh::setEventListener(EventListener* listener, EventListenerData* curData = l_d->second; if ( curData && curData != data && curData->IsDeletable() ) delete curData; - if ( l_d->first->IsDeletable() ) + if ( l_d->first != listener && l_d->first->IsDeletable() ) delete l_d->first; _eventListeners.erase( l_d ); break; @@ -2301,16 +2234,31 @@ void SMESH_subMesh::setEventListener(EventListener* listener, /*! * \brief Return an event listener data * \param listener - the listener whose data is + * \param myOwn - if \c true, returns a listener set by this sub-mesh, + * else returns a listener listening to events of this sub-mesh * \retval EventListenerData* - found data, maybe NULL */ //================================================================================ -EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const +EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener, + const bool myOwn) const { - map< EventListener*, EventListenerData* >::const_iterator l_d = - _eventListeners.find( listener ); - if ( l_d != _eventListeners.end() ) - return l_d->second; + if ( myOwn ) + { + list< OwnListenerData >::const_iterator d; + for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) + { + if ( d->myListener == listener && _father->MeshExists( d->myMeshID )) + return d->mySubMesh->GetEventListenerData( listener, !myOwn ); + } + } + else + { + map< EventListener*, EventListenerData* >::const_iterator l_d = + _eventListeners.find( listener ); + if ( l_d != _eventListeners.end() ) + return l_d->second; + } return 0; } @@ -2318,16 +2266,31 @@ EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) /*! * \brief Return an event listener data * \param listenerName - the listener name + * \param myOwn - if \c true, returns a listener set by this sub-mesh, + * else returns a listener listening to events of this sub-mesh * \retval EventListenerData* - found data, maybe NULL */ //================================================================================ -EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName) const +EventListenerData* SMESH_subMesh::GetEventListenerData(const string& listenerName, + const bool myOwn) const { - map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin(); - for ( ; l_d != _eventListeners.end(); ++l_d ) - if ( listenerName == l_d->first->GetName() ) - return l_d->second; + if ( myOwn ) + { + list< OwnListenerData >::const_iterator d; + for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) + { + if ( _father->MeshExists( d->myMeshID ) && listenerName == d->myListener->GetName()) + return d->mySubMesh->GetEventListenerData( listenerName, !myOwn ); + } + } + else + { + map< EventListener*, EventListenerData* >::const_iterator l_d = _eventListeners.begin(); + for ( ; l_d != _eventListeners.end(); ++l_d ) + if ( listenerName == l_d->first->GetName() ) + return l_d->second; + } return 0; } @@ -2402,9 +2365,8 @@ void SMESH_subMesh::deleteOwnListeners() list< OwnListenerData >::iterator d; for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) { - if ( !_father->MeshExists( d->myMeshID )) - continue; - if ( _father->GetId() == d->myMeshID && !_father->GetSubMeshContaining( d->mySubMeshID )) + SMESH_Mesh* mesh = _father->FindMesh( d->myMeshID ); + if ( !mesh || !mesh->GetSubMeshContaining( d->mySubMeshID )) continue; d->mySubMesh->DeleteEventListener( d->myListener ); } @@ -2546,6 +2508,44 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS } } +//================================================================================ +/*! + * \brief Returns ancestor sub-meshes. Finds them if not yet found. + */ +//================================================================================ + +const std::vector< SMESH_subMesh * > & SMESH_subMesh::GetAncestors() const +{ + if ( _ancestors.empty() && + !_subShape.IsSame( _father->GetShapeToMesh() )) + { + const TopTools_ListOfShape& ancShapes = _father->GetAncestors( _subShape ); + + SMESH_subMesh* me = const_cast< SMESH_subMesh* >( this ); + me->_ancestors.reserve( ancShapes.Extent() ); + + TopTools_MapOfShape map; + + for ( TopTools_ListIteratorOfListOfShape it( ancShapes ); it.More(); it.Next() ) + if ( SMESH_subMesh* sm = _father->GetSubMeshContaining( it.Value() )) + if ( map.Add( it.Value() )) + me->_ancestors.push_back( sm ); + } + + return _ancestors; +} + +//================================================================================ +/*! + * \brief Clears the vector of ancestor sub-meshes + */ +//================================================================================ + +void SMESH_subMesh::ClearAncestors() +{ + _ancestors.clear(); +} + //================================================================================ /*! * \brief Find common submeshes (based on shared sub-shapes with other @@ -2554,16 +2554,18 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS */ //================================================================================ -bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther, +bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther, std::set& theSetOfCommon ) const { int oldNb = theSetOfCommon.size(); + // check main submeshes const map ::const_iterator otherEnd = theOther->_mapDepend.end(); if ( theOther->_mapDepend.find(this->GetId()) != otherEnd ) theSetOfCommon.insert( this ); if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() ) theSetOfCommon.insert( theOther ); + // check common submeshes map ::const_iterator mapIt = _mapDepend.begin(); for( ; mapIt != _mapDepend.end(); mapIt++ )