From 97787812e26d555a6141ece38c9f13167410f425 Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 5 Mar 2014 17:42:42 +0400 Subject: [PATCH] ILMAB: export GEOM fields to MED file --- idl/SMESH_Mesh.idl | 34 +- src/DriverMED/CMakeLists.txt | 2 + src/DriverMED/DriverMED.hxx | 17 + src/DriverMED/DriverMED_W_Field.cxx | 404 +++++++++++++++++++++ src/DriverMED/DriverMED_W_Field.h | 80 ++++ src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx | 2 +- src/MEDWrapper/Base/MED_Common.hxx | 2 +- src/SMDS/SMDSAbs_ElementType.hxx | 3 +- src/SMDS/SMDS_Mesh.cxx | 5 + src/SMDS/SMDS_Mesh0DElement.cxx | 1 - src/SMESH/SMESH_Mesh.cxx | 13 + src/SMESHGUI/CMakeLists.txt | 2 + src/SMESHGUI/SMESHGUI.cxx | 28 +- src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx | 237 ++++++++++++ src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h | 61 ++++ src/SMESHGUI/SMESH_msg_en.ts | 7 + src/SMESH_I/SMESH_2smeshpy.cxx | 4 +- src/SMESH_I/SMESH_DumpPython.cxx | 5 + src/SMESH_I/SMESH_Mesh_i.cxx | 398 +++++++++++++++++++- src/SMESH_I/SMESH_Mesh_i.hxx | 13 +- src/SMESH_I/SMESH_PreMeshInfo.cxx | 59 +-- src/SMESH_I/SMESH_PythonDump.hxx | 3 + src/SMESH_SWIG/smeshBuilder.py | 25 +- 23 files changed, 1305 insertions(+), 100 deletions(-) create mode 100644 src/DriverMED/DriverMED_W_Field.cxx create mode 100644 src/DriverMED/DriverMED_W_Field.h create mode 100644 src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 2b72b3da8..059170dcb 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -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. + * - 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 ) raises (SALOME::SALOME_Exception); + 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 diff --git a/src/DriverMED/CMakeLists.txt b/src/DriverMED/CMakeLists.txt index 35f2fdd65..28d1b8a02 100644 --- a/src/DriverMED/CMakeLists.txt +++ b/src/DriverMED/CMakeLists.txt @@ -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 --- diff --git a/src/DriverMED/DriverMED.hxx b/src/DriverMED/DriverMED.hxx index ff1e3c173..857023efe 100644 --- a/src/DriverMED/DriverMED.hxx +++ b/src/DriverMED/DriverMED.hxx @@ -22,7 +22,24 @@ // Declarations needed for usage of DriverMED +#include "SMDSAbs_ElementType.hxx" + #include class DriverMED_Family; typedef boost::shared_ptr 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 index 000000000..721396f04 --- /dev/null +++ b/src/DriverMED/DriverMED_W_Field.cxx @@ -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 index 000000000..56b907d73 --- /dev/null +++ b/src/DriverMED/DriverMED_W_Field.h @@ -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 +#include + +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 diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 1006479cc..f46f225ec 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -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(); diff --git a/src/MEDWrapper/Base/MED_Common.hxx b/src/MEDWrapper/Base/MED_Common.hxx index be1e11c6c..0c1182385 100644 --- a/src/MEDWrapper/Base/MED_Common.hxx +++ b/src/MEDWrapper/Base/MED_Common.hxx @@ -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; diff --git a/src/SMDS/SMDSAbs_ElementType.hxx b/src/SMDS/SMDSAbs_ElementType.hxx index d81f67593..f80b41e9f 100644 --- a/src/SMDS/SMDSAbs_ElementType.hxx +++ b/src/SMDS/SMDSAbs_ElementType.hxx @@ -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, diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 936c775b9..63c658638 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -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 TIterator; + return SMDS_ElemIteratorPtr( new TIterator(myNodes)); + } // naturally always sorted by ID typedef ElemVecIterator < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator; diff --git a/src/SMDS/SMDS_Mesh0DElement.cxx b/src/SMDS/SMDS_Mesh0DElement.cxx index bf67bdfae..6f1c7f83f 100644 --- a/src/SMDS/SMDS_Mesh0DElement.cxx +++ b/src/SMDS/SMDS_Mesh0DElement.cxx @@ -38,7 +38,6 @@ using namespace std; //======================================================================= SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node) { - MESSAGE("SMDS_Mesh0DElement " << GetID()); myNode = node; } diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index ead79debf..692940c54 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -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 */ //================================================================================ diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index f30103188..39f744757 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -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 diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 2d1419586..aa09da82a 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -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 index 000000000..3185ea365 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx @@ -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 +#include + +#include +#include +#include +#include +#include +#include +#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 index 000000000..feaa83415 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h @@ -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 +#include CORBA_CLIENT_HEADER(SMESH_Mesh) +#include CORBA_CLIENT_HEADER(GEOM_Gen) + +#include + +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 diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index baf4a4ca7..ec5ab322c 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -4220,6 +4220,13 @@ It can't be deleted Sort child items + + SMESHGUI_FieldSelectorWdg + + FIELDS_TO_EXPORT + Export Fields + + SMESHGUI_Dialog diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index e12cd7f5a..f5595c08a 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -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 ); diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index 74ed8aa8b..494722b8a 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -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 ); diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c24ea9465..2689dc899 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -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; } - pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( " - << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << ", " - << autoDimension << " )"; + + // 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; + } + 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 } //================================================================================ diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 65de305a5..c6ad4ebed 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -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 */ diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx index 2315d2b7a..59a7e65c8 100644 --- a/src/SMESH_I/SMESH_PreMeshInfo.cxx +++ b/src/SMESH_I/SMESH_PreMeshInfo.cxx @@ -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 - #include #include #include @@ -228,54 +228,17 @@ 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 intended to retrieve - * MED::EGeometrieElement by SMDSAbs_EntityType - */ - //================================================================================ - - const vector& mesh2medElemType() - { - static vector 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& medTypes = mesh2medElemType(); + //const vector& medTypes = mesh2medElemType(); vector 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 ] ); } diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index 98fb742ac..13d66a497 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -223,6 +223,9 @@ namespace SMESH TPythonDump& operator<<(const GEOM::ListOfGO& theList); + TPythonDump& + operator<<(const GEOM::ListOfGBO& theList); + TPythonDump& operator<<(const SMESH::ListOfIDSources& theList); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 98b192177..7c4acfad4 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -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)