Salome HOME
bos #24357 [CEA] Export mesh with field on vertices
[modules/smesh.git] / src / DriverMED / DriverMED_W_Field.cxx
index e40aac434f02d8d06962d5c802c21928845e12c8..1db5c32a8d7b2388899ac99d0b4f80b3476b4a10 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "DriverMED.hxx"
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "MED_Factory.hxx"
+#include "MED_TFile.hxx"
 #include "MED_Utilities.hxx"
 #include "MED_Wrapper.hxx"
 #include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_MeshElement.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMESHDS_Mesh.hxx"
+#include "SMESH_TypeDefs.hxx"
 
 //================================================================================
 /*!
@@ -91,23 +92,23 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
   }
 
   // find out "MED order" of elements - sort elements by geom type
-  int nbElems;
+  smIdType nbElems;
   if ( _nbElemsByGeom.empty() || _elemType != type )
   {
     _elemType = type;
-    _nbElemsByGeom.resize( 1, make_pair( SMDSEntity_Last, 0 ));
+    _nbElemsByGeom.resize( 1, std::make_pair( SMDSEntity_Last, 0 ));
 
     // count nb of elems of each geometry
-    for ( int iG = 0; iG < SMDSEntity_Last; ++iG )
+    SMDSAbs_EntityType geom = SMDSEntity_0D;
+    for ( ; geom < SMDSEntity_Last; SMESHUtils::Increment( geom ))
     {
-      SMDSAbs_EntityType  geom = (SMDSAbs_EntityType) iG;
-      SMDSAbs_ElementType t = SMDS_MeshCell::toSmdsType( geom );
+      SMDSAbs_ElementType t = SMDS_MeshCell::ElemType( geom );
       if ( t != _elemType ) continue;
 
       nbElems = mesh->GetMeshInfo().NbElements( geom );
       if ( nbElems < 1 ) continue;
 
-      _nbElemsByGeom.push_back( make_pair( geom, nbElems + _nbElemsByGeom.back().second ));
+      _nbElemsByGeom.push_back( std::make_pair( geom, nbElems + _nbElemsByGeom.back().second ));
     }
     // add nodes of missing 0D elements on VERTEXes
     if ( _addODOnVertices && _elemType == SMDSAbs_0DElement )
@@ -118,9 +119,9 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
       if ( !nodes.empty() )
       {
         if ( _nbElemsByGeom.size() == 1 )
-          _nbElemsByGeom.push_back( make_pair( SMDSEntity_0D, 0));
-        _nbElemsByGeom.push_back( make_pair( SMDSEntity_Node,
-                                             nodes.size() + _nbElemsByGeom.back().second ));
+          _nbElemsByGeom.push_back( std::make_pair( SMDSEntity_0D, 0));
+        _nbElemsByGeom.push_back( std::make_pair( SMDSEntity_Node,
+                                                  nodes.size() + _nbElemsByGeom.back().second ));
       }
     }
 
@@ -157,7 +158,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
   else
     _dblValues.reserve( nbElems * nbComps );
 
-  return nbElems * nbComps;
+  return nbElems && nbComps;
 }
 
 //================================================================================
@@ -237,16 +238,8 @@ SMDS_ElemIteratorPtr DriverMED_W_Field::GetOrderedElems()
   return SMDS_ElemIteratorPtr( new TItIterator( iterVec ));
 }
 
-//================================================================================
-/*!
- * Writes a field to the file
- */
-//================================================================================
-
-Driver_Mesh::Status DriverMED_W_Field::Perform()
+Driver_Mesh::Status DriverMED_W_Field::PerformInternal(MED::PWrapper& medFile)
 {
-  if ( myFile.empty() )
-    return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug'
   if ( myMeshId < 0 && myMeshName.empty() )
     return addMessage("Mesh in file not specified", /*isFatal=*/true );
   if ( _nbElemsByGeom.size() < 2 )
@@ -254,7 +247,6 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
   if ( !myMesh )
     return addMessage("Supporting mesh not set", /*isFatal=*/true );
 
-  MED::PWrapper medFile = MED::CrWrapper( myFile, MED::eV2_2 );
   MED::PMeshInfo meshInfo;
   if ( myMeshId > 0 )
   {
@@ -277,7 +269,7 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
       ( !myMeshName.empty() && meshInfo->GetName() != myMeshName ))
   {
     myMeshId = -1;
-    return addMessage("Specified mesh not found in the file", /*isFatal=*/true );
+    return addMessage("DriverMED_W_Field: Specified mesh not found in the file", /*isFatal=*/true );
   }
 
   // create a field
@@ -314,7 +306,7 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
     SMDSAbs_EntityType    smdsType = _nbElemsByGeom[iG].first;
     MED::EGeometrieElement medType = (MED::EGeometrieElement) DriverMED::GetMedGeoType( smdsType );
     int                    nbElems = _nbElemsByGeom[iG].second - _nbElemsByGeom[iG-1].second;
-    type2nb.insert( make_pair( medType, nbElems ));
+    type2nb.insert( std::make_pair( medType, nbElems ));
   }
 
   MED::EEntiteMaillage       entity = ( _elemType == SMDSAbs_Node ? MED::eNOEUD : MED::eMAILLE );
@@ -358,7 +350,45 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
   return DRS_OK;
 }
 
-namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx
+/*!
+ * Writes a field to the file
+ */
+Driver_Mesh::Status DriverMED_W_Field::Perform()
+{
+  if ( myFile.empty() )
+    return addMessage("File name not set", /*isFatal=*/true ); // 'fatal' means 'bug'
+  int version = -1, major, minor, release;
+  if ( MED::GetMEDVersion( myFile, major, minor, release ))
+    version = major * 10 + minor;
+
+  MED::PWrapper medFile = MED::CrWrapperW( myFile, version );
+  return this->PerformInternal(medFile);
+}
+
+/*!
+ * Writes a field to a chunck of memory
+ */
+Driver_Mesh::Status DriverMED_W_Field_Mem::Perform()
+{
+  Driver_Mesh::Status status = Driver_Mesh::DRS_OK;
+  bool isClosed(false);
+  void *ptr(_data->getPointer());
+  std::size_t sz(_data->getNumberOfTuples());
+  _data->accessToMemArray().setSpecificDeallocator(nullptr);
+  _data->useArray(nullptr,false,MEDCoupling::DeallocType::C_DEALLOC,0,1);
+  {// let braces to flush (call of MED::PWrapper myMed destructor)
+    MED::TMemFile *tfileInst = new MED::TMemFile(&ptr,&sz,&isClosed);
+    MED::PWrapper myMed = MED::CrWrapperW(myFile, -1, tfileInst);
+    status = this->PerformInternal(myMed);
+  }
+  if(!isClosed)
+    EXCEPTION(std::runtime_error, "TFTMemFile destructor : on destruction file has not been closed properly -> chunk of memory data may be invalid !");
+  _data = MEDCoupling::DataArrayByte::New();
+  _data->useArray(reinterpret_cast<char *>(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1);
+  return status;
+}
+
+namespace DriverMED // Implementation of functions declared in DriverMED.hxx
 {
   //================================================================================
   /*!
@@ -393,6 +423,7 @@ namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx
       theVec[ SMDSEntity_TriQuad_Hexa       ] = MED::eHEXA27  ;
       theVec[ SMDSEntity_Penta              ] = MED::ePENTA6  ;
       theVec[ SMDSEntity_Quad_Penta         ] = MED::ePENTA15 ;
+      theVec[ SMDSEntity_BiQuad_Penta       ] = MED::ePENTA18 ;
       theVec[ SMDSEntity_Hexagonal_Prism    ] = MED::eOCTA12  ;
       theVec[ SMDSEntity_Polyhedra          ] = MED::ePOLYEDRE;
       //theVec[ SMDSEntity_Quad_Polyhedra     ] = MED::ePOLYEDRE; // !!