X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FDriverMED%2FDriverMED_W_SMESHDS_Mesh.cxx;h=b0d98d2c32c3263529502975c9c892518c4910fe;hp=63c69c992ee921e3a18351a076439b76abd0d968;hb=HEAD;hpb=a63fc78c25199b018fae4f5b182e6a348be0abf2 diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 63c69c992..fda036694 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -34,6 +34,8 @@ #include "SMDS_MeshNode.hxx" #include "SMDS_SetIterator.hxx" #include "SMESHDS_Mesh.hxx" +#include "MED_Common.hxx" +#include "MED_TFile.hxx" #include @@ -51,6 +53,12 @@ using namespace std; using namespace MED; +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): myAllSubMeshes (false), myDoGroupOfNodes (false), @@ -62,19 +70,32 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): myAutoDimension(false), myAddODOnVertices(false), myDoAllInGroups(false), - myVersion(-1) + myVersion(-1), + myZTolerance(-1.), + mySaveNumbers(true) {} +//================================================================================ +/*! + * \brief Set a file name and a version + * \param [in] theFileName - output file name + * \param [in] theVersion - desired MED file version == major * 10 + minor + */ +//================================================================================ + void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, int theVersion) { myVersion = theVersion; Driver_SMESHDS_Mesh::SetFile(theFileName); } +//================================================================================ /*! * MED version is either the latest available, or with an inferior minor, * to ensure backward compatibility on writing med files. */ +//================================================================================ + string DriverMED_W_SMESHDS_Mesh::GetVersionString(int theMinor, int theNbDigits) { TInt majeur, mineur, release; @@ -110,7 +131,7 @@ void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes() myAllSubMeshes = true; } -void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID) +void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int /*theID*/) { mySubMeshes.push_back( theSubMesh ); } @@ -145,24 +166,15 @@ void DriverMED_W_SMESHDS_Mesh::AddGroupOfBalls() myDoGroupOfBalls = true; } -//================================================================================ -/*! - * \brief Set up a flag to add all elements not belonging to any group to - * some auxiliary group. This is needed for SMESH -> SAUVE -> SMESH conversion, - * which since PAL0023285 reads only SAUVE elements belonging to any group, - * and hence can lose some elements. That auxiliary group is ignored while - * reading a MED file. - */ -//================================================================================ - -void DriverMED_W_SMESHDS_Mesh::AddAllToGroup() -{ - myDoAllInGroups = true; -} - namespace { + //--------------------------------------------- + /*! + * \brief Retrieving node coordinates utilities + */ + //--------------------------------------------- + typedef double (SMDS_MeshNode::* TGetCoord)() const; typedef const char* TName; typedef const char* TUnit; @@ -244,7 +256,7 @@ namespace const SMDS_MeshNode* GetNode(){ return myCurrentNode; } - MED::TIntVector::value_type GetID(){ + MED::TIDVector::value_type GetID(){ return myCurrentNode->GetID(); } MED::TFloatVector::value_type GetCoord(TInt theCoodId){ @@ -341,12 +353,60 @@ namespace } } +//================================================================================ +/*! + * \brief Write my mesh to a file + */ +//================================================================================ + Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() +{ + MED::PWrapper myMed = CrWrapperW(myFile, myVersion); + return this->PerformInternal(myMed); +} + +//================================================================================ +/*! + * \brief Write my mesh to a MEDCoupling DS + */ +//================================================================================ + +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh_Mem::Perform() +{ + void *ptr(nullptr); + std::size_t sz(0); + Driver_Mesh::Status status = Driver_Mesh::DRS_OK; + bool isClosed(false); + {// let braces to flush (call of MED::PWrapper myMed destructor) + TMemFile *tfileInst = new TMemFile(&ptr,&sz,&isClosed);// this new will be destroyed by destructor of myMed + MED::PWrapper myMed = CrWrapperW(myFile, -1, tfileInst); + status = this->PerformInternal(myMed); + } + if(!isClosed) + EXCEPTION(std::runtime_error, "TFTMemFile destructor : on destruction file has not been closed properly -> chunk of memory data may be invalid !"); + _data = MEDCoupling::DataArrayByte::New(); + _data->useArray(reinterpret_cast(ptr),true,MEDCoupling::DeallocType::C_DEALLOC,sz,1); + if(!isClosed) + THROW_SALOME_EXCEPTION("DriverMED_W_SMESHDS_Mesh_Mem::Perform - MED memory file id is supposed to be closed !"); + return status; +} + +//================================================================================ +/*! + * \brief Write my mesh + */ +//================================================================================ + +template +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::PerformInternal(LowLevelWriter myMed) { Status aResult = DRS_OK; try { //MESSAGE("Perform - myFile : "<( myMesh, /*checkIDs =*/ true )) + return DRS_TOO_LARGE_MESH; + // Creating the MED mesh for corresponding SMDS structure //------------------------------------------------------- string aMeshName; @@ -377,7 +437,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( myAutoDimension && aMeshDimension < 3 ) { SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); - double aBounds[6]; + double aBounds[6] = {0.,0.,0.,0.,0.,0.}; if(aNodesIter->more()){ const SMDS_MeshNode* aNode = aNodesIter->next(); aBounds[0] = aBounds[1] = aNode->X(); @@ -417,6 +477,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS; anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS; anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS; + if ( myZTolerance > 0 && anIsZDimension ) + anIsZDimension = (aBounds[5] > myZTolerance || aBounds[4] < -myZTolerance ); aSpaceDimension = Max( aMeshDimension, anIsXDimension + anIsYDimension + anIsZDimension ); if ( !aSpaceDimension ) aSpaceDimension = 3; @@ -458,7 +520,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() } } - MED::PWrapper myMed = CrWrapperW(myFile, myVersion); PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName); //MESSAGE("Add - aMeshName : "<GetName()); myMed->SetMeshInfo(aMeshInfo); @@ -471,12 +532,12 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() int myEdgesDefaultFamilyId = 0; int myFacesDefaultFamilyId = 0; int myVolumesDefaultFamilyId = 0; - int nbNodes = myMesh->NbNodes(); - int nb0DElements = myMesh->Nb0DElements(); - int nbBalls = myMesh->NbBalls(); - int nbEdges = myMesh->NbEdges(); - int nbFaces = myMesh->NbFaces(); - int nbVolumes = myMesh->NbVolumes(); + smIdType nbNodes = myMesh->NbNodes(); + smIdType nb0DElements = myMesh->Nb0DElements(); + smIdType nbBalls = myMesh->NbBalls(); + smIdType nbEdges = myMesh->NbEdges(); + smIdType nbFaces = myMesh->NbFaces(); + smIdType nbVolumes = myMesh->NbVolumes(); if (myDoGroupOfNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY; if (myDoGroupOfEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY; if (myDoGroupOfFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY; @@ -519,7 +580,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() list::iterator aFamsIter; for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++) { - PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); + PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); myMed->SetFamilyInfo(aFamilyInfo); } @@ -531,11 +592,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() #endif const EModeSwitch theMode = eFULL_INTERLACE; const ERepere theSystem = eCART; - const EBooleen theIsElemNum = eVRAI; + const EBooleen theIsElemNum = mySaveNumbers ? eVRAI : eFAUX; const EBooleen theIsElemNames = eFAUX; const EConnectivite theConnMode = eNOD; - TInt aNbNodes = myMesh->NbNodes(); + TInt aNbNodes = FromSmIdType( myMesh->NbNodes() ); PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes, theMode, theSystem, theIsElemNum, theIsElemNames); @@ -550,8 +611,12 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){ aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord); } + if ( aSpaceDimension == 3 && + -myZTolerance < aTCoordSlice[2] && aTCoordSlice[2] < myZTolerance ) + aTCoordSlice[2] = 0.; + // node number - int aNodeID = aCoordHelperPtr->GetID(); + TInt aNodeID = FromSmIdType( aCoordHelperPtr->GetID() ); aNodeInfo->SetElemNum( iNode, aNodeID ); #ifdef _EDF_NODE_IDS_ aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 )); @@ -617,66 +682,66 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, eBALL, - nbElemInfo.NbBalls(), + FromSmIdType(nbElemInfo.NbBalls()), SMDSAbs_Ball)); #ifdef _ELEMENTS_BY_DIM_ anEntity = eARETE; #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, eSEG2, - nbElemInfo.NbEdges( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbEdges( ORDER_LINEAR )), SMDSAbs_Edge)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eSEG3, - nbElemInfo.NbEdges( ORDER_QUADRATIC ), + FromSmIdType(nbElemInfo.NbEdges( ORDER_QUADRATIC )), SMDSAbs_Edge)); #ifdef _ELEMENTS_BY_DIM_ anEntity = eFACE; #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, eTRIA3, - nbElemInfo.NbTriangles( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbTriangles( ORDER_LINEAR )), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eTRIA6, - nbElemInfo.NbTriangles( ORDER_QUADRATIC ) - - nbElemInfo.NbBiQuadTriangles(), + FromSmIdType(nbElemInfo.NbTriangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadTriangles()), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eTRIA7, - nbElemInfo.NbBiQuadTriangles(), + FromSmIdType(nbElemInfo.NbBiQuadTriangles()), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eQUAD4, - nbElemInfo.NbQuadrangles( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbQuadrangles( ORDER_LINEAR )), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eQUAD8, - nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) - - nbElemInfo.NbBiQuadQuadrangles(), + FromSmIdType(nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadQuadrangles()), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eQUAD9, - nbElemInfo.NbBiQuadQuadrangles(), + FromSmIdType(nbElemInfo.NbBiQuadQuadrangles()), SMDSAbs_Face)); if ( polyTypesSupported ) { aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGONE, - nbElemInfo.NbPolygons( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbPolygons( ORDER_LINEAR )), SMDSAbs_Face)); // we need one more loop on poly elements to count nb of their nodes aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGONE, - nbElemInfo.NbPolygons( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbPolygons( ORDER_LINEAR )), SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGON2, - nbElemInfo.NbPolygons( ORDER_QUADRATIC ), + FromSmIdType(nbElemInfo.NbPolygons( ORDER_QUADRATIC )), SMDSAbs_Face)); // we need one more loop on QUAD poly elements to count nb of their nodes aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGON2, - nbElemInfo.NbPolygons( ORDER_QUADRATIC ), + FromSmIdType(nbElemInfo.NbPolygons( ORDER_QUADRATIC )), SMDSAbs_Face)); } #ifdef _ELEMENTS_BY_DIM_ @@ -684,58 +749,58 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, eTETRA4, - nbElemInfo.NbTetras( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbTetras( ORDER_LINEAR )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eTETRA10, - nbElemInfo.NbTetras( ORDER_QUADRATIC ), + FromSmIdType(nbElemInfo.NbTetras( ORDER_QUADRATIC )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePYRA5, - nbElemInfo.NbPyramids( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbPyramids( ORDER_LINEAR )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePYRA13, - nbElemInfo.NbPyramids( ORDER_QUADRATIC ), + FromSmIdType(nbElemInfo.NbPyramids( ORDER_QUADRATIC )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePENTA6, - nbElemInfo.NbPrisms( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbPrisms( ORDER_LINEAR )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePENTA15, - nbElemInfo.NbQuadPrisms(), + FromSmIdType(nbElemInfo.NbQuadPrisms()), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePENTA18, - nbElemInfo.NbBiQuadPrisms(), + FromSmIdType(nbElemInfo.NbBiQuadPrisms()), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA8, - nbElemInfo.NbHexas( ORDER_LINEAR ), + FromSmIdType(nbElemInfo.NbHexas( ORDER_LINEAR )), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA20, - nbElemInfo.NbHexas( ORDER_QUADRATIC )- - nbElemInfo.NbTriQuadHexas(), + FromSmIdType(nbElemInfo.NbHexas( ORDER_QUADRATIC )- + nbElemInfo.NbTriQuadHexas()), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA27, - nbElemInfo.NbTriQuadHexas(), + FromSmIdType(nbElemInfo.NbTriQuadHexas()), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eOCTA12, - nbElemInfo.NbHexPrisms(), + FromSmIdType(nbElemInfo.NbHexPrisms()), SMDSAbs_Volume)); if ( polyTypesSupported ) { aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYEDRE, - nbElemInfo.NbPolyhedrons(), + FromSmIdType(nbElemInfo.NbPolyhedrons()), SMDSAbs_Volume)); // we need one more loop on poly elements to count nb of their nodes aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYEDRE, - nbElemInfo.NbPolyhedrons(), + FromSmIdType(nbElemInfo.NbPolyhedrons()), SMDSAbs_Volume)); } @@ -769,7 +834,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // iterator on elements of a current type SMDS_ElemIteratorPtr elemIterator; - int iElem = 0; + TInt iElem = 0; // Treat POLYGONs // --------------- @@ -814,13 +879,13 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() for(TInt iNode = 0; iNode < aNbNodes; iNode++) { const SMDS_MeshElement* aNode = anElem->GetNode( iNode ); #ifdef _EDF_NODE_IDS_ - aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()]; + aTConnSlice[ iNode ] = aNodeIdMap[FromSmIdType(aNode->GetID())]; #else aTConnSlice[ iNode ] = aNode->GetID(); #endif } // element number - aPolygoneInfo->SetElemNum( iElem, anElem->GetID() ); + aPolygoneInfo->SetElemNum( iElem, FromSmIdType(anElem->GetID()) ); // family number int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); @@ -888,14 +953,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() while ( nodeIt->more() ) { const SMDS_MeshElement* aNode = nodeIt->next(); #ifdef _EDF_NODE_IDS_ - conn[ iNode ] = aNodeIdMap[aNode->GetID()]; + conn[ iNode ] = aNodeIdMap[FromSmIdType(aNode->GetID())]; #else conn[ iNode ] = aNode->GetID(); #endif ++iNode; } // element number - aPolyhInfo->SetElemNum( iElem, anElem->GetID() ); + aPolyhInfo->SetElemNum( iElem, FromSmIdType(anElem->GetID()) ); // family number int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); @@ -922,12 +987,12 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() // connectivity const SMDS_MeshElement* aNode = anElem->GetNode( 0 ); #ifdef _EDF_NODE_IDS_ - (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[aNode->GetID()]; + (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[FromSmIdType(aNode->GetID())]; #else (*aBallInfo->myConn)[ iElem ] = aNode->GetID(); #endif // element number - aBallInfo->SetElemNum( iElem, anElem->GetID() ); + aBallInfo->SetElemNum( iElem, FromSmIdType(anElem->GetID()) ); // diameter aBallInfo->myDiameters[ iElem ] = @@ -956,9 +1021,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() theIsElemNames); 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(); @@ -970,13 +1037,13 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() for (TInt iNode = 0; iNode < aNbNodes; iNode++) { const SMDS_MeshElement* aNode = anElem->GetNode( iNode ); #ifdef _EDF_NODE_IDS_ - aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()]; + aTConnSlice[ iNode ] = aNodeIdMap[FromSmIdType(aNode->GetID())]; #else aTConnSlice[ iNode ] = aNode->GetID(); #endif } // element number - aCellInfo->SetElemNum( iElem, anElem->GetID() ); + aCellInfo->SetElemNum( iElem, FromSmIdType(anElem->GetID()) ); // family number int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); @@ -985,6 +1052,15 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( ++iElem == aCellInfo->GetNbElem() ) break; } + // fix numbers of added SMDSAbs_0DElement + if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() ) + { + iElem = myMesh->Nb0DElements(); + TInt elem0DNum = FromSmIdType( myMesh->MaxElementID() + 1 ); + for ( size_t i = 0; i < nodesOf0D.size(); ++i ) + aCellInfo->SetElemNum( iElem++, elem0DNum++); + } + // store data in a file myMed->SetCellInfo(aCellInfo); }