ILMAB: export GEOM fields to MED file

Re-implement addition of 0D elements w/o modification of SMESHDS_Mesh
This commit is contained in:
eap 2014-03-05 19:37:55 +04:00
parent 97787812e2
commit dc749f7053
7 changed files with 93 additions and 54 deletions

View File

@ -27,6 +27,7 @@
#include "DriverMED_W_Field.h"
#include "DriverMED.hxx"
#include "DriverMED_W_SMESHDS_Mesh.h"
#include "MED_Factory.hxx"
#include "MED_Utilities.hxx"
#include "MED_Wrapper.hxx"
@ -108,6 +109,20 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh * mesh,
_nbElemsByGeom.push_back( make_pair( geom, nbElems + _nbElemsByGeom.back().second ));
}
// add nodes of missing 0D elements on VERTEXes
if ( _addODOnVertices && _elemType == SMDSAbs_0DElement )
{
std::vector< const SMDS_MeshElement* >& nodes = _elemsByGeom[SMDSEntity_Node];
if ( nodes.empty() )
DriverMED_W_SMESHDS_Mesh::getNodesOfMissing0DOnVert( myMesh, nodes );
if ( !nodes.empty() )
{
if ( _nbElemsByGeom.size() == 1 )
_nbElemsByGeom.push_back( make_pair( SMDSEntity_0D, 0));
_nbElemsByGeom.push_back( make_pair( SMDSEntity_Node,
nodes.size() + _nbElemsByGeom.back().second ));
}
}
// sort elements by their geometry
int iGeoType, nbGeomTypes = _nbElemsByGeom.size() - 1;
@ -119,6 +134,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh * mesh,
nbElems = _nbElemsByGeom[iG].second - _nbElemsByGeom[iG-1].second;
_elemsByGeom[ iGeoType ].reserve( nbElems );
}
iGeoType = _nbElemsByGeom[1].first; // for missing 0D
if ( _elemsByGeom[ iGeoType ].empty() )
{
nbElems = mesh->GetMeshInfo().NbElements( _elemType );
@ -283,6 +299,14 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
}
medFile->SetFieldInfo( fieldInfo );
// specific treatment of added 0D elements
if ( _nbElemsByGeom.size() == 3 &&
_nbElemsByGeom[1].first == SMDSEntity_0D )
{
_nbElemsByGeom[1].second += _nbElemsByGeom[2].second;
_nbElemsByGeom.resize( 2 );
}
// create a time stamp
MED::TGeom2Size type2nb;
for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )

View File

@ -41,6 +41,8 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
DriverMED_W_Field();
void AddODOnVertices(bool toAdd) { _addODOnVertices = toAdd; }
bool Set(SMESHDS_Mesh * mesh,
const std::string & fieldName,
SMDSAbs_ElementType type,
@ -72,6 +74,7 @@ class MESHDRIVERMED_EXPORT DriverMED_W_Field: public Driver_SMESHDS_Mesh
std::vector< double > _dblValues;
std::vector< int > _intValues;
int _dt, _it;
bool _addODOnVertices;
std::vector< const SMDS_MeshElement* > _elemsByGeom[SMDSEntity_Last];
std::vector< std::pair< SMDSAbs_EntityType, int > > _nbElemsByGeom;

View File

@ -30,9 +30,11 @@
#include "DriverMED_Family.h"
#include "MED_Factory.hxx"
#include "MED_Utilities.hxx"
#include "SMDS_IteratorOnIterators.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_SetIterator.hxx"
#include "SMESHDS_Mesh.hxx"
#include <utilities.h>
@ -421,7 +423,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
if (myDoGroupOfBalls && nbBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY;
MESSAGE("Perform - aFamilyInfo");
//cout << " DriverMED_Family::MakeFamilies() " << endl;
list<DriverMED_FamilyPtr> aFamilies;
if (myAllSubMeshes) {
aFamilies = DriverMED_Family::MakeFamilies
@ -442,7 +443,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
myDoGroupOf0DElems && nb0DElements,
myDoGroupOfBalls && nbBalls);
}
//cout << " myMed->SetFamilyInfo() " << endl;
list<DriverMED_FamilyPtr>::iterator aFamsIter;
for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++)
{
@ -463,7 +463,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
const EConnectivite theConnMode = eNOD;
TInt aNbNodes = myMesh->NbNodes();
//cout << " myMed->CrNodeInfo() aNbNodes = " << aNbNodes << endl;
PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes,
theMode, theSystem, theIsElemNum, theIsElemNames);
@ -514,6 +513,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0);
TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
// nodes on VERTEXes where 0D elements are absent
std::vector<const SMDS_MeshElement*> nodesOf0D;
std::vector< SMDS_ElemIteratorPtr > iterVec;
SMDS_ElemIteratorPtr iterVecIter;
if ( myAddODOnVertices && getNodesOfMissing0DOnVert( myMesh, nodesOf0D ))
{
iterVec.resize(2);
iterVec[0] = myMesh->elementsIterator( SMDSAbs_0DElement );
iterVec[1] = SMDS_ElemIteratorPtr
( new SMDS_ElementVectorIterator( nodesOf0D.begin(), nodesOf0D.end() ));
typedef SMDS_IteratorOnIterators
< const SMDS_MeshElement *, std::vector< SMDS_ElemIteratorPtr > > TItIterator;
iterVecIter = SMDS_ElemIteratorPtr( new TItIterator( iterVec ));
}
// collect info on all geom types
list< TElemTypeData > aTElemTypeDatas;
@ -524,7 +539,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
#endif
aTElemTypeDatas.push_back(TElemTypeData(anEntity,
ePOINT1,
nbElemInfo.Nb0DElements(),
nbElemInfo.Nb0DElements() + nodesOf0D.size(),
SMDSAbs_0DElement));
#ifdef _ELEMENTS_BY_DIM_
anEntity = eSTRUCT_ELEMENT;
@ -873,6 +888,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType );
if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() )
elemIterator = iterVecIter;
while ( elemIterator->more() )
{
const SMDS_MeshElement* anElem = elemIterator->next();
@ -921,3 +938,31 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
mySubMeshes.clear();
return aResult;
}
//================================================================================
/*!
* \brief Returns nodes on VERTEXes where 0D elements are absent
*/
//================================================================================
bool DriverMED_W_SMESHDS_Mesh::
getNodesOfMissing0DOnVert(SMESHDS_Mesh* meshDS,
std::vector<const SMDS_MeshElement*>& nodes)
{
nodes.clear();
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 )
nodes.push_back( n );
}
}
}
return !nodes.empty();
}

View File

@ -35,6 +35,7 @@
#include <string>
#include <list>
#include <map>
#include <vector>
class SMESHDS_Mesh;
class SMESHDS_GroupBase;
@ -49,10 +50,9 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
virtual void SetFile(const std::string& theFileName);
void SetFile(const std::string& theFileName, MED::EVersion theId);
void SetAutoDimension(bool toFindOutDimension) { myAutoDimension = toFindOutDimension; }
static std::string GetVersionString(const MED::EVersion theVersion, int theNbDigits=2);
/*! sets file name; only for usage with Add(), not Write()
*/
void AddGroupOfNodes();
void AddGroupOfEdges();
void AddGroupOfFaces();
@ -65,6 +65,10 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
void AddGroup(SMESHDS_GroupBase * theGroup);
void AddAllSubMeshes();
void AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID);
void AddODOnVertices(bool toAdd) { myAddODOnVertices = toAdd; }
static bool getNodesOfMissing0DOnVert(SMESHDS_Mesh* mesh,
std::vector<const SMDS_MeshElement*>& nodes);
/*! add one mesh
*/
@ -83,6 +87,7 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
bool myDoGroupOf0DElems;
bool myDoGroupOfBalls;
bool myAutoDimension;
bool myAddODOnVertices;
};
#endif

View File

@ -1289,7 +1289,8 @@ void SMESH_Mesh::ExportMED(const char * file,
bool theAutoGroups,
int theVersion,
const SMESHDS_Mesh* meshPart,
bool theAutoDimension)
bool theAutoDimension,
bool theAddODOnVertices)
throw(SALOME_Exception)
{
SMESH_TRY;
@ -1298,6 +1299,7 @@ void SMESH_Mesh::ExportMED(const char * file,
myWriter.SetFile ( file, MED::EVersion(theVersion) );
myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
myWriter.SetAutoDimension( theAutoDimension );
myWriter.AddODOnVertices ( theAddODOnVertices );
if ( !theMeshName )
myWriter.SetMeshId ( _id );
else {

View File

@ -236,7 +236,8 @@ public:
bool theAutoGroups = true,
int theVersion = 0,
const SMESHDS_Mesh* theMeshPart = 0,
bool theAutoDimension = false)
bool theAutoDimension = false,
bool theAddODOnVertices = false)
throw(SALOME_Exception);
void ExportDAT(const char * file,

View File

@ -2848,25 +2848,6 @@ 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
@ -2921,29 +2902,6 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
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";
@ -2952,8 +2910,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
{
aMeshName = prepareMeshNameAndGroups(file, overwrite);
_impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
_impl->ExportMED( file, aMeshName.c_str(), auto_groups,
version, 0, autoDimension, have0dField);
meshDS = _impl->GetMeshDS();
}
else
@ -2972,8 +2930,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
}
}
SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
_impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, partDS, autoDimension );
_impl->ExportMED( file, aMeshName.c_str(), auto_groups,
version, partDS, autoDimension, have0dField);
meshDS = tmpDSDeleter._obj = partDS;
}
@ -2984,6 +2942,7 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
DriverMED_W_Field fieldWriter;
fieldWriter.SetFile( file );
fieldWriter.SetMeshName( aMeshName );
fieldWriter.AddODOnVertices( have0dField );
exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
}