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=9fce23337f80410db0b0cc76714487d90492dd25;hp=f994b82f0762ac67efd7c632710618cb0685a379;hb=e8af688e3b07bdb0324e59760e978a60180efde5;hpb=aa574473cfc2112ef654904d6f2af9fd6e46d4c7 diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index f994b82f0..9fce23337 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-2021 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 @@ -49,7 +49,6 @@ #include #include - #ifdef WIN32 #include #include @@ -103,6 +102,10 @@ #include "SMESH_PreMeshInfo.hxx" #include "SMESH_PythonDump.hxx" #include "SMESH_ControlsDef.hxx" +#include + +// 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) @@ -110,6 +113,7 @@ #include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include #include #include @@ -138,6 +142,11 @@ #include #include #include +#include + +#include +#include +#include using namespace std; using SMESH::TPythonDump; @@ -152,12 +161,12 @@ 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; -SALOME_LifeCycleCORBA* SMESH_Gen_i::myLCC = NULL; -SMESH_Gen_i* SMESH_Gen_i::mySMESHGen = NULL; +SALOME_NamingService_Abstract* SMESH_Gen_i::myNS = nullptr; +SALOME_LifeCycleCORBA* SMESH_Gen_i::myLCC = nullptr; +SMESH_Gen_i* SMESH_Gen_i::mySMESHGen = nullptr; const int nbElemPerDiagonal = 10; @@ -180,22 +189,22 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb } catch (PortableServer::POA::ObjectNotActive &ex) { - INFOS("GetServant: ObjectNotActive"); + MESSAGE("GetServant: ObjectNotActive"); return NULL; } catch (PortableServer::POA::WrongAdapter &ex) { - INFOS("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel..."); + MESSAGE("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel..."); return NULL; } catch (PortableServer::POA::WrongPolicy &ex) { - INFOS("GetServant: WrongPolicy"); + MESSAGE("GetServant: WrongPolicy"); return NULL; } catch (...) { - INFOS( "GetServant - Unknown exception was caught!!!" ); + MESSAGE( "GetServant - Unknown exception was caught!!!" ); return NULL; } } @@ -228,6 +237,14 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject return anObj; } +// Set Naming Service object +void SMESH_Gen_i::SetNS(SALOME_NamingService_Abstract *ns) +{ + if(myNS) + delete myNS; + myNS = ns; +} + //============================================================================= /*! * GetNS [ static ] @@ -236,9 +253,9 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject */ //============================================================================= -SALOME_NamingService* SMESH_Gen_i::GetNS() +SALOME_NamingService_Abstract* SMESH_Gen_i::GetNS() { - if ( myNS == NULL ) { + if ( !myNS ) { myNS = SINGLETON_::Instance(); ASSERT(SINGLETON_::IsAlreadyExisting()); myNS->init_orb( GetORB() ); @@ -253,14 +270,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 ] @@ -268,16 +286,13 @@ 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); - } - return myGeomGen; + +GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( GEOM::GEOM_Object_ptr go ) +{ + GEOM::GEOM_Gen_ptr gen = GEOM::GEOM_Gen::_nil(); + if ( !CORBA::is_nil( go )) + gen = go->GetGen(); + return gen; } //============================================================================= @@ -304,8 +319,9 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, PortableServer::ObjectId* contId, const char* instanceName, - const char* interfaceName ) - : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) + const char* interfaceName, + bool checkNS) + : Engines_Component_i( orb, poa, contId, instanceName, interfaceName, false, checkNS ) { myOrb = CORBA::ORB::_duplicate(orb); @@ -330,21 +346,24 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, // find out mode (embedded or standalone) here else // meshes created before calling SMESH_Client::GetSMESHGen(), which calls // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag - if ( SALOME_NamingService* ns = GetNS() ) + if(checkNS) { - CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" ); - SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; - if ( !session->_is_nil() ) + if ( SALOME_NamingService_Abstract* ns = GetNS() ) { - CORBA::String_var str_host = session->getHostname(); - CORBA::Long s_pid = session->getPID(); - string my_host = Kernel_Utils::GetHostname(); + CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; + if ( !session->_is_nil() ) + { + CORBA::String_var str_host = session->getHostname(); + CORBA::Long s_pid = session->getPID(); + string my_host = Kernel_Utils::GetHostname(); #ifdef WIN32 - long my_pid = (long)_getpid(); + long my_pid = (long)_getpid(); #else - long my_pid = (long) getpid(); + long my_pid = (long) getpid(); #endif - SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() ); + SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() ); + } } } } @@ -381,6 +400,7 @@ SMESH_Gen_i::~SMESH_Gen_i() if ( myShapeReader ) delete myShapeReader; } + //============================================================================= /*! * SMESH_Gen_i::getHypothesisCreator @@ -388,10 +408,10 @@ SMESH_Gen_i::~SMESH_Gen_i() * Get hypothesis creator */ //============================================================================= + GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHypName, const char* theLibName, std::string& thePlatformLibName) - throw (SALOME::SALOME_Exception) { std::string aPlatformLibName; /* It's Need to translate lib name for WIN32 or X platform */ @@ -439,15 +459,27 @@ 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); + SMESHUtils::ArrayDeleter deleter( path ); +# else + const char* path = aPlatformLibName.c_str(); +# endif +#else + const char* path = aPlatformLibName.c_str(); +#endif + LibHandle libHandle = LoadLib( path ); + if (!libHandle) { // 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 } @@ -457,7 +489,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); } @@ -466,7 +499,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; @@ -491,6 +525,7 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp * Create hypothesis of given type */ //============================================================================= + SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName, const char* theLibName) { @@ -512,7 +547,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName hypothesis_i = myHypothesis_i->_this(); int nextId = RegisterObject( hypothesis_i ); if(MYDEBUG) { MESSAGE( "Add hypo to map with id = "<< nextId ); } - else { nextId = 0; } // avoid "unused variable" warning in release mode + else { (void)nextId; } // avoid "unused variable" warning in release mode } return hypothesis_i._retn(); } @@ -524,8 +559,8 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName * Create empty mesh on shape */ //============================================================================= + SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::createMesh" ); @@ -542,7 +577,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() ); int nextId = RegisterObject( mesh ); if(MYDEBUG) { MESSAGE( "Add mesh to map with id = "<< nextId); } - else { nextId = 0; } // avoid "unused variable" warning in release mode + else { (void)nextId; } // avoid "unused variable" warning in release mode return mesh._retn(); } catch (SALOME_Exception& S_ex) { @@ -558,6 +593,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() * Get shape reader */ //============================================================================= + GEOM_Client* SMESH_Gen_i::GetShapeReader() { // create shape reader if necessary @@ -574,13 +610,10 @@ GEOM_Client* SMESH_Gen_i::GetShapeReader() * Set GEOM::GEOM_Gen reference */ //============================================================================= -//GEOM::GEOM_Gen_ptr SMESH_Gen_i::SetGeomEngine( const char* containerLoc ) + void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ) { - //Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component(containerLoc,"GEOM"); - //myGeomGen=GEOM::GEOM_Gen::_narrow(temp); - myGeomGen=GEOM::GEOM_Gen::_duplicate(geomcompo); - //return myGeomGen; + myGeomGen = GEOM::GEOM_Gen::_duplicate( geomcompo ); } //============================================================================= @@ -635,6 +668,7 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode() * Set enable publishing in the study */ //============================================================================= + void SMESH_Gen_i::SetEnablePublish( CORBA::Boolean theIsEnablePublish ) { myIsEnablePublish = theIsEnablePublish; @@ -667,11 +701,18 @@ void SMESH_Gen_i::UpdateStudy() myStudyContext = new StudyContext; SALOMEDS::Study_var aStudy = getStudyServant(); - if ( !CORBA::is_nil( aStudy ) ) { + 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() ); + aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/false ) ); + + GEOM_var = aStudy->FindComponent( "SHAPERSTUDY" ); + if( !GEOM_var->_is_nil() ) + aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/true ) ); + // NPAL16168, issue 0020210 // Let meshes update their data depending on GEOM groups that could change CORBA::String_var compDataType = ComponentDataType(); @@ -688,6 +729,63 @@ void SMESH_Gen_i::UpdateStudy() } } +//================================================================================ +/*! + * \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 +//================================================================================= + +char* SMESH_Gen_i::getObjectInfo( const char* entry ) +{ + // 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::GetStudyContext @@ -695,6 +793,7 @@ void SMESH_Gen_i::UpdateStudy() * Get study context */ //============================================================================= + StudyContext* SMESH_Gen_i::GetStudyContext() { return myStudyContext; @@ -704,13 +803,12 @@ StudyContext* SMESH_Gen_i::GetStudyContext() /*! * 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 */ //============================================================================= SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName, const char* theLibName ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); // Create hypothesis/algorithm @@ -721,7 +819,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam SALOMEDS::SObject_wrap aSO = PublishHypothesis( hyp ); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateHypothesis('" + TPythonDump(this) << aSO << " = " << this << ".CreateHypothesis('" << theHypName << "', '" << theLibName << "')"; } } @@ -729,6 +827,42 @@ 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) +{ + 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(this) << hyp << " = " << this << ".CreateHypothesisByAverageLength( '" + << theHypType << "', '" + << theLibName << "', " + << theAverageLength << ", " + << theQuadDominated << " )"; + + return hyp._retn(); +} + //================================================================================ /*! * \brief Return a hypothesis holding parameter values corresponding either to the mesh @@ -744,14 +878,15 @@ 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) - throw ( SALOME::SALOME_Exception ) +SMESH_Gen_i::GetHypothesisParameterValues( const char* theHypType, + const char* theLibName, + SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theGeom, + const SMESH::HypInitParams& theParams) { 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 ) ) @@ -806,17 +941,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 ); } @@ -924,26 +1066,26 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr //============================================================================= /*! - * Sets number of segments per diagonal of boundary box of geometry by which + * Set number of segments per diagonal of boundary box of geometry by which * default segment length of appropriate 1D hypotheses is defined */ //============================================================================= void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments ) - throw ( SALOME::SALOME_Exception ) { if ( theNbSegments > 0 ) myGen.SetBoundaryBoxSegmentation( int( theNbSegments )); else THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM ); } + //============================================================================= - /*! - * \brief Sets default number of segments per edge - */ +/*! + * \brief Set default number of segments per edge + */ //============================================================================= + void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments) - throw ( SALOME::SALOME_Exception ) { if ( theNbSegments > 0 ) myGen.SetDefaultNbSegments( int(theNbSegments) ); @@ -953,8 +1095,8 @@ void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments) //============================================================================= /*! - Set an option value -*/ + * Set an option value + */ //============================================================================= void SMESH_Gen_i::SetOption(const char* name, const char* value) @@ -1016,8 +1158,8 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value) //============================================================================= /*! - Return an option value -*/ + * Return an option value + */ //============================================================================= char* SMESH_Gen_i::GetOption(const char* name) @@ -1049,7 +1191,6 @@ char* SMESH_Gen_i::GetOption(const char* name) //============================================================================= SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObject ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" ); @@ -1068,7 +1209,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")"; + TPythonDump(this) << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")"; } } @@ -1084,7 +1225,6 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj //============================================================================= SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh() - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" ); @@ -1099,7 +1239,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh() aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateEmptyMesh()"; + TPythonDump(this) << aSO << " = " << this << ".CreateEmptyMesh()"; } } @@ -1110,11 +1250,11 @@ namespace { //================================================================================ /*! - * \brief Throws an exception in case if the file can't be read + * \brief Throw an exception in case if the file can't be read */ //================================================================================ - void checkFileReadable( const char* theFileName ) throw ( SALOME::SALOME_Exception ) + void checkFileReadable( const char* theFileName ) { SMESH_File f ( theFileName ); if ( !f ) @@ -1138,7 +1278,6 @@ namespace //============================================================================= SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); @@ -1154,7 +1293,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')"; + TPythonDump(this) << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')"; } } @@ -1177,17 +1316,17 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName */ //============================================================================= -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus, - const char* theCommandNameForPython, - const char* theFileNameForPython) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus ) { + checkFileReadable( theFileName ); + #ifdef WIN32 char bname[ _MAX_FNAME ]; - _splitpath( theFileNameForPython, NULL, NULL, bname, NULL ); + _splitpath( theFileName, NULL, NULL, bname, NULL ); string aFileName = bname; #else - string aFileName = basename( const_cast(theFileNameForPython) ); + string aFileName = basename( const_cast( theFileName )); #endif // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; @@ -1200,59 +1339,57 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() - // Python Dump - TPythonDump aPythonDump; - aPythonDump << "(["; + // Python Dump + TPythonDump aPythonDump(this); + aPythonDump << "(["; - if (theStatus == SMESH::DRS_OK) { - SALOMEDS::StudyBuilder_var aStudyBuilder; - aStudyBuilder = getStudyServant()->NewBuilder(); - aStudyBuilder->NewCommand(); // There is a transaction + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder; + aStudyBuilder = getStudyServant()->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction - aResult->length( aNames.size() ); - int i = 0; + aResult->length( aNames.size() ); + int i = 0; - // Iterate through all meshes and create mesh objects - for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) - { - // Python Dump - if (i > 0) aPythonDump << ", "; - - // create mesh - SMESH::SMESH_Mesh_var mesh = createMesh(); - - // publish mesh in the study - SALOMEDS::SObject_wrap aSO; - if ( CanPublishInStudy( mesh ) ) - // 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( mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() ); - - // Python Dump - if ( !aSO->_is_nil() ) { - aPythonDump << aSO; - } else { - aPythonDump << "mesh_" << i; - } + // Iterate through all meshes and create mesh objects + for ( const std::string & meshName : aNames ) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); - // Read mesh data (groups are published automatically by ImportMEDFile()) - SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); - ASSERT( meshServant ); - SMESH::DriverMED_ReadStatus status1 = - meshServant->ImportMEDFile( theFileName, (*it).c_str() ); - if (status1 > theStatus) - theStatus = status1; + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if ( CanPublishInStudy( mesh ) ) + aSO = PublishMesh( mesh.in(), meshName.c_str() ); + + // Python Dump + if ( !aSO->_is_nil() ) { + aPythonDump << aSO; + } else { + aPythonDump << "mesh_" << i; + } + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportMEDFile( theFileName, meshName.c_str() ); + if (status1 > theStatus) + theStatus = status1; - aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); - meshServant->GetImpl().GetMeshDS()->Modified(); + aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); + } + if ( !aStudyBuilder->_is_nil() ) + aStudyBuilder->CommitCommand(); } - if ( !aStudyBuilder->_is_nil() ) - aStudyBuilder->CommitCommand(); - } - // Update Python script - aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')"; + // Update Python script + aPythonDump << "], status) = " << this << ".CreateMeshesFromMED( r'" << theFileName << "' )"; } // Dump creation of groups for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) @@ -1261,58 +1398,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa return aResult._retn(); } -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) -{ - Unexpect aCatch(SALOME_SalomeException); - checkFileReadable( theFileName ); - - SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName); - return result; -} - -//============================================================================= -/*! - * SMESH_Gen_i::CreateMeshFromSAUV - * - * Create mesh and import data from SAUV file - */ -//============================================================================= - -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) -{ - Unexpect aCatch(SALOME_SalomeException); - checkFileReadable( theFileName ); - - std::string sauvfilename(theFileName); - std::string medfilename(theFileName); - medfilename += ".med"; - std::string cmd; -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str()); -#ifdef WIN32 - cmd = "%PYTHONBIN% "; -#else - cmd = "python3 "; -#endif - cmd += "-c \""; - cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; - cmd += "\""; - system(cmd.c_str()); - return result; -} - //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL @@ -1322,7 +1407,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, //============================================================================= SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); checkFileReadable( theFileName ); @@ -1344,7 +1428,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; + TPythonDump(this) << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; } } @@ -1361,9 +1445,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName */ //================================================================================ -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); checkFileReadable( theFileName ); @@ -1383,7 +1466,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() // Python Dump - TPythonDump aPythonDump; + TPythonDump aPythonDump(this); aPythonDump << "(["; if (theStatus == SMESH::DRS_OK) @@ -1451,7 +1534,6 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, CORBA::Boolean theMakeRequiredGroups, SMESH::ComputeError_out theError) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); checkFileReadable( theFileName ); @@ -1472,7 +1554,7 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'" + TPythonDump(this) << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'" << theFileName << "', " << theMakeRequiredGroups << " )"; } @@ -1489,13 +1571,12 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, /*! * SMESH_Gen_i::IsReadyToCompute * - * Returns true if mesh contains enough data to be computed + * Return true if mesh contains enough data to be computed */ //============================================================================= CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" ); @@ -1503,11 +1584,9 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, if ( CORBA::is_nil( theShapeObject ) ) THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); - if ( CORBA::is_nil( theMesh ) ) THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM ); - try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); @@ -1535,7 +1614,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) { if ( algo ) { - SALOMEDS::Study_var aStudy = getStudyServant(); + SALOMEDS::Study_var aStudy = getStudyServant(); if ( !aStudy->_is_nil() ) { // find algo in the study CORBA::String_var compDataType = ComponentDataType(); @@ -1572,7 +1651,6 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" ); @@ -1647,7 +1725,6 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr SMESH::MeshPreviewStruct* SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, CORBA::Short theSubShapeID ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetBadInputElements()" ); @@ -1735,7 +1812,6 @@ SMESH::ListOfGroups* SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, CORBA::Short theSubShapeID, const char* theGroupName ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); @@ -1748,7 +1824,7 @@ SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, if ( SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh )) { groups = meshServant->MakeGroupsOfBadInputElements( theSubShapeID, theGroupName ); - TPythonDump() << groups << " = " << this + TPythonDump(this) << groups << " = " << this << ".MakeGroupsOfBadInputElements( " << theMesh << ", " << theSubShapeID << ", '" << theGroupName << "' )"; } @@ -1762,15 +1838,14 @@ SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, //================================================================================ /*! * \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 + * \param theMesh - the mesh + * \param theSubObject - the main or sub- shape + * \retval SMESH::algo_error_array* - sequence of errors */ //================================================================================ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" ); @@ -1832,7 +1907,6 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject, const SMESH::object_array& theListOfSubShapeObject ) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" ); @@ -1906,7 +1980,6 @@ SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject, CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) - throw ( SALOME::SALOME_Exception ) { //MEMOSTAT; Unexpect aCatch(SALOME_SalomeException); @@ -1921,15 +1994,18 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, SALOME::BAD_PARAM ); // Update Python script - TPythonDump() << "isDone = " << this << ".Compute( " + TPythonDump(this) << "isDone = " << this << ".Compute( " << theMesh << ", " << theShapeObject << ")"; 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(); + 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 @@ -1948,10 +2024,12 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) myLocMesh.GetMeshDS()->Modified(); UpdateIcons( theMesh ); + if ( ok ) + HighLightInvalid( theMesh, /*isInvalid=*/false ); return ok; } } - catch ( std::bad_alloc ) { + catch ( std::bad_alloc& ) { INFOS( "Compute(): lack of memory" ); } catch ( SALOME_Exception& S_ex ) { @@ -1974,14 +2052,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); + } } //============================================================================= @@ -1996,7 +2076,6 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh GEOM::GEOM_Object_ptr theShapeObject, SMESH::Dimension theDimension, SMESH::long_array& theShapesId) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" ); @@ -2023,7 +2102,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh if(theMesh->HasShapeToMesh()) myLocShape = GeomObjectToShape( theShapeObject ); else - return result._retn();; + return result._retn(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); @@ -2160,7 +2239,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh } } } - catch ( std::bad_alloc ) { + catch ( std::bad_alloc& ) { INFOS( "Precompute(): lack of memory" ); } catch ( SALOME_Exception& S_ex ) { @@ -2181,30 +2260,26 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh */ //============================================================================= -SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, - GEOM::GEOM_Object_ptr theShapeObject) -// SMESH::long_array& theNbElems) - throw ( SALOME::SALOME_Exception ) +SMESH::smIdType_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", - SALOME::BAD_PARAM ); + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) - THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", - SALOME::BAD_PARAM ); + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM ); - SMESH::long_array_var nbels = new SMESH::long_array; + SMESH::smIdType_array_var nbels = new SMESH::smIdType_array; nbels->length(SMESH::Entity_Last); int i = SMESH::Entity_Node; for (; i < SMESH::Entity_Last; i++) nbels[i] = 0; // Update Python script - TPythonDump() << "theNbElems = " << this << ".Evaluate( " + TPythonDump(this) << "theNbElems = " << this << ".Evaluate( " << theMesh << ", " << theShapeObject << ")"; try { @@ -2227,9 +2302,9 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap); MapShapeNbElemsItr anIt = aResMap.begin(); for(; anIt!=aResMap.end(); anIt++) { - const vector& aVec = (*anIt).second; + const vector& aVec = (*anIt).second; for ( i = SMESH::Entity_Node; i < (int)aVec.size(); i++ ) { - int nbElem = aVec[i]; + smIdType nbElem = aVec[i]; if ( nbElem < 0 ) // algo failed, check that it has reported a message { SMESH_subMesh* sm = anIt->first; @@ -2247,7 +2322,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, return nbels._retn(); } } - catch ( std::bad_alloc ) { + catch ( std::bad_alloc& ) { INFOS( "Evaluate(): lack of memory" ); } catch ( SALOME_Exception& S_ex ) { @@ -2272,16 +2347,15 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, - CORBA::Long theElementID, + SMESH::smIdType theElementID, const char* theGeomName) - throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); 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( geom.in() ); @@ -2312,7 +2386,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } } } - if ( SObj->_is_nil() ) // publish a new subshape + if ( SObj->_is_nil() && !geomGen->_is_nil() ) // publish a new subshape SObj = geomGen->AddInStudy( geom, theGeomName, mainShape ); // return only published geometry @@ -2337,15 +2411,14 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, - CORBA::Long theElementID) - throw ( SALOME::SALOME_Exception ) + SMESH::smIdType theElementID) { Unexpect aCatch(SALOME_SalomeException); if ( CORBA::is_nil( 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 ); @@ -2368,7 +2441,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } 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() ) { @@ -2412,14 +2485,15 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) - throw ( SALOME::SALOME_Exception ) + CORBA::Double theMergeTolerance, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) { return ConcatenateCommon(theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - false); + false, + theMeshToAppendTo); } //================================================================================ @@ -2435,14 +2509,15 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) - throw ( SALOME::SALOME_Exception ) + CORBA::Double theMergeTolerance, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) { return ConcatenateCommon(theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - true); + true, + theMeshToAppendTo); } //================================================================================ @@ -2458,16 +2533,21 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, CORBA::Boolean theUniteIdenticalGroups, CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance, - CORBA::Boolean theCommonGroups) - throw ( SALOME::SALOME_Exception ) + CORBA::Boolean theCommonGroups, + SMESH::SMESH_Mesh_ptr theMeshToAppendTo) { - std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump ); + std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump(this) ); TPythonDump& pythonDump = *pPythonDump; // prevent dump of called methods - // create mesh - SMESH::SMESH_Mesh_var newMesh = CreateEmptyMesh(); - SMESH_Mesh_i* newImpl = SMESH::DownCast( newMesh ); + // 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& locMesh = newImpl->GetImpl(); SMESHDS_Mesh* newMeshDS = locMesh.GetMeshDS(); @@ -2478,6 +2558,22 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, TGroupsMap groupsMap; TListOfNewGroups listOfNewGroups; + 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 newEditor( &locMesh ); ::SMESH_MeshEditor::ElemFeatures elemType; @@ -2488,9 +2584,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, 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(); - // assure that IDs increments by one during iteration + // assure that IDs increment by one during iteration ::SMESH_Mesh& initLocMesh = initImpl->GetImpl(); SMESHDS_Mesh* initMeshDS = initLocMesh.GetMeshDS(); if ( initMeshDS->MaxNodeID() > initMeshDS->NbNodes() || @@ -2501,7 +2599,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, } // remember nb of elements before filling in - SMESH::long_array_var prevState = newMesh->GetNbElementsByType(); + SMESH::smIdType_array_var prevState = newMesh->GetNbElementsByType(); // copy nodes @@ -2515,6 +2613,9 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, // copy elements + 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() ) @@ -2543,12 +2644,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, { // 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(); + // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed: + static_assert( sizeof(typeNames) / sizeof(const char*) ==SMESH::NB_ELEMENT_TYPES, + "Update names of ElementType's!!!" ); + + SMESH::smIdType_array_var curState = newMesh->GetNbElementsByType(); for( groupType = SMESH::NODE; groupType < SMESH::NB_ELEMENT_TYPES; @@ -2595,7 +2696,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, SMESH::SMESH_GroupBase_ptr group; CORBA::String_var groupName; - SMESH::long_array_var newIDs = new SMESH::long_array(); + SMESH::smIdType_array_var newIDs = new SMESH::smIdType_array(); // loop on groups of a source mesh SMESH::ListOfGroups_var listOfGroups = initImpl->GetGroups(); @@ -2674,11 +2775,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, // Update Python script pythonDump << newMesh << " = " << this - << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "(" + << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "( " << theMeshesArray << ", " << theUniteIdenticalGroups << ", " << theMergeNodesAndElements << ", " - << TVar( theMergeTolerance ) << ")"; + << TVar( theMergeTolerance ) << ", " + << theMeshToAppendTo << " )"; pPythonDump.reset(); // enable python dump from GetGroups() @@ -2715,7 +2817,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, { Unexpect aCatch(SALOME_SalomeException); - TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh() + TPythonDump* pyDump = new TPythonDump(this); // prevent dump from CreateMesh() + std::unique_ptr pyDumpDeleter( pyDump ); // 1. Get source mesh @@ -2758,7 +2861,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, } else { - SMESH::long_array_var ids = meshPart->GetIDs(); + SMESH::smIdType_array_var ids = meshPart->GetIDs(); if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes { for ( CORBA::ULong i=0; i < ids->length(); i++ ) @@ -2881,8 +2984,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, { TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ]; if ( e2eMap.empty() ) continue; - int minID = e2eMap.begin()->first->GetID(); - int maxID = e2eMap.rbegin()->first->GetID(); + smIdType minID = e2eMap.begin()->first->GetID(); + smIdType maxID = e2eMap.rbegin()->first->GetID(); TE2EMap::iterator e2e; while ( eIt->more() && groupElems.size() < e2eMap.size()) { @@ -2918,7 +3021,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(); @@ -2926,58 +3029,1021 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, return newMesh._retn(); } -//================================================================================ -/*! - * \brief Get version of MED format being used. - */ -//================================================================================ -char* SMESH_Gen_i::GetMEDFileVersion() +namespace // utils for CopyMeshWithGeom() { - 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() ); -} + 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; -//================================================================================ -/*! - * 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() ); -} + //================================================================================ + /*! + * \brief Return a new sub-shape corresponding to an old one + */ + //================================================================================ -//================================================================================ -/*! - * 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 ); -} + 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 )); + } + } + } + } -//================================================================================ -/*! - * 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 ); -} + //================================================================================ + /*! + * \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_wrap 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) +{ + 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(this); // 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::smIdType_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 ); +} //================================================================================ /*! @@ -2987,13 +4053,12 @@ CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName) */ //================================================================================ 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++ ) { @@ -3011,10 +4076,14 @@ SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName) * Save SMESH module's data */ //============================================================================= + SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile ) { + // localizing + Kernel_Utils::Localizer loc; + if (!myStudyContext) UpdateStudy(); @@ -3068,11 +4137,15 @@ 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 - DriverMED_W_SMESHDS_Mesh myWriter; - myWriter.SetFile( meshfile.ToCString() ); + DriverMED_W_SMESHDS_Mesh writer; + writer.SetFile( meshfile.ToCString() ); + //writer.SetSaveNumbers( false ); // bos #24400 -- it leads to change of element IDs // IMP issue 20918 // SetStoreName() to groups before storing hypotheses to let them refer to @@ -3087,7 +4160,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ; if ( !myMesh->_is_nil() ) { myMesh->Load(); // load from study file if not yet done - TPythonDump pd; // not to dump GetGroups() + TPythonDump pd(this); // not to dump GetGroups() SMESH::ListOfGroups_var groups = myMesh->GetGroups(); for ( CORBA::ULong i = 0; i < groups->length(); ++i ) { @@ -3097,7 +4170,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 ); } @@ -3147,8 +4220,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, #else // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning - //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif @@ -3217,8 +4288,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, #else // PAL17753 (Regression: missing hypothesis in restored study) // "lib" also should be removed from the beginning - //if( libname_len > 3 ) - //libname.resize( libname_len - 3 ); if( libname_len > 6 ) libname = libname.substr( 3, libname_len - 3 - 3 ); #endif @@ -3283,8 +4352,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // check if the mesh is not empty if ( mySMESHDSMesh->NbNodes() > 0 ) { // write mesh data to med file - myWriter.SetMesh( mySMESHDSMesh ); - myWriter.SetMeshId( id ); + writer.SetMesh( mySMESHDSMesh ); + writer.SetMeshId( id ); strHasData = "1"; } aSize[ 0 ] = strHasData.length() + 1; @@ -3321,10 +4390,18 @@ 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; - bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef.inout() ); + bool found = gotBranch->FindSubObject( (CORBA::Long)GetRefOnShapeTag(), myRef.inout() ); if ( found ) { SALOMEDS::SObject_wrap myShape; bool ok = myRef->ReferencedObject( myShape.inout() ); @@ -3355,7 +4432,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // write applied hypotheses if exist SALOMEDS::SObject_wrap myHypBranch; - found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() ); + found = gotBranch->FindSubObject( (CORBA::Long)GetRefOnAppliedHypothesisTag(), myHypBranch.inout() ); if ( found && !shapeRefFound && hasShape ) { // remove applied hyps aStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch ); } @@ -3614,14 +4691,11 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } } - // All sub-meshes will be stored in MED file - // .. will NOT (PAL 12992) - //if ( shapeRefFound ) - //myWriter.AddAllSubMeshes(); // store submesh order if any const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder(); - if ( theOrderIds.size() ) { + const bool isNewOrederVersion = true; // old version saves ids, new one, entries + if ( !theOrderIds.empty() && !isNewOrederVersion ) { // keep old version for reference char order_list[ 30 ]; strcpy( order_list, "Mesh Order" ); // count number of submesh ids @@ -3652,6 +4726,38 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // delete[] smIDs; } + if ( !theOrderIds.empty() && isNewOrederVersion ) + { + // convert ids to entries + std::list< std::list< std::string > > orderEntryLists; + for ( const TListOfInt& idList : theOrderIds ) + { + orderEntryLists.emplace_back(); + std::list< std::string > & entryList = orderEntryLists.back(); + for ( const int& id : idList ) + { + const TopoDS_Shape& shape = mySMESHDSMesh->IndexToShape( id ); + GEOM::GEOM_Object_var go = ShapeToGeomObject( shape ); + SALOMEDS::SObject_var so = ObjectToSObject( go ); + if ( !so->_is_nil() ) + { + CORBA::String_var entry = so->GetID(); + entryList.emplace_back( entry.in() ); + } + } + } + // convert orderEntryLists to string + std::ostringstream ostream; + boost::archive::text_oarchive( ostream ) << orderEntryLists; + std::string orderEntryString = ostream.str(); + + // write HDF group + aSize[ 0 ] = orderEntryString.size() + 1; + aDataset = new HDFdataset( "MeshOrder_new", aTopGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk((char*) orderEntryString.data() ); + aDataset->CloseOnDisk(); + } // groups root sub-branch SALOMEDS::SObject_wrap myGroupsBranch; @@ -3721,7 +4827,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // Pass SMESHDS_Group to MED writer SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); + writer.AddGroup( aGrpDS ); // write reference on a shape if exists SMESHDS_GroupOnGeom* aGeomGrp = @@ -3746,7 +4852,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, else // shape ref is invalid: { // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); + writer.AddGroup( aGeomGrp ); } } else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = @@ -3769,7 +4875,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( strcmp( strHasData.c_str(), "1" ) == 0 ) { // Flush current mesh information into MED file - myWriter.Perform(); + writer.Perform(); // save info on nb of elements SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile ); @@ -3796,7 +4902,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, { SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All ); - int nbElems = isNode ? mySMESHDSMesh->NbNodes() : mySMESHDSMesh->GetMeshInfo().NbElements(); + smIdType nbElems = isNode ? mySMESHDSMesh->NbNodes() : mySMESHDSMesh->GetMeshInfo().NbElements(); if ( nbElems < 1 ) continue; std::vector smIDs; smIDs.reserve( nbElems ); @@ -3837,7 +4943,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, SMESHDS_SubMesh* aSubMesh = const_cast< SMESHDS_SubMesh* >( smIt->next() ); if ( aSubMesh->IsComplexSubmesh() ) continue; // submesh containing other submeshs - int nbNodes = aSubMesh->NbNodes(); + smIdType nbNodes = aSubMesh->NbNodes(); if ( nbNodes == 0 ) continue; int aShapeID = aSubMesh->GetID(); @@ -3996,23 +5102,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::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder(); - aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); -} - //============================================================================= /*! * SMESH_Gen_i::Load @@ -4026,14 +5115,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, const char* theURL, bool isMultiFile ) { - //if (!myStudyContext) - UpdateStudy(); + UpdateStudy(); // load geom data + Kernel_Utils::Localizer loc; + SALOMEDS::Study_var aStudy = getStudyServant(); - /* if( !theComponent->_is_nil() ) - { - if( !aStudy->FindComponent( "GEOM" )->_is_nil() ) - loadGeomData( aStudy->FindComponent( "GEOM" ) ); - }*/ // Get temporary files location TCollection_AsciiString tmpDir = @@ -4046,7 +5131,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, TCollection_AsciiString aStudyName( "" ); if ( isMultiFile ) { CORBA::WString_var url = aStudy->URL(); - aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(url.in()) ).c_str(); + SMESHUtils::ArrayDeleter urlMulibyte( Kernel_Utils::encode( url.in()) ); + aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( urlMulibyte.get() ).c_str(); } // Set names of temporary files TCollection_AsciiString filename = tmpDir + aStudyName + "_SMESH.hdf"; @@ -4071,10 +5157,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, return false; } - TPythonDump pd; // prevent dump during loading - - // DriverMED_R_SMESHDS_Mesh myReader; - // myReader.SetFile( meshfile.ToCString() ); + TPythonDump pd(this); // prevent dump during loading // For PAL13473 ("Repetitive mesh") implementation. // New dependencies between SMESH objects are established: @@ -4270,6 +5353,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" ); } @@ -4351,11 +5438,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { SALOMEDS::SObject_wrap shapeSO = aStudy->FindObjectID( refFromFile ); - - // Make sure GEOM data are loaded first - //loadGeomData( shapeSO->GetFatherComponent() ); - - CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); + CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); if ( !CORBA::is_nil( shapeObject ) ) { aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject ); if ( !aShapeObject->_is_nil() ) @@ -4366,7 +5449,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(); @@ -4378,6 +5461,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, 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" )) { @@ -4393,7 +5486,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } // reading MESHes - // As all object that can be referred by hypothesis are created, + // As all objects that can be referred by hypothesis are created, // we can restore hypothesis data list< pair< SMESH_Hypothesis_i*, string > >::iterator hyp_data; @@ -4411,8 +5504,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, { aTopGroup = meshi_group->second; SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; - //::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); - //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh(); bool hasData = false; @@ -4420,7 +5511,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" ) ) { @@ -4432,10 +5523,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; @@ -4461,8 +5548,6 @@ 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 = aStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); delete [] refFromFile; string anIOR = myStudyContext->getIORbyOldId( id ); @@ -4498,8 +5583,6 @@ 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 = myStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); delete [] refFromFile; string anIOR = myStudyContext->getIORbyOldId( id ); @@ -4579,7 +5662,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aSubMesh->_is_nil() ) continue; string iorSubString = GetORB()->object_to_string( aSubMesh ); - int newSubId = myStudyContext->findId( iorSubString ); + int newSubId = myStudyContext->findId( iorSubString ); myStudyContext->mapOldToNew( subid, newSubId ); } } @@ -4702,9 +5785,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // check if it is a group if ( name_dataset.substr( 0, 5 ) == "Group" ) { // --> get group id - int subid = atoi( name_dataset.substr( 5 ).c_str() ); + char * endptr; + int subid = strtol( name_dataset.data() + 5, &endptr, 10 ); if ( subid <= 0 ) continue; + int groupID = -1; // group local ID (also persistent) + if ( *endptr ) + groupID = atoi( endptr + 1 ); aDataset = new HDFdataset( name_dataset.c_str(), aGroup ); aDataset->OpenOnDisk(); @@ -4761,13 +5848,14 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // 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; - string iorSubString = GetORB()->object_to_string( aNewGroup ); + CORBA::String_var iorSubStringVar = GetORB()->object_to_string( aNewGroup ); + string iorSubString(iorSubStringVar.in()); int newSubId = myStudyContext->findId( iorSubString ); myStudyContext->mapOldToNew( subid, newSubId ); @@ -4810,16 +5898,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" )) { // old version keeps ids aDataset = new HDFdataset( "Mesh Order", aTopGroup ); aDataset->OpenOnDisk(); size = aDataset->GetSize(); @@ -4837,6 +5925,32 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); delete [] smIDs; } + if ( aTopGroup->ExistInternalObject( "MeshOrder_new" )) // new version keeps entries + { + aDataset = new HDFdataset( "MeshOrder_new", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + std::string dataString; dataString.resize( size ); + aDataset->ReadFromDisk((char*) dataString.data() ); + aDataset->CloseOnDisk(); + + std::list< std::list< std::string > > orderEntryLists; + SMESHUtils::BoostTxtArchive( dataString ) >> orderEntryLists; + + TListOfListOfInt anOrderIds; + for ( const std::list< std::string >& entryList : orderEntryLists ) + { + anOrderIds.emplace_back(); + for ( const std::string & entry : entryList ) + { + GEOM::GEOM_Object_var go = GetGeomObjectByEntry( entry ); + TopoDS_Shape shape = GeomObjectToShape( go ); + if ( SMESH_subMesh* sm = myNewMeshImpl->GetImpl().GetSubMesh( shape )) + anOrderIds.back().emplace_back( sm->GetId() ); + } + } + myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); + } } // loop on meshes // update hyps needing full mesh data restored (issue 20918) @@ -4896,7 +6010,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } - pd << ""; // prevent optimizing pd out // creation of tree nodes for all data objects in the study // to support tree representation customization and drag-n-drop: @@ -5062,11 +6175,12 @@ int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) */ //================================================================================ -CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject) +CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject) { if ( myStudyContext && !CORBA::is_nil( theObject )) { - string iorString = GetORB()->object_to_string( theObject ); - return myStudyContext->findId( iorString ); + CORBA::String_var iorString = GetORB()->object_to_string( theObject ); + string iorStringCpp(iorString.in()); + return myStudyContext->findId( iorStringCpp ); } return 0; } @@ -5078,6 +6192,7 @@ CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject) * Set a new object name */ //============================================================================= + void SMESH_Gen_i::SetName(const char* theIOR, const char* theName) { @@ -5105,6 +6220,7 @@ char* SMESH_Gen_i::getVersion() // purpose : Moves objects to the specified position. // Is used in the drag-n-drop functionality. //================================================================================= + void SMESH_Gen_i::Move( const SMESH::sobject_list& what, SALOMEDS::SObject_ptr where, CORBA::Long row ) @@ -5158,13 +6274,13 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, SMESH_TRY; std::string aPlatformLibName; - typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char*); GenericHypothesisCreator_i* aCreator = getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName); 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 { @@ -5179,10 +6295,12 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, return true; } -//================================================================================= -// function : GetInsideSphere -// purpose : Collect indices of elements, which are located inside the sphere -//================================================================================= +//================================================================================ +/*! + * \brief Collect indices of elements, which are located inside the sphere + */ +//================================================================================ + SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart, SMESH::ElementType theElemType, CORBA::Double theX, @@ -5209,6 +6327,12 @@ SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshP return aResult._retn(); } +//================================================================================ +/*! + * \brief Collect indices of elements, which are located inside the box + */ +//================================================================================ + SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart, SMESH::ElementType theElemType, CORBA::Double theX1, @@ -5216,12 +6340,14 @@ SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart CORBA::Double theZ1, CORBA::Double theX2, CORBA::Double theY2, - CORBA::Double theZ2) { + CORBA::Double theZ2) +{ SMESH::long_array_var aResult = new SMESH::long_array(); if( meshPart->_is_nil() ) return aResult._retn(); - TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ), gp_Pnt( theX2, theY2, theZ2 ) ).Shape(); + TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ), + gp_Pnt( theX2, theY2, theZ2 ) ).Shape(); std::vector lst =_GetInside(meshPart, theElemType, aShape); @@ -5234,6 +6360,12 @@ SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart return aResult._retn(); } +//================================================================================ +/*! + * \brief Collect indices of elements, which are located inside the cylinder + */ +//================================================================================ + SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart, SMESH::ElementType theElemType, CORBA::Double theX, @@ -5243,7 +6375,8 @@ SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr mes CORBA::Double theDY, CORBA::Double theDZ, CORBA::Double theH, - CORBA::Double theR ){ + CORBA::Double theR ) +{ SMESH::long_array_var aResult = new SMESH::long_array(); if( meshPart->_is_nil() ) return aResult._retn(); @@ -5265,10 +6398,17 @@ SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr mes return aResult._retn(); } +//================================================================================ +/*! + * \brief Collect indices of elements, which are located inside the geom object + */ +//================================================================================ + SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart, SMESH::ElementType theElemType, GEOM::GEOM_Object_ptr theGeom, - CORBA::Double theTolerance ) { + CORBA::Double theTolerance ) +{ SMESH::long_array_var aResult = new SMESH::long_array(); if( meshPart->_is_nil() || theGeom->_is_nil() ) return aResult._retn(); @@ -5286,12 +6426,16 @@ SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart, return aResult._retn(); } - +//================================================================================ +/*! + * \brief Collect indices of elements, which are located inside the TopoDS_Shape + */ +//================================================================================ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, - SMESH::ElementType theElemType, - TopoDS_Shape& aShape, - double* theTolerance) { + SMESH::ElementType theElemType, + const TopoDS_Shape& theShape, + double* theTolerance) { std::vector res; SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); @@ -5312,7 +6456,7 @@ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, SMESH::Controls::ElementsOnShape* anElementsOnShape = new SMESH::Controls::ElementsOnShape(); anElementsOnShape->SetAllNodes( true ); anElementsOnShape->SetMesh( meshDS ); - anElementsOnShape->SetShape( aShape, aType ); + anElementsOnShape->SetShape( theShape, aType ); if(theTolerance) anElementsOnShape->SetTolerance(*theTolerance); @@ -5332,7 +6476,7 @@ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, SMESH::SMESH_Group_var gsource = SMESH::SMESH_Group::_narrow(meshPart); if ( !gsource->_is_nil() ) { if(theElemType == SMESH::NODE) { - SMESH::long_array_var nodes = gsource->GetNodeIDs(); + SMESH::smIdType_array_var nodes = gsource->GetNodeIDs(); for ( CORBA::ULong i = 0; i < nodes->length(); ++i ) { if ( const SMDS_MeshNode* node = meshDS->FindNode( nodes[i] )) { long anId = node->GetID(); @@ -5341,7 +6485,7 @@ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, } } } else if (gsource->GetType() == theElemType || theElemType == SMESH::ALL ) { - SMESH::long_array_var elems = gsource->GetListOfID(); + SMESH::smIdType_array_var elems = gsource->GetListOfID(); for ( CORBA::ULong i = 0; i < elems->length(); ++i ) { if ( const SMDS_MeshElement* elem = meshDS->FindElement( elems[i] )) { long anId = elem->GetID(); @@ -5353,7 +6497,7 @@ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, } SMESH::SMESH_subMesh_var smsource = SMESH::SMESH_subMesh::_narrow(meshPart); if ( !smsource->_is_nil() ) { - SMESH::long_array_var elems = smsource->GetElementsByType( theElemType ); + SMESH::smIdType_array_var elems = smsource->GetElementsByType( theElemType ); for ( CORBA::ULong i = 0; i < elems->length(); ++i ) { const SMDS_MeshElement* elem = ( theElemType == SMESH::NODE ) ? meshDS->FindNode( elems[i] ) : meshDS->FindElement( elems[i] ); if (elem) { @@ -5365,27 +6509,3 @@ std::vector SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart, } return res; } - - -//============================================================================= -/*! - * SMESHEngine_factory - * - * C factory, accessible with dlsym, after dlopen - */ -//============================================================================= - -extern "C" -{ SMESH_I_EXPORT - PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, - const char* interfaceName ) - { - if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" ); - if(MYDEBUG) SCRUTE(interfaceName); - SMESH_Gen_i* aSMESHGen = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName); - return aSMESHGen->getId() ; - } -}