Salome HOME
ILMAB: export GEOM fields to MED file
authoreap <eap@opencascade.com>
Wed, 5 Mar 2014 13:42:42 +0000 (17:42 +0400)
committereap <eap@opencascade.com>
Wed, 5 Mar 2014 13:42:42 +0000 (17:42 +0400)
23 files changed:
idl/SMESH_Mesh.idl
src/DriverMED/CMakeLists.txt
src/DriverMED/DriverMED.hxx
src/DriverMED/DriverMED_W_Field.cxx [new file with mode: 0644]
src/DriverMED/DriverMED_W_Field.h [new file with mode: 0644]
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/MEDWrapper/Base/MED_Common.hxx
src/SMDS/SMDSAbs_ElementType.hxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh0DElement.cxx
src/SMESH/SMESH_Mesh.cxx
src/SMESHGUI/CMakeLists.txt
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h [new file with mode: 0644]
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_DumpPython.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_PreMeshInfo.cxx
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_SWIG/smeshBuilder.py

index 2b72b3d..059170d 100644 (file)
@@ -613,39 +613,47 @@ module SMESH
      * - auto_groups : boolean parameter for creating/not creating
      *                 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
      *                 the typical use is auto_groups=false.
-     * - version : define the version of format of MED file, that will be created
+     * - version : defines the version of format of MED file, that will be created
      * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists
-     * - autoDimension: if @c True (default), a space dimension of a MED mesh can be either
+     * - 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
      *         - 3D in the rest cases.
-     *
-     *         If @a autoDimension is @c False, the space dimension is always 3.
+     *         If @a autoDimension is @c false, the space dimension is always 3.
      */
     void ExportToMEDX( in string      file, 
                        in boolean     auto_groups, 
                        in MED_VERSION version, 
                        in boolean     overwrite,
-                       in boolean     autoDimension ) raises (SALOME::SALOME_Exception);
+                       in boolean     autoDimension) raises (SALOME::SALOME_Exception);
 
     /*!
-     * Export a part of Mesh into a MED file
+     * Export a [part of] Mesh into a MED file
      * @params
      * - meshPart : a part of mesh to store
      * - file : name of the MED file
      * - version : define the version of format of MED file, that will be created
      * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists
-     * - autoDimension: if @c True, a space dimension for export is defined by mesh 
+     * - 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. 
      *                 If @a autoDimension == @c False, the space dimension is 3.
-     */
-    void ExportPartToMED( in SMESH_IDSource meshPart, 
-                          in string         file, 
-                          in boolean        auto_groups,
-                          in MED_VERSION    version,
-                          in boolean        overwrite,
-                          in boolean        autoDimension ) raises (SALOME::SALOME_Exception);
+     * - fields : list of GEOM fields defined on the shape to mesh.
+     * - geomAssocFields : each character of this string means a need to export a 
+     *         corresponding field; correspondence between fields and characters is following:
+     *         - 'v' stands for _vertices_ field;
+     *         - 'e' stands for _edges_ field;
+     *         - 'f' stands for _faces_ field;
+     *         - 's' stands for _solids_ field.
+     */
+    void ExportPartToMED( in SMESH_IDSource     meshPart,
+                          in string             file,
+                          in boolean            auto_groups,
+                          in MED_VERSION        version,
+                          in boolean            overwrite,
+                          in boolean            autoDimension,
+                          in GEOM::ListOfFields fields,
+                          in string             geomAssocFields ) raises (SALOME::SALOME_Exception);
 
     /*!
      * Export Mesh to a MED Format file
index 35f2fdd..28d1b8a 100644 (file)
@@ -67,6 +67,7 @@ SET(MeshDriverMED_HEADERS
   DriverMED_R_SMESHDS_Mesh.h
   DriverMED_W_SMESHDS_Mesh.h
   DriverMED_Family.h
+  DriverMED_W_Field.h
   SMESH_DriverMED.hxx
 )
 
@@ -77,6 +78,7 @@ SET(MeshDriverMED_SOURCES
   DriverMED_R_SMESHDS_Mesh.cxx
   DriverMED_W_SMESHDS_Mesh.cxx
   DriverMED_Family.cxx
+  DriverMED_W_Field.cxx
 )
 
 # --- rules ---
index ff1e3c1..857023e 100644 (file)
 
 // Declarations needed for usage of DriverMED
 
+#include "SMDSAbs_ElementType.hxx"
+
 #include <boost/shared_ptr.hpp>
 
 class DriverMED_Family;
 typedef boost::shared_ptr<DriverMED_Family> DriverMED_FamilyPtr;
+
+namespace DriverMED
+{
+  // Implemetation is in DriverMED_W_Field.cxx
+
+  /*
+   * Returns MED element geom type (MED::EGeometrieElement) by SMDS type
+   */
+  int GetMedGeoType( SMDSAbs_EntityType smdsType );
+  
+  /*
+   * Returns SMDS element geom type by MED type (MED::EGeometrieElement)
+   */
+  SMDSAbs_EntityType GetSMDSType( int medType );
+}
diff --git a/src/DriverMED/DriverMED_W_Field.cxx b/src/DriverMED/DriverMED_W_Field.cxx
new file mode 100644 (file)
index 0000000..721396f
--- /dev/null
@@ -0,0 +1,404 @@
+// Copyright (C) 2007-2014  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
+//
+// 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, or (at your option) any later version.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File      : DriverMED_W_Field.cxx
+// Created   : Thu Feb 27 17:45:00 2014
+// Author    : eap
+
+#include "DriverMED_W_Field.h"
+
+#include "DriverMED.hxx"
+#include "MED_Factory.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"
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+DriverMED_W_Field::DriverMED_W_Field():
+  //_medFileID( -1 ),
+  _elemType( SMDSAbs_All ),
+  _dt( -1 ),
+  _it( -1 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief Sets basic data
+ *  \param [in] mesh - supporting mesh
+ *  \param [in] fieldName - name of a field
+ *  \param [in] type - type of supporting elements
+ *  \param [in] nbComps - number of components
+ *  \param [in] isIntData - type of data: double or integer
+ */
+//================================================================================
+
+bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
+                            const std::string & fieldName,
+                            SMDSAbs_ElementType type,
+                            const int           nbComps,
+                            const bool          isIntData)
+{
+  _fieldName = fieldName;
+  _compNames.resize( nbComps, "" );
+
+  if ( type == SMDSAbs_All )
+  {
+    if ( mesh->NbVolumes() > 0 )
+      type = SMDSAbs_Volume;
+    else if ( mesh->NbFaces() > 0 )
+      type = SMDSAbs_Face;
+    else if ( mesh->NbEdges() > 0 )
+      type = SMDSAbs_Edge;
+    else
+      type = SMDSAbs_Node;
+  }
+  if ( myMesh != mesh )
+  {
+    _nbElemsByGeom.clear();
+    for ( int iG = 0; iG < SMDSEntity_Last; ++iG )
+      _elemsByGeom[iG].clear();
+    SetMesh( mesh );
+  }
+
+  // find out "MED order" of elements - sort elements by geom type
+  int nbElems;
+  if ( _nbElemsByGeom.empty() || _elemType != type )
+  {
+    _elemType = type;
+    _nbElemsByGeom.resize( 1, make_pair( SMDSEntity_Last, 0 ));
+
+    // count nb of elems of each geometry
+    for ( int iG = 0; iG < SMDSEntity_Last; ++iG )
+    {
+      SMDSAbs_EntityType  geom = (SMDSAbs_EntityType) iG;
+      SMDSAbs_ElementType t = SMDS_MeshCell::toSmdsType( geom );
+      if ( t != _elemType ) continue;
+
+      nbElems = mesh->GetMeshInfo().NbElements( geom );
+      if ( nbElems < 1 ) continue;
+
+      _nbElemsByGeom.push_back( make_pair( geom, nbElems + _nbElemsByGeom.back().second ));
+    }
+
+    // sort elements by their geometry
+    int iGeoType, nbGeomTypes = _nbElemsByGeom.size() - 1;
+    if ( nbGeomTypes > 1 )
+    {
+      for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
+      {
+        iGeoType = _nbElemsByGeom[iG].first;
+        nbElems  = _nbElemsByGeom[iG].second - _nbElemsByGeom[iG-1].second;
+        _elemsByGeom[ iGeoType ].reserve( nbElems );
+      }
+      if ( _elemsByGeom[ iGeoType ].empty() )
+      {
+        nbElems = mesh->GetMeshInfo().NbElements( _elemType );
+        SMDS_ElemIteratorPtr eIt = mesh->elementsIterator( _elemType );
+        for ( int iE = 0; iE < nbElems && eIt->more(); ++iE )
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          _elemsByGeom[ e->GetEntityType() ].push_back( e );
+        }
+      }
+    }
+  }
+  _intValues.clear();
+  _dblValues.clear();
+
+  // allocate memory for values
+  nbElems = _nbElemsByGeom.empty() ? 0 : _nbElemsByGeom.back().second;
+  if ( isIntData )
+    _intValues.reserve( nbElems * nbComps );
+  else
+    _dblValues.reserve( nbElems * nbComps );
+
+  return nbElems * nbComps;
+}
+
+//================================================================================
+/*!
+ * \brief Set a name of a component countered from zero
+ */
+//================================================================================
+
+void DriverMED_W_Field::SetCompName(const int iComp, const char* name)
+{
+  if ( _compNames.size() <= iComp )
+    _compNames.resize( iComp + 1 );
+  _compNames[ iComp ] = name;
+}
+
+//================================================================================
+/*!
+ * \brief Sets numdt and numit field features. Call this fun before AddValue()!
+ */
+//================================================================================
+
+void DriverMED_W_Field::SetDtIt(const int dt, const int it)
+{
+  _dt = dt;
+  _it = it;
+  _intValues.clear();
+  _dblValues.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Adds a float field value 
+ */
+//================================================================================
+
+void DriverMED_W_Field::AddValue( double val )
+{
+  _dblValues.push_back( val );
+}
+
+//================================================================================
+/*!
+ * \brief Adds an integer field value 
+ */
+//================================================================================
+
+void DriverMED_W_Field::AddValue( int    val )
+{
+  _intValues.push_back( val );
+}
+
+//================================================================================
+/*!
+ * Returns elements in the order they are written in MED file
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr DriverMED_W_Field::GetOrderedElems()
+{
+  if ( _nbElemsByGeom.size() < 2 )
+    return SMDS_ElemIteratorPtr();
+
+  if ( _nbElemsByGeom.size() == 2 )
+    // sole geom type of elements
+    return myMesh->elementsIterator( _elemType );
+
+  std::vector< SMDS_ElemIteratorPtr > iterVec( _nbElemsByGeom.size()-1 );
+  for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
+  {
+    int iGeoType = _nbElemsByGeom[ iG ].first;
+    iterVec[ iG-1 ] = SMDS_ElemIteratorPtr
+      ( new SMDS_ElementVectorIterator( _elemsByGeom[ iGeoType ].begin(),
+                                        _elemsByGeom[ iGeoType ].end() ));
+  }
+  typedef SMDS_IteratorOnIterators
+    < const SMDS_MeshElement *, std::vector< SMDS_ElemIteratorPtr > > TItIterator;
+  return SMDS_ElemIteratorPtr( new TItIterator( iterVec ));
+}
+
+//================================================================================
+/*!
+ * 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'
+  if ( myMeshId < 0 && myMeshName.empty() )
+    return addMessage("Mesh in file not specified", /*isFatal=*/true );
+  if ( _nbElemsByGeom.size() < 2 )
+    return addMessage("No values to write", /*isFatal=*/false );
+  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 )
+  {
+    meshInfo = medFile->GetPMeshInfo( myMeshId );
+  }
+  else
+  {
+    // look for a mesh by name
+    int aNbMeshes = medFile->GetNbMeshes();
+    for ( int iMesh = aNbMeshes; iMesh > 0 && myMeshId < 1; --iMesh )
+    {
+      meshInfo = medFile->GetPMeshInfo( iMesh );
+      if ( !meshInfo || meshInfo->GetName() != myMeshName )
+        meshInfo.reset();
+      else
+        myMeshId = iMesh;
+    }
+  }
+  if (( !meshInfo ) ||
+      ( !myMeshName.empty() && meshInfo->GetName() != myMeshName ))
+  {
+    myMeshId = -1;
+    return addMessage("Specified mesh not found in the file", /*isFatal=*/true );
+  }
+
+  // create a field
+  MED::ETypeChamp  dataType = _dblValues.empty() ? MED::eINT : MED::eFLOAT64;
+  MED::PFieldInfo fieldInfo = medFile->CrFieldInfo( meshInfo,
+                                                    _compNames.size(),
+                                                    dataType );
+  fieldInfo->SetName( _fieldName );
+  for ( size_t iC = 0; iC < _compNames.size(); ++iC )
+  {
+    fieldInfo->SetCompName( iC, _compNames[ iC ]);
+    fieldInfo->SetUnitName( iC, "");
+  }
+  if ( _compNames.size() > 1 )
+  {
+    for ( size_t i = 0; i < fieldInfo->myCompNames.size()-1; ++i )
+      if ( !fieldInfo->myCompNames[i] )
+        fieldInfo->myCompNames[i] = ' ';
+  }
+  medFile->SetFieldInfo( fieldInfo );
+
+  // create a time stamp
+  MED::TGeom2Size type2nb;
+  for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
+  {
+    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 ));
+  }
+
+  MED::EEntiteMaillage       entity = ( _elemType == SMDSAbs_Node ? MED::eNOEUD : MED::eMAILLE );
+  MED::PTimeStampInfo timeStampInfo = medFile->CrTimeStampInfo( fieldInfo, entity, type2nb );
+  timeStampInfo->myNumDt  = _dt;
+  timeStampInfo->myNumOrd = _it;
+
+  MED::PTimeStampValueBase  timeStampVal = medFile->CrTimeStampValue( timeStampInfo, dataType );
+  MED::PFloatTimeStampValue timeStampFltVal = timeStampVal;
+  MED::PIntTimeStampValue   timeStampIntVal = timeStampVal;
+
+  // set values
+  int iVal = 0, i, nbE;
+  MED::TFloat* ptrDbl = 0;
+  MED::TInt*   ptrInt = 0;
+  for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
+  {
+    SMDSAbs_EntityType    smdsType = _nbElemsByGeom[iG].first;
+    MED::EGeometrieElement medType = (MED::EGeometrieElement) DriverMED::GetMedGeoType( smdsType );
+    int nbElems = ( _nbElemsByGeom[iG].second - _nbElemsByGeom[iG-1].second ) * _compNames.size();
+    if ( dataType == MED::eFLOAT64 )
+    {
+      ptrDbl = timeStampFltVal->GetMeshValue( medType ).GetPointer();
+      for ( int i = 0; i < nbElems; ++i, ++iVal )
+        ptrDbl[ i ] = _dblValues[ iVal ];
+    }
+    else
+    {
+      ptrInt = timeStampIntVal->GetMeshValue( medType ).GetPointer();
+      for ( int i = 0; i < nbElems; ++i, ++iVal )
+        ptrInt[ i ] = _intValues[ iVal ];
+    }
+  }
+
+  // write
+  medFile->SetTimeStampValue( timeStampVal );
+
+  _dblValues.clear();
+  _intValues.clear();
+}
+
+namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx
+{
+  //================================================================================
+  /*!
+   * Returns a vector containing MED::EGeometrieElement for each SMDSAbs_EntityType
+   */
+  //================================================================================
+
+  const std::vector< MED::EGeometrieElement >& getMedTypesVec()
+  {
+    static std::vector< MED::EGeometrieElement > theVec;
+    if ( theVec.empty() )
+    {
+      theVec.resize( SMDSEntity_Last, MED::eAllGeoType );
+      theVec[ SMDSEntity_Node               ] = MED::eNONE    ;
+      theVec[ SMDSEntity_0D                 ] = MED::ePOINT1  ;
+      theVec[ SMDSEntity_Edge               ] = MED::eSEG2    ;
+      theVec[ SMDSEntity_Quad_Edge          ] = MED::eSEG3    ;
+      theVec[ SMDSEntity_Triangle           ] = MED::eTRIA3   ;
+      theVec[ SMDSEntity_Quad_Triangle      ] = MED::eTRIA6   ;
+      theVec[ SMDSEntity_BiQuad_Triangle    ] = MED::eTRIA7   ;
+      theVec[ SMDSEntity_Quadrangle         ] = MED::eQUAD4   ;
+      theVec[ SMDSEntity_Quad_Quadrangle    ] = MED::eQUAD8   ;
+      theVec[ SMDSEntity_BiQuad_Quadrangle  ] = MED::eQUAD9   ;
+      theVec[ SMDSEntity_Polygon            ] = MED::ePOLYGONE;
+      //theVec[ SMDSEntity_Quad_Polygon       ] = MED::ePOLYGONE; // !!
+      theVec[ SMDSEntity_Tetra              ] = MED::eTETRA4  ;
+      theVec[ SMDSEntity_Quad_Tetra         ] = MED::eTETRA10 ;
+      theVec[ SMDSEntity_Pyramid            ] = MED::ePYRA5   ;
+      theVec[ SMDSEntity_Quad_Pyramid       ] = MED::ePYRA13  ;
+      theVec[ SMDSEntity_Hexa               ] = MED::eHEXA8   ;
+      theVec[ SMDSEntity_Quad_Hexa          ] = MED::eHEXA20  ;
+      theVec[ SMDSEntity_TriQuad_Hexa       ] = MED::eHEXA27  ;
+      theVec[ SMDSEntity_Penta              ] = MED::ePENTA6  ;
+      theVec[ SMDSEntity_Quad_Penta         ] = MED::ePENTA15 ;
+      theVec[ SMDSEntity_Hexagonal_Prism    ] = MED::eOCTA12  ;
+      theVec[ SMDSEntity_Polyhedra          ] = MED::ePOLYEDRE;
+      //theVec[ SMDSEntity_Quad_Polyhedra     ] = MED::ePOLYEDRE; // !!
+      theVec[ SMDSEntity_Ball               ] = MED::eBALL    ;
+    }
+    return theVec;
+  }
+
+  //================================================================================
+  /*!
+   * Returns MED element geom type (MED::EGeometrieElement) by SMDS type
+   */
+  //================================================================================
+
+  int GetMedGeoType( SMDSAbs_EntityType smdsType )
+  {
+    return getMedTypesVec()[ smdsType ];
+  }
+
+  //================================================================================
+  /*!
+   * Returns SMDS element geom type by MED type (MED::EGeometrieElement)
+   */
+  //================================================================================
+
+  SMDSAbs_EntityType GetSMDSType( int medType )
+  {
+    const std::vector< MED::EGeometrieElement >& theVec = getMedTypesVec();
+
+    std::vector< MED::EGeometrieElement >::const_iterator i =
+      std::find( theVec.begin(), theVec.end(), medType );
+
+    return SMDSAbs_EntityType( std::distance( theVec.begin(), i ));
+  }
+}
diff --git a/src/DriverMED/DriverMED_W_Field.h b/src/DriverMED/DriverMED_W_Field.h
new file mode 100644 (file)
index 0000000..56b907d
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2007-2014  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
+//
+// 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, or (at your option) any later version.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH DriverMED : driver to write a field to 'med' file
+//  Module : SMESH
+//
+#ifndef _INCLUDE_DriverMED_W_Field
+#define _INCLUDE_DriverMED_W_Field
+
+#include "SMESH_DriverMED.hxx"
+
+#include "Driver_SMESHDS_Mesh.h"
+#include "SMDSAbs_ElementType.hxx"
+#include "SMDS_ElemIterator.hxx"
+
+#include <string>
+#include <vector>
+
+class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
+{
+ public:
+
+  DriverMED_W_Field();
+
+  bool Set(SMESHDS_Mesh *      mesh,
+           const std::string & fieldName,
+           SMDSAbs_ElementType type,
+           const int           nbComps,
+           const bool          isIntData);
+
+  void SetCompName(const int iComp, const char* name);
+
+  void SetDtIt(const int dt, const int it);
+
+  void AddValue( double val );
+  void AddValue( int    val );
+
+  /*
+   * Returns elements in the order they are written in MED file. Result can be NULL!
+   */
+  SMDS_ElemIteratorPtr GetOrderedElems();
+
+  /*
+   * Add one field to the file
+   */
+  virtual Status Perform();
+
+ private:
+
+  std::string                _fieldName;
+  SMDSAbs_ElementType        _elemType;
+  std::vector< std::string > _compNames;
+  std::vector< double >      _dblValues;
+  std::vector< int >         _intValues;
+  int                        _dt, _it;
+
+  std::vector< const SMDS_MeshElement* >              _elemsByGeom[SMDSEntity_Last];
+  std::vector< std::pair< SMDSAbs_EntityType, int > > _nbElemsByGeom;
+};
+
+#endif
index 1006479..f46f225 100644 (file)
@@ -483,7 +483,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       int aNodeID = aCoordHelperPtr->GetID();
       aNodeInfo->SetElemNum( iNode, aNodeID );
 #ifdef _EDF_NODE_IDS_
-      aNodeIdMap[aNodeID] = iNode+1;
+      aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 ));
 #endif
       // family number
       const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
index be1e11c..0c11823 100644 (file)
@@ -59,7 +59,7 @@ namespace MED{
 
   typedef enum {eFULL_INTERLACE, eNO_INTERLACE} EModeSwitch;
 
-  typedef enum {eFLOAT64=6, eINT=26} ETypeChamp;
+  typedef enum {eFLOAT64=6, eINT=24, eLONG=26 } ETypeChamp;
 
   typedef enum {eNON_STRUCTURE, eSTRUCTURE} EMaillage;
 
index d81f675..f80b41e 100644 (file)
@@ -74,8 +74,7 @@ enum SMDSAbs_ElementOrder {
 };
 
 /*!
- * Enumeration of entity type uses in mesh info array,
- *  and should be synchronised with enum in SMDS  
+ * Enumeration of entity type used in mesh info array
  */
 enum SMDSAbs_EntityType {
   SMDSEntity_Node,
index 936c775..63c6586 100644 (file)
@@ -2944,6 +2944,11 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) c
 
 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
 {
+  if ( type == SMDSEntity_Node )
+  {
+    typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
+    return SMDS_ElemIteratorPtr( new TIterator(myNodes));
+  }
   // naturally always sorted by ID
   typedef ElemVecIterator
     < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
index bf67bdf..6f1c7f8 100644 (file)
@@ -38,7 +38,6 @@ using namespace std;
 //=======================================================================
 SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node)
 {
-  MESSAGE("SMDS_Mesh0DElement " << GetID());
   myNode = node;
 }
 
index ead79de..692940c 100644 (file)
@@ -1268,6 +1268,19 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 //================================================================================
 /*!
  * \brief Export the mesh to a med file
+ *  \param [in] file - name of the MED file
+ *  \param [in] theMeshName - name of this mesh
+ *  \param [in] theAutoGroups - boolean parameter for creating/not creating
+ *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
+ *              the typical use is auto_groups=false.
+ *  \param [in] theVersion - defines the version of format of MED file, that will be created
+ *  \param [in] meshPart - mesh data to export
+ *  \param [in] theAutoDimension - 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
+     *         - 3D in the rest cases.
+     *         If \a theAutoDimension is \c false, the space dimension is always 3.
+ *  \return int - mesh index in the file
  */
 //================================================================================
 
index f301031..39f7447 100644 (file)
@@ -141,6 +141,7 @@ SET(_moc_HEADERS
   SMESHGUI_ReorientFacesDlg.h
   SMESHGUI_PropertiesDlg.h
   SMESHGUI_Add0DElemsOnAllNodesDlg.h
+  SMESHGUI_FieldSelectorWdg.h
 )
 
 # header files / no moc processing
@@ -246,6 +247,7 @@ SET(_other_SOURCES
   SMESHGUI_Filter.cxx
   SMESHGUI_MeshEditPreview.cxx
   SMESHGUI_FileValidator.cxx
+  SMESHGUI_FieldSelectorWdg.cxx
 )
 
 # sources / to compile
index 2d14195..aa09da8 100644 (file)
@@ -44,6 +44,7 @@
 #include "SMESHGUI_DuplicateNodesDlg.h"
 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
 #include "SMESHGUI_ExtrusionDlg.h"
+#include "SMESHGUI_FieldSelectorWdg.h"
 #include "SMESHGUI_FileInfoDlg.h"
 #include "SMESHGUI_FileValidator.h"
 #include "SMESHGUI_FilterDlg.h"
@@ -212,7 +213,12 @@ namespace
   void Control( int theCommandID );
 
   // Definitions
-  //=============================================================
+  //================================================================================
+  /*!
+   * \brief Reads meshes from file
+   */
+  //================================================================================
+
   void ImportMeshesFromFile( SMESH::SMESH_Gen_ptr theComponentMesh,
                              int theCommandID )
   {
@@ -611,6 +617,8 @@ namespace
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
       anInitialPath = QDir::currentPath();
 
+    QList< QPair< GEOM::ListOfFields_var, QString > > aFieldList;
+
     // Get a file name to write in and additional otions
     if ( isUNV || isDAT || isGMF ) // Export w/o options
     {
@@ -696,8 +704,13 @@ namespace
       QStringList checkBoxes;
       checkBoxes << QObject::tr("SMESH_AUTO_GROUPS") << QObject::tr("SMESH_AUTO_DIM");
 
+      SMESHGUI_FieldSelectorWdg* fieldSelWdg = new SMESHGUI_FieldSelectorWdg();
+      QList< QWidget* > wdgList;
+      if ( fieldSelWdg->GetAllFeilds( aMeshList, aFieldList ))
+        wdgList.append( fieldSelWdg );
+
       SalomeApp_CheckFileDlg* fd =
-        new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true );
+        new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, checkBoxes, true, true, wdgList );
       fd->setWindowTitle( aTitle );
       fd->setNameFilters( filters );
       fd->selectNameFilter( aDefaultFilter );
@@ -787,6 +800,9 @@ namespace
       }
       toCreateGroups = fd->IsChecked(0);
       toFindOutDim   = fd->IsChecked(1);
+      fieldSelWdg->GetSelectedFeilds();
+      if ( !fieldSelWdg->parent() )
+        delete fieldSelWdg;
       delete fd;
     }
     else
@@ -823,12 +839,16 @@ namespace
           {
             SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
             SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
-            if ( aMeshOrGroup->_is_equivalent( aMeshItem ))
+            const GEOM::ListOfFields&       fields = aFieldList[ aMeshIndex ].first.in();
+            const QString&            geoAssFields = aFieldList[ aMeshIndex ].second;
+            const bool                   hasFields = ( fields.length() || !geoAssFields.isEmpty() );
+            if ( !hasFields && aMeshOrGroup->_is_equivalent( aMeshItem ))
               aMeshItem->ExportToMEDX( aFilename.toUtf8().data(), toCreateGroups,
                                        aFormat, toOverwrite && aMeshIndex == 0, toFindOutDim );
             else
               aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toUtf8().data(), toCreateGroups,
-                                          aFormat, toOverwrite && aMeshIndex == 0, toFindOutDim );
+                                          aFormat, toOverwrite && aMeshIndex == 0, toFindOutDim,
+                                          fields, geoAssFields.toLatin1().data() );
           }
         }
         else if ( isSAUV )
diff --git a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx
new file mode 100644 (file)
index 0000000..3185ea3
--- /dev/null
@@ -0,0 +1,237 @@
+// Copyright (C) 2007-2014  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
+//
+// 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, or (at your option) any later version.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SMESHGUI_FieldSelectorWdg.h"
+
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+
+#include <SALOMEDSClient_Study.hxx>
+#include <GEOM_wrap.hxx>
+
+#include <QGroupBox>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QTreeWidgetItemIterator>
+#include <QVBoxLayout>
+#include <QLabel>
+#include "SMESHGUI.h"
+
+namespace
+{
+  QTreeWidgetItem* createItem( QTreeWidget*     tree,
+                               const QString&   text,
+                               const int        index,
+                               QTreeWidgetItem* parentItem=0)
+  {
+    QTreeWidgetItem* item;
+    if ( parentItem )
+      item = new QTreeWidgetItem( parentItem );
+    else
+      item = new QTreeWidgetItem( tree );
+    item->setText( 0, text );
+    item->setData( 0, Qt::UserRole, index );
+    item->setFlags( item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsEditable );
+    item->setCheckState( 0, Qt::Unchecked );
+    item->setExpanded( true );
+    if ( index < 0 )
+    {
+      QFont f = item->font( 0 );
+      f.setItalic( true );
+      item->setFont( 0, f );
+    }
+    return item;
+  }
+}
+
+//--------------------------------------------------------------------------------
+/*!
+ * \brief Constructor of SMESHGUI_FieldSelectorWdg
+ */
+SMESHGUI_FieldSelectorWdg::SMESHGUI_FieldSelectorWdg( QWidget* p )
+  :QGroupBox( tr("FIELDS_TO_EXPORT"), p )
+{
+  setCheckable( true );
+  myTree = new QTreeWidget( this );
+  myTree->setHeaderHidden( true );
+  
+  QVBoxLayout* lay = new QVBoxLayout( this );
+  lay->addWidget( myTree );
+
+  connect( myTree, SIGNAL( itemChanged(QTreeWidgetItem*, int)),
+           this,   SLOT  ( onItemCheck(QTreeWidgetItem*, int)));
+}
+
+//--------------------------------------------------------------------------------
+/*!
+ * \brief Retrieves all fields defined on geometry of given meshes
+ */
+bool SMESHGUI_FieldSelectorWdg::
+GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+             QList< QPair< GEOM::ListOfFields_var, QString > >&          fields)
+{
+  myFields = & fields;
+  myTree->clear();
+  
+  _PTR(Study) study = SMESH::GetActiveStudyDocument();
+  GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+  GEOM::GEOM_IFieldOperations_wrap fieldOp = geomGen->GetIFieldOperations( study->StudyId() );
+
+  for ( int iM = 0; iM < meshes.count(); ++iM )
+  {
+    GEOM::ListOfFields_var fields;
+    QString                geoAss;
+
+    SMESH::SMESH_Mesh_var mesh = meshes[iM].first->GetMesh();
+    if ( !mesh->_is_nil() && mesh->HasShapeToMesh() )
+    {
+      SMESH::array_of_ElementType_var elemTypes = meshes[iM].first->GetTypes();
+      if ( &elemTypes.in() && elemTypes->length() > 0 )
+      {
+        QTreeWidgetItem* meshItem = createItem( myTree, meshes[iM].second, iM );
+
+        GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
+        fields = fieldOp->GetFields( shape );
+        for ( size_t iF = 0; iF < fields->length(); ++iF )
+        {
+          CORBA::String_var name = fields[iF]->GetName();
+          createItem( myTree, name.in(), iF, meshItem );
+        }
+        QString geoAss;
+        for ( size_t i = 0; i < elemTypes->length(); ++i )
+        {
+          QString name;
+          switch ( elemTypes[i] ) {
+          case SMESH::NODE:   name = "_vertices_"; break;
+          case SMESH::EDGE:   name = "_edges_"   ; break;
+          case SMESH::FACE:   name = "_faces_"   ; break;
+          case SMESH::VOLUME: name = "_solids_"  ; break;
+          default: continue;
+          }
+          geoAss += name[1];
+          createItem( myTree, name, -1, meshItem );
+        }
+        if ( !geoAss.isEmpty() && !geoAss.count('v') )
+        {
+          createItem( myTree, "_vertices_", -1, meshItem );
+        }
+      }
+    } // if ( mesh->HasShapeToMesh() )
+
+    if ( ! &fields.in() )
+      fields = new GEOM::ListOfFields();
+
+    myFields->push_back( qMakePair( fields, QString() ));
+
+  } // loop on meshes
+
+  setChecked( false );
+
+  return myTree->topLevelItemCount();
+}
+
+//--------------------------------------------------------------------------------
+/*!
+ * \brief Filter off not selected fields from myFields
+ */
+bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds()
+{
+  int nbSelected = 0;
+  if ( myTree->isEnabled() )
+    for ( size_t i = 0; i < myTree->topLevelItemCount(); ++i )
+    {
+      QTreeWidgetItem* meshItem = myTree->topLevelItem( i );
+      int iM = meshItem->data( 0, Qt::UserRole ).toInt();
+
+      GEOM::ListOfFields& fields = (*myFields)[ iM ].first.inout();
+      QString&            geoAss = (*myFields)[ iM ].second;
+
+      int nbF = 0;
+      QTreeWidgetItemIterator it ( meshItem, QTreeWidgetItemIterator::Checked );
+      if ( *it == meshItem ) ++it;
+      for ( ; *it ; ++it, ++nbSelected )
+      {
+        if ( !(*it)->parent() )
+          break; // next mesh item
+
+        int iF = (*it)->data( 0, Qt::UserRole ).toInt();
+        if ( iF < 0 )
+        {
+          geoAss += (*it)->text(0)[1];
+        }
+        else
+        {
+          if ( nbF != iF )
+            fields[ nbF ] = fields[ iF ];
+          ++nbF;
+        }
+      }
+      fields.length( nbF );
+    }
+  else
+  {
+    for ( size_t iF = 0; iF < myFields->count(); ++iF )
+    {
+      GEOM::ListOfFields& fields = (*myFields)[ iF ].first.inout();
+      fields.length( 0 );
+    }
+  }
+  return nbSelected;
+}
+
+//--------------------------------------------------------------------------------
+/*!
+ * \brief SLOT called when a tree item is checked
+ */
+void SMESHGUI_FieldSelectorWdg::onItemCheck(QTreeWidgetItem * item, int column)
+{
+  myTree->blockSignals( true );
+  if ( !item->parent() ) // mesh item
+  {
+    Qt::CheckState st = item->checkState(0);
+    QTreeWidgetItemIterator it( item );
+    for ( ++it; *it ; ++it )
+      if ( !(*it)->parent() )
+        break; // next mesh item
+      else
+        (*it)->setCheckState( 0, st );
+  }
+  else // field item
+  {
+    // update CheckState of a parent mesh item
+    QTreeWidgetItem* meshItem = item->parent();
+    Qt::CheckState st = item->checkState(0);
+    QTreeWidgetItemIterator it( meshItem );
+    for ( ++it; *it ; ++it )
+      if ( !(*it)->parent() )
+      {
+        break; // next mesh item
+      }
+      else if ( (*it)->checkState(0) != st )
+      {
+        st = Qt::PartiallyChecked;
+        break;
+      }
+    meshItem->setCheckState( 0, st );
+  }
+  myTree->blockSignals( false );
+}
diff --git a/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h
new file mode 100644 (file)
index 0000000..feaa834
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2007-2014  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
+//
+// 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, or (at your option) any later version.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef STDMESHERSGUI_FieldSelectorWdg_H
+#define STDMESHERSGUI_FieldSelectorWdg_H
+
+#include "SMESH_SMESHGUI.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SMESH_Mesh)
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+
+#include <QGroupBox>
+
+class QTreeWidget;
+class QTreeWidgetItem;
+
+/*!
+ * \brief Widget listing all fields available for export to MED file
+ */
+class SMESHGUI_EXPORT SMESHGUI_FieldSelectorWdg : public QGroupBox
+{
+  Q_OBJECT
+
+ public:
+  SMESHGUI_FieldSelectorWdg( QWidget* = 0 );
+
+  bool GetAllFeilds(const QList< QPair< SMESH::SMESH_IDSource_var, QString > >& meshes,
+                    QList< QPair< GEOM::ListOfFields_var,          QString > >& fields);
+
+  bool GetSelectedFeilds();
+
+ private slots:
+  
+  void onItemCheck(QTreeWidgetItem * item, int column);
+
+ private:
+
+  QList< QPair< GEOM::ListOfFields_var, QString > > * myFields;
+  QTreeWidget*                                        myTree;
+};
+
+#endif // STDMESHERSGUI_FieldSelectorWdg_H
index baf4a4c..ec5ab32 100644 (file)
@@ -4221,6 +4221,13 @@ It can&apos;t be deleted </translation>
     </message>
 </context>
 <context>
+    <name>SMESHGUI_FieldSelectorWdg</name>
+    <message>
+        <source>FIELDS_TO_EXPORT</source>
+        <translation>Export Fields</translation>
+    </message>
+</context>
+<context>
     <name>SMESHGUI_Dialog</name>
     <message>
         <source>DLG_MESH</source>
index e12cd7f..f5595c0 100644 (file)
@@ -1963,9 +1963,9 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       TCollection_AsciiString newMethod = method;
       newMethod.Remove( 7, 6 );
       theCommand->SetMethod( newMethod );
-      // make the 1st arg be the last one (or last but one for ExportMED())
+      // make the 1st arg be the last one (or last but three for ExportMED())
       _pyID partID = theCommand->GetArg( 1 );
-      int nbArgs = theCommand->GetNbArgs() - (newMethod == "ExportMED");
+      int nbArgs = theCommand->GetNbArgs() - 3 * (newMethod == "ExportMED");
       for ( int i = 2; i <= nbArgs; ++i )
         theCommand->SetArg( i-1, theCommand->GetArg( i ));
       theCommand->SetArg( nbArgs, partID );
index 74ed8aa..494722b 100644 (file)
@@ -536,6 +536,11 @@ namespace SMESH
     DumpArray( theList, *this );
     return *this;
   }
+  TPythonDump& TPythonDump::operator<<(const GEOM::ListOfGBO& theList)
+  {
+    DumpArray( theList, *this );
+    return *this;
+  }
   TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList)
   {
     DumpArray( theList, *this );
index c24ea94..2689dc8 100644 (file)
@@ -26,6 +26,7 @@
 #include "SMESH_Mesh_i.hxx"
 
 #include "DriverMED_R_SMESHDS_Mesh.h"
+#include "DriverMED_W_Field.h"
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "MED_Factory.hxx"
 #include "SMDS_EdgePosition.hxx"
@@ -2719,13 +2720,13 @@ void SMESH_Mesh_i::ExportToMEDX (const char*        file,
     _preMeshInfo->FullLoadFromFile();
 
   string aMeshName = prepareMeshNameAndGroups(file, overwrite);
+  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
+
   TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
                 << file << "', " << auto_groups << ", "
                 << theVersion << ", " << overwrite << ", "
                 << autoDimension << " )";
 
-  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
-
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
@@ -2847,26 +2848,113 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   _impl->ExportSTL(file, isascii);
 }
 
+namespace // utils used by ExportPartToMED()
+{
+  // remover of 0d elements temporary added by ExportPartToMED()
+  struct OdRemover
+  {
+    std::vector< const SMDS_MeshElement* > _0dElems;
+    SMESHDS_Mesh*                          _mesh;
+    OdRemover( SMESHDS_Mesh* mesh ): _mesh( mesh ) {}
+    ~OdRemover() {
+      for ( size_t i = 0; i < _0dElems.size(); ++i )
+        if ( _0dElems[i] )
+        {
+          SMESHDS_SubMesh* sm = _mesh->MeshElements( _0dElems[i]->getshapeId() );
+          _mesh->RemoveFreeElement( _0dElems[i], sm, false );
+        }
+    }
+  };
+}
+
 //================================================================================
 /*!
  * \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,
-                                   ::SMESH::MED_VERSION        version,
-                                   ::CORBA::Boolean            overwrite,
-                                   ::CORBA::Boolean            autoDimension)
+void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
+                                   const char*               file,
+                                   CORBA::Boolean            auto_groups,
+                                   SMESH::MED_VERSION        version,
+                                   CORBA::Boolean            overwrite,
+                                   CORBA::Boolean            autoDimension,
+                                   const GEOM::ListOfFields& fields,
+                                   const char*               geomAssocFields)
   throw (SALOME::SALOME_Exception)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-  TPythonDump pyDump;
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
-  if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
+  // check fields
+  bool have0dField = false;
+  if ( fields.length() > 0 )
   {
-    mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
+    GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
+    if ( shapeToMesh->_is_nil() )
+      THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
+
+    for ( size_t i = 0; i < fields.length(); ++i )
+    {
+      if ( fields[i]->GetDataType() == GEOM::FDT_String )
+        THROW_SALOME_CORBA_EXCEPTION
+          ( "Export of string fields is not supported", SALOME::BAD_PARAM);
+      GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
+      if ( fieldShape->_is_nil() )
+        THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
+      if ( !fieldShape->IsSame( shapeToMesh ) )
+        THROW_SALOME_CORBA_EXCEPTION
+          ( "Field defined not on shape", SALOME::BAD_PARAM);
+      if ( fields[i]->GetDimension() == 0 )
+        have0dField = true;
+    }
+    if ( geomAssocFields )
+      for ( int i = 0; geomAssocFields[i]; ++i )
+        switch ( geomAssocFields[i] ) {
+        case 'v':case 'e':case 'f':case 's': break;
+        case 'V':case 'E':case 'F':case 'S': break;
+        default: THROW_SALOME_CORBA_EXCEPTION
+            ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
+        }
+  }
+
+  SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
+
+  OdRemover a0dRemover( meshDS );
+  if ( have0dField )
+  {
+    // temporary add 0D elements on all nodes on vertices
+    for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
+    {
+      if ( meshDS->IndexToShape( i ).ShapeType() != TopAbs_VERTEX )
+        continue;
+      if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(i) ) {
+        SMDS_NodeIteratorPtr nIt= sm->GetNodes();
+        while (nIt->more())
+        {
+          const SMDS_MeshNode* n = nIt->next();
+          if ( n->NbInverseElements( SMDSAbs_0DElement ) == 0 )
+          {
+            a0dRemover._0dElems.push_back( meshDS->Add0DElement( n ));
+            sm->AddElement( a0dRemover._0dElems.back() );
+          }
+        }
+      }
+    }
+  }
+
+  // write mesh
+
+  string aMeshName = "Mesh";
+  SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
+  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 );
+
+    meshDS = _impl->GetMeshDS();
   }
   else
   {
@@ -2875,7 +2963,6 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
 
     PrepareForWriting(file, overwrite);
 
-    string aMeshName = "Mesh";
     SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
     if ( !aStudy->_is_nil() ) {
       SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
@@ -2884,13 +2971,286 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
         aMeshName = name;
       }
     }
-    SMESH_MeshPartDS partDS( meshPart );
-    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
+    SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
+    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, partDS, autoDimension );
+
+    meshDS = tmpDSDeleter._obj = partDS;
+  }
+
+  // write fields
+
+  if ( _impl->HasShapeToMesh() )
+  {
+    DriverMED_W_Field fieldWriter;
+    fieldWriter.SetFile( file );
+    fieldWriter.SetMeshName( aMeshName );
+
+    exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
+  }
+
+  // dump
+  GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
+  goList->length( fields.length() );
+  for ( size_t i = 0; i < fields.length(); ++i )
+  {
+    GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
+    goList[i] = gbo;
   }
-  pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( "
-         << meshPart << ", r'" << file << "', "
-         << auto_groups << ", " << version << ", " << overwrite << ", "
-         << autoDimension << " )";
+  TPythonDump() << _this() << ".ExportPartToMED( "
+                << meshPart << ", r'" << file << "', "
+                << auto_groups << ", " << version << ", " << overwrite << ", "
+                << autoDimension << ", " << goList
+                << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
+
+//================================================================================
+/*!
+ * Write GEOM fields to MED file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
+                                    SMESHDS_Mesh*             meshDS,
+                                    const GEOM::ListOfFields& fields,
+                                    const char*               geomAssocFields)
+{
+#define METH "SMESH_Mesh_i::exportMEDFields() "
+
+  if (( fields.length() < 1 ) &&
+      ( !geomAssocFields || !geomAssocFields[0] ))
+    return;
+
+  std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
+  std::vector< int >    intVals( meshDS->MaxShapeIndex()+1 );
+  std::vector< int >    subIdsByDim[ 4 ];
+  const double noneDblValue = 0.;
+  const double noneIntValue = 0;
+
+  for ( size_t iF = 0; iF < fields.length(); ++iF )
+  {
+    // set field data
+
+    int dim = fields[ iF ]->GetDimension();
+    SMDSAbs_ElementType elemType;
+    TopAbs_ShapeEnum    shapeType;
+    switch ( dim ) {
+    case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
+    case 1: elemType = SMDSAbs_Edge;      shapeType = TopAbs_EDGE;   break;
+    case 2: elemType = SMDSAbs_Face;      shapeType = TopAbs_FACE;   break;
+    case 3: elemType = SMDSAbs_Volume;    shapeType = TopAbs_SOLID;  break;
+    default:
+      continue; // skip fields on whole shape
+    }
+    GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
+    if ( dataType == GEOM::FDT_String )
+      continue;
+    GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
+    if ( stepIDs->length() < 1 )
+      continue;
+    GEOM::string_array_var comps = fields[ iF ]->GetComponents();
+    if ( comps->length() < 1 )
+      continue;
+    CORBA::String_var       name = fields[ iF ]->GetName();
+
+    if ( !fieldWriter.Set( meshDS,
+                           name.in(),
+                           elemType,
+                           comps->length(),
+                           ( dataType == GEOM::FDT_Int )))
+      continue;
+
+    for ( size_t iC = 0; iC < comps->length(); ++iC )
+      fieldWriter.SetCompName( iC, comps[ iC ].in() );
+
+    // find sub-shape IDs
+
+    std::vector< int >& subIds = subIdsByDim[ dim ];
+    if ( subIds.empty() )
+      for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
+        if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
+          subIds.push_back( id );
+
+    // write steps
+
+    SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
+    if ( !elemIt )
+      continue;
+
+    for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
+    {
+      GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
+      if ( step->_is_nil() )
+        continue;
+
+      CORBA::Long stamp = step->GetStamp();
+      CORBA::Long id    = step->GetID();
+      fieldWriter.SetDtIt( int( stamp ), int( id ));
+
+      // fill dblVals or intVals
+      switch ( dataType )
+      {
+      case GEOM::FDT_Double:
+      {
+        GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
+        if ( dblStep->_is_nil() ) continue;
+        GEOM::ListOfDouble_var vv = dblStep->GetValues();
+        if ( vv->length() != subIds.size() )
+          THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
+        for ( size_t i = 0; i < vv->length(); ++i )
+          dblVals[ subIds[ i ]] = vv[ i ];
+        break;
+      }
+      case GEOM::FDT_Int:
+      {
+        GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
+        if ( intStep->_is_nil() ) continue;
+        GEOM::ListOfLong_var vv = intStep->GetValues();
+        if ( vv->length() != subIds.size() )
+          THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
+        for ( size_t i = 0; i < vv->length(); ++i )
+          intVals[ subIds[ i ]] = (int) vv[ i ];
+        break;
+      }
+      case GEOM::FDT_Bool:
+      {
+        GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
+        if ( boolStep->_is_nil() ) continue;
+        GEOM::short_array_var vv = boolStep->GetValues();
+        if ( vv->length() != subIds.size() )
+          THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
+        for ( size_t i = 0; i < vv->length(); ++i )
+          intVals[ subIds[ i ]] = (int) vv[ i ];
+        break;
+      }
+      default: continue;
+      }
+
+      // pass values to fieldWriter
+      elemIt = fieldWriter.GetOrderedElems();
+      if ( dataType == GEOM::FDT_Double )
+        while ( elemIt->more() )
+        {
+          const SMDS_MeshElement* e = elemIt->next();
+          const int shapeID = e->getshapeId();
+          if ( shapeID < 1 || shapeID >= dblVals.size() )
+            fieldWriter.AddValue( noneDblValue );
+          else
+            fieldWriter.AddValue( dblVals[ shapeID ]);
+        }
+      else
+        while ( elemIt->more() )
+        {
+          const SMDS_MeshElement* e = elemIt->next();
+          const int shapeID = e->getshapeId();
+          if ( shapeID < 1 || shapeID >= intVals.size() )
+            fieldWriter.AddValue( noneIntValue );
+          else
+            fieldWriter.AddValue( intVals[ shapeID ]);
+        }
+
+      // write a step
+      fieldWriter.Perform();
+      SMESH_ComputeErrorPtr res = fieldWriter.GetError();
+      if ( res && res->IsKO() )
+      {
+        if ( res->myComment.empty() )
+        { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
+        else
+        { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
+      }
+
+    } // loop on steps
+  } // loop on fields
+
+  if ( !geomAssocFields || !geomAssocFields[0] )
+    return;
+
+  // write geomAssocFields
+
+  std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
+  shapeDim[ TopAbs_COMPOUND  ] = 3;
+  shapeDim[ TopAbs_COMPSOLID ] = 3;
+  shapeDim[ TopAbs_SOLID     ] = 3;
+  shapeDim[ TopAbs_SHELL     ] = 2;
+  shapeDim[ TopAbs_FACE      ] = 2;
+  shapeDim[ TopAbs_WIRE      ] = 1;
+  shapeDim[ TopAbs_EDGE      ] = 1;
+  shapeDim[ TopAbs_VERTEX    ] = 0;
+  shapeDim[ TopAbs_SHAPE     ] = 3;
+
+  for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
+  {
+    std::vector< std::string > compNames;
+    switch ( geomAssocFields[ iF ]) {
+    case 'v': case 'V':
+      fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
+      compNames.push_back( "dim" );
+      break;
+    case 'e': case 'E':
+      fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
+      break;
+    case 'f': case 'F':
+      fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
+      break;
+    case 's': case 'S':
+      fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
+      break;
+    default: continue;
+    }
+    compNames.push_back( "id" );
+    for ( size_t iC = 0; iC < compNames.size(); ++iC )
+      fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
+
+    fieldWriter.SetDtIt( -1, -1 );
+
+    SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
+    if ( !elemIt )
+      continue;
+
+    if ( compNames.size() == 2 ) // _vertices_
+      while ( elemIt->more() )
+      {
+        const SMDS_MeshElement* e = elemIt->next();
+        const int shapeID = e->getshapeId();
+        if ( shapeID < 1 )
+        {
+          fieldWriter.AddValue( -1 );
+          fieldWriter.AddValue( -1 );
+        }
+        else
+        {
+          const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
+          fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
+          fieldWriter.AddValue( shapeID );
+        }
+      }
+    else
+      while ( elemIt->more() )
+      {
+        const SMDS_MeshElement* e = elemIt->next();
+        const int shapeID = e->getshapeId();
+        if ( shapeID < 1 )
+          fieldWriter.AddValue( -1 );
+        else
+          fieldWriter.AddValue( shapeID );
+      }
+
+    // write a step
+    fieldWriter.Perform();
+    SMESH_ComputeErrorPtr res = fieldWriter.GetError();
+    if ( res && res->IsKO() )
+    {
+      if ( res->myComment.empty() )
+      { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
+      else
+      { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
+    }
+
+  } // loop on geomAssocFields
+
+#undef METH
 }
 
 //================================================================================
index 65de305..c6ad4eb 100644 (file)
@@ -47,6 +47,8 @@ class SMESH_GroupBase_i;
 class SMESH_subMesh_i;
 class SMESH_PreMeshInfo;
 class SMESH_MeshEditor_i;
+class DriverMED_W_Field;
+class SMESHDS_Mesh;
 
 class SMESH_I_EXPORT SMESH_Mesh_i:
   public virtual POA_SMESH::SMESH_Mesh,
@@ -255,7 +257,9 @@ public:
                        CORBA::Boolean            auto_groups,
                        SMESH::MED_VERSION        version,
                        CORBA::Boolean            overwrite,
-                       CORBA::Boolean            autoDim=true) throw (SALOME::SALOME_Exception);
+                       CORBA::Boolean            autoDim,
+                       const GEOM::ListOfFields& fields,
+                       const char*               geomAssocFields) throw (SALOME::SALOME_Exception);
   void ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart,
                        const char*               file) throw (SALOME::SALOME_Exception);
   void ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart,
@@ -650,6 +654,13 @@ private:
    */
   void checkGroupNames();
 
+  /*
+   * Write GEOM fields to MED file
+   */
+  void exportMEDFields( DriverMED_W_Field &       writer,
+                        SMESHDS_Mesh*             meshDS,
+                        const GEOM::ListOfFields& fields,
+                        const char*               geomAssocFields);
   /*!
    * Convert submesh ids into submesh interfaces
    */
index 2315d2b..59a7e65 100644 (file)
@@ -26,7 +26,9 @@
 
 #include "SMESH_PreMeshInfo.hxx"
 
+#include "DriverMED.hxx"
 #include "DriverMED_R_SMESHDS_Mesh.h"
+#include "MED_Factory.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
@@ -38,8 +40,6 @@
 #include "SMESH_Mesh_i.hxx"
 #include "SMESH_subMesh_i.hxx"
 
-#include <MED_Factory.hxx>
-
 #include <HDFarray.hxx>
 #include <HDFdataset.hxx>
 #include <HDFfile.hxx>
@@ -228,56 +228,19 @@ namespace
     static map< MED::EGeometrieElement, SMDSAbs_EntityType> med2smeshTypes;
     if ( med2smeshTypes.empty() )
     {
-      med2smeshTypes[ MED::ePOINT1   ] = SMDSEntity_0D                ;
-      med2smeshTypes[ MED::eSEG2     ] = SMDSEntity_Edge              ;
-      med2smeshTypes[ MED::eSEG3     ] = SMDSEntity_Quad_Edge         ;
-      med2smeshTypes[ MED::eTRIA3    ] = SMDSEntity_Triangle          ;
-      med2smeshTypes[ MED::eTRIA6    ] = SMDSEntity_Quad_Triangle     ;
-      med2smeshTypes[ MED::eTRIA7    ] = SMDSEntity_BiQuad_Triangle   ;
-      med2smeshTypes[ MED::eQUAD4    ] = SMDSEntity_Quadrangle        ;
-      med2smeshTypes[ MED::eQUAD8    ] = SMDSEntity_Quad_Quadrangle   ;
-      med2smeshTypes[ MED::eQUAD9    ] = SMDSEntity_BiQuad_Quadrangle ;
-      med2smeshTypes[ MED::eTETRA4   ] = SMDSEntity_Tetra             ;
-      med2smeshTypes[ MED::ePYRA5    ] = SMDSEntity_Pyramid           ;
-      med2smeshTypes[ MED::ePENTA6   ] = SMDSEntity_Penta             ;
-      med2smeshTypes[ MED::eHEXA8    ] = SMDSEntity_Hexa              ;
-      med2smeshTypes[ MED::eOCTA12   ] = SMDSEntity_Hexagonal_Prism   ;
-      med2smeshTypes[ MED::eTETRA10  ] = SMDSEntity_Quad_Tetra        ;
-      med2smeshTypes[ MED::ePYRA13   ] = SMDSEntity_Quad_Pyramid      ;
-      med2smeshTypes[ MED::ePENTA15  ] = SMDSEntity_Quad_Penta        ;
-      med2smeshTypes[ MED::eHEXA20   ] = SMDSEntity_Quad_Hexa         ;
-      med2smeshTypes[ MED::eHEXA27   ] = SMDSEntity_TriQuad_Hexa      ;
-      med2smeshTypes[ MED::ePOLYGONE ] = SMDSEntity_Polygon           ;
-      med2smeshTypes[ MED::ePOLYEDRE ] = SMDSEntity_Polyhedra         ;
-      med2smeshTypes[ MED::eNONE     ] = SMDSEntity_Node              ;
-      med2smeshTypes[ MED::eBALL     ] = SMDSEntity_Ball              ;
+      for  ( int iG = 0; iG < SMDSEntity_Last; ++iG )
+      {
+        SMDSAbs_EntityType    smdsType = (SMDSAbs_EntityType) iG;
+        MED::EGeometrieElement medType =
+          (MED::EGeometrieElement) DriverMED::GetMedGeoType( smdsType );
+        med2smeshTypes.insert( make_pair( medType, smdsType ));
+      }
     }
     return med2smeshTypes;
   }
 
   //================================================================================
   /*!
-   * \brief Return a vector<MED::EGeometrieElement> intended to retrieve
-   *        MED::EGeometrieElement by SMDSAbs_EntityType
-   */
-  //================================================================================
-
-  const vector<MED::EGeometrieElement>& mesh2medElemType()
-  {
-    static vector<MED::EGeometrieElement> mesh2medElemTypes;
-    if ( mesh2medElemTypes.empty() )
-    {
-      mesh2medElemTypes.resize( SMDSEntity_Last + 1 );
-      Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
-      Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
-      for ( ; me2sme != me2smeEnd; ++me2sme )
-        mesh2medElemTypes[ me2sme->second ] = me2sme->first;
-    }
-    return mesh2medElemTypes;
-  }
-
-  //================================================================================
-  /*!
    * \brief Writes meshInfo into a HDF file
    */
   //================================================================================
@@ -289,14 +252,14 @@ namespace
     // we use med identification of element (MED::EGeometrieElement) types
     // but not enum SMDSAbs_EntityType because values of SMDSAbs_EntityType may
     // change at insertion of new items in the middle.
-    const vector<MED::EGeometrieElement>& medTypes = mesh2medElemType();
+    //const vector<MED::EGeometrieElement>& medTypes = mesh2medElemType();
 
     vector<int> data;
 
     for ( size_t i = 0; i < meshInfo->length(); ++i )
       if ( meshInfo[i] > 0 )
       {
-        data.push_back( medTypes[ i ] );
+        data.push_back( DriverMED::GetMedGeoType( SMDSAbs_EntityType( i ))); //medTypes[ i ] );
         data.push_back( meshInfo[ i ] );
       }
 
index 98fb742..13d66a4 100644 (file)
@@ -224,6 +224,9 @@ namespace SMESH
     operator<<(const GEOM::ListOfGO& theList);
 
     TPythonDump&
+    operator<<(const GEOM::ListOfGBO& theList);
+
+    TPythonDump&
     operator<<(const SMESH::ListOfIDSources& theList);
 
     static const char* SMESHGenName() { return "smeshgen"; }
index 98b1921..7c4acfa 100644 (file)
@@ -1563,18 +1563,20 @@ class Mesh:
             if not geom:
                 geom = self.mesh.GetShapeToMesh()
             pass
-        hyp_name = hyp.GetName()
-        lib_name = hyp.GetLibName()
+        hyp_name = GetName( hyp )
         geom_name = ""
         if geom:
             geom_name = geom.GetName()
         isApplicable = True
-        isAlgo = hyp._narrow( SMESH_Algo )
         if self.mesh.HasShapeToMesh():
-            isApplicable = self.smeshpyD.IsApplicable(hyp_name, lib_name, geom, not geom.IsSame( self.mesh.GetShapeToMesh() ) )
+            hyp_type     = hyp.GetName()
+            lib_name     = hyp.GetLibName()
+            isSubMesh    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
+            isApplicable = self.smeshpyD.IsApplicable(hyp_name, lib_name, geom, isSubMesh)
         if isApplicable:
             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
             status = self.mesh.AddHypothesis(geom, hyp)
+            isAlgo = hyp._narrow( SMESH_Algo )
             TreatHypoStatus( status, hyp_name, geom_name, isAlgo )
             return status
         else:
@@ -1649,17 +1651,24 @@ class Mesh:
     #         - 1D if all mesh nodes lie on OX coordinate axis, or
     #         - 2D if all mesh nodes lie on XOY coordinate plane, or
     #         - 3D in the rest cases.
-    #
     #         If @a autoDimension is @c False, the space dimension is always 3.
+    #  @param fields : list of GEOM fields defined on the shape to mesh.
+    #  @param geomAssocFields : each character of this string means a need to export a 
+    #         corresponding field; correspondence between fields and characters is following:
+    #         - 'v' stands for _vertices_ field;
+    #         - 'e' stands for _edges_ field;
+    #         - 'f' stands for _faces_ field;
+    #         - 's' stands for _solids_ field.
     #  @ingroup l2_impexp
     def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
-                  overwrite=1, meshPart=None, autoDimension=True):
-        if meshPart:
+                  overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
+        if meshPart or fields or geomAssocFields:
             unRegister = genObjUnRegister()
             if isinstance( meshPart, list ):
                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
                 unRegister.set( meshPart )
-            self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite, autoDimension)
+            self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite, autoDimension,
+                                       fields, geomAssocFields)
         else:
             self.mesh.ExportToMEDX(f, auto_groups, version, overwrite, autoDimension)