X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Gen_i.cxx;h=ac0b696007a2f4329b6ecf2b404d421475d5c3e9;hp=5e2316415e5ba5a74669116499403f0df5190ee6;hb=6472eab132825fec572beda8276947593f85ffa1;hpb=ef3921b2afe32874a6a266ceea8a12a30cc6f17c diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 5e2316415..ac0b69600 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 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 @@ -23,30 +23,31 @@ // Author : Paul RASCLE, EDF // Module : SMESH +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include -#include -#include #include -#include -#include -#include -#include +#include #include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include #ifdef WIN32 @@ -54,6 +55,7 @@ #include #else #include + #include // for basename function #endif #ifdef WIN32 @@ -61,12 +63,16 @@ #define LoadLib( name ) LoadLibrary( name ) #define GetProc GetProcAddress #define UnLoadLib( handle ) FreeLibrary( handle ); -#else +#else // WIN32 #define LibHandle void* - #define LoadLib( name ) dlopen( name, RTLD_LAZY ) + #ifdef DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_LOCAL ) + #else // DYNLOAD_LOCAL + #define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) + #endif // DYNLOAD_LOCAL #define GetProc dlsym #define UnLoadLib( handle ) dlclose( handle ); -#endif +#endif // WIN32 #include "SMESH_Gen_i.hxx" #include "SMESH_version.h" @@ -79,7 +85,6 @@ #include "MED_Factory.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_VertexPosition.hxx" @@ -98,6 +103,9 @@ #include "SMESH_PreMeshInfo.hxx" #include "SMESH_PythonDump.hxx" #include "SMESH_ControlsDef.hxx" + +// to pass CORBA exception through SMESH_TRY +#define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } #include "SMESH_TryCatch.hxx" // to include after OCC headers! #include CORBA_SERVER_HEADER(SMESH_Group) @@ -105,6 +113,7 @@ #include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include #include #include @@ -130,8 +139,10 @@ #include #include +#include #include #include +#include using namespace std; using SMESH::TPythonDump; @@ -146,7 +157,7 @@ static int MYDEBUG = 0; #endif // Static variables definition -GEOM::GEOM_Gen_var SMESH_Gen_i::myGeomGen = GEOM::GEOM_Gen::_nil(); +GEOM::GEOM_Gen_var SMESH_Gen_i::myGeomGen; CORBA::ORB_var SMESH_Gen_i::myOrb; PortableServer::POA_var SMESH_Gen_i::myPoa; SALOME_NamingService* SMESH_Gen_i::myNS = NULL; @@ -172,7 +183,23 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject ); return aServant; } - catch (...) { + catch (PortableServer::POA::ObjectNotActive &ex) + { + INFOS("GetServant: ObjectNotActive"); + return NULL; + } + catch (PortableServer::POA::WrongAdapter &ex) + { + INFOS("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel..."); + return NULL; + } + catch (PortableServer::POA::WrongPolicy &ex) + { + INFOS("GetServant: WrongPolicy"); + return NULL; + } + catch (...) + { INFOS( "GetServant - Unknown exception was caught!!!" ); return NULL; } @@ -231,14 +258,15 @@ SALOME_NamingService* SMESH_Gen_i::GetNS() * Get SALOME_LifeCycleCORBA object */ //============================================================================= -SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { + +SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() +{ if ( myLCC == NULL ) { myLCC = new SALOME_LifeCycleCORBA( GetNS() ); } return myLCC; } - //============================================================================= /*! * GetGeomEngine [ static ] @@ -246,18 +274,33 @@ SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { * Get GEOM::GEOM_Gen reference */ //============================================================================= -GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() { - //CCRT GEOM::GEOM_Gen_var aGeomEngine = - //CCRT GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") ); - //CCRT return aGeomEngine._retn(); - if(CORBA::is_nil(myGeomGen)) - { - Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); - myGeomGen=GEOM::GEOM_Gen::_narrow(temp); - } + +GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( bool isShaper ) +{ + Engines::EngineComponent_ptr temp = + GetLCC()->FindOrLoad_Component( isShaper ? "FactoryServer" : "FactoryServer", + isShaper ? "SHAPERSTUDY" : "GEOM" ); + myGeomGen = GEOM::GEOM_Gen::_narrow( temp ); + return myGeomGen; } +//============================================================================= +/*! + * GetGeomEngine [ static ] + * + * Get GEOM::GEOM_Gen reference + */ +//============================================================================= + +GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( GEOM::GEOM_Object_ptr go ) +{ + GEOM::GEOM_Gen_ptr gen; + if ( !CORBA::is_nil( go )) + gen = go->GetGen(); + return gen; +} + //============================================================================= /*! * SMESH_Gen_i::SMESH_Gen_i @@ -292,7 +335,10 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, _thisObj = this ; _id = myPoa->activate_object( _thisObj ); + myStudyContext = new StudyContext; + myIsEmbeddedMode = false; + myIsEnablePublish = true; myShapeReader = NULL; // shape reader mySMESHGen = this; myIsHistoricalPythonDump = true; @@ -350,11 +396,8 @@ SMESH_Gen_i::~SMESH_Gen_i() myHypCreatorMap.clear(); // Clear study contexts data - map::iterator it; - for ( it = myStudyContextMap.begin(); it != myStudyContextMap.end(); ++it ) { - delete it->second; - } - myStudyContextMap.clear(); + delete myStudyContext; + // delete shape reader if ( myShapeReader ) delete myShapeReader; @@ -372,7 +415,7 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp throw (SALOME::SALOME_Exception) { std::string aPlatformLibName; - /* It's Need to tranlate lib name for WIN32 or X platform */ + /* It's Need to translate lib name for WIN32 or X platform */ if ( theLibName && theLibName[0] != '\0' ) { int libNameLen = strlen(theLibName); @@ -382,8 +425,10 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp !strcmp( theLibName+libNameLen-3, ".so" )) { //the old format -#ifdef WIN32 +#if defined(WIN32) aPlatformLibName = std::string( theLibName+3, libNameLen-6 ) + ".dll"; +#elif defined(__APPLE__) + aPlatformLibName = std::string( theLibName, libNameLen-3 ) + ".dylib"; #else aPlatformLibName = theLibName; #endif @@ -391,11 +436,13 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp else { //try to use new format -#ifdef WIN32 +#if defined(WIN32) aPlatformLibName = theLibName; aPlatformLibName += ".dll"; +#elif defined(__APPLE__) + aPlatformLibName = std::string( "lib" ) + std::string( theLibName ) + ".dylib"; #else - aPlatformLibName = "lib" + std::string( theLibName ) + ".so"; + aPlatformLibName = std::string( "lib" ) + std::string( theLibName ) + ".so"; #endif } } @@ -413,15 +460,28 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp { // load plugin library if(MYDEBUG) MESSAGE("Loading server meshers plugin library ..."); - LibHandle libHandle = LoadLib( aPlatformLibName.c_str() ); +#ifdef WIN32 +#ifdef UNICODE + const wchar_t* path = Kernel_Utils::decode_s(aPlatformLibName); +#else + const char* path = aPlatformLibName.c_str(); +#endif +#else + const char* path = aPlatformLibName.c_str(); +#endif + LibHandle libHandle = LoadLib( path ); +#if defined(WIN32) && defined(UNICODE) + delete path; +#endif if (!libHandle) { - // report any error, if occured + // report any error, if occurred #ifndef WIN32 const char* anError = dlerror(); - throw(SALOME_Exception(anError)); + throw(SALOME_Exception( anError )); #else - throw(SALOME_Exception(LOCALIZED( "Can't load server meshers plugin library" ))); + throw(SALOME_Exception ( SMESH_Comment("Can't load meshers plugin library " ) + << aPlatformLibName)); #endif } @@ -431,7 +491,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp (GetHypothesisCreator)GetProc( libHandle, "GetHypothesisCreator" ); if (!procHandle) { - throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library"))); + throw(SALOME_Exception(SMESH_Comment("bad hypothesis plugin library") + << aPlatformLibName )); UnLoadLib(libHandle); } @@ -440,7 +501,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp aCreator = procHandle(theHypName); if (!aCreator) { - throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin"))); + throw(SALOME_Exception( SMESH_Comment( theHypName ) << " is missing from " + << aPlatformLibName)); } // map hypothesis creator to a hypothesis name myHypCreatorMap[string(theHypName)] = aCreator; @@ -475,7 +537,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName getHypothesisCreator(theHypName, theLibName, aPlatformLibName); // create a new hypothesis object, store its ref. in studyContext - myHypothesis_i = aCreator->Create(myPoa, GetCurrentStudyID(), &myGen); + myHypothesis_i = aCreator->Create(myPoa, &myGen); if (myHypothesis_i) { myHypothesis_i->SetLibName( aPlatformLibName.c_str() ); // for persistency assurance @@ -507,10 +569,10 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() // Get or create the GEOM_Client instance try { // create a new mesh object servant, store it in a map in study context - SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() ); + SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this ); // create a new mesh object if(MYDEBUG) MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); - meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); + meshServant->SetImpl( myGen.CreateMesh( myIsEmbeddedMode )); // activate the CORBA servant of Mesh SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() ); @@ -604,89 +666,145 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode() //============================================================================= /*! - * SMESH_Gen_i::SetCurrentStudy + * SMESH_Gen_i::SetEnablePublish + * + * Set enable publishing in the study + */ +//============================================================================= +void SMESH_Gen_i::SetEnablePublish( CORBA::Boolean theIsEnablePublish ) +{ + myIsEnablePublish = theIsEnablePublish; +} + +//============================================================================= +/*! + * SMESH_Gen_i::IsEnablePublish * - * Set current study + * Check enable publishing */ //============================================================================= -void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy ) +CORBA::Boolean SMESH_Gen_i::IsEnablePublish() { - setCurrentStudy( theStudy ); + return myIsEnablePublish; } -void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy, - bool theStudyIsBeingClosed) +//============================================================================= +/*! + * SMESH_Gen_i::UpdateStudy + * + * Update study (needed at switching GEOM->SMESH) + */ +//============================================================================= + +void SMESH_Gen_i::UpdateStudy() { - int curStudyId = GetCurrentStudyID(); - myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy ); - // create study context, if it doesn't exist and set current study - int studyId = GetCurrentStudyID(); - if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) - myStudyContextMap[ studyId ] = new StudyContext; - - // myCurrentStudy may be nil - if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); - SALOMEDS::SComponent_wrap GEOM_var = myCurrentStudy->FindComponent( "GEOM" ); + if ( !myStudyContext ) + myStudyContext = new StudyContext; + + SALOMEDS::Study_var aStudy = getStudyServant(); + if ( !CORBA::is_nil( aStudy ) ) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + + SALOMEDS::SComponent_wrap GEOM_var = aStudy->FindComponent( "GEOM" ); + if( !GEOM_var->_is_nil() ) + aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/false ) ); + + GEOM_var = aStudy->FindComponent( "SHAPERSTUDY" ); if( !GEOM_var->_is_nil() ) - aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine() ); + aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/true ) ); + // NPAL16168, issue 0020210 // Let meshes update their data depending on GEOM groups that could change - if ( curStudyId != studyId ) - { - CORBA::String_var compDataType = ComponentDataType(); - SALOMEDS::SComponent_wrap me = myCurrentStudy->FindComponent( compDataType.in() ); - if ( !me->_is_nil() ) { - SALOMEDS::ChildIterator_wrap anIter = myCurrentStudy->NewChildIterator( me ); - for ( ; anIter->More(); anIter->Next() ) { - SALOMEDS::SObject_wrap so = anIter->Value(); - CORBA::Object_var ior = SObjectToObject( so ); - if ( SMESH_Mesh_i* mesh = SMESH::DownCast( ior )) - mesh->CheckGeomModif(); - } + CORBA::String_var compDataType = ComponentDataType(); + SALOMEDS::SComponent_wrap me = aStudy->FindComponent( compDataType.in() ); + if ( !me->_is_nil() ) { + SALOMEDS::ChildIterator_wrap anIter = aStudy->NewChildIterator( me ); + for ( ; anIter->More(); anIter->Next() ) { + SALOMEDS::SObject_wrap so = anIter->Value(); + CORBA::Object_var ior = SObjectToObject( so ); + if ( SMESH_Mesh_i* mesh = SMESH::DownCast( ior )) + mesh->CheckGeomModif(); } } } } -//============================================================================= +//================================================================================ /*! - * SMESH_Gen_i::GetCurrentStudy - * - * Get current study + * \brief Return true if mesh has ICON_SMESH_TREE_GEOM_MODIF icon */ -//============================================================================= +//================================================================================ + +bool SMESH_Gen_i::isGeomModifIcon( SMESH::SMESH_Mesh_ptr mesh ) +{ + SALOMEDS::SObject_wrap so = ObjectToSObject( mesh ); + SALOMEDS::GenericAttribute_wrap attr; + if ( ! so->_is_nil() && so->FindAttribute( attr.inout(), "AttributePixMap" )) + { + SALOMEDS::AttributePixMap_wrap pm = attr; + CORBA::String_var ico = pm->GetPixMap(); + return ( strcmp( ico.in(), "ICON_SMESH_TREE_GEOM_MODIF" ) == 0 ); + } + return false; +} + +//================================================================================= +// function : hasObjectInfo() +// purpose : shows if module provides information for its objects +//================================================================================= + +bool SMESH_Gen_i::hasObjectInfo() +{ + return true; +} + +//================================================================================= +// function : getObjectInfo() +// purpose : returns an information for a given object by its entry +//================================================================================= -SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy() +char* SMESH_Gen_i::getObjectInfo( const char* entry ) { - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetCurrentStudy: study Id = " << GetCurrentStudyID() ); - if ( GetCurrentStudyID() < 0 ) - return SALOMEDS::Study::_nil(); - return SALOMEDS::Study::_duplicate( myCurrentStudy ); + // for a mesh with icon == ICON_SMESH_TREE_GEOM_MODIF show a warning; + // for the rest, "module 'SMESH', ID=0:1:2:*" + + SMESH_Comment txt; + + SALOMEDS::SObject_wrap so = getStudyServant()->FindObjectID( entry ); + CORBA::Object_var obj = SObjectToObject( so ); + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj ); + if ( isGeomModifIcon( mesh )) + { + txt << "The geometry was changed and the mesh needs to be recomputed"; + } + + if ( txt.empty() ) + { + CORBA::String_var compType = ComponentDataType(); + txt << "module '" << compType << "', ID=" << entry; + } + return CORBA::string_dup( txt ); } //============================================================================= /*! - * SMESH_Gen_i::GetCurrentStudyContext + * SMESH_Gen_i::GetStudyContext * - * Get current study context + * Get study context */ //============================================================================= -StudyContext* SMESH_Gen_i::GetCurrentStudyContext() +StudyContext* SMESH_Gen_i::GetStudyContext() { - if ( !CORBA::is_nil( myCurrentStudy ) && - myStudyContextMap.find( GetCurrentStudyID() ) != myStudyContextMap.end() ) - return myStudyContextMap[ myCurrentStudy->StudyId() ]; - else - return 0; + return myStudyContext; } //============================================================================= /*! * SMESH_Gen_i::CreateHypothesis * - * Create hypothesis/algorothm of given type and publish it in the study + * Create hypothesis/algorithm of given type and publish it in the study */ //============================================================================= @@ -700,7 +818,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam // Publish hypothesis/algorithm in the study if ( CanPublishInStudy( hyp ) ) { - SALOMEDS::SObject_wrap aSO = PublishHypothesis( myCurrentStudy, hyp ); + SALOMEDS::SObject_wrap aSO = PublishHypothesis( hyp ); if ( !aSO->_is_nil() ) { // Update Python script TPythonDump() << aSO << " = " << this << ".CreateHypothesis('" @@ -711,6 +829,43 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam return hyp._retn(); } +//================================================================================ +/*! + * \brief Return a hypothesis initialized by given average length. + * \param theHypType - hypothesis type name + * \param theLibName - plugin library name + * \param theAverageLength - average length + * \param theQuadDominated - is quad-dominated flag + * \retval SMESH::SMESH_Hypothesis_ptr - the new hypothesis + */ +//================================================================================ + +SMESH::SMESH_Hypothesis_ptr +SMESH_Gen_i::CreateHypothesisByAverageLength( const char* theHypType, + const char* theLibName, + CORBA::Double theAverageLength, + CORBA::Boolean theQuadDominated) + throw ( SALOME::SALOME_Exception ) +{ + SMESH::HypInitParams initParams = { ::SMESH_Hypothesis::BY_AVERAGE_LENGTH, + theAverageLength, theQuadDominated }; + + SMESH::SMESH_Hypothesis_var hyp = + GetHypothesisParameterValues( theHypType, theLibName, + SMESH::SMESH_Mesh::_nil(), + GEOM::GEOM_Object::_nil(), + initParams ); + SALOMEDS::SObject_wrap so = PublishHypothesis( hyp ); + + TPythonDump() << hyp << " = " << this << ".CreateHypothesisByAverageLength( '" + << theHypType << "', '" + << theLibName << "', " + << theAverageLength << ", " + << theQuadDominated << " )"; + + return hyp._retn(); +} + //================================================================================ /*! * \brief Return a hypothesis holding parameter values corresponding either to the mesh @@ -726,14 +881,16 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam //================================================================================ SMESH::SMESH_Hypothesis_ptr -SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, - const char* theLibName, - SMESH::SMESH_Mesh_ptr theMesh, - GEOM::GEOM_Object_ptr theGeom, - CORBA::Boolean byMesh) +SMESH_Gen_i::GetHypothesisParameterValues( const char* theHypType, + const char* theLibName, + SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theGeom, + const SMESH::HypInitParams& theParams) throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); + + const bool byMesh = ( theParams.way == ::SMESH_Hypothesis::BY_MESH ); if ( byMesh && CORBA::is_nil( theMesh ) ) return SMESH::SMESH_Hypothesis::_nil(); if ( byMesh && CORBA::is_nil( theGeom ) ) @@ -788,17 +945,24 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, if ( hyp->SetParametersByMesh( mesh, shape )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); } - else { - double diagonal = 0; - if ( mesh ) - diagonal = mesh->GetShapeDiagonalSize(); - else - diagonal = ::SMESH_Mesh::GetShapeDiagonalSize( shape ); + else + { ::SMESH_Hypothesis::TDefaults dflts; - dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation(); - dflts._nbSegments = myGen.GetDefaultNbSegments(); - dflts._shape = &shape; - // let the temporary hypothesis initialize it's values + dflts._way = ( ::SMESH_Hypothesis::InitWay) theParams.way; + dflts._nbSegments = myGen.GetDefaultNbSegments(); + dflts._elemLength = theParams.averageLength; + dflts._quadDominated = theParams.quadDominated; + if ( theParams.way == ::SMESH_Hypothesis::BY_GEOM ) + { + if ( mesh ) + dflts._diagonal = mesh->GetShapeDiagonalSize(); + else + dflts._diagonal = ::SMESH_Mesh::GetShapeDiagonalSize( shape ); + dflts._elemLength = dflts._diagonal / myGen.GetBoundaryBoxSegmentation(); + dflts._shape = &shape; + } + + // let the hypothesis initialize it's values if ( hyp->SetParametersByDefaults( dflts, mesh )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); } @@ -825,12 +989,12 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr SMESH::SMESH_Mesh_out theMesh, GEOM::GEOM_Object_out theShape) { - if ( GetCurrentStudyID() < 0 || CORBA::is_nil( theHyp )) + if ( CORBA::is_nil( theHyp )) return false; // get Mesh component SO CORBA::String_var compDataType = ComponentDataType(); - SALOMEDS::SComponent_wrap comp = myCurrentStudy->FindComponent( compDataType.in() ); + SALOMEDS::SComponent_wrap comp = getStudyServant()->FindComponent( compDataType.in() ); if ( CORBA::is_nil( comp )) return false; @@ -838,7 +1002,7 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr SMESH::SMESH_Mesh_var foundMesh; TopoDS_Shape foundShape; bool isSole = true; - SALOMEDS::ChildIterator_wrap meshIter = myCurrentStudy->NewChildIterator( comp ); + SALOMEDS::ChildIterator_wrap meshIter = getStudyServant()->NewChildIterator( comp ); for ( ; meshIter->More() && isSole; meshIter->Next() ) { SALOMEDS::SObject_wrap curSO = meshIter->Value(); @@ -876,10 +1040,17 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr { if ( !foundMesh->_is_nil() ) // not a sole mesh { - GEOM::GEOM_Object_var s1 = mesh_i ->GetShapeToMesh(); - GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh(); - if ( ! ( isSole = s1->IsSame( s2 ))) - break; + if ( !foundMesh->HasShapeToMesh() || + !mesh_i ->HasShapeToMesh() ) + { + isSole = ( foundMesh->HasShapeToMesh() == mesh_i->HasShapeToMesh() ); + } + else + { + GEOM::GEOM_Object_var s1 = mesh_i ->GetShapeToMesh(); + GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh(); + isSole = s1->IsSame( s2 ); + } } foundMesh = SMESH::SMESH_Mesh::_narrow( obj ); } @@ -953,16 +1124,16 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value) { vector color; string str = value; - // color must be presented as a string of next form: + // color must be presented as a string of following form: if ( str.at(0) == '#' && str.length() == 7 ) { // hexadecimal color ("#ffaa00", for example) str = str.substr(1); for ( size_t i = 0; i < str.length()/2; i++ ) if ( str.at(i*2) >= '0' && str.at(i*2) <= 'f' && str.at(i*2+1) >= '0' && str.at(i*2+1) <= 'f' ) color.push_back( strtol( str.substr( i*2, 2 ).c_str(), NULL, 16 ) ); } - else { // rgb color ("255,170,0", for example) - char* tempValue = strdup( value ); - char* colorValue = strtok( tempValue, "," ); + else if ( value ) { // rgb color ("255,170,0", for example) + string tempValue( value ); + char* colorValue = strtok( &tempValue[0], "," ); while ( colorValue != NULL ) { int c_value = atoi( colorValue ); if ( c_value >= 0 && c_value <= 255 ) @@ -1037,9 +1208,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj // publish mesh in the study if ( CanPublishInStudy( mesh ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( mesh.in() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -1068,9 +1239,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh() // publish mesh in the study if ( CanPublishInStudy( mesh ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( mesh.in() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -1123,9 +1294,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName string aFileName; // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( aMesh.in(), aFileName.c_str() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -1162,7 +1333,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa _splitpath( theFileNameForPython, NULL, NULL, bname, NULL ); string aFileName = bname; #else - string aFileName = basename( theFileNameForPython ); + string aFileName = basename( const_cast(theFileNameForPython) ); #endif // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; @@ -1181,11 +1352,9 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa if (theStatus == SMESH::DRS_OK) { SALOMEDS::StudyBuilder_var aStudyBuilder; - if ( GetCurrentStudyID() > -1 ) - { - aStudyBuilder = myCurrentStudy->NewBuilder(); - aStudyBuilder->NewCommand(); // There is a transaction - } + aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + aResult->length( aNames.size() ); int i = 0; @@ -1204,12 +1373,12 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV // - as names of meshes are stored in MED file, we use them for data publishing // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data - aSO = PublishMesh( myCurrentStudy, mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() ); + aSO = PublishMesh( mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() ); + + // Python Dump if ( !aSO->_is_nil() ) { - // Python Dump aPythonDump << aSO; } else { - // Python Dump aPythonDump << "mesh_" << i; } @@ -1271,7 +1440,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, #ifdef WIN32 cmd = "%PYTHONBIN% "; #else - cmd = "python "; + cmd = "python3 "; #endif cmd += "-c \""; cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')"; @@ -1281,7 +1450,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, #ifdef WIN32 cmd = "%PYTHONBIN% "; #else - cmd = "python "; + cmd = "python3 "; #endif cmd += "-c \""; cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; @@ -1311,14 +1480,13 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName _splitpath( theFileName, NULL, NULL, bname, NULL ); string aFileName = bname; #else - string aFileName = basename( theFileName ); + string aFileName = basename( const_cast(theFileName) ); #endif // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_wrap aSO = PublishInStudy - ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); + SALOMEDS::SObject_wrap aSO = PublishInStudy( SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -1366,7 +1534,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, if (theStatus == SMESH::DRS_OK) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction int i = 0; @@ -1394,7 +1562,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, // publish mesh in the study SALOMEDS::SObject_wrap aSO; if ( CanPublishInStudy( mesh ) ) - aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() ); + aSO = PublishMesh( mesh.in(), meshName.c_str() ); // Python Dump if ( !aSO->_is_nil() ) { @@ -1440,14 +1608,13 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, _splitpath( theFileName, NULL, NULL, bname, NULL ); string aFileName = bname; #else - string aFileName = basename( theFileName ); + string aFileName = basename( const_cast(theFileName) ); #endif // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_wrap aSO = PublishInStudy - ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); + SALOMEDS::SObject_wrap aSO = PublishInStudy( SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -1514,16 +1681,17 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) { if ( algo ) { - if ( !myCurrentStudy->_is_nil() ) { + SALOMEDS::Study_var aStudy = getStudyServant(); + if ( !aStudy->_is_nil() ) { // find algo in the study CORBA::String_var compDataType = ComponentDataType(); - SALOMEDS::SComponent_wrap father = myCurrentStudy->FindComponent( compDataType.in() ); + SALOMEDS::SComponent_wrap father = aStudy->FindComponent( compDataType.in() ); if ( !father->_is_nil() ) { - SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( father ); + SALOMEDS::ChildIterator_wrap itBig = aStudy->NewChildIterator( father ); for ( ; itBig->More(); itBig->Next() ) { SALOMEDS::SObject_wrap gotBranch = itBig->Value(); if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) { - SALOMEDS::ChildIterator_wrap algoIt = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap algoIt = aStudy->NewChildIterator( gotBranch ); for ( ; algoIt->More(); algoIt->Next() ) { SALOMEDS::SObject_wrap algoSO = algoIt->Value(); CORBA::Object_var algoIOR = SObjectToObject( algoSO ); @@ -1603,7 +1771,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr else { errStruct.algoName = error->myAlgo->GetName(); } - errStruct.hasBadMesh = !error->myBadElements.empty(); + errStruct.hasBadMesh = error->HasBadElems(); } } error_array->length( nbErr ); @@ -1645,7 +1813,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, { // compute error SMESH_ComputeErrorPtr error = sm->GetComputeError(); - if ( error && !error->myBadElements.empty()) + if ( error && error->HasBadElems() ) { typedef map TNode2LocalIDMap; typedef TNode2LocalIDMap::iterator TNodeLocalID; @@ -1655,8 +1823,10 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, list< TNodeLocalID > connectivity; int i, nbElements = 0, nbConnNodes = 0; - list::iterator elemIt = error->myBadElements.begin(); - list::iterator elemEnd = error->myBadElements.end(); + const list& badElems = + static_cast( error.get() )->myBadElements; + list::const_iterator elemIt = badElems.begin(); + list::const_iterator elemEnd = badElems.end(); for ( ; elemIt != elemEnd; ++elemIt, ++nbElements ) { SMDS_ElemIteratorPtr nIt = (*elemIt)->nodesIterator(); @@ -1683,7 +1853,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, } // fill element types result->elementTypes.length( nbElements ); - for ( i = 0, elemIt = error->myBadElements.begin(); i elementTypes[i].SMDS_ElementType = (SMESH::ElementType) elem->GetType(); @@ -1737,7 +1907,7 @@ SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, //================================================================================ /*! - * \brief Returns errors of hypotheses definintion + * \brief Returns errors of hypotheses definition * \param theMesh - the mesh * \param theSubObject - the main or sub- shape * \retval SMESH::algo_error_array* - sequence of errors @@ -1902,11 +2072,14 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, try { // get mesh servant - SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh ); ASSERT( meshServant ); if ( meshServant ) { - meshServant->Load(); - // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + if ( isGeomModifIcon( theMesh )) + meshServant->Clear(); + else + meshServant->Load(); + // NPAL16168: "geometrical group edition from a submesh don't modify mesh computation" meshServant->CheckGeomModif(); // get local TopoDS_Shape TopoDS_Shape myLocShape; @@ -1916,10 +2089,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, myLocShape = SMESH_Mesh::PseudoShape(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - myGen.PrepareCompute( myLocMesh, myLocShape); - bool ok = myGen.Compute( myLocMesh, myLocShape); + myGen.PrepareCompute( myLocMesh, myLocShape ); + int how = ::SMESH_Gen::COMPACT_MESH; + if ( myLocShape != myLocMesh.GetShapeToMesh() ) // compute a sub-mesh + how |= ::SMESH_Gen::SHAPE_ONLY; + bool ok = myGen.Compute( myLocMesh, myLocShape, how ); meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) myLocMesh.GetMeshDS()->Modified(); + UpdateIcons( theMesh ); + if ( ok ) + HighLightInvalid( theMesh, /*isInvalid=*/false ); return ok; } } @@ -1946,14 +2125,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) { - SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); - ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - TopoDS_Shape myLocShape; - if(theMesh->HasShapeToMesh()) - myLocShape = GeomObjectToShape( theShapeObject ); - else - myLocShape = SMESH_Mesh::PseudoShape(); - myGen.CancelCompute( myLocMesh, myLocShape); + if ( SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() )) + { + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + TopoDS_Shape myLocShape; + if(theMesh->HasShapeToMesh()) + myLocShape = GeomObjectToShape( theShapeObject ); + else + myLocShape = SMESH_Mesh::PseudoShape(); + myGen.CancelCompute( myLocMesh, myLocShape); + } } //============================================================================= @@ -1988,7 +2169,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { - // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + // NPAL16168: "geometrical group edition from a submesh don't modify mesh computation" meshServant->CheckGeomModif(); // get local TopoDS_Shape TopoDS_Shape myLocShape; @@ -2001,7 +2182,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); TSetOfInt shapeIds; ::MeshDimension aDim = (MeshDimension)theDimension; - if ( myGen.Compute( myLocMesh, myLocShape, false, false, aDim, &shapeIds ) ) + if ( myGen.Compute( myLocMesh, myLocShape, ::SMESH_Gen::COMPACT_MESH, aDim, &shapeIds ) ) { int nbShapeId = shapeIds.size(); theShapesId.length( nbShapeId ); @@ -2185,7 +2366,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, ASSERT( meshServant ); if ( meshServant ) { meshServant->Load(); - // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + // NPAL16168: "geometrical group edition from a submesh don't modify mesh computation" meshServant->CheckGeomModif(); // get local TopoDS_Shape TopoDS_Shape myLocShape; @@ -2253,19 +2434,19 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_wrap geom = FindGeometryByMeshElement(theMesh, theElementID); if ( !geom->_is_nil() ) { GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); - GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine(); + GEOM::GEOM_Gen_var geomGen = GetGeomEngine( geom ); // try to find the corresponding SObject - SALOMEDS::SObject_wrap SObj = ObjectToSObject( myCurrentStudy, geom.in() ); + SALOMEDS::SObject_wrap SObj = ObjectToSObject( geom.in() ); if ( SObj->_is_nil() ) // submesh can be not found even if published { // try to find published submesh GEOM::ListOfLong_var list = geom->GetSubShapeIndices(); if ( !geom->IsMainShape() && list->length() == 1 ) { - SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape ); + SALOMEDS::SObject_wrap mainSO = ObjectToSObject( mainShape ); SALOMEDS::ChildIterator_wrap it; if ( !mainSO->_is_nil() ) { - it = myCurrentStudy->NewChildIterator( mainSO ); + it = getStudyServant()->NewChildIterator( mainSO ); } if ( !it->_is_nil() ) { for ( it->InitEx(true); it->More(); it->Next() ) { @@ -2284,8 +2465,8 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } } } - if ( SObj->_is_nil() ) // publish a new subshape - SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape ); + if ( SObj->_is_nil() && !geomGen->_is_nil() ) // publish a new subshape + SObj = geomGen->AddInStudy( geom, theGeomName, mainShape ); // return only published geometry if ( !SObj->_is_nil() ) { @@ -2317,7 +2498,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM ); GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); - GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine(); + GEOM::GEOM_Gen_var geomGen = GetGeomEngine( mainShape ); // get a core mesh DS SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh ); @@ -2333,14 +2514,14 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_var geom = ShapeToGeomObject( meshDS->IndexToShape( shapeID )); if ( geom->_is_nil() ) { // try to find a published sub-shape - SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape ); + SALOMEDS::SObject_wrap mainSO = ObjectToSObject( mainShape ); SALOMEDS::ChildIterator_wrap it; if ( !mainSO->_is_nil() ) { - it = myCurrentStudy->NewChildIterator( mainSO ); + it = getStudyServant()->NewChildIterator( mainSO ); } if ( !it->_is_nil() ) { for ( it->InitEx(true); it->More(); it->Next() ) { - SALOMEDS::SObject_wrap so = it->Value(); + SALOMEDS::SObject_wrap so = it->Value(); CORBA::Object_var obj = SObjectToObject( so ); GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj ); if ( !subGeom->_is_nil() ) { @@ -2355,8 +2536,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } if ( geom->_is_nil() ) { // explode - GEOM::GEOM_IShapesOperations_wrap op = - geomGen->GetIShapesOperations( GetCurrentStudyID() ); + GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations(); if ( !op->_is_nil() ) geom = op->GetSubShape( mainShape, shapeID ); } @@ -2385,14 +2565,16 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) + CORBA::Double theMergeTolerance, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) throw ( SALOME::SALOME_Exception ) { return ConcatenateCommon(theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - false); + false, + theMeshToAppendTo); } //================================================================================ @@ -2408,14 +2590,16 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) + CORBA::Double theMergeTolerance, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) throw ( SALOME::SALOME_Exception ) { return ConcatenateCommon(theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - true); + true, + theMeshToAppendTo); } //================================================================================ @@ -2431,284 +2615,271 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance, - CORBA::Boolean theCommonGroups) + CORBA::Boolean theCommonGroups, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) throw ( SALOME::SALOME_Exception ) { - typedef list TListOfNewGroups; - typedef map< pair, TListOfNewGroups > TGroupsMap; - - TPythonDump* pPythonDump = new TPythonDump; - TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods + std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump ); + TPythonDump& pythonDump = *pPythonDump; // prevent dump of called methods - // create mesh - SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh(); - - if ( aNewMesh->_is_nil() ) - return aNewMesh._retn(); + // create mesh if theMeshToAppendTo not provided + SMESH::SMESH_Mesh_var newMesh; + if ( CORBA::is_nil( theMeshToAppendTo )) + newMesh = CreateEmptyMesh(); + else + newMesh = SMESH::SMESH_Mesh::_duplicate( theMeshToAppendTo ); + SMESH_Mesh_i* newImpl = SMESH::DownCast( newMesh ); + if ( !newImpl ) return newMesh._retn(); + newImpl->Load(); - SMESH_Mesh_i* aNewImpl = SMESH::DownCast( aNewMesh ); - if ( !aNewImpl ) - return aNewMesh._retn(); + ::SMESH_Mesh& locMesh = newImpl->GetImpl(); + SMESHDS_Mesh* newMeshDS = locMesh.GetMeshDS(); - ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl(); - SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS(); + typedef std::list TListOfNewGroups; + typedef std::pair TNameAndType; + typedef std::map< TNameAndType, TListOfNewGroups > TGroupsMap; + TGroupsMap groupsMap; + TListOfNewGroups listOfNewGroups; - TGroupsMap aGroupsMap; - TListOfNewGroups aListOfNewGroups; - ::SMESH_MeshEditor aNewEditor(&aLocMesh); - SMESH::ListOfGroups_var aListOfGroups; + if ( !CORBA::is_nil( theMeshToAppendTo )) + { + // fill groupsMap with existing groups + SMESH::ListOfGroups_var groups = theMeshToAppendTo->GetGroups(); + for ( CORBA::ULong i = 0; i < groups->length(); ++i ) + { + SMESH::SMESH_Group_var group = SMESH::SMESH_Group::_narrow( groups[ i ]); + if ( !group->_is_nil() ) + { + CORBA::String_var name = group->GetName(); + SMESH::ElementType type = group->GetType(); + groupsMap[ TNameAndType( name.in(), type ) ].push_back( group ); + } + } + } - ::SMESH_MeshEditor::ElemFeatures elemType; - std::vector aNodesArray; + ::SMESH_MeshEditor newEditor( &locMesh ); + ::SMESH_MeshEditor::ElemFeatures elemType; // loop on sub-meshes - for ( CORBA::ULong i = 0; i < theMeshesArray.length(); i++) + for ( CORBA::ULong i = 0; i < theMeshesArray.length(); i++ ) { if ( CORBA::is_nil( theMeshesArray[i] )) continue; - SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]->GetMesh(); - if ( anInitMesh->_is_nil() ) continue; - SMESH_Mesh_i* anInitImpl = SMESH::DownCast( anInitMesh ); - if ( !anInitImpl ) continue; - anInitImpl->Load(); + SMESH::SMESH_Mesh_var initMesh = theMeshesArray[i]->GetMesh(); + SMESH_Mesh_i* initImpl = SMESH::DownCast( initMesh ); + if ( !initImpl ) continue; + if ( initMesh->_is_equivalent( theMeshToAppendTo )) + continue; + initImpl->Load(); - //::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl(); - //SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS(); + // assure that IDs increment by one during iteration + ::SMESH_Mesh& initLocMesh = initImpl->GetImpl(); + SMESHDS_Mesh* initMeshDS = initLocMesh.GetMeshDS(); + if ( initMeshDS->MaxNodeID() > initMeshDS->NbNodes() || + initMeshDS->MaxElementID() > initMeshDS->NbElements() ) + { + initMeshDS->Modified(); + initMeshDS->CompactMesh(); + } // remember nb of elements before filling in - SMESH::long_array_var prevState = aNewMesh->GetNbElementsByType(); + SMESH::long_array_var prevState = newMesh->GetNbElementsByType(); + + // copy nodes - typedef std::map TEEMap; - TEEMap elemsMap, nodesMap; + std::vector< const SMDS_MeshElement* > newNodes( initMeshDS->NbNodes() + 1, 0 ); + SMDS_ElemIteratorPtr elemIt = initImpl->GetElements( theMeshesArray[i], SMESH::NODE ); + while ( elemIt->more() ) + { + SMESH_NodeXYZ node = elemIt->next(); + newNodes[ node->GetID() ] = newMeshDS->AddNode( node.X(), node.Y(), node.Z() ); + } - // loop on elements of a sub-mesh - SMDS_ElemIteratorPtr itElems = anInitImpl->GetElements( theMeshesArray[i], SMESH::ALL ); - const SMDS_MeshElement* anElem; - const SMDS_MeshElement* aNewElem; - const SMDS_MeshNode* aNode; - const SMDS_MeshNode* aNewNode; - int anElemNbNodes; + // copy elements - while ( itElems->more() ) + SMESH::array_of_ElementType_var srcElemTypes = theMeshesArray[i]->GetTypes(); + if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes + continue; + std::vector< const SMDS_MeshElement* > newElems( initMeshDS->NbElements() + 1, 0 ); + elemIt = initImpl->GetElements( theMeshesArray[i], SMESH::ALL ); + while ( elemIt->more() ) { - anElem = itElems->next(); - anElemNbNodes = anElem->NbNodes(); - aNodesArray.resize( anElemNbNodes ); + const SMDS_MeshElement* elem = elemIt->next(); + elemType.myNodes.resize( elem->NbNodes() ); - // loop on nodes of an element - SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator(); + SMDS_NodeIteratorPtr itNodes = elem->nodeIterator(); for ( int k = 0; itNodes->more(); k++) { - aNode = static_cast( itNodes->next() ); - TEEMap::iterator n2nnIt = nodesMap.find( aNode ); - if ( n2nnIt == nodesMap.end() ) - { - aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); - nodesMap.insert( make_pair( aNode, aNewNode )); - } - else - { - aNewNode = static_cast( n2nnIt->second ); - } - aNodesArray[k] = aNewNode; + const SMDS_MeshNode* node = itNodes->next(); + elemType.myNodes[ k ] = static_cast< const SMDS_MeshNode*> ( newNodes[ node->GetID() ]); } // creates a corresponding element on existent nodes in new mesh - if ( anElem->GetType() == SMDSAbs_Node ) - aNewElem = 0; - else - aNewElem = - aNewEditor.AddElement( aNodesArray, elemType.Init( anElem, /*basicOnly=*/false )); - - if ( aNewElem ) - elemsMap.insert( make_pair( anElem, aNewElem )); - - } //elems loop - - aNewEditor.ClearLastCreated(); // forget the history + newElems[ elem->GetID() ] = + newEditor.AddElement( elemType.myNodes, elemType.Init( elem, /*basicOnly=*/false )); + } + newEditor.ClearLastCreated(); // forget the history // create groups of just added elements - SMESH::SMESH_Group_var aNewGroup; - SMESH::ElementType aGroupType; + SMESH::SMESH_Group_var newGroup; + SMESH::ElementType groupType; if ( theCommonGroups ) { - SMESH::long_array_var curState = aNewMesh->GetNbElementsByType(); + // type names + const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" }; + { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed: + const int nbNames = sizeof(typeNames) / sizeof(const char*); + int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0; + } + + SMESH::long_array_var curState = newMesh->GetNbElementsByType(); - for( aGroupType = SMESH::NODE; - aGroupType < SMESH::NB_ELEMENT_TYPES; - aGroupType = (SMESH::ElementType)( aGroupType + 1 )) + for( groupType = SMESH::NODE; + groupType < SMESH::NB_ELEMENT_TYPES; + groupType = (SMESH::ElementType)( groupType + 1 )) { - if ( curState[ aGroupType ] <= prevState[ aGroupType ]) - continue; + if ( curState[ groupType ] <= prevState[ groupType ]) + continue; // no elements of groupType added from the i-th mesh // make a group name - const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" }; - { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed: - const int nbNames = sizeof(typeNames) / sizeof(const char*); - int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]; - } - string groupName = "Gr"; - SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] ); - if ( aMeshSObj ) { - CORBA::String_var name = aMeshSObj->GetName(); + std::string groupName = "Gr"; + SALOMEDS::SObject_wrap meshSO = ObjectToSObject( theMeshesArray[i] ); + if ( meshSO ) { + CORBA::String_var name = meshSO->GetName(); groupName += name; } groupName += "_"; - groupName += typeNames[ aGroupType ]; + groupName += typeNames[ groupType ]; // make and fill a group - TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap; - aNewGroup = aNewImpl->CreateGroup( aGroupType, groupName.c_str() ); - if ( SMESH_Group_i* grp_i = SMESH::DownCast( aNewGroup )) + newGroup = newImpl->CreateGroup( groupType, groupName.c_str() ); + std::vector< const SMDS_MeshElement* > & elemVec = + ( groupType == SMESH::NODE ) ? newNodes : newElems; + if ( SMESH_Group_i* grp_i = SMESH::DownCast( newGroup )) { if ( SMESHDS_Group* grpDS = dynamic_cast( grp_i->GetGroupDS() )) { - TEEMap::iterator e2neIt = e2neMap.begin(); - for ( ; e2neIt != e2neMap.end(); ++e2neIt ) + for ( size_t j = 0; j < elemVec.size(); ++j ) { - aNewElem = e2neIt->second; - if ( aNewElem->GetType() == grpDS->GetType() ) - { - grpDS->Add( aNewElem ); - - if ( prevState[ aGroupType ]++ >= curState[ aGroupType ] ) - break; - } + if ( elemVec[j] && elemVec[j]->GetType() == grpDS->GetType() ) + grpDS->Add( elemVec[j] ); } } } - aListOfNewGroups.clear(); - aListOfNewGroups.push_back(aNewGroup); - aGroupsMap.insert(make_pair( make_pair(groupName, aGroupType), aListOfNewGroups )); + listOfNewGroups.clear(); + listOfNewGroups.push_back( newGroup ); + groupsMap.insert( std::make_pair( TNameAndType( groupName, groupType ), + listOfNewGroups )); } } - if ( SMESH_Mesh_i* anSrcImpl = SMESH::DownCast( theMeshesArray[i] )) + if ( SMESH_Mesh_i* initImpl = SMESH::DownCast( theMeshesArray[i] )) { - // copy orphan nodes - if ( anSrcImpl->NbNodes() > (int)nodesMap.size() ) - { - SMDS_ElemIteratorPtr itNodes = anInitImpl->GetElements( theMeshesArray[i], SMESH::NODE ); - while ( itNodes->more() ) - { - const SMDS_MeshNode* aNode = static_cast< const SMDS_MeshNode* >( itNodes->next() ); - if ( aNode->NbInverseElements() == 0 ) - { - aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); - nodesMap.insert( make_pair( aNode, aNewNode )); - } - } - } - // copy groups - SMESH::SMESH_GroupBase_ptr aGroup; - CORBA::String_var aGroupName; - SMESH::long_array_var anNewIDs = new SMESH::long_array(); + SMESH::SMESH_GroupBase_ptr group; + CORBA::String_var groupName; + SMESH::long_array_var newIDs = new SMESH::long_array(); // loop on groups of a source mesh - aListOfGroups = anSrcImpl->GetGroups(); - for ( CORBA::ULong iG = 0; iG < aListOfGroups->length(); iG++ ) + SMESH::ListOfGroups_var listOfGroups = initImpl->GetGroups(); + for ( CORBA::ULong iG = 0; iG < listOfGroups->length(); iG++ ) { - aGroup = aListOfGroups[iG]; - aGroupType = aGroup->GetType(); - aGroupName = aGroup->GetName(); - string aName = aGroupName.in(); + group = listOfGroups[iG]; + groupType = group->GetType(); + groupName = group->GetName(); + std::string name = groupName.in(); // convert a list of IDs - anNewIDs->length( aGroup->Size() ); - TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap; - SMDS_ElemIteratorPtr itGrElems = anSrcImpl->GetElements( aGroup, SMESH::ALL ); - int iElem = 0; + newIDs->length( group->Size() ); + std::vector< const SMDS_MeshElement* > & elemVec = + ( groupType == SMESH::NODE ) ? newNodes : newElems; + SMDS_ElemIteratorPtr itGrElems = initImpl->GetElements( group, SMESH::ALL ); + int nbElems = 0; while ( itGrElems->more() ) { - anElem = itGrElems->next(); - TEEMap::iterator e2neIt = e2neMap.find( anElem ); - if ( e2neIt != e2neMap.end() ) - anNewIDs[ iElem++ ] = e2neIt->second->GetID(); + const SMDS_MeshElement* elem = itGrElems->next(); + const SMDS_MeshElement* newElem = elemVec[ elem->GetID() ]; + if ( newElem ) + newIDs[ nbElems++ ] = newElem->GetID(); } - anNewIDs->length( iElem ); + newIDs->length( nbElems ); - // check a current group name and type don't have identical ones in final mesh - aListOfNewGroups.clear(); - TGroupsMap::iterator anIter = aGroupsMap.find( make_pair( aName, aGroupType )); - if ( anIter == aGroupsMap.end() ) { + // check that a current group name and type don't have identical ones in final mesh + listOfNewGroups.clear(); + TNameAndType nameAndType( name, groupType ); + TGroupsMap::iterator anIter = groupsMap.find( nameAndType ); + if ( anIter == groupsMap.end() ) + { // add a new group in the mesh - aNewGroup = aNewImpl->CreateGroup( aGroupType, aGroupName.in() ); - // add elements into new group - aNewGroup->Add( anNewIDs ); + newGroup = newImpl->CreateGroup( groupType, groupName.in() ); + newGroup->Add( newIDs ); - aListOfNewGroups.push_back(aNewGroup); - aGroupsMap.insert(make_pair( make_pair(aName, aGroupType), aListOfNewGroups )); + listOfNewGroups.push_back( newGroup ); + groupsMap.insert( std::make_pair( nameAndType, listOfNewGroups )); } - - else if ( theUniteIdenticalGroups ) { + else if ( theUniteIdenticalGroups ) + { // unite identical groups TListOfNewGroups& aNewGroups = anIter->second; - aNewGroups.front()->Add( anNewIDs ); + aNewGroups.front()->Add( newIDs ); } - - else { + else + { // rename identical groups - aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName.in()); - aNewGroup->Add( anNewIDs ); + newGroup = newImpl->CreateGroup( groupType, groupName ); + newGroup->Add( newIDs ); - TListOfNewGroups& aNewGroups = anIter->second; - string aNewGroupName; - if (aNewGroups.size() == 1) { - aNewGroupName = aName + "_1"; - aNewGroups.front()->SetName(aNewGroupName.c_str()); + TListOfNewGroups& newGroups = anIter->second; + std::string newGroupName; + if ( newGroups.size() == 1 ) + { + newGroupName = name + "_1"; + newGroups.front()->SetName( newGroupName.c_str() ); } - char aGroupNum[128]; - sprintf(aGroupNum, "%u", (unsigned int)aNewGroups.size()+1); - aNewGroupName = aName + "_" + string(aGroupNum); - aNewGroup->SetName(aNewGroupName.c_str()); - aNewGroups.push_back(aNewGroup); + newGroupName = name + "_" + SMESH_Comment( newGroups.size() + 1 ); + newGroup->SetName( newGroupName.c_str() ); + newGroups.push_back( newGroup ); } - } //groups loop + } // loop on groups } // if an IDSource is a mesh } //meshes loop - if (theMergeNodesAndElements) // merge nodes + if ( theMergeNodesAndElements ) // merge nodes { - TIDSortedNodeSet aMeshNodes; // no input nodes - SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; - aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes, - /*SeparateCornersAndMedium=*/ false ); - aNewEditor.MergeNodes( aGroupsOfNodes ); + TIDSortedNodeSet meshNodes; // no input nodes == treat all + SMESH_MeshEditor::TListOfListOfNodes groupsOfNodes; + newEditor.FindCoincidentNodes( meshNodes, theMergeTolerance, groupsOfNodes, + /*SeparateCornersAndMedium=*/ false ); + newEditor.MergeNodes( groupsOfNodes ); // merge elements - aNewEditor.MergeEqualElements(); + newEditor.MergeEqualElements(); } // Update Python script - aPythonDump << aNewMesh << " = " << this << "." - << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) - << "(["; - for ( CORBA::ULong i = 0; i < theMeshesArray.length(); i++) { - if (i > 0) aPythonDump << ", "; - aPythonDump << theMeshesArray[i]; - } - aPythonDump << "], "; - aPythonDump << theUniteIdenticalGroups << ", " - << theMergeNodesAndElements << ", " - << TVar( theMergeTolerance ) << ")"; + pythonDump << newMesh << " = " << this + << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "( " + << theMeshesArray << ", " + << theUniteIdenticalGroups << ", " + << theMergeNodesAndElements << ", " + << TVar( theMergeTolerance ) << ", " + << theMeshToAppendTo << " )"; - delete pPythonDump; // enable python dump from GetGroups() + pPythonDump.reset(); // enable python dump from GetGroups() // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups - if ( !aNewMesh->_is_nil() ) + if ( !newMesh->_is_nil() ) { - SMESH::ListOfGroups_var groups = aNewMesh->GetGroups(); + SMESH::ListOfGroups_var groups = newMesh->GetGroups(); } // IPAL21468 Change icon of compound because it need not be computed. - SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh ); - SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" ); + SALOMEDS::SObject_wrap meshSO = ObjectToSObject( newMesh ); + SetPixMap( meshSO, "ICON_SMESH_TREE_MESH" ); - if (aNewMeshDS) - aNewMeshDS->Modified(); + newMeshDS->Modified(); - return aNewMesh._retn(); + return newMesh._retn(); } //================================================================================ @@ -2726,10 +2897,12 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, const char* meshName, CORBA::Boolean toCopyGroups, CORBA::Boolean toKeepIDs) + throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh() + std::unique_ptr pyDumpDeleter( pyDump ); // 1. Get source mesh @@ -2749,7 +2922,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh ); if ( !newMesh_i ) THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR ); - SALOMEDS::SObject_wrap meshSO = ObjectToSObject(myCurrentStudy, newMesh ); + SALOMEDS::SObject_wrap meshSO = ObjectToSObject( newMesh ); if ( !meshSO->_is_nil() ) { SetName( meshSO, meshName, "Mesh" ); @@ -2932,7 +3105,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, << toCopyGroups << ", " << toKeepIDs << ")"; - delete pyDump; pyDump = 0; // allow dump in GetGroups() + pyDumpDeleter.reset(); // allow dump in GetGroups() if ( nbNewGroups > 0 ) // dump created groups SMESH::ListOfGroups_var groups = newMesh->GetGroups(); @@ -2940,40 +3113,1036 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, return newMesh._retn(); } -//================================================================================ -/*! - * SMESH_Gen_i::GetMEDVersion - * - * Get MED version of the file by its name - */ -//================================================================================ -CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName, - SMESH::MED_VERSION& theVersion) -{ - theVersion = SMESH::MED_V2_1; - MED::EVersion aVersion = MED::GetVersionId( theFileName ); - switch( aVersion ) { - case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true; - case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true; - case MED::eVUnknown : return false; - } - return false; -} -//================================================================================ -/*! - * SMESH_Gen_i::GetMeshNames - * - * Get names of meshes defined in file with the specified name - */ -//================================================================================ -SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName) +namespace // utils for CopyMeshWithGeom() { - SMESH::string_array_var aResult = new SMESH::string_array(); - MED::PWrapper aMed = MED::CrWrapper( theFileName ); - MED::TErr anErr; - MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr ); - if( anErr >= 0 ) { + typedef std::map< std::string, std::string > TStr2StrMap; + typedef std::map< std::string, std::set< std::string > > TStr2StrSetMap; + typedef std::map< std::set, int > TIdSet2IndexMap; + typedef std::map< std::string, int > TName2IndexMap; + + //================================================================================ + /*! + * \brief Return a new sub-shape corresponding to an old one + */ + //================================================================================ + + struct ShapeMapper + { + SMESH_Mesh_i* mySrcMesh_i; + SMESH_Mesh_i* myNewMesh_i; + SMESH_Gen_i* myGen_i; + bool myToPublish; + bool myIsSameGeom; + + TStr2StrMap myOld2NewEntryMap; // map of study entries + + GEOM::ListOfGO_var mySubshapes; // sub-shapes existing in the new geometry + TIdSet2IndexMap myIds2SubshapeIndex; // to find an existing sub-shape + TName2IndexMap myName2SubshapeIndex; // to find an existing sub-shape by name + + bool myGIPMapDone; + GEOM::ListOfListOfLong_var myGIPMap; // filled by GetInPlaceMap() + + // not directly relating to shape search + TStr2StrSetMap myInvalidMap; // blame shape -> invalid objects + + //================================================================================ + /*! + * \brief Constructor + */ + ShapeMapper( SMESH_Mesh_i* srcMesh_i, + SMESH_Mesh_i* newMesh_i, + SMESH_Gen_i* smeshGen_i ) + : mySrcMesh_i( srcMesh_i ), + myNewMesh_i( newMesh_i ), + myGen_i ( smeshGen_i ), + myToPublish( smeshGen_i->IsEnablePublish() ), + myGIPMapDone( false ) + { + // retrieve from the study shape mapping made thanks to + // "Set presentation parameters and sub-shapes from arguments" option + + GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh(); + GEOM::GEOM_Object_var mainShapeOld = mySrcMesh_i->GetShapeToMesh(); + SALOMEDS::SObject_wrap oldSO = myGen_i->ObjectToSObject( mainShapeOld ); + SALOMEDS::SObject_wrap newSO = myGen_i->ObjectToSObject( mainShapeNew ); + if ( newSO->_is_nil() ) + { + myToPublish = false; + return; + } + if (( myIsSameGeom = mainShapeNew->_is_equivalent( mainShapeOld ))) + return; + CORBA::String_var oldEntry = oldSO->GetID(); + CORBA::String_var newEntry = newSO->GetID(); + myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ), + std::string( newEntry.in() ))); + std::string newMainEntry = newEntry.in(); + + SALOMEDS::Study_var study = myGen_i->getStudyServant(); + GEOM::GEOM_Gen_var geomGen = myGen_i->GetGeomEngine( mainShapeNew ); + GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations(); + mySubshapes = op->GetExistingSubObjects( mainShapeNew, + /*groupsOnly=*/false ); + for ( CORBA::ULong i = 0; i < mySubshapes->length(); ++i ) + { + newSO = myGen_i->ObjectToSObject( mySubshapes[ i ]); + SALOMEDS::ChildIterator_wrap anIter = study->NewChildIterator( newSO ); + bool refFound = false; + for ( ; anIter->More(); anIter->Next() ) + { + SALOMEDS::SObject_wrap so = anIter->Value(); + if ( so->ReferencedObject( oldSO.inout() )) + { + oldEntry = oldSO->GetID(); + newEntry = newSO->GetID(); + if (( refFound = ( newMainEntry != oldEntry.in() ))) + myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ), + std::string( newEntry.in() ))); + } + } + if ( !refFound ) + { + GEOM::GEOM_Object_var father = mySubshapes[ i ]->GetMainShape(); + if ( father->_is_equivalent( mainShapeNew )) + { + GEOM::ListOfLong_var ids = mySubshapes[ i ]->GetSubShapeIndices(); + std::set< int > idSet( &ids[0] , &ids[0] + ids->length() ); + myIds2SubshapeIndex.insert( std::make_pair( idSet, i )); + CORBA::String_var name = newSO->GetName(); + if ( name.in()[0] ) + myName2SubshapeIndex.insert( std::make_pair( name.in(), i )); + } + } + } + } + + //================================================================================ + /*! + * \brief Find a new sub-shape corresponding to an old one + */ + GEOM::GEOM_Object_ptr FindNew( GEOM::GEOM_Object_ptr oldShape ) + { + if ( myIsSameGeom ) + return GEOM::GEOM_Object::_duplicate( oldShape ); + + GEOM::GEOM_Object_var newShape; + + if ( CORBA::is_nil( oldShape )) + return newShape._retn(); + + if ( !isChildOfOld( oldShape )) + return GEOM::GEOM_Object::_duplicate( oldShape ); // shape independent of the old shape + + GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh(); + GEOM::GEOM_Gen_var geomGen = myGen_i->GetGeomEngine( mainShapeNew ); + + // try to find by entry or name + if ( myToPublish ) + { + CORBA::String_var oldEntry = oldShape->GetStudyEntry(); + TStr2StrMap::iterator o2nID = myOld2NewEntryMap.find( oldEntry.in() ); + if ( o2nID != myOld2NewEntryMap.end() ) + { + newShape = getShapeByEntry( o2nID->second ); + } + if ( newShape->_is_nil() ) + { + CORBA::String_var name = oldShape->GetName(); + TName2IndexMap::iterator n2ind = myName2SubshapeIndex.find( name.in() ); + if ( n2ind != myName2SubshapeIndex.end() ) + { + newShape = GEOM::GEOM_Object::_duplicate( mySubshapes[ n2ind->second ]); + GEOM::ListOfLong_var oldIndices = oldShape->GetSubShapeIndices(); + GEOM::ListOfLong_var newIndices = newShape->GetSubShapeIndices(); + if ( oldIndices->length() == 0 || + newIndices->length() == 0 || + getShapeType( myNewMesh_i, newIndices[0] ) != + getShapeType( mySrcMesh_i, oldIndices[0] )) + newShape = GEOM::GEOM_Object::_nil(); + } + } + } + + if ( newShape->_is_nil() ) + { + // try to construct a new sub-shape using myGIPMap + buildGIPMap(); + std::vector< int > newIndices; + GEOM::ListOfLong_var oldIndices = oldShape->GetSubShapeIndices(); + for ( CORBA::ULong i = 0; i < oldIndices->length(); ++i ) + { + findNewIDs( oldIndices[i], newIndices ); + } + if ( newIndices.size() < oldIndices->length() ) // issue #17096 + { + newIndices.clear(); + newShape = getInPlace( oldShape ); + } + if ( !newIndices.empty() && newShape->_is_nil() ) + { + // search for a sub-shape with same ids + std::set< int > idSet( newIndices.begin(), newIndices.end() ); + TIdSet2IndexMap::iterator ids2ind = myIds2SubshapeIndex.find( idSet ); + if ( ids2ind != myIds2SubshapeIndex.end() ) { + newShape = GEOM::GEOM_Object::_duplicate( mySubshapes[ ids2ind->second ]); + } + if ( newShape->_is_nil() ) + try + { + // create a new shape + if ( newIndices.size() > 1 || oldShape->GetType() == GEOM_GROUP ) + { + int groupType = getShapeType( myNewMesh_i, newIndices[0] ); + + GEOM::GEOM_IGroupOperations_ptr grOp = geomGen->GetIGroupOperations(); + newShape = grOp->CreateGroup( mainShapeNew, groupType ); + + GEOM::ListOfLong_var newIndicesList = new GEOM::ListOfLong(); + newIndicesList->length( newIndices.size() ); + for ( size_t i = 0; i < newIndices.size(); ++i ) + newIndicesList[ i ] = newIndices[ i ]; + grOp->UnionIDs( newShape, newIndicesList ); + } + else + { + GEOM::GEOM_IShapesOperations_wrap shOp = geomGen->GetIShapesOperations(); + newShape = shOp->GetSubShape( mainShapeNew, newIndices[0] ); + } + } + catch (...) + { + } + } + } + + if ( !newShape->_is_nil() && myToPublish ) + { + CORBA::String_var oldEntry, newEntry = newShape->GetStudyEntry(); + if ( !newEntry.in() || !newEntry.in()[0] ) + { + CORBA::String_var name = oldShape->GetName(); + SALOMEDS::SObject_wrap so = geomGen->AddInStudy( newShape, name, mainShapeNew ); + newEntry = newShape->GetStudyEntry(); + oldEntry = oldShape->GetStudyEntry(); + myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ), + std::string( newEntry.in() ))); + } + } + + return newShape._retn(); + } + + //================================================================================ + /*! + * \brief Return a study entry of a new shape by study entry of the old one + */ + std::string FindNew( const std::string & oldEntry ) + { + if ( myIsSameGeom ) + return oldEntry; + + TStr2StrMap::iterator o2nID = myOld2NewEntryMap.find( oldEntry ); + if ( o2nID != myOld2NewEntryMap.end() ) + return o2nID->second; + + GEOM::GEOM_Object_var oldShape = getShapeByEntry( oldEntry ); + if ( oldShape->_is_nil() || !isChildOfOld( oldShape )) + return oldEntry; + + GEOM::GEOM_Object_ptr newShape = FindNew( oldShape ); + if ( newShape->_is_nil() ) + return std::string(); + + CORBA::String_var newEntry = newShape->GetStudyEntry(); + return newEntry.in(); + } + + //================================================================================ + /*! + * \brief Return a sub-shape ID of a new shape by a sub-shape ID of the old one. + * Return zero if not found or there are more than one new ID + */ + int FindNew( int oldID ) + { + if ( myIsSameGeom ) + return oldID; + + buildGIPMap(); + + int newID = 0; + + if ( 0 < oldID && oldID < (int)myGIPMap->length() ) + { + if ( myGIPMap[ oldID ].length() == 1 ) + { + newID = myGIPMap[ oldID ][ 0 ]; + } + else if ( myGIPMap[ oldID ].length() > 1 && + getShapeType( mySrcMesh_i, oldID ) == TopAbs_VERTEX ) + { + // select a meshed VERTEX + SMESH_subMesh* newSM; + for ( CORBA::ULong i = 0; i < myGIPMap[ oldID ].length() && !newID; ++i ) + if (( newSM = myNewMesh_i->GetImpl().GetSubMeshContaining( myGIPMap[ oldID ][ i ] )) && + ( !newSM->IsEmpty() )) + newID = myGIPMap[ oldID ][ i ]; + } + } + return newID; + } + + //================================================================================ + /*! + * \brief Return a sub-shape ID of a new shape by an old sub-mesh. + * Return zero if the old shape is not kept as is in the new shape. + */ + int FindNewNotChanged( SMESH_subMesh* oldSM ) + { + if ( myIsSameGeom ) + return oldSM->GetId(); + + int newID = FindNew( oldSM->GetId() ); + if ( !newID ) + return 0; + + SMESH_subMesh* newSM = myNewMesh_i->GetImpl().GetSubMeshContaining( newID ); + if ( !newSM ) + return 0; + + // consider a sub-shape as not changed if all its sub-shapes are mapped into + // one new sub-shape of the same type. + + if ( oldSM->DependsOn().size() != + newSM->DependsOn().size() ) + return 0; + + SMESH_subMeshIteratorPtr srcSMIt = oldSM->getDependsOnIterator( /*includeSelf=*/true ); + while ( srcSMIt->more() ) + { + oldSM = srcSMIt->next(); + int newSubID = FindNew( oldSM->GetId() ); + if ( getShapeType( myNewMesh_i, newSubID ) != + getShapeType( mySrcMesh_i, oldSM->GetId() )) + return 0; + } + return newID; + } + + //================================================================================ + /*! + * \brief Return shape by study entry + */ + GEOM::GEOM_Object_ptr getShapeByEntry( const std::string & entry ) + { + GEOM::GEOM_Object_var shape; + SALOMEDS::SObject_wrap so = myGen_i->getStudyServant()->FindObjectID( entry.c_str() ); + if ( !so->_is_nil() ) + { + CORBA::Object_var obj = so->GetObject(); + shape = GEOM::GEOM_Object::_narrow( obj ); + } + return shape._retn(); + } + + //================================================================================ + /*! + * \brief Fill myGIPMap by calling GetInPlaceMap() + */ + void buildGIPMap() + { + if ( !myGIPMapDone ) + { + myGIPMapDone = true; + + GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh(); + GEOM::GEOM_Object_var mainShapeOld = mySrcMesh_i->GetShapeToMesh(); + GEOM::GEOM_Gen_var geomGen = myGen_i->GetGeomEngine( mainShapeNew ); + GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations(); + try + { + myGIPMap = op->GetInPlaceMap( mainShapeNew, mainShapeOld ); + } + catch( ... ) + { + myGIPMap = new GEOM::ListOfListOfLong(); + } + } + } + + //================================================================================ + /*! + * \brief Get new sub-shape by calling GetInPlace() + */ + GEOM::GEOM_Object_ptr getInPlace( GEOM::GEOM_Object_ptr oldShape ) + { + GEOM::GEOM_Object_var newShape; + + GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh(); + GEOM::GEOM_Gen_var geomGen = myGen_i->GetGeomEngine( mainShapeNew ); + GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations(); + try + { + newShape = op->GetInPlace( mainShapeNew, oldShape ); + } + catch( ... ) + { + } + return newShape._retn(); + } + + //================================================================================ + /*! + * \brief Find a new sub-shape indices by an old one in myGIPMap. Return + * number of found IDs + */ + int findNewIDs( int oldID, std::vector< int >& newIDs ) + { + size_t prevNbIDs = newIDs.size(); + + if ( 0 < oldID && oldID < (int) myGIPMap->length() ) + { + for ( CORBA::ULong i = 0; i < myGIPMap[ oldID ].length(); ++i ) + newIDs.push_back( myGIPMap[ oldID ][ i ]); + } + return newIDs.size() - prevNbIDs; + } + + //================================================================================ + /*! + * \brief Check if an object relates to the old shape + */ + bool isChildOfOld( GEOM::GEOM_Object_ptr oldShape ) + { + if ( CORBA::is_nil( oldShape )) + return false; + GEOM::GEOM_Object_var mainShapeOld1 = mySrcMesh_i->GetShapeToMesh(); + GEOM::GEOM_Object_var mainShapeOld2 = oldShape->GetMainShape(); + return ( mainShapeOld1->_is_equivalent( mainShapeOld2 ) || + mainShapeOld1->_is_equivalent( oldShape )); + } + + //================================================================================ + /*! + * \brief Return shape type by shape ID + */ + TopAbs_ShapeEnum getShapeType( SMESH_Mesh_i* mesh_i, int shapeID ) + { + SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS(); + const TopoDS_Shape& shape = meshDS->IndexToShape( shapeID ); + return shape.IsNull() ? TopAbs_SHAPE : shape.ShapeType(); + } + + //================================================================================ + /*! + * \brief Store a source sub-shape for which a counterpart not found and + * a smesh object invalid due to that + */ + void AddInvalid( GEOM::GEOM_Object_var srcShape, + SALOMEDS::SObject_wrap smeshSO ) + { + CORBA::String_var geomEntry = srcShape->GetStudyEntry(); + if ( geomEntry.in()[0] && !smeshSO->_is_nil() ) + { + CORBA::String_var smeshEntry = smeshSO->GetID(); + myInvalidMap[ geomEntry.in() ].insert( smeshEntry.in() ); + } + } + + //================================================================================ + /*! + * \brief Store a source sub-shape for which a counterpart not found and + * a smesh object invalid due to that + */ + void AddInvalid( std::string geomEntry, + SALOMEDS::SObject_wrap smeshSO ) + { + if ( !geomEntry.empty() ) + { + CORBA::String_var smeshEntry = smeshSO->GetID(); + myInvalidMap[ geomEntry ].insert( smeshEntry.in() ); + } + } + + //================================================================================ + /*! + * \brief Store a source sub-shape for which a counterpart not found and + * a smesh object invalid due to that + */ + void AddInvalid( int oldGeomID, + SALOMEDS::SObject_wrap smeshSO ) + { + int shapeType = getShapeType( mySrcMesh_i, oldGeomID ); + if ( shapeType < 0 || shapeType > TopAbs_SHAPE ) + return; + + const char* typeName[] = { "COMPOUND","COMPSOLID","SOLID","SHELL", + "FACE","WIRE","EDGE","VERTEX","SHAPE" }; + + SMESH_Comment geomName( typeName[ shapeType ]); + geomName << " #" << oldGeomID; + + CORBA::String_var smeshEntry = smeshSO->GetID(); + myInvalidMap[ geomName ].insert( smeshEntry.in() ); + } + + //================================================================================ + /*! + * \brief Return entries of a source sub-shape for which a counterpart not found and + * of smesh objects invalid due to that + */ + void GetInvalid( SMESH::string_array_out & theInvalidEntries, + std::vector< SALOMEDS::SObject_wrap > & theInvalidMeshSObjects) + { + int nbSO = 0; + TStr2StrSetMap::iterator entry2entrySet = myInvalidMap.begin(); + for ( ; entry2entrySet != myInvalidMap.end(); ++entry2entrySet ) + { + nbSO += 1 + entry2entrySet->second.size(); + } + int iSO = theInvalidMeshSObjects.size(), iEntry = 0; + theInvalidEntries->length ( nbSO ); + theInvalidMeshSObjects.resize( theInvalidMeshSObjects.size() + nbSO - myInvalidMap.size() ); + + entry2entrySet = myInvalidMap.begin(); + for ( ; entry2entrySet != myInvalidMap.end(); ++entry2entrySet ) + { + theInvalidEntries[ iEntry++ ] = entry2entrySet->first.c_str(); + + std::set< std::string > & entrySet = entry2entrySet->second; + std::set< std::string >::iterator entry = entrySet.begin(); + for ( ; entry != entrySet.end(); ++entry ) + { + theInvalidEntries[ iEntry++ ] = entry->c_str(); + + SALOMEDS::SObject_wrap so = myGen_i->getStudyServant()->FindObjectID( entry->c_str() ); + if ( !so->_is_nil() ) + theInvalidMeshSObjects[ iSO++ ] = so; + } + } + } + + }; // struct ShapeMapper + + //================================================================================ + /*! + * \brief Append an item to a CORBA sequence + */ + template < class CORBA_seq, class ITEM > + void append( CORBA_seq& seq, ITEM item ) + { + if ( !CORBA::is_nil( item )) + { + seq->length( 1 + seq->length() ); + seq[ seq->length() - 1 ] = item; + } + } +} // namespace // utils for CopyMeshWithGeom() + +//================================================================================ +/*! + * \brief Create a mesh by copying definitions of another mesh to a given geometry + * \param [in] sourceMesh - a mesh to copy + * \param [in] newGeometry - a new geometry + * \param [in] toCopyGroups - to create groups in the new mesh + * \param [in] toReuseHypotheses - if True, existing hypothesis will be used by the new mesh, + * otherwise new hypotheses with the same parameters will be created for the new mesh. + * \param [in] toCopyElements - to copy mesh elements of same sub-shapes of the two geometries + * \param [out] newMesh - return a new mesh + * \param [out] newGroups - return new groups + * \param [out] newSubmeshes - return new sub-meshes + * \param [out] newHypotheses - return new algorithms and hypotheses + * \param [out] invalidEntries - return study entries of objects whose + * counterparts are not found in the newGeometry, followed by entries + * of mesh sub-objects that are invalid because they depend on a not found + * preceding sub-shape + * \return CORBA::Boolean - is a success + */ +//================================================================================ + +CORBA::Boolean SMESH_Gen_i::CopyMeshWithGeom( SMESH::SMESH_Mesh_ptr theSourceMesh, + GEOM::GEOM_Object_ptr theNewGeometry, + const char* theMeshName, + CORBA::Boolean theToCopyGroups, + CORBA::Boolean theToReuseHypotheses, + CORBA::Boolean theToCopyElements, + SMESH::SMESH_Mesh_out theNewMesh, + SMESH::ListOfGroups_out theNewGroups, + SMESH::submesh_array_out theNewSubmeshes, + SMESH::ListOfHypothesis_out theNewHypotheses, + SMESH::string_array_out theInvalidEntries) +throw ( SALOME::SALOME_Exception ) +{ + if ( CORBA::is_nil( theSourceMesh ) || + CORBA::is_nil( theNewGeometry )) + THROW_SALOME_CORBA_EXCEPTION( "NULL arguments", SALOME::BAD_PARAM ); + + if ( !theSourceMesh->HasShapeToMesh() ) + THROW_SALOME_CORBA_EXCEPTION( "Source mesh not on geometry", SALOME::BAD_PARAM ); + + bool ok = true; + SMESH_TRY; + + TPythonDump pyDump; // prevent dump from CreateMesh() + + theNewMesh = CreateMesh( theNewGeometry ); + theNewGroups = new SMESH::ListOfGroups(); + theNewSubmeshes = new SMESH::submesh_array(); + theNewHypotheses = new SMESH::ListOfHypothesis(); + theInvalidEntries = new SMESH::string_array(); + + std::vector< SALOMEDS::SObject_wrap > invalidSObjects; + + GEOM::GEOM_Object_var srcGeom = theSourceMesh->GetShapeToMesh(); + GEOM::GEOM_Object_var geom, newGeom; + SALOMEDS::SObject_wrap so; + + SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( theSourceMesh ); + SMESH_Mesh_i* newMesh_i = SMESH::DownCast( theNewMesh ); + srcMesh_i->Load(); + + ShapeMapper shapeMapper( srcMesh_i, newMesh_i, this ); + + // treat hypotheses of mesh and sub-meshes + SMESH::submesh_array_var smList = theSourceMesh->GetSubMeshes(); + for ( CORBA::ULong iSM = 0; iSM <= smList->length(); ++iSM ) + { + bool isSubMesh = ( iSM < smList->length() ); + if ( isSubMesh ) + { + // create a new sub-mesh + SMESH::SMESH_subMesh_var newSM; + geom = smList[iSM]->GetSubShape(); + so = ObjectToSObject( smList[iSM] ); + CORBA::String_var name; + if ( !so->_is_nil() ) + name = so->GetName(); + newGeom = shapeMapper.FindNew( geom ); + if ( newGeom->_is_nil() ) + { + newSM = createInvalidSubMesh( theNewMesh, geom, name.in() ); + shapeMapper.AddInvalid( geom, ObjectToSObject( newSM )); + ok = false; + } + else + { + newSM = theNewMesh->GetSubMesh( newGeom, name.in() ); + } + append( theNewSubmeshes, newSM ); + + if ( newGeom->_is_nil() ) + continue; // don't assign hypotheses + } + else + { + newGeom = GEOM::GEOM_Object::_duplicate( theNewGeometry ); + geom = srcGeom; + so = ObjectToSObject( theNewMesh ); + SetName( so, theMeshName, "Mesh" ); + } + + // assign hypotheses + SMESH::ListOfHypothesis_var hypList = theSourceMesh->GetHypothesisList( geom ); + for ( CORBA::ULong iHyp = 0; iHyp < hypList->length(); ++iHyp ) + { + SMESH::SMESH_Hypothesis_var hyp = hypList[ iHyp ]; + SMESH_Hypothesis_i* hyp_i = SMESH::DownCast< SMESH_Hypothesis_i* >( hyp ); + + // get geometry hyp depends on + std::vector< std::string > entryArray; + std::vector< int > subIDArray; + bool dependsOnGeom = hyp_i->getObjectsDependOn( entryArray, subIDArray ); + + if ( !theToReuseHypotheses || dependsOnGeom ) + { + // create a new hypothesis + CORBA::String_var type = hyp->GetName(); + CORBA::String_var lib = hyp->GetLibName(); + CORBA::String_var data = hyp_i->SaveTo(); + if ( data.in()[0] ) + { + hyp = CreateHypothesis( type, lib ); + hyp_i = SMESH::DownCast< SMESH_Hypothesis_i* >( hyp ); + hyp_i->LoadFrom( data.in() ); + append( theNewHypotheses, hyp ); + } + } + + // update geometry hyp depends on + if ( dependsOnGeom ) + { + for ( size_t iGeo = 0; iGeo < entryArray.size(); ++iGeo ) + { + if ( !entryArray[ iGeo ].empty() ) + { + std::string newEntry = shapeMapper.FindNew( entryArray[ iGeo ]); + if ( newEntry.empty() ) + { + ok = false; + shapeMapper.AddInvalid( entryArray[ iGeo ], ObjectToSObject( hyp )); + shapeMapper.AddInvalid( entryArray[ iGeo ], so ); // sub-mesh + } + entryArray[ iGeo ] = newEntry; + } + } + for ( size_t iGeo = 0; iGeo < subIDArray.size(); ++iGeo ) + { + if ( subIDArray[ iGeo ] > 0 ) + { + int newID = shapeMapper.FindNew( subIDArray[ iGeo ]); + if ( newID < 1 ) + { + ok = false; + shapeMapper.AddInvalid( subIDArray[ iGeo ], ObjectToSObject( hyp )); + shapeMapper.AddInvalid( subIDArray[ iGeo ], so ); // sub-mesh + } + subIDArray[ iGeo ] = newID; + } + } + if ( !hyp_i->setObjectsDependOn( entryArray, subIDArray )) + ok = false; + } + + CORBA::String_var errorText; + theNewMesh->AddHypothesis( newGeom, hyp, errorText.out() ); + if ( errorText.in()[0] ) + ok = false; + + } // loop on hypotheses + } // loop on sub-meshes and mesh + + + // copy mesh elements, keeping IDs + SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); + if ( theToCopyElements && theSourceMesh->NbNodes() > 0 ) + { + ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() ); + ::SMESH_MeshEditor::ElemFeatures elemData; + + SMESH_subMesh* srcMainSM = srcMesh_i->GetImpl().GetSubMeshContaining( 1 ); + SMESH_subMeshIteratorPtr srcSMIt = srcMainSM->getDependsOnIterator( /*includeSelf=*/true, + /*vertexLast=*/false); + while ( srcSMIt->more() ) + { + SMESH_subMesh* srcSM = srcSMIt->next(); + if ( srcSM->IsEmpty() ) + continue; // not yet computed + int newID = shapeMapper.FindNewNotChanged( srcSM ); + if ( newID < 1 ) + continue; + + SMESHDS_SubMesh* srcSMDS = srcSM->GetSubMeshDS(); + SMDS_NodeIteratorPtr nIt = srcSMDS->GetNodes(); + while ( nIt->more() ) + { + SMESH_NodeXYZ node( nIt->next() ); + const SMDS_MeshNode* newNode = newMeshDS->AddNodeWithID( node.X(), node.Y(), node.Z(), + node->GetID() ); + const SMDS_PositionPtr pos = node->GetPosition(); + const double* uv = pos->GetParameters(); + switch ( pos->GetTypeOfPosition() ) + { + case SMDS_TOP_3DSPACE: newMeshDS->SetNodeInVolume( newNode, newID ); break; + case SMDS_TOP_FACE: newMeshDS->SetNodeOnFace ( newNode, newID, uv[0], uv[1] ); break; + case SMDS_TOP_EDGE: newMeshDS->SetNodeOnEdge ( newNode, newID, uv[0] ); break; + case SMDS_TOP_VERTEX: newMeshDS->SetNodeOnVertex( newNode, newID ); break; + default: ; + } + } + SMDS_ElemIteratorPtr eIt = srcSMDS->GetElements(); + while( eIt->more() ) + { + const SMDS_MeshElement* e = eIt->next(); + elemData.Init( e, /*basicOnly=*/false ); + elemData.SetID( e->GetID() ); + elemData.myNodes.resize( e->NbNodes() ); + SMDS_NodeIteratorPtr nnIt = e->nodeIterator(); + size_t iN; + for ( iN = 0; nnIt->more(); ++iN ) + { + const SMDS_MeshNode* srcNode = nnIt->next(); + elemData.myNodes[ iN ] = newMeshDS->FindNode( srcNode->GetID() ); + if ( !elemData.myNodes[ iN ]) + break; + } + if ( iN == elemData.myNodes.size() ) + if ( const SMDS_MeshElement * newElem = editor.AddElement( elemData.myNodes, elemData )) + newMeshDS->SetMeshElementOnShape( newElem, newID ); + } + if ( SMESH_subMesh* newSM = newMesh_i->GetImpl().GetSubMeshContaining( newID )) + newSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + } + + newMeshDS->Modified(); + } + + + // treat groups + + TStr2StrMap old2newGroupMap; + + SALOME::GenericObj_wrap< SMESH::FilterManager > filterMgr = CreateFilterManager(); + + SMESH::ListOfGroups_var groups = theSourceMesh->GetGroups(); + CORBA::ULong nbGroups = theToCopyGroups ? groups->length() : 0, nbAddedGroups = 0; + for ( CORBA::ULong i = 0; i < nbGroups + nbAddedGroups; ++i ) + { + SMESH::SMESH_Group_var stdlGroup = SMESH::SMESH_Group::_narrow ( groups[ i ]); + SMESH::SMESH_GroupOnGeom_var geomGroup = SMESH::SMESH_GroupOnGeom::_narrow ( groups[ i ]); + SMESH::SMESH_GroupOnFilter_var fltrGroup = SMESH::SMESH_GroupOnFilter::_narrow( groups[ i ]); + + CORBA::String_var name = groups[ i ]->GetName(); + SMESH::ElementType elemType = groups[ i ]->GetType(); + + SMESH::SMESH_GroupBase_var newGroup; + + if ( !stdlGroup->_is_nil() ) + { + if ( newMeshDS->GetMeshInfo().NbElements( SMDSAbs_ElementType( elemType )) > 0 ) + { + SMESH::long_array_var elemIDs = stdlGroup->GetIDs(); + const bool isElem = ( elemType != SMESH::NODE ); + CORBA::ULong iE = 0; + for ( ; iE < elemIDs->length(); ++iE ) // check if any element has been copied + if ( newMeshDS->GetElementType( elemIDs[ iE ], isElem ) != SMDSAbs_All ) + break; + if ( iE < elemIDs->length() ) + { + stdlGroup = theNewMesh->CreateGroup( elemType, name ); + stdlGroup->Add( elemIDs ); + newGroup = SMESH::SMESH_GroupBase::_narrow( stdlGroup ); + } + } + } + else if ( !geomGroup->_is_nil() ) + { + GEOM::GEOM_Object_var geom = geomGroup->GetShape(); + GEOM::GEOM_Object_var newGeom = shapeMapper.FindNew( geom ); + if ( newGeom->_is_nil() ) + { + newGroup = theNewMesh->CreateGroup( elemType, name ); // just to notify the user + shapeMapper.AddInvalid( geom, ObjectToSObject( newGroup )); + ok = false; + } + else + { + newGroup = theNewMesh->CreateGroupFromGEOM( elemType, name, newGeom ); + } + } + else if ( !fltrGroup->_is_nil() ) + { + // replace geometry in a filter + SMESH::Filter_var filter = fltrGroup->GetFilter(); + SMESH::Filter::Criteria_var criteria; + filter->GetCriteria( criteria.out() ); + + bool isMissingGroup = false; + std::vector< std::string > badEntries; + + for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr ) + { + const char* thresholdID = criteria[ iCr ].ThresholdID.in(); + switch ( criteria[ iCr ].Type ) + { + case SMESH::FT_BelongToMeshGroup: + { + SALOME::GenericObj_wrap< SMESH::BelongToMeshGroup > btgg = filterMgr->CreateBelongToMeshGroup(); + btgg->SetGroupID( thresholdID ); + SMESH::SMESH_GroupBase_ptr refGroup = btgg->GetGroup(); + SALOMEDS::SObject_wrap refGroupSO = ObjectToSObject( refGroup ); + if ( refGroupSO->_is_nil() ) + break; + CORBA::String_var refID = refGroupSO->GetID(); + TStr2StrMap::iterator o2nID = old2newGroupMap.find( refID.in() ); + if ( o2nID == old2newGroupMap.end() ) + { + isMissingGroup = true; // corresponding new group not yet created + break; + } + criteria[ iCr ].ThresholdID = o2nID->second.c_str(); + + if ( o2nID->second.empty() ) // new referred group is invalid + badEntries.push_back( refID.in() ); + break; + } + case SMESH::FT_BelongToGeom: + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + case SMESH::FT_LyingOnGeom: + { + std::string newID = shapeMapper.FindNew( thresholdID ); + criteria[ iCr ].ThresholdID = newID.c_str(); + if ( newID.empty() ) + badEntries.push_back( thresholdID ); + break; + } + case SMESH::FT_ConnectedElements: + { + if ( thresholdID && thresholdID[0] ) + { + std::string newID = shapeMapper.FindNew( thresholdID ); + criteria[ iCr ].ThresholdID = newID.c_str(); + if ( newID.empty() ) + badEntries.push_back( thresholdID ); + } + break; + } + default:; + } + } // loop on criteria + + if ( isMissingGroup && i < nbGroups ) + { + // to treat the group again + append( groups, SMESH::SMESH_GroupBase::_duplicate( groups[ i ])); + ++nbAddedGroups; + continue; + } + SMESH::Filter_var newFilter = filterMgr->CreateFilter(); + newFilter->SetCriteria( criteria ); + + newGroup = theNewMesh->CreateGroupFromFilter( elemType, name, newFilter ); + newFilter->UnRegister(); + + SALOMEDS::SObject_wrap newSO = ObjectToSObject( newGroup ); + for ( size_t iEnt = 0; iEnt < badEntries.size(); ++iEnt ) + shapeMapper.AddInvalid( badEntries[ iEnt ], newSO ); + + if ( isMissingGroup ) // all groups treated but a referred groups still not found + { + invalidSObjects.push_back( ObjectToSObject( newGroup )); + ok = false; + } + if ( !badEntries.empty() ) + ok = false; + + } // treat a group on filter + + append( theNewGroups, newGroup ); + + // fill old2newGroupMap + SALOMEDS::SObject_wrap srcSO = ObjectToSObject( groups[i] ); + SALOMEDS::SObject_wrap newSO = ObjectToSObject( newGroup ); + if ( !srcSO->_is_nil() ) + { + CORBA::String_var srcID, newID(""); + srcID = srcSO->GetID(); + if ( !newSO->_is_nil() ) + newID = newSO->GetID(); + old2newGroupMap.insert( std::make_pair( std::string( srcID.in() ), + std::string( newID.in() ))); + } + + if ( newGroup->_is_nil() ) + ok = false; + + } // loop on groups + + newMeshDS->CompactMesh(); + + // set mesh name + if ( !theMeshName || !theMeshName[0] ) + { + SALOMEDS::SObject_wrap soNew = ObjectToSObject( theNewMesh ); + SALOMEDS::SObject_wrap soOld = ObjectToSObject( theSourceMesh ); + CORBA::String_var oldName = soOld->GetName(); + SetName( soNew, oldName.in(), "Mesh" ); + } + // mark invalid objects + shapeMapper.GetInvalid( theInvalidEntries, invalidSObjects ); + + for ( size_t i = 0; i < invalidSObjects.size(); ++i ) + highLightInvalid( invalidSObjects[i].in(), true ); + + pyDump << "ok, " + << theNewMesh << ", " + << theNewGroups << ", " + << *theNewSubmeshes.ptr() << ", " + << *theNewHypotheses.ptr() << ", " + << "invalidEntries = " << this << ".CopyMeshWithGeom( " + << theSourceMesh << ", " + << theNewGeometry << ", " + << "'" << theMeshName << "', " + << theToCopyGroups << ", " + << theToReuseHypotheses << ", " + << theToCopyElements << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); + + return ok; +} + +//================================================================================ +/*! + * \brief Get version of MED format being used. + */ +//================================================================================ + +char* SMESH_Gen_i::GetMEDFileVersion() +{ + MED::TInt majeur, mineur, release; + majeur = mineur = release = 0; + MED::GetVersionRelease(majeur, mineur, release); + std::ostringstream version; + version << majeur << "." << mineur << "." << release; + return CORBA::string_dup( version.str().c_str() ); +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMEDVersion + * + * Get MED version of the file by its name + */ +//================================================================================ +char* SMESH_Gen_i::GetMEDVersion(const char* theFileName) +{ + std::string version = MED::GetMEDVersion( theFileName ); + return CORBA::string_dup( version.c_str() ); +} + +//================================================================================ +/*! + * SMESH_Gen_i::CheckCompatibility + * + * Check compatibility of file with MED format being used, read only. + */ +//================================================================================ +CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName) +{ + return MED::CheckCompatibility( theFileName ); +} + +//================================================================================ +/*! + * SMESH_Gen_i::CheckWriteCompatibility + * + * Check compatibility of file with MED format being used, for append on write. + */ +//================================================================================ +CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName) +{ + return MED::CheckCompatibility( theFileName, true ); +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMeshNames + * + * Get names of meshes defined in file with the specified name + */ +//================================================================================ +SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName) +{ + //MESSAGE("GetMeshNames " << theFileName); + SMESH::string_array_var aResult = new SMESH::string_array(); + MED::PWrapper aMed = MED::CrWrapperR( theFileName ); + MED::TErr anErr; + MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr ); + //MESSAGE("---" << aNbMeshes); + if( anErr >= 0 ) { aResult->length( aNbMeshes ); for( MED::TInt i = 0; i < aNbMeshes; i++ ) { MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 ); @@ -2994,16 +4163,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile ) { - // ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) - // san -- in case differs from theComponent's study, - // use that of the component - if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() ) - SetCurrentStudy( theComponent->GetStudy() ); + // localizing + Kernel_Utils::Localizer loc; + + if (!myStudyContext) + UpdateStudy(); // Store study contents as a set of python commands - SavePython(myCurrentStudy); + SavePython(); - StudyContext* myStudyContext = GetCurrentStudyContext(); + SALOMEDS::Study_var aStudy = getStudyServant(); // Declare a byte stream SALOMEDS::TMPFile_var aStreamFile; @@ -3013,20 +4182,20 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, ( isMultiFile ) ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str(); // Create a sequence of files processed - SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames; - aFileSeq->length( NUM_TMP_FILES ); + SALOMEDS_Tool::ListOfFiles aFileSeq; + aFileSeq.reserve( NUM_TMP_FILES ); TCollection_AsciiString aStudyName( "" ); if ( isMultiFile ) - aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); + aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(aStudy->URL()) ).c_str() ); // Set names of temporary files TCollection_AsciiString filename = aStudyName + TCollection_AsciiString( "_SMESH.hdf" ); // for SMESH data itself TCollection_AsciiString meshfile = aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" ); // for mesh data to be stored in MED file - aFileSeq[ 0 ] = CORBA::string_dup( filename.ToCString() ); - aFileSeq[ 1 ] = CORBA::string_dup( meshfile.ToCString() ); + aFileSeq.push_back(CORBA::string_dup( filename.ToCString() )); + aFileSeq.push_back(CORBA::string_dup( meshfile.ToCString() )); filename = tmpDir + filename; meshfile = tmpDir + meshfile; @@ -3050,6 +4219,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, cmd+="\" \""; cmd+=meshfile; cmd+="\""; +#ifdef WIN32 + cmd+=" 2>NUL"; +#endif system(cmd.ToCString()); // MED writer to be used by storage process @@ -3060,7 +4232,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // SetStoreName() to groups before storing hypotheses to let them refer to // groups using "store name", which is "Group " { - SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent ); + SALOMEDS::ChildIterator_wrap itBig = aStudy->NewChildIterator( theComponent ); for ( ; itBig->More(); itBig->Next() ) { SALOMEDS::SObject_wrap gotBranch = itBig->Value(); if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { @@ -3071,7 +4243,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, myMesh->Load(); // load from study file if not yet done TPythonDump pd; // not to dump GetGroups() SMESH::ListOfGroups_var groups = myMesh->GetGroups(); - pd << ""; // to avoid optimizing pd out for ( CORBA::ULong i = 0; i < groups->length(); ++i ) { SMESH_GroupBase_i* grImpl = SMESH::DownCast( groups[i]); @@ -3080,7 +4251,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() ); int anId = myStudyContext->findId( string( objStr.in() ) ); char grpName[ 30 ]; - sprintf( grpName, "Group %d", anId ); + sprintf( grpName, "Group %d %d", anId, grImpl->GetLocalID() ); SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS(); aGrpBaseDS->SetStoreName( grpName ); } @@ -3097,7 +4268,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aFile->CreateOnDisk(); // --> iterator for top-level objects - SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent ); + SALOMEDS::ChildIterator_wrap itBig = aStudy->NewChildIterator( theComponent ); for ( ; itBig->More(); itBig->Next() ) { SALOMEDS::SObject_wrap gotBranch = itBig->Value(); @@ -3108,7 +4279,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aTopGroup->CreateOnDisk(); // iterator for all hypotheses - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( gotBranch ); for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySObject = it->Value(); CORBA::Object_var anObject = SObjectToObject( mySObject ); @@ -3117,8 +4288,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( !myHyp->_is_nil() ) { SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); if ( myImpl ) { - string hypname = string( myHyp->GetName() ); - string libname = string( myHyp->GetLibName() ); + CORBA::String_var hn = myHyp->GetName(), ln = myHyp->GetLibName(); + std::string hypname = hn.in(); + std::string libname = ln.in(); // BUG SWP13062 // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for // WIN32 and ".so" for X-system) must be deleted @@ -3127,16 +4299,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if( libname_len > 4 ) libname.resize( libname_len - 4 ); #else - // PAL17753 (Regresion: missing hypothesis in restored study) + // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); + //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif - CORBA::String_var objStr = GetORB()->object_to_string( anObject ); - int id = myStudyContext->findId( string( objStr.in() ) ); - string hypdata = string( myImpl->SaveTo() ); + CORBA::String_var objStr = GetORB()->object_to_string( anObject ); + CORBA::String_var hypdata = myImpl->SaveTo(); + int id = myStudyContext->findId( string( objStr.in() )); // for each hypothesis create HDF group basing on its id char hypGrpName[30]; @@ -3156,10 +4328,10 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); aDataset->CloseOnDisk(); // --> persistent data of hypothesis - aSize[ 0 ] = hypdata.length() + 1; + aSize[ 0 ] = strlen( hypdata.in() ) + 1; aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); + aDataset->WriteOnDisk( ( char* )( hypdata.in() ) ); aDataset->CloseOnDisk(); // close hypothesis HDF group aGroup->CloseOnDisk(); @@ -3177,7 +4349,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aTopGroup->CreateOnDisk(); // iterator for all algorithms - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( gotBranch ); for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySObject = it->Value(); CORBA::Object_var anObject = SObjectToObject( mySObject ); @@ -3186,8 +4358,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( !myHyp->_is_nil() ) { SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); if ( myImpl ) { - string hypname = string( myHyp->GetName() ); - string libname = string( myHyp->GetLibName() ); + CORBA::String_var hn = myHyp->GetName(), ln = myHyp->GetLibName(); + std::string hypname = hn.in(); + std::string libname = ln.in(); // BUG SWP13062 // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for // WIN32 and ".so" for X-system) must be deleted @@ -3196,16 +4369,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if( libname_len > 4 ) libname.resize( libname_len - 4 ); #else - // PAL17753 (Regresion: missing hypothesis in restored study) + // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); + //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif - CORBA::String_var objStr = GetORB()->object_to_string( anObject ); - int id = myStudyContext->findId( string( objStr.in() ) ); - string hypdata = string( myImpl->SaveTo() ); + CORBA::String_var objStr = GetORB()->object_to_string( anObject ); + CORBA::String_var hypdata = myImpl->SaveTo(); + int id = myStudyContext->findId( string( objStr.in() ) ); // for each algorithm create HDF group basing on its id char hypGrpName[30]; @@ -3225,10 +4398,10 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); aDataset->CloseOnDisk(); // --> persistent data of algorithm - aSize[0] = hypdata.length() + 1; + aSize[0] = strlen( hypdata.in() ) + 1; aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); + aDataset->WriteOnDisk( ( char* )( hypdata.in() )); aDataset->CloseOnDisk(); // close algorithm HDF group aGroup->CloseOnDisk(); @@ -3302,6 +4475,14 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( &meshPersistentId ); aDataset->CloseOnDisk(); + // Store SMESH_Mesh_i::_mainShapeTick + int shapeTick = myImpl->MainShapeTick(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "shapeTick", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &shapeTick ); + aDataset->CloseOnDisk(); + // write reference on a shape if exists SALOMEDS::SObject_wrap myRef; bool shapeRefFound = false; @@ -3310,29 +4491,41 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, SALOMEDS::SObject_wrap myShape; bool ok = myRef->ReferencedObject( myShape.inout() ); if ( ok ) { - shapeRefFound = (! CORBA::is_nil( myShape->GetObject() )); - string myRefOnObject = myShape->GetID(); - if ( shapeRefFound && myRefOnObject.length() > 0 ) { - aSize[ 0 ] = myRefOnObject.length() + 1; + CORBA::Object_var shapeObj = myShape->GetObject(); + shapeRefFound = (! CORBA::is_nil( shapeObj )); + CORBA::String_var myRefOnObject = myShape->GetID(); + if ( shapeRefFound && myRefOnObject.in()[0] ) { + aSize[ 0 ] = strlen( myRefOnObject.in() ) + 1; aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.in() ) ); aDataset->CloseOnDisk(); } } } + // Store file info + std::string info = myImpl->FileInfoToString(); + if ( !info.empty() ) + { + aSize[ 0 ] = info.size(); + aDataset = new HDFdataset( "file info", aTopGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( (char*) info.data() ); + aDataset->CloseOnDisk(); + } + // write applied hypotheses if exist SALOMEDS::SObject_wrap myHypBranch; found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() ); - if ( found && !shapeRefFound && hasShape) { // remove applied hyps - myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch ); + if ( found && !shapeRefFound && hasShape ) { // remove applied hyps + aStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch ); } if ( found && (shapeRefFound || !hasShape) ) { aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); aGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myHypBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( myHypBranch ); int hypNb = 0; for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySObject = it->Value(); @@ -3370,13 +4563,13 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch.inout() ); if ( found && !shapeRefFound && hasShape) { // remove applied algos - myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch ); + aStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch ); } if ( found && (shapeRefFound || !hasShape)) { aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); aGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myAlgoBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( myAlgoBranch ); int algoNb = 0; for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySObject = it->Value(); @@ -3419,7 +4612,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, { bool hasShapeRef = false; SALOMEDS::ChildIterator_wrap itSM = - myCurrentStudy->NewChildIterator( mySubmeshBranch ); + aStudy->NewChildIterator( mySubmeshBranch ); for ( ; itSM->More(); itSM->Next() ) { SALOMEDS::SObject_wrap mySubRef, myShape, mySObject = itSM->Value(); if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() )) @@ -3444,11 +4637,11 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } } } - myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySObject ); + aStudy->NewBuilder()->RemoveObjectWithChildren( mySObject ); } } // loop on submeshes of a type if ( !shapeRefFound || !hasShapeRef ) { // remove the whole submeshes branch - myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySubmeshBranch ); + aStudy->NewBuilder()->RemoveObjectWithChildren( mySubmeshBranch ); found = false; } } // end check if there is shape reference in submeshes @@ -3474,7 +4667,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup->CreateOnDisk(); // iterator for all submeshes of given type - SALOMEDS::ChildIterator_wrap itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch ); + SALOMEDS::ChildIterator_wrap itSM = aStudy->NewChildIterator( mySubmeshBranch ); for ( ; itSM->More(); itSM->Next() ) { SALOMEDS::SObject_wrap mySObject = itSM->Value(); CORBA::Object_var anSubObject = SObjectToObject( mySObject ); @@ -3511,7 +4704,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); aSubSubGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( mySubHypBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( mySubHypBranch ); int hypNb = 0; for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySubSObject = it->Value(); @@ -3548,7 +4741,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aSubSubGroup->CreateOnDisk(); SALOMEDS::ChildIterator_wrap it = - myCurrentStudy->NewChildIterator( mySubAlgoBranch ); + aStudy->NewChildIterator( mySubAlgoBranch ); int algoNb = 0; for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySubSObject = it->Value(); @@ -3644,7 +4837,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myGroupsBranch ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( myGroupsBranch ); for ( ; it->More(); it->Next() ) { SALOMEDS::SObject_wrap mySObject = it->Value(); CORBA::Object_var aSubObject = SObjectToObject( mySObject ); @@ -3662,8 +4855,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // For each group, create a dataset named "Group " // and store the group's user name into it - const char* grpName = aGrpBaseDS->GetStoreName(); - char* aUserName = myGroupImpl->GetName(); + const char* grpName = aGrpBaseDS->GetStoreName(); + CORBA::String_var aUserName = myGroupImpl->GetName(); aSize[ 0 ] = strlen( aUserName ) + 1; aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); @@ -3701,14 +4894,14 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, mySubRef->ReferencedObject( myShape.inout() ) && !CORBA::is_nil( myShape->GetObject() )) { - string myRefOnObject = myShape->GetID(); - if ( myRefOnObject.length() > 0 ) { + CORBA::String_var myRefOnObject = myShape->GetID(); + if ( myRefOnObject.in()[0] ) { char aRefName[ 30 ]; sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = myRefOnObject.length() + 1; + aSize[ 0 ] = strlen( myRefOnObject.in() ) + 1; aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.in() )); aDataset->CloseOnDisk(); } } @@ -3797,7 +4990,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // "Face V positions" - V parameter of node on face // Find out nb of nodes on edges and faces - // Collect corresponing sub-meshes + // Collect corresponding sub-meshes int nbEdgeNodes = 0, nbFaceNodes = 0; list aEdgeSM, aFaceSM; // loop on SMESHDS_SubMesh'es @@ -3856,8 +5049,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // Position const SMDS_PositionPtr pos = node->GetPosition(); if ( onFace ) { // on FACE - const SMDS_FacePosition* fPos = - dynamic_cast( pos ); + SMDS_FacePositionPtr fPos = pos; if ( fPos ) { aUPos[ iNode ] = fPos->GetUParameter(); aVPos[ iNode ] = fPos->GetVParameter(); @@ -3867,8 +5059,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, nbNodes--; } else { // on EDGE - const SMDS_EdgePosition* ePos = - dynamic_cast( pos ); + SMDS_EdgePositionPtr ePos = pos; if ( ePos ) { aUPos[ iNode ] = ePos->GetUParameter(); iNode++; @@ -3929,11 +5120,11 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, delete aFile; // Convert temporary files to stream - aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile ); + aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq, isMultiFile ); // Remove temporary files and directory if ( !isMultiFile ) - SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq, true ); return aStreamFile._retn(); } @@ -3967,27 +5158,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent return anAsciiStreamFile._retn(); } -//============================================================================= -/*! - * SMESH_Gen_i::loadGeomData - * - * Load GEOM module data - */ -//============================================================================= - -void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ) -{ - if ( theCompRoot->_is_nil() ) - return; - - SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theCompRoot->GetStudy() ); - if ( aStudy->_is_nil() ) - return; - - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); -} - //============================================================================= /*! * SMESH_Gen_i::Load @@ -4001,30 +5171,23 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile ) { - if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() ) - SetCurrentStudy( theComponent->GetStudy() ); + UpdateStudy(); // load geom data + Kernel_Utils::Localizer loc; - /* if( !theComponent->_is_nil() ) - { - //SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theComponent->GetStudy() ); - if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() ) - loadGeomData( myCurrentStudy->FindComponent( "GEOM" ) ); - }*/ - - StudyContext* myStudyContext = GetCurrentStudyContext(); + SALOMEDS::Study_var aStudy = getStudyServant(); // Get temporary files location TCollection_AsciiString tmpDir = ( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() ); // Convert the stream into sequence of files to process - SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, - tmpDir.ToCString(), - isMultiFile ); + SALOMEDS_Tool::ListOfFiles aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, + tmpDir.ToCString(), + isMultiFile ); TCollection_AsciiString aStudyName( "" ); if ( isMultiFile ) { - CORBA::String_var url = myCurrentStudy->URL(); - aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( url.in() ).c_str(); + CORBA::WString_var url = aStudy->URL(); + aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(url.in()) ).c_str(); } // Set names of temporary files TCollection_AsciiString filename = tmpDir + aStudyName + "_SMESH.hdf"; @@ -4248,6 +5411,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, try { // protect persistence mechanism against exceptions myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); } + catch( SALOME::SALOME_Exception& ex ) + { + INFOS( "Exception during hypothesis creation: " << ex.details.text ); + } catch (...) { INFOS( "Exception during hypothesis creation" ); } @@ -4328,12 +5495,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile ); - - // Make sure GEOM data are loaded first - //loadGeomData( shapeSO->GetFatherComponent() ); - - CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); + SALOMEDS::SObject_wrap shapeSO = aStudy->FindObjectID( refFromFile ); + CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); if ( !CORBA::is_nil( shapeObject ) ) { aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject ); if ( !aShapeObject->_is_nil() ) @@ -4344,7 +5507,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // issue 20918. Restore Persistent Id of SMESHDS_Mesh - if( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) + if ( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) { aDataset = new HDFdataset( "meshPersistentId", aTopGroup ); aDataset->OpenOnDisk(); @@ -4355,6 +5518,28 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId ); delete [] meshPersistentId; } + + // Restore SMESH_Mesh_i::_mainShapeTick + if ( aTopGroup->ExistInternalObject( "shapeTick" )) + { + aDataset = new HDFdataset( "shapeTick", aTopGroup ); + aDataset->OpenOnDisk(); + int* shapeTick = & myNewMeshImpl->MainShapeTick(); + aDataset->ReadFromDisk( shapeTick ); + aDataset->CloseOnDisk(); + } + + // Restore file info + if ( aTopGroup->ExistInternalObject( "file info" )) + { + aDataset = new HDFdataset( "file info", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + std::string info( size, ' '); + aDataset->ReadFromDisk( (char*) info.data() ); + aDataset->CloseOnDisk(); + myNewMeshImpl->FileInfoFromString( info ); + } } } } // reading MESHes @@ -4386,7 +5571,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // get mesh old id CORBA::String_var iorString = GetORB()->object_to_string( myNewMeshImpl->_this() ); int newId = myStudyContext->findId( iorString.in() ); - int id = myStudyContext->getOldId( newId ); + int meshOldId = myStudyContext->getOldId( newId ); // try to find mesh data dataset if ( aTopGroup->ExistInternalObject( "Has data" ) ) { @@ -4398,10 +5583,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( strHasData ); aDataset->CloseOnDisk(); if ( strcmp( strHasData, "1") == 0 ) { - // read mesh data from MED file - // myReader.SetMesh( mySMESHDSMesh ); - // myReader.SetMeshId( id ); - // myReader.Perform(); hasData = true; } delete [] strHasData; @@ -4427,7 +5608,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); // san - it is impossible to recover applied algorithms using their entries within Load() method - //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //SALOMEDS::SObject_wrap hypSO = aStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); delete [] refFromFile; @@ -4464,7 +5645,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); // san - it is impossible to recover applied hypotheses using their entries within Load() method - //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //SALOMEDS::SObject_wrap hypSO = myStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); delete [] refFromFile; @@ -4535,7 +5716,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_wrap subShapeSO = myCurrentStudy->FindObjectID( refFromFile ); + SALOMEDS::SObject_wrap subShapeSO = aStudy->FindObjectID( refFromFile ); CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO ); if ( !CORBA::is_nil( subShapeObject ) ) { aSubShapeObject = GEOM::GEOM_Object::_narrow( subShapeObject ); @@ -4549,6 +5730,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myStudyContext->mapOldToNew( subid, newSubId ); } } + delete [] refFromFile; } if ( aSubMesh->_is_nil() ) @@ -4583,6 +5765,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp ); } } + delete [] refFromFile; } } // close "applied algorithms" HDF group @@ -4618,6 +5801,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp ); } } + delete [] refFromFile; } } // close "APPLIED HYPOTHESES" hdf group @@ -4652,18 +5836,27 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aTopGroup->ExistInternalObject( name_group ) ) { aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->OpenOnDisk(); - // get number of groups - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int j = 0; j < aNbSubObjects; j++ ) { - char name_dataset[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( j, name_dataset ); - // check if it is an group - if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) { + // PAL23514: get all names from the HDFgroup to avoid iteration on its contents + // within aGroup->ExistInternalObject( name ) + std::vector< std::string > subNames; + TColStd_MapOfAsciiString mapOfNames; + aGroup->GetAllObjects( subNames ); + for ( size_t iN = 0; iN < subNames.size(); ++iN ) + 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 - int subid = atoi( string( name_dataset ).substr( 5 ).c_str() ); + char * endptr; + int subid = strtol( name_dataset.data() + 5, &endptr, 10 ); if ( subid <= 0 ) continue; - aDataset = new HDFdataset( name_dataset, aGroup ); + int groupID = -1; // group local ID (also persistent) + if ( *endptr ) + groupID = atoi( endptr + 1 ); + aDataset = new HDFdataset( name_dataset.c_str(), aGroup ); aDataset->OpenOnDisk(); // Retrieve actual group name @@ -4676,7 +5869,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, TopoDS_Shape aShape; char aRefName[ 30 ]; 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 aDataset = new HDFdataset( aRefName, aGroup ); aDataset->OpenOnDisk(); @@ -4685,7 +5879,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile ); + SALOMEDS::SObject_wrap shapeSO = aStudy->FindObjectID( refFromFile ); CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); if ( !CORBA::is_nil( shapeObject ) ) { aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject ); @@ -4693,12 +5887,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aShape = GeomObjectToShape( aShapeObject ); } } + delete [] refFromFile; } // Try to read a filter of SMESH_GroupOnFilter SMESH::Filter_var filter; SMESH_PredicatePtr predicate; - std::string hdfGrpName = "Filter " + SMESH_Comment(subid); - if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) + std::string hdfGrpName = ( SMESH_Comment( "Filter ") << subid ); + if ( mapOfNames.Contains( hdfGrpName.c_str() )) { aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); aDataset->OpenOnDisk(); @@ -4711,12 +5906,14 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); filters.push_back( filter ); } + delete [] persistStr; } // Create group servant SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1); SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate - ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) ); + ( myNewMeshImpl->createGroup( type, nameFromFile, groupID, aShape, predicate ) ); + delete [] nameFromFile; // Obtain a SMESHDS_Group object if ( aNewGroup->_is_nil() ) continue; @@ -4739,13 +5936,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( !aGroupBaseDS ) continue; - aGroupBaseDS->SetStoreName( name_dataset ); + aGroupBaseDS->SetStoreName( name_dataset.c_str() ); // ouv : NPAL12872 // Read color of the group char aGroupColorName[ 30 ]; sprintf( aGroupColorName, "ColorGroup %d", subid); - if ( aGroup->ExistInternalObject( aGroupColorName ) ) + if ( mapOfNames.Contains( aGroupColorName )) { aDataset = new HDFdataset( aGroupColorName, aGroup ); aDataset->OpenOnDisk(); @@ -4755,6 +5952,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); aGroupBaseDS->SetColor( aColor ); + delete [] anRGB; } } } @@ -4763,16 +5961,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // reading GROUPs // instead of reading mesh data, we read only brief information of all - // objects: mesh, groups, sub-meshes (issue 0021208 ) + // objects: mesh, groups, sub-meshes (issue 0021208) if ( hasData ) { - SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id, + SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, meshOldId, meshfile.ToCString(), filename.ToCString(), !isMultiFile ); } // read Sub-Mesh ORDER if any - if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { + if ( aTopGroup->ExistInternalObject( "Mesh Order" )) { aDataset = new HDFdataset( "Mesh Order", aTopGroup ); aDataset->OpenOnDisk(); size = aDataset->GetSize(); @@ -4788,6 +5986,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, anOrderIds.back().push_back(smIDs[ i ]); myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); + delete [] smIDs; } } // loop on meshes @@ -4835,7 +6034,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, SMESH_File meshFile( meshfile.ToCString() ); if ( !meshFile ) // no meshfile exists { - SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq, true ); } else { @@ -4852,12 +6051,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // creation of tree nodes for all data objects in the study // to support tree representation customization and drag-n-drop: - SALOMEDS::Study_var study = theComponent->GetStudy(); - SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = study->GetUseCaseBuilder(); + SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = aStudy->GetUseCaseBuilder(); if ( !useCaseBuilder->IsUseCaseNode( theComponent ) ) { useCaseBuilder->SetRootCurrent(); useCaseBuilder->Append( theComponent ); // component object is added as the top level item - SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent ); + SALOMEDS::ChildIterator_wrap it = aStudy->NewChildIterator( theComponent ); for (it->InitEx(true); it->More(); it->Next()) { useCaseBuilder->AppendTo( it->Value()->GetFather(), it->Value() ); } @@ -4917,22 +6115,15 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" ); - // set correct current study - SALOMEDS::Study_var study = theComponent->GetStudy(); - if ( study->StudyId() != GetCurrentStudyID()) - setCurrentStudy( study, /*IsBeingClosed=*/true ); - // Clear study contexts data - int studyId = GetCurrentStudyID(); - if ( myStudyContextMap.find( studyId ) != myStudyContextMap.end() ) { - delete myStudyContextMap[ studyId ]; - myStudyContextMap.erase( studyId ); - } + myStudyContext->Clear(); // remove the tmp files meshes are loaded from SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent ); - myCurrentStudy = SALOMEDS::Study::_nil(); + // Clean trace of API methods calls + CleanPythonTrace(); + return; } @@ -4965,7 +6156,6 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" ); - StudyContext* myStudyContext = GetCurrentStudyContext(); if ( myStudyContext && strcmp( IORString, "" ) != 0 ) { int anId = myStudyContext->findId( IORString ); @@ -4993,7 +6183,6 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID ); - StudyContext* myStudyContext = GetCurrentStudyContext(); if ( myStudyContext && strcmp( aLocalPersistentID, "" ) != 0 ) { int anId = atoi( aLocalPersistentID ); @@ -5009,7 +6198,6 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) { - StudyContext* myStudyContext = GetCurrentStudyContext(); if ( myStudyContext && !CORBA::is_nil( theObject )) { CORBA::String_var iorString = GetORB()->object_to_string( theObject ); return myStudyContext->addObject( string( iorString.in() ) ); @@ -5027,7 +6215,6 @@ int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject) { - StudyContext* myStudyContext = GetCurrentStudyContext(); if ( myStudyContext && !CORBA::is_nil( theObject )) { string iorString = GetORB()->object_to_string( theObject ); return myStudyContext->findId( iorString ); @@ -5047,18 +6234,13 @@ void SMESH_Gen_i::SetName(const char* theIOR, { if ( theIOR && strcmp( theIOR, "" ) ) { CORBA::Object_var anObject = GetORB()->string_to_object( theIOR ); - SALOMEDS::SObject_wrap aSO = ObjectToSObject( myCurrentStudy, anObject ); + SALOMEDS::SObject_wrap aSO = ObjectToSObject( anObject ); if ( !aSO->_is_nil() ) { SetName( aSO, theName ); } } } -int SMESH_Gen_i::GetCurrentStudyID() -{ - return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId(); -} - // Version information char* SMESH_Gen_i::getVersion() { @@ -5080,9 +6262,8 @@ void SMESH_Gen_i::Move( const SMESH::sobject_list& what, { if ( CORBA::is_nil( where ) ) return; - SALOMEDS::Study_var study = where->GetStudy(); - SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder(); - SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder(); + SALOMEDS::StudyBuilder_var studyBuilder = getStudyServant()->NewBuilder(); + SALOMEDS::UseCaseBuilder_var useCaseBuilder = getStudyServant()->GetUseCaseBuilder(); SALOMEDS::SComponent_var father = where->GetFatherComponent(); std::string dataType = father->ComponentDataType(); if ( dataType != "SMESH" ) return; // not a SMESH component @@ -5134,7 +6315,8 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, if (aCreator) { TopoDS_Shape shape = GeomObjectToShape( theGeomObject ); - return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll ); + const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType ); + return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim ); } else {