X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=0b3c98369862f4a68e52e582d36aa1c017d2ff24;hb=0650af74abac6c08b6b238eb073e72c9cdc28852;hp=21d1675184e5ce3f911484c3b2308fab9430fe54;hpb=fd8513f94e2c17a62fb9a654cdbf0d7ea58d6692;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 21d167518..0b3c98369 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 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 +// 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 +// 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 @@ -39,6 +40,7 @@ #include "utilities.h" #include "OpUtil.hxx" +#include "Basics_Utils.hxx" #include #include @@ -54,6 +56,8 @@ #include #include +#include + using namespace std; //============================================================================= @@ -261,7 +265,7 @@ bool SMESH_subMesh::SubMeshesComputed() break; // the rest subMeshes are all of less dimension SMESHDS_SubMesh * ds = sm->GetSubMeshDS(); bool computeOk = (sm->GetComputeState() == COMPUTE_OK || - (ds && ( ds->NbNodes() || ds->NbElements() ))); + (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() ))); if (!computeOk) { int type = ss.ShapeType(); @@ -368,23 +372,24 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_COMPOUND: { //MESSAGE("compound"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + 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()) + 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()) + 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()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -392,9 +397,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() } case TopAbs_COMPSOLID: { - //MESSAGE("compsolid"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + //MESSAGE("compsolid"); + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -403,8 +407,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_SHELL: { //MESSAGE("shell"); - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -413,8 +416,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_WIRE: { //MESSAGE("wire"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -424,8 +426,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() { //MESSAGE("solid"); if(_father->HasShapeToMesh()) { - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -435,8 +436,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_FACE: { //MESSAGE("face"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -445,11 +445,10 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_EDGE: { //MESSAGE("edge"); - for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); - } + InsertDependence(exp.Current()); + } break; } case TopAbs_VERTEX: @@ -1001,9 +1000,12 @@ SMESH_Hypothesis::Hypothesis_Status if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDescretBoundary() && !algo->SupportSubmeshes()) { + TopoDS_Shape algoAssignedTo, otherAssignedTo; + gen->GetAlgo( *_father, _subShape, &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 )) + if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) && + SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo )) ret = SMESH_Hypothesis::HYP_HIDING_ALGO; } } @@ -1286,6 +1288,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(); @@ -1368,6 +1374,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) algo->InitComputeError(); MemoryReserve aMemoryReserve; SMDS_Mesh::CheckMemory(); + Kernel_Utils::Localizer loc; if ( !_father->HasShapeToMesh() ) // no shape { SMESH_MesherHelper helper( *_father ); @@ -1425,26 +1432,41 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else ret = false; } - if (ret && !_alwaysComputed && shape == _subShape) { // check if anything was built - ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() )); + TopExp_Explorer subS(shape, _subShape.ShapeType()); + if (ret) // check if anything was built + { + for (; ret && subS.More(); subS.Next()) + ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed(); } bool isComputeErrorSet = !CheckComputeError( algo, shape ); if (!ret && !isComputeErrorSet) { // Set _computeError - if ( !_computeError ) - _computeError = SMESH_ComputeError::New(); - if ( _computeError->IsOK() ) - _computeError->myName = COMPERR_ALGO_FAILED; - _computeState = FAILED_TO_COMPUTE; + for (subS.ReInit(); subS.More(); subS.Next()) + { + SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); + if ( !sm->IsMeshComputed() ) + { + if ( !sm->_computeError ) + sm->_computeError = SMESH_ComputeError::New(); + if ( sm->_computeError->IsOK() ) + sm->_computeError->myName = COMPERR_ALGO_FAILED; + sm->_computeState = FAILED_TO_COMPUTE; + sm->_computeError->myAlgo = algo; + } + } } - 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(); @@ -1494,6 +1516,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(); // clean sub-meshes, dependant on this one, with event CLEAN RemoveSubMeshElementsAndNodes(); @@ -1515,11 +1541,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event) ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); break; case CHECK_COMPUTE_STATE: - if ( !IsMeshComputed() ) + if ( !IsMeshComputed() ) { if (_algoState == HYP_OK) _computeState = READY_TO_COMPUTE; else _computeState = NOT_READY; + } break; default: ASSERT(0); @@ -1533,6 +1560,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_ALGO_STATE: + if ( !IsEmpty() ) + ComputeStateEngine( CLEAN ); algo = gen->GetAlgo((*_father), _subShape); if (algo && !algo->NeedDescretBoundary()) CleanDependsOn(); // clean sub-meshes with event CLEAN @@ -1543,6 +1572,14 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: // nothing to do break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: + { + algo = gen->GetAlgo((*_father), _subShape); + algo->CancelCompute(); + } + break; +#endif case CLEAN: CleanDependants(); // submeshes dependent on me should be cleaned as well RemoveSubMeshElementsAndNodes(); @@ -1598,11 +1635,9 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap) bool ret = true; if (_subShape.ShapeType() == TopAbs_VERTEX) { - std::vector aVec(SMDSEntity_Last); - for(int i= SMDSEntity_Node; i < SMDSEntity_Last; i++) - aVec[i] = 0; + vector aVec(SMDSEntity_Last,0); aVec[SMDSEntity_Node] = 1; - aResMap.insert(std::make_pair(this,aVec)); + aResMap.insert(make_pair(this,aVec)); return ret; } @@ -1611,15 +1646,32 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap) SMESH_Hypothesis::Hypothesis_Status hyp_status; algo = gen->GetAlgo((*_father), _subShape); - if(algo) { + if(algo && !aResMap.count(this) ) + { ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); if (!ret) return false; - TopoDS_Shape shape = _subShape; - + if (_father->HasShapeToMesh() && algo->NeedDescretBoundary()) + { + // check submeshes needed + bool subMeshEvaluated = true; + int dimToCheck = SMESH_Gen::GetShapeDim( _subShape ) - 1; + SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,/*complexShapeFirst=*/true); + while ( smIt->more() && subMeshEvaluated ) + { + SMESH_subMesh* sm = smIt->next(); + int dim = SMESH_Gen::GetShapeDim( sm->GetSubShape() ); + if (dim < dimToCheck) break; // the rest subMeshes are all of less dimension + const vector & nbs = aResMap[ sm ]; + subMeshEvaluated = (std::accumulate( nbs.begin(), nbs.end(), 0 ) > 0 ); + } + if ( !subMeshEvaluated ) + return false; + } _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo); + ret = algo->Evaluate((*_father), _subShape, aResMap); - ret = algo->Evaluate((*_father), shape, aResMap); + aResMap.insert( make_pair( this,vector(0))); } return ret; @@ -1668,7 +1720,8 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t // Check my state if ( !_computeError || _computeError->IsOK() ) { - _computeState = COMPUTE_OK; + // no error description is set to this sub-mesh, check if any mesh is computed + _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; } else { @@ -1685,67 +1738,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() ); - if ( _computeError ) - _computeError->myName = COMPERR_OK; + _computeState = _computeError->IsKO() ? FAILED_TO_COMPUTE : COMPUTE_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 : @@ -2036,8 +2038,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 */ //================================================================================ @@ -2048,7 +2048,11 @@ 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 ); + if ( (*l_d).first->myBusySM.insert( this ).second ) + { + l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp ); + l_d->first->myBusySM.erase( this ); + } } //================================================================================ @@ -2191,3 +2195,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS ( new _Iterator( new SMDS_mapIterator( DependsOn() ), prepend, append )); } } + +//================================================================================ +/*! + * \brief Find common submeshes (based on shared subshapes with other + * \param theOther submesh to check + * \param theSetOfCommon set of common submesh + */ +//================================================================================ + +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++ ) + if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd ) + theSetOfCommon.insert( (*mapIt).second ); + return oldNb < theSetOfCommon.size(); +}