diff --git a/src/DriverMED/DriverMED_W_Field.cxx b/src/DriverMED/DriverMED_W_Field.cxx index 721396f04..938927572 100644 --- a/src/DriverMED/DriverMED_W_Field.cxx +++ b/src/DriverMED/DriverMED_W_Field.cxx @@ -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 ) diff --git a/src/DriverMED/DriverMED_W_Field.h b/src/DriverMED/DriverMED_W_Field.h index 56b907d73..074912341 100644 --- a/src/DriverMED/DriverMED_W_Field.h +++ b/src/DriverMED/DriverMED_W_Field.h @@ -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; diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index f46f225ec..47fa68b5d 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -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 @@ -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 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::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 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& 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(); +} diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h index fc68df52d..d817c3f27 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.h @@ -35,6 +35,7 @@ #include #include #include +#include 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& 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 diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 692940c54..b3cf4dfda 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -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 { diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 6c25414e2..19818878e 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -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, diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 2689dc899..0b8337141 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -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 ); }