X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=eac04a4d1604fda010e7e467e0897f81f132a8b7;hp=a355866d08bcd3da95f7b7e1a4a3c400822a3271;hb=5d0b75d9d1a9935ec419e820e6dde45a665dd978;hpb=a1e66f21f0a737448968cde85063790ab9f16e6a diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index a355866d0..eac04a4d1 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 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 @@ -55,6 +55,8 @@ #include "DriverCGNS_Write.hxx" #endif +#include + #undef _Precision_HeaderFile #include #include @@ -70,11 +72,12 @@ #include "SMESH_TryCatch.hxx" // include after OCCT headers! #include "Utils_ExceptHandlers.hxx" + #ifndef WIN32 #include #include #else -#include +#include #endif using namespace std; @@ -109,7 +112,7 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESHDS_Document* theDocument): _groupId( 0 ), _nbSubShapes( 0 ) { - MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); + if(MYDEBUG) MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); _id = theLocalId; _studyId = theStudyId; _gen = theGen; @@ -176,7 +179,12 @@ namespace SMESH_Mesh::~SMESH_Mesh() { - MESSAGE("SMESH_Mesh::~SMESH_Mesh"); + if(MYDEBUG) MESSAGE("SMESH_Mesh::~SMESH_Mesh"); + + // avoid usual removal of elements while processing RemoveHypothesis( algo ) event + SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes(); + while ( smIt->more() ) + const_cast( smIt->next() )->Clear(); // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study // Notify event listeners at least that something happens @@ -226,7 +234,27 @@ SMESH_Mesh::~SMESH_Mesh() bool SMESH_Mesh::MeshExists( int meshId ) const { - return _myDocument ? _myDocument->GetMesh( meshId ) : false; + return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false; +} + +//================================================================================ +/*! + * \brief Return a mesh by id + */ +//================================================================================ + +SMESH_Mesh* SMESH_Mesh::FindMesh( int meshId ) const +{ + if ( _id == meshId ) + return (SMESH_Mesh*) this; + + if ( StudyContextStruct *aStudyContext = _gen->GetStudyContext( _studyId )) + { + std::map < int, SMESH_Mesh * >::iterator i_m = aStudyContext->mapMesh.find( meshId ); + if ( i_m != aStudyContext->mapMesh.end() ) + return i_m->second; + } + return NULL; } //============================================================================= @@ -327,8 +355,27 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape) { if ( !aShape.IsNull() ) { Bnd_Box Box; - BRepBndLib::Add(aShape, Box); - return sqrt( Box.SquareExtent() ); + // avoid too long waiting on large shapes. PreciseBoundingBox() was added + // to assure same result which else depends on presence of triangulation (IPAL52557). + const int maxNbFaces = 4000; + int nbFaces = 0; + for ( TopExp_Explorer f( aShape, TopAbs_FACE ); f.More() && nbFaces < maxNbFaces; f.Next() ) + ++nbFaces; + bool isPrecise = false; + if ( nbFaces < maxNbFaces ) + try { + GEOMUtils::PreciseBoundingBox( aShape, Box ); + isPrecise = true; + } + catch (...) { + isPrecise = false; + } + if ( !isPrecise ) + { + BRepBndLib::Add( aShape, Box ); + } + if ( !Box.IsVoid() ) + return sqrt( Box.SquareExtent() ); } return 0; } @@ -391,6 +438,7 @@ void SMESH_Mesh::Clear() sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } } + GetMeshDS()->Modified(); _isModified = false; } @@ -427,47 +475,38 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) int SMESH_Mesh::UNVToMesh(const char* theFileName) { - if(MYDEBUG) MESSAGE("UNVToMesh - theFileName = "<NbNodes() = "<<_myMeshDS->NbNodes()); - MESSAGE("UNVToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); - MESSAGE("UNVToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); - MESSAGE("UNVToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); - } - SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup(); - if (aGroup != 0) { + + if ( SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup() ) + { TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap(); - //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap(); aGroup->InitSubGroupsIterator(); - while (aGroup->MoreSubGroups()) { + while (aGroup->MoreSubGroups()) + { SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup(); string aName = aGroupNames[aSubGroup]; int aId; - - SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId ); - if ( aSMESHGroup ) { - if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<GetType(), aName.c_str(), aId )) + { SMESHDS_Group* aGroupDS = dynamic_cast( aSMESHGroup->GetGroupDS() ); if ( aGroupDS ) { aGroupDS->SetStoreName(aName.c_str()); aSubGroup->InitIterator(); const SMDS_MeshElement* aElement = 0; - while (aSubGroup->More()) { - aElement = aSubGroup->Next(); - if (aElement) { - aGroupDS->SMDSGroup().Add(aElement); - } - } + while ( aSubGroup->More() ) + if (( aElement = aSubGroup->Next() )) + aGroupDS->SMDSGroup().Add( aElement ); + if (aElement) - aGroupDS->SetType(aElement->GetType()); + aGroupDS->SetType( aElement->GetType() ); } } } @@ -477,37 +516,34 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) //======================================================================= //function : MEDToMesh -//purpose : +//purpose : //======================================================================= int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) { - if(MYDEBUG) MESSAGE("MEDToMesh - theFileName = "<NbNodes() = "<<_myMeshDS->NbNodes()); - MESSAGE("MEDToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); - MESSAGE("MEDToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); - MESSAGE("MEDToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); - } +#ifdef _DEBUG_ + SMESH_ComputeErrorPtr er = myReader.GetError(); + if ( er && !er->IsOK() ) cout << er->myComment << endl; +#endif // Reading groups (sub-meshes are out of scope of MED import functionality) list aGroupNames = myReader.GetGroupNamesAndTypes(); - if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<::iterator name_type = aGroupNames.begin(); - for ( ; name_type != aGroupNames.end(); name_type++ ) { + for ( ; name_type != aGroupNames.end(); name_type++ ) + { SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId ); if ( aGroup ) { - if(MYDEBUG) MESSAGE("MEDToMesh - group added: "<first.c_str()); SMESHDS_Group* aGroupDS = dynamic_cast( aGroup->GetGroupDS() ); if ( aGroupDS ) { aGroupDS->SetStoreName( name_type->first.c_str() ); @@ -525,21 +561,16 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) int SMESH_Mesh::STLToMesh(const char* theFileName) { - if(MYDEBUG) MESSAGE("STLToMesh - theFileName = "<NbNodes() = "<<_myMeshDS->NbNodes()); - MESSAGE("STLToMesh - _myMeshDS->NbEdges() = "<<_myMeshDS->NbEdges()); - MESSAGE("STLToMesh - _myMeshDS->NbFaces() = "<<_myMeshDS->NbFaces()); - MESSAGE("STLToMesh - _myMeshDS->NbVolumes() = "<<_myMeshDS->NbVolumes()); - } + return 1; } @@ -601,12 +632,16 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName, //============================================================================= SMESH_Hypothesis::Hypothesis_Status - SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, - int anHypId ) throw(SALOME_Exception) +SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, + int anHypId, + std::string* anError ) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis"); + if ( anError ) + anError->clear(); + SMESH_subMesh *subMesh = GetSubMesh(aSubShape); if ( !subMesh || !subMesh->GetId()) return SMESH_Hypothesis::HYP_BAD_SUBSHAPE; @@ -631,23 +666,36 @@ SMESH_Hypothesis::Hypothesis_Status } } - // shape + // shape - bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); - int event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP; + bool isAlgo = ( anHyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ); + SMESH_subMesh::algo_event event = isAlgo ? SMESH_subMesh::ADD_ALGO : SMESH_subMesh::ADD_HYP; SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); + if ( anError && SMESH_Hypothesis::IsStatusFatal(ret) && subMesh->GetComputeError() ) + *anError = subMesh->GetComputeError()->myComment; + // sub-shapes - if (!SMESH_Hypothesis::IsStatusFatal(ret) && - anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father + if ( !SMESH_Hypothesis::IsStatusFatal(ret) && + anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father { event = isAlgo ? SMESH_subMesh::ADD_FATHER_ALGO : SMESH_subMesh::ADD_FATHER_HYP; SMESH_Hypothesis::Hypothesis_Status ret2 = - subMesh->SubMeshesAlgoStateEngine(event, anHyp); + subMesh->SubMeshesAlgoStateEngine(event, anHyp, /*exitOnFatal=*/true); if (ret2 > ret) + { ret = ret2; + if ( SMESH_Hypothesis::IsStatusFatal( ret )) + { + if ( anError && subMesh->GetComputeError() ) + *anError = subMesh->GetComputeError()->myComment; + // remove anHyp + event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; + subMesh->AlgoStateEngine(event, anHyp); + } + } // check concurent hypotheses on ancestors if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) @@ -666,6 +714,7 @@ SMESH_Hypothesis::Hypothesis_Status } } HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty + GetMeshDS()->Modified(); if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); @@ -679,25 +728,23 @@ SMESH_Hypothesis::Hypothesis_Status //============================================================================= SMESH_Hypothesis::Hypothesis_Status - SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape, - int anHypId)throw(SALOME_Exception) +SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape, + int anHypId) throw( SALOME_Exception ) { Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis"); - + StudyContextStruct *sc = _gen->GetStudyContext(_studyId); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) throw SALOME_Exception(LOCALIZED("hypothesis does not exist")); - + SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId]; - if(MYDEBUG) { - SCRUTE(anHyp->GetType()); - } - + if(MYDEBUG) { SCRUTE(anHyp->GetType()); } + // shape - - bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); - int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; + + bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); + SMESH_subMesh::algo_event event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; SMESH_subMesh *subMesh = GetSubMesh(aSubShape); @@ -738,6 +785,7 @@ SMESH_Hypothesis::Hypothesis_Status } HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + GetMeshDS()->Modified(); if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); @@ -892,16 +940,19 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); const list& hypList = _myMeshDS->GetHypothesis(aSubShape); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) - if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) && - ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && - hypTypes.insert( (*hyp)->GetName() ).second ) + { + const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); + if (( aFilter.IsOk( h, aSubShape )) && + ( h->IsAuxiliary() || !mainHypFound ) && + ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second )) { aHypList.push_back( *hyp ); nbHyps++; - if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) + if ( !h->IsAuxiliary() ) mainHypFound = true; if ( assignedTo ) assignedTo->push_back( aSubShape ); } + } } // get hypos from ancestors of aSubShape @@ -918,16 +969,19 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); const list& hypList = _myMeshDS->GetHypothesis(curSh); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) - if (( aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh )) && - ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && - ( hypTypes.insert( (*hyp)->GetName() ).second )) + { + const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); + if (( aFilter.IsOk( h, curSh )) && + ( h->IsAuxiliary() || !mainHypFound ) && + ( h->IsAuxiliary() || hypTypes.insert( h->GetName() ).second )) { aHypList.push_back( *hyp ); nbHyps++; - if ( !cSMESH_Hyp(*hyp)->IsAuxiliary() ) + if ( !h->IsAuxiliary() ) mainHypFound = true; if ( assignedTo ) assignedTo->push_back( curSh ); } + } } } return nbHyps; @@ -958,7 +1012,6 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const const list & SMESH_Mesh::GetLog() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog"); return _myMeshDS->GetScript()->GetCommands(); } @@ -970,7 +1023,6 @@ const list & SMESH_Mesh::GetLog() throw(SALOME_Exception) void SMESH_Mesh::ClearLog() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog"); _myMeshDS->GetScript()->Clear(); } @@ -980,13 +1032,16 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception) */ //============================================================================= -SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) +SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) throw(SALOME_Exception) { int index = _myMeshDS->ShapeToIndex(aSubShape); + if ( !index && aSubShape.IsNull() ) + return 0; // for submeshes on GEOM Group - if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) { + if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) + { TopoDS_Iterator it( aSubShape ); if ( it.More() ) { @@ -1054,7 +1109,7 @@ throw(SALOME_Exception) //================================================================================ /*! - * \brief Return submeshes of groups containing the given sub-shape + * \brief Return sub-meshes of groups containing the given sub-shape */ //================================================================================ @@ -1068,8 +1123,8 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const if ( !subMesh ) return found; - // submeshes of groups have max IDs, so search from the map end -SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) ); + // sub-meshes of groups have max IDs, so search from the map end + SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) ); while ( smIt->more() ) { SMESH_subMesh* sm = smIt->next(); SMESHDS_SubMesh * ds = sm->GetSubMeshDS(); @@ -1095,6 +1150,12 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) ) found.push_back( mainSM ); } } + else // issue 0023068 + { + if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1) ) + if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND ) + found.push_back( mainSM ); + } return found; } //======================================================================= @@ -1132,27 +1193,6 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, return false; } -//============================================================================= -/*! - * - */ -//============================================================================= - -// const list < SMESH_subMesh * >& -// SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp) -// throw(SALOME_Exception) -// { -// _subMeshesUsingHypothesisList.clear(); -// SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); -// while ( smIt->more() ) -// { -// SMESH_subMesh* aSubMesh = smIt->next(); -// if ( IsUsedHypothesis ( anHyp, aSubMesh )) -// _subMeshesUsingHypothesisList.push_back( aSubMesh ); -// } -// return _subMeshesUsingHypothesisList; -// } - //======================================================================= //function : NotifySubMeshesHypothesisModification //purpose : Say all submeshes using theChangedHyp that it has been modified @@ -1171,48 +1211,67 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h SMESH_Algo *algo; const SMESH_HypoFilter* compatibleHypoKind; list usedHyps; - - // keep sub-meshes not to miss ones whose state can change due to notifying others vector< SMESH_subMesh* > smToNotify; + bool allMeshedEdgesNotified = true; SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); while ( smIt->more() ) { SMESH_subMesh* aSubMesh = smIt->next(); + bool toNotify = false; // if aSubMesh meshing depends on hyp, // we call aSubMesh->AlgoStateEngine( MODIF_HYP, hyp ) that causes either - // 1) clearing of already computed aSubMesh or + // 1) clearing already computed aSubMesh or // 2) changing algo_state from MISSING_HYP to HYP_OK when parameters of hyp becomes valid, // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb) - if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK && - aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE && - aSubMesh->GetAlgoState() != SMESH_subMesh::MISSING_HYP ) - continue; - - const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - - if (( aSubMesh->IsApplicableHypotesis( hyp )) && - ( algo = aSubMesh->GetAlgo() ) && - ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) && - ( compatibleHypoKind->IsOk( hyp, aSubShape ))) + if ( aSubMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK || + aSubMesh->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE || + aSubMesh->GetAlgoState() == SMESH_subMesh::MISSING_HYP || + hyp->DataDependOnParams() ) { - // check if hyp is used by algo - usedHyps.clear(); - if ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) && - find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ) + const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); + + if (( aSubMesh->IsApplicableHypotesis( hyp )) && + ( algo = aSubMesh->GetAlgo() ) && + ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) && + ( compatibleHypoKind->IsOk( hyp, aSubShape ))) { - smToNotify.push_back( aSubMesh ); + // check if hyp is used by algo + usedHyps.clear(); + toNotify = ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) && + std::find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ); } } + if ( toNotify ) + { + smToNotify.push_back( aSubMesh ); + if ( aSubMesh->GetAlgoState() == SMESH_subMesh::MISSING_HYP ) + allMeshedEdgesNotified = false; // update of algo state needed, not mesh clearing + } + else + { + if ( !aSubMesh->IsEmpty() && + aSubMesh->GetSubShape().ShapeType() == TopAbs_EDGE ) + allMeshedEdgesNotified = false; + } } + if ( smToNotify.empty() ) + return; - for ( size_t i = 0; i < smToNotify.size(); ++i ) + // if all meshed EDGEs will be notified then the notification is equivalent + // to the whole mesh clearing, which is usually faster + if ( allMeshedEdgesNotified && NbNodes() > 0 ) { - smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, - const_cast< SMESH_Hypothesis*>( hyp )); + Clear(); + } + else + { + // notify in reverse order to avoid filling the pool of IDs + for ( int i = smToNotify.size()-1; i >= 0; --i ) + smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, + const_cast< SMESH_Hypothesis*>( hyp )); } - HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty GetMeshDS()->Modified(); } @@ -1264,7 +1323,7 @@ bool SMESH_Mesh::HasModificationsToDiscard() const // return true if the next Compute() will be partial and // existing but changed elements may prevent successful re-compute bool hasComputed = false, hasNotComputed = false; -SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); + SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); while ( smIt->more() ) { const SMESH_subMesh* aSubMesh = smIt->next(); @@ -1279,6 +1338,8 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); hasNotComputed = true; if ( hasComputed && hasNotComputed) return true; + + default:; } } if ( NbNodes() < 1 ) @@ -1295,15 +1356,15 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); bool SMESH_Mesh::HasDuplicatedGroupNamesMED() { - //set aGroupNames; // Corrected for Mantis issue 0020028 + // Corrected for Mantis issue 0020028 map< SMDSAbs_ElementType, set > aGroupNames; for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { - SMESH_Group* aGroup = it->second; + SMESH_Group* aGroup = it->second; SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType(); - string aGroupName = aGroup->GetName(); - aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); - if (!aGroupNames[aType].insert(aGroupName).second) + string aGroupName = aGroup->GetName(); + aGroupName.resize( MAX_MED_GROUP_NAME_LENGTH ); + if ( !aGroupNames[aType].insert(aGroupName).second ) return true; } @@ -1325,6 +1386,8 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() * - 2D if all mesh nodes lie on XOY coordinate plane, or * - 3D in the rest cases. * If \a theAutoDimension is \c false, the space dimension is always 3. + * \param [in] theAddODOnVertices - to create 0D elements on all vertices + * \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413) * \return int - mesh index in the file */ //================================================================================ @@ -1335,7 +1398,8 @@ void SMESH_Mesh::ExportMED(const char * file, int theVersion, const SMESHDS_Mesh* meshPart, bool theAutoDimension, - bool theAddODOnVertices) + bool theAddODOnVertices, + bool theAllElemsToGroup) throw(SALOME_Exception) { SMESH_TRY; @@ -1358,6 +1422,8 @@ void SMESH_Mesh::ExportMED(const char * file, myWriter.AddGroupOfFaces(); myWriter.AddGroupOfVolumes(); } + if ( theAllElemsToGroup ) + myWriter.AddAllToGroup(); // Pass groups to writer. Provide unique group names. //set aGroupNames; // Corrected for Mantis issue 0020028 @@ -1413,7 +1479,9 @@ void SMESH_Mesh::ExportSAUV(const char *file, cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; cmd += "\""; system(cmd.c_str()); - ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1); + ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, /*theVersion=*/1, + /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false, + /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413 #ifdef WIN32 cmd = "%PYTHONBIN% "; #else @@ -1508,7 +1576,8 @@ void SMESH_Mesh::ExportSTL(const char * file, //================================================================================ void SMESH_Mesh::ExportCGNS(const char * file, - const SMESHDS_Mesh* meshDS) + const SMESHDS_Mesh* meshDS, + const char * meshName) { int res = Driver_Mesh::DRS_FAIL; #ifdef WITH_CGNS @@ -1516,6 +1585,8 @@ void SMESH_Mesh::ExportCGNS(const char * file, myWriter.SetFile( file ); myWriter.SetMesh( const_cast( meshDS )); myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); + if ( meshName && meshName[0] ) + myWriter.SetMeshName( meshName ); res = myWriter.Perform(); #endif if ( res != Driver_Mesh::DRS_OK ) @@ -1561,7 +1632,7 @@ double SMESH_Mesh::GetComputeProgress() const const std::vector& smToCompute = algo->SubMeshesToCompute(); for ( size_t i = 0; i < smToCompute.size(); ++i ) { - if ( smToCompute[i]->IsEmpty() ) + if ( smToCompute[i]->IsEmpty() || smToCompute.size() == 1 ) algoNotDoneCost += smToCompute[i]->GetComputeCost(); else algoDoneCost += smToCompute[i]->GetComputeCost(); @@ -1716,10 +1787,10 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception) +int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPolygons(); + return _myMeshDS->GetMeshInfo().NbPolygons(order); } //================================================================================ @@ -1842,6 +1913,18 @@ int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception) return _myMeshDS->NbSubMesh(); } +//================================================================================ +/*! + * \brief Returns number of meshes in the Study, that is supposed to be + * equal to SMESHDS_Document::NbMeshes() + */ +//================================================================================ + +int SMESH_Mesh::NbMeshes() const // nb meshes in the Study +{ + return _myDocument->NbMeshes(); +} + //======================================================================= //function : IsNotConformAllowed //purpose : check if a hypothesis alowing notconform mesh is present @@ -1925,8 +2008,8 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce bool SMESH_Mesh::SynchronizeGroups() { - int nbGroups = _mapGroup.size(); - const set& groups = _myMeshDS->GetGroups(); + const size_t nbGroups = _mapGroup.size(); + const set& groups = _myMeshDS->GetGroups(); set::const_iterator gIt = groups.begin(); for ( ; gIt != groups.end(); ++gIt ) { @@ -2001,7 +2084,7 @@ void SMESH_Mesh::SetCallUp( TCallUp* upCaller ) */ //============================================================================= -bool SMESH_Mesh::RemoveGroup (const int theGroupID) +bool SMESH_Mesh::RemoveGroup( const int theGroupID ) { if (_mapGroup.find(theGroupID) == _mapGroup.end()) return false; @@ -2037,11 +2120,11 @@ ostream& SMESH_Mesh::Dump(ostream& save) { int clause = 0; save << "========================== Dump contents of mesh ==========================" << endl << endl; - save << ++clause << ") Total number of nodes: \t" << NbNodes() << endl; - save << ++clause << ") Total number of edges: \t" << NbEdges() << endl; - save << ++clause << ") Total number of faces: \t" << NbFaces() << endl; - save << ++clause << ") Total number of polygons:\t" << NbPolygons() << endl; - save << ++clause << ") Total number of volumes:\t" << NbVolumes() << endl; + save << ++clause << ") Total number of nodes: \t" << NbNodes() << endl; + save << ++clause << ") Total number of edges: \t" << NbEdges() << endl; + save << ++clause << ") Total number of faces: \t" << NbFaces() << endl; + save << ++clause << ") Total number of polygons: \t" << NbPolygons() << endl; + save << ++clause << ") Total number of volumes: \t" << NbVolumes() << endl; save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl; for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic ) { @@ -2076,10 +2159,10 @@ ostream& SMESH_Mesh::Dump(ostream& save) int nb4 = NbTetras(order); int nb5 = NbPyramids(order); int nb6 = NbPrisms(order); - save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl; + save << clause << ".1) Number of " << orderStr << " hexahedrons: \t" << nb8 << endl; save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl; save << clause << ".3) Number of " << orderStr << " prisms: \t" << nb6 << endl; - save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl; + save << clause << ".4) Number of " << orderStr << " pyramids: \t" << nb5 << endl; if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) { map myVolumesMap; SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); @@ -2125,9 +2208,9 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) return aGroup; SMESH_Group* anOldGrp = (*itg).second; - SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS(); - if ( !anOldGrp || !anOldGrpDS ) + if ( !anOldGrp || !anOldGrp->GetGroupDS() ) return aGroup; + SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS(); // create new standalone group aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() ); @@ -2208,8 +2291,8 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) TopTools_ListIteratorOfListOfShape ancIt (ancList); while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType ) ancIt.Next(); - if ( ancIt.More() ) - ancList.InsertBefore( theShape, ancIt ); + if ( ancIt.More() ) ancList.InsertBefore( theShape, ancIt ); + else ancList.Append( theShape ); } } else // else added for 52457: Addition of hypotheses is 8 time longer than meshing @@ -2240,27 +2323,31 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) */ //============================================================================= - bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) const +bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) const { if ( !_mySubMeshOrder.size() || theListToSort.size() < 2) return true; bool res = false; - vector onlyOrderedList; + vector onlyOrderedList, smVec; + // collect all ordered submeshes in one list as pointers // and get their positions within theListToSort typedef vector::iterator TPosInList; map< int, TPosInList > sortedPos; TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); - TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); + TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) { const TListOfInt& listOfId = *listIdsIt; // convert sm ids to sm's - vector smVec; + smVec.clear(); TListOfInt::const_iterator idIt = listOfId.begin(); - for ( ; idIt != listOfId.end(); idIt++ ) { - if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) { + for ( ; idIt != listOfId.end(); idIt++ ) + { + if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) + { + smVec.push_back( sm ); if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->IsComplexSubmesh() ) { SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator(); @@ -2271,10 +2358,6 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) smVec.push_back( sm ); } } - else - { - smVec.push_back( sm ); - } } } // find smVec items in theListToSort @@ -2294,7 +2377,7 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) vector::iterator onlyBIt = onlyOrderedList.begin(); vector::iterator onlyEIt = onlyOrderedList.end(); - // iterate on ordered submeshes and insert them in detected positions + // iterate on ordered sub-meshes and insert them in detected positions map< int, TPosInList >::iterator i_pos = sortedPos.begin(); for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos ) *(i_pos->second) = *onlyBIt; @@ -2312,18 +2395,27 @@ bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore, const SMESH_subMesh* smAfter ) const { TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); - TListOfInt::const_iterator idBef, idAft; for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) { const TListOfInt& listOfId = *listIdsIt; - idBef = std::find( listOfId.begin(), listOfId.end(), smBefore->GetId() ); - if ( idBef != listOfId.end() ) - idAft = std::find( listOfId.begin(), listOfId.end(), smAfter->GetId() ); - if ( idAft != listOfId.end () ) - return ( std::distance( listOfId.begin(), idBef ) < - std::distance( listOfId.begin(), idAft ) ); + int iB = -1, iA = -1, i = 0; + for ( TListOfInt::const_iterator id = listOfId.begin(); id != listOfId.end(); ++id, ++i ) + { + if ( *id == smBefore->GetId() ) + { + iB = i; + if ( iA > -1 ) + return iB < iA; + } + else if ( *id == smAfter->GetId() ) + { + iA = i; + if ( iB > -1 ) + return iB < iA; + } + } } - return true; // no order imposed to given submeshes + return true; // no order imposed to given sub-meshes } //=============================================================================