From 90d5aa5cfe1fc4ea753b6828979fd3a9908d8bd7 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 28 Apr 2021 22:13:29 +0200 Subject: [PATCH] Implementation de ExportPartToMEDCoupling --- idl/SMESH_Mesh.idl | 7 ++ src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx | 17 ++- src/MEDWrapper/MED_TFile.hxx | 10 +- src/SMESH_I/SMESH_Gen_No_Session_i.cxx | 2 +- src/SMESH_I/SMESH_Mesh_i.cxx | 136 ++++++++++++++++----- src/SMESH_I/SMESH_Mesh_i.hxx | 32 +++-- src/SMESH_SWIG/smeshBuilder.py | 6 +- 7 files changed, 157 insertions(+), 53 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 6497ddfcb..070732b25 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -705,6 +705,13 @@ module SMESH in string geomAssocFields, in double ZTolerance) raises (SALOME::SALOME_Exception); + long long ExportPartToMEDCoupling( in SMESH_IDSource meshPart, + in boolean auto_groups, + in boolean autoDimension, + in GEOM::ListOfFields fields, + in string geomAssocFields, + in double ZTolerance) raises (SALOME::SALOME_Exception); + /*! * Export Mesh to SAUV formatted file * Write a temporary med file and use med2sauv diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 33a250f1c..3bdd0bed8 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -352,12 +352,19 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh_Mem::Perform() { - TMemFile *tfileInst = new TMemFile; - MED::PWrapper myMed = CrWrapperW(myFile, -1, tfileInst); - Driver_Mesh::Status status = this->PerformInternal(myMed); + void *ptr(nullptr); + std::size_t sz(0); + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; + bool isClosed(false); + {// let braces to flush (call of MED::PWrapper myMed destructor) + TMemFile *tfileInst = new TMemFile(&isClosed); + MED::PWrapper myMed = CrWrapperW(myFile, -1, tfileInst); + status = this->PerformInternal(myMed); + ptr = tfileInst->getData(); sz = tfileInst->getSize(); + } _data = MEDCoupling::DataArrayByte::New(); - _data->useArray(reinterpret_cast(tfileInst->getData()),true,MEDCoupling::DeallocType::C_DEALLOC,tfileInst->getSize(),1); - if(!tfileInst->IsClosed()) + _data->useArray(reinterpret_cast(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1); + if(!isClosed) THROW_SALOME_EXCEPTION("DriverMED_W_SMESHDS_Mesh_Mem::Perform - MED memory file id is supposed to be closed !"); return status; } diff --git a/src/MEDWrapper/MED_TFile.hxx b/src/MEDWrapper/MED_TFile.hxx index 7ce2346be..10dc55396 100644 --- a/src/MEDWrapper/MED_TFile.hxx +++ b/src/MEDWrapper/MED_TFile.hxx @@ -29,31 +29,32 @@ namespace MED virtual ~TFileInternal() = default; virtual void Open(EModeAcces theMode, TErr* theErr = nullptr) = 0; virtual void Close() = 0; - virtual bool IsClosed() const = 0; virtual const TIdt& Id() const = 0; }; class MEDIDTHoder : public TFileInternal { protected: - MEDIDTHoder() = default; + MEDIDTHoder(bool *isClosedStatus = nullptr):_isClosedStatus(isClosedStatus) { } void UnRefFid() { if (--myCount == 0) { MEDfileClose(myFid); myIsClosed = true; + if(_isClosedStatus) + *_isClosedStatus = true; } } public: const TIdt& Id() const override; ~MEDIDTHoder() { this->UnRefFid(); } void Close() override { this->UnRefFid(); } - bool IsClosed() const override { return myIsClosed; } protected: TInt myCount = 0; TIdt myFid = 0; bool myIsClosed = false; + bool *_isClosedStatus = nullptr; }; class TFileDecorator : public TFileInternal @@ -63,7 +64,6 @@ namespace MED void Open(EModeAcces theMode, TErr* theErr = nullptr) override { if(_effective) _effective->Open(theMode,theErr); } void Close() override { if(_effective) _effective->Close(); } const TIdt& Id() const override { if(_effective) return _effective->Id(); EXCEPTION(std::runtime_error, "TFileDecorator - GetFid() : no effective TFile !"); } - bool IsClosed() const override { if(_effective) return _effective->IsClosed(); EXCEPTION(std::runtime_error, "TFileDecorator - IsClosed() : no effective TFile !"); } ~TFileDecorator() { delete _effective; } private: TFileInternal *_effective = nullptr; @@ -72,7 +72,7 @@ namespace MED class TMemFile : public MEDIDTHoder { public: - TMemFile() = default; + TMemFile(bool* isClosedStatus = nullptr):MEDIDTHoder(isClosedStatus) { } void Open(EModeAcces theMode, TErr* theErr = nullptr) override; void *getData() const { return memfile.app_image_ptr; } std::size_t getSize() const { return memfile.app_image_size; } diff --git a/src/SMESH_I/SMESH_Gen_No_Session_i.cxx b/src/SMESH_I/SMESH_Gen_No_Session_i.cxx index 24c5f4d81..cbcc33eb3 100644 --- a/src/SMESH_I/SMESH_Gen_No_Session_i.cxx +++ b/src/SMESH_I/SMESH_Gen_No_Session_i.cxx @@ -27,7 +27,7 @@ SMESH_Gen_No_Session_i::SMESH_Gen_No_Session_i( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, PortableServer::ObjectId* contId, const char* instanceName, - const char* interfaceName):SMESH_Gen_i(orb,poa,contId,instanceName,interfaceName,true) + const char* interfaceName):SMESH_Gen_i(orb,poa,contId,instanceName,interfaceName,false) { } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index ae8012d1e..2fc681ef5 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -3784,8 +3784,9 @@ CORBA::LongLong SMESH_Mesh_i::ExportMEDCoupling(CORBA::Boolean auto_groups, CORB { MEDCoupling::MCAuto data; SMESH_TRY; - if( !this->_gen_i->IsEmbeddedMode() ) - SMESH::throwCorbaException("SMESH_Mesh_i::ExportMEDCoupling : only for embedded mode !"); + // TODO : Fix me ! 2 next lines are required + //if( !this->_gen_i->IsEmbeddedMode() ) + // SMESH::throwCorbaException("SMESH_Mesh_i::ExportMEDCoupling : only for embedded mode !"); if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3895,23 +3896,47 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) SMESH_CATCH( SMESH::throwCorbaException ); } -//================================================================================ -/*! - * \brief Export a part of mesh to a med file - */ -//================================================================================ +class MEDFileSpeCls +{ +public: + MEDFileSpeCls(const char *file, CORBA::Boolean overwrite, CORBA::Long version):_file(file),_overwrite(overwrite),_version(version) { } + std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self) { return self.prepareMeshNameAndGroups(_file.c_str(),_overwrite); } + void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups, + SMESH_MeshPartDS* partDS, + CORBA::Boolean autoDimension, bool have0dField, + CORBA::Double ZTolerance) + { + mesh->ExportMED( _file.c_str(), aMeshName.c_str(), auto_groups, _version, + partDS, autoDimension,have0dField,ZTolerance); -void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - CORBA::Long version, - CORBA::Boolean overwrite, - CORBA::Boolean autoDimension, - const GEOM::ListOfFields& fields, - const char* geomAssocFields, - CORBA::Double ZTolerance) + } + + void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField, SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields, const char*geomAssocFields) + { + DriverMED_W_Field fieldWriter; + fieldWriter.SetFile( _file.c_str() ); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + self.exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + } + + void prepareForWriting(SMESH_Mesh_i& self) { self.PrepareForWriting(_file.c_str(), _overwrite); } +private: + std::string _file; + CORBA::Boolean _overwrite; + CORBA::Long _version; +}; + + +template +void SMESH_Mesh_i::ExportPartToMEDCommon(SPECLS& speCls, + SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance) { - MESSAGE("MED version: "<< version); SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3957,10 +3982,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( CORBA::is_nil( meshPart ) || SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) { - aMeshName = prepareMeshNameAndGroups(file, overwrite); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, - 0, autoDimension, /*addODOnVertices=*/have0dField, - ZTolerance); + aMeshName = speCls.prepareMeshNameAndGroups(*this); + speCls.exportTo(_impl, aMeshName, auto_groups, nullptr, autoDimension, have0dField, ZTolerance); meshDS = _impl->GetMeshDS(); } else @@ -3968,7 +3991,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - PrepareForWriting(file, overwrite); + speCls.prepareForWriting(*this); SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart ); if ( !SO->_is_nil() ) { @@ -3977,8 +4000,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, } SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, - partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance); + speCls.exportTo(_impl, aMeshName, auto_groups, partDS, autoDimension, have0dField, ZTolerance); meshDS = tmpDSDeleter._obj = partDS; } @@ -3986,15 +4008,32 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, if ( _impl->HasShapeToMesh() ) { - DriverMED_W_Field fieldWriter; - fieldWriter.SetFile( file ); - fieldWriter.SetMeshName( aMeshName ); - fieldWriter.AddODOnVertices( have0dField ); - - exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + speCls.exportField(*this,aMeshName,have0dField,meshDS,fields,geomAssocFields); } + SMESH_CATCH( SMESH::throwCorbaException ); +} +//================================================================================ +/*! + * \brief Export a part of mesh to a med file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + CORBA::Long version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance) +{ + MESSAGE("MED version: "<< version); + MEDFileSpeCls spe(file,overwrite,version); + this->ExportPartToMEDCommon(spe,meshPart,auto_groups,autoDimension,fields,geomAssocFields,ZTolerance); // dump + SMESH_TRY; GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO; goList->length( fields.length() ); for ( size_t i = 0; i < fields.length(); ++i ) @@ -4013,10 +4052,45 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, << ( geomAssocFields ? geomAssocFields : "" ) << "'," << TVar( ZTolerance ) << " )"; - SMESH_CATCH( SMESH::throwCorbaException ); } +class MEDFileMemSpeCls +{ +public: + std::string prepareMeshNameAndGroups(SMESH_Mesh_i& self) { return self.generateMeshName(); } + void exportTo(SMESH_Mesh *mesh, const std::string& aMeshName, CORBA::Boolean auto_groups, + SMESH_MeshPartDS* partDS, + CORBA::Boolean autoDimension, bool have0dField, + CORBA::Double ZTolerance) + { + _res = mesh->ExportMEDCoupling(aMeshName.c_str(),auto_groups,partDS,autoDimension,have0dField,ZTolerance); + } + void prepareForWriting(SMESH_Mesh_i& self) { /* nothing here */ } + void exportField(SMESH_Mesh_i& self, const std::string& aMeshName, bool have0dField, SMESHDS_Mesh *meshDS, const GEOM::ListOfFields& fields, const char*geomAssocFields) + { + THROW_IK_EXCEPTION("exportField Not implemented yet for full memory !"); + } +public: + MEDCoupling::MCAuto getData() { return _res; } +private: + MEDCoupling::MCAuto _res; +}; + +CORBA::LongLong SMESH_Mesh_i::ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance) +{ + MEDFileMemSpeCls spe; + this->ExportPartToMEDCommon(spe,meshPart,auto_groups,autoDimension,fields,geomAssocFields,ZTolerance); + MEDCoupling::MCAuto res( spe.getData() ); + MEDCoupling::DataArrayByte *ret(res.retn()); + return reinterpret_cast(ret); +} + //================================================================================ /*! * Write GEOM fields to MED file diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 1592ed85c..f17c076de 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -229,6 +229,16 @@ public: const char* file, CORBA::Boolean withRequiredGroups); + + template + void ExportPartToMEDCommon(SPECLS& speCls, + SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDim, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance); + void ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, const char* file, CORBA::Boolean auto_groups, @@ -238,6 +248,14 @@ public: const GEOM::ListOfFields& fields, const char* geomAssocFields, CORBA::Double ZTolerance); + + CORBA::LongLong ExportPartToMEDCoupling(SMESH::SMESH_IDSource_ptr meshPart, + CORBA::Boolean auto_groups, + CORBA::Boolean autoDim, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance); + void ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart, const char* file); void ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart, @@ -630,15 +648,9 @@ public: std::map _mapSubMesh_i; //NRI std::map _mapSubMesh; //NRI -private: +public: std::string generateMeshName( ); std::string prepareMeshNameAndGroups( const char* file, CORBA::Boolean overwrite ); - - /*! - * Check and correct names of mesh groups - */ - void checkGroupNames(); - /* * Write GEOM fields to MED file */ @@ -646,6 +658,12 @@ private: SMESHDS_Mesh* meshDS, const GEOM::ListOfFields& fields, const char* geomAssocFields); +private: + /*! + * Check and correct names of mesh groups + */ + void checkGroupNames(); + /*! * Convert submesh ids into submesh interfaces */ diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index ef8bb8362..e80de4279 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -2355,11 +2355,9 @@ class Mesh(metaclass = MeshMeta): z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance) self.mesh.SetParameters(Parameters) - self.mesh.ExportPartToMEDCoupling( meshPart, auto_groups, - autoDimension, - fields, geomAssocFields, z_tolerance) + return self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance) else: - self.mesh.ExportMEDCoupling(auto_groups, autoDimension) + return self.mesh.ExportMEDCoupling(auto_groups, autoDimension) def ExportMED(self, *args, **kwargs): -- 2.39.2