SauvMedConvertor.cxx
SauvReader.cxx
SauvWriter.cxx
+ MEDMESHConverterUtilities.cxx
+ MeshFormatReader.cxx
+ MeshFormatWriter.cxx
+ libmesh5.cxx
)
ADD_LIBRARY(medloader ${medloader_SOURCES})
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 "MEDMESHConverterUtilities.hxx"
+
+#include "libmesh5.hxx"
+
+namespace MeshFormat
+{
+ bool isMeshExtensionCorrect( const std::string& fileName )
+ {
+ std::string ext;
+ {
+ auto pos(fileName.find_last_of('.'));
+ if(pos != std::string::npos)
+ ext = fileName.substr(pos);
+ }
+ switch ( ext.size() ) {
+ case 5:
+ return ( ext == ".mesh" || ext == ".solb" );
+ case 6:
+ return ( ext == ".meshb" );
+ case 4:
+ return ( ext == ".sol" );
+ }
+ return false;
+ }
+
+
+ Localizer::Localizer()
+ {
+ _locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
+ }
+
+ Localizer::~Localizer()
+ {
+ setlocale(LC_NUMERIC, _locale.c_str() );
+ }
+}
+
+
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 MEDMESHCONVERTERUTILITIES_HXX
+#define MEDMESHCONVERTERUTILITIES_HXX
+
+#include "MEDLoaderDefines.hxx"
+
+# include <string>
+# include <sstream>
+#include <iostream>
+# include <vector>
+#include <cstring>
+
+
+
+#define THROW_IK_EXCEPTION(text) \
+{ \
+ std::ostringstream oss; oss << text; \
+ throw INTERP_KERNEL::Exception(oss.str().c_str()); \
+}
+
+namespace MeshFormat
+{
+bool isMeshExtensionCorrect( const std::string& fileName );
+
+//~void closeMeshFile(const int gmfMeshID);
+
+enum Status {
+ DRS_OK,
+ DRS_EMPTY, // a file contains no mesh with the given name
+ DRS_WARN_RENUMBER, // a file has overlapped ranges of element numbers,
+ // so the numbers from the file are ignored
+ DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data
+ DRS_WARN_DESCENDING, // some elements were skipped due to descending connectivity
+ DRS_FAIL // general failure (exception etc.)
+};
+/*!
+ * \brief Class to generate string from any type
+ */
+class Comment : public std::string
+{
+ std::ostringstream _s ;
+
+public :
+
+ Comment():std::string("") {}
+
+ Comment(const Comment& c):std::string() {
+ _s << c.c_str() ;
+ this->std::string::operator=( _s.str() );
+ }
+
+ Comment & operator=(const Comment& c) {
+ _s << c.c_str() ;
+ this->std::string::operator=( _s.str() );
+ return *this;
+ }
+
+ template <class T>
+ Comment( const T &anything ) {
+ _s << anything ;
+ this->std::string::operator=( _s.str() );
+ }
+
+ template <class T>
+ Comment & operator<<( const T &anything ) {
+ _s << anything ;
+ this->std::string::operator=( _s.str() );
+ return *this ;
+ }
+
+ operator char*() const {
+ return (char*)c_str();
+ }
+
+ std::ostream& Stream() {
+ return _s;
+ }
+};
+/*!
+ * \brief Enforce freeing memory allocated by std::vector
+ */
+template <class TVECTOR>
+void FreeVector(TVECTOR& vec)
+{
+ TVECTOR v2;
+ vec.swap( v2 );
+}
+template <class TVECTOR>
+void CompactVector(TVECTOR& vec)
+{
+ TVECTOR v2( vec );
+ vec.swap( v2 );
+}
+
+class Localizer
+{
+ std::string _locale;
+public:
+ Localizer();
+ ~Localizer();
+};
+}
+
+
+#endif // MEDMESHCONVERTERUTILITIES_HXX
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 "MeshFormatReader.hxx"
+
+#include "MEDFileMesh.hxx"
+#include "MEDFileField.hxx"
+#include "MEDFileData.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "libmesh5.hxx"
+#include "MEDMESHConverterUtilities.hxx"
+#include <cstring>
+#include <fstream>
+
+namespace MEDCoupling {
+MeshFormatReader::MeshFormatReader():_myMeshName("MESH")
+{}
+MeshFormatReader::MeshFormatReader(const std::string& meshFileName,
+ const std::vector<std::string>& fieldFileName):_myFile(meshFileName),
+ _myFieldFileNames(fieldFileName),
+ _myCurrentFileId(0),
+ _myMeshName("MESH")
+{}
+
+MeshFormatReader::~MeshFormatReader()
+{}
+
+MEDCoupling::MCAuto<MEDCoupling::MEDFileData> MeshFormatReader::loadInMedFileDS()
+{
+ _myStatus = perform();
+ if(_myStatus != MeshFormat::DRS_OK) return 0;
+
+ if ( !_uMesh->getName().c_str() || strlen( _uMesh->getName().c_str() ) == 0 )
+ _uMesh->setName( _myMeshName );
+ if ( _myFieldFileNames.size() ) performFields();
+
+
+ MEDCoupling::MCAuto< MEDCoupling::MEDFileMeshes > meshes = MEDCoupling::MEDFileMeshes::New();
+ _myMed = MEDCoupling::MEDFileData::New();
+ meshes->pushMesh( _uMesh );
+ _myMed->setMeshes( meshes );
+
+ if ( _fields ) _myMed->setFields( _fields );
+
+ return _myMed.retn();
+}
+
+//================================================================================
+/*!
+ * \brief Read a GMF file
+ */
+//================================================================================
+
+MeshFormat::Status MeshFormatReader::perform()
+{
+ MeshFormat::Localizer loc;
+
+ MeshFormat::Status status = MeshFormat::DRS_OK;
+
+
+ // open the file
+ _reader = MeshFormat::MeshFormatParser();
+ _myCurrentOpenFile = _myFile;
+ _myCurrentFileId = _reader.GmfOpenMesh( _myFile.c_str(), GmfRead, &_version, &_dim );
+ if ( !_myCurrentFileId )
+ {
+ if ( MeshFormat::isMeshExtensionCorrect( _myFile ))
+ {
+
+ return addMessage( MeshFormat::Comment("Can't open for reading ") << _myFile,
+ /*fatal=*/true );
+ }
+ else
+ return addMessage( MeshFormat::Comment("Not '.mesh' or '.meshb' extension of file ") << _myFile,
+ /*fatal=*/true );
+ }
+
+
+ // Read nodes
+
+
+ MEDCoupling::DataArrayDouble* coordArray = MEDCoupling::DataArrayDouble::New();
+ setNodes(coordArray);
+
+
+ int nbEdges = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfEdges);
+ int nbTria = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfTriangles);
+ int nbQuad = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals);
+ int nbTet = _reader.GmfStatKwd( _myCurrentFileId, MeshFormat::GmfTetrahedra );
+ int nbPyr = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfPyramids);
+ int nbHex = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfHexahedra);
+ int nbPrism = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfPrisms);
+
+ _dim1NbEl = nbEdges;
+ _dim2NbEl = nbTria + nbQuad;
+ _dim3NbEl = nbTet + nbPyr + nbHex + nbPrism;
+ bool okdim1 = (nbEdges > 0), okdim2= (_dim2NbEl > 0), okdim3= (_dim3NbEl > 0);
+
+ MEDCoupling::MEDCouplingUMesh* dimMesh1;
+ MEDCoupling::MEDCouplingUMesh* dimMesh2;
+ MEDCoupling::MEDCouplingUMesh* dimMesh3;
+
+ // dim 1
+ if (okdim1 ) {
+ dimMesh1 = MEDCoupling::MEDCouplingUMesh::New();
+ dimMesh1->setCoords( coordArray );
+ dimMesh1->allocateCells( nbEdges);
+ dimMesh1->setMeshDimension( 1 );
+ }
+ // dim 2
+ if (okdim2) {
+ dimMesh2 = MEDCoupling::MEDCouplingUMesh::New();
+ dimMesh2->setCoords( coordArray );
+ dimMesh2->allocateCells(_dim2NbEl);
+ dimMesh2->setMeshDimension( 2 );
+ }
+ // dim 3
+ if (okdim3) {
+ dimMesh3 = MEDCoupling::MEDCouplingUMesh::New();
+ dimMesh3->setCoords( coordArray );
+ dimMesh3->allocateCells(_dim3NbEl);
+ dimMesh3->setMeshDimension( 3 );
+ }
+
+ // Read elements
+
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+
+ /* Read edges */
+
+ if ( nbEdges)
+ {
+ setEdges(dimMesh1, nbEdges);
+ dimMesh1->decrRef();
+ }
+
+ /* Read triangles */
+ if (nbTria)
+ {
+ setTriangles(dimMesh2, nbTria);
+ }
+
+ /* Read quadrangles */
+ if (nbQuad)
+ {
+ setQuadrangles( dimMesh2, nbQuad);
+ }
+
+ if (okdim2 ) {
+ dimMesh2->finishInsertingCells();
+ _uMesh->setMeshAtLevel( 2 - _dim, dimMesh2 );
+ dimMesh2->sortCellsInMEDFileFrmt();
+ dimMesh2->decrRef();
+ }
+ /* Read terahedra */
+ if ( nbTet )
+ {
+ setTetrahedras( dimMesh3, nbTet);
+ }
+
+ /* Read pyramids */
+ if ( nbPyr )
+ {
+ setPyramids( dimMesh3, nbPyr);
+ }
+
+ /* Read hexahedra */
+ if ( nbHex )
+ {
+ setHexahedras(dimMesh3, nbHex);
+ }
+
+ /* Read prism */
+ //~const int prismIDShift = myMesh->GetMeshInfo().NbElements();
+ if ( nbPrism )
+ {
+ setPrisms(dimMesh3, nbPrism);
+ }
+
+ if (okdim3 ) {
+ dimMesh3->finishInsertingCells();
+ _uMesh->setMeshAtLevel( 3 - _dim, dimMesh3 );
+ dimMesh3->decrRef();
+ }
+
+ buildFamilies();
+ coordArray->decrRef();
+ _reader.GmfCloseMesh(_myCurrentFileId);
+ _myCurrentFileId = -1;
+ _myCurrentOpenFile ="";
+ return status;
+}
+
+MeshFormat::Status MeshFormatReader::performFields()
+{
+
+ MeshFormat::Status status = MeshFormat::DRS_OK;
+ _fields = MEDCoupling::MEDFileFields::New();
+
+
+ const MeshFormat::GmfKwdCod meshFormatSol[1] = { MeshFormat::GmfSolAtVertices}; // ONLY VERTEX SOL FOR NOW
+
+ int dim, version;
+ std::vector<std::string>::const_iterator fieldFileIt = _myFieldFileNames.begin();
+
+ for (; fieldFileIt !=_myFieldFileNames.end(); ++fieldFileIt)
+ {
+ _myCurrentOpenFile = *fieldFileIt;
+ _myCurrentFileId = _reader.GmfOpenMesh( fieldFileIt->c_str(), GmfRead, &version, &dim );
+ if ( !_myCurrentFileId )
+ {
+ if ( MeshFormat::isMeshExtensionCorrect( *fieldFileIt ))
+ {
+
+ return addMessage( MeshFormat::Comment("Can't open for reading ") << *fieldFileIt,
+ /*fatal=*/true );
+ }
+ else
+ return addMessage( MeshFormat::Comment("Not '.sol' or '.solb' extension of file ") << _myFile,
+ /*fatal=*/true );
+ }
+
+ if (version != _version)
+ {
+
+ addMessage( MeshFormat::Comment("Warning sol file version is different than mesh file version ") << *fieldFileIt,
+ /*fatal=*/false );
+ }
+ if (dim != _dim)
+ {
+
+ return addMessage( MeshFormat::Comment("Error sol file must have same dimension as mesh file ") << *fieldFileIt,
+ /*fatal=*/true );
+ }
+
+
+ MeshFormat::GmfKwdCod kwd = meshFormatSol[0];
+ int NmbSol, NmbTypes, NmbReals, TypesTab[ GmfMaxTyp ];
+ NmbSol = _reader.GmfStatKwd( _myCurrentFileId, kwd, &NmbTypes, &NmbReals, TypesTab );
+ if(NmbSol)
+ {
+
+ for(int i=0; i<NmbTypes; i++)
+ {
+ _reader.GmfGotoKwd(_myCurrentFileId, kwd);
+ switch(TypesTab[i])
+ {
+ case GmfSca:
+ {
+
+ setFields(kwd, NmbSol, 1);
+ break;
+ }
+ case GmfVec:
+ {
+
+ setFields(kwd, NmbSol, dim);
+ break;
+ }
+ case GmfSymMat :
+ {
+
+ setFields(kwd, NmbSol, dim*(dim+1)/2 );
+ break;
+ }
+ case GmfMat:
+ {
+
+ setFields(kwd, NmbSol, dim*dim);
+ break;
+ }
+ }
+
+ }
+
+
+
+ }
+
+
+
+ _reader.GmfCloseMesh(_myCurrentFileId);
+ _myCurrentFileId = -1;
+ _myCurrentOpenFile ="";
+ }
+
+}
+
+void MeshFormatReader::setFields( MeshFormat::GmfKwdCod kwd, int nmbSol, int nbComp)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> fieldValues = MEDCoupling::DataArrayDouble::New();
+ fieldValues->alloc(nmbSol, nbComp);
+ double* values = fieldValues->getPointer();
+
+ int ref;
+ double *val = new double[nbComp];
+
+ bool isOnAll = (_uMesh->getNumberOfNodes()== nmbSol);
+
+
+ for(int i = 1; i<= nmbSol; i++)
+ {
+ callParserGetLin(kwd, val, nbComp, &ref);
+
+ std::copy(val, val+nbComp, values);
+
+ values+=nbComp;
+ }
+ values=fieldValues->getPointer(); // to delete
+
+ delete []val;
+
+ MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> timeStamp;
+ MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tsField = MEDCoupling::MEDFileFieldMultiTS::New();
+ MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> dimMesh ;
+ int dimRel;
+ MEDCoupling::TypeOfField typeOfField;
+ setTypeOfFieldAndDimRel(kwd, &typeOfField, &dimRel );
+
+ timeStamp = MEDCoupling::MEDCouplingFieldDouble::New(typeOfField);
+ dimMesh = _uMesh->getMeshAtLevel(dimRel);
+
+
+ timeStamp->setMesh( dimMesh );
+ std::string name = "Field_on_Vertex";
+ timeStamp->setName(name);
+ timeStamp->setArray(fieldValues);
+ // set an order
+ const int nbTS = tsField->getNumberOfTS();
+ if ( nbTS > 0 )
+ timeStamp->setOrder( nbTS );
+
+ // add the time-stamp
+ timeStamp->checkConsistencyLight();
+
+ if (isOnAll)
+ {
+ tsField->appendFieldNoProfileSBT( timeStamp );
+ }
+
+
+ _fields->pushField( tsField);
+
+}
+
+void MeshFormatReader::setMeshName(const std::string& theMeshName)
+{
+ _myMeshName = theMeshName;
+}
+
+std::string MeshFormatReader::getMeshName() const
+{
+ return _myMeshName;
+}
+
+
+void MeshFormatReader::setFile(const std::string& theFileName)
+{
+ _myFile = theFileName;
+}
+
+void MeshFormatReader::setFieldFileNames(const std::vector<std::string>& theFieldFileNames)
+{
+ _myFieldFileNames = theFieldFileNames;
+}
+std::vector<std::string> MeshFormatReader::getFieldFileNames() const
+{
+ return _myFieldFileNames;
+}
+
+MeshFormat::Status MeshFormatReader::addMessage(const std::string& msg,
+ const bool isFatal/*=false*/)
+{
+ if ( isFatal )
+ _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
+
+ _myErrorMessages.push_back( msg );
+
+ //~MESSAGE(msg);
+#ifdef _DEBUG_
+ std::cout << msg << std::endl;
+#endif
+ return ( _myStatus = isFatal ? MeshFormat::DRS_FAIL : MeshFormat::DRS_WARN_SKIP_ELEM );
+}
+
+void MeshFormatReader::backward_shift(mcIdType* tab, int size)
+{
+ for(int i = 0; i<size; i++) tab[i] = tab[i]-1;
+}
+
+
+MeshFormat::Status MeshFormatReader::setNodes( MEDCoupling::DataArrayDouble* coordArray)
+{
+
+ MeshFormat::Status status = MeshFormat::DRS_OK;
+ int nbNodes = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfVertices);
+ if ( nbNodes < 1 )
+ return addMessage( "No nodes in the mesh", /*fatal=*/true );
+
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfVertices);
+
+ int ref;
+ _uMesh = MEDCoupling::MEDFileUMesh::New();
+ coordArray->alloc( nbNodes, _dim );
+ double* coordPrt = coordArray->getPointer();
+ std::vector<double> nCoords (_dim+2, 0.0) ;
+
+ double* coordPointer = &nCoords[0];
+
+ if ( _version != GmfFloat )
+ {
+ double x, y, z;
+
+ for ( int i = 1; i <= nbNodes; ++i )
+ {
+ _dim == 2 ? _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfVertices, &x, &y, &ref) : \
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfVertices, &x, &y, &z, &ref);
+ nCoords[0] = x;
+ nCoords[1] = y;
+ nCoords[2] = z;
+ std::copy(coordPointer, coordPointer+_dim, coordPrt);
+ MeshFormatElement e(MeshFormat::GmfVertices, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 1);
+ coordPrt += _dim;
+
+ }
+
+ }
+ else
+ {
+ float x, y, z;
+
+ for ( int i = 1; i <= nbNodes; ++i )
+ {
+ _dim == 2 ? _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfVertices, &x, &y, &ref) :
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfVertices, &x, &y, &z, &ref);
+ nCoords[0] = x;
+ nCoords[1] = y;
+ nCoords[2] = z;
+ std::copy(coordPointer, coordPointer+_dim, coordPrt);
+ MeshFormatElement e(MeshFormat::GmfVertices, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 1);
+ coordPrt += _dim;
+ }
+ }
+ _uMesh->setCoords( coordArray );
+
+ return status;
+
+}
+
+
+void MeshFormatReader::setEdges( MEDCoupling::MEDCouplingUMesh* dimMesh1, int nbEdges)
+{
+
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ // read extra vertices for quadratic edges
+ std::vector<int> quadNodesAtEdges( nbEdges + 1, -1 );
+ if ( int nbQuadEdges = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges))
+ {
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges);
+ for ( int i = 1; i <= nbQuadEdges; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges, &iN[0], &iN[1], &iN[2]);
+ if ( iN[1] >= 1 )
+ quadNodesAtEdges[ iN[0] ] = iN[2];
+ }
+ }
+ // create edges
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfEdges);
+ for ( int i = 1; i <= nbEdges; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfEdges, &iN[0], &iN[1], &ref);
+ const int midN = quadNodesAtEdges[ i ];
+ if ( midN > 0 )
+ {
+
+ mcIdType nodalConnPerCell[3] = {iN[0], iN[1], midN};
+ backward_shift(nodalConnPerCell, 3);
+ dimMesh1->insertNextCell(INTERP_KERNEL::NORM_SEG3, 3,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfEdges, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 1 -_dim);
+ }
+ else
+ {
+
+ mcIdType nodalConnPerCell[2] = {iN[0], iN[1]};
+ backward_shift(nodalConnPerCell, 2);
+ dimMesh1->insertNextCell(INTERP_KERNEL::NORM_SEG2, 2,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfEdges, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 1 -_dim);
+ }
+ }
+
+ dimMesh1->finishInsertingCells();
+ dimMesh1->sortCellsInMEDFileFrmt();
+ _uMesh->setMeshAtLevel( 1 - _dim, dimMesh1 );
+}
+
+void MeshFormatReader::setTriangles(MEDCoupling::MEDCouplingUMesh* dimMesh2, int nbTria)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ // read extra vertices for quadratic triangles
+ std::vector< std::vector<int> > quadNodesAtTriangles( nbTria + 1 );
+ if ( int nbQuadTria = _reader.GmfStatKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles ))
+ {
+ _reader.GmfGotoKwd( _myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles );
+ for ( int i = 1; i <= nbQuadTria; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles,
+ &iN[0], &iN[1], &iN[2], &iN[3], &iN[4],
+ &iN[5]); // iN[5] - preview TRIA7
+ if ( iN[0] <= nbTria )
+ {
+ std::vector<int>& nodes = quadNodesAtTriangles[ iN[0] ];
+ nodes.insert( nodes.end(), & iN[2], & iN[5+1] );
+ nodes.resize( iN[1] );
+ }
+ }
+ }
+
+ // create triangles
+
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfTriangles);
+
+ for ( int i = 1; i <= nbTria; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfTriangles, &iN[0], &iN[1], &iN[2], &ref);
+ std::vector<int>& midN = quadNodesAtTriangles[ i ];
+ if ( midN.size() >= 3 )
+ {
+
+ mcIdType nodalConnPerCell[6] = {iN[0], iN[1], iN[2], midN[0], midN[1], midN[2]};
+ backward_shift(nodalConnPerCell, 6);
+ dimMesh2->insertNextCell(INTERP_KERNEL::NORM_TRI6, 6, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfTriangles, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 2 -_dim);
+ }
+ else
+ {
+ mcIdType nodalConnPerCell[3] = {iN[0], iN[1], iN[2]};
+ backward_shift(nodalConnPerCell, 3);
+ dimMesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfTriangles, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 2 -_dim);
+ }
+ if ( !midN.empty() ) MeshFormat::FreeVector( midN );
+ }
+
+
+}
+
+void MeshFormatReader::setQuadrangles( MEDCoupling::MEDCouplingUMesh* dimMesh2, int nbQuad)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ // read extra vertices for quadratic quadrangles
+ std::vector< std::vector<int> > quadNodesAtQuadrilaterals( nbQuad + 1 );
+ if ( int nbQuadQuad = _reader.GmfStatKwd( _myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals ))
+ {
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals);
+ for ( int i = 1; i <= nbQuadQuad; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals,
+ &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6]);
+ if ( iN[0] <= nbQuad )
+ {
+ std::vector<int>& nodes = quadNodesAtQuadrilaterals[ iN[0] ];
+ nodes.insert( nodes.end(), & iN[2], & iN[6+1] );
+ nodes.resize( iN[1] );
+ }
+ }
+ }
+ // create quadrangles
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals);
+ for ( int i = 1; i <= nbQuad; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
+ std::vector<int>& midN = quadNodesAtQuadrilaterals[ i ];
+ if ( midN.size() == 8-4 ) // QUAD8
+ {
+ mcIdType nodalConnPerCell[8] = {iN[0], iN[1], iN[2], iN[3],
+ midN[0], midN[1], midN[2], midN[3]
+ };
+ backward_shift(nodalConnPerCell, 8);
+ dimMesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfQuadrilaterals, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 2 -_dim);
+ }
+ else if ( midN.size() > 8-4 ) // QUAD9
+ {
+ mcIdType nodalConnPerCell[9] = {iN[0], iN[1], iN[2], iN[3],
+ midN[0], midN[1], midN[2], midN[3], midN[4]
+ };
+ backward_shift(nodalConnPerCell, 9);
+ dimMesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD9,9, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfQuadrilaterals, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 2 -_dim);
+ }
+ else // QUAD4
+ {
+ mcIdType nodalConnPerCell[4] = {iN[0], iN[1], iN[2], iN[3]};
+ backward_shift(nodalConnPerCell, 4);
+ dimMesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4, 4, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfQuadrilaterals, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 2 -_dim);
+ }
+ if ( !midN.empty() ) MeshFormat::FreeVector( midN );
+ }
+
+}
+
+void MeshFormatReader::setTetrahedras( MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbTet)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ // read extra vertices for quadratic tetrahedra
+ std::vector< std::vector<int> > quadNodesAtTetrahedra( nbTet + 1 );
+ if ( int nbQuadTetra = _reader.GmfStatKwd( _myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra ))
+ {
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra);
+ for ( int i = 1; i <= nbQuadTetra; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra,
+ &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7]);
+ if ( iN[0] <= nbTet )
+ {
+ std::vector<int>& nodes = quadNodesAtTetrahedra[ iN[0] ];
+ nodes.insert( nodes.end(), & iN[2], & iN[7+1] );
+ nodes.resize( iN[1] );
+ }
+ }
+ }
+ // create tetrahedra
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfTetrahedra);
+ for ( int i = 1; i <= nbTet; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
+ std::vector<int>& midN = quadNodesAtTetrahedra[ i ];
+ if ( midN.size() >= 10-4 ) // TETRA10
+ {
+ mcIdType nodalConnPerCell[10] = {iN[0], iN[2], iN[1], iN[3],
+ midN[2], midN[1], midN[0], midN[3], midN[5], midN[4]
+ };
+ backward_shift(nodalConnPerCell, 10);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_TETRA10, 10,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfTetrahedra, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+ }
+ else // TETRA4
+ {
+ mcIdType nodalConnPerCell[4] = {iN[0], iN[2], iN[1], iN[3]};
+ backward_shift(nodalConnPerCell, 4);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfTetrahedra, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+ }
+ if ( !midN.empty() ) MeshFormat::FreeVector( midN );
+ }
+
+}
+
+
+void MeshFormatReader::setPyramids( MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbPyr)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfPyramids);
+ for ( int i = 1; i <= nbPyr; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfPyramids, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &ref);
+ mcIdType nodalConnPerCell[5] = {iN[3], iN[2], iN[1], iN[0], iN[4]};
+ backward_shift(nodalConnPerCell, 5);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_PYRA5, 5,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfPyramids, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+ }
+
+}
+
+
+void MeshFormatReader::setHexahedras( MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbHex)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ // read extra vertices for quadratic hexahedra
+ std::vector< std::vector<int> > quadNodesAtHexahedra( nbHex + 1 );
+ if ( int nbQuadHexa = _reader.GmfStatKwd( _myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra ))
+ {
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra);
+ for ( int i = 1; i <= nbQuadHexa; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, &iN[0], &iN[1], // Hexa Id, Nb extra vertices
+ &iN[2], &iN[3], &iN[4], &iN[5],
+ &iN[6], &iN[7], &iN[8], &iN[9],
+ &iN[10], &iN[11], &iN[12], &iN[13], // HEXA20
+ &iN[14],
+ &iN[15], &iN[16], &iN[17], &iN[18],
+ &iN[19],
+ &iN[20]); // HEXA27
+ if ( iN[0] <= nbHex )
+ {
+ std::vector<int>& nodes = quadNodesAtHexahedra[ iN[0] ];
+ nodes.insert( nodes.end(), & iN[2], & iN[20+1] );
+ nodes.resize( iN[1] );
+ }
+ }
+ }
+ // create hexhedra
+
+
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfHexahedra);
+ for ( int i = 1; i <= nbHex; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfHexahedra, &iN[0], &iN[1], &iN[2], &iN[3],
+ &iN[4], &iN[5], &iN[6], &iN[7], &ref);
+ std::vector<int>& midN = quadNodesAtHexahedra[ i ];
+ if ( midN.size() == 20-8 ) // HEXA20
+ {
+ mcIdType nodalConnPerCell[20] = {iN[0], iN[3], iN[2], iN[1],
+ iN[4], iN[7], iN[6], iN[5],
+ midN[3], midN[2], midN[1], midN[0],
+ midN[7], midN[6], midN[5], midN[4],
+ midN[8], midN[11], midN[10], midN[9]
+ };
+ backward_shift(nodalConnPerCell, 20);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_HEXA20,20, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfHexahedra, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+
+
+ }
+ else if ( midN.size() >= 27-8 ) // HEXA27
+ {
+ mcIdType nodalConnPerCell[27] = {iN[0], iN[3], iN[2], iN[1],
+ iN[4], iN[7], iN[6], iN[5],
+ midN[3], midN[2], midN[1], midN[0],
+ midN[7], midN[6], midN[5], midN[4],
+ midN[8], midN[11], midN[10], midN[9],
+ midN[12],
+ midN[16], midN[15], midN[14], midN[13],
+ midN[17],
+ midN[18]
+ };
+ backward_shift(nodalConnPerCell, 27);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_HEXA27,27, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfHexahedra, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+
+ }
+ else // HEXA8
+ {
+ mcIdType nodalConnPerCell[8] = {iN[0], iN[3], iN[2], iN[1],
+ iN[4], iN[7], iN[6], iN[5]
+ };
+ backward_shift(nodalConnPerCell, 8);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8, nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfHexahedra, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+
+ }
+ if ( !midN.empty() ) MeshFormat::FreeVector( midN );
+ }
+
+
+}
+
+
+
+void MeshFormatReader::setPrisms(MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbPrism)
+{
+ int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
+ int ref;
+ _reader.GmfGotoKwd(_myCurrentFileId, MeshFormat::GmfPrisms);
+ for ( int i = 1; i <= nbPrism; ++i )
+ {
+ _reader.GmfGetLin(_myCurrentFileId, MeshFormat::GmfPrisms, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
+ mcIdType nodalConnPerCell[8] = {iN[0], iN[2], iN[1], iN[3], iN[5], iN[4]};
+ backward_shift(nodalConnPerCell, 8);
+ dimMesh3->insertNextCell(INTERP_KERNEL::NORM_PENTA6, 6,nodalConnPerCell);
+ MeshFormatElement e(MeshFormat::GmfPrisms, i-1);
+ _fams.insert(std::pair <int, MeshFormatElement> (ref, e), 3 -_dim);
+
+ }
+
+
+}
+
+void MeshFormatReader::callParserGetLin( MeshFormat::GmfKwdCod kwd, double* val, int valSize, int* ref)
+{
+ switch(valSize)
+ {
+ case 1:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], ref);
+ break;
+ }
+ case 2:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], &val[1], ref);
+ break;
+ }
+ case 3:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], &val[1], &val[2], ref);
+ break;
+ }
+ case 4:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], &val[1], &val[2], &val[3], ref);
+ break;
+ }
+ case 6:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], ref);
+ break;
+ }
+ case 9:
+ {
+ _reader.GmfGetLin(_myCurrentFileId, kwd, &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7], &val[8], ref);
+ break;
+ }
+ }
+}
+
+void MeshFormatReader::setTypeOfFieldAndDimRel(MeshFormat::GmfKwdCod kwd, MEDCoupling::TypeOfField* typeOfField, int* dimRel )
+{
+ switch (kwd)
+ {
+ case MeshFormat::GmfSolAtVertices :
+ {
+ *typeOfField = MEDCoupling::ON_NODES;
+ *dimRel = 1 ;
+ break;
+ }
+ case MeshFormat::GmfSolAtEdges :
+ {
+ *typeOfField = MEDCoupling::ON_CELLS;
+ *dimRel = 1 - _dim ;
+ break;
+ }
+ case MeshFormat::GmfSolAtTriangles :
+ case MeshFormat::GmfSolAtQuadrilaterals :
+ {
+ *typeOfField = MEDCoupling::ON_CELLS;
+ *dimRel = 2 - _dim;
+ break;
+ }
+ case MeshFormat::GmfSolAtTetrahedra :
+ case MeshFormat::GmfSolAtPrisms :
+ case MeshFormat::GmfSolAtHexahedra :
+ {
+ *typeOfField = MEDCoupling::ON_CELLS;
+ *dimRel = 3 - _dim;
+ break;
+ }
+ }
+}
+
+
+INTERP_KERNEL::NormalizedCellType MeshFormatReader::toMedType(MeshFormat::GmfKwdCod kwd)
+{
+ INTERP_KERNEL::NormalizedCellType type;
+ //~switch (kwd)
+ //~{
+ //~case MeshFormat::GmfEdges :
+ //~{
+
+ //~type = INTERP_KERNEL::NORM_SEG2;
+ //~break;
+ //~}
+ //~case MeshFormat::GmfTriangles :
+ //~{
+ //~type = INTERP_KERNEL::NORM_TRI3;
+ //~break;
+ //~}
+ //~case MeshFormat::GmfQuadrilaterals :
+ //~{
+ //~type = INTERP_KERNEL::NORM_QUAD;
+ //~break;
+ //~}
+ //~case MeshFormat::GmfSolAtTetrahedra :
+ //~case MeshFormat::GmfSolAtPrisms :
+ //~case MeshFormat::GmfSolAtHexahedra :
+ //~{
+ //~*typeOfField = MEDCoupling::ON_CELLS;
+ //~*dimRel = 3 - _dim;
+ //~break;
+ //~}
+ //~}
+ return type;
+}
+
+
+void MeshFormatReader::buildFamilies()
+{
+ buildNodesFamilies();
+ buildCellsFamilies();
+}
+
+void MeshFormatReader::buildCellsFamilies()
+{
+ std::vector<int> levs = _uMesh->getNonEmptyLevels();
+ for (size_t iDim = 0; iDim<levs.size(); iDim++ )
+ {
+ int dimRelMax = levs[iDim];
+ std::map <int, std::vector<MeshFormatElement>* > famDim = _fams.getMapAtLevel(dimRelMax);
+ std::map <int, std::vector<MeshFormatElement>* >::const_iterator _meshFormatFamsIt = famDim.begin();
+ std::vector< const MEDCoupling::DataArrayIdType* > fams;
+ MEDCoupling::DataArrayIdType* cellIds = MEDCoupling::DataArrayIdType::New();
+ cellIds->alloc(_uMesh->getSizeAtLevel(dimRelMax), 1);
+ cellIds->fillWithZero();
+
+ for(; _meshFormatFamsIt!= famDim.end(); ++_meshFormatFamsIt)
+ {
+ const int famId = _meshFormatFamsIt->first;
+ std::string famName ="FromMeshGemsFormatAttributFamily_"+std::to_string(famId);
+ std::vector <MeshFormatElement>* cellsInFam = _meshFormatFamsIt->second;
+ if (!famId) continue;
+ std::vector <MeshFormatElement>::iterator cellsInFamIt = cellsInFam->begin();
+
+ _uMesh->addFamily(famName, famId);
+ for ( ; cellsInFamIt !=cellsInFam->end(); ++cellsInFamIt)
+ {
+ cellIds->setIJ(cellsInFamIt->_id, 0, famId);
+ }
+
+ }
+ _uMesh->setFamilyFieldArr(dimRelMax, cellIds->deepCopy());
+ cellIds->decrRef();
+
+
+ }
+}
+
+void MeshFormatReader::buildNodesFamilies()
+{
+ std::vector<int> levs = _uMesh->getNonEmptyLevels();
+ int dimRelMax = 1;
+ std::map <int, std::vector<MeshFormatElement>* > famDim = _fams.getMapAtLevel(dimRelMax);
+ std::map <int, std::vector<MeshFormatElement>* >::const_iterator _meshFormatFamsIt = famDim.begin();
+ std::vector< const MEDCoupling::DataArrayIdType* > fams;
+ MEDCoupling::DataArrayIdType* cellIds = MEDCoupling::DataArrayIdType::New();
+ cellIds->alloc(_uMesh->getSizeAtLevel(dimRelMax), 1);
+ cellIds->fillWithZero();
+
+ for(; _meshFormatFamsIt!= famDim.end(); ++_meshFormatFamsIt)
+ {
+ const int famId = _meshFormatFamsIt->first;
+ if (!famId) continue;
+ bool thisIsACellFamily = false;
+
+ for (size_t iDim = 0; iDim<levs.size(); iDim++ )
+ {
+ int dimMesh = levs[iDim];
+ std::map <int, std::vector<MeshFormatElement>* > famDimAtLevel = _fams.getMapAtLevel(dimMesh);
+ std::map <int, std::vector<MeshFormatElement>* >::iterator famDimAtLevelId = famDimAtLevel.find(famId);
+ if (famDimAtLevelId != famDimAtLevel.end())
+ {
+ thisIsACellFamily = true;
+ break;
+ }
+
+ }
+
+ if (thisIsACellFamily) continue;
+ std::string famName ="FromMeshGemsFormatAttributFamily_"+std::to_string(famId);
+ std::vector <MeshFormatElement>* cellsInFam = _meshFormatFamsIt->second;
+ std::vector <MeshFormatElement>::iterator cellsInFamIt = cellsInFam->begin();
+
+ _uMesh->addFamily(famName, famId);
+ for ( ; cellsInFamIt !=cellsInFam->end(); ++cellsInFamIt)
+ {
+ cellIds->setIJ(cellsInFamIt->_id, 0, famId);
+ }
+
+ }
+ _uMesh->setFamilyFieldArr(dimRelMax, cellIds->deepCopy());
+ cellIds->decrRef();
+}
+}
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 MESHFORMATREADER_HXX
+#define MESHFORMATREADER_HXX
+
+#include <vector>
+#include <string>
+#include <map>
+#include <algorithm>
+#include <utility>
+#include <iterator>
+#include "MCAuto.hxx"
+#include "InterpKernelException.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
+#include "MCType.hxx"
+#include "MEDMESHConverterUtilities.hxx"
+#include "libmesh5.hxx"
+
+#include <fstream>
+#include <features.h>
+namespace MEDCoupling
+{
+class DataArrayDouble;
+class DataArrayInt;
+class MEDFileData;
+class MEDFileFields;
+class MEDFileFieldMultiTS;
+class MEDFileUMesh;
+class MEDCouplingUMesh;
+
+
+struct MeshFormatElement {
+ MeshFormatElement(int type, int id=0):_type(type), _id(id) {}
+ int _type;
+ int _id;
+
+ inline friend bool operator==(const MeshFormatElement& a, const MeshFormatElement&b ) {
+ return ((a._type == b._type) && (a._id == b._id));
+ }
+};
+
+struct MeshFormatFamily {
+
+ std::map <int, std::vector<MeshFormatElement>* > _meshFormatFams;
+ std::map <int, std::vector<MeshFormatElement>* > _meshFormatFams_0;
+ std::map <int, std::vector<MeshFormatElement>* > _meshFormatFams_1;
+ std::map <int, std::vector<MeshFormatElement>* > _meshFormatFams_2;
+ std::map <int, std::vector<MeshFormatElement>* > _meshFormatFamsNodes;
+
+public:
+ void insert(std::pair<int, MeshFormatElement> addToFamily, int dimRelMax)
+ {
+ insertPairInMap(_meshFormatFams, addToFamily);
+ insertPairInMap(getMapAtLevel(dimRelMax), addToFamily);
+ }
+private:
+ void insertPairInMap(std::map <int, std::vector<MeshFormatElement>* >& aMap, std::pair<int, MeshFormatElement> addToFamily)
+ {
+ std::map <int, std::vector<MeshFormatElement>* >::iterator it = aMap.find(addToFamily.first);
+ if (it!= aMap.end())
+ {
+ aMap[addToFamily.first]->push_back(addToFamily.second);
+ }
+ else
+ {
+ std::vector <MeshFormatElement>* tmpVec = new std::vector <MeshFormatElement> ;
+ tmpVec->push_back(addToFamily.second);
+ aMap.insert(std::pair <int, std::vector <MeshFormatElement>* > (addToFamily.first, tmpVec) );
+
+ }
+
+ }
+public:
+ void remove(std::pair<int, MeshFormatElement> removeFromFamily, int dimRelMax)
+ {
+ removePairFromMap(_meshFormatFams, removeFromFamily);
+ removePairFromMap(getMapAtLevel(dimRelMax), removeFromFamily);
+
+ }
+private:
+ void removePairFromMap(std::map <int, std::vector<MeshFormatElement>* > & aMap, const std::pair<int, MeshFormatElement> removeFromFamily)
+ {
+
+ if (!aMap.size() ) return;
+ std::map <int, std::vector<MeshFormatElement>* >::iterator itTmp = aMap.find(removeFromFamily.first);
+ if (itTmp == aMap.end()) return;
+ else
+ {
+ std::vector <MeshFormatElement>* tmpVec2 = aMap[removeFromFamily.first];
+#if __GNUC_PREREQ(4,9)
+ std::vector <MeshFormatElement>::const_iterator itt2;
+#else
+ std::vector <MeshFormatElement>::iterator itt2;
+#endif
+ const MeshFormatElement e = removeFromFamily.second;
+ itt2 = std::find(tmpVec2->begin(), tmpVec2->end(), e);
+ if (itt2 != tmpVec2->end())
+ tmpVec2->erase(itt2);
+
+ if (!tmpVec2->size())
+ {
+ delete tmpVec2;
+ aMap.erase(removeFromFamily.first);
+ }
+ }
+ }
+public:
+ std::map <int, std::vector<MeshFormatElement>* > & getMapAtLevel(int dimRelMax)
+ {
+ switch(dimRelMax)
+ {
+ case 0 :
+ return _meshFormatFams_0;
+ break;
+ case -1 :
+ return _meshFormatFams_1;
+ break;
+ case -2 :
+ return _meshFormatFams_2;
+ break;
+ case 1 :
+ return _meshFormatFamsNodes;
+ break;
+ }
+ }
+public:
+ ~MeshFormatFamily()
+ {
+
+ freeMap(_meshFormatFams);
+ freeMap(_meshFormatFams_0);
+ freeMap(_meshFormatFams_1);
+ freeMap(_meshFormatFams_2);
+ freeMap(_meshFormatFamsNodes);
+
+ }
+
+private:
+ void freeMap(std::map <int, std::vector<MeshFormatElement>* > & aMap)
+ {
+ std::map <int, std::vector<MeshFormatElement>* >::iterator it = aMap.begin();
+ for (; it !=aMap.end(); ++it) delete it->second;
+ }
+
+};
+class MeshFormatReader
+{
+public :
+ MEDLOADER_EXPORT MeshFormatReader();
+ MEDLOADER_EXPORT MeshFormatReader(const std::string& meshFileName, const std::vector<std::string>& fieldFileName);
+ MEDLOADER_EXPORT ~MeshFormatReader();
+
+ MEDLOADER_EXPORT MEDCoupling::MCAuto<MEDCoupling::MEDFileData> loadInMedFileDS() ;
+ MEDLOADER_EXPORT void setMeshName(const std::string& theMeshName);
+ MEDLOADER_EXPORT std::string getMeshName() const;
+ MEDLOADER_EXPORT void setFile(const std::string& theFileName);
+ MEDLOADER_EXPORT void setFieldFileNames(const std::vector<std::string>& theFieldFileNames);
+ MEDLOADER_EXPORT std::vector<std::string> getFieldFileNames() const;
+ MEDLOADER_EXPORT std::vector< std::string > getErroMessage() const;
+
+private :
+
+ MeshFormat::Status addMessage(const std::string& msg, const bool isFatal=false);
+ MeshFormat::Status perform();
+ MeshFormat::Status performFields();
+ MeshFormat::Status setNodes(MEDCoupling::DataArrayDouble* coordArray);
+ void setEdges(MEDCoupling::MEDCouplingUMesh* dimMesh1, int nbEdges);
+ void setTriangles( MEDCoupling::MEDCouplingUMesh* dimMesh2, int nbTria);
+ void setQuadrangles( MEDCoupling::MEDCouplingUMesh* dimMesh2, int nbQuad);
+ void setTetrahedras( MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbTet);
+ void setPyramids(MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbPyr);
+ void setHexahedras(MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbHex);
+ void setPrisms(MEDCoupling::MEDCouplingUMesh* dimMesh3, int nbPrism);
+ void callParserGetLin( MeshFormat::GmfKwdCod kwd, double* val, int valSize, int* ref);
+ void setTypeOfFieldAndDimRel(MeshFormat::GmfKwdCod kwd, MEDCoupling::TypeOfField* typeOfField, int* dimRel );
+ void backward_shift(MEDCoupling::mcIdType*, int size);
+ void setFields( MeshFormat::GmfKwdCod kwd, int nmbSol, int nbComp);
+ INTERP_KERNEL::NormalizedCellType toMedType(MeshFormat::GmfKwdCod kwd);
+ void buildFamilies();
+ void buildNodesFamilies();
+ void buildCellsFamilies();
+
+ std::string _myFile;
+ MeshFormat::MeshFormatParser _reader;
+ std::string _myCurrentOpenFile;
+ int _myCurrentFileId;
+ std::string _myMeshName;
+ std::vector<std::string> _myFieldFileNames;
+ int _dim, _version;
+ std::vector< std::string > _myErrorMessages;
+ MeshFormat::Status _myStatus;
+ MEDCoupling::MCAuto<MEDCoupling::MEDFileData> _myMed;
+ MEDCoupling::MCAuto<MEDCoupling::MEDFileUMesh> _uMesh;
+ MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> _fields;
+ // map id family --element
+ MeshFormatFamily _fams;
+
+ int _dim1NbEl;
+ int _dim2NbEl;
+ int _dim3NbEl;
+};
+}
+#endif //MESHFORMATREADER_HXX
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 "MeshFormatWriter.hxx"
+#include "MEDFileMesh.hxx"
+#include "MEDFileField.hxx"
+#include "MEDFileData.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "libmesh5.hxx"
+#include "MEDMESHConverterUtilities.hxx"
+#include <cstring>
+#include <algorithm>
+#include <map>
+#include <cstdlib>
+#include <fstream>
+
+
+namespace MEDCoupling {
+
+MeshFormatWriter::MeshFormatWriter()
+{}
+MeshFormatWriter::MeshFormatWriter(const std::string& meshFileName,
+ const std::vector<std::string>& fieldFileNames):_meshFileName(meshFileName),
+ _fieldFileNames(fieldFileNames)
+{}
+MeshFormatWriter::~MeshFormatWriter()
+{}
+void MeshFormatWriter::setMeshFileName(const std::string& meshFileName)
+{
+ _meshFileName = meshFileName;
+}
+void MeshFormatWriter::setFieldFileNames(const std::vector<std::string>& fieldFileNames)
+{
+ _fieldFileNames = fieldFileNames;
+}
+void MeshFormatWriter::setMEDFileDS(MEDCoupling::MEDFileData* mfd)
+{
+
+ if(!mfd)
+ {
+ addMessage( MeshFormat::Comment(" MEDFileData is nullptr! ") << _meshFileName, /*fatal=*/true );
+ return;
+ }
+ if ( !mfd->getNumberOfMeshes())
+ {
+ addMessage( MeshFormat::Comment("No Mesh in MEDFileData! ") << _meshFileName, /*fatal=*/true );
+ return;
+ }
+ if ( mfd->getNumberOfMeshes() > 1)
+ {
+ addMessage( MeshFormat::Comment("More than One Mesh in File! ") << _meshFileName, /*fatal=*/true );
+ return;
+ }
+
+ MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
+ _mesh = meshes->getMeshAtPos(0);
+
+ _mesh->incrRef();
+ MEDCoupling::MEDFileFields* fields = mfd->getFields();
+
+ for (int i = 0; i<fields->getNumberOfFields(); i++ )
+ {
+ MEDCoupling::MEDFileAnyTypeFieldMultiTS* field = fields->getFieldAtPos(i);
+ MEDCoupling::MEDFileFieldMultiTS * f = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(field);
+ _fields.push_back(f);
+ }
+
+
+}
+
+void MeshFormatWriter::write()
+{
+
+ MeshFormat::Localizer loc;
+
+ MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh > mesh = _mesh->getMeshAtLevel( 1 );
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh = mesh->buildUnstructured();
+ _dim = umesh->getSpaceDimension();
+
+ if (_dim != 2 && _dim != 3)
+ {
+ addMessage( MeshFormat::Comment("Only 3D or 2D mesh allowed! ") << _meshFileName, /*fatal=*/true );
+ return ;
+ }
+
+
+ _version = sizeof(double) < 8 ? 1 : 2;
+ _writer = MeshFormat::MeshFormatParser();
+ _myCurrentOpenFile = _meshFileName;
+ _myCurrentFileId = _writer.GmfOpenMesh( _meshFileName.c_str(), GmfWrite, _version, _dim );
+ if ( !_myCurrentFileId )
+ {
+ if ( MeshFormat::isMeshExtensionCorrect( _meshFileName ))
+ {
+ addMessage( MeshFormat::Comment("Can't open for writing ") << _meshFileName, /*fatal=*/true );
+ return;
+ }
+
+ else
+ {
+ addMessage( MeshFormat::Comment("Not '.mesh' or '.meshb' extension of file ") << _meshFileName, /*fatal=*/true );
+ return;
+ }
+
+ }
+
+
+ perform();
+ _writer.GmfCloseMesh(_myCurrentFileId);
+ _myCurrentFileId = -1;
+ _myCurrentOpenFile = "";
+ if (_fields.size()) performFields();
+
+
+}
+
+MeshFormat::Status MeshFormatWriter::perform()
+{
+
+
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh1;
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1;
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh2;
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2;
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh3;
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3;
+
+ std::vector<int> dims = _mesh->getNonEmptyLevelsExt();
+ int dim = _mesh->getMeshDimension();
+ bool threeDElements = false;
+ bool twoDElements = false;
+ bool OneDElements = false;
+ if (dims.size() != 0)
+ {
+ bool maxLevelDimElments = ( std::find(dims.begin(), dims.end(), 0) != dims.end() );
+ bool nextToMaxLevelDimElments = ( std::find(dims.begin(), dims.end(), -1) != dims.end() );
+ bool nextToNextToMaxLevelDimElments = (std::find(dims.begin(), dims.end(), -2) != dims.end() );
+ threeDElements = (dim == 3) ? maxLevelDimElments : false ;
+ twoDElements = (dim == 3) ? nextToMaxLevelDimElments : maxLevelDimElments ;
+ OneDElements = (dim == 3) ? nextToNextToMaxLevelDimElments : nextToMaxLevelDimElments;
+ }
+
+ MEDCoupling::mcIdType nbEdgesNSEG2 = 0;
+ MEDCoupling::mcIdType nbEdgesNSEG3 = 0;
+ MEDCoupling::mcIdType nbTRI3 = 0;
+ MEDCoupling::mcIdType nbTRI6 = 0;
+ MEDCoupling::mcIdType nbQUAD4 = 0;
+ MEDCoupling::mcIdType nbQUAD8 = 0;
+ MEDCoupling::mcIdType nbQUAD9 = 0;
+ MEDCoupling::mcIdType nbTETRA4 = 0;
+ MEDCoupling::mcIdType nbTETRA10 = 0;
+ MEDCoupling::mcIdType nbPYRA5 = 0;
+ MEDCoupling::mcIdType nbHEXA8 = 0;
+ MEDCoupling::mcIdType nbHEXA20 = 0;
+ MEDCoupling::mcIdType nbHEXA27 = 0;
+ MEDCoupling::mcIdType nbPENTA6 = 0;
+
+ if (OneDElements)
+ {
+ mesh1 = _mesh->getMeshAtLevel( 1-dim );
+ umesh1 = mesh1->buildUnstructured();
+ nbEdgesNSEG2 = umesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_SEG2);
+
+ nbEdgesNSEG3 = umesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_SEG3);
+
+ }
+ if (twoDElements)
+ {
+ mesh2 = _mesh->getMeshAtLevel( 2-dim );
+ umesh2 = mesh2->buildUnstructured();
+ nbTRI3 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3);
+
+ nbTRI6 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI6);
+
+ nbQUAD4 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+
+ nbQUAD8 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD8);
+
+ nbQUAD9 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD9);
+
+ }
+ if (threeDElements)
+ {
+
+ mesh3 = _mesh->getMeshAtLevel( 3-dim );
+ umesh3 = mesh3->buildUnstructured();
+ nbTETRA4 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TETRA4);
+
+ nbTETRA10 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TETRA10);
+
+ nbPYRA5 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_PYRA5);
+
+ nbHEXA8 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+
+ nbHEXA20 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA20);
+
+ nbHEXA27 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA27);
+
+ nbPENTA6 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_PENTA6);
+
+ }
+
+
+
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh0 = _mesh->getMeshAtLevel(1);
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0 = mesh0->buildUnstructured();
+
+ // nodes
+ getNodes(umesh0);
+
+ // edges SEG2
+ if ( nbEdgesNSEG2 > 0)
+ {
+ getNSEG2( nbEdgesNSEG2, umesh1);
+ }
+ //~// nodes of quadratic edges SEG3
+ if ( nbEdgesNSEG3 > 0)
+ {
+ getNSEG3( nbEdgesNSEG3, umesh1);
+ }
+
+ // triangles TRI3
+ if ( nbTRI3 > 0)
+ {
+ getTRI3( nbTRI3, umesh2);
+ }
+
+ // nodes of quadratic triangles
+ // triangles TRI6
+ if ( nbTRI6 > 0)
+ {
+ getTRI6( nbTRI6, umesh2);
+
+ }
+ //~// quadrangles QUAD4
+ if ( nbQUAD4 > 0)
+ {
+ getQUAD4(nbQUAD4, umesh2);
+ }
+
+ //~// quadrangles quadratic QUAD8
+ if ( nbQUAD8 > 0)
+ {
+ getQUAD8( nbQUAD8, umesh2);
+ }
+
+ //~// quadrangles quadratic QUAD9
+ if ( nbQUAD9 > 0)
+ {
+ getQUAD9( nbQUAD9, umesh2);
+ }
+
+ // terahedra TETRA4
+ if ( nbTETRA4 > 0)
+ {
+ getTETRA4( nbTETRA4, umesh3);
+ }
+ //~terahedra TETRA10
+ if ( nbTETRA10 > 0)
+ {
+ getTETRA10( nbTETRA10, umesh3);
+ }
+
+ //~// pyramids 5
+ if ( nbPYRA5 > 0)
+ {
+ getPYRA5(nbPYRA5, umesh3);
+ }
+ //~// hexahedra 8
+ if ( nbHEXA8 > 0)
+ {
+ getHEXA8( nbHEXA8, umesh3);
+ }
+
+ //~// hexahedra 20
+ if ( nbHEXA20 > 0)
+ {
+ getHEXA20( nbHEXA20, umesh3);
+ }
+
+ //~// hexahedra 27
+ if ( nbHEXA27 > 0)
+ {
+ getHEXA27 (nbHEXA27, umesh3);
+ }
+
+ // prism
+ if ( nbPENTA6 > 0)
+ {
+ getPENTA6(nbPENTA6, umesh3);
+ }
+
+ linkFamilyToCells();
+ writeCells();
+
+
+ return MeshFormat::DRS_OK;
+}
+
+
+MeshFormat::Status MeshFormatWriter::performFields()
+{
+
+ MeshFormat::Status status = MeshFormat::Status::DRS_OK;
+
+ if (_fields.size() != _fieldFileNames.size() )
+ {
+ addMessage( MeshFormat::Comment(" Number of fields and number of input *.sol files must be equal ") << _meshFileName, /*fatal=*/true );
+ status = MeshFormat::Status::DRS_FAIL;
+ return status;
+ }
+
+
+ int dim = _mesh->getMeshDimension(); // dim mesh field lying to
+ std::vector<std::string>::const_iterator fieldFileIt = _fieldFileNames.begin();
+ int iField = 0;
+ std::vector<int> levs {0} ;
+ for (; fieldFileIt !=_fieldFileNames.end(); ++fieldFileIt)
+ {
+ // Open files
+ _myCurrentOpenFile = *fieldFileIt;
+
+ MEDCoupling::MEDFileFieldMultiTS* f = _fields[iField];
+
+ if(!f)
+ continue;// why???
+ if ( f->getMeshName() == _mesh->getName() )
+ {
+
+ std::vector< std::vector<MEDCoupling::TypeOfField> > fTypes = f->getTypesOfFieldAvailable();
+ std::vector< std::pair<int,int> > iters = f->getIterations();
+ const std::vector<std::string>& compInfo = f->getInfo();
+ std::pair<int,int> it = iters[0];
+
+ //~// Open File for writing
+ _myCurrentFileId = _writer.GmfOpenMesh( fieldFileIt->c_str(), GmfWrite, _version, _dim );
+
+ if ( fTypes[0].size() == 1 && fTypes[0][0] == MEDCoupling::ON_NODES )
+ {
+ setFieldOnNodes(f, it.first, it.second, compInfo.size());
+ }
+ else
+ {
+ setFieldOnCells( f, it.first, it.second, levs );
+ }
+ //~// Close File
+ _writer.GmfCloseMesh( _myCurrentFileId );
+ }
+
+
+ iField++;
+ }
+
+ return status;
+}
+
+MeshFormat::Status MeshFormatWriter::setFieldOnNodes(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, size_t compSize)
+{
+
+
+ std::vector<INTERP_KERNEL::NormalizedCellType> types;
+ std::vector< std::vector<MEDCoupling::TypeOfField> > typesF;
+ std::vector< std::vector<std::string> > pfls, locs;
+ std::vector< std::vector< std::pair<mcIdType,mcIdType> > > valsVec;
+ valsVec = f->getFieldSplitedByType( iteration, order, _mesh->getName().c_str(),
+ types, typesF, pfls, locs);
+ // believe that there can be only one type in a nodal field,
+ // so do not perform a loop on types
+ const MEDCoupling::DataArrayDouble* valsArray = f->getUndergroundDataArray(iteration, order);
+ int typTab[] = { getGmfSolKwd((int)compSize, _dim) };
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfSolAtVertices, (int)valsVec[0][0].second, 1, typTab);
+ double* valTab0 = new double[compSize];
+ double* valTab;
+ for ( size_t i = valsVec[0][0].first; i < (std::size_t)valsVec[0][0].second; ++i )
+ {
+
+ for ( size_t j = 0; j < compSize; ++j )
+ valTab0[j] = valsArray->getIJ( i, j );
+
+ if (compSize == 9 || compSize == 4){ // full matrix ==>uper triangular matrix
+ extractSymetricTensor(valTab0, valTab);
+ _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
+ delete [] valTab;
+
+ }
+ else
+ _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab0);
+
+ }
+ delete [] valTab0;
+
+
+
+}
+
+MeshFormat::Status MeshFormatWriter::setFieldOnCells(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, std::vector<int> levs )
+{
+
+ int dim = _mesh->getMeshDimension(); // dim mesh field lying to
+ int absDim = f->getNonEmptyLevels(iteration, order, f->getMeshName(), levs);
+
+ MEDCoupling::MEDCouplingFieldDouble** cellToNodeFldb = new MEDCoupling::MEDCouplingFieldDouble* [(int)levs.size()] ;
+ MEDCoupling::MEDCouplingFieldDouble** fldb = new MEDCoupling::MEDCouplingFieldDouble* [(int)levs.size()] ;
+
+ for (size_t k = 0; k<levs.size(); k++) fldb[k] = f->field( iteration, order,_mesh );
+
+ // turn it node discretization
+ for (size_t l = 0; l < levs.size(); l++) cellToNodeFldb[l] = fldb[l]->cellToNodeDiscretization() ;
+
+ for(size_t j =0; j < levs.size(); j++ )
+ {
+
+ const mcIdType pointsNumber = cellToNodeFldb[j]->getNumberOfTuples();
+ const mcIdType nbComp = (int) cellToNodeFldb[j]->getNumberOfComponents() ;
+
+ MEDCoupling::DataArrayDouble* timeStamp = cellToNodeFldb[j]->getArray();
+ double* values = timeStamp->getPointer();
+
+ int typ = getGmfSolKwd((int)nbComp, _dim) ;
+ if(typ == -1)
+ {
+ addMessage( MeshFormat::Comment(" error with Number of Component ") << nbComp, /*fatal=*/true );
+ return MeshFormat::Status::DRS_FAIL;
+ }
+
+ int typTab[] = {typ};
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfSolAtVertices, pointsNumber, 1, typTab);
+
+
+ double *valTab;
+ for (int i = 0; i < pointsNumber ; i++ )
+ {
+
+ double valTab0[10]; //max 3x3 matrix +1 for safety ;)
+
+ std::copy(values, values+nbComp, valTab0);
+
+ if (nbComp == 9 || nbComp == 4) // full matrix ==>uper triangular matrix
+ {
+ extractSymetricTensor(valTab0, valTab);
+ _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
+ delete [] valTab;
+ }
+ else //sym mat, scalar or vec
+ {
+ valTab = new double[nbComp];
+ std::copy(valTab0, valTab0+nbComp, valTab);
+ _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
+ delete [] valTab;
+ }
+ values+=nbComp;
+
+ }
+
+
+ }
+
+ for(size_t i = 0; i < levs.size(); i++ ) fldb[i]->decrRef();
+ for(size_t i = 0; i < levs.size(); i++ ) cellToNodeFldb[i]->decrRef();
+ delete [] cellToNodeFldb;
+ delete [] fldb;
+
+}
+ /*\
+ |*| extract the upper triangular matrix of fullTensor
+ |*| if _dim == 2 fill symTensor with values at index 0, 1 & 3 of fullTensor
+ |*| |x0 x1|
+ |*| |x2 x3|
+ |*| if _dim == 3 fill symTensor with values at index 0, 1, 2, 4, 5 & 8 of fullTensor
+ |*| |x0 x1 x2|
+ |*| |x3 x4 x5|
+ |*| |x6 x7 x8|
+ \*/
+void MeshFormatWriter::extractSymetricTensor(double fullTensor[], double*& symTensor)
+{
+ symTensor = new double[_dim*(_dim+1)/2];
+ for (int ii =0; ii<_dim; ii++)
+ for (int jj =ii; jj<_dim; jj++)
+ {
+ int kk = _dim*(_dim-1)/2- (_dim-ii)*(_dim-ii-1)/2+jj;
+ symTensor[kk] = fullTensor[ii+jj*_dim];
+ }
+}
+int MeshFormatWriter::getGmfSolKwd(const int nbComp, const int dim)
+{
+ if (nbComp== 1) return GmfSca;
+ else if( dim == nbComp) return GmfVec;
+ else if (dim*(dim+1)/2 == nbComp || dim*dim == nbComp ) return GmfSymMat;
+ //~else if (dim*dim == nbComp) return GmfMat; // Not valid in mg-adapt if not sym
+ else return -1;
+}
+bool MeshFormatWriter::checkFileName()
+{
+ bool ret = true;
+ return ret;
+}
+bool MeshFormatWriter::checkFieldFileName()
+{
+ bool ret = true;
+ return ret;
+
+}
+
+std::string MeshFormatWriter::getMeshFileName() const
+{
+ return _meshFileName;
+}
+
+
+std::vector<std::string> MeshFormatWriter::getFieldFileNames() const
+{
+ return _fieldFileNames;
+}
+
+MeshFormat::Status MeshFormatWriter::addMessage(const std::string& msg,
+ const bool isFatal/*=false*/)
+{
+ if ( isFatal )
+ _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
+
+ _myErrorMessages.push_back( msg );
+
+ //~MESSAGE(msg);
+#ifdef _DEBUG_
+ std::cout << msg << std::endl;
+#endif
+ return ( _myStatus = isFatal ? MeshFormat::DRS_FAIL : MeshFormat::DRS_WARN_SKIP_ELEM );
+}
+
+
+void MeshFormatWriter::forward_shift(std::vector<MEDCoupling::mcIdType> &conn)
+{
+ std::vector<MEDCoupling::mcIdType>::iterator it = conn.begin();
+ for (; it != conn.end(); ++it) *it = *it+1;
+}
+
+
+void MeshFormatWriter::getNodes(MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0)
+{
+ MEDCoupling::mcIdType nbNodes = 0;
+ nbNodes = umesh0->getNumberOfNodes();
+
+
+ // nodes
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> coordArray = umesh0->getCoordinatesAndOwner();
+ double* coordPrt = coordArray->getPointer();
+ _writer.GmfSetKwd( _myCurrentFileId, MeshFormat::GmfVertices, nbNodes );
+ double xyz[3];
+ int j = (int)nbNodes;
+
+ int idNode = 0;
+
+ while ( j >0 )
+ {
+
+ std::copy(coordPrt, coordPrt+_dim, xyz);
+
+ MeshFormatNode e(xyz[0], xyz[1], xyz[2], idNode);
+ _idNodeToNode.insert(std::pair <int, MeshFormatNode> (idNode, e));
+
+ coordPrt+= _dim;
+ j--;
+ idNode++;
+ }
+ linkFamilyToNodes();
+ std::map <int, MeshFormatNode>::iterator itNode = _idNodeToNode.begin();
+ for (; itNode!= _idNodeToNode.end(); ++itNode)
+ _dim == 3? _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfVertices, itNode->second.xyz[0],
+ itNode->second.xyz[1], itNode->second.xyz[2], std::abs(itNode->second._famId) ) :
+ _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfVertices, itNode->second.xyz[0],
+ itNode->second.xyz[1], std::abs(itNode->second._famId) );
+}
+
+
+void MeshFormatWriter::getNSEG2(MEDCoupling::mcIdType nbEdgesNSEG2, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh1->giveCellsWithType(INTERP_KERNEL::NORM_SEG2);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh1->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+
+ MeshFormatCell e(INTERP_KERNEL::NORM_SEG2, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_SEG2, idCellToCell) );
+}
+
+
+void MeshFormatWriter::getNSEG3( MEDCoupling::mcIdType nbEdgesNSEG3, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1)
+{
+
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh1->giveCellsWithType(INTERP_KERNEL::NORM_SEG3);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh1->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_SEG3, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_SEG3, idCellToCell) );
+}
+
+
+void MeshFormatWriter::getTRI3( MEDCoupling::mcIdType nbTRI3, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_TRI3);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh2->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_TRI3, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TRI3, idCellToCell) );
+}
+
+
+void MeshFormatWriter::getTRI6( MEDCoupling::mcIdType nbTRI6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_TRI6);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh2->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_TRI6, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TRI6, idCellToCell) );
+}
+
+void MeshFormatWriter::getQUAD4( MEDCoupling::mcIdType nbQUAD4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh2->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_QUAD4, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD4, idCellToCell) );
+}
+
+void MeshFormatWriter::getQUAD8(MEDCoupling::mcIdType nbQUAD8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD8);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh2->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_QUAD8, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD8, idCellToCell) );
+}
+
+void MeshFormatWriter::getQUAD9(MEDCoupling::mcIdType nbQUAD9, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD9);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh2->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_QUAD9, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD9, idCellToCell) );
+}
+
+void MeshFormatWriter::getTETRA4(MEDCoupling::mcIdType nbTETRA4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_TETRA4);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_TETRA4, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TETRA4, idCellToCell) );
+}
+
+void MeshFormatWriter::getTETRA10(MEDCoupling::mcIdType nbTETRA10, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_TETRA10);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_TETRA10, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TETRA10, idCellToCell) );
+}
+
+void MeshFormatWriter::getPYRA5(MEDCoupling::mcIdType nbPYRA5, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_PYRA5);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_PYRA5, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_PYRA5, idCellToCell) );
+}
+
+void MeshFormatWriter::getHEXA8(MEDCoupling::mcIdType nbHEXA8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA8);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_HEXA8, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA8, idCellToCell) );
+}
+void MeshFormatWriter::getHEXA20(MEDCoupling::mcIdType nbHEXA20, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA20);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_HEXA20, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA20, idCellToCell) );
+}
+void MeshFormatWriter::getHEXA27(MEDCoupling::mcIdType nbHEXA27, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA27);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_HEXA27, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA27, idCellToCell) );
+}
+
+void MeshFormatWriter::getPENTA6(MEDCoupling::mcIdType nbPENTA6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
+{
+
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_PENTA6);
+ std::map<int, MeshFormatCell> idCellToCell;
+ for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
+ {
+ std::vector<MEDCoupling::mcIdType> conn;
+ umesh3->getNodeIdsOfCell(*it, conn) ;
+ forward_shift(conn);
+ MeshFormatCell e(INTERP_KERNEL::NORM_PENTA6, (int)*it);
+ e.setConn(conn);
+ idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
+ }
+ _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_PENTA6, idCellToCell) );
+}
+
+
+void MeshFormatWriter::linkFamilyToNodes()
+{
+
+ std::map<std::string,mcIdType> famInfos = _mesh->getFamilyInfo();
+ std::map<std::string,mcIdType>::const_iterator famIt = famInfos.begin();
+ for (; famIt != famInfos.end(); ++famIt)
+ {
+ if(!famIt->second) continue; //FAMILLE_ZERO
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> nodeIds = _mesh->getNodeFamilyArr(famIt->first);
+ const MEDCoupling::mcIdType * nodeIdsIt = nodeIds->begin(), * famIDEnd = nodeIds->end();
+ for(; nodeIdsIt< famIDEnd; ++nodeIdsIt) {
+
+ std::map <int, MeshFormatNode>::iterator itNode = _idNodeToNode.find((int)*nodeIdsIt);
+ if (itNode == _idNodeToNode.end()) continue;
+ else itNode->second._famId =(int) famIt->second;
+
+
+ }
+ }
+}
+
+
+
+void MeshFormatWriter::linkFamilyToCells()
+{
+
+ std::vector<int> levs = _mesh->getNonEmptyLevels();
+ for (size_t iDim = 0; iDim < levs.size(); iDim++ )
+ {
+ int meshDimRelToMax = levs[iDim];
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh = _mesh->getMeshAtLevel( meshDimRelToMax);
+ MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0 = mesh->buildUnstructured();
+ const MEDCoupling::DataArrayIdType * famIds = _mesh->getFamilyFieldAtLevel(meshDimRelToMax);
+ const MEDCoupling::mcIdType * famID = famIds->begin(), *famIDEnd = famIds->end();
+ for (; famID < famIDEnd; ++famID)
+ {
+ if (!(*famID)) continue; // "FAMILLE_ZERO"
+ std::string famName = _mesh->getFamilyNameGivenId(*famID);
+ MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> cellIds = _mesh->getFamilyArr( meshDimRelToMax, famName);
+ const MEDCoupling::mcIdType * cellIdsIt = cellIds->begin(), *cellIDEnd = cellIds->end();
+ for(; cellIdsIt< cellIDEnd; ++cellIdsIt)
+ {
+ INTERP_KERNEL::NormalizedCellType type = umesh0->getTypeOfCell(*cellIdsIt); //TODO
+ std::map<INTERP_KERNEL::NormalizedCellType, std::map <int, MeshFormatCell> >::iterator itCellMap = _typeToIdCellToCell.find(type);
+ if (itCellMap == _typeToIdCellToCell.end()) continue;
+ else
+ {
+ std::map <int, MeshFormatCell>::iterator itCell = itCellMap->second.find((int)*cellIdsIt);
+ if (itCell == itCellMap->second.end()) continue;
+ else itCell->second._famId = (int)*famID;
+ }
+
+ }
+
+
+
+ }
+ }
+}
+void MeshFormatWriter::writeCells()
+{
+
+ std::map < INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >::iterator typeCellMapIt = _typeToIdCellToCell.begin();
+ for (; typeCellMapIt!= _typeToIdCellToCell.end(); ++typeCellMapIt)
+ {
+ std::map<int, MeshFormatCell>::iterator cellMapIt = typeCellMapIt->second.begin();
+ switch (typeCellMapIt->first)
+ {
+ case INTERP_KERNEL::NORM_SEG2 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfEdges, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfEdges, conn[0], conn[1], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_SEG3 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfEdges, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfEdges, conn[0], conn[1], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges, cellMapIt->first+1, 1, conn[2] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_TRI3 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTriangles, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTriangles, conn[0], conn[1], conn[2], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_TRI6 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTriangles, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTriangles, conn[0], conn[1], conn[2], std::abs(cellMapIt->second._famId) );
+ }
+
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles, cellMapIt->first+1, 3, conn[3], conn[4], conn[5] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_QUAD4 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_QUAD8 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, cellMapIt->first+1, 4, conn[4], conn[5],
+ conn[6], conn[7] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_QUAD9 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals,cellMapIt->first+1, 5, conn[4], conn[5],
+ conn[6], conn[7], conn[8] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_TETRA4 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTetrahedra, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTetrahedra, conn[0], conn[2], conn[1], conn[3], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_TETRA10 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTetrahedra, conn[0], conn[2], conn[1], conn[3], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTetrahedra, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra, cellMapIt->first+1, 6, conn[6], conn[5],
+ conn[4], conn[7], conn[8], conn[9] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_PYRA5 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfPyramids, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfPyramids, conn[3], conn[2], conn[1], conn[0], conn[4], std::abs(cellMapIt->second._famId) );
+
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_HEXA8 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfHexahedra, conn[0], conn[3], conn[2], conn[1], conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
+
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_HEXA20 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfHexahedra, conn[0], conn[3], conn[2], conn[1],
+ conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, cellMapIt->first+1, 12, conn[11], conn[10], conn[9],
+ conn[8], conn[15], conn[14], conn[13], conn[12], conn[16], conn[19], conn[18], conn[17] );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_HEXA27 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, conn[0], conn[3], conn[2], conn[1],
+ conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
+ }
+ cellMapIt = typeCellMapIt->second.begin();
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, cellMapIt->first+1, 19, conn[11], conn[10], conn[9],
+ conn[8], conn[15], conn[14], conn[13], conn[12], conn[16], conn[19], conn[18], conn[17],
+ conn[20], conn[24], conn[23], conn[22], conn[21], conn[25], conn[26], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ case INTERP_KERNEL::NORM_PENTA6 :
+ {
+
+ _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfPrisms, (int)typeCellMapIt->second.size());
+
+ for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
+ {
+ std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
+ _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfPrisms, conn[0], conn[2], conn[1], conn[3], conn[5], conn[4], std::abs(cellMapIt->second._famId) );
+ }
+ break;
+ }
+ }
+ }
+}
+}
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 MESHFORMATWRITER_HXX
+#define MESHFORMATWRITER_HXX
+
+#include <vector>
+#include <string>
+#include <string>
+#include "MCAuto.hxx"
+#include "InterpKernelException.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
+#include "MCType.hxx"
+#include "MEDMESHConverterUtilities.hxx"
+#include "libmesh5.hxx"
+
+#include "MEDFileMesh.hxx"
+#include <fstream>
+
+namespace MEDCoupling
+{
+class DataArrayDouble;
+class DataArrayInt;
+class MEDFileData;
+class MEDFileFields;
+class MEDFileFieldMultiTS;
+class MEDFileUMesh;
+
+
+struct MeshFormatNode {
+ MeshFormatNode(double x, double y, double z=0, int id=0, int famId=0): _id(id), _famId(famId) {
+ xyz[0] = x;
+ xyz[1] = y;
+ xyz[2] = z;
+ }
+ int _id;
+ int _famId;
+ double xyz[3];
+
+ //~inline friend bool operator==(const MeshFormatNode& a, const MeshFormatNode&b ) { return ((a._type == b._type) && (a._id == b._id));}
+};
+
+struct MeshFormatCell {
+ MeshFormatCell(INTERP_KERNEL::NormalizedCellType type, int id=0, int famId=0):_type(type), _id(id), _famId(famId) {}
+ INTERP_KERNEL::NormalizedCellType _type;
+ int _id;
+ int _famId;
+ void setConn(const std::vector<MEDCoupling::mcIdType> cpy)
+ {
+ conn.clear();
+ std::copy(cpy.begin(), cpy.end(), std::back_inserter(conn));
+ }
+ std::vector<MEDCoupling::mcIdType> conn;
+};
+
+
+class MeshFormatWriter
+{
+public :
+ MEDLOADER_EXPORT MeshFormatWriter();
+ MEDLOADER_EXPORT MeshFormatWriter(const std::string& meshFileName, const std::vector<std::string>& fieldFileNames);
+ MEDLOADER_EXPORT ~MeshFormatWriter();
+ MEDLOADER_EXPORT void setMeshFileName(const std::string& meshFileName);
+ MEDLOADER_EXPORT std::string getMeshFileName() const;
+ MEDLOADER_EXPORT void setFieldFileNames(const std::vector<std::string>& fieldFileNames);
+ MEDLOADER_EXPORT std::vector<std::string> getFieldFileNames() const;
+ MEDLOADER_EXPORT void setMEDFileDS(MEDCoupling::MEDFileData* mfd);
+
+ MEDLOADER_EXPORT void write();
+
+private :
+
+ void getNodes( MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0);
+ void getNSEG2( MEDCoupling::mcIdType nbEdgesNSEG2, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1);
+ void getNSEG3( MEDCoupling::mcIdType nbEdgesNSEG2, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1);
+ void getTRI3( MEDCoupling::mcIdType nbTRI3, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2);
+ void getTRI6( MEDCoupling::mcIdType nbTRI6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2);
+ void getQUAD4( MEDCoupling::mcIdType nbQUAD4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2);
+ void getQUAD8( MEDCoupling::mcIdType nbQUAD8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2);
+ void getQUAD9( MEDCoupling::mcIdType nbQUAD9, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2);
+ void getTETRA4( MEDCoupling::mcIdType nbTETRA4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getTETRA10( MEDCoupling::mcIdType nbTETRA10, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getPYRA5( MEDCoupling::mcIdType nbPYRA5, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getHEXA8( MEDCoupling::mcIdType nbHEXA8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getHEXA20( MEDCoupling::mcIdType nbHEXA20, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getHEXA27( MEDCoupling::mcIdType nbHEXA27, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ void getPENTA6( MEDCoupling::mcIdType nbPENTA6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3);
+ int getGmfSolKwd(const int nbComp, const int dim);
+ MeshFormat::Status setFieldOnNodes(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, size_t compInfoSize);
+ MeshFormat::Status setFieldOnCells(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, std::vector<int> levs );
+ void extractSymetricTensor(double fullTensor[], double*& symTensor);
+ void linkFamilyToNodes();
+ void linkFamilyToCells();
+ void writeCells();
+
+ bool checkFileName();
+ bool checkFieldFileName();
+ void forward_shift(std::vector<MEDCoupling::mcIdType> &conn);
+ MeshFormat::Status perform();
+ MeshFormat::Status performFields();
+ MeshFormat::Status addMessage(const std::string& msg, const bool isFatal = false);
+
+ std::string _meshFileName;
+ MeshFormat::MeshFormatParser _writer;
+ std::vector<std::string> _fieldFileNames;
+ MEDCoupling::MEDFileData* _mfd;
+ MEDCoupling::MCAuto< MEDCoupling::MEDFileMesh > _mesh;
+ std::vector< MEDCoupling::MCAuto< MEDCoupling::MEDFileFieldMultiTS > > _fields;
+ std::vector< std::string > _myErrorMessages;
+ MeshFormat::Status _myStatus;
+ int _myCurrentFileId, _dim, _version;
+ std::string _myCurrentOpenFile;
+ std::map<int, MeshFormatNode> _idNodeToNode;
+ std::map < INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> > _typeToIdCellToCell;
+
+};
+}
+#endif //MESHFORMATWRITER_HXX
#include "MEDLoaderTypemaps.i"
#include "SauvReader.hxx"
#include "SauvWriter.hxx"
+#include "MeshFormatReader.hxx"
+#include "MeshFormatWriter.hxx"
using namespace MEDCoupling;
%}
%newobject MEDCoupling::SauvReader::New;
%newobject MEDCoupling::SauvReader::loadInMEDFileDS;
+
%newobject MEDCoupling::MEDFileMeshStruct::New;
%newobject MEDCoupling::MEDMeshMultiLev::prepare;
%newobject MEDCoupling::MEDMeshMultiLev::buildDataArray;
%newobject MEDCoupling::MEDFileFastCellSupportComparator::New;
%newobject MEDCoupling::MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport;
+%newobject MEDCoupling::MeshFormatReader::loadInMEDFileDS;
+%newobject MEDCoupling::MeshFormatReader::MeshFormatReader;
+%newobject MEDCoupling::MeshFormatWriter::MeshFormatWriter;
+
%feature("unref") MEDFileMesh "$this->decrRef();"
%feature("unref") MEDFileUMesh "$this->decrRef();"
%feature("unref") MEDFileCMesh "$this->decrRef();"
}
}
};
+
+ class MeshFormatReader
+ {
+ public:
+ MeshFormatReader(const std::string& meshFileName, const std::vector<std::string>& fieldFileName);
+ MeshFormatReader();
+ MEDFileData* loadInMedFileDS();
+ void setMeshName(const std::string& theMeshName);
+ std::string getMeshName() const;
+ void setFile(const std::string& theFileName);
+ void setFieldFileNames(const std::vector<std::string>& theFieldFileNames);
+ std::vector<std::string> getFieldFileNames() const;
+ };
+ class MeshFormatWriter
+ {
+ public:
+ MeshFormatWriter(const std::string& meshFileName, const std::vector<std::string>& fieldFileNames);
+ MeshFormatWriter();
+ void setMeshFileName(const std::string& meshFileName);
+ std::string getMeshFileName() const;
+ void setFieldFileNames(const std::vector<std::string>& fieldFileNames);
+ std::vector<std::string> getFieldFileNames() const;
+ void setMEDFileDS(MEDCoupling::MEDFileData* mfd);
+ void write();
+ };
+
}
%pythoncode %{
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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
+//
+
+/*----------------------------------------------------------*/
+/* */
+/* LIBMESH V 5.46 */
+/* */
+/*----------------------------------------------------------*/
+/* */
+/* Description: handle .meshb file format I/O */
+/* Author: Loic MARECHAL */
+/* Creation date: feb 16 2007 */
+/* Last modification: apr 03 2012 */
+/* */
+/*----------------------------------------------------------*/
+
+
+/*----------------------------------------------------------*/
+/* Includes */
+/*----------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <ctype.h>
+#include "libmesh5.hxx"
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+using namespace MeshFormat;
+
+
+
+/*----------------------------------------------------------*/
+/* Global variables */
+/*----------------------------------------------------------*/
+
+// see MeshGems/Docs/meshgems_formats_description.pdf
+const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
+{ {"Reserved", "", "", ""},
+ {"MeshVersionFormatted", "", "", "i"},
+ {"Reserved", "", "", ""},
+ {"Dimension", "", "", "i"},
+ {"Vertices", "Vertex", "i", "dri"},
+ {"Edges", "Edge", "i", "iii"},
+ {"Triangles", "Triangle", "i", "iiii"},
+ {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
+ {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
+ {"Prisms", "Prism", "i", "iiiiiii"},
+ {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
+ {"IterationsAll", "IterationAll","","i"},
+ {"TimesAll", "TimeAll","","r"},
+ {"Corners", "Corner", "i", "i"},
+ {"Ridges", "Ridge", "i", "i"},
+ {"RequiredVertices", "RequiredVertex", "i", "i"},
+ {"RequiredEdges", "RequiredEdge", "i", "i"},
+ {"RequiredTriangles", "RequiredTriangle", "i", "i"},
+ {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
+ {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
+ {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
+ {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
+ {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
+ {"AngleOfCornerBound", "", "", "r"},
+ {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
+ {"EdgesP2", "EdgeP2", "i", "iiii"},
+ {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
+ {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
+ {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
+ {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
+ {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
+ {"Fault_NearTri", "Fault_NearTri", "i", "i"},
+ {"Fault_Inter", "Fault_Inter", "i", "i"},
+ {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
+ {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
+ {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
+ {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
+ {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
+ {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
+ {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
+ {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
+ {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
+ {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
+ {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
+ {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
+ {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
+ {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
+ {"Polygons", "Polygon", "", "iiiiiiiii"},
+ {"Fault_Overlap", "Fault_Overlap", "i", "i"},
+ {"Pyramids", "Pyramid", "i", "iiiiii"},
+ {"BoundingBox", "", "", "drdr"},
+ {"Body","i", "drdrdrdr"},
+ {"PrivateTable", "PrivateTable", "i", "i"},
+ {"Fault_BadShape", "Fault_BadShape", "i", "i"},
+ {"End", "", "", ""},
+ {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
+ {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
+ {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
+ {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
+ {"Tangents", "Tangent", "i", "dr"},
+ {"Normals", "Normal", "i", "dr"},
+ {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
+ {"SolAtVertices", "SolAtVertex", "i", "sr"},
+ {"SolAtEdges", "SolAtEdge", "i", "sr"},
+ {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
+ {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
+ {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
+ {"SolAtPrisms", "SolAtPrism", "i", "sr"},
+ {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
+ {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
+ {"ISolAtVertices", "ISolAtVertex", "i", "i"},
+ {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
+ {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
+ {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
+ {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
+ {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
+ {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
+ {"Iterations", "","","i"},
+ {"Time", "","","r"},
+ {"Fault_SmallTri", "Fault_SmallTri","i","i"},
+ {"CoarseHexahedra", "CoarseHexahedron", "i", "i"},
+ {"Fault_MultipleEdge", "Fault_MultipleEdge", "i", "i"}
+};
+
+
+
+MeshFormatParser::MeshFormatParser():GmfIniFlg(0)
+{
+
+}
+
+/*----------------------------------------------------------*/
+/* Open a mesh file in read or write mod */
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::GmfOpenMesh(const char *FilNam, int mod, ...)
+{
+ int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
+ char str[ GmfStrSiz ];
+ va_list VarArg;
+ GmfMshSct *msh;
+ char *ptr;
+ int k;
+#if defined(WIN32) && defined(UNICODE)
+ wchar_t* encoded = 0;
+ int size_needed = 0;
+#endif
+ if(!GmfIniFlg)
+ {
+ for(i=0; i<=MaxMsh; i++)
+ //~GmfMshTab[i] = NULL;
+ GmfMshTab[i] = nullptr;
+
+ GmfIniFlg = 1;
+ }
+
+ /*---------------------*/
+ /* MESH STRUCTURE INIT */
+ /*---------------------*/
+
+ for(i=1; i<=MaxMsh; i++)
+ if(!GmfMshTab[i])
+ {
+ MshIdx = i;
+ break;
+ }
+
+
+ if( !MshIdx || !(msh = new GmfMshSct() ) )
+ return(0);
+
+ /* Copy the FilNam into the structure */
+
+ if(strlen(FilNam) + 7 >= GmfStrSiz)
+ {
+ //~free (msh);
+ delete msh;
+ return(0);
+ }
+
+ strcpy(msh->FilNam, FilNam);
+
+ /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
+
+ msh->mod = mod;
+ msh->buf = (unsigned char *)msh->DblBuf;
+ msh->FltBuf = (float *)msh->DblBuf;
+ msh->IntBuf = (int *)msh->DblBuf;
+
+ k = static_cast<int>(strlen(msh->FilNam)) - 6;
+ if(k < 0)
+ k = 0;
+ ptr = msh->FilNam+k;
+ if(strstr(ptr, ".meshb"))
+ msh->typ |= (Bin | MshFil);
+ else if(strstr(ptr, ".mesh"))
+ msh->typ |= (Asc | MshFil);
+ else if(strstr(ptr, ".solb"))
+ msh->typ |= (Bin | SolFil);
+ else if(strstr(ptr, ".sol"))
+ msh->typ |= (Asc | SolFil);
+ else {
+ //~free (msh);
+ delete msh;
+ return(0);
+ }
+
+ /* Open the file in the required mod and initialise the mesh structure */
+
+ if(msh->mod == GmfRead)
+ {
+
+ /*-----------------------*/
+ /* OPEN FILE FOR READING */
+ /*-----------------------*/
+
+ va_start(VarArg, mod);
+ PtrVer = va_arg(VarArg, int *);
+ PtrDim = va_arg(VarArg, int *);
+ va_end(VarArg);
+
+ /* Create the name string and open the file */
+#if defined(WIN32) && defined(UNICODE)
+ size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
+ //~encoded = malloc((size_needed + 1)*sizeof(wchar_t));
+ encoded = new wchar_t[size_needed + 1] ;
+ MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
+ encoded[size_needed] = '\0';
+ if (!(msh->hdl = _wfopen(encoded, L"rb")))
+#else
+ if (!(msh->hdl = fopen(msh->FilNam, "rb")))
+#endif
+ {
+
+ delete msh;
+#if defined(WIN32) && defined(UNICODE)
+
+ delete [] encoded;
+#endif
+ return(0);
+ }
+
+#if defined(WIN32) && defined(UNICODE)
+
+ delete [] encoded;
+#endif
+
+ /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
+
+ if(msh->typ & Bin)
+ {
+ fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
+
+ if( (msh->cod != 1) && (msh->cod != 16777216) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ ScaWrd(msh, (unsigned char *)&msh->ver);
+
+ if( (msh->ver < 1) || (msh->ver > 3) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ if( (msh->ver == 3) && (sizeof(long) == 4) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ ScaWrd(msh, (unsigned char *)&KwdCod);
+
+ if(KwdCod != GmfDimension)
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ GetPos(msh);
+ ScaWrd(msh, (unsigned char *)&msh->dim);
+ }
+ else
+ {
+ do
+ {
+ res = fscanf(msh->hdl, "%s", str);
+ } while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
+
+ if(res == EOF)
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ fscanf(msh->hdl, "%d", &msh->ver);
+
+ if( (msh->ver < 1) || (msh->ver > 3) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ do
+ {
+ res = fscanf(msh->hdl, "%s", str);
+ } while( (res != EOF) && strcmp(str, "Dimension") );
+
+ if(res == EOF)
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ fscanf(msh->hdl, "%d", &msh->dim);
+ }
+
+ if( (msh->dim != 2) && (msh->dim != 3) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ (*PtrVer) = msh->ver;
+ (*PtrDim) = msh->dim;
+
+ /*------------*/
+ /* KW READING */
+ /*------------*/
+
+ /* Read the list of kw present in the file */
+
+ if(!ScaKwdTab(msh))
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ GmfMshTab[ MshIdx ] = msh;
+
+ return(MshIdx);
+ }
+ else if(msh->mod == GmfWrite)
+ {
+
+ /*-----------------------*/
+ /* OPEN FILE FOR WRITING */
+ /*-----------------------*/
+
+ msh->cod = 1;
+
+ /* Check if the user provided a valid version number and dimension */
+
+ va_start(VarArg, mod);
+ msh->ver = va_arg(VarArg, int);
+ msh->dim = va_arg(VarArg, int);
+ va_end(VarArg);
+
+ if( (msh->ver < 1) || (msh->ver > 3) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ if( (msh->ver == 3) && (sizeof(long) == 4) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ if( (msh->dim != 2) && (msh->dim != 3) )
+ {
+
+ delete msh;
+ return(0);
+ }
+
+ /* Create the mesh file */
+#if defined(WIN32) && defined(UNICODE)
+ size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
+
+ encoded = new wchar_t[size_needed + 1];
+ MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
+ encoded[size_needed] = '\0';
+ if (!(msh->hdl = _wfopen(encoded, L"wb")))
+#else
+ if(!(msh->hdl = fopen(msh->FilNam, "wb")))
+#endif
+ {
+
+ delete msh;
+#if defined(WIN32) && defined(UNICODE)
+
+ delete []encoded;
+#endif
+ return(0);
+ }
+
+#if defined(WIN32) && defined(UNICODE)
+
+ delete []encoded;
+#endif
+ GmfMshTab[ MshIdx ] = msh;
+
+
+ /*------------*/
+ /* KW WRITING */
+ /*------------*/
+
+ /* Write the mesh version and dimension */
+
+ if(msh->typ & Asc)
+ {
+ fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
+ fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
+ }
+ else
+ {
+ RecWrd(msh, (unsigned char *)&msh->cod);
+ RecWrd(msh, (unsigned char *)&msh->ver);
+ GmfSetKwd(MshIdx, GmfDimension, 0);
+ RecWrd(msh, (unsigned char *)&msh->dim);
+ }
+
+ return(MshIdx);
+ }
+ else
+ {
+
+ delete msh;
+ return(0);
+ }
+}
+
+
+/*----------------------------------------------------------*/
+/* Close a meshfile in the right way */
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::GmfCloseMesh(int MshIdx)
+{
+ int res = 1;
+ GmfMshSct *msh;
+
+ if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+ return(0);
+
+ msh = GmfMshTab[ MshIdx ];
+ RecBlk(msh, msh->buf, 0);
+
+ /* In write down the "End" kw in write mode */
+
+ if(msh->mod == GmfWrite) {
+ if(msh->typ & Asc)
+ fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
+ else
+ GmfSetKwd(MshIdx, GmfEnd, 0);
+ }
+ /* Close the file and free the mesh structure */
+
+ if(fclose(msh->hdl))
+ res = 0;
+
+
+ delete msh;
+
+ GmfMshTab[ MshIdx ] = nullptr;
+
+ return(res);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read the number of lines and set the position to this kwd*/
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::GmfStatKwd(int MshIdx, int KwdCod, ...)
+{
+ int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
+ GmfMshSct *msh;
+ KwdSct *kwd;
+ va_list VarArg;
+
+ if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+ return(0);
+
+ msh = GmfMshTab[ MshIdx ];
+
+ if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+ return(0);
+
+ kwd = &msh->KwdTab[ KwdCod ];
+
+ if(!kwd->NmbLin)
+ return(0);
+
+ /* Read further arguments if this kw is a sol */
+
+ if(kwd->typ == SolKwd)
+ {
+ va_start(VarArg, KwdCod);
+
+ PtrNmbTyp = va_arg(VarArg, int *);
+ *PtrNmbTyp = kwd->NmbTyp;
+
+ PtrSolSiz = va_arg(VarArg, int *);
+ *PtrSolSiz = kwd->SolSiz;
+
+ TypTab = va_arg(VarArg, int *);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ TypTab[i] = kwd->TypTab[i];
+
+ va_end(VarArg);
+ }
+
+ return(kwd->NmbLin);
+}
+
+
+/*----------------------------------------------------------*/
+/* Set the current file position to a given kwd */
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::GmfGotoKwd(int MshIdx, int KwdCod)
+{
+ GmfMshSct *msh;
+ KwdSct *kwd;
+
+ if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+ return(0);
+
+ msh = GmfMshTab[ MshIdx ];
+
+ if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+ return(0);
+
+ kwd = &msh->KwdTab[ KwdCod ];
+
+ if(!kwd->NmbLin)
+ return(0);
+
+ return(fseek(msh->hdl, kwd->pos, SEEK_SET));
+}
+
+
+/*----------------------------------------------------------*/
+/* Write the kwd and set the number of lines */
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::GmfSetKwd(int MshIdx, int KwdCod, ...)
+{
+ int i, NmbLin=0, *TypTab;
+ long CurPos;
+ va_list VarArg;
+ GmfMshSct *msh;
+ KwdSct *kwd;
+
+ if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+ return(0);
+
+ msh = GmfMshTab[ MshIdx ];
+ RecBlk(msh, msh->buf, 0);
+
+ if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+ return(0);
+
+ kwd = &msh->KwdTab[ KwdCod ];
+
+ /* Read further arguments if this kw has a header */
+
+ if(strlen(GmfKwdFmt[ KwdCod ][2]))
+ {
+ va_start(VarArg, KwdCod);
+ NmbLin = va_arg(VarArg, int);
+
+ if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
+ {
+ kwd->NmbTyp = va_arg(VarArg, int);
+ TypTab = va_arg(VarArg, int *);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ kwd->TypTab[i] = TypTab[i];
+ }
+
+ va_end(VarArg);
+ }
+
+ /* Setup the kwd info */
+
+ ExpFmt(msh, KwdCod);
+
+ if(!kwd->typ)
+ return(0);
+ else if(kwd->typ == InfKwd)
+ kwd->NmbLin = 1;
+ else
+ kwd->NmbLin = NmbLin;
+
+ /* Store the next kwd position in binary file */
+
+ if( (msh->typ & Bin) && msh->NexKwdPos )
+ {
+ CurPos = ftell(msh->hdl);
+ fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
+ SetPos(msh, CurPos);
+ fseek(msh->hdl, CurPos, SEEK_SET);
+ }
+
+ /* Write the header */
+
+ if(msh->typ & Asc)
+ {
+ fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
+
+ if(kwd->typ != InfKwd)
+ fprintf(msh->hdl, "%d\n", kwd->NmbLin);
+
+ /* In case of solution field, write the extended header */
+
+ if(kwd->typ == SolKwd)
+ {
+ fprintf(msh->hdl, "%d ", kwd->NmbTyp);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
+
+ fprintf(msh->hdl, "\n\n");
+ }
+ }
+ else
+ {
+ RecWrd(msh, (unsigned char *)&KwdCod);
+ msh->NexKwdPos = ftell(msh->hdl);
+ SetPos(msh, 0);
+
+ if(kwd->typ != InfKwd)
+ RecWrd(msh, (unsigned char *)&kwd->NmbLin);
+
+ /* In case of solution field, write the extended header at once */
+
+ if(kwd->typ == SolKwd)
+ {
+ RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
+ }
+ }
+
+ /* Reset write buffer position */
+ msh->pos = 0;
+
+ /* Estimate the total file size and check whether it crosses the 2GB threshold */
+
+ msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
+
+ if(msh->siz > static_cast<long>(2E9))
+ return(0);
+ else
+ return(kwd->NmbLin);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a full line from the current kwd */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::GmfGetLin(int MshIdx, int KwdCod, ...)
+{
+ int i, j;
+ float *FltSolTab;
+ double *DblSolTab;
+ va_list VarArg;
+ GmfMshSct *msh = GmfMshTab[ MshIdx ];
+ KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+ /* Start decoding the arguments */
+
+ va_start(VarArg, KwdCod);
+
+ if(kwd->typ != SolKwd)
+ {
+ int k, nb_repeat = 0;
+
+ if(msh->ver == 1)
+ {
+ if(msh->typ & Asc)
+ {
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
+ else if(kwd->fmt[i] == 'n') {
+ fscanf(msh->hdl, "%d", &nb_repeat);
+ *(va_arg(VarArg, int *)) = nb_repeat;
+ for(k=0; k<nb_repeat; k++)
+ fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+ }
+ else
+ fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+ }
+ else
+ {
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
+ else if(kwd->fmt[i] == 'n') {
+ ScaWrd(msh, (unsigned char *)&nb_repeat);
+ *(va_arg(VarArg, int *)) = nb_repeat;
+ for(k=0; k<nb_repeat; k++)
+ ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
+ }
+ else
+ ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
+ }
+ }
+ else
+ {
+ if(msh->typ & Asc)
+ {
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
+ else if(kwd->fmt[i] == 'n') {
+ fscanf(msh->hdl, "%d", &nb_repeat);
+ *(va_arg(VarArg, int *)) = nb_repeat;
+ for(k=0; k<nb_repeat; k++)
+ fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+ }
+ else
+ fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+ }
+ else
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
+ else if(kwd->fmt[i] == 'n') {
+ ScaWrd(msh, (unsigned char *)&nb_repeat);
+ *(va_arg(VarArg, int *)) = nb_repeat;
+ for(k=0; k<nb_repeat; k++)
+ ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
+ }
+ else
+ ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
+ }
+ }
+ else
+ {
+ if(msh->ver == 1)
+ {
+ FltSolTab = va_arg(VarArg, float *);
+
+ if(msh->typ & Asc)
+ for(j=0; j<kwd->SolSiz; j++)
+ fscanf(msh->hdl, "%f", &FltSolTab[j]);
+ else
+ ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
+ }
+ else
+ {
+ DblSolTab = va_arg(VarArg, double *);
+
+ if(msh->typ & Asc)
+ for(j=0; j<kwd->SolSiz; j++)
+ fscanf(msh->hdl, "%lf", &DblSolTab[j]);
+ else
+ for(j=0; j<kwd->SolSiz; j++)
+ ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
+ }
+ }
+
+ va_end(VarArg);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a full line from the current kwd */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::GmfSetLin(int MshIdx, int KwdCod, ...)
+{
+ int i, j, pos, *IntBuf;
+ float *FltSolTab;
+ double *DblSolTab, *DblBuf;
+ va_list VarArg;
+ GmfMshSct *msh = GmfMshTab[ MshIdx ];
+ KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+ /* Start decoding the arguments */
+
+ va_start(VarArg, KwdCod);
+
+ if(kwd->typ != SolKwd)
+ {
+ int k, nb_repeat = 0;
+
+ if(msh->ver == 1)
+ {
+ if(msh->typ & Asc)
+ {
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
+ else if(kwd->fmt[i] == 'n') {
+ nb_repeat = va_arg(VarArg, int);
+ fprintf(msh->hdl, "%d ", nb_repeat);
+ for(k=0; k<nb_repeat; k++)
+ fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+ }
+ else
+ fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+ }
+ else
+ {
+ int size_of_block = kwd->SolSiz;
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ msh->FltBuf[i] = static_cast<float>(va_arg(VarArg, double));
+ else if(kwd->fmt[i] == 'n') {
+ nb_repeat = va_arg(VarArg, int);
+ msh->FltBuf[i] = static_cast<float> (nb_repeat);
+ for(k=0; k<nb_repeat; k++) {
+ msh->IntBuf[i+1+k] = va_arg(VarArg, int);
+ size_of_block ++;
+ }
+ }
+ else
+ msh->IntBuf[i] = va_arg(VarArg, int);
+
+ RecBlk(msh, msh->buf, size_of_block);
+ }
+ }
+ else
+ {
+ if(msh->typ & Asc)
+ {
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
+ else if(kwd->fmt[i] == 'n') {
+ nb_repeat = va_arg(VarArg, int);
+ fprintf(msh->hdl, "%d ", nb_repeat);
+ for(k=0; k<nb_repeat; k++)
+ fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+ }
+ else
+ fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+ }
+ else
+ {
+ pos = 0;
+
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'r')
+ {
+ DblBuf = (double *)&msh->buf[ pos ];
+ *DblBuf = va_arg(VarArg, double);
+ pos += 8;
+ }
+ else if(kwd->fmt[i] == 'n')
+ {
+ IntBuf = (int *)&msh->buf[ pos ];
+ nb_repeat = va_arg(VarArg, int);
+ *IntBuf = nb_repeat;
+ pos += 4;
+ for(k=0; k<nb_repeat; k++) {
+ IntBuf = (int *)&msh->buf[ pos ];
+ *IntBuf = va_arg(VarArg, int);
+ pos += 4;
+ }
+ }
+ else
+ {
+ IntBuf = (int *)&msh->buf[ pos ];
+ *IntBuf = va_arg(VarArg, int);
+ pos += 4;
+ }
+ RecBlk(msh, msh->buf, pos/4);
+ }
+ }
+ }
+ else
+ {
+ if(msh->ver == 1)
+ {
+ FltSolTab = va_arg(VarArg, float *);
+
+ if(msh->typ & Asc)
+ for(j=0; j<kwd->SolSiz; j++)
+ fprintf(msh->hdl, "%g ", FltSolTab[j]);
+ else
+ RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
+ }
+ else
+ {
+ DblSolTab = va_arg(VarArg, double *);
+
+ if(msh->typ & Asc)
+ for(j=0; j<kwd->SolSiz; j++)
+ fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
+ else
+ RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
+ }
+ }
+
+ va_end(VarArg);
+
+ if(msh->typ & Asc)
+ fprintf(msh->hdl, "\n");
+}
+
+
+/*----------------------------------------------------------*/
+/* Private procedure for transmesh : copy a whole line */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
+{
+ double d;
+ float f;
+ int i, a;
+ GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
+ KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
+
+ for(i=0; i<kwd->SolSiz; i++)
+ {
+ if(kwd->fmt[i] == 'r')
+ {
+ if(InpMsh->ver == 1)
+ {
+ if(InpMsh->typ & Asc)
+ fscanf(InpMsh->hdl, "%f", &f);
+ else
+ ScaWrd(InpMsh, (unsigned char *)&f);
+
+ d = f;
+ }
+ else
+ {
+ if(InpMsh->typ & Asc)
+ fscanf(InpMsh->hdl, "%lf", &d);
+ else
+ ScaDblWrd(InpMsh, (unsigned char *)&d);
+
+ f = (float)d;
+ }
+
+ if(OutMsh->ver == 1)
+ if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "%g ", f);
+ else
+ RecWrd(OutMsh, (unsigned char *)&f);
+ else if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "%.15g ", d);
+ else
+ RecDblWrd(OutMsh, (unsigned char *)&d);
+ }
+ else if(kwd->fmt[i] == 'n')
+ {
+ int k, nb_repeat = 0;
+
+ if(InpMsh->typ & Asc)
+ fscanf(InpMsh->hdl, "%d", &a);
+ else
+ ScaWrd(InpMsh, (unsigned char *)&a);
+
+ nb_repeat = a;
+
+ if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "%d ", a);
+ else
+ RecWrd(OutMsh, (unsigned char *)&a);
+
+ for(k=0; k<nb_repeat; k++) {
+ if(InpMsh->typ & Asc)
+ fscanf(InpMsh->hdl, "%d", &a);
+ else
+ ScaWrd(InpMsh, (unsigned char *)&a);
+
+ if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "%d ", a);
+ else
+ RecWrd(OutMsh, (unsigned char *)&a);
+ }
+ }
+ else
+ {
+ if(InpMsh->typ & Asc)
+ fscanf(InpMsh->hdl, "%d", &a);
+ else
+ ScaWrd(InpMsh, (unsigned char *)&a);
+
+ if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "%d ", a);
+ else
+ RecWrd(OutMsh, (unsigned char *)&a);
+ }
+ }
+
+ if(OutMsh->typ & Asc)
+ fprintf(OutMsh->hdl, "\n");
+}
+
+
+/*----------------------------------------------------------*/
+/* Find every kw present in a meshfile */
+/*----------------------------------------------------------*/
+
+int MeshFormatParser::ScaKwdTab(GmfMshSct *msh)
+{
+ int KwdCod;
+ long NexPos, CurPos, EndPos;
+ char str[ GmfStrSiz ];
+
+ if(msh->typ & Asc)
+ {
+ /* Scan each string in the file until the end */
+
+ while(fscanf(msh->hdl, "%s", str) != EOF)
+ {
+ /* Fast test in order to reject quickly the numeric values */
+
+ if(isalpha(str[0]))
+ {
+ /* Search which kwd code this string is associated with,
+ then get its header and save the current position in file (just before the data) */
+ // printf("libmesh ScaKwdTab %s\n", str);
+ for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
+ if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
+ {
+ ScaKwdHdr(msh, KwdCod);
+ break;
+ }
+ }
+ else if(str[0] == '#')
+ while(fgetc(msh->hdl) != '\n');
+ }
+ }
+ else
+ {
+ /* Get file size */
+
+ CurPos = ftell(msh->hdl);
+ fseek(msh->hdl, 0, SEEK_END);
+ EndPos = ftell(msh->hdl);
+ fseek(msh->hdl, CurPos, SEEK_SET);
+
+ /* Jump through kwd positions in the file */
+
+ do
+ {
+ /* Get the kwd code and the next kwd position */
+
+ ScaWrd(msh, (unsigned char *)&KwdCod);
+ NexPos = GetPos(msh);
+
+ if(NexPos > EndPos)
+ return(0);
+
+ /* Check if this kwd belongs to this mesh version */
+
+ if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
+ ScaKwdHdr(msh, KwdCod);
+
+ /* Go to the next kwd */
+
+ if(NexPos)
+ fseek(msh->hdl, NexPos, SEEK_SET);
+ } while(NexPos && (KwdCod != GmfEnd));
+ }
+
+ return(1);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read and setup the keyword's header */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::ScaKwdHdr(GmfMshSct *msh, int KwdCod)
+{
+ int i;
+ KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+ if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
+ {
+ if(msh->typ & Asc)
+ fscanf(msh->hdl, "%d", &kwd->NmbLin);
+ else
+ ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
+ }
+ else
+ kwd->NmbLin = 1;
+
+ if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
+ {
+ if(msh->typ & Asc)
+ {
+ fscanf(msh->hdl, "%d", &kwd->NmbTyp);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
+ }
+ else
+ {
+ ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
+
+ for(i=0; i<kwd->NmbTyp; i++)
+ ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
+ }
+ }
+
+ ExpFmt(msh, KwdCod);
+ kwd->pos = ftell(msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Expand the compacted format and compute the line size */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::ExpFmt(GmfMshSct *msh, int KwdCod)
+{
+ int i, j, TmpSiz=0;
+ char chr;
+ const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
+ KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+ /* Set the kwd's type */
+
+ if(!strlen(GmfKwdFmt[ KwdCod ][2]))
+ kwd->typ = InfKwd;
+ else if(!strcmp(InpFmt, "sr"))
+ kwd->typ = SolKwd;
+ else
+ kwd->typ = RegKwd;
+
+ /* Get the solution-field's size */
+
+ if(kwd->typ == SolKwd)
+ for(i=0; i<kwd->NmbTyp; i++)
+ switch(kwd->TypTab[i])
+ {
+ case GmfSca :
+ TmpSiz += 1;
+ break;
+ case GmfVec :
+ TmpSiz += msh->dim;
+ break;
+ case GmfSymMat :
+ TmpSiz += (msh->dim * (msh->dim+1)) / 2;
+ break;
+ case GmfMat :
+ TmpSiz += msh->dim * msh->dim;
+ break;
+ }
+
+ /* Scan each character from the format string */
+
+ i = kwd->SolSiz = kwd->NmbWrd = 0;
+
+ while(i < static_cast<int>(strlen(InpFmt)) )
+ {
+ chr = InpFmt[ i++ ];
+
+ if(chr == 'd')
+ {
+ chr = InpFmt[i++];
+
+ for(j=0; j<msh->dim; j++)
+ kwd->fmt[ kwd->SolSiz++ ] = chr;
+ }
+ else if(chr == 's')
+ {
+ chr = InpFmt[i++];
+
+ for(j=0; j<TmpSiz; j++)
+ kwd->fmt[ kwd->SolSiz++ ] = chr;
+ }
+ else
+ kwd->fmt[ kwd->SolSiz++ ] = chr;
+ }
+
+ for(i=0; i<kwd->SolSiz; i++)
+ if(kwd->fmt[i] == 'i')
+ kwd->NmbWrd++;
+ else if(msh->ver >= 2)
+ kwd->NmbWrd += 2;
+ else
+ kwd->NmbWrd++;
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a four bytes word from a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::ScaWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+ unsigned char swp;
+
+ fread(wrd, WrdSiz, 1, msh->hdl);
+
+ if(msh->cod == 1)
+ return;
+
+ swp = wrd[3];
+ wrd[3] = wrd[0];
+ wrd[0] = swp;
+
+ swp = wrd[2];
+ wrd[2] = wrd[1];
+ wrd[1] = swp;
+}
+
+
+/*----------------------------------------------------------*/
+/* Read an eight bytes word from a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+ int i;
+ unsigned char swp;
+
+ fread(wrd, WrdSiz, 2, msh->hdl);
+
+ if(msh->cod == 1)
+ return;
+
+ for(i=0; i<4; i++)
+ {
+ swp = wrd[7-i];
+ wrd[7-i] = wrd[i];
+ wrd[i] = swp;
+ }
+}
+
+
+/*----------------------------------------------------------*/
+/* Read ablock of four bytes word from a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
+{
+ int i, j;
+ unsigned char swp, *wrd;
+
+ fread(blk, WrdSiz, siz, msh->hdl);
+
+ if(msh->cod == 1)
+ return;
+
+ for(i=0; i<siz; i++)
+ {
+ wrd = &blk[ i * 4 ];
+
+ for(j=0; j<2; j++)
+ {
+ swp = wrd[ 3-j ];
+ wrd[ 3-j ] = wrd[j];
+ wrd[j] = swp;
+ }
+ }
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a 4 or 8 bytes position in mesh file */
+/*----------------------------------------------------------*/
+
+long MeshFormatParser::GetPos(GmfMshSct *msh)
+{
+ int IntVal;
+ long pos;
+
+ if(msh->ver >= 3)
+ ScaDblWrd(msh, (unsigned char*)&pos);
+ else
+ {
+ ScaWrd(msh, (unsigned char*)&IntVal);
+ pos = IntVal;
+ }
+
+ return(pos);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a four bytes word to a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::RecWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+ fwrite(wrd, WrdSiz, 1, msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write an eight bytes word to a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+ fwrite(wrd, WrdSiz, 2, msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a block of four bytes word to a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
+{
+ /* Copy this line-block into the main mesh buffer */
+
+ if(siz)
+ {
+ memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
+ msh->pos += siz * WrdSiz;
+ }
+
+ /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
+
+ if( (msh->pos > BufSiz) || (!siz && msh->pos) )
+ {
+ fwrite(msh->blk, 1, msh->pos, msh->hdl);
+ msh->pos = 0;
+ }
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a 4 or 8 bytes position in a mesh file */
+/*----------------------------------------------------------*/
+
+void MeshFormatParser::SetPos(GmfMshSct *msh, long pos)
+{
+ int IntVal;
+
+ if(msh->ver >= 3)
+ RecDblWrd(msh, (unsigned char*)&pos);
+ else
+ {
+ IntVal = static_cast<int>(pos);
+ RecWrd(msh, (unsigned char*)&IntVal);
+ }
+}
--- /dev/null
+// Copyright (C) 2021 CEA/DEN, EDF R&D
+//
+// 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 MESHFORMATPARSER_HXX
+#define MESHFORMATPARSER_HXX
+/*----------------------------------------------------------*/
+/* */
+/* LIBMESH V 5.46 */
+/* */
+/*----------------------------------------------------------*/
+/* */
+/* Description: handle .meshb file format I/O */
+/* Author: Loic MARECHAL */
+/* Creation date: feb 16 2007 */
+/* Last modification: dec 12 2020 */
+/* */
+/*----------------------------------------------------------*/
+
+
+/*----------------------------------------------------------*/
+/* Defines */
+/*----------------------------------------------------------*/
+
+
+#define GmfStrSiz 1024
+#define GmfMaxTyp 1000
+#define GmfMaxKwd 81
+#define GmfMshVer 1
+#define GmfRead 1
+#define GmfWrite 2
+#define GmfSca 1
+#define GmfVec 2
+#define GmfSymMat 3
+#define GmfMat 4
+#define GmfFloat 1
+#define GmfDouble 2
+
+
+/*----------------------------------------------------------*/
+/* Defines */
+/*----------------------------------------------------------*/
+
+#define Asc 1
+#define Bin 2
+#define MshFil 4
+#define SolFil 8
+#define MaxMsh 100
+#define InfKwd 1
+#define RegKwd 2
+#define SolKwd 3
+#define WrdSiz 4
+#define BufSiz 10000
+
+
+// see MeshGems/Docs/meshgems_formats_description.pdf
+extern const char* GmfKwdFmt[ GmfMaxKwd + 1 ][4];
+/*----------------------------------------------------------*/
+/* Structures */
+/*----------------------------------------------------------*/
+namespace MeshFormat {
+typedef struct
+{
+ int typ, SolSiz, NmbWrd, NmbLin, NmbTyp, TypTab[ GmfMaxTyp ];
+ long pos;
+ char fmt[ GmfMaxTyp*9 ];
+} KwdSct;
+
+typedef struct
+{
+ int dim, ver, mod, typ, cod, pos;
+ long NexKwdPos, siz;
+ KwdSct KwdTab[ GmfMaxKwd + 1 ];
+ FILE *hdl;
+ int *IntBuf;
+ float *FltBuf;
+ unsigned char *buf;
+ char FilNam[ GmfStrSiz ];
+ double DblBuf[1000/8];
+ unsigned char blk[ BufSiz + 1000 ];
+} GmfMshSct;
+
+
+
+
+
+// see MeshGems/Docs/meshgems_formats_description.pdf
+enum GmfKwdCod
+{
+ GmfReserved1, \
+ GmfVersionFormatted, \
+ GmfReserved2, \
+ GmfDimension, \
+ GmfVertices, \
+ GmfEdges, \
+ GmfTriangles, \
+ GmfQuadrilaterals, \
+ GmfTetrahedra, \
+ GmfPrisms, \
+ GmfHexahedra, \
+ GmfIterationsAll, \
+ GmfTimesAll, \
+ GmfCorners, \
+ GmfRidges, \
+ GmfRequiredVertices, \
+ GmfRequiredEdges, \
+ GmfRequiredTriangles, \
+ GmfRequiredQuadrilaterals, \
+ GmfTangentAtEdgeVertices, \
+ GmfNormalAtVertices, \
+ GmfNormalAtTriangleVertices, \
+ GmfNormalAtQuadrilateralVertices, \
+ GmfAngleOfCornerBound, \
+ GmfTrianglesP2, \
+ GmfEdgesP2, \
+ GmfSolAtPyramids, \
+ GmfQuadrilateralsQ2, \
+ GmfISolAtPyramids, \
+ GmfSubDomainFromGeom, \
+ GmfTetrahedraP2, \
+ GmfFault_NearTri, \
+ GmfFault_Inter, \
+ GmfHexahedraQ2, \
+ GmfExtraVerticesAtEdges, \
+ GmfExtraVerticesAtTriangles, \
+ GmfExtraVerticesAtQuadrilaterals, \
+ GmfExtraVerticesAtTetrahedra, \
+ GmfExtraVerticesAtPrisms, \
+ GmfExtraVerticesAtHexahedra, \
+ GmfVerticesOnGeometricVertices, \
+ GmfVerticesOnGeometricEdges, \
+ GmfVerticesOnGeometricTriangles, \
+ GmfVerticesOnGeometricQuadrilaterals, \
+ GmfEdgesOnGeometricEdges, \
+ GmfFault_FreeEdge, \
+ GmfPolyhedra, \
+ GmfPolygons, \
+ GmfFault_Overlap, \
+ GmfPyramids, \
+ GmfBoundingBox, \
+ GmfBody, \
+ GmfPrivateTable, \
+ GmfFault_BadShape, \
+ GmfEnd, \
+ GmfTrianglesOnGeometricTriangles, \
+ GmfTrianglesOnGeometricQuadrilaterals, \
+ GmfQuadrilateralsOnGeometricTriangles, \
+ GmfQuadrilateralsOnGeometricQuadrilaterals, \
+ GmfTangents, \
+ GmfNormals, \
+ GmfTangentAtVertices, \
+ GmfSolAtVertices, \
+ GmfSolAtEdges, \
+ GmfSolAtTriangles, \
+ GmfSolAtQuadrilaterals, \
+ GmfSolAtTetrahedra, \
+ GmfSolAtPrisms, \
+ GmfSolAtHexahedra, \
+ GmfDSolAtVertices, \
+ GmfISolAtVertices, \
+ GmfISolAtEdges, \
+ GmfISolAtTriangles, \
+ GmfISolAtQuadrilaterals, \
+ GmfISolAtTetrahedra, \
+ GmfISolAtPrisms, \
+ GmfISolAtHexahedra, \
+ GmfIterations, \
+ GmfTime, \
+ GmfFault_SmallTri, \
+ GmfCoarseHexahedra, \
+ GmfFault_MultipleEdge
+};
+
+
+
+class MeshFormatParser {
+ /*----------------------------------------------------------*/
+ /* External procedures */
+ /*----------------------------------------------------------*/
+public :
+ MeshFormatParser();
+ int GmfOpenMesh(const char *, int, ...);
+ int GmfCloseMesh(int);
+ int GmfStatKwd(int, int, ...);
+ int GmfGotoKwd(int, int);
+ int GmfSetKwd(int, int, ...);
+ void GmfGetLin(int, int, ...);
+ void GmfSetLin(int, int, ...);
+private :
+
+
+ /*----------------------------------------------------------*/
+ /* private procedures methods */
+ /*----------------------------------------------------------*/
+
+ void ScaWrd(GmfMshSct *, unsigned char *);
+ void ScaDblWrd(GmfMshSct *, unsigned char *);
+ void ScaBlk(GmfMshSct *, unsigned char *, int);
+ long GetPos(GmfMshSct *);
+ void RecWrd(GmfMshSct *, unsigned char *);
+ void RecDblWrd(GmfMshSct *, unsigned char *);
+ void RecBlk(GmfMshSct *, unsigned char *, int);
+ void SetPos(GmfMshSct *, long);
+ int ScaKwdTab(GmfMshSct *);
+ void ExpFmt(GmfMshSct *, int);
+ void ScaKwdHdr(GmfMshSct *, int);
+
+ void GmfCpyLin(int, int, int);
+
+
+ int GmfIniFlg;
+ GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
+
+
+
+
+
+};
+
+}
+#endif // MESHFORMATPARSER_HXX