X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Gen_i.cxx;h=c22499d1747eebab63dea8b0aab4f58341a8c38a;hb=93e79bb6c3a7c6e695af77feabbf5bb17c41ab42;hp=c644c20875c70c718f68ac84f39b406cec2a2fd2;hpb=035f2b519d61c242c30546de21801ce10a871529;p=modules%2Fsmesh.git diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index c644c2087..c22499d17 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2011 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Gen_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include #include #include @@ -54,6 +53,7 @@ #ifdef WNT #include + #include #else #include #endif @@ -78,6 +78,7 @@ #include "SMESH_Algo_i.hxx" #include "SMESH_Group_i.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_PreMeshInfo.hxx" #include "SMESHDS_Document.hxx" #include "SMESHDS_Group.hxx" @@ -89,9 +90,10 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" -#include "SMDS_VertexPosition.hxx" -#include "SMDS_SpacePosition.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_VertexPosition.hxx" #include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Filter) @@ -99,6 +101,9 @@ #include "DriverMED_W_SMESHDS_Mesh.h" #include "DriverMED_R_SMESHDS_Mesh.h" +#ifdef WITH_CGNS +#include "DriverCGNS_Read.hxx" +#endif #include "SALOMEDS_Tool.hxx" #include "SALOME_NamingService.hxx" @@ -111,12 +116,14 @@ #include "GEOM_Client.hxx" #include "Utils_ExceptHandlers.hxx" +#include "memoire.h" #include "Basics_Utils.hxx" #include using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; #define NUM_TMP_FILES 2 @@ -152,9 +159,9 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb try { PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject ); return aServant; - } + } catch (...) { - INFOS( "GetServant - Unknown exception was caught!!!" ); + INFOS( "GetServant - Unknown exception was caught!!!" ); return NULL; } } @@ -191,7 +198,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject /*! * GetNS [ static ] * - * Get SALOME_NamingService object + * Get SALOME_NamingService object */ //============================================================================= @@ -211,7 +218,7 @@ SALOME_NamingService* SMESH_Gen_i::GetNS() * * Get SALOME_LifeCycleCORBA object */ -//============================================================================= +//============================================================================= SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { if ( myLCC == NULL ) { myLCC = new SALOME_LifeCycleCORBA( GetNS() ); @@ -226,14 +233,14 @@ SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { * * Get GEOM::GEOM_Gen reference */ -//============================================================================= +//============================================================================= GEOM::GEOM_Gen_ptr 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::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); + Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); myGeomGen=GEOM::GEOM_Gen::_narrow(temp); } return myGeomGen; @@ -254,7 +261,7 @@ SMESH_Gen_i::SMESH_Gen_i() //============================================================================= /*! - * SMESH_Gen_i::SMESH_Gen_i + * SMESH_Gen_i::SMESH_Gen_i * * Standard constructor, used with Container */ @@ -262,8 +269,8 @@ SMESH_Gen_i::SMESH_Gen_i() SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, + PortableServer::ObjectId* contId, + const char* instanceName, const char* interfaceName ) : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) { @@ -271,13 +278,15 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, myOrb = CORBA::ORB::_duplicate(orb); myPoa = PortableServer::POA::_duplicate(poa); - + _thisObj = this ; _id = myPoa->activate_object( _thisObj ); - + myIsEmbeddedMode = false; myShapeReader = NULL; // shape reader mySMESHGen = this; + myIsHistoricalPythonDump = true; + myToForgetMeshDataOnHypModif = false; // set it in standalone mode only //OSD::SetSignal( true ); @@ -292,7 +301,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; if ( !session->_is_nil() ) { - CORBA::String_var s_host = session->getHostname(); + CORBA::String_var str_host = session->getHostname(); CORBA::Long s_pid = session->getPID(); string my_host = Kernel_Utils::GetHostname(); #ifdef WNT @@ -300,7 +309,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, #else long my_pid = (long) getpid(); #endif - SetEmbeddedMode( s_pid == my_pid && my_host == s_host.in() ); + SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() ); } } } @@ -315,7 +324,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, SMESH_Gen_i::~SMESH_Gen_i() { - INFOS( "SMESH_Gen_i::~SMESH_Gen_i" ); + MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" ); // delete hypothesis creators map::iterator itHyp; @@ -332,10 +341,10 @@ SMESH_Gen_i::~SMESH_Gen_i() } myStudyContextMap.clear(); // delete shape reader - if ( !myShapeReader ) + if ( !myShapeReader ) delete myShapeReader; } - + //============================================================================= /*! * SMESH_Gen_i::createHypothesis @@ -373,7 +382,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName } else { - //try to use new format + //try to use new format #ifdef WNT aPlatformLibName = new char[ libNameLen + 5 ]; aPlatformLibName[0] = '\0'; @@ -459,7 +468,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName // activate the CORBA servant of hypothesis hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() ); int nextId = RegisterObject( hypothesis_i ); - if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId ); + if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId ); return hypothesis_i._retn(); } @@ -482,6 +491,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() // create a new mesh object servant, store it in a map in study context SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() ); // create a new mesh object + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); // activate the CORBA servant of Mesh @@ -506,7 +516,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() GEOM_Client* SMESH_Gen_i::GetShapeReader() { // create shape reader if necessary - if ( !myShapeReader ) + if ( !myShapeReader ) myShapeReader = new GEOM_Client(GetContainerRef()); ASSERT( myShapeReader ); return myShapeReader; @@ -539,6 +549,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ) void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode ) { myIsEmbeddedMode = theMode; + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); if ( !myIsEmbeddedMode ) { //PAL10867: disable signals catching with "noexcepthandler" option @@ -588,12 +599,12 @@ void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy ) // create study context, if it doesn't exist and set current study int studyId = GetCurrentStudyID(); if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) { - myStudyContextMap[ studyId ] = new StudyContext; + myStudyContextMap[ studyId ] = new StudyContext; } // myCurrentStudy may be nil if ( !CORBA::is_nil( myCurrentStudy ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() ) aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() ); @@ -633,7 +644,7 @@ SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy() //============================================================================= /*! - * SMESH_Gen_i::GetCurrentStudyContext + * SMESH_Gen_i::GetCurrentStudyContext * * Get current study context */ @@ -649,7 +660,7 @@ StudyContext* SMESH_Gen_i::GetCurrentStudyContext() //============================================================================= /*! - * SMESH_Gen_i::CreateHypothesis + * SMESH_Gen_i::CreateHypothesis * * Create hypothesis/algorothm of given type and publish it in the study */ @@ -747,7 +758,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, } } - // let the temporary hypothesis find out some how parameter values by mesh + // let the temporary hypothesis find out somehow parameter values by mesh if ( hyp->SetParametersByMesh( mesh, shape )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); } @@ -760,6 +771,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, ::SMESH_Hypothesis::TDefaults dflts; dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation(); dflts._nbSegments = myGen.GetDefaultNbSegments(); + dflts._shape = &shape; // let the temporary hypothesis initialize it's values if ( hyp->SetParametersByDefaults( dflts, mesh )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); @@ -797,6 +809,63 @@ void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments) THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM ); } +//============================================================================= +/*! + Set an option value +*/ +//============================================================================= + +void SMESH_Gen_i::SetOption(const char* name, const char* value) +{ + if ( name && value && strlen( value ) > 0 ) + { + string msgToGUI; + if ( strcmp(name, "historical_python_dump") == 0 ) + { + myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences:SMESH:historical_python_dump:"; + msgToGUI += myIsHistoricalPythonDump ? "true" : "false"; + } + else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences:SMESH:forget_mesh_on_hyp_modif:"; + msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false"; + } + + // update preferences in case if SetOption() is invoked from python console + if ( !msgToGUI.empty() ) + { + CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ); + if ( !CORBA::is_nil( session ) ) + session->emitMessageOneWay(msgToGUI.c_str()); + } + } +} + +//============================================================================= +/*! + Return an option value +*/ +//============================================================================= + +char* SMESH_Gen_i::GetOption(const char* name) +{ + if ( name ) + { + if ( strcmp(name, "historical_python_dump") == 0 ) + { + return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" ); + } + if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" ); + } + } + return CORBA::string_dup( "" ); +} + //============================================================================= /*! * SMESH_Gen_i::CreateMesh @@ -887,7 +956,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV('" << theFileName << "')"; + TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')"; } } @@ -896,8 +965,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aServant->ImportUNVFile( theFileName ); // Dump creation of groups - aServant->GetGroups(); + SMESH::ListOfGroups_var groups = aServant->GetGroups(); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } @@ -909,13 +979,11 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName */ //============================================================================= -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus, + const char* theCommandNameForPython, + const char* theFileNameForPython) { - Unexpect aCatch(SALOME_SalomeException); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); - // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; myReader.SetFile( theFileName ); @@ -930,23 +998,21 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, // Python Dump TPythonDump aPythonDump; aPythonDump << "(["; - //TCollection_AsciiString aStr ("(["); if (theStatus == SMESH::DRS_OK) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction 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) aStr += ", "; if (i > 0) aPythonDump << ", "; // create mesh SMESH::SMESH_Mesh_var mesh = createMesh(); - + // publish mesh in the study SALOMEDS::SObject_var aSO; if ( CanPublishInStudy( mesh ) ) @@ -954,12 +1020,9 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, if ( !aSO->_is_nil() ) { // Python Dump aPythonDump << aSO; - //aStr += aSO->GetID(); } else { // Python Dump aPythonDump << "mesh_" << i; -// aStr += "mesh_"; -// aStr += TCollection_AsciiString(i); } // Read mesh data (groups are published automatically by ImportMEDFile()) @@ -971,20 +1034,71 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, theStatus = status1; aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); } aStudyBuilder->CommitCommand(); } // Update Python script - aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')"; + aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')"; } // Dump creation of groups for ( int i = 0; i < aResult->length(); ++i ) - aResult[ i ]->GetGroups(); + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); 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); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); + 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); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromSAUV" ); + std::string sauvfilename(theFileName); + std::string medfilename(theFileName); + medfilename += ".med"; + std::string cmd; +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#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 WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + return result; +} + //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL @@ -1010,16 +1124,100 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL('" << theFileName << "')"; + TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; } } SMESH_Mesh_i* aServant = dynamic_cast( GetServant( aMesh ).in() ); ASSERT( aServant ); aServant->ImportSTLFile( theFileName ); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } +//================================================================================ +/*! + * \brief Create meshes and import data from the CGSN file + */ +//================================================================================ + +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + +#ifdef WITH_CGNS + // Retrieve nb meshes from the file + DriverCGNS_Read myReader; + myReader.SetFile( theFileName ); + Driver_Mesh::Status aStatus; + int nbMeshes = myReader.GetNbMeshes(aStatus); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + aResult->length( nbMeshes ); + + { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() + + // Python Dump + TPythonDump aPythonDump; + aPythonDump << "(["; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + int i = 0; + + // Iterate through all meshes and create mesh objects + for ( ; i < nbMeshes; ++i ) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); + aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh ); + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + string meshName; + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportCGNSFile( theFileName, i, meshName ); + if (status1 > theStatus) + theStatus = status1; + + meshServant->GetImpl().GetMeshDS()->Modified(); + // publish mesh in the study + SALOMEDS::SObject_var aSO; + if ( CanPublishInStudy( mesh ) ) + aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() ); + + // Python Dump + if ( !aSO->_is_nil() ) + aPythonDump << aSO; + else + aPythonDump << "mesh_" << i; + } + aStudyBuilder->CommitCommand(); + } + + aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')"; + } + // Dump creation of groups + for ( int i = 0; i < aResult->length(); ++i ) + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif + + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::IsReadyToCompute @@ -1036,7 +1234,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" ); if ( CORBA::is_nil( theShapeObject ) ) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1104,7 +1302,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) */ //================================================================================ -SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1126,7 +1324,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr shape = GeomObjectToShape( theSubObject ); else shape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& mesh = meshServant->GetImpl(); error_array->length( mesh.GetMeshDS()->MaxShapeIndex() ); @@ -1166,7 +1364,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr return error_array._retn(); } -// +// //================================================================================ /*! * \brief Return mesh elements preventing computation of a subshape @@ -1261,7 +1459,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, */ //================================================================================ -SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1284,7 +1482,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes myLocShape = GeomObjectToShape( theSubObject ); else myLocShape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); list< ::SMESH_Gen::TAlgoStateError > error_list; list< ::SMESH_Gen::TAlgoStateError >::iterator error; @@ -1337,7 +1535,7 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha try { TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject); - TopTools_IndexedMapOfShape myIndexToShape; + TopTools_IndexedMapOfShape myIndexToShape; TopExp::MapShapes(myMainShape,myIndexToShape); for ( int i = 0; i < theListOfSubShapeObject.length(); i++ ) @@ -1399,11 +1597,12 @@ 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); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1417,6 +1616,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1429,7 +1629,13 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, myLocShape = SMESH_Mesh::PseudoShape(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - return myGen.Compute( myLocMesh, myLocShape); +#ifdef WITH_SMESH_CANCEL_COMPUTE + myGen.PrepareCompute( myLocMesh, myLocShape); +#endif + bool ok = myGen.Compute( myLocMesh, myLocShape); + meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) + myLocMesh.GetMeshDS()->Modified(); + return ok; } } catch ( std::bad_alloc ) { @@ -1444,6 +1650,29 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, return false; } +//============================================================================= +/*! + * SMESH_Gen_i::CancelCompute + * + * Cancel Compute mesh on a shape + */ +//============================================================================= + +void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject ) +{ +#ifdef WITH_SMESH_CANCEL_COMPUTE + 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); +#endif +} + //============================================================================= /*! * SMESH_Gen_i::Precompute @@ -1462,7 +1691,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1473,6 +1702,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1512,7 +1742,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt); if ( !sm || !sm->IsMeshComputed() ) continue; - + const TopoDS_Shape& aSh = sm->GetSubShape(); const int shDim = myGen.GetShapeDim( aSh ); if ( shDim < 1 || shDim > theDimension ) @@ -1649,7 +1879,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1686,8 +1916,20 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, MapShapeNbElemsItr anIt = aResMap.begin(); for(; anIt!=aResMap.end(); anIt++) { const vector& aVec = (*anIt).second; - for(i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) { - nbels[i] += aVec[i]; + for(i = SMESH::Entity_Node; i < aVec.size(); i++) { + int nbElem = aVec[i]; + if ( nbElem < 0 ) // algo failed, check that it has reported a message + { + SMESH_subMesh* sm = anIt->first; + SMESH_ComputeErrorPtr& error = sm->GetComputeError(); + const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape()); + if ( (algo && !error.get()) || error->IsOK() ) + error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo)); + } + else + { + nbels[i] += aVec[i]; + } } } return nbels._retn(); @@ -1723,7 +1965,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); - + GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID); if ( !geom->_is_nil() ) { GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); @@ -1844,8 +2086,8 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, //================================================================================ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { @@ -1867,8 +2109,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { @@ -1889,8 +2131,8 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance, CORBA::Boolean theCommonGroups) throw ( SALOME::SALOME_Exception ) @@ -1905,12 +2147,13 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // create mesh SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh(); - + + SMESHDS_Mesh* aNewMeshDS = 0; if ( !aNewMesh->_is_nil() ) { SMESH_Mesh_i* aNewImpl = dynamic_cast( GetServant( aNewMesh ).in() ); if ( aNewImpl ) { ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl(); - SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS(); + aNewMeshDS = aLocMesh.GetMeshDS(); TGroupsMap aGroupsMap; TListOfNewGroups aListOfNewGroups; @@ -1979,18 +2222,18 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // creates a corresponding element on existent nodes in new mesh if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume ) { - const SMDS_PolyhedralVolumeOfNodes* aVolume = - dynamic_cast (anElem); + const SMDS_VtkVolume* aVolume = + dynamic_cast (anElem); if ( aVolume ) { - aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, - aVolume->GetQuanities()); + aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, + aVolume->GetQuantities()); elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); if( theCommonGroups ) anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); } } else { - + aNewElem = aNewEditor.AddElement(aNodesArray, anElemType, anElem->IsPoly()); @@ -2003,9 +2246,25 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, else if( anElemType == SMDSAbs_Volume ) anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); } - } + } }//elems loop - + + // copy orphan nodes + SMDS_NodeIteratorPtr itNodes = anInitMeshDS->nodesIterator(); + while ( itNodes->more() ) + { + const SMDS_MeshNode* aNode = itNodes->next(); + if ( aNode->NbInverseElements() == 0 ) + { + const SMDS_MeshNode* aNewNode = + aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); + nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) ); + if( theCommonGroups ) + anIDsNodes[anNbNodes++] = aNewNode->GetID(); + } + } + + aListOfGroups = anInitImpl->GetGroups(); SMESH::SMESH_GroupBase_ptr aGroup; @@ -2073,7 +2332,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, default: break; } - + aListOfNewGroups.clear(); aListOfNewGroups.push_back(aNewGroup); aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); @@ -2101,14 +2360,14 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, for (int j = 0; j < anInitIDs->length(); j++) { anNewIDs[j] = elemsMap.find(anInitIDs[j])->second; } - + // check that current group name and type don't have identical ones in union mesh if ( anIter == aGroupsMap.end() ) { // add a new group in the mesh aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); // add elements into new group aNewGroup->Add( anNewIDs ); - + aListOfNewGroups.push_back(aNewGroup); aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); } @@ -2123,7 +2382,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // rename identical groups aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); aNewGroup->Add( anNewIDs ); - + TListOfNewGroups& aNewGroups = anIter->second; string aNewGroupName; if (aNewGroups.size() == 1) { @@ -2143,7 +2402,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, if (theMergeNodesAndElements) { // merge nodes - set aMeshNodes; // no input nodes + TIDSortedNodeSet aMeshNodes; // no input nodes SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes ); aNewEditor.MergeNodes( aGroupsOfNodes ); @@ -2152,7 +2411,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, } } } - + // Update Python script aPythonDump << aNewMesh << " = " << this; if( !theCommonGroups ) @@ -2167,7 +2426,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, aPythonDump << "], "; aPythonDump << theUniteIdenticalGroups << ", " << theMergeNodesAndElements << ", " - << theMergeTolerance << ")"; + << TVar( theMergeTolerance ) << ")"; delete pPythonDump; // enable python dump from GetGroups() @@ -2186,10 +2445,242 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); aPixmap->SetPixMap("ICON_SMESH_TREE_MESH"); } - + if (aNewMeshDS) + aNewMeshDS->Modified(); return aNewMesh._retn(); } +//================================================================================ +/*! + * \brief Create a mesh by copying a part of another mesh + * \param meshPart - a part of mesh to copy + * \param toCopyGroups - to create in the new mesh groups + * the copied elements belongs to + * \param toKeepIDs - to preserve IDs of the copied elements or not + * \retval SMESH::SMESH_Mesh_ptr - the new mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, + const char* meshName, + CORBA::Boolean toCopyGroups, + CORBA::Boolean toKeepIDs) +{ + Unexpect aCatch(SALOME_SalomeException); + + TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh() + + // 1. Get source mesh + + if ( CORBA::is_nil( meshPart )) + THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM ); + + SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh(); + SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( srcMesh ); + if ( !srcMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM ); + + SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS(); + + // 2. Make a new mesh + + SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil()); + SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh ); + if ( !newMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR ); + SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh ); + if ( !meshSO->_is_nil() ) + { + SetName( meshSO, meshName, "Mesh" ); + SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); + } + SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); + ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() ); + + // 3. Get elements to copy + + SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt; + TIDSortedElemSet srcElems; + SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes(); + if ( SMESH::DownCast( meshPart )) + { + srcElemIt = srcMeshDS->elementsIterator(); + srcNodeIt = srcMeshDS->nodesIterator(); + } + else + { + SMESH::long_array_var ids = meshPart->GetIDs(); + if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] )) + srcElems.insert( elem ); + } + else + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] )) + srcElems.insert( elem ); + } + if ( srcElems.empty() ) + return newMesh._retn(); + + typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter; + srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() )); + } + + // 4. Copy elements + + typedef map TE2EMap; + TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ]; + TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ]; + int iN; + const SMDS_MeshNode *nSrc, *nTgt; + vector< const SMDS_MeshNode* > nodes; + while ( srcElemIt->more() ) + { + const SMDS_MeshElement * elem = srcElemIt->next(); + nodes.resize( elem->NbNodes()); + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + if ( toKeepIDs ) { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + nTgt = newMeshDS->FindNode( nSrc->GetID()); + if ( !nTgt ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + nodes[ iN ] = nTgt; + } + } + else { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first; + if ( !n2n->second ) + n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + nodes[ iN ] = (const SMDS_MeshNode*) n2n->second; + } + } + if ( elem->GetType() != SMDSAbs_Node ) + { + int ID = toKeepIDs ? elem->GetID() : 0; + const SMDS_MeshElement * newElem; + if ( elem->GetEntityType() == SMDSEntity_Polyhedra ) + newElem = editor.GetMeshDS()-> + AddPolyhedralVolumeWithID( nodes, + static_cast(elem)->GetQuantities(), + elem->GetID()); + else + newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID); + + if ( toCopyGroups && !toKeepIDs ) + e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem )); + } + } + + // 4(b). Copy free nodes + + if ( srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes() ) + { + while ( srcNodeIt->more() ) + { + nSrc = srcNodeIt->next(); + if ( nSrc->NbInverseElements() == 0 ) + { + if ( toKeepIDs ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + else + n2nMap[ nSrc ] = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + } + } + } + + // 5. Copy groups + + int nbNewGroups = 0; + if ( toCopyGroups ) + { + SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups(); + while ( gIt->more() ) + { + SMESH_Group* group = gIt->next(); + const SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + + // Check group type. We copy nodal groups containing nodes of copied element + SMDSAbs_ElementType groupType = groupDS->GetType(); + if ( groupType != SMDSAbs_Node && + newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 ) + continue; // group type differs from types of meshPart + + // Find copied elements in the group + vector< const SMDS_MeshElement* > groupElems; + SMDS_ElemIteratorPtr eIt = groupDS->GetElements(); + if ( toKeepIDs ) + { + const SMDS_MeshElement* foundElem; + if ( groupType == SMDSAbs_Node ) + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + else + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + } + else + { + TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ]; + if ( e2eMap.empty() ) continue; + int minID = e2eMap.begin()->first->GetID(); + int maxID = e2eMap.rbegin()->first->GetID(); + TE2EMap::iterator e2e; + while ( eIt->more() && groupElems.size() < e2eMap.size()) + { + const SMDS_MeshElement* e = eIt->next(); + if ( e->GetID() < minID || e->GetID() > maxID ) continue; + if ((e2e = e2eMap.find( e )) != e2eMap.end()) + groupElems.push_back( e2e->second ); + } + } + // Make a new group + if ( !groupElems.empty() ) + { + SMESH::SMESH_Group_var newGroupObj = + newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() ); + if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast( newGroupObj)) + { + SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS(); + SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup(); + for ( unsigned i = 0; i < groupElems.size(); ++i ) + smdsGroup.Add( groupElems[i] ); + + nbNewGroups++; + } + } + } + } + + newMeshDS->Modified(); + + *pyDump << newMesh << " = " << this + << ".CopyMesh( " << meshPart << ", " + << "'" << meshName << "', " + << toCopyGroups << ", " + << toKeepIDs << ")"; + + delete pyDump; pyDump = 0; // allow dump in GetGroups() + + if ( nbNewGroups > 0 ) // dump created groups + SMESH::ListOfGroups_var groups = newMesh->GetGroups(); + + return newMesh._retn(); +} + //================================================================================ /*! * SMESH_Gen_i::GetMEDVersion @@ -2249,7 +2740,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) // san -- in case differs from theComponent's study, // use that of the component - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -2270,7 +2761,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aFileSeq->length( NUM_TMP_FILES ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -2309,6 +2800,41 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile( meshfile.ToCString() ); + // IMP issue 20918 + // SetStoreName() to groups before storing hypotheses to let them refer to + // groups using "store name", which is "Group " + { + SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { + CORBA::Object_var anObject = SObjectToObject( gotBranch ); + if ( !CORBA::is_nil( anObject ) ) { + 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() + SMESH::ListOfGroups_var groups = myMesh->GetGroups(); + pd << ""; // to avoid optimizing pd out + for ( int i = 0; i < groups->length(); ++i ) + { + SMESH_GroupBase_i* grImpl = SMESH::DownCast( groups[i]); + if ( grImpl ) + { + 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 ); + SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS(); + aGrpBaseDS->SetStoreName( grpName ); + } + } + } + } + } + } + } + // Write data // ---> create HDF file aFile = new HDFfile( (char*) filename.ToCString() ); @@ -2504,6 +3030,22 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( anAutoColor ); aDataset->CloseOnDisk(); + // issue 0020693. Store _isModified flag + int isModified = myLocMesh.GetIsModified(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &isModified ); + aDataset->CloseOnDisk(); + + // issue 20918. Store Persistent Id of SMESHDS_Mesh + int meshPersistentId = mySMESHDSMesh->GetPersistentId(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &meshPersistentId ); + aDataset->CloseOnDisk(); + // write reference on a shape if exists SALOMEDS::SObject_var myRef; bool shapeRefFound = false; @@ -2543,7 +3085,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( ok ) { // san - it is impossible to recover applied hypotheses // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of hypotheses as references to them //string myRefOnObject = myRefOnHyp->GetID(); @@ -2586,7 +3128,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( ok ) { // san - it is impossible to recover applied algorithms // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of algorithms as references to them //string myRefOnObject = myRefOnAlgo->GetID(); @@ -2822,7 +3364,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // groups root sub-branch SALOMEDS::SObject_var myGroupsBranch; - for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) { + for ( int i = GetNodeGroupsTag(); i <= Get0DElementsGroupsTag(); i++ ) { found = gotBranch->FindSubObject( i, myGroupsBranch ); if ( found ) { char name_group[ 30 ]; @@ -2834,6 +3376,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, strcpy( name_group, "Groups of Faces" ); else if ( i == GetVolumeGroupsTag() ) strcpy( name_group, "Groups of Volumes" ); + else if ( i == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->CreateOnDisk(); @@ -2847,17 +3391,19 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, dynamic_cast( GetServant( aSubObject ).in() ); if ( !myGroupImpl ) continue; - + SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS(); + if ( !aGrpBaseDS ) + continue; + CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); int anId = myStudyContext->findId( string( objStr.in() ) ); - + // For each group, create a dataset named "Group " // and store the group's user name into it - char grpName[ 30 ]; - sprintf( grpName, "Group %d", anId ); + const char* grpName = aGrpBaseDS->GetStoreName(); char* aUserName = myGroupImpl->GetName(); aSize[ 0 ] = strlen( aUserName ) + 1; - + aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); aDataset->WriteOnDisk( aUserName ); @@ -2879,74 +3425,78 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( anRGB ); aDataset->CloseOnDisk(); - // Store the group contents into MED file - if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) { - - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = " - << grpName << " to MED file" ); - SMESHDS_GroupBase* aGrpBaseDS = - myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS(); - aGrpBaseDS->SetStoreName( grpName ); - - // Pass SMESHDS_Group to MED writer - SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); - if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); - - // write reference on a shape if exists - SMESHDS_GroupOnGeom* aGeomGrp = - dynamic_cast( aGrpBaseDS ); - if ( aGeomGrp ) { - SALOMEDS::SObject_var mySubRef, myShape; - if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && - mySubRef->ReferencedObject( myShape ) && - !CORBA::is_nil( myShape->GetObject() )) - { - string myRefOnObject = myShape->GetID(); - if ( myRefOnObject.length() > 0 ) { - char aRefName[ 30 ]; - sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = myRefOnObject.length() + 1; - aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); - aDataset->CloseOnDisk(); - } - } - else // shape ref is invalid: - { - // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); + // Pass SMESHDS_Group to MED writer + SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); + if ( aGrpDS ) + myWriter.AddGroup( aGrpDS ); + + // write reference on a shape if exists + SMESHDS_GroupOnGeom* aGeomGrp = + dynamic_cast( aGrpBaseDS ); + if ( aGeomGrp ) { + SALOMEDS::SObject_var mySubRef, myShape; + if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && + mySubRef->ReferencedObject( myShape ) && + !CORBA::is_nil( myShape->GetObject() )) + { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + char aRefName[ 30 ]; + sprintf( aRefName, "Ref on shape %d", anId); + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); } } + else // shape ref is invalid: + { + // save a group on geometry as ordinary group + myWriter.AddGroup( aGeomGrp ); + } + } + else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = + dynamic_cast( myGroupImpl )) + { + std::string str = aFilterGrp_i->FilterToString(); + std::string hdfGrpName = "Filter " + SMESH_Comment(anId); + aSize[ 0 ] = str.length() + 1; + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( str.c_str() ) ); + aDataset->CloseOnDisk(); } } } aGroup->CloseOnDisk(); } - } // loop on groups - + } // loop on groups + if ( strcmp( strHasData.c_str(), "1" ) == 0 ) { // Flush current mesh information into MED file myWriter.Perform(); - + + // save info on nb of elements + SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile ); + // maybe a shape was deleted in the study if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) { TopoDS_Shape nullShape; myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data } - + if ( !mySMESHDSMesh->SubMeshes().empty() ) { // Store submeshes // ---------------- aGroup = new HDFgroup( "Submeshes", aTopGroup ); aGroup->CreateOnDisk(); - + // each element belongs to one or none submesh, // so for each node/element, we store a submesh ID - + // Make maps of submesh IDs of elements sorted by element IDs typedef int TElemID; typedef int TSubMID; @@ -2971,7 +3521,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint) hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID )); } - + // Care of elements that are not on submeshes if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) { for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); ) @@ -2985,7 +3535,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); ) eId2smId.insert( make_pair( itElem->next()->GetID(), 0 )); } - + // Store submesh IDs for ( int isNode = 0; isNode < 2; ++isNode ) { @@ -3006,20 +3556,22 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // delete[] smIDs; } - + + aGroup->CloseOnDisk(); + // Store node positions on sub-shapes (SMDS_Position): // ---------------------------------------------------- - + aGroup = new HDFgroup( "Node Positions", aTopGroup ); aGroup->CreateOnDisk(); - + // in aGroup, create 5 datasets to contain: // "Nodes on Edges" - ID of node on edge // "Edge positions" - U parameter on node on edge // "Nodes on Faces" - ID of node on face // "Face U positions" - U parameter of node on face // "Face V positions" - V parameter of node on face - + // Find out nb of nodes on edges and faces // Collect corresponing sub-meshes int nbEdgeNodes = 0, nbFaceNodes = 0; @@ -3032,8 +3584,10 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, continue; // submesh containing other submeshs int nbNodes = aSubMesh->NbNodes(); if ( nbNodes == 0 ) continue; - + int aShapeID = (*itSubM).first; + if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() ) + continue; int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType(); // write only SMDS_FacePosition and SMDS_EdgePosition switch ( aShapeType ) { @@ -3058,7 +3612,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, int* aNodeIDs = new int [ nbNodes ]; double* aUPos = new double [ nbNodes ]; double* aVPos = ( onFace ? new double[ nbNodes ] : 0 ); - + // Fill arrays // loop on sub-meshes list * pListSM = ( onFace ? &aFaceSM : &aEdgeSM ); @@ -3066,7 +3620,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, for ( ; itSM != pListSM->end(); itSM++ ) { SMESHDS_SubMesh* aSubMesh = (*itSM); - + SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes(); // loop on nodes in aSubMesh while ( itNode->more() ) @@ -3074,12 +3628,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //node ID const SMDS_MeshNode* node = itNode->next(); aNodeIDs [ iNode ] = node->GetID(); - + // Position const SMDS_PositionPtr pos = node->GetPosition(); if ( onFace ) { // on FACE const SMDS_FacePosition* fPos = - dynamic_cast( pos.get() ); + dynamic_cast( pos ); if ( fPos ) { aUPos[ iNode ] = fPos->GetUParameter(); aVPos[ iNode ] = fPos->GetVParameter(); @@ -3090,7 +3644,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } else { // on EDGE const SMDS_EdgePosition* ePos = - dynamic_cast( pos.get() ); + dynamic_cast( pos ); if ( ePos ) { aUPos[ iNode ] = ePos->GetUParameter(); iNode++; @@ -3100,7 +3654,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } } // loop on nodes in aSubMesh } // loop on sub-meshes - + // Write datasets if ( nbNodes ) { @@ -3111,7 +3665,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->CreateOnDisk(); aDataset->WriteOnDisk( aNodeIDs ); aDataset->CloseOnDisk(); - + // U Positions aDSName = ( onFace ? "Face U positions" : "Edge positions"); aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1); @@ -3129,15 +3683,15 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, delete [] aNodeIDs; delete [] aUPos; if ( aVPos ) delete [] aVPos; - + } // treat positions on edges or faces - + // close "Node Positions" group - aGroup->CloseOnDisk(); - + aGroup->CloseOnDisk(); + } // if ( there are submeshes in SMESHDS_Mesh ) } // if ( hasData ) - + // close mesh HDF group aTopGroup->CloseOnDisk(); } @@ -3145,7 +3699,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } } } - + // close HDF file aFile->CloseOnDisk(); delete aFile; @@ -3154,7 +3708,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile ); // Remove temporary files and directory - if ( !isMultiFile ) + if ( !isMultiFile ) SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); INFOS( "SMESH_Gen_i::Save() completed" ); @@ -3181,12 +3735,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent int size = aStreamFile.in().length(); _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1]; for ( int i = 0; i < size; i++ ) - sprintf( (char*)&(buffer[i*3]), "|%02x", (char*)(aStreamFile[i]) ); + sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] ); buffer[size * 3] = '\0'; SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1); - + return anAsciiStreamFile._retn(); } @@ -3207,34 +3761,9 @@ void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ) if ( aStudy->_is_nil() ) return; - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); } -//============================================================================= -/*! - * \brief Creates SMDS_Position according to shape type - */ -//============================================================================= - -class PositionCreator { -public: - SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) { - return (this->*myFuncTable[ type ])(); - } - PositionCreator() { - myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition ); - myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; - myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; - myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition; - } -private: - SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); } - SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); } - SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); } - SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); } - typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const; - vector myFuncTable; -}; //============================================================================= /*! @@ -3251,7 +3780,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, { INFOS( "SMESH_Gen_i::Load" ); - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -3267,7 +3796,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // Get temporary files location TCollection_AsciiString tmpDir = isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str(); - + INFOS( "THE URL++++++++++++++" ) INFOS( theURL ); INFOS( "THE TMP PATH+++++++++" ); @@ -3278,7 +3807,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, tmpDir.ToCString(), isMultiFile ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -3304,8 +3833,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, return false; } - DriverMED_R_SMESHDS_Mesh myReader; - myReader.SetFile( meshfile.ToCString() ); + TPythonDump pd; // prevent dump during loading + + // DriverMED_R_SMESHDS_Mesh myReader; + // myReader.SetFile( meshfile.ToCString() ); // For PAL13473 ("Repetitive mesh") implementation. // New dependencies between SMESH objects are established: @@ -3321,16 +3852,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList; // get total number of top-level groups - int aNbGroups = aFile->nInternalObjects(); + int aNbGroups = aFile->nInternalObjects(); if ( aNbGroups > 0 ) { // --> in first turn we should read&create hypotheses if ( aFile->ExistInternalObject( "Hypotheses" ) ) { // open hypotheses root HDF group - aTopGroup = new HDFgroup( "Hypotheses", aFile ); + aTopGroup = new HDFgroup( "Hypotheses", aFile ); aTopGroup->OpenOnDisk(); // get number of hypotheses - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { // try to identify hypothesis char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; @@ -3338,7 +3869,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { // open hypothesis group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup = new HDFgroup( hypGrpName, aTopGroup ); aGroup->OpenOnDisk(); // --> get hypothesis id @@ -3425,11 +3956,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // --> then we should read&create algorithms if ( aFile->ExistInternalObject( "Algorithms" ) ) { // open algorithms root HDF group - aTopGroup = new HDFgroup( "Algorithms", aFile ); + aTopGroup = new HDFgroup( "Algorithms", aFile ); aTopGroup->OpenOnDisk(); // get number of algorithms - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { // try to identify algorithm char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; @@ -3437,7 +3968,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { // open algorithm group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup = new HDFgroup( hypGrpName, aTopGroup ); aGroup->OpenOnDisk(); // --> get algorithm id @@ -3535,11 +4066,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, continue; // open mesh HDF group - aTopGroup = new HDFgroup( meshName, aFile ); + aTopGroup = new HDFgroup( meshName, aFile ); aTopGroup->OpenOnDisk(); // get number of child HDF objects - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); if ( aNbObjects > 0 ) { // create mesh if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id ); @@ -3565,7 +4096,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, int* anAutoColor = new int[ size ]; aDataset->ReadFromDisk( anAutoColor ); aDataset->CloseOnDisk(); - myNewMeshImpl->SetAutoColor( (bool)anAutoColor[0] ); + myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] ); } // try to read and set reference to shape @@ -3592,9 +4123,33 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } + + // issue 0020693. Restore _isModified flag + if( aTopGroup->ExistInternalObject( "_isModified" ) ) + { + aDataset = new HDFdataset( "_isModified", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* isModified = new int[ size ]; + aDataset->ReadFromDisk( isModified ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified)); + } + + // issue 20918. Restore Persistent Id of SMESHDS_Mesh + if( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) + { + aDataset = new HDFdataset( "meshPersistentId", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* meshPersistentId = new int[ size ]; + aDataset->ReadFromDisk( meshPersistentId ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId ); + } } } - } + } // reading MESHes // As all object that can be referred by hypothesis are created, // we can restore hypothesis data @@ -3614,8 +4169,8 @@ 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(); + //::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh(); bool hasData = false; @@ -3636,19 +4191,20 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); if ( strcmp( strHasData, "1") == 0 ) { // read mesh data from MED file - myReader.SetMesh( mySMESHDSMesh ); - myReader.SetMeshId( id ); - myReader.Perform(); + // myReader.SetMesh( mySMESHDSMesh ); + // myReader.SetMeshId( id ); + // myReader.Perform(); hasData = true; } } - // try to get applied algorithms + // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because + // nodes and elements are not yet put into sub-meshes) if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) { aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects ); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; @@ -3661,9 +4217,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied algorithms using their entries within Load() method - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); @@ -3687,7 +4241,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -3699,9 +4253,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied hypotheses using their entries within Load() method - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); @@ -3720,7 +4272,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } - // --> try to find submeshes containers for each type of submesh + // --> try to find SUB-MESHES containers for each type of submesh for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) { char name_meshgroup[ 30 ]; if ( j == GetSubMeshOnVertexTag() ) @@ -3745,7 +4297,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->OpenOnDisk(); // get number of submeshes - int aNbSubMeshes = aGroup->nInternalObjects(); + int aNbSubMeshes = aGroup->nInternalObjects(); for ( int k = 0; k < aNbSubMeshes; k++ ) { // identify submesh char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ]; @@ -3791,28 +4343,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aSubMesh->_is_nil() ) continue; - // VSR: Get submesh data from MED convertor - // int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape - // if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " << - // subid << " for subshape # " << anInternalSubmeshId); - // SMESHDS_SubMesh* aSubMeshDS = - // myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS(); - // if ( !aSubMeshDS ) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " << - // anInternalSubmeshId << " in current mesh!"); - // } - // else - // myReader.GetSubMesh( aSubMeshDS, subid ); - // } - // try to get applied algorithms if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) { // open "applied algorithms" HDF group aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3825,8 +4362,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3849,7 +4384,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3862,8 +4397,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3876,240 +4409,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } - // close "applied hypotheses" HDF group + // close "APPLIED HYPOTHESES" hdf group aSubSubGroup->CloseOnDisk(); } - // close submesh HDF group + // close SUB-MESH hdf group aSubGroup->CloseOnDisk(); } } - // close submeshes containers HDF group + // close SUB-MESHES containers hdf group aGroup->CloseOnDisk(); } } - if(hasData) { - - // Read sub-meshes from MED - // ------------------------- - if(MYDEBUG) MESSAGE("Create all sub-meshes"); - bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" )); - if ( submeshesInFamilies ) - { - // old way working before fix of PAL 12992 - myReader.CreateAllSubMeshes(); - } - else - { - // open a group - aGroup = new HDFgroup( "Submeshes", aTopGroup ); - aGroup->OpenOnDisk(); - - int maxID = mySMESHDSMesh->MaxShapeIndex(); - vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 ); - vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE ); - - PositionCreator aPositionCreator; - - SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator(); - SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator(); - for ( int isNode = 0; isNode < 2; ++isNode ) - { - string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); - if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() )) - { - aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup ); - aDataset->OpenOnDisk(); - // read submesh IDs for all elements sorted by ID - int nbElems = aDataset->GetSize(); - int* smIDs = new int [ nbElems ]; - aDataset->ReadFromDisk( smIDs ); - aDataset->CloseOnDisk(); - - // get elements sorted by ID - TIDSortedElemSet elemSet; - if ( isNode ) - while ( nIt->more() ) elemSet.insert( nIt->next() ); - else - while ( eIt->more() ) elemSet.insert( eIt->next() ); - //ASSERT( elemSet.size() == nbElems ); -- issue 20182 - // -- Most probably a bad study was saved when there were - // not fixed bugs in SMDS_MeshInfo - if ( elemSet.size() < nbElems ) { -#ifdef _DEBUG_ - cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl; -#endif - nbElems = elemSet.size(); - } - // add elements to submeshes - TIDSortedElemSet::iterator iE = elemSet.begin(); - for ( int i = 0; i < nbElems; ++i, ++iE ) - { - int smID = smIDs[ i ]; - if ( smID == 0 ) continue; - const SMDS_MeshElement* elem = *iE; - if( smID > maxID ) { - // corresponding subshape no longer exists: maybe geom group has been edited - if ( myNewMeshImpl->HasShapeToMesh() ) - mySMESHDSMesh->RemoveElement( elem ); - continue; - } - // get or create submesh - SMESHDS_SubMesh* & sm = subMeshes[ smID ]; - if ( ! sm ) { - sm = mySMESHDSMesh->NewSubMesh( smID ); - smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType(); - } - // add - if ( isNode ) { - SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]); - pos->SetShapeId( smID ); - SMDS_MeshNode* node = const_cast( static_cast( elem )); - node->SetPosition( pos ); - sm->AddNode( node ); - } else { - sm->AddElement( elem ); - } - } - delete [] smIDs; - } - } - } // end reading submeshes - - // Read node positions on sub-shapes (SMDS_Position) - - if ( aTopGroup->ExistInternalObject( "Node Positions" )) - { - // There are 5 datasets to read: - // "Nodes on Edges" - ID of node on edge - // "Edge positions" - U parameter on node on edge - // "Nodes on Faces" - ID of node on face - // "Face U positions" - U parameter of node on face - // "Face V positions" - V parameter of node on face - const char* aEid_DSName = "Nodes on Edges"; - const char* aEu_DSName = "Edge positions"; - const char* aFu_DSName = "Face U positions"; - //char* aFid_DSName = "Nodes on Faces"; - //char* aFv_DSName = "Face V positions"; - - // data to retrieve - int nbEids = 0, nbFids = 0; - int *aEids = 0, *aFids = 0; - double *aEpos = 0, *aFupos = 0, *aFvpos = 0; - - // open a group - aGroup = new HDFgroup( "Node Positions", aTopGroup ); - aGroup->OpenOnDisk(); - - // loop on 5 data sets - int aNbObjects = aGroup->nInternalObjects(); - for ( int i = 0; i < aNbObjects; i++ ) - { - // identify dataset - char aDSName[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( i, aDSName ); - // read data - aDataset = new HDFdataset( aDSName, aGroup ); - aDataset->OpenOnDisk(); - if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions - { - double* pos = new double [ aDataset->GetSize() ]; - aDataset->ReadFromDisk( pos ); - // which one? - if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 ) - aEpos = pos; - else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 ) - aFupos = pos; - else - aFvpos = pos; - } - else // NODE IDS - { - int aSize = aDataset->GetSize(); - - // for reading files, created from 18.07.2005 till 10.10.2005 - if (aDataset->GetType() == HDF_STRING) - aSize /= sizeof(int); - - int* ids = new int [aSize]; - aDataset->ReadFromDisk( ids ); - // on face or nodes? - if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) { - aEids = ids; - nbEids = aSize; - } - else { - aFids = ids; - nbFids = aSize; - } - } - aDataset->CloseOnDisk(); - } // loop on 5 datasets - - // Set node positions on edges or faces - for ( int onFace = 0; onFace < 2; onFace++ ) - { - int nbNodes = ( onFace ? nbFids : nbEids ); - if ( nbNodes == 0 ) continue; - int* aNodeIDs = ( onFace ? aFids : aEids ); - double* aUPos = ( onFace ? aFupos : aEpos ); - double* aVPos = ( onFace ? aFvpos : 0 ); - // loop on node IDs - for ( int iNode = 0; iNode < nbNodes; iNode++ ) - { - const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]); - if ( !node ) continue; // maybe removed while Loading() if geometry changed - SMDS_PositionPtr aPos = node->GetPosition(); - ASSERT( aPos ); - if ( onFace ) { - // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182 - // -- Most probably a bad study was saved when there were - // not fixed bugs in SMDS_MeshInfo - if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) { - SMDS_FacePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - fPos->SetVParameter( aVPos[ iNode ]); - } - } - else { - // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182 - if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) { - SMDS_EdgePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - } - } - } - } - if ( aEids ) delete [] aEids; - if ( aFids ) delete [] aFids; - if ( aEpos ) delete [] aEpos; - if ( aFupos ) delete [] aFupos; - if ( aFvpos ) delete [] aFvpos; - - aGroup->CloseOnDisk(); - - } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) ) - } // if ( hasData ) - - // Recompute State (as computed sub-meshes are restored from MED) - if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) { - MESSAGE("Compute State Engine ..."); - TopoDS_Shape myLocShape; - if(myNewMeshImpl->HasShapeToMesh()) - myLocShape = GeomObjectToShape( aShapeObject ); - else - myLocShape = SMESH_Mesh::PseudoShape(); - - myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine - (SMESH_subMesh::SUBMESH_RESTORED); - MESSAGE("Compute State Engine finished"); - } - - // try to get groups - for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) { + // try to get GROUPS + for ( int ii = GetNodeGroupsTag(); ii <= Get0DElementsGroupsTag(); ii++ ) { char name_group[ 30 ]; if ( ii == GetNodeGroupsTag() ) strcpy( name_group, "Groups of Nodes" ); @@ -4119,12 +4433,14 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, strcpy( name_group, "Groups of Faces" ); else if ( ii == GetVolumeGroupsTag() ) strcpy( name_group, "Groups of Volumes" ); + else if ( ii == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); if ( aTopGroup->ExistInternalObject( name_group ) ) { aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->OpenOnDisk(); // get number of groups - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -4165,11 +4481,29 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } + // Try to read a filter of SMESH_GroupOnFilter + SMESH::Filter_var filter; + SMESH_PredicatePtr predicate; + std::string hdfGrpName = "Filter " + SMESH_Comment(subid); + if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) + { + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* persistStr = new char[ size ]; + aDataset->ReadFromDisk( persistStr ); + aDataset->CloseOnDisk(); + if ( strlen( persistStr ) > 0 ) { + filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr ); + predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); + } + } + // 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 ) ); - // Obtain a SMESHDS_Group object + ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) ); + // Obtain a SMESHDS_Group object if ( aNewGroup->_is_nil() ) continue; @@ -4177,16 +4511,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, int newSubId = myStudyContext->findId( iorSubString ); myStudyContext->mapOldToNew( subid, newSubId ); - SMESH_GroupBase_i* aGroupImpl = - dynamic_cast( GetServant( aNewGroup ).in() ); + SMESH_GroupBase_i* aGroupImpl = SMESH::DownCast< SMESH_GroupBase_i*>( aNewGroup ); if ( !aGroupImpl ) continue; - SMESH_Group* aLocalGroup = myLocMesh.GetGroup( aGroupImpl->GetLocalID() ); - if ( !aLocalGroup ) + if ( SMESH_GroupOnFilter_i* aFilterGroup = + dynamic_cast< SMESH_GroupOnFilter_i*>( aGroupImpl )) + aFilterGroup->SetFilter( filter ); + + SMESHDS_GroupBase* aGroupBaseDS = aGroupImpl->GetGroupDS(); + if ( !aGroupBaseDS ) continue; - SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS(); aGroupBaseDS->SetStoreName( name_dataset ); // ouv : NPAL12872 @@ -4206,15 +4542,25 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // Fill group with contents from MED file - SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); - if ( aGrp ) - myReader.GetGroup( aGrp ); + // SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); + // if ( aGrp ) + // myReader.GetGroup( aGrp ); } } aGroup->CloseOnDisk(); } + } // reading GROUPs + + // instead of reading mesh data, we read only brief information of all + // objects: mesh, groups, sub-meshes (issue 0021208 ) + if ( hasData ) + { + SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id, + meshfile.ToCString(), filename.ToCString(), + !isMultiFile ); } - // read submeh order if any + + // read Sub-Mesh ORDER if any if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { aDataset = new HDFdataset( "Mesh Order", aTopGroup ); aDataset->OpenOnDisk(); @@ -4229,21 +4575,47 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, anOrderIds.push_back( TListOfInt() ); else anOrderIds.back().push_back(smIDs[ i ]); - + myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); } + } // loop on meshes + + // update hyps needing full mesh data restored (issue 20918) + for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data ) + { + SMESH_Hypothesis_i* hyp = hyp_data->first; + hyp->UpdateAsMeshesRestored(); + } + + // notify algos on completed restoration to set sub-mesh event listeners + for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group ) + { + SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; + ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + + TopoDS_Shape myLocShape; + if(myLocMesh.HasShapeToMesh()) + myLocShape = myLocMesh.GetShapeToMesh(); + else + myLocShape = SMESH_Mesh::PseudoShape(); + + myLocMesh.GetSubMesh(myLocShape)-> + ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); } + // close mesh group if(aTopGroup) - aTopGroup->CloseOnDisk(); + aTopGroup->CloseOnDisk(); } // close HDF file aFile->CloseOnDisk(); delete aFile; // Remove temporary files created from the stream - if ( !isMultiFile ) - SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + // if ( !isMultiFile ) + // SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + + pd << ""; // prevent optimizing pd out INFOS( "SMESH_Gen_i::Load completed" ); return true; @@ -4284,7 +4656,7 @@ bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, } SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1); - + return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile ); } @@ -4301,8 +4673,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" ); // set correct current study - if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID()) - SetCurrentStudy(theComponent->GetStudy()); + SALOMEDS::Study_var study = theComponent->GetStudy(); + if ( study->StudyId() != GetCurrentStudyID()) + SetCurrentStudy( study ); // Clear study contexts data int studyId = GetCurrentStudyID(); @@ -4320,7 +4693,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) // printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second ); // delete i_mesh->second; // } - + // delete SMESHDS_Mesh's // it's too long on big meshes @@ -4328,7 +4701,10 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) // delete context->myDocument; // context->myDocument = 0; // } - + + // remove the tmp files meshes are loaded from + SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent ); + myCurrentStudy = SALOMEDS::Study::_nil(); return; } @@ -4336,7 +4712,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) //============================================================================= /*! * SMESH_Gen_i::ComponentDataType - * + * * Get component data type */ //============================================================================= @@ -4347,11 +4723,11 @@ char* SMESH_Gen_i::ComponentDataType() return CORBA::string_dup( "SMESH" ); } - + //============================================================================= /*! * SMESH_Gen_i::IORToLocalPersistentID - * + * * Transform data from transient form to persistent */ //============================================================================= @@ -4363,7 +4739,7 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" ); StudyContext* myStudyContext = GetCurrentStudyContext(); - + if ( myStudyContext && strcmp( IORString, "" ) != 0 ) { int anId = myStudyContext->findId( IORString ); if ( anId ) { @@ -4401,7 +4777,7 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, //======================================================================= //function : RegisterObject -//purpose : +//purpose : //======================================================================= int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) @@ -4455,21 +4831,21 @@ int SMESH_Gen_i::GetCurrentStudyID() { return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId(); } - + //============================================================================= -/*! +/*! * SMESHEngine_factory * - * C factory, accessible with dlsym, after dlopen + * 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::POA_ptr poa, PortableServer::ObjectId* contId, - const char* instanceName, + const char* instanceName, const char* interfaceName ) { if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );