X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_subMesh.cxx;h=b297cf60945552487f4f9a0c72e7e98ebff68bc3;hp=57a401df93e39f33c1a86c14bea38a286afd5db8;hb=cf7328b78f5781ca1e17ab0b15d878746084dfa9;hpb=25b7d7ffe76e153c93cb67055192b11b16c3d0e2 diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 57a401df9..b297cf609 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -27,16 +27,16 @@ #include "SMESH_subMesh.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Algo.hxx" +#include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "SMESH_Comment.hxx" -#include "SMDS_SetIterator.hxx" -#include "SMDSAbs_ElementType.hxx" #include @@ -63,6 +63,11 @@ using namespace std; +#ifdef _DEBUG_ +// enable printing algo + shape id + hypo used while meshing +//#define PRINT_WHO_COMPUTE_WHAT +#endif + //============================================================================= /*! * \brief Allocate some memory at construction and release it at destruction. @@ -241,7 +246,7 @@ bool SMESH_subMesh::IsMeshComputed() const { if ( _alwaysComputed ) return true; - // algo may bind a submesh not to _subShape, eg 3D algo + // algo may bind a sub-mesh not to _subShape, eg 3D algo // sets nodes on SHELL while _subShape may be SOLID SMESHDS_Mesh* meshDS = _father->GetMeshDS(); @@ -280,7 +285,7 @@ bool SMESH_subMesh::SubMeshesComputed(bool * isFailedToCompute/*=0*/) const int dimToCheck = myDim - 1; bool subMeshesComputed = true; if ( isFailedToCompute ) *isFailedToCompute = false; - // check subMeshes with upper dimension => reverse iteration + // check sub-meshes with upper dimension => reverse iteration SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true); while ( smIt->more() ) { @@ -291,67 +296,22 @@ bool SMESH_subMesh::SubMeshesComputed(bool * isFailedToCompute/*=0*/) const // MSV 07.04.2006: restrict checking to myDim-1 only. Ex., there is no sense // in checking of existence of edges if the algo needs only faces. Moreover, - // degenerated edges may have no submesh, as after computing NETGEN_2D. + // degenerated edges may have no sub-mesh, as after computing NETGEN_2D. if ( !_algo || _algo->NeedDiscreteBoundary() ) { int dim = SMESH_Gen::GetShapeDim( ss ); if (dim < dimToCheck) - break; // the rest subMeshes are all of less dimension + break; // the rest sub-meshes are all of less dimension } SMESHDS_SubMesh * ds = sm->GetSubMeshDS(); - bool computeOk = (sm->GetComputeState() == COMPUTE_OK || - (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() ))); + bool computeOk = ((sm->GetComputeState() == COMPUTE_OK ) || + (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() ))); if (!computeOk) { subMeshesComputed = false; + if ( isFailedToCompute && !(*isFailedToCompute) ) *isFailedToCompute = ( sm->GetComputeState() == FAILED_TO_COMPUTE ); - // int type = ss.ShapeType(); - - // switch (type) - // { - // case TopAbs_COMPOUND: - // { - // MESSAGE("The not computed sub mesh is a COMPOUND"); - // break; - // } - // case TopAbs_COMPSOLID: - // { - // MESSAGE("The not computed sub mesh is a COMPSOLID"); - // break; - // } - // case TopAbs_SHELL: - // { - // MESSAGE("The not computed sub mesh is a SHEL"); - // break; - // } - // case TopAbs_WIRE: - // { - // MESSAGE("The not computed sub mesh is a WIRE"); - // break; - // } - // case TopAbs_SOLID: - // { - // MESSAGE("The not computed sub mesh is a SOLID"); - // break; - // } - // case TopAbs_FACE: - // { - // MESSAGE("The not computed sub mesh is a FACE"); - // break; - // } - // case TopAbs_EDGE: - // { - // MESSAGE("The not computed sub mesh is a EDGE"); - // break; - // } - // default: - // { - // MESSAGE("The not computed sub mesh is of unknown type"); - // break; - // } - // } - if ( !isFailedToCompute ) break; } @@ -438,7 +398,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() } break; case TopAbs_COMPSOLID: insertDependence( _subShape, TopAbs_SOLID ); break; - case TopAbs_SOLID: insertDependence( _subShape, TopAbs_FACE ); break; + case TopAbs_SOLID: insertDependence( _subShape, TopAbs_FACE ); + { /*internal EDGE*/ insertDependence( _subShape, TopAbs_EDGE, TopAbs_WIRE ); 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; @@ -477,9 +438,10 @@ namespace //============================================================================= void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape, - TopAbs_ShapeEnum aSubType) + TopAbs_ShapeEnum aSubType, + TopAbs_ShapeEnum avoidType) { - TopExp_Explorer sub( aShape, aSubType ); + TopExp_Explorer sub( aShape, aSubType, avoidType ); for ( ; sub.More(); sub.Next() ) { SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() ); @@ -553,7 +515,20 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons //======================================================================= //function : IsApplicableHypotesis -//purpose : +//purpose : check if this sub-mesh can be computed using a hypothesis +//======================================================================= + +bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const +{ + if ( !_father->HasShapeToMesh() && _subShape.ShapeType() == TopAbs_SOLID ) + return true; // true for the PseudoShape + + return IsApplicableHypotesis( theHypothesis, _subShape.ShapeType() ); +} + +//======================================================================= +//function : IsApplicableHypotesis +//purpose : compare shape type and hypothesis type //======================================================================= bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, @@ -607,7 +582,7 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, //================================================================================ SMESH_Hypothesis::Hypothesis_Status - SMESH_subMesh::AlgoStateEngine(int event, SMESH_Hypothesis * anHyp) + SMESH_subMesh::AlgoStateEngine(algo_event event, SMESH_Hypothesis * anHyp) { // **** les retour des evenement shape sont significatifs // (add ou remove fait ou non) @@ -1165,7 +1140,7 @@ void SMESH_subMesh::setAlgoState(algo_state state) //================================================================================ SMESH_Hypothesis::Hypothesis_Status - SMESH_subMesh::SubMeshesAlgoStateEngine(int event, + SMESH_subMesh::SubMeshesAlgoStateEngine(algo_event event, SMESH_Hypothesis * anHyp, bool exitOnFatal) { @@ -1215,8 +1190,6 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ ) } else if ( algoRequiringCleaning && algoRequiringCleaning->SupportSubmeshes() ) { - SMESHDS_Mesh* meshDS = _father->GetMeshDS(); - // find sub-meshes to keep elements on set< SMESH_subMesh* > smToKeep; TopAbs_ShapeEnum prevShapeType = TopAbs_SHAPE; @@ -1232,26 +1205,29 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ ) if ( !sameShapeType ) { // check if the algo allows presence of global algos of dimension the algo - // can generate it-self + // can generate it-self; + // always keep a node on VERTEX, as this node can be shared by segments + // lying on EDGEs not shared by the VERTEX of sm, due to MergeNodes (PAL23068) int shapeDim = SMESH_Gen::GetShapeDim( sm->GetSubShape() ); - keepSubMeshes = algoRequiringCleaning->NeedLowerHyps( shapeDim ); + keepSubMeshes = ( algoRequiringCleaning->NeedLowerHyps( shapeDim ) || shapeDim == 0 ); prevShapeType = sm->GetSubShape().ShapeType(); toKeepPrevShapeType = keepSubMeshes; } if ( !keepSubMeshes ) { - // look for an algo assigned to sm - bool algoFound = false; - const list& hyps = meshDS->GetHypothesis( sm->_subShape ); - list::const_iterator h = hyps.begin(); - for ( ; ( !algoFound && h != hyps.end() ); ++h ) - algoFound = ((*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ); - keepSubMeshes = algoFound; + // look for a local algo used to mesh sm + TopoDS_Shape algoShape = SMESH_MesherHelper::GetShapeOfHypothesis + ( algoRequiringCleaning, _subShape, _father ); + SMESH_HypoFilter moreLocalAlgo; + moreLocalAlgo.Init( SMESH_HypoFilter::IsMoreLocalThan( algoShape, *_father )); + moreLocalAlgo.And ( SMESH_HypoFilter::IsAlgo() ); + bool localAlgoFound = _father->GetHypothesis( sm->_subShape, moreLocalAlgo, true ); + keepSubMeshes = localAlgoFound; } // remember all sub-meshes of sm if ( keepSubMeshes ) { - SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false); + SMESH_subMeshIteratorPtr smIt2 = sm->getDependsOnIterator(true); while ( smIt2->more() ) smToKeep.insert( smIt2->next() ); } @@ -1314,24 +1290,44 @@ void SMESH_subMesh::DumpAlgoState(bool isMain) static void cleanSubMesh( SMESH_subMesh * subMesh ) { if (subMesh) { - if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) { + if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) + { SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS(); - SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); - while (ite->more()) { - const SMDS_MeshElement * elt = ite->next(); - //MESSAGE( " RM elt: "<GetID()<<" ( "<NbNodes()<<" )" ); - //meshDS->RemoveElement(elt); - meshDS->RemoveFreeElement(elt, 0); + int nbElems = subMeshDS->NbElements(); + if ( nbElems > 0 ) + { + // start from elem with max ID to avoid filling the pool of IDs + bool rev = true; + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements( rev ); + const SMDS_MeshElement * lastElem = ite->next(); + rev = ( lastElem->GetID() == meshDS->MaxElementID() ); + if ( !rev ) + ite = subMeshDS->GetElements( rev ); + else + meshDS->RemoveFreeElement( lastElem, subMeshDS ); + while (ite->more()) { + const SMDS_MeshElement * elt = ite->next(); + meshDS->RemoveFreeElement( elt, subMeshDS ); + } } - - SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); - while (itn->more()) { - const SMDS_MeshNode * node = itn->next(); - //MESSAGE( " RM node: "<GetID()); - if ( node->NbInverseElements() == 0 ) - meshDS->RemoveFreeNode(node, 0); - else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another - meshDS->RemoveNode(node); + int nbNodes = subMeshDS->NbNodes(); + if ( nbNodes > 0 ) + { + bool rev = true; + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes( rev ); + const SMDS_MeshNode * lastNode = itn->next(); + rev = ( lastNode->GetID() == meshDS->MaxNodeID() ); + if ( !rev ) + itn = subMeshDS->GetNodes( rev ); + else + meshDS->RemoveNode( lastNode ); + while (itn->more()) { + const SMDS_MeshNode * node = itn->next(); + if ( node->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( node, subMeshDS ); + else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another + meshDS->RemoveNode(node); + } } subMeshDS->Clear(); } @@ -1344,7 +1340,7 @@ static void cleanSubMesh( SMESH_subMesh * subMesh ) */ //============================================================================= -bool SMESH_subMesh::ComputeStateEngine(int event) +bool SMESH_subMesh::ComputeStateEngine(compute_event event) { switch ( event ) { case MODIF_ALGO_STATE: @@ -1458,6 +1454,31 @@ bool SMESH_subMesh::ComputeStateEngine(int event) _computeState = READY_TO_COMPUTE; } break; + + case COMPUTE_NOGEOM: // no geometry; can be several algos + if ( !_father->HasShapeToMesh() ) + { + algo = GetAlgo(); // current algo + if ( algo ) + { + // apply algos in the order of increasing dimension + std::list< const SMESHDS_Hypothesis * > algos = _father->GetHypothesisList( _subShape ); + for ( int t = SMESHDS_Hypothesis::ALGO_1D; t <= SMESHDS_Hypothesis::ALGO_3D; ++t ) + { + std::list::iterator al = algos.begin(); + for ( ; al != algos.end(); ++al ) + if ( (*al)->GetType() == t ) + { + _algo = (SMESH_Algo*) *al; + _computeState = READY_TO_COMPUTE; + if ( !ComputeStateEngine( COMPUTE )) + break; + } + } + _algo = algo; // restore + } + break; + } case COMPUTE: case COMPUTE_SUBMESH: { @@ -1541,7 +1562,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event) MESSAGE("std::bad_alloc thrown inside algo->Compute()"); if ( _computeError ) { _computeError->myName = COMPERR_MEMORY_PB; - //_computeError->myComment = exc.what(); } cleanSubMesh( this ); throw exc; @@ -1550,7 +1570,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event) MESSAGE("Standard_OutOfMemory thrown inside algo->Compute()"); if ( _computeError ) { _computeError->myName = COMPERR_MEMORY_PB; - //_computeError->myComment = exc.what(); } cleanSubMesh( this ); throw std::bad_alloc(); @@ -1591,7 +1610,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) ret = false; // check if anything was built TopExp_Explorer subS(shape, _subShape.ShapeType()); - if (ret) + if ( ret ) { for (; ret && subS.More(); subS.Next()) if ( !_father->GetSubMesh( subS.Current() )->IsMeshComputed() && @@ -1599,10 +1618,27 @@ bool SMESH_subMesh::ComputeStateEngine(int event) !algo->isDegenerated( TopoDS::Edge( subS.Current() )))) ret = false; } +#ifdef PRINT_WHO_COMPUTE_WHAT + for (subS.ReInit(); subS.More(); subS.Next()) + { + const std::list & hyps = + _algo->GetUsedHypothesis( *_father, _subShape ); + SMESH_Comment hypStr; + if ( !hyps.empty() ) + { + hypStr << hyps.front()->GetName() << " "; + ((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() ); + hypStr << " "; + } + cout << _algo->GetName() + << " " << _father->GetSubMesh( subS.Current() )->GetId() + << " " << hypStr << endl; + } +#endif // Set _computeError - if (!ret && !isComputeErrorSet) + if ( !ret && !isComputeErrorSet ) { - for (subS.ReInit(); subS.More(); subS.Next()) + for ( subS.ReInit(); subS.More(); subS.Next() ) { SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); if ( !sm->IsMeshComputed() ) @@ -1616,11 +1652,41 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } } } - if (ret && _computeError && _computeError->myName != COMPERR_WARNING ) + if ( ret && _computeError && _computeError->myName != COMPERR_WARNING ) { _computeError.reset(); } + // transform errors into warnings if it is caused by mesh edition (imp 0023068) + if (!ret && _father->GetIsModified() ) + { + for (subS.ReInit(); subS.More(); subS.Next()) + { + SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); + if ( !sm->IsMeshComputed() && sm->_computeError ) + { + // check if there is a VERTEX w/o nodes + // with READY_TO_COMPUTE state (after MergeNodes()) + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false); + while ( smIt->more() ) + { + SMESH_subMesh * vertSM = smIt->next(); + if ( vertSM->_subShape.ShapeType() != TopAbs_VERTEX ) break; + if ( vertSM->GetComputeState() == READY_TO_COMPUTE ) + { + SMESHDS_SubMesh * ds = vertSM->GetSubMeshDS(); + if ( !ds || ds->NbNodes() == 0 ) + { + sm->_computeState = READY_TO_COMPUTE; + sm->_computeError->myName = COMPERR_WARNING; + break; + } + } + } + } + } + } + // send event SUBMESH_COMPUTED if ( ret ) { if ( !algo->NeedDiscreteBoundary() ) @@ -1981,7 +2047,7 @@ void SMESH_subMesh::updateSubMeshState(const compute_state theState) //purpose : //======================================================================= -void SMESH_subMesh::ComputeSubMeshStateEngine(int event, const bool includeSelf) +void SMESH_subMesh::ComputeSubMeshStateEngine(compute_event event, const bool includeSelf) { SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(includeSelf,false); while ( smIt->more() ) @@ -2091,10 +2157,10 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, const TopoDS_Shape& S = subMesh->_subShape; if ( S.ShapeType() != this->_subShape.ShapeType() ) continue; - theSubs.push_back( subMesh ); if ( subMesh == this ) { aBuilder.Add( aCompound, S ); + theSubs.push_back( subMesh ); } else if ( subMesh->GetComputeState() == READY_TO_COMPUTE ) { @@ -2105,6 +2171,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, aBuilder.Add( aCompound, S ); if ( !subMesh->SubMeshesComputed() ) theSubComputed = false; + theSubs.push_back( subMesh ); } } } @@ -2150,8 +2217,6 @@ const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape& SMESH_Hypothesis::Hypothesis_Status SMESH_subMesh::CheckConcurentHypothesis (const int theHypType) { - MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis"); - // is there local hypothesis on me? if ( getSimilarAttached( _subShape, 0, theHypType ) ) return SMESH_Hypothesis::HYP_OK; @@ -2452,7 +2517,7 @@ void SMESH_subMeshEventListener::ProcessEvent(const int event, switch ( event ) { case SMESH_subMesh::CLEAN: for ( ; smIt != smEnd; ++ smIt) - (*smIt)->ComputeStateEngine( event ); + (*smIt)->ComputeStateEngine( SMESH_subMesh::compute_event( event )); break; case SMESH_subMesh::COMPUTE: case SMESH_subMesh::COMPUTE_SUBMESH: