X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=d15405195f40f53da4ee50498ae6cf4512ac9af6;hb=5142df035d3a1f35c6af00cde28969088a547205;hp=b0211dc4a4150ef89e2e8f0c4aceed5a06ceae06;hpb=a448c25876fd98a090edc9d2b575c88b3e49af31;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index b0211dc4a..d15405195 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2010 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 @@ -19,6 +19,7 @@ // // 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; //============================================================================= @@ -82,22 +86,22 @@ SMESH_subMesh::SMESH_subMesh(int Id, SMESHDS_Mesh * meshDS, const TopoDS_Shape & aSubShape) { - _subShape = aSubShape; - _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... - _father = father; - _Id = Id; - _dependenceAnalysed = _alwaysComputed = false; - - if (_subShape.ShapeType() == TopAbs_VERTEX) - { - _algoState = HYP_OK; - _computeState = READY_TO_COMPUTE; - } - else - { + _subShape = aSubShape; + _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... + _father = father; + _Id = Id; + _dependenceAnalysed = _alwaysComputed = false; + + if (_subShape.ShapeType() == TopAbs_VERTEX) + { + _algoState = HYP_OK; + _computeState = READY_TO_COMPUTE; + } + else + { _algoState = NO_ALGO; _computeState = NOT_READY; - } + } } //============================================================================= @@ -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: @@ -495,8 +494,8 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) const TopoDS_Shape & SMESH_subMesh::GetSubShape() const { - //MESSAGE("SMESH_subMesh::GetSubShape"); - return _subShape; + //MESSAGE("SMESH_subMesh::GetSubShape"); + return _subShape; } @@ -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; } } @@ -1148,48 +1150,48 @@ void SMESH_subMesh::CleanDependsOn() void SMESH_subMesh::DumpAlgoState(bool isMain) { - int dim = SMESH_Gen::GetShapeDim(_subShape); + int dim = SMESH_Gen::GetShapeDim(_subShape); // 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 = " << dim << " type of shape " << type); - 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); + } + } + int type = _subShape.ShapeType(); + MESSAGE("dim = " << dim << " type of shape " << type); + 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; + } } //================================================================================ @@ -1284,13 +1286,13 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if ( _algoState == HYP_OK ) _computeState = READY_TO_COMPUTE; break; - case COMPUTE: // nothing to do + case COMPUTE: // nothing to do break; case CLEAN: CleanDependants(); RemoveSubMeshElementsAndNodes(); break; - case SUBMESH_COMPUTED: // nothing to do + case SUBMESH_COMPUTED: // nothing to do break; case SUBMESH_RESTORED: ComputeSubMeshStateEngine( SUBMESH_RESTORED ); @@ -1368,6 +1370,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,18 +1428,29 @@ 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) { @@ -1515,11 +1529,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 +1548,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 @@ -1598,11 +1615,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 +1626,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 +1700,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t // Check my state if ( !_computeError || _computeError->IsOK() ) { - _computeState = COMPUTE_OK; + _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; } else { @@ -1685,20 +1717,8 @@ 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; } @@ -2036,8 +2056,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 +2066,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 +2213,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(); +}