23514: EDF 16031 - SMESH freezes

Optimize loading a study with multiple mesh groups
This commit is contained in:
eap 2017-11-30 19:51:51 +03:00
parent 70c33e5f83
commit ccb5e3c25b
8 changed files with 151 additions and 100 deletions

View File

@ -93,7 +93,7 @@ DriverMED_Family
return myType; return myType;
} }
const std::set< SMDSAbs_ElementType >& const ElemTypeSet&
DriverMED_Family DriverMED_Family
::GetTypes() const ::GetTypes() const
{ {

View File

@ -36,6 +36,7 @@
#include "SMESHDS_SubMesh.hxx" #include "SMESHDS_SubMesh.hxx"
#include "MED_Common.hxx" #include "MED_Common.hxx"
#include <boost/container/flat_set.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <set> #include <set>
#include <limits> #include <limits>
@ -62,6 +63,7 @@ typedef std::list<DriverMED_FamilyPtr > DriverMED_FamilyPtrList;
typedef std::map<int,SMESHDS_SubMesh* > SMESHDS_SubMeshPtrMap; typedef std::map<int,SMESHDS_SubMesh* > SMESHDS_SubMeshPtrMap;
typedef std::list<SMESHDS_GroupBase* > SMESHDS_GroupBasePtrList; typedef std::list<SMESHDS_GroupBase* > SMESHDS_GroupBasePtrList;
typedef std::set<const SMDS_MeshElement*,TIDCompare > ElementsSet; typedef std::set<const SMDS_MeshElement*,TIDCompare > ElementsSet;
typedef boost::container::flat_set< SMDSAbs_ElementType > ElemTypeSet;
class MESHDRIVERMED_EXPORT DriverMED_Family class MESHDRIVERMED_EXPORT DriverMED_Family
{ {
@ -113,7 +115,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
void SetType(const SMDSAbs_ElementType theType); void SetType(const SMDSAbs_ElementType theType);
SMDSAbs_ElementType GetType(); SMDSAbs_ElementType GetType();
const std::set< SMDSAbs_ElementType >& GetTypes() const; const ElemTypeSet& GetTypes() const;
bool MemberOf(std::string theGroupName) const; bool MemberOf(std::string theGroupName) const;
@ -126,8 +128,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
//! Split <theSubMesh> on some parts (families) on the basis of the elements type. //! Split <theSubMesh> on some parts (families) on the basis of the elements type.
static static
DriverMED_FamilyPtrList DriverMED_FamilyPtrList SplitByType(SMESHDS_SubMesh* theSubMesh,
SplitByType(SMESHDS_SubMesh* theSubMesh,
const int theId); const int theId);
@ -148,7 +149,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
ElementsSet myElements; ElementsSet myElements;
MED::TStringSet myGroupNames; MED::TStringSet myGroupNames;
int myGroupAttributVal; int myGroupAttributVal;
std::set<SMDSAbs_ElementType> myTypes; // Issue 0020576 ElemTypeSet myTypes; // Issue 0020576
}; };
#endif #endif

View File

@ -1092,8 +1092,8 @@ list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
set<string>::const_iterator aGrNamesIter = aGroupNames.begin(); set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++) for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
{ {
const set< SMDSAbs_ElementType >& types = aFamily->GetTypes(); const ElemTypeSet& types = aFamily->GetTypes();
set< SMDSAbs_ElementType >::const_iterator type = types.begin(); ElemTypeSet::const_iterator type = types.begin();
for ( ; type != types.end(); ++type ) for ( ; type != types.end(); ++type )
{ {
TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type ); TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type );
@ -1109,14 +1109,38 @@ list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup) void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
{ {
string aGroupName (theGroup->GetStoreName()); TFamilyVec * famVecPtr;
if ( myGroups2FamiliesMap.IsEmpty() ) // PAL23514
{
TFamilyVec famVector( 1 );
map<int, DriverMED_FamilyPtr>::iterator famIter = myFamilies.begin();
for ( ; famIter != myFamilies.end(); famIter++ )
{
DriverMED_FamilyPtr family = famIter->second;
const MED::TStringSet& groups = family->GetGroupNames();
famVector[ 0 ] = family;
MED::TStringSet::const_iterator grpIter = groups.begin();
for ( ; grpIter != groups.end(); ++grpIter )
{
TCollection_AsciiString groupName = grpIter->c_str();
if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( groupName )))
famVecPtr->push_back( family );
else
myGroups2FamiliesMap.Bind( groupName, famVector );
}
}
}
const char* aGroupName = theGroup->GetStoreName();
if(MYDEBUG) MESSAGE("Get Group " << aGroupName); if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin(); if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( aGroupName )))
for (; aFamsIter != myFamilies.end(); aFamsIter++)
{ {
DriverMED_FamilyPtr aFamily = (*aFamsIter).second; for ( size_t i = 0; i < famVecPtr->size(); ++i )
if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName)) {
DriverMED_FamilyPtr aFamily = (*famVecPtr)[i];
if ( aFamily->GetTypes().count( theGroup->GetType() ))
{ {
const ElementsSet& anElements = aFamily->GetElements(); const ElementsSet& anElements = aFamily->GetElements();
ElementsSet::const_iterator anElemsIter = anElements.begin(); ElementsSet::const_iterator anElemsIter = anElements.begin();
@ -1127,10 +1151,9 @@ void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
theGroup->SMDSGroup().Add(element); theGroup->SMDSGroup().Add(element);
} }
int aGroupAttrVal = aFamily->GetGroupAttributVal(); int aGroupAttrVal = aFamily->GetGroupAttributVal();
if( aGroupAttrVal != 0) if( aGroupAttrVal != 0 )
theGroup->SetColorGroup(aGroupAttrVal); theGroup->SetColorGroup(aGroupAttrVal);
// if ( element ) -- Issue 0020576 }
// theGroup->SetType( theGroup->SMDSGroup().GetType() );
} }
} }
} }

View File

@ -36,11 +36,16 @@
#include <list> #include <list>
#include <map> #include <map>
#include <NCollection_DataMap.hxx>
#include <TCollection_AsciiString.hxx>
class SMESHDS_Mesh; class SMESHDS_Mesh;
class SMESHDS_Group; class SMESHDS_Group;
class SMESHDS_SubMesh; class SMESHDS_SubMesh;
typedef std::vector< DriverMED_FamilyPtr > TFamilyVec;
typedef std::pair< std::string, SMDSAbs_ElementType > TNameAndType; typedef std::pair< std::string, SMDSAbs_ElementType > TNameAndType;
typedef NCollection_DataMap< TCollection_AsciiString, TFamilyVec > TName2Falilies;
class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
{ {
@ -58,7 +63,7 @@ class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
private: private:
std::string myMeshName; std::string myMeshName;
std::map<int, DriverMED_FamilyPtr> myFamilies; std::map<int, DriverMED_FamilyPtr> myFamilies;
TName2Falilies myGroups2FamiliesMap;
}; };
#endif #endif

View File

@ -23,30 +23,31 @@
// Author : Paul RASCLE, EDF // Author : Paul RASCLE, EDF
// Module : SMESH // Module : SMESH
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRep_Tool.hxx>
#include <OSD.hxx>
#include <TColStd_MapOfAsciiString.hxx>
#include <TCollection_AsciiString.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx> #include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <BRep_Tool.hxx>
#include <TCollection_AsciiString.hxx>
#include <OSD.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#ifdef WIN32 #ifdef WIN32
@ -4682,18 +4683,23 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
if ( aTopGroup->ExistInternalObject( name_group ) ) { if ( aTopGroup->ExistInternalObject( name_group ) ) {
aGroup = new HDFgroup( name_group, aTopGroup ); aGroup = new HDFgroup( name_group, aTopGroup );
aGroup->OpenOnDisk(); aGroup->OpenOnDisk();
// get number of groups // PAL23514: get all names from the HDFgroup to avoid iteration on its contents
int aNbSubObjects = aGroup->nInternalObjects(); // within aGroup->ExistInternalObject( name )
for ( int j = 0; j < aNbSubObjects; j++ ) { std::vector< std::string > subNames;
char name_dataset[ HDF_NAME_MAX_LEN+1 ]; TColStd_MapOfAsciiString mapOfNames;
aGroup->InternalObjectIndentify( j, name_dataset ); aGroup->GetAllObjects( subNames );
// check if it is an group for ( size_t iN = 0; iN < subNames.size(); ++iN )
if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) { mapOfNames.Add( subNames[ iN ].c_str() );
// loop on groups
for ( size_t j = 0; j < subNames.size(); j++ ) {
const std::string& name_dataset = subNames[ j ];
// check if it is a group
if ( name_dataset.substr( 0, 5 ) == "Group" ) {
// --> get group id // --> get group id
int subid = atoi( string( name_dataset ).substr( 5 ).c_str() ); int subid = atoi( name_dataset.substr( 5 ).c_str() );
if ( subid <= 0 ) if ( subid <= 0 )
continue; continue;
aDataset = new HDFdataset( name_dataset, aGroup ); aDataset = new HDFdataset( name_dataset.c_str(), aGroup );
aDataset->OpenOnDisk(); aDataset->OpenOnDisk();
// Retrieve actual group name // Retrieve actual group name
@ -4706,7 +4712,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
TopoDS_Shape aShape; TopoDS_Shape aShape;
char aRefName[ 30 ]; char aRefName[ 30 ];
sprintf( aRefName, "Ref on shape %d", subid); sprintf( aRefName, "Ref on shape %d", subid);
if ( aGroup->ExistInternalObject( aRefName ) ) { if ( mapOfNames.Contains( aRefName ))
{
// load mesh "Ref on shape" - it's an entry to SObject // load mesh "Ref on shape" - it's an entry to SObject
aDataset = new HDFdataset( aRefName, aGroup ); aDataset = new HDFdataset( aRefName, aGroup );
aDataset->OpenOnDisk(); aDataset->OpenOnDisk();
@ -4727,8 +4734,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
// Try to read a filter of SMESH_GroupOnFilter // Try to read a filter of SMESH_GroupOnFilter
SMESH::Filter_var filter; SMESH::Filter_var filter;
SMESH_PredicatePtr predicate; SMESH_PredicatePtr predicate;
std::string hdfGrpName = "Filter " + SMESH_Comment(subid); std::string hdfGrpName = ( SMESH_Comment( "Filter ") << subid );
if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) if ( mapOfNames.Contains( hdfGrpName.c_str() ))
{ {
aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup );
aDataset->OpenOnDisk(); aDataset->OpenOnDisk();
@ -4769,13 +4776,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
if ( !aGroupBaseDS ) if ( !aGroupBaseDS )
continue; continue;
aGroupBaseDS->SetStoreName( name_dataset ); aGroupBaseDS->SetStoreName( name_dataset.c_str() );
// ouv : NPAL12872 // ouv : NPAL12872
// Read color of the group // Read color of the group
char aGroupColorName[ 30 ]; char aGroupColorName[ 30 ];
sprintf( aGroupColorName, "ColorGroup %d", subid); sprintf( aGroupColorName, "ColorGroup %d", subid);
if ( aGroup->ExistInternalObject( aGroupColorName ) ) if ( mapOfNames.Contains( aGroupColorName ))
{ {
aDataset = new HDFdataset( aGroupColorName, aGroup ); aDataset = new HDFdataset( aGroupColorName, aGroup );
aDataset->OpenOnDisk(); aDataset->OpenOnDisk();

View File

@ -49,6 +49,7 @@
#include <TCollection_AsciiString.hxx> #include <TCollection_AsciiString.hxx>
#include <Resource_DataMapOfAsciiStringAsciiString.hxx> #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
#include <TColStd_HSequenceOfAsciiString.hxx> #include <TColStd_HSequenceOfAsciiString.hxx>
#include <NCollection_DataMap.hxx>
#include <map> #include <map>
#include <sstream> #include <sstream>
@ -61,56 +62,53 @@ class SALOME_LifeCycleCORBA;
// ========================================================== // ==========================================================
class SMESH_I_EXPORT StudyContext class SMESH_I_EXPORT StudyContext
{ {
typedef NCollection_DataMap< int, std::string > TInt2StringMap;
typedef NCollection_DataMap< int, int > TInt2IntMap;
public: public:
// constructor // constructor
StudyContext() {} StudyContext() {}
// destructor
~StudyContext()
{
mapIdToIOR.clear();
mapIdToId.clear();
}
// register object in the internal map and return its id // register object in the internal map and return its id
int addObject( std::string theIOR ) int addObject( std::string theIOR )
{ {
int nextId = getNextId(); int nextId = getNextId();
mapIdToIOR[ nextId ] = theIOR; mapIdToIOR.Bind( nextId, theIOR );
return nextId; return nextId;
} }
// find the object id in the internal map by the IOR // find the object id in the internal map by the IOR
int findId( std::string theIOR ) int findId( std::string theIOR )
{ {
std::map<int, std::string>::iterator imap; TInt2StringMap::iterator imap;
for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) { for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) {
if ( imap->second == theIOR ) if ( *imap == theIOR )
return imap->first; return imap.Iterator().Key();
} }
return 0; return 0;
} }
// get object's IOR by id // get object's IOR by id
std::string getIORbyId( const int theId ) std::string getIORbyId( const int theId )
{ {
if ( mapIdToIOR.find( theId ) != mapIdToIOR.end() ) if ( mapIdToIOR.IsBound( theId ) )
return mapIdToIOR[ theId ]; return mapIdToIOR( theId );
return std::string( "" ); return std::string();
} }
// get object's IOR by old id // get object's IOR by old id
std::string getIORbyOldId( const int theOldId ) std::string getIORbyOldId( const int theOldId )
{ {
if ( mapIdToId.find( theOldId ) != mapIdToId.end() ) if ( mapIdToId.IsBound( theOldId ) )
return getIORbyId( mapIdToId[ theOldId ] ); return getIORbyId( mapIdToId( theOldId ));
return std::string( "" ); return std::string();
} }
// maps old object id to the new one (used when restoring data) // maps old object id to the new one (used when restoring data)
void mapOldToNew( const int oldId, const int newId ) { void mapOldToNew( const int oldId, const int newId ) {
mapIdToId[ oldId ] = newId; mapIdToId.Bind( oldId, newId );
} }
// get old id by a new one // get old id by a new one
int getOldId( const int newId ) { int getOldId( const int newId ) {
std::map<int, int>::iterator imap; TInt2IntMap::iterator imap;
for ( imap = mapIdToId.begin(); imap != mapIdToId.end(); ++imap ) { for ( imap = mapIdToId.begin(); imap != mapIdToId.end(); ++imap ) {
if ( imap->second == newId ) if ( *imap == newId )
return imap->first; return imap.Iterator().Key();
} }
return 0; return 0;
} }
@ -120,13 +118,13 @@ private:
int getNextId() int getNextId()
{ {
int id = 1; int id = 1;
while( mapIdToIOR.find( id ) != mapIdToIOR.end() ) while( mapIdToIOR.IsBound( id ) )
id++; id++;
return id; return id;
} }
std::map<int, std::string> mapIdToIOR; // persistent-to-transient map TInt2StringMap mapIdToIOR; // persistent-to-transient map
std::map<int, int> mapIdToId; // to translate object from persistent to transient form TInt2IntMap mapIdToId; // to translate object from persistent to transient form
}; };
// =========================================================== // ===========================================================

View File

@ -288,9 +288,11 @@ namespace
//================================================================================ //================================================================================
void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name, void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name,
HDFgroup* hdfGroup) HDFgroup* hdfGroup,
const TColStd_MapOfAsciiString& allHdfNames)
{ {
if ( hdfGroup->ExistInternalObject( name.c_str()) ) //if ( hdfGroup->ExistInternalObject( name.c_str()) ) PAL23514
if ( allHdfNames.Contains( name.c_str() ))
{ {
HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup ); HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup );
dataset->OpenOnDisk(); dataset->OpenOnDisk();
@ -419,7 +421,17 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF()
HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile ); HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile );
infoHdfGroup->OpenOnDisk(); infoHdfGroup->OpenOnDisk();
_mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup ); // PAL23514: get all names from the HDFgroup to avoid iteration on its contents
// within aGroup->ExistInternalObject( name )
TColStd_MapOfAsciiString mapOfNames;
{
std::vector< std::string > subNames;
infoHdfGroup->GetAllObjects( subNames );
for ( size_t iN = 0; iN < subNames.size(); ++iN )
mapOfNames.Add( subNames[ iN ].c_str() );
}
_mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup, mapOfNames );
// read SMESH_PreMeshInfo of groups // read SMESH_PreMeshInfo of groups
map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin(); map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
@ -432,7 +444,7 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF()
if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() ) if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() )
{ {
const std::string name = group->GetStoreName(); const std::string name = group->GetStoreName();
group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup ); group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup, mapOfNames );
} }
} }
} }
@ -444,7 +456,9 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF()
if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second )) if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
{ {
sm->changePreMeshInfo() = newInstance(); sm->changePreMeshInfo() = newInstance();
sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), infoHdfGroup ); sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()),
infoHdfGroup,
mapOfNames );
} }
} }
} }

View File

@ -33,6 +33,7 @@
#include CORBA_SERVER_HEADER(SALOMEDS) #include CORBA_SERVER_HEADER(SALOMEDS)
#include <TopAbs_ShapeEnum.hxx> #include <TopAbs_ShapeEnum.hxx>
#include <TColStd_MapOfAsciiString.hxx>
class DriverMED_R_SMESHDS_Mesh; class DriverMED_R_SMESHDS_Mesh;
class HDFfile; class HDFfile;
@ -101,7 +102,9 @@ private:
// reading from the new study, for which SaveToFile() was called // reading from the new study, for which SaveToFile() was called
bool readPreInfoFromHDF(); bool readPreInfoFromHDF();
void hdf2meshInfo( const std::string& dataSetName, HDFgroup* infoHdfGroup ); void hdf2meshInfo( const std::string& dataSetName,
HDFgroup* infoHdfGroup,
const TColStd_MapOfAsciiString& allHdfNames);
// reading from the old study, for which SaveToFile() was not called // reading from the old study, for which SaveToFile() was not called
bool readMeshInfo(); bool readMeshInfo();