From 9cef4666a14b0edf129bb94643a841e29e1d4f3a Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Wed, 3 Oct 2018 15:08:45 +0200 Subject: [PATCH] introduction of MED write/append with a lower major version of MED file format (hdf5 >= 1.10.2 needed) --- idl/SMESH_Mesh.idl | 30 +++++++++++++++++------- src/MEDWrapper/MED_Factory.cxx | 43 +++++++++++++++++++++++++++++++--- src/MEDWrapper/MED_Factory.hxx | 4 ++++ src/SMESHGUI/SMESHGUI.cxx | 31 ++++++++++++------------ src/SMESH_I/SMESH_Mesh_i.cxx | 17 ++++++++++++++ src/SMESH_I/SMESH_Mesh_i.hxx | 7 ++++++ 6 files changed, 104 insertions(+), 28 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 46f4a40b7..9daba34f4 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -622,10 +622,13 @@ module SMESH * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; * the typical use is auto_groups=false. * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists - * - minor : define the minor version of MED file format. + * - version : define the version of MED file format, coded with major and minor digits (release digit not used) + * for instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40. + * The rules of compatibility to write a mesh in an older version than the current version + * depend on the current version. For instance, with med 4.0 it is possible to write/append + * med files in 4.0.0 (default format) or 3.2.1 or 3.3.1 formats. * The minor must be between 0 and the current minor version of MED file library. - * If minor is equal to -1, the minor version is not changed (default). - * The major version cannot be changed. + * If version is equal to -1, the version is not changed (default). * - autoDimension : if @c true, a space dimension of a MED mesh can be either * - 1D if all mesh nodes lie on OX coordinate axis, or * - 2D if all mesh nodes lie on XOY coordinate plane, or @@ -634,7 +637,7 @@ module SMESH */ void ExportMED( in string fileName, in boolean auto_groups, - in long minor, + in long version, in boolean overwrite, in boolean autoDimension) raises (SALOME::SALOME_Exception); @@ -644,10 +647,13 @@ module SMESH * - meshPart : a part of mesh to store * - fileName : name of the MED file * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists - * - minor : define the minor version (y, where version is x.y.z) of MED file format. + * - version : define the version of MED file format, coded with major and minor digits (release digit not used) + * for instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40. + * The rules of compatibility to write a mesh in an older version than the current version + * depend on the current version. For instance, with med 4.0 it is possible to write/append + * med files in 4.0.0 (default format) or 3.2.1 or 3.3.1 formats. * The minor must be between 0 and the current minor version of MED file library. - * If minor is equal to -1, the minor version is not changed (default). - * The major version (x, where version is x.y.z) cannot be changed. + * If version is equal to -1, the version is not changed (default). * - autoDimension : if @c True, a space dimension for export is defined by mesh * configuration; for example a planar mesh lying on XOY plane * will be exported as a mesh in 2D space. @@ -663,7 +669,7 @@ module SMESH void ExportPartToMED( in SMESH_IDSource meshPart, in string fileName, in boolean auto_groups, - in long minor, + in long version, in boolean overwrite, in boolean autoDimension, in GEOM::ListOfFields fields, @@ -680,7 +686,13 @@ module SMESH * Return string representation of a MED file version comprising nbDigits */ string GetVersionString(in long minor, in short nbDigits); - + + /*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ + long_array GetMEDVersionsCompatibleForAppend(); + /*! * Export Mesh to different Formats * (UNV supported version is I-DEAS 10) diff --git a/src/MEDWrapper/MED_Factory.cxx b/src/MEDWrapper/MED_Factory.cxx index dbe60c051..5ae8e43de 100644 --- a/src/MEDWrapper/MED_Factory.cxx +++ b/src/MEDWrapper/MED_Factory.cxx @@ -41,6 +41,17 @@ extern "C" #include #endif +#define MED_MAJOR_EXPECTED 4 +#define MED_MINOR_EXPECTED 0 +#if MED_MAJOR_NUM != MED_MAJOR_EXPECTED + #error "MED major version does not correspond to the expected version, fix the minor and major compatibility values in CheckCompatibility method (MED_VERSIONS_APPEND_COMPATIBLE) and set the correct expected version" +#endif +#if MED_MINOR_NUM != MED_MINOR_EXPECTED + #error "MED minor version does not correspond to the expected version, fix the minor and major compatibility values in CheckCompatibility method (MED_VERSIONS_APPEND_COMPATIBLE) and set the correct expected version" +#endif +#define MED_VERSIONS_APPEND_COMPATIBLE {40, 32, 33} // --- 10*major + minor (the 3rd digit, release, is not used here, + // med uses always the latest available) + // --- The first in the list should be the default: current version namespace MED { @@ -61,25 +72,51 @@ namespace MED #endif } + /*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ + std::vector GetMEDVersionsAppendCompatible() + { + int mvok[] = MED_VERSIONS_APPEND_COMPATIBLE; + std::vector MEDVersionsOK(mvok, mvok + sizeof(mvok)/sizeof(int)); + return MEDVersionsOK; + } + + /*! + * \brief: Check read or write(append) Compatibility of a med file + * \param [in] : fileName - the file to read or to append to + * \param [in] : isforAppend - when true, check if the med file version is OK to append a mesh, + * when false, check if the med file is readable. + */ bool CheckCompatibility(const std::string& fileName, bool isForAppend) { bool ok = false; + int medVersionsOK[] = MED_VERSIONS_APPEND_COMPATIBLE; // check that file is accessible if ( exists(fileName) ) { // check HDF5 && MED compatibility med_bool hdfok, medok; med_err r0 = MEDfileCompatibility(fileName.c_str(), &hdfok, &medok); - //MESSAGE(r0 << " " << hdfok << " " << medok); + MESSAGE(r0 << " " << hdfok << " " << medok); if ( r0==0 && hdfok && medok ) { med_idt aFid = MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); if (aFid >= 0) { med_int major, minor, release; med_err ret = MEDfileNumVersionRd(aFid, &major, &minor, &release); - //MESSAGE(ret << " " << major << "." << minor << "." << release); + MESSAGE(ret << " " << major << "." << minor << "." << release); if (ret >= 0) { bool isReadOnly = !isForAppend; - if ( isReadOnly || ((major == MED_MAJOR_NUM) && (minor == MED_MINOR_NUM))) + if (isReadOnly) ok = true; + else { + int medVersion = 10*major + minor; + for (int ii=0; ii < sizeof(medVersionsOK)/sizeof(int); ii++) + if (medVersionsOK[ii] == medVersion) { + ok =true; + break; + } + } } } MEDfileClose(aFid); diff --git a/src/MEDWrapper/MED_Factory.hxx b/src/MEDWrapper/MED_Factory.hxx index fe5e0032c..402f97cb9 100644 --- a/src/MEDWrapper/MED_Factory.hxx +++ b/src/MEDWrapper/MED_Factory.hxx @@ -27,6 +27,7 @@ #include "MED_Wrapper.hxx" #include +#include namespace MED { @@ -39,6 +40,9 @@ namespace MED MEDWRAPPER_EXPORT bool CheckCompatibility( const std::string& , bool isForAppend=false); + MEDWRAPPER_EXPORT + std::vector GetMEDVersionsAppendCompatible(); + MEDWRAPPER_EXPORT PWrapper CrWrapperR( const std::string& ); diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 1225963f6..e9a49327c 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -747,35 +747,33 @@ namespace QMap aFilterMap; if ( isMED ) { //filters << QObject::tr( "MED_FILES_FILTER" ) + " (*.med)"; - QString vmed (aMesh->GetVersionString(-1, 2)); + //QString vmed (aMesh->GetVersionString(-1, 2)); //MESSAGE("MED version: " << vmed.toStdString()); - int minor = vmed.split(".").last().toInt(); - //MESSAGE("MED version minor: "<< minor); - //minor +=3; // TODO remove: test multiple minor - aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vmed ) + " (*.med)", minor ); - for (int ii=0; iiGetMEDVersionsCompatibleForAppend(); + for ( int i = 0; i < mvok->length(); ++i ) { - QString vs = aMesh->GetVersionString(ii, 2); - //std::ostringstream vss; // TODO remove: test multiple minor - //vss << "4."; // TODO remove: test multiple minor - //vss << ii; // TODO remove: test multiple minor - //vs = vss.str().c_str(); // TODO remove: test multiple minor - //MESSAGE("MED version: " << vs.toStdString()); - aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", ii); + int versionInt = mvok[i]; + std::ostringstream vss; + vss << versionInt/10; + vss << "."; + vss << versionInt%10; + QString vs = vss.str().c_str(); + MESSAGE("MED version: " << vs.toStdString()); + aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( vs ) + " (*.med)", i); } } else { // isSAUV aFilterMap.insert("All files (*)", -1 ); - aFilterMap.insert("SAUV files (*.sauv)", -1 ); + aFilterMap.insert("SAUV files (*.sauv)", 0 ); aFilterMap.insert("SAUV files (*.sauve)", -1 ); } QStringList filters; - QString aDefaultFilter; QMap::const_iterator it = aFilterMap.begin(); + QString aDefaultFilter = it.key(); for ( ; it != aFilterMap.end(); ++it ) { filters.push_back( it.key() ); - if (it.key() == 0) + if (it.value() == 0) // explicit default for MED = current MED version aDefaultFilter = it.key(); } QStringList checkBoxes; @@ -790,6 +788,7 @@ namespace new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true, wdgList ); fd->setWindowTitle( aTitle ); fd->setNameFilters( filters ); + fd->selectNameFilter( aDefaultFilter ); fd->SetChecked( toCreateGroups, 0 ); fd->SetChecked( toFindOutDim, 1 ); if ( !anInitialPath.isEmpty() ) diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 128dbed1c..540211542 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -468,6 +468,23 @@ char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits) return CORBA::string_dup( ver.c_str() ); } +//================================================================================ +/*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ +//================================================================================ +SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend() +{ + SMESH::long_array_var aResult = new SMESH::long_array(); + std::vector mvok = MED::GetMEDVersionsAppendCompatible(); + long nbver = mvok.size(); + aResult->length( nbver ); + for ( int i = 0; i < nbver; i++ ) + aResult[i] = mvok[i]; + return aResult._retn(); +} + //============================================================================= /*! * ImportUNVFile diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 7e612be13..786bfc9bd 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -225,11 +225,18 @@ public: * Consider maximum group name length stored in MED file. */ CORBA::Boolean HasDuplicatedGroupNamesMED(); + /*! * Return string representation of a MED file version comprising nbDigits */ char* GetVersionString(CORBA::Long minor, CORBA::Short nbDigits); + /*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ + SMESH::long_array* GetMEDVersionsCompatibleForAppend(); + void ExportMED( const char* file, CORBA::Boolean auto_groups, CORBA::Long minor, -- 2.39.2