/*============================================================================ MetaIO Copyright 2000-2010 Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #ifdef _MSC_VER # pragma warning(disable : 4702) # pragma warning(disable : 4284) #endif #include "metaMesh.h" #if (METAIO_USE_NAMESPACE) namespace METAIO_NAMESPACE { #endif union bufferAlignedUnion { char character; unsigned char ucharacter; short shortint; unsigned short ushortint; int integer; unsigned int uinteger; long int linteger; unsigned long int ulinteger; float floatingpoint; double doublefloatingpoint; }; MeshPoint::MeshPoint(int dim) { m_Dim = static_cast(dim); m_X = new float[m_Dim]; for (unsigned int i = 0; i < m_Dim; i++) { m_X[i] = 0; } } MeshPoint::~MeshPoint() { delete[] m_X; } MeshCell::MeshCell(int dim) { m_Dim = static_cast(dim); m_Id = -1; m_PointsId = new int[m_Dim]; for (unsigned int i = 0; i < m_Dim; i++) { m_PointsId[i] = -1; } } MeshCell::~MeshCell() { delete[] m_PointsId; } // // MetaMesh Constructors // MetaMesh::MetaMesh() : MetaObject() { META_DEBUG_PRINT( "MetaMesh()" ); m_NPoints = 0; for (auto & i : m_CellListArray) { i = nullptr; } MetaMesh::Clear(); } // MetaMesh::MetaMesh(const char * _headerName) : MetaObject() { META_DEBUG_PRINT( "MetaMesh()" ); m_NPoints = 0; for (auto & i : m_CellListArray) { i = nullptr; } MetaMesh::Clear(); MetaMesh::Read(_headerName); } // MetaMesh::MetaMesh(const MetaMesh * _mesh) : MetaObject() { META_DEBUG_PRINT( "MetaMesh()" ); m_NPoints = 0; for (auto & i : m_CellListArray) { i = nullptr; } MetaMesh::Clear(); MetaMesh::CopyInfo(_mesh); } // MetaMesh::MetaMesh(unsigned int dim) : MetaObject(dim) { META_DEBUG_PRINT( "MetaMesh()" ); m_NPoints = 0; for (auto & i : m_CellListArray) { i = nullptr; } MetaMesh::Clear(); } /** Destructor */ MetaMesh::~MetaMesh() { MetaMesh::Clear(); for (auto & i : m_CellListArray) { delete i; i = nullptr; } MetaObject::M_Destroy(); } // void MetaMesh::PrintInfo() const { MetaObject::PrintInfo(); std::cout << "PointDim = " << m_PointDim << std::endl; std::cout << "NPoints = " << m_NPoints << std::endl; char str[255]; MET_TypeToString(m_PointType, str); std::cout << "PointType = " << str << std::endl; MET_TypeToString(m_PointDataType, str); std::cout << "PointDataType = " << str << std::endl; MET_TypeToString(m_CellDataType, str); std::cout << "CellDataType = " << str << std::endl; } void MetaMesh::CopyInfo(const MetaObject * _object) { MetaObject::CopyInfo(_object); } int MetaMesh::NPoints() const { return m_NPoints; } int MetaMesh::NCells() const { return m_NCells; } int MetaMesh::NCellLinks() const { return m_NCellLinks; } /** Clear tube information */ void MetaMesh::Clear() { META_DEBUG_PRINT( "MetaMesh: Clear" ); MetaObject::Clear(); strcpy(m_ObjectTypeName, "Mesh"); META_DEBUG_PRINT( "MetaMesh: Clear: m_NPoints" ); // Delete the list of pointers to points. auto it_pnt = m_PointList.begin(); while (it_pnt != m_PointList.end()) { MeshPoint * pnt = *it_pnt; ++it_pnt; delete pnt; } // Delete the list of pointers to celllinks auto it_celllinks = m_CellLinks.begin(); while (it_celllinks != m_CellLinks.end()) { MeshCellLink * link = *it_celllinks; ++it_celllinks; delete link; } // Delete the list of pointers to pointdata auto it_pointdata = m_PointData.begin(); while (it_pointdata != m_PointData.end()) { MeshDataBase * data = *it_pointdata; ++it_pointdata; delete data; } // Delete the list of pointers to celldata auto it_celldata = m_CellData.begin(); while (it_celldata != m_CellData.end()) { MeshDataBase * data = *it_celldata; ++it_celldata; delete data; } // Initialize the new array for (auto & i : m_CellListArray) { if (i) { // Delete the list of pointers to cells. auto it_cell = i->begin(); while (it_cell != i->end()) { MeshCell * cell = *it_cell; ++it_cell; delete cell; } delete i; } i = new CellListType; } m_PointList.clear(); m_PointData.clear(); m_CellData.clear(); m_NPoints = 0; m_NCells = 0; m_NCellLinks = 0; m_NCellData = 0; m_NPointData = 0; strcpy(m_PointDim, "ID x y ..."); m_PointType = MET_FLOAT; m_PointDataType = MET_FLOAT; m_CellDataType = MET_FLOAT; } /** Set Read fields */ void MetaMesh::M_SetupReadFields() { META_DEBUG_PRINT( "MetaMesh: M_SetupReadFields" ); MetaObject::M_SetupReadFields(); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NCellTypes", MET_INT, true); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "PointDim", MET_STRING, true); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NPoints", MET_INT, true); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "PointType", MET_STRING, true); mF->required = true; m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "PointDataType", MET_STRING, true); mF->required = true; m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellDataType", MET_STRING, true); mF->required = true; m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "Points", MET_NONE, true); mF->terminateRead = true; m_Fields.push_back(mF); } void MetaMesh::M_SetupWriteFields() { MetaObject::M_SetupWriteFields(); MET_FieldRecordType * mF; char s[255]; mF = new MET_FieldRecordType; MET_TypeToString(m_PointType, s); MET_InitWriteField(mF, "PointType", MET_STRING, strlen(s), s); m_Fields.push_back(mF); // Find the pointDataType if (!m_PointData.empty()) { m_PointDataType = (*m_PointData.begin())->GetMetaType(); } char s1[255]; mF = new MET_FieldRecordType; MET_TypeToString(m_PointDataType, s1); MET_InitWriteField(mF, "PointDataType", MET_STRING, strlen(s1), s1); m_Fields.push_back(mF); char s2[255]; mF = new MET_FieldRecordType; MET_TypeToString(m_CellDataType, s2); MET_InitWriteField(mF, "CellDataType", MET_STRING, strlen(s2), s2); m_Fields.push_back(mF); unsigned int numberOfCellTypes = 0; for (auto & i : m_CellListArray) { if (!i->empty()) { numberOfCellTypes++; } } if (numberOfCellTypes) { mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NCellTypes", MET_INT, numberOfCellTypes); m_Fields.push_back(mF); } if (strlen(m_PointDim) > 0) { mF = new MET_FieldRecordType; MET_InitWriteField(mF, "PointDim", MET_STRING, strlen(m_PointDim), m_PointDim); m_Fields.push_back(mF); } m_NPoints = static_cast(m_PointList.size()); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NPoints", MET_INT, m_NPoints); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "Points", MET_NONE); m_Fields.push_back(mF); } bool MetaMesh::M_Read() { META_DEBUG_PRINT( "MetaMesh: M_Read: Loading Header" ); if (!MetaObject::M_Read()) { std::cout << "MetaMesh: M_Read: Error parsing file" << std::endl; return false; } META_DEBUG_PRINT( "MetaMesh: M_Read: Parsing Header" ); MET_FieldRecordType * mF; unsigned int numberOfCellTypes = 0; mF = MET_GetFieldRecord("NCellTypes", &m_Fields); if (mF->defined) { numberOfCellTypes = static_cast(mF->value[0]); } mF = MET_GetFieldRecord("NPoints", &m_Fields); if (mF->defined) { m_NPoints = static_cast(mF->value[0]); } mF = MET_GetFieldRecord("PointType", &m_Fields); if (mF->defined) { MET_StringToType(reinterpret_cast(mF->value), &m_PointType); } mF = MET_GetFieldRecord("PointDataType", &m_Fields); if (mF->defined) { MET_StringToType(reinterpret_cast(mF->value), &m_PointDataType); } mF = MET_GetFieldRecord("CellDataType", &m_Fields); if (mF->defined) { MET_StringToType(reinterpret_cast(mF->value), &m_CellDataType); } mF = MET_GetFieldRecord("PointDim", &m_Fields); if (mF->defined) { strcpy(m_PointDim, reinterpret_cast(mF->value)); } if (m_BinaryData) { int elementSize; MET_SizeOfType(m_PointType, &elementSize); int readSize = m_NPoints * (m_NDims)*elementSize + m_NPoints * sizeof(int); char * _data = new char[readSize]; m_ReadStream->read(_data, readSize); int gc = static_cast(m_ReadStream->gcount()); if (gc != readSize) { std::cout << "MetaMesh: m_Read: Points not read completely" << std::endl; std::cout << " ideal = " << readSize << " : actual = " << gc << std::endl; delete[] _data; return false; } int i = 0; for (int j = 0; j < m_NPoints; j++) { auto * pnt = new MeshPoint(m_NDims); { int td; char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); pnt->m_Id = td; i += sizeof(int); } for (int d = 0; d < m_NDims; d++) { bufferAlignedUnion alignedBuffer{}; char * const num = reinterpret_cast(&alignedBuffer); for (unsigned int k = 0; k < static_cast(elementSize); k++) { num[k] = _data[i + k]; } i += elementSize; if (m_PointType == MET_CHAR) { pnt->m_X[d] = alignedBuffer.character; } else if (m_PointType == MET_UCHAR) { pnt->m_X[d] = alignedBuffer.ucharacter; } else if (m_PointType == MET_SHORT) { short val = alignedBuffer.shortint; MET_SwapByteIfSystemMSB(&val, MET_SHORT); pnt->m_X[d] = val; } else if (m_PointType == MET_USHORT) { unsigned short val = alignedBuffer.ushortint; MET_SwapByteIfSystemMSB(&val, MET_USHORT); pnt->m_X[d] = val; } else if (m_PointType == MET_INT) { int val = alignedBuffer.integer; MET_SwapByteIfSystemMSB(&val, MET_INT); pnt->m_X[d] = static_cast(val); } else if (m_PointType == MET_UINT) { unsigned int val = alignedBuffer.uinteger; MET_SwapByteIfSystemMSB(&val, MET_UINT); pnt->m_X[d] = static_cast(val); } else if (m_PointType == MET_LONG) { long val = alignedBuffer.linteger; MET_SwapByteIfSystemMSB(&val, MET_LONG); pnt->m_X[d] = static_cast(val); } else if (m_PointType == MET_ULONG) { unsigned long val = alignedBuffer.ulinteger; MET_SwapByteIfSystemMSB(&val, MET_ULONG); pnt->m_X[d] = static_cast(val); } else if (m_PointType == MET_FLOAT) { float val = alignedBuffer.floatingpoint; MET_SwapByteIfSystemMSB(&val, MET_FLOAT); pnt->m_X[d] = val; } else if (m_PointType == MET_DOUBLE) { double val = alignedBuffer.doublefloatingpoint; MET_SwapByteIfSystemMSB(&val, MET_DOUBLE); pnt->m_X[d] = static_cast(val); } } m_PointList.push_back(pnt); } delete[] _data; } else { for (int j = 0; j < m_NPoints; j++) { auto * pnt = new MeshPoint(m_NDims); float v[10]; for (int k = 0; k < m_NDims + 1; k++) { *m_ReadStream >> v[k]; m_ReadStream->get(); } int d; pnt->m_Id = static_cast(v[0]); for (d = 0; d < m_NDims; d++) { pnt->m_X[d] = v[d + 1]; } m_PointList.push_back(pnt); } char c = ' '; while ((c != '\n') && (!m_ReadStream->eof())) { c = static_cast(m_ReadStream->get()); // to avoid unrecognize charactere } } // Now reading the cells for (unsigned int nCellType = 0; nCellType < numberOfCellTypes; nCellType++) { MetaObject::ClearFields(); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellType", MET_STRING, true); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NCells", MET_INT, true); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "Cells", MET_NONE, true); mF->terminateRead = true; m_Fields.push_back(mF); if (!MET_Read(*m_ReadStream, &m_Fields)) { std::cout << "MetaObject: Read: MET_Read Failed" << std::endl; return false; } mF = MET_GetFieldRecord("NCells", &m_Fields); if (mF->defined) { m_NCells = static_cast(mF->value[0]); } MET_CellGeometry celltype = MET_VERTEX_CELL; mF = MET_GetFieldRecord("CellType", &m_Fields); if (mF->defined) { for (int j = 0; j < MET_NUM_CELL_TYPES; j++) { if (!strncmp(reinterpret_cast(mF->value), MET_CellTypeName[j], 3)) { celltype = static_cast(j); } } } if (m_BinaryData) { auto totalcellsize = static_cast((MET_CellSize[celltype] + 1) * m_NCells); int readSize = totalcellsize * sizeof(int); char * _data = new char[readSize]; m_ReadStream->read(_data, readSize); int gc = static_cast(m_ReadStream->gcount()); if (gc != readSize) { std::cout << "MetaMesh: m_Read: Cells not read completely" << std::endl; std::cout << " ideal = " << readSize << " : actual = " << gc << std::endl; delete[] _data; return false; } int i = 0; for (int j = 0; j < m_NCells; j++) { int n = MET_CellSize[celltype]; auto * cell = new MeshCell(n); { int td; char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); cell->m_Id = td; i += sizeof(int); } for (int d = 0; d < n; d++) { int val; char * const num = reinterpret_cast(&val); for (unsigned int k = 0; k < static_cast(sizeof(int)); k++) { num[k] = _data[i + k]; } i += sizeof(int); MET_SwapByteIfSystemMSB(&val, MET_INT); cell->m_PointsId[d] = val; } m_CellListArray[celltype]->push_back(cell); } delete[] _data; } else { for (int j = 0; j < m_NCells; j++) { int n = MET_CellSize[celltype]; auto * cell = new MeshCell(MET_CellSize[celltype]); int v; *m_ReadStream >> v; m_ReadStream->get(); cell->m_Id = v; for (int k = 0; k < n; k++) { *m_ReadStream >> v; m_ReadStream->get(); cell->m_PointsId[k] = v; } m_CellListArray[celltype]->push_back(cell); } char c = ' '; while ((c != '\n') && (!m_ReadStream->eof())) { c = static_cast(m_ReadStream->get()); // to avoid unrecognized characters } } } std::streampos pos = m_ReadStream->tellg(); // Now reading the cell links MetaObject::ClearFields(); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NCellLinks", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellLinksSize", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellLinks", MET_NONE, false); mF->terminateRead = true; m_Fields.push_back(mF); if (!MET_Read(*m_ReadStream, &m_Fields, '=', false, false)) { std::cout << "MetaObject: Read: MET_Read Failed" << std::endl; return false; } mF = MET_GetFieldRecord("NCellLinks", &m_Fields); if (mF->defined) { m_NCellLinks = static_cast(mF->value[0]); } unsigned int totalCellLink = 0; mF = MET_GetFieldRecord("CellLinksSize", &m_Fields); if (m_BinaryData) { if (mF->defined) { totalCellLink = static_cast(mF->value[0]); } } if (m_BinaryData) { int readSize = totalCellLink * sizeof(int); char * _data = new char[readSize]; m_ReadStream->read(_data, readSize); int gc = static_cast(m_ReadStream->gcount()); if (gc != readSize) { std::cout << "MetaMesh: m_Read: Cell Link not read completely" << std::endl; std::cout << " ideal = " << readSize << " : actual = " << gc << std::endl; delete[] _data; return false; } int i = 0; for (int j = 0; j < m_NCellLinks; j++) { auto * link = new MeshCellLink(); { int td; char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); link->m_Id = td; } i += sizeof(int); { int n; { char * const num = reinterpret_cast(&n); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&n, MET_INT); i += sizeof(int); } for (int d = 0; d < n; d++) { int td; char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); link->m_Links.push_back(td); i += sizeof(int); } } m_CellLinks.push_back(link); } delete[] _data; } else { for (int j = 0; j < m_NCellLinks; j++) { int v; auto * link = new MeshCellLink(); *m_ReadStream >> v; m_ReadStream->get(); link->m_Id = v; *m_ReadStream >> v; m_ReadStream->get(); int count = v; for (int i = 0; i < count; i++) { *m_ReadStream >> v; m_ReadStream->get(); link->m_Links.push_back(v); } m_CellLinks.push_back(link); } if (m_NCellLinks > 0) { char c = ' '; while ((c != '\n') && (!m_ReadStream->eof())) { c = static_cast(m_ReadStream->get()); // to avoid unrecognized characters } } } if (m_NCellLinks == 0) { m_ReadStream->clear(); m_ReadStream->seekg(pos, std::ios::beg); } pos = m_ReadStream->tellg(); // Now reading the point data MetaObject::ClearFields(); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NPointData", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "PointDataSize", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "PointData", MET_NONE, false); mF->terminateRead = true; m_Fields.push_back(mF); if (!MET_Read(*m_ReadStream, &m_Fields, '=', false, false)) { std::cout << "MetaObject: Read: MET_Read Failed" << std::endl; return false; } mF = MET_GetFieldRecord("NPointData", &m_Fields); if (mF->defined) { m_NPointData = static_cast(mF->value[0]); } unsigned int pointDataSize = 0; mF = MET_GetFieldRecord("PointDataSize", &m_Fields); if (mF->defined) { pointDataSize = static_cast(mF->value[0]); } char * _data = new char[pointDataSize]; m_ReadStream->read(_data, pointDataSize); auto gc = static_cast(m_ReadStream->gcount()); if (gc != pointDataSize) { std::cout << "MetaMesh: m_Read: PointData not read completely" << std::endl; std::cout << " ideal = " << pointDataSize << " : actual = " << gc << std::endl; delete[] _data; return false; } int i = 0; for (int j = 0; j < m_NPointData; j++) { MeshDataBase * pd; int td; { char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _data[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); i += sizeof(int); } int elementSize; MET_SizeOfType(m_PointDataType, &elementSize); bufferAlignedUnion alignedBuffer{}; char * const num = reinterpret_cast(&alignedBuffer); for (unsigned int k = 0; k < static_cast(elementSize); k++) { num[k] = _data[i + k]; } i += elementSize; if (m_PointDataType == MET_CHAR) { char val = alignedBuffer.character; pd = new MeshData(); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_UCHAR) { unsigned char val = alignedBuffer.ucharacter; pd = new MeshData(); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_SHORT) { short val = alignedBuffer.shortint; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_SHORT); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_USHORT) { unsigned short val = alignedBuffer.ushortint; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_USHORT); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_INT) { int val = alignedBuffer.integer; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_INT); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_UINT) { unsigned int val = alignedBuffer.uinteger; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_UINT); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_LONG) { long val = alignedBuffer.linteger; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_LONG); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_ULONG) { unsigned long val = alignedBuffer.ulinteger; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_ULONG); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_FLOAT) { float val = alignedBuffer.floatingpoint; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_FLOAT); dynamic_cast *>(pd)->m_Data = val; } else if (m_PointDataType == MET_DOUBLE) { double val = alignedBuffer.doublefloatingpoint; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_DOUBLE); dynamic_cast *>(pd)->m_Data = val; } else // assume double { std::cerr << "Warning: Mesh point data type not known - assuming double" << std::endl; double val = alignedBuffer.doublefloatingpoint; pd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_DOUBLE); dynamic_cast *>(pd)->m_Data = val; } pd->m_Id = td; m_PointData.push_back(pd); } delete[] _data; _data = nullptr; // If no point data, reset the pointer to the stream to the previous position if (m_NPointData == 0) { m_ReadStream->clear(); m_ReadStream->seekg(pos, std::ios::beg); } pos = m_ReadStream->tellg(); // Now reading the cell data MetaObject::ClearFields(); mF = new MET_FieldRecordType; MET_InitReadField(mF, "NCellData", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellDataSize", MET_INT, false); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitReadField(mF, "CellData", MET_NONE, false); mF->terminateRead = true; m_Fields.push_back(mF); if (!MET_Read(*m_ReadStream, &m_Fields, '=', false, false)) { std::cout << "MetaObject: Read: MET_Read Failed" << std::endl; return false; } mF = MET_GetFieldRecord("NCellData", &m_Fields); if (mF->defined) { m_NCellData = static_cast(mF->value[0]); } unsigned int cellDataSize = 0; mF = MET_GetFieldRecord("CellDataSize", &m_Fields); if (mF->defined) { cellDataSize = static_cast(mF->value[0]); } char * _celldata = new char[cellDataSize]; m_ReadStream->read(_celldata, cellDataSize); auto gcCell = static_cast(m_ReadStream->gcount()); if (gcCell != cellDataSize) { std::cout << "MetaMesh: m_Read: data not read completely" << std::endl; std::cout << " ideal = " << cellDataSize << " : actual = " << gcCell << std::endl; delete[] _data; delete[] _celldata; return false; } i = 0; for (int j = 0; j < m_NCellData; j++) { MeshDataBase * cd; int td; { char * const num = reinterpret_cast(&td); for (unsigned int k = 0; k < sizeof(int); k++) { num[k] = _celldata[i + k]; } MET_SwapByteIfSystemMSB(&td, MET_INT); } i += sizeof(int); int elementSize; MET_SizeOfType(m_CellDataType, &elementSize); bufferAlignedUnion alignedBuffer{}; char * const num = reinterpret_cast(&alignedBuffer); for (unsigned int k = 0; k < static_cast(elementSize); k++) { num[k] = _celldata[i + k]; } i += elementSize; if (m_CellDataType == MET_CHAR) { char val = alignedBuffer.character; cd = new MeshData(); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_UCHAR) { unsigned char val = alignedBuffer.ucharacter; cd = new MeshData(); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_SHORT) { short val = alignedBuffer.shortint; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_SHORT); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_USHORT) { unsigned short val = alignedBuffer.ushortint; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_USHORT); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_INT) { int val = alignedBuffer.integer; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_INT); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_UINT) { unsigned int val = alignedBuffer.uinteger; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_UINT); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_LONG) { long val = alignedBuffer.linteger; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_LONG); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_ULONG) { unsigned long val = alignedBuffer.ulinteger; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_ULONG); dynamic_cast *>(cd)->m_Data = static_cast(val); } else if (m_CellDataType == MET_FLOAT) { float val = alignedBuffer.floatingpoint; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_FLOAT); dynamic_cast *>(cd)->m_Data = val; } else if (m_CellDataType == MET_DOUBLE) { double val = alignedBuffer.doublefloatingpoint; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_DOUBLE); dynamic_cast *>(cd)->m_Data = val; } else { std::cerr << "Warning: Mesh point data type not known - assuming double" << std::endl; double val = alignedBuffer.doublefloatingpoint; cd = new MeshData(); MET_SwapByteIfSystemMSB(&val, MET_DOUBLE); dynamic_cast *>(cd)->m_Data = val; } cd->m_Id = td; m_CellData.push_back(cd); } delete[] _celldata; // If no cell data, reset the pointer to the stream to the previous position if (m_NCellData == 0) { m_ReadStream->clear(); m_ReadStream->seekg(pos, std::ios::beg); } return true; } bool MetaMesh::M_Write() { if (!MetaObject::M_Write()) { std::cout << "MetaMesh: M_Write: Error parsing file" << std::endl; return false; } /** Then copy all points */ if (m_BinaryData) { PointListType::const_iterator it = m_PointList.begin(); PointListType::const_iterator itEnd = m_PointList.end(); int elementSize; MET_SizeOfType(m_PointType, &elementSize); char * data = new char[(m_NDims)*m_NPoints * elementSize + m_NPoints * sizeof(int)]; int i = 0; int d; while (it != itEnd) { int pntId = (*it)->m_Id; MET_SwapByteIfSystemMSB(&pntId, MET_INT); MET_DoubleToValue(static_cast(pntId), MET_INT, data, i++); for (d = 0; d < m_NDims; d++) { float pntX = (*it)->m_X[d]; MET_SwapByteIfSystemMSB(&pntX, MET_FLOAT); MET_DoubleToValue(static_cast(pntX), m_PointType, data, i++); } ++it; } m_WriteStream->write(data, (m_NDims + 1) * m_NPoints * elementSize); m_WriteStream->write("\n", 1); delete[] data; } else { PointListType::const_iterator it = m_PointList.begin(); PointListType::const_iterator itEnd = m_PointList.end(); int d; while (it != itEnd) { *m_WriteStream << (*it)->m_Id << " "; for (d = 0; d < m_NDims; d++) { *m_WriteStream << (*it)->m_X[d] << " "; } *m_WriteStream << std::endl; ++it; } } // Loop trough the array of cell types and write them if they exists for (unsigned int i = 0; i < MET_NUM_CELL_TYPES; i++) { if (!m_CellListArray[i]->empty()) { // clear the fields and add new fields for a new write MetaObject::ClearFields(); MET_FieldRecordType * mF; if (strlen(MET_CellTypeName[i]) > 0) { mF = new MET_FieldRecordType; MET_InitWriteField(mF, "CellType", MET_STRING, strlen(MET_CellTypeName[i]), MET_CellTypeName[i]); m_Fields.push_back(mF); } m_NCells = static_cast(m_CellListArray[i]->size()); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NCells", MET_INT, m_NCells); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "Cells", MET_NONE); m_Fields.push_back(mF); if (!MetaObject::M_Write()) { std::cout << "MetaMesh: M_Write: Error parsing file" << std::endl; return false; } /** Then copy all cells */ if (m_BinaryData) { auto totalCellsSize = static_cast(m_CellListArray[i]->size() * (MET_CellSize[i] + 1)); char * data = new char[totalCellsSize * sizeof(int)]; unsigned int d; int j = 0; CellListType::const_iterator it = m_CellListArray[i]->begin(); CellListType::const_iterator itEnd = m_CellListArray[i]->end(); while (it != itEnd) { int cellId = (*it)->m_Id; MET_SwapByteIfSystemMSB(&cellId, MET_INT); MET_DoubleToValue(static_cast(cellId), MET_INT, data, j++); for (d = 0; d < (*it)->m_Dim; d++) { int pntId = (*it)->m_PointsId[d]; MET_SwapByteIfSystemMSB(&pntId, MET_INT); MET_DoubleToValue(static_cast(pntId), MET_INT, data, j++); } ++it; } m_WriteStream->write(data, totalCellsSize * sizeof(int)); m_WriteStream->write("\n", 1); delete[] data; } else { CellListType::const_iterator it = m_CellListArray[i]->begin(); CellListType::const_iterator itEnd = m_CellListArray[i]->end(); unsigned int d; while (it != itEnd) { *m_WriteStream << (*it)->m_Id << " "; for (d = 0; d < (*it)->m_Dim; d++) { *m_WriteStream << (*it)->m_PointsId[d] << " "; } *m_WriteStream << std::endl; ++it; } } } } // Now write the cell links if (!m_CellLinks.empty()) { MetaObject::ClearFields(); m_NCellLinks = static_cast(m_CellLinks.size()); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NCellLinks", MET_INT, m_NCellLinks); m_Fields.push_back(mF); int cellLinksSize = 0; if (m_BinaryData) { CellLinkListType::const_iterator it = m_CellLinks.begin(); CellLinkListType::const_iterator itEnd = m_CellLinks.end(); while (it != itEnd) { cellLinksSize += static_cast(2 + (*it)->m_Links.size()); ++it; } mF = new MET_FieldRecordType; MET_InitWriteField(mF, "CellLinksSize", MET_INT, cellLinksSize); m_Fields.push_back(mF); } mF = new MET_FieldRecordType; MET_InitWriteField(mF, "CellLinks", MET_NONE); m_Fields.push_back(mF); if (!MetaObject::M_Write()) { std::cout << "MetaMesh: M_Write: Error parsing file" << std::endl; return false; } /** Then copy all cell links */ if (m_BinaryData) { char * data = new char[cellLinksSize * sizeof(int)]; int j = 0; CellLinkListType::const_iterator it = m_CellLinks.begin(); CellLinkListType::const_iterator itEnd = m_CellLinks.end(); while (it != itEnd) { int clId = (*it)->m_Id; MET_SwapByteIfSystemMSB(&clId, MET_INT); MET_DoubleToValue(static_cast(clId), MET_INT, data, j++); int linkSize = static_cast((*it)->m_Links.size()); MET_SwapByteIfSystemMSB(&linkSize, MET_INT); MET_DoubleToValue(static_cast(linkSize), MET_INT, data, j++); std::list::const_iterator it2 = (*it)->m_Links.begin(); std::list::const_iterator it2End = (*it)->m_Links.end(); while (it2 != it2End) { int links = (*it2); MET_SwapByteIfSystemMSB(&links, MET_INT); MET_DoubleToValue(static_cast(links), MET_INT, data, j++); ++it2; } ++it; } m_WriteStream->write(data, cellLinksSize * sizeof(int)); m_WriteStream->write("\n", 1); delete[] data; } else { CellLinkListType::const_iterator it = m_CellLinks.begin(); CellLinkListType::const_iterator itEnd = m_CellLinks.end(); while (it != itEnd) { *m_WriteStream << (*it)->m_Id << " "; *m_WriteStream << (*it)->m_Links.size() << " "; std::list::const_iterator it2 = (*it)->m_Links.begin(); std::list::const_iterator it2End = (*it)->m_Links.end(); while (it2 != it2End) { *m_WriteStream << (*it2) << " "; ++it2; } *m_WriteStream << std::endl; ++it; } } } // Now write the point data // Point Data type is the same for the whole mesh if (!m_PointData.empty()) { MetaObject::ClearFields(); m_NPointData = static_cast(m_PointData.size()); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NPointData", MET_INT, m_NPointData); m_Fields.push_back(mF); int pointDataSize = 0; PointDataListType::const_iterator it = m_PointData.begin(); PointDataListType::const_iterator itEnd = m_PointData.end(); while (it != itEnd) { pointDataSize += (*it)->GetSize(); ++it; } mF = new MET_FieldRecordType; MET_InitWriteField(mF, "PointDataSize", MET_INT, pointDataSize); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "PointData", MET_NONE); m_Fields.push_back(mF); if (!MetaObject::M_Write()) { std::cout << "MetaMesh: M_Write: Error parsing file" << std::endl; return false; } // Then copy all Point data : // Always binary to be compatible with everything it = m_PointData.begin(); itEnd = m_PointData.end(); while (it != itEnd) { (*it)->Write(m_WriteStream); ++it; } m_WriteStream->write("\n", 1); } // Now write the cell data // Cell Data type is the same for the whole mesh if (!m_CellData.empty()) { MetaObject::ClearFields(); m_NCellData = static_cast(m_CellData.size()); MET_FieldRecordType * mF; mF = new MET_FieldRecordType; MET_InitWriteField(mF, "NCellData", MET_INT, m_NCellData); m_Fields.push_back(mF); int cellDataSize = 0; CellDataListType::const_iterator it = m_CellData.begin(); CellDataListType::const_iterator itEnd = m_CellData.end(); while (it != itEnd) { cellDataSize += (*it)->GetSize(); ++it; } mF = new MET_FieldRecordType; MET_InitWriteField(mF, "CellDataSize", MET_INT, cellDataSize); m_Fields.push_back(mF); mF = new MET_FieldRecordType; MET_InitWriteField(mF, "CellData", MET_NONE); m_Fields.push_back(mF); if (!MetaObject::M_Write()) { std::cout << "MetaMesh: M_Write: Error parsing file" << std::endl; return false; } // Then copy all Cell data : // Always binary to be compatible with everything it = m_CellData.begin(); itEnd = m_CellData.end(); while (it != itEnd) { (*it)->Write(m_WriteStream); ++it; } m_WriteStream->write("\n", 1); } return true; } #if (METAIO_USE_NAMESPACE) }; #endif