X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=73bd794f52a9ed8944e0ae67de0653fd22ce4fda;hb=493747e8ea338a2d88204a5f12ba924d72ecbb5b;hp=f90f792da4374bd169af4f2d9bd06402ded22acb;hpb=2de294b09ac8b9ace071a01db9cb4e235f1eadbb;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index f90f792da..73bd794f5 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,30 +1,29 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2011 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// 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. +// 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. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_subMesh.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include "SMESH_subMesh.hxx" #include "SMESH_Algo.hxx" @@ -38,6 +37,8 @@ #include "SMDS_SetIterator.hxx" #include "SMDSAbs_ElementType.hxx" +#include + #include "utilities.h" #include "OpUtil.hxx" #include "Basics_Utils.hxx" @@ -173,6 +174,17 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() return 0; // nothing to compute } +//================================================================================ +/*! + * \brief Returns a current algorithm + */ +//================================================================================ + +SMESH_Algo* SMESH_subMesh::GetAlgo() const +{ + return _father->GetGen()->GetAlgo(*_father, _subShape); +} + //================================================================================ /*! * \brief Allow algo->Compute() if a subshape of lower dim is meshed but @@ -509,12 +521,13 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons { int aHypDim = theHypothesis->GetDim(); int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); - if (aHypDim == 3 && aShapeDim == 3) { - // check case of open shell - //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed()) - if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape)) - return false; - } + // issue 21106. Forbid 3D mesh on the SHELL + // if (aHypDim == 3 && aShapeDim == 3) { + // // check case of open shell + // //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed()) + // if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape)) + // return false; + // } if ( aHypDim <= aShapeDim ) return true; @@ -530,8 +543,14 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, const TopAbs_ShapeEnum theShapeType) { if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) + { // algorithm - return ( theHypothesis->GetShapeType() & (1<< theShapeType)); + if ( theHypothesis->GetShapeType() & (1<< theShapeType)) + // issue 21106. Forbid 3D mesh on the SHELL + return !( theHypothesis->GetDim() == 3 && theShapeType == TopAbs_SHELL ); + else + return false; + } // hypothesis switch ( theShapeType ) { @@ -578,7 +597,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK; SMESHDS_Mesh* meshDS =_father->GetMeshDS(); - SMESH_Gen* gen =_father->GetGen(); + //SMESH_Gen* gen =_father->GetGen(); SMESH_Algo* algo = 0; if (_subShape.ShapeType() == TopAbs_VERTEX ) @@ -595,7 +614,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( event != REMOVE_FATHER_ALGO ) { _algoState = NO_ALGO; - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if ( algo ) { _algoState = MISSING_HYP; if ( event == REMOVE_FATHER_HYP || @@ -688,7 +707,7 @@ SMESH_Hypothesis::Hypothesis_Status case ADD_HYP: break; case ADD_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if (algo->CheckHypothesis((*_father),_subShape, aux_ret)) SetAlgoState(HYP_OK); @@ -705,7 +724,7 @@ SMESH_Hypothesis::Hypothesis_Status case ADD_FATHER_HYP: break; case ADD_FATHER_ALGO: { // Algo just added in father - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo == anHyp ) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret)) @@ -718,7 +737,7 @@ SMESH_Hypothesis::Hypothesis_Status case REMOVE_FATHER_HYP: break; case REMOVE_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) @@ -741,7 +760,7 @@ SMESH_Hypothesis::Hypothesis_Status switch (event) { case ADD_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, ret )) SetAlgoState(HYP_OK); @@ -755,7 +774,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_ALGO: { //already existing algo : on father ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status SetAlgoState(HYP_OK); @@ -770,7 +789,7 @@ SMESH_Hypothesis::Hypothesis_Status case REMOVE_HYP: break; case REMOVE_ALGO: { // perhaps a father algo applies ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo == NULL) // no more algo applying on subShape... { SetAlgoState(NO_ALGO); @@ -786,7 +805,7 @@ SMESH_Hypothesis::Hypothesis_Status } case MODIF_HYP: // assigned hypothesis value may become good case ADD_FATHER_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) SetAlgoState(HYP_OK); @@ -795,7 +814,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_FATHER_ALGO: { // new father algo - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT( algo ); if ( algo == anHyp ) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) @@ -808,7 +827,7 @@ SMESH_Hypothesis::Hypothesis_Status case REMOVE_FATHER_HYP: // nothing to do break; case REMOVE_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo == NULL) // no more applying algo on father { SetAlgoState(NO_ALGO); @@ -834,7 +853,7 @@ SMESH_Hypothesis::Hypothesis_Status switch (event) { case ADD_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if (!algo->CheckHypothesis((*_father),_subShape, ret )) { @@ -857,7 +876,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_ALGO: { //already existing algo : on father ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // check if algo changes SMESH_HypoFilter f; @@ -874,7 +893,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case REMOVE_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) SetAlgoState(HYP_OK); @@ -884,7 +903,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case REMOVE_ALGO: { // perhaps a father algo applies ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo == NULL) // no more algo applying on subShape... { SetAlgoState(NO_ALGO); @@ -903,7 +922,7 @@ SMESH_Hypothesis::Hypothesis_Status } case MODIF_HYP: // hypothesis value may become bad case ADD_FATHER_HYP: { // new father hypothesis ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { @@ -915,7 +934,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if ( algo == anHyp ) { // a new algo on father if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // check if algo changes @@ -934,7 +953,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case REMOVE_FATHER_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // is there the same local hyp or maybe a new father algo applied? @@ -952,7 +971,7 @@ SMESH_Hypothesis::Hypothesis_Status if (!algo->NeedDescretBoundary()) needFullClean = true; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo == NULL) // no more applying algo on father { SetAlgoState(NO_ALGO); @@ -1280,7 +1299,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_ALGO_STATE: - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo && !algo->NeedDescretBoundary()) CleanDependsOn(); // clean sub-meshes with event CLEAN if ( _algoState == HYP_OK ) @@ -1288,6 +1307,10 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: // nothing to do break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do + break; +#endif case CLEAN: CleanDependants(); RemoveSubMeshElementsAndNodes(); @@ -1316,7 +1339,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { case MODIF_ALGO_STATE: _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { if (!algo->NeedDescretBoundary()) @@ -1327,7 +1350,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); if (!ret) @@ -1364,7 +1387,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = FAILED_TO_COMPUTE; _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo); try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif algo->InitComputeError(); @@ -1385,6 +1408,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh _computeError = algo->GetComputeError(); } + catch ( ::SMESH_ComputeError& comperr ) { + cout << " SMESH_ComputeError caught" << endl; + if ( !_computeError ) _computeError = SMESH_ComputeError::New(); + *_computeError = comperr; + } catch ( std::bad_alloc& exc ) { MESSAGE("std::bad_alloc thrown inside algo->Compute()"); if ( _computeError ) { @@ -1452,18 +1480,22 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } } } - if (ret) + if (ret && _computeError && _computeError->myName != COMPERR_WARNING ) { _computeError.reset(); } UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do + break; +#endif case CLEAN: CleanDependants(); RemoveSubMeshElementsAndNodes(); _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); @@ -1480,7 +1512,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) // happen after retrieval from a file ComputeStateEngine( CHECK_COMPUTE_STATE ); ComputeSubMeshStateEngine( SUBMESH_RESTORED ); - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if (algo) algo->SubmeshRestored( this ); break; case MESH_ENTITY_REMOVED: @@ -1502,12 +1534,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { case MODIF_ALGO_STATE: ComputeStateEngine( CLEAN ); - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo && !algo->NeedDescretBoundary()) CleanDependsOn(); // clean sub-meshes with event CLEAN break; case COMPUTE: // nothing to do break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do + break; +#endif case CLEAN: CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN RemoveSubMeshElementsAndNodes(); @@ -1520,7 +1556,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) case SUBMESH_RESTORED: ComputeStateEngine( CHECK_COMPUTE_STATE ); ComputeSubMeshStateEngine( SUBMESH_RESTORED ); - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if (algo) algo->SubmeshRestored( this ); break; case MESH_ENTITY_REMOVED: @@ -1550,7 +1586,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) case MODIF_ALGO_STATE: if ( !IsEmpty() ) ComputeStateEngine( CLEAN ); - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo && !algo->NeedDescretBoundary()) CleanDependsOn(); // clean sub-meshes with event CLEAN if (_algoState == HYP_OK) @@ -1560,6 +1596,14 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: // nothing to do break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: + { + algo = GetAlgo(); + algo->CancelCompute(); + } + break; +#endif case CLEAN: CleanDependants(); // submeshes dependent on me should be cleaned as well RemoveSubMeshElementsAndNodes(); @@ -1621,11 +1665,11 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap) return ret; } - SMESH_Gen *gen = _father->GetGen(); + //SMESH_Gen *gen = _father->GetGen(); SMESH_Algo *algo = 0; SMESH_Hypothesis::Hypothesis_Status hyp_status; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if(algo && !aResMap.count(this) ) { ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); @@ -1700,6 +1744,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t // Check my state if ( !_computeError || _computeError->IsOK() ) { + // no error description is set to this sub-mesh, check if any mesh is computed _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; } else @@ -1717,67 +1762,16 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t if ( _computeError->myComment.size() > 0 ) text << " \"" << _computeError->myComment << "\""; -#ifdef _DEBUG_ - MESSAGE_BEGIN ( text ); - // Show vertices location of a failed shape - TopTools_IndexedMapOfShape vMap; - TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); - MESSAGE_ADD ( "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") ); - for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { - gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); - MESSAGE_ADD ( "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " " - << P.X() << " " << P.Y() << " " << P.Z() << " " ); - } -#else INFOS( text ); -#endif - _computeState = FAILED_TO_COMPUTE; - noErrors = false; - } - } - return noErrors; -} -//======================================================================= -//function : ApplyToCollection -//purpose : Apply theAlgo to all subshapes in theCollection -//======================================================================= - -bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo, - const TopoDS_Shape& theCollection) -{ - MESSAGE("SMESH_subMesh::ApplyToCollection"); - ASSERT ( !theAlgo->NeedDescretBoundary() ); + _computeState = _computeError->IsKO() ? FAILED_TO_COMPUTE : COMPUTE_OK; - if ( _computeError ) - _computeError->myName = COMPERR_OK; - - bool ok = theAlgo->Compute( *_father, theCollection ); - - // set _computeState of subshapes - TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() ); - for ( ; anExplorer.More(); anExplorer.Next() ) - { - if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() )) - { - bool localOK = subMesh->CheckComputeError( theAlgo ); - if ( !ok && localOK && !subMesh->IsMeshComputed() ) - { - subMesh->_computeError = theAlgo->GetComputeError(); - if ( subMesh->_computeError->IsOK() ) - _computeError = SMESH_ComputeError::New(COMPERR_ALGO_FAILED); - localOK = CheckComputeError( theAlgo ); - } - if ( localOK ) - subMesh->UpdateDependantsState( SUBMESH_COMPUTED ); - subMesh->UpdateSubMeshState( localOK ? COMPUTE_OK : FAILED_TO_COMPUTE ); + noErrors = false; } } - - return true; + return noErrors; } - //======================================================================= //function : UpdateSubMeshState //purpose : @@ -1840,7 +1834,8 @@ void SMESH_subMesh::CleanDependants() // will erase mesh on other shapes in a compound if ( ancestor.ShapeType() >= TopAbs_SOLID ) { SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); - if (aSubMesh) + if (aSubMesh && + !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners aSubMesh->ComputeStateEngine(CLEAN); } } @@ -2068,8 +2063,6 @@ EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) * \brief Notify stored event listeners on the occured event * \param event - algo_event or compute_event itself * \param eventType - algo_event or compute_event - * \param subMesh - the submesh where the event occures - * \param data - listener data stored in the subMesh * \param hyp - hypothesis, if eventType is algo_event */ //================================================================================ @@ -2080,7 +2073,17 @@ void SMESH_subMesh::NotifyListenersOnEvent( const int event, { map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin(); for ( ; l_d != myEventListeners.end(); ++l_d ) - l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp ); + { + std::pair< EventListener*, EventListenerData* > li_da = *l_d; /* copy to enable removal + of a listener from + myEventListeners by + its ProcessEvent() */ + if ( li_da.first->myBusySM.insert( this ).second ) + { + li_da.first->ProcessEvent( event, eventType, this, li_da.second, hyp ); + li_da.first->myBusySM.erase( this ); + } + } } //================================================================================