X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Mesh.cxx;h=893a28aba659e6f8fbfb93475a251acddc4c0b97;hb=51540539e509f5e21439ddef0d88dba6a45a6679;hp=aac87a540f26e24a594d6c852ca88b4508e7a38d;hpb=e6d6fd4aa127fce6f9750cc84b025a333a3c78a3;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index aac87a540..ad3d733f0 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 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 @@ -57,7 +57,7 @@ #include -#undef _Precision_HeaderFile +//#undef _Precision_HeaderFile #include #include #include @@ -76,21 +76,18 @@ #ifndef WIN32 #include #include -#else +#else #include #endif -using namespace std; +#ifndef WIN32 +#include +namespace fs=boost::filesystem; +#endif // maximum stored group name length in MED file #define MAX_MED_GROUP_NAME_LENGTH 80 -#ifdef _DEBUG_ -static int MYDEBUG = 0; -#else -static int MYDEBUG = 0; -#endif - #define cSMESH_Hyp(h) static_cast(h) typedef SMESH_HypoFilter THypType; @@ -101,12 +98,11 @@ class SMESH_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< SMESH_subMesh > //============================================================================= /*! - * + * */ //============================================================================= -SMESH_Mesh::SMESH_Mesh(int theLocalId, - int theStudyId, +SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESH_Gen* theGen, bool theIsEmbeddedMode, SMESHDS_Document* theDocument): @@ -114,17 +110,34 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, { MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); _id = theLocalId; - _studyId = theStudyId; _gen = theGen; - _myDocument = theDocument; - _myMeshDS = theDocument->NewMesh(theIsEmbeddedMode,theLocalId); + _document = theDocument; + _meshDS = theDocument->NewMesh(theIsEmbeddedMode,theLocalId); _isShapeToMesh = false; _isAutoColor = false; _isModified = false; _shapeDiagonal = 0.0; _callUp = NULL; - _myMeshDS->ShapeToMesh( PseudoShape() ); + _meshDS->ShapeToMesh( PseudoShape() ); _subMeshHolder = new SubMeshHolder; + + // assure unique persistent ID + if ( _document->NbMeshes() > 1 ) + { + std::set< int > ids; + for ( _document->InitMeshesIterator(); _document->MoreMesh(); ) + { + SMESHDS_Mesh * meshDS =_document->NextMesh(); + if ( meshDS != _meshDS ) + ids.insert( meshDS->GetPersistentId() ); + } + + if ( ids.count( _meshDS->GetPersistentId() )) + { + int uniqueID = *ids.rbegin() + 1; + _meshDS->SetPersistentId( uniqueID ); + } + } } //================================================================================ @@ -135,12 +148,11 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESH_Mesh::SMESH_Mesh(): _id(-1), - _studyId(-1), _groupId( 0 ), _nbSubShapes( 0 ), _isShapeToMesh( false ), - _myDocument( 0 ), - _myMeshDS( 0 ), + _document( 0 ), + _meshDS( 0 ), _gen( 0 ), _isAutoColor( false ), _isModified( false ), @@ -155,13 +167,11 @@ namespace #ifndef WIN32 void deleteMeshDS(SMESHDS_Mesh* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; delete meshDS; } #else static void* deleteMeshDS(void* meshDS) { - //cout << "deleteMeshDS( " << meshDS << endl; SMESHDS_Mesh* m = (SMESHDS_Mesh*)meshDS; if(m) { delete m; @@ -181,30 +191,26 @@ SMESH_Mesh::~SMESH_Mesh() { MESSAGE("SMESH_Mesh::~SMESH_Mesh"); - // Unassign algorithms in order to have all SMESH_subMeshEventListenerData deleted (22874) - SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes(); - while ( smIt->more() ) { - // avoid usual removal of elements while processing RemoveHypothesis( algo ) event - const_cast( smIt->next() )->Clear(); - } - const ShapeToHypothesis & hyps = _myMeshDS->GetHypotheses(); - for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) + if ( _document ) // avoid destructing _meshDS from ~SMESH_Gen() + _document->RemoveMesh( _id ); + _document = 0; + + // remove self from studyContext + if ( _gen ) { - const TopoDS_Shape& s = s2hyps.Key(); - THypList hyps = s2hyps.ChangeValue(); // copy - THypList::const_iterator h = hyps.begin(); - for ( ; h != hyps.end(); ++h ) - if ( (*h)->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ) - RemoveHypothesis( s, (*h)->GetID() ); + StudyContextStruct * studyContext = _gen->GetStudyContext(); + studyContext->mapMesh.erase( _id ); } + _meshDS->ClearMesh(); + // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study // Notify event listeners at least that something happens if ( SMESH_subMesh * sm = GetSubMeshContaining(1)) sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); // delete groups - map < int, SMESH_Group * >::iterator itg; + std::map < int, SMESH_Group * >::iterator itg; for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) { SMESH_Group *aGroup = (*itg).second; delete aGroup; @@ -217,23 +223,13 @@ SMESH_Mesh::~SMESH_Mesh() if ( _callUp) delete _callUp; _callUp = 0; - // remove self from studyContext - if ( _gen ) - { - StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId ); - studyContext->mapMesh.erase( _id ); - } - if ( _myDocument ) - _myDocument->RemoveMesh( _id ); - _myDocument = 0; - - if ( _myMeshDS ) { - // delete _myMeshDS, in a thread in order not to block closing a study with large meshes + if ( _meshDS ) { + // delete _meshDS, in a thread in order not to block closing a study with large meshes #ifndef WIN32 - boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS )); + boost::thread aThread(boost::bind( & deleteMeshDS, _meshDS )); #else pthread_t thread; - int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_myMeshDS); + int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS); #endif } } @@ -246,7 +242,27 @@ SMESH_Mesh::~SMESH_Mesh() bool SMESH_Mesh::MeshExists( int meshId ) const { - return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false; + return _document ? bool( _document->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()) + { + std::map < int, SMESH_Mesh * >::iterator i_m = aStudyContext->mapMesh.find( meshId ); + if ( i_m != aStudyContext->mapMesh.end() ) + return i_m->second; + } + return NULL; } //============================================================================= @@ -257,24 +273,24 @@ bool SMESH_Mesh::MeshExists( int meshId ) const void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { - if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh"); + MESSAGE("SMESH_Mesh::ShapeToMesh"); if ( !aShape.IsNull() && _isShapeToMesh ) { if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change - _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) + _meshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined")); } // clear current data - if ( !_myMeshDS->ShapeToMesh().IsNull() ) + if ( !_meshDS->ShapeToMesh().IsNull() ) { // removal of a shape to mesh, delete objects referring to sub-shapes: // - sub-meshes _subMeshHolder->DeleteAll(); // - groups on geometry - map ::iterator i_gr = _mapGroup.begin(); + std::map ::iterator i_gr = _mapGroup.begin(); while ( i_gr != _mapGroup.end() ) { if ( dynamic_cast( i_gr->second->GetGroupDS() )) { - _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() ); + _meshDS->RemoveGroup( i_gr->second->GetGroupDS() ); delete i_gr->second; _mapGroup.erase( i_gr++ ); } @@ -285,7 +301,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // clear SMESHDS TopoDS_Shape aNullShape; - _myMeshDS->ShapeToMesh( aNullShape ); + _meshDS->ShapeToMesh( aNullShape ); _shapeDiagonal = 0.0; } @@ -293,9 +309,9 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) // set a new geometry if ( !aShape.IsNull() ) { - _myMeshDS->ShapeToMesh(aShape); + _meshDS->ShapeToMesh(aShape); _isShapeToMesh = true; - _nbSubShapes = _myMeshDS->MaxShapeIndex(); + _nbSubShapes = _meshDS->MaxShapeIndex(); // fill map of ancestors fillAncestorsMap(aShape); @@ -304,7 +320,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { _isShapeToMesh = false; _shapeDiagonal = 0.0; - _myMeshDS->ShapeToMesh( PseudoShape() ); + _meshDS->ShapeToMesh( PseudoShape() ); } _isModified = false; } @@ -317,7 +333,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const { - return _myMeshDS->ShapeToMesh(); + return _meshDS->ShapeToMesh(); } //======================================================================= @@ -353,10 +369,20 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape) int nbFaces = 0; for ( TopExp_Explorer f( aShape, TopAbs_FACE ); f.More() && nbFaces < maxNbFaces; f.Next() ) ++nbFaces; + bool isPrecise = false; if ( nbFaces < maxNbFaces ) - GEOMUtils::PreciseBoundingBox(aShape, Box); - else - BRepBndLib::Add( aShape, Box); + try { + OCC_CATCH_SIGNALS; + GEOMUtils::PreciseBoundingBox( aShape, Box ); + isPrecise = true; + } + catch (...) { + isPrecise = false; + } + if ( !isPrecise ) + { + BRepBndLib::Add( aShape, Box ); + } if ( !Box.IsVoid() ) return sqrt( Box.SquareExtent() ); } @@ -400,7 +426,7 @@ void SMESH_Mesh::Clear() if ( HasShapeToMesh() ) // remove all nodes and elements { // clear mesh data - _myMeshDS->ClearMesh(); + _meshDS->ClearMesh(); // update compute state of submeshes if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) @@ -421,6 +447,7 @@ void SMESH_Mesh::Clear() sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } } + GetMeshDS()->Modified(); _isModified = false; } @@ -432,7 +459,7 @@ void SMESH_Mesh::Clear() void SMESH_Mesh::ClearSubMesh(const int theShapeId) { - // clear sub-meshes; get ready to re-compute as a side-effect + // clear sub-meshes; get ready to re-compute as a side-effect if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) ) { SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, @@ -440,7 +467,7 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) while ( smIt->more() ) { sm = smIt->next(); - TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); + TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID ) // all other shapes depends on vertices so they are already cleaned sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); @@ -452,92 +479,68 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) //======================================================================= //function : UNVToMesh -//purpose : +//purpose : //======================================================================= 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) { - TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap(); - //const TGroupIdMap& aGroupId = myReader.GetGroupIdMap(); - aGroup->InitSubGroupsIterator(); - 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: "<( 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); - } - } - if (aElement) - aGroupDS->SetType(aElement->GetType()); - } - } - } + + TGroupNamesMap& aGroupNames = myReader.GetGroupNamesMap(); + TGroupNamesMap::iterator gr2names; + int anId = 1 + ( _mapGroup.empty() ? 0 : _mapGroup.rbegin()->first ); + for ( gr2names = aGroupNames.begin(); gr2names != aGroupNames.end(); ++gr2names ) + { + SMDS_MeshGroup* aGroup = gr2names->first; + const std::string& aName = gr2names->second; + SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _meshDS, aGroup->GetType() ); + aGroupDS->SMDSGroup() = std::move( *aGroup ); + aGroupDS->SetStoreName( aName.c_str() ); + AddGroup( aGroupDS ); } + return 1; } //======================================================================= //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()); + + if (SALOME::VerbosityActivated()) + { + SMESH_ComputeErrorPtr er = myReader.GetError(); + if ( er && !er->IsOK() ) std::cout << er->myComment << std::endl; } // 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++ ) { - SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId ); + std::list aGroupNames = myReader.GetGroupNamesAndTypes(); + std::list::iterator name_type = aGroupNames.begin(); + for ( ; name_type != aGroupNames.end(); name_type++ ) + { + SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str() ); 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() ); @@ -545,32 +548,31 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) } } } + + _meshDS->Modified(); + _meshDS->CompactMesh(); + return (int) status; } //======================================================================= //function : STLToMesh -//purpose : +//purpose : //======================================================================= -int SMESH_Mesh::STLToMesh(const char* theFileName) +std::string 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; + + return myReader.GetName(); } //================================================================================ @@ -589,7 +591,7 @@ int SMESH_Mesh::CGNSToMesh(const char* theFileName, #ifdef WITH_CGNS DriverCGNS_Read myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMeshId(theMeshIndex); res = myReader.Perform(); @@ -612,7 +614,7 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName, bool theMakeRequiredGroups) { DriverGMF_Read myReader; - myReader.SetMesh(_myMeshDS); + myReader.SetMesh(_meshDS); myReader.SetFile(theFileName); myReader.SetMakeRequiredGroups( theMakeRequiredGroups ); myReader.Perform(); @@ -626,17 +628,16 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName, //============================================================================= /*! - * + * */ //============================================================================= SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId, - std::string* anError ) throw(SALOME_Exception) + std::string* anError ) { - Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis"); + MESSAGE("SMESH_Mesh::AddHypothesis"); if ( anError ) anError->clear(); @@ -657,18 +658,18 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, // NOTE: this is not a correct way to check a name of hypothesis, // there should be an attribute of hypothesis saying that it can/can't // be global/local - string hypName = anHyp->GetName(); + std::string hypName = anHyp->GetName(); if ( hypName == "NotConformAllowed" ) { - if(MYDEBUG) MESSAGE( "Hypotesis can be only global" ); + MESSAGE( "Hypothesis can be only global" ); return SMESH_Hypothesis::HYP_INCOMPATIBLE; } } // 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); @@ -696,14 +697,14 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, } } - // check concurent hypotheses on ancestors - if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) + // check concurrent hypotheses on ancestors + if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !isGlobalHyp ) { SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); while ( smIt->more() ) { SMESH_subMesh* sm = smIt->next(); - if ( sm->IsApplicableHypotesis( anHyp )) { - ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() ); + if ( sm->IsApplicableHypothesis( anHyp )) { + ret2 = sm->CheckConcurrentHypothesis( anHyp ); if (ret2 > ret) { ret = ret2; break; @@ -713,48 +714,46 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape, } } HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty + GetMeshDS()->Modified(); - if(MYDEBUG) subMesh->DumpAlgoState(true); - if(MYDEBUG) SCRUTE(ret); + if(SALOME::VerbosityActivated()) subMesh->DumpAlgoState(true); + SCRUTE(ret); return ret; } //============================================================================= /*! - * + * */ //============================================================================= 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) { - Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis"); - - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); + MESSAGE("SMESH_Mesh::RemoveHypothesis"); + + StudyContextStruct *sc = _gen->GetStudyContext(); 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()); - } - - // shape - - bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); - int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; + SCRUTE(anHyp->GetType()); + + // shape + + 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); SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); // there may appear concurrent hyps that were covered by the removed hyp - if (ret < SMESH_Hypothesis::HYP_CONCURENT && - subMesh->IsApplicableHypotesis( anHyp ) && - subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK) - ret = SMESH_Hypothesis::HYP_CONCURENT; + if (ret < SMESH_Hypothesis::HYP_CONCURRENT && + subMesh->IsApplicableHypothesis( anHyp ) && + subMesh->CheckConcurrentHypothesis( anHyp ) != SMESH_Hypothesis::HYP_OK) + ret = SMESH_Hypothesis::HYP_CONCURRENT; // sub-shapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && @@ -767,14 +766,14 @@ SMESH_Hypothesis::Hypothesis_Status if (ret2 > ret) // more severe ret = ret2; - // check concurent hypotheses on ancestors - if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) ) + // check concurrent hypotheses on ancestors + if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !IsMainShape( aSubShape ) ) { SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); while ( smIt->more() ) { SMESH_subMesh* sm = smIt->next(); - if ( sm->IsApplicableHypotesis( anHyp )) { - ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() ); + if ( sm->IsApplicableHypothesis( anHyp )) { + ret2 = sm->CheckConcurrentHypothesis( anHyp ); if (ret2 > ret) { ret = ret2; break; @@ -785,23 +784,23 @@ SMESH_Hypothesis::Hypothesis_Status } HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + GetMeshDS()->Modified(); - if(MYDEBUG) subMesh->DumpAlgoState(true); - if(MYDEBUG) SCRUTE(ret); + if(SALOME::VerbosityActivated()) subMesh->DumpAlgoState(true); + SCRUTE(ret); return ret; } //============================================================================= /*! - * + * */ //============================================================================= -const list& +const std::list& SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const - throw(SALOME_Exception) { - return _myMeshDS->GetHypothesis(aSubShape); + return _meshDS->GetHypothesis(aSubShape); } //======================================================================= @@ -844,8 +843,8 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubM { const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - const list& hypList = _myMeshDS->GetHypothesis(aSubShape); - list::const_iterator hyp = hypList.begin(); + const std::list& hypList = _meshDS->GetHypothesis(aSubShape); + std::list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); if ( aFilter.IsOk( h, aSubShape)) { @@ -861,12 +860,12 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubM const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() ); SortByMeshOrder( ancestors ); - vector::const_iterator smIt = ancestors.begin(); + std::vector::const_iterator smIt = ancestors.begin(); for ( ; smIt != ancestors.end(); smIt++ ) { const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); - const list& hypList = _myMeshDS->GetHypothesis(curSh); - list::const_iterator hyp = hypList.begin(); + const std::list& hypList = _meshDS->GetHypothesis(curSh); + std::list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); if (aFilter.IsOk( h, curSh )) { @@ -890,11 +889,11 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh * aSubM */ //================================================================================ -int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors, - list< TopoDS_Shape > * assignedTo/*=0*/) const +int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, + const SMESH_HypoFilter& aFilter, + std::list & aHypList, + const bool andAncestors, + std::list< TopoDS_Shape > * assignedTo/*=0*/) const { return GetHypotheses( const_cast< SMESH_Mesh* >(this)->GetSubMesh( aSubShape ), aFilter, aHypList, andAncestors, assignedTo ); @@ -911,22 +910,22 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, */ //================================================================================ -int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, - const SMESH_HypoFilter& aFilter, - list & aHypList, - const bool andAncestors, - list< TopoDS_Shape > * assignedTo/*=0*/) const +int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, + const SMESH_HypoFilter& aFilter, + std::list & aHypList, + const bool andAncestors, + std::list< TopoDS_Shape > * assignedTo/*=0*/) const { if ( !aSubMesh ) return 0; - set hypTypes; // to exclude same type hypos from the result list + std::set< std::string > hypTypes; // to exclude same type hypos from the result list int nbHyps = 0; // only one main hypothesis is allowed bool mainHypFound = false; // fill in hypTypes - list::const_iterator hyp; + std::list::const_iterator hyp; for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) { if ( hypTypes.insert( (*hyp)->GetName() ).second ) nbHyps++; @@ -937,7 +936,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, // get hypos from aSubShape { const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - const list& hypList = _myMeshDS->GetHypothesis(aSubShape); + const std::list& hypList = _meshDS->GetHypothesis(aSubShape); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); @@ -962,11 +961,11 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() ); SortByMeshOrder( ancestors ); - vector::const_iterator smIt = ancestors.begin(); + std::vector::const_iterator smIt = ancestors.begin(); for ( ; smIt != ancestors.end(); smIt++ ) { const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); - const list& hypList = _myMeshDS->GetHypothesis(curSh); + const std::list& hypList = _meshDS->GetHypothesis(curSh); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp ); @@ -994,7 +993,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh * aSubMesh, SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const { - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); + StudyContextStruct *sc = _gen->GetStudyContext(); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) return NULL; @@ -1004,27 +1003,23 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const //============================================================================= /*! - * + * */ //============================================================================= -const list & SMESH_Mesh::GetLog() throw(SALOME_Exception) +const std::list & SMESH_Mesh::GetLog() { - Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog"); - return _myMeshDS->GetScript()->GetCommands(); + return _meshDS->GetScript()->GetCommands(); } //============================================================================= /*! - * + * */ //============================================================================= -void SMESH_Mesh::ClearLog() throw(SALOME_Exception) +void SMESH_Mesh::ClearLog() { - Unexpect aCatch(SalomeException); - if(MYDEBUG) MESSAGE("SMESH_Mesh::ClearLog"); - _myMeshDS->GetScript()->Clear(); + _meshDS->GetScript()->Clear(); } //============================================================================= @@ -1033,22 +1028,22 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception) */ //============================================================================= -SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) - throw(SALOME_Exception) +SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) { - int index = _myMeshDS->ShapeToIndex(aSubShape); + int index = _meshDS->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() ) { - index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); + index = _meshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); // fill map of Ancestors while ( _nbSubShapes < index ) - fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes )); + fillAncestorsMap( _meshDS->IndexToShape( ++_nbSubShapes )); } } // if ( !index ) @@ -1057,7 +1052,7 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index ); if ( !aSubMesh ) { - aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape); + aSubMesh = new SMESH_subMesh(index, this, _meshDS, aSubShape); _subMeshHolder->Add( index, aSubMesh ); // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes @@ -1080,51 +1075,47 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) //============================================================================= /*! - * Get the SMESH_subMesh object implementation. Dont create it, return null + * Get the SMESH_subMesh object implementation. Don't create it, return null * if it does not exist. */ //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const - throw(SALOME_Exception) { - int index = _myMeshDS->ShapeToIndex(aSubShape); + int index = _meshDS->ShapeToIndex(aSubShape); return GetSubMeshContaining( index ); } //============================================================================= /*! - * Get the SMESH_subMesh object implementation. Dont create it, return null + * Get the SMESH_subMesh object implementation. Don't create it, return null * if it does not exist. */ //============================================================================= SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const -throw(SALOME_Exception) { SMESH_subMesh *aSubMesh = _subMeshHolder->Get( aShapeID ); - return aSubMesh; } //================================================================================ /*! - * \brief Return submeshes of groups containing the given sub-shape + * \brief Return sub-meshes of groups containing the given sub-shape */ //================================================================================ -list +std::list SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const - throw(SALOME_Exception) { - list found; + std::list found; SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape); 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(); @@ -1150,6 +1141,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; } //======================================================================= @@ -1163,7 +1160,7 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, SMESH_Hypothesis* hyp = static_cast(anHyp); // check if anHyp can be used to mesh aSubMesh - if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp )) + if ( !aSubMesh || !aSubMesh->IsApplicableHypothesis( hyp )) return false; SMESH_Algo *algo = aSubMesh->GetAlgo(); @@ -1175,10 +1172,10 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, // algorithm parameter if (algo) { - // look trough hypotheses used by algo + // look through hypotheses used by algo const SMESH_HypoFilter* hypoKind; if (( hypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() ))) { - list usedHyps; + std::list usedHyps; if ( GetHypotheses( aSubMesh, *hypoKind, usedHyps, true )) return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() ); } @@ -1187,27 +1184,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 @@ -1215,62 +1191,87 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp) { - Unexpect aCatch(SalomeException); if ( !GetMeshDS()->IsUsedHypothesis( hyp )) return; - if (_callUp) - _callUp->HypothesisModified(); + smIdType nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); + if ( hyp && _callUp && !_callUp->IsLoaded() ) // for not loaded mesh (#16648) + { + _callUp->HypothesisModified( hyp->GetID(), /*updateIcons=*/true ); + nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); // after loading mesh + } 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; + std::list usedHyps; + std::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 && - !hyp->DataDependOnParams() ) - 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->IsApplicableHypothesis( 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(); + + smIdType newNbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); + if ( hyp && _callUp ) + _callUp->HypothesisModified( hyp->GetID(), newNbEntities != nbEntities ); } //============================================================================= @@ -1278,15 +1279,13 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h * Auto color functionality */ //============================================================================= -void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception) +void SMESH_Mesh::SetAutoColor(bool theAutoColor) { - Unexpect aCatch(SalomeException); _isAutoColor = theAutoColor; } -bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception) +bool SMESH_Mesh::GetAutoColor() { - Unexpect aCatch(SalomeException); return _isAutoColor; } @@ -1320,7 +1319,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(); @@ -1335,6 +1334,8 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); hasNotComputed = true; if ( hasComputed && hasNotComputed) return true; + + default:; } } if ( NbNodes() < 1 ) @@ -1343,6 +1344,41 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); return false; } +//============================================================================= +/*! + * \brief Return true if all sub-meshes are computed OK - to update an icon + */ +//============================================================================= + +bool SMESH_Mesh::IsComputedOK() +{ + if ( NbNodes() == 0 ) + return false; + + // if ( !HasShapeToMesh() ) + // return true; + + if ( SMESH_subMesh* mainSM = GetSubMeshContaining( 1 )) + { + SMESH_subMeshIteratorPtr smIt = mainSM->getDependsOnIterator(/*includeSelf=*/true); + while ( smIt->more() ) + { + const SMESH_subMesh* sm = smIt->next(); + if ( !sm->IsAlwaysComputed() ) + switch ( sm->GetComputeState() ) + { + case SMESH_subMesh::NOT_READY: + case SMESH_subMesh::COMPUTE_OK: + continue; // ok + case SMESH_subMesh::FAILED_TO_COMPUTE: + case SMESH_subMesh::READY_TO_COMPUTE: + return false; + } + } + } + return true; +} + //================================================================================ /*! * \brief Check if any groups of the same type have equal names @@ -1351,15 +1387,15 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); bool SMESH_Mesh::HasDuplicatedGroupNamesMED() { - //set aGroupNames; // Corrected for Mantis issue 0020028 - map< SMDSAbs_ElementType, set > aGroupNames; - for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) + // Corrected for Mantis issue 0020028 + std::map< SMDSAbs_ElementType, std::set< std::string > > aGroupNames; + for ( std::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) + std::string aGroupName = aGroup->GetName(); + aGroupName.resize( MAX_MED_GROUP_NAME_LENGTH ); + if ( !aGroupNames[aType].insert(aGroupName).second ) return true; } @@ -1368,126 +1404,140 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() //================================================================================ /*! - * \brief Export the mesh to a med file - * \param [in] file - name of the MED file - * \param [in] theMeshName - name of this mesh - * \param [in] theAutoGroups - boolean parameter for creating/not creating - * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; - * the typical use is auto_groups=false. - * \param [in] theVersion - defines the version of format of MED file, that will be created - * \param [in] meshPart - mesh data to export - * \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either - * - 1D if all mesh nodes lie on OX coordinate axis, or - * - 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. - * \return int - mesh index in the file + * \brief Export the mesh to a writer */ //================================================================================ -void SMESH_Mesh::ExportMED(const char * file, - const char* theMeshName, - bool theAutoGroups, - int theVersion, - const SMESHDS_Mesh* meshPart, - bool theAutoDimension, - bool theAddODOnVertices) - throw(SALOME_Exception) +void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter, + const char* theMeshName, + bool theAutoGroups, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers) { + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; + SMESH_TRY; - DriverMED_W_SMESHDS_Mesh myWriter; - myWriter.SetFile ( file, MED::EVersion(theVersion) ); - myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetAutoDimension( theAutoDimension ); - myWriter.AddODOnVertices ( theAddODOnVertices ); - if ( !theMeshName ) - myWriter.SetMeshId ( _id ); + theWriter.SetMesh ( theMeshPart ? (SMESHDS_Mesh*) theMeshPart : _meshDS ); + theWriter.SetAutoDimension( theAutoDimension ); + theWriter.AddODOnVertices ( theAddODOnVertices ); + theWriter.SetZTolerance ( theZTolerance ); + theWriter.SetSaveNumbers ( theSaveNumbers ); + if ( !theMeshName ) + theWriter.SetMeshId ( _id ); else { - myWriter.SetMeshId ( -1 ); - myWriter.SetMeshName ( theMeshName ); + theWriter.SetMeshId ( -1 ); + theWriter.SetMeshName ( theMeshName ); } if ( theAutoGroups ) { - myWriter.AddGroupOfNodes(); - myWriter.AddGroupOfEdges(); - myWriter.AddGroupOfFaces(); - myWriter.AddGroupOfVolumes(); + theWriter.AddGroupOfNodes(); + theWriter.AddGroupOfEdges(); + theWriter.AddGroupOfFaces(); + theWriter.AddGroupOfVolumes(); + theWriter.AddGroupOf0DElems(); + theWriter.AddGroupOfBalls(); } // Pass groups to writer. Provide unique group names. //set aGroupNames; // Corrected for Mantis issue 0020028 - if ( !meshPart ) + if ( !theMeshPart ) { - map< SMDSAbs_ElementType, set > aGroupNames; + std::map< SMDSAbs_ElementType, std::set > aGroupNames; char aString [256]; int maxNbIter = 10000; // to guarantee cycle finish - for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + for ( std::map::iterator it = _mapGroup.begin(); + it != _mapGroup.end(); + it++ ) { SMESH_Group* aGroup = it->second; SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); if ( aGroupDS ) { SMDSAbs_ElementType aType = aGroupDS->GetType(); - string aGroupName0 = aGroup->GetName(); + std::string aGroupName0 = aGroup->GetName(); aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH); - string aGroupName = aGroupName0; + std::string aGroupName = aGroupName0; for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) { sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); aGroupName = aString; aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); } aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); + theWriter.AddGroup( aGroupDS ); } } } // Perform export - myWriter.Perform(); + status = theWriter.Perform(); SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("MED"); } //================================================================================ /*! - * \brief Export the mesh to a SAUV file + * Same as SMESH_Mesh::ExportMED except for \a file and \a theVersion */ //================================================================================ -void SMESH_Mesh::ExportSAUV(const char *file, - const char* theMeshName, - bool theAutoGroups) - throw(SALOME_Exception) +MEDCoupling::MCAuto +SMESH_Mesh::ExportMEDCoupling(const char* theMeshName, + bool theAutoGroups, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers) { - std::string medfilename(file); - medfilename += ".med"; - std::string cmd; -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1); -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python "; -#endif - cmd += "-c \""; - cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')"; - cmd += "\""; - system(cmd.c_str()); -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); + DriverMED_W_SMESHDS_Mesh_Mem writer; + this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, + theAddODOnVertices, theZTolerance, theSaveNumbers); + return writer.getData(); +} + +//================================================================================ +/*! + * \brief Export the mesh to a med file + * \param [in] theFile - name of the MED file + * \param [in] theMeshName - name of this mesh + * \param [in] theAutoGroups - boolean parameter for creating/not creating + * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + * the typical use is auto_groups=false. + * \param [in] theVersion - define the minor (xy, where version is x.y.z) of MED file format. + * If theVersion is equal to -1, the minor version is not changed (default). + * \param [in] theMeshPart - mesh data to export + * \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either + * - 1D if all mesh nodes lie on OX coordinate axis, or + * - 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] theZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero + * within a given tolerance, the coordinate is set to zero. + * If \a ZTolerance is negative, the node coordinates are kept as is. + * \param [in] theSaveNumbers : enable saving numbers of nodes and cells. + * \return int - mesh index in the file + */ +//================================================================================ + +void SMESH_Mesh::ExportMED(const char * theFile, + const char* theMeshName, + bool theAutoGroups, + int theVersion, + const SMESHDS_Mesh* theMeshPart, + bool theAutoDimension, + bool theAddODOnVertices, + double theZTolerance, + bool theSaveNumbers) +{ + MESSAGE("MED_VERSION:"<< theVersion); + DriverMED_W_SMESHDS_Mesh writer; + writer.SetFile( theFile, theVersion ); + this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, theAddODOnVertices, theZTolerance, theSaveNumbers ); } //================================================================================ @@ -1497,14 +1547,23 @@ void SMESH_Mesh::ExportSAUV(const char *file, //================================================================================ void SMESH_Mesh::ExportDAT(const char * file, - const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) + const SMESHDS_Mesh* meshPart, + const bool renumber) { - Unexpect aCatch(SalomeException); - DriverDAT_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_id); - myWriter.Perform(); + Driver_Mesh::Status status; + SMESH_TRY; + + DriverDAT_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS ); + writer.SetMeshId(_id); + writer.SetRenumber( renumber ); + status = writer.Perform(); + + SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("DAT"); } //================================================================================ @@ -1514,28 +1573,38 @@ void SMESH_Mesh::ExportDAT(const char * file, //================================================================================ void SMESH_Mesh::ExportUNV(const char * file, - const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) + const SMESHDS_Mesh* meshPart, + const bool renumber) { - Unexpect aCatch(SalomeException); - DriverUNV_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); - myWriter.SetMeshId(_id); - // myWriter.SetGroups(_mapGroup); + Driver_Mesh::Status status; + + SMESH_TRY; + DriverUNV_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS ); + writer.SetMeshId(_id); + writer.SetRenumber( renumber ); + // pass group names to SMESHDS if ( !meshPart ) { - for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + std::map::iterator it = _mapGroup.begin(); + for ( ; it != _mapGroup.end(); it++ ) { SMESH_Group* aGroup = it->second; SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); if ( aGroupDS ) { - string aGroupName = aGroup->GetName(); + std::string aGroupName = aGroup->GetName(); aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); + writer.AddGroup( aGroupDS ); } } } - myWriter.Perform(); + status = writer.Perform(); + + SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("UNV"); } //================================================================================ @@ -1546,15 +1615,24 @@ void SMESH_Mesh::ExportUNV(const char * file, void SMESH_Mesh::ExportSTL(const char * file, const bool isascii, - const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) + const char * name, + const SMESHDS_Mesh* meshPart) { - Unexpect aCatch(SalomeException); - DriverSTL_W_SMDS_Mesh myWriter; - myWriter.SetFile( file ); - myWriter.SetIsAscii( isascii ); - myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS); - myWriter.SetMeshId(_id); - myWriter.Perform(); + Driver_Mesh::Status status; + SMESH_TRY; + + DriverSTL_W_SMDS_Mesh writer; + writer.SetFile( file ); + writer.SetIsAscii( isascii ); + writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS); + writer.SetMeshId(_id); + if ( name ) writer.SetName( name ); + status = writer.Perform(); + + SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("STL"); } //================================================================================ @@ -1564,16 +1642,47 @@ 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, + const bool groupElemsByType) { + int res = Driver_Mesh::DRS_FAIL; + SMESH_TRY; + + // pass group names to SMESHDS + std::map::iterator it = _mapGroup.begin(); + for ( ; it != _mapGroup.end(); it++ ) { + SMESH_Group* group = it->second; + SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + if ( groupDS ) { + std::string groupName = group->GetName(); + groupDS->SetStoreName( groupName.c_str() ); + } + } #ifdef WITH_CGNS - DriverCGNS_Write myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( const_cast( meshDS )); - myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); - res = myWriter.Perform(); + + DriverCGNS_Write writer; + writer.SetFile( file ); + writer.SetMesh( const_cast( meshDS )); + writer.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); + if ( meshName && meshName[0] ) + writer.SetMeshName( meshName ); + writer.SetElementsByType( groupElemsByType ); + res = writer.Perform(); + if ( res != Driver_Mesh::DRS_OK ) + { + SMESH_ComputeErrorPtr err = writer.GetError(); + if ( err && !err->IsOK() && !err->myComment.empty() ) + throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() ); + } + #endif + SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( res == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("CGNS"); + if ( res != Driver_Mesh::DRS_OK ) throw SALOME_Exception("Export failed"); } @@ -1588,12 +1697,20 @@ void SMESH_Mesh::ExportGMF(const char * file, const SMESHDS_Mesh* meshDS, bool withRequiredGroups) { - DriverGMF_Write myWriter; - myWriter.SetFile( file ); - myWriter.SetMesh( const_cast( meshDS )); - myWriter.SetExportRequiredGroups( withRequiredGroups ); + Driver_Mesh::Status status; + SMESH_TRY; + + DriverGMF_Write writer; + writer.SetFile( file ); + writer.SetMesh( const_cast( meshDS )); + writer.SetExportRequiredGroups( withRequiredGroups ); - myWriter.Perform(); + status = writer.Perform(); + + SMESH_CATCH( SMESH::throwSalomeEx ); + + if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH ) + throw TooLargeForExport("GMF"); } //================================================================================ @@ -1609,7 +1726,7 @@ double SMESH_Mesh::GetComputeProgress() const const SMESH_subMesh* curSM = _gen->GetCurrentSubMesh(); // get progress of a current algo - TColStd_MapOfInteger currentSubIds; + TColStd_MapOfInteger currentSubIds; if ( curSM ) if ( SMESH_Algo* algo = curSM->GetAlgo() ) { @@ -1617,7 +1734,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(); @@ -1630,9 +1747,8 @@ double SMESH_Mesh::GetComputeProgress() const rate = algo->GetProgress(); } catch (...) { -#ifdef _DEBUG_ - cerr << "Exception in " << algo->GetName() << "::GetProgress()" << endl; -#endif + if (SALOME::VerbosityActivated()) + std::cerr << "Exception in " << algo->GetName() << "::GetProgress()" << std::endl; } if ( 0. < rate && rate < 1.001 ) { @@ -1643,7 +1759,6 @@ double SMESH_Mesh::GetComputeProgress() const rate = algo->GetProgressByTic(); computedCost += algoDoneCost + rate * algoNotDoneCost; } - // cout << "rate: "<GetMeshInfo().NbElements() << endl; return computedCost / totalCost; } @@ -1676,10 +1788,9 @@ double SMESH_Mesh::GetComputeProgress() const */ //================================================================================ -int SMESH_Mesh::NbNodes() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbNodes() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->NbNodes(); + return _meshDS->NbNodes(); } //================================================================================ @@ -1688,10 +1799,9 @@ int SMESH_Mesh::NbNodes() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception) +smIdType SMESH_Mesh::Nb0DElements() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().Nb0DElements(); + return _meshDS->GetMeshInfo().Nb0DElements(); } //================================================================================ @@ -1700,10 +1810,9 @@ int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbEdges(order); + return _meshDS->GetMeshInfo().NbEdges(order); } //================================================================================ @@ -1712,10 +1821,9 @@ int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception */ //================================================================================ -int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbFaces(order); + return _meshDS->GetMeshInfo().NbFaces(order); } //================================================================================ @@ -1724,10 +1832,9 @@ int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception */ //================================================================================ -int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTriangles(order); + return _meshDS->GetMeshInfo().NbTriangles(order); } //================================================================================ @@ -1736,10 +1843,9 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Excep */ //================================================================================ -int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbBiQuadTriangles() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBiQuadTriangles(); + return _meshDS->GetMeshInfo().NbBiQuadTriangles(); } //================================================================================ @@ -1748,10 +1854,9 @@ int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbQuadrangles(order); + return _meshDS->GetMeshInfo().NbQuadrangles(order); } //================================================================================ @@ -1760,10 +1865,9 @@ int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exc */ //================================================================================ -int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbBiQuadQuadrangles() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles(); + return _meshDS->GetMeshInfo().NbBiQuadQuadrangles(); } //================================================================================ @@ -1772,10 +1876,9 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPolygons(); + return _meshDS->GetMeshInfo().NbPolygons(order); } //================================================================================ @@ -1784,10 +1887,9 @@ int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbVolumes(order); + return _meshDS->GetMeshInfo().NbVolumes(order); } //================================================================================ @@ -1796,10 +1898,9 @@ int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Excepti */ //================================================================================ -int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTetras(order); + return _meshDS->GetMeshInfo().NbTetras(order); } //================================================================================ @@ -1808,10 +1909,9 @@ int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exceptio */ //================================================================================ -int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbHexas(order); + return _meshDS->GetMeshInfo().NbHexas(order); } //================================================================================ @@ -1820,10 +1920,9 @@ int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception */ //================================================================================ -int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbTriQuadraticHexas() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbTriQuadHexas(); + return _meshDS->GetMeshInfo().NbTriQuadHexas(); } //================================================================================ @@ -1832,10 +1931,9 @@ int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPyramids(order); + return _meshDS->GetMeshInfo().NbPyramids(order); } //================================================================================ @@ -1844,22 +1942,31 @@ int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Except */ //================================================================================ -int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const +{ + return _meshDS->GetMeshInfo().NbPrisms(order); +} + +smIdType SMESH_Mesh::NbQuadPrisms() const +{ + return _meshDS->GetMeshInfo().NbQuadPrisms(); +} + +smIdType SMESH_Mesh::NbBiQuadPrisms() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPrisms(order); + return _meshDS->GetMeshInfo().NbBiQuadPrisms(); } + //================================================================================ /*! * \brief Return number of hexagonal prisms in the mesh */ //================================================================================ -int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbHexagonalPrisms() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbHexPrisms(); + return _meshDS->GetMeshInfo().NbHexPrisms(); } //================================================================================ @@ -1868,10 +1975,9 @@ int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbPolyhedrons() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbPolyhedrons(); + return _meshDS->GetMeshInfo().NbPolyhedrons(); } //================================================================================ @@ -1880,10 +1986,9 @@ int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbBalls() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbBalls() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->GetMeshInfo().NbBalls(); + return _meshDS->GetMeshInfo().NbBalls(); } //================================================================================ @@ -1892,10 +1997,9 @@ int SMESH_Mesh::NbBalls() const throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception) +smIdType SMESH_Mesh::NbSubMesh() const { - Unexpect aCatch(SalomeException); - return _myMeshDS->NbSubMesh(); + return _meshDS->NbSubMesh(); } //================================================================================ @@ -1907,50 +2011,61 @@ int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception) int SMESH_Mesh::NbMeshes() const // nb meshes in the Study { - return _myDocument->NbMeshes(); + return _document->NbMeshes(); } //======================================================================= //function : IsNotConformAllowed -//purpose : check if a hypothesis alowing notconform mesh is present +//purpose : check if a hypothesis allowing notconform mesh is present //======================================================================= bool SMESH_Mesh::IsNotConformAllowed() const { - if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed"); + MESSAGE("SMESH_Mesh::IsNotConformAllowed"); static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" )); - return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false ); + return GetHypothesis( _meshDS->ShapeToMesh(), filter, false ); } //======================================================================= //function : IsMainShape -//purpose : +//purpose : //======================================================================= bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const { - return theShape.IsSame(_myMeshDS->ShapeToMesh() ); + return theShape.IsSame(_meshDS->ShapeToMesh() ); +} + +//======================================================================= +//function : GetShapeByEntry +//purpose : return TopoDS_Shape by its study entry +//======================================================================= + +TopoDS_Shape SMESH_Mesh::GetShapeByEntry(const std::string& entry) const +{ + return _callUp ? _callUp->GetShapeByEntry( entry ) : TopoDS_Shape(); } //============================================================================= /*! - * + * */ //============================================================================= SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, const char* theName, - int& theId, + const int theId, const TopoDS_Shape& theShape, const SMESH_PredicatePtr& thePredicate) { - if (_mapGroup.count(_groupId)) + if ( _mapGroup.count( theId )) return NULL; - theId = _groupId; - SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape, thePredicate); + int id = ( theId < 0 ) ? _groupId : theId; + SMESH_Group* aGroup = new SMESH_Group ( id, this, theType, theName, theShape, thePredicate ); GetMeshDS()->AddGroup( aGroup->GetGroupDS() ); - _mapGroup[_groupId++] = aGroup; + _mapGroup[ id ] = aGroup; + _groupId = 1 + _mapGroup.rbegin()->first; return aGroup; } @@ -1960,12 +2075,12 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, */ //================================================================================ -SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exception) +SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) { - if ( !groupDS ) + if ( !groupDS ) throw SALOME_Exception(LOCALIZED ("SMESH_Mesh::AddGroup(): NULL SMESHDS_GroupBase")); - map ::iterator i_g = _mapGroup.find( groupDS->GetID() ); + std::map ::iterator i_g = _mapGroup.find( groupDS->GetID() ); if ( i_g != _mapGroup.end() && i_g->second ) { if ( i_g->second->GetGroupDS() == groupDS ) @@ -1987,15 +2102,15 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce /*! * \brief Creates SMESH_Groups for not wrapped SMESHDS_Groups * \retval bool - true if new SMESH_Groups have been created - * + * */ //================================================================================ bool SMESH_Mesh::SynchronizeGroups() { - int nbGroups = _mapGroup.size(); - const set& groups = _myMeshDS->GetGroups(); - set::const_iterator gIt = groups.begin(); + const size_t nbGroups = _mapGroup.size(); + const std::set& groups = _meshDS->GetGroups(); + std::set::const_iterator gIt = groups.begin(); for ( ; gIt != groups.end(); ++gIt ) { SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt; @@ -2004,7 +2119,7 @@ bool SMESH_Mesh::SynchronizeGroups() _mapGroup[_groupId] = new SMESH_Group( groupDS ); } if ( !_mapGroup.empty() ) - _groupId = _mapGroup.rbegin()->first + 1; + _groupId = 1 + _mapGroup.rbegin()->first; return nbGroups < _mapGroup.size(); } @@ -2017,7 +2132,7 @@ bool SMESH_Mesh::SynchronizeGroups() SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const { - typedef map TMap; + typedef std::map TMap; return GroupIteratorPtr( new SMDS_mapIterator( _mapGroup )); } @@ -2027,11 +2142,12 @@ SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const */ //============================================================================= -SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) +SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) const { - if (_mapGroup.find(theGroupID) == _mapGroup.end()) + std::map ::const_iterator id_grp = _mapGroup.find( theGroupID ); + if ( id_grp == _mapGroup.end() ) return NULL; - return _mapGroup[theGroupID]; + return id_grp->second; } @@ -2041,12 +2157,13 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) */ //============================================================================= -list SMESH_Mesh::GetGroupIds() const +std::list SMESH_Mesh::GetGroupIds() const { - list anIds; - for ( map::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) + std::list anIds; + std::map::const_iterator it = _mapGroup.begin(); + for ( ; it != _mapGroup.end(); it++ ) anIds.push_back( it->first ); - + return anIds; } @@ -2065,11 +2182,11 @@ 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; @@ -2084,7 +2201,7 @@ bool SMESH_Mesh::RemoveGroup (const int theGroupID) //======================================================================= //function : GetAncestors //purpose : return list of ancestors of theSubShape in the order -// that lower dimention shapes come first. +// that lower dimension shapes come first. //======================================================================= const TopTools_ListOfShape& SMESH_Mesh::GetAncestors(const TopoDS_Shape& theS) const @@ -2105,27 +2222,27 @@ 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 ) { - string orderStr = isQuadratic ? "quadratic" : "linear"; + std::string orderStr = isQuadratic ? "quadratic" : "linear"; SMDSAbs_ElementOrder order = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR; save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl; save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl; if ( NbFaces(order) > 0 ) { - int nb3 = NbTriangles(order); - int nb4 = NbQuadrangles(order); + smIdType nb3 = NbTriangles(order); + smIdType nb4 = NbQuadrangles(order); save << clause << ".1) Number of " << orderStr << " triangles: \t" << nb3 << endl; save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl; if ( nb3 + nb4 != NbFaces(order) ) { - map myFaceMap; - SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); + std::map myFaceMap; + SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator(); while( itFaces->more( ) ) { int nbNodes = itFaces->next()->NbNodes(); if ( myFaceMap.find( nbNodes ) == myFaceMap.end() ) @@ -2133,24 +2250,24 @@ ostream& SMESH_Mesh::Dump(ostream& save) myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1; } save << clause << ".3) Faces in detail: " << endl; - map ::iterator itF; + std::map ::iterator itF; for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++) - save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl; + save << "--> nb nodes: " << itF->first << " - nb elements:\t" << itF->second << endl; } } save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl; if ( NbVolumes(order) > 0 ) { - int nb8 = NbHexas(order); - int nb4 = NbTetras(order); - int nb5 = NbPyramids(order); - int nb6 = NbPrisms(order); - save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl; + smIdType nb8 = NbHexas(order); + smIdType nb4 = NbTetras(order); + smIdType nb5 = NbPyramids(order); + smIdType nb6 = NbPrisms(order); + 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(); + std::map myVolumesMap; + SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator(); while( itVolumes->more( ) ) { int nbNodes = itVolumes->next()->NbNodes(); if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() ) @@ -2158,9 +2275,9 @@ ostream& SMESH_Mesh::Dump(ostream& save) myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1; } save << clause << ".5) Volumes in detail: " << endl; - map ::iterator itV; + std::map ::iterator itV; for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++) - save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl; + save << "--> nb nodes: " << itV->first << " - nb elements:\t" << itV->second << endl; } } save << endl; @@ -2174,9 +2291,9 @@ ostream& SMESH_Mesh::Dump(ostream& save) //purpose : Returns type of mesh element with certain id //======================================================================= -SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem ) +SMDSAbs_ElementType SMESH_Mesh::GetElementType( const smIdType id, const bool iselem ) { - return _myMeshDS->GetElementType( id, iselem ); + return _meshDS->GetElementType( id, iselem ); } //============================================================================= @@ -2188,14 +2305,14 @@ SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) { SMESH_Group* aGroup = 0; - map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID ); + std::map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID ); if ( itg == _mapGroup.end() ) 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() ); @@ -2227,7 +2344,7 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) void SMESH_Mesh::ClearMeshOrder() { - _mySubMeshOrder.clear(); + _subMeshOrder.clear(); } //============================================================================= @@ -2238,7 +2355,7 @@ void SMESH_Mesh::ClearMeshOrder() void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) { - _mySubMeshOrder = theOrder; + _subMeshOrder = theOrder; } //============================================================================= @@ -2249,7 +2366,7 @@ void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const { - return _mySubMeshOrder; + return _subMeshOrder; } //============================================================================= @@ -2276,8 +2393,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 @@ -2308,29 +2425,35 @@ 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) + if ( _subMeshOrder.empty() || theListToSort.size() < 2 ) return true; - - bool res = false; - vector onlyOrderedList; - // collect all ordered submeshes in one list as pointers + + + // collect all ordered sub-meshes in smVec as pointers // and get their positions within theListToSort - typedef vector::iterator TPosInList; - map< int, TPosInList > sortedPos; + + std::vector smVec; + typedef std::vector::iterator TPosInList; + std::map< size_t, size_t > sortedPos; // index in theListToSort to order TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); - TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); - for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) + TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin(); + bool needSort = false; + for( ; listIdsIt != _subMeshOrder.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() ) { + smVec.reserve( smVec.size() + sm->GetSubMeshDS()->NbSubMeshes() ); SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator(); while ( smdsIt->more() ) { @@ -2339,35 +2462,51 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) smVec.push_back( sm ); } } - else - { - smVec.push_back( sm ); - } } } // find smVec items in theListToSort for ( size_t i = 0; i < smVec.size(); ++i ) { - TPosInList smPos = find( smBeg, smEnd, smVec[i] ); - if ( smPos != smEnd ) { - onlyOrderedList.push_back( smVec[i] ); - sortedPos[ distance( smBeg, smPos )] = smPos; + TPosInList smPos = find( smBeg, smEnd, smVec[i] ); // position in theListToSort + if ( smPos != smEnd ) + { + size_t posInList = std::distance( smBeg, smPos ); + size_t order = sortedPos.size(); + sortedPos.insert( std::make_pair( posInList, order )); + if ( posInList != order ) + needSort = true; } } } - if (onlyOrderedList.size() < 2) - return res; - res = true; + if ( ! needSort ) + return false; - vector::iterator onlyBIt = onlyOrderedList.begin(); - vector::iterator onlyEIt = onlyOrderedList.end(); + // set sm of sortedPos from theListToSort to front of orderedSM + // and the rest of theListToSort to orderedSM end - // iterate on ordered submeshes and insert them in detected positions - map< int, TPosInList >::iterator i_pos = sortedPos.begin(); - for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos ) - *(i_pos->second) = *onlyBIt; + std::vector orderedSM; + orderedSM.reserve( theListToSort.size() ); + orderedSM.resize( sortedPos.size() ); - return res; + size_t iPrev = 0; + sortedPos.insert( std::make_pair( theListToSort.size(), sortedPos.size() )); + for ( const auto & pos_order : sortedPos ) + { + const size_t& posInList = pos_order.first; + const size_t& order = pos_order.second; + if ( order < sortedPos.size() - 1 ) + orderedSM[ order ] = theListToSort[ posInList ]; + + if ( iPrev < posInList ) + orderedSM.insert( orderedSM.end(), + theListToSort.begin() + iPrev, + theListToSort.begin() + posInList ); + iPrev = posInList + 1; + } + + theListToSort.swap( orderedSM ); + + return true; } //================================================================================ @@ -2379,20 +2518,29 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) 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++) + TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin(); + for( ; listIdsIt != _subMeshOrder.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 +} //============================================================================= /*!