From ab1b5fac9a3d7e37af9175e4138972610b50d92a Mon Sep 17 00:00:00 2001
From: Karsten Rink <karsten.rink@ufz.de>
Date: Wed, 9 May 2012 08:35:12 +0200
Subject: [PATCH] added fileio for reading meshes

---
 FileIO/CMakeLists.txt |  20 ++++
 FileIO/MeshIO.cpp     | 215 ++++++++++++++++++++++++++++++++++++++++++
 FileIO/MeshIO.h       |  54 +++++++++++
 FileIO/Writer.cpp     |  65 +++++++++++++
 FileIO/Writer.h       |  53 +++++++++++
 5 files changed, 407 insertions(+)
 create mode 100644 FileIO/CMakeLists.txt
 create mode 100644 FileIO/MeshIO.cpp
 create mode 100644 FileIO/MeshIO.h
 create mode 100644 FileIO/Writer.cpp
 create mode 100644 FileIO/Writer.h

diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt
new file mode 100644
index 00000000000..fe8840c4524
--- /dev/null
+++ b/FileIO/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Source files
+GET_SOURCE_FILES(SOURCES_FILEIO)
+SET ( SOURCES ${SOURCES_FILEIO})
+
+# Create the library
+ADD_LIBRARY(FileIO STATIC ${SOURCES})
+
+include_directories(
+	.
+	../Base
+	../GeoLib
+	../MathLib
+	../MeshLib
+)
+
+target_link_libraries (FileIO
+	GeoLib
+	MeshLib
+)
+
diff --git a/FileIO/MeshIO.cpp b/FileIO/MeshIO.cpp
new file mode 100644
index 00000000000..5ad1cb2b8c1
--- /dev/null
+++ b/FileIO/MeshIO.cpp
@@ -0,0 +1,215 @@
+/**
+ * MeshIO.cpp
+ *
+ *      Date: 2012/05/08
+ *      Author: KR
+ */
+
+#include "GEOObjects.h"
+#include "MeshIO.h"
+#include "Node.h"
+#include "Elements/Edge.h"
+#include "Elements/Tri.h"
+#include "Elements/Quad.h"
+#include "Elements/Tet.h"
+#include "Elements/Hex.h"
+#include "Elements/Pyramid.h"
+#include "Elements/Prism.h"
+
+#include <iomanip>
+#include <sstream>
+
+namespace FileIO
+{
+
+MeshIO::MeshIO()
+: _mesh(NULL)
+{
+}
+
+MeshLib::Mesh* MeshIO::loadMeshFromFile(const std::string& file_name)
+{
+	std::cout << "Read mesh ... " << std::flush;
+/*
+   #ifndef NDEBUG
+    QTime myTimer;
+    myTimer.start();
+   #endif
+ */
+	std::ifstream in (file_name.c_str(),std::ios::in);
+	if (!in.is_open())
+	{
+		std::cout << "CFEMesh::FEMRead() - Could not open file...\n";
+		return NULL;
+	}
+
+	std::string line_string ("");
+	getline(in, line_string);
+
+	std::vector<MeshLib::Node*> nodes;
+	std::vector<MeshLib::Element*> elements;
+
+	if(line_string.find("#FEM_MSH") != std::string::npos) // OGS mesh file
+	{
+		while (!in.eof())
+		{
+			getline(in, line_string);
+
+			// check keywords
+			if (line_string.find("#STOP") != std::string::npos)
+				break;
+			else if (line_string.find("$NODES") != std::string::npos)
+			{
+				double x, y, z, double_dummy;
+				unsigned nNodes, idx;
+				in >> nNodes >> std::ws;
+				std::string s;
+				std::ios::pos_type position = in.tellg();
+				for (unsigned i = 0; i < nNodes; i++)
+				{
+					in >> idx >> x >> y >> z;
+					MeshLib::Node* node(new MeshLib::Node(x, y, z, nodes.size()));
+					nodes.push_back(node);
+					position = in.tellg();
+					in >> s;
+					if (s.find("$AREA") != std::string::npos)
+						in >> double_dummy;
+					else
+						in.seekg(position, std::ios::beg);
+					in >> std::ws;
+				}
+			}
+			else if (line_string.find("$ELEMENTS") != std::string::npos)
+			{
+				unsigned nElements;
+				in >> nElements >> std::ws;
+				for (unsigned i = 0; i < nElements; i++)
+				{
+					getline(in, line_string);
+					
+					elements.push_back(readElement(line_string, nodes));
+				}
+			}
+		}
+
+		MeshLib::Mesh* mesh (new MeshLib::Mesh(file_name, nodes, elements));
+		std::cout << "Nr. Nodes: " << nodes.size() << std::endl;
+		std::cout << "Nr. Elements: " << elements.size() << std::endl;
+
+		/*
+		   #ifndef NDEBUG
+				std::cout << "Loading time: " << myTimer.elapsed() << " ms" << std::endl;
+		   #endif
+		 */
+		return mesh;
+	}
+	else 
+	{
+		in.close();
+		return NULL;
+	}
+}
+
+MeshLib::Element* MeshIO::readElement(const std::string& line, const std::vector<MeshLib::Node*> &nodes)
+{
+	std::stringstream ss (line);
+	std::string elem_type_str;
+	unsigned index, patch_index;
+	ss >> index >> patch_index >> elem_type_str;
+
+	MshElemType::type elem_type (String2MshElemType(elem_type_str));
+	unsigned* idx = new unsigned[8];
+
+	MeshLib::Element* elem;
+					
+	switch(index)
+	{
+	case MshElemType::LINE:
+		for (int i = 0; i < 2; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Edge(nodes[idx[0]], nodes[idx[1]], patch_index);
+		break;
+	case MshElemType::TRIANGLE:
+		for (int i = 0; i < 3; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Tri(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], patch_index);
+		break;
+	case MshElemType::QUAD:
+		for (int i = 0; i < 4; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Quad(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], patch_index);
+		break;
+	case MshElemType::TETRAHEDRON:
+		for (int i = 0; i < 4; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Tet(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], patch_index);
+		break;
+	case MshElemType::HEXAHEDRON:
+		for (int i = 0; i < 8; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Hex(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], nodes[idx[5]], nodes[idx[6]], nodes[idx[7]], patch_index);
+		break;
+	case MshElemType::PYRAMID:
+		for (int i = 0; i < 5; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Pyramid(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], patch_index);
+		break;
+	case MshElemType::PRISM:
+		for (int i = 0; i < 6; i++)
+			ss >> idx[i];
+		elem = new MeshLib::Prism(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], nodes[idx[5]], patch_index);
+		break;
+	default:
+		elem = NULL;
+	}	
+
+	/*
+		neighbors.resize(nfaces);
+		for (unsigned i = 0; i < nfaces; i++)
+			neighbors[i] = NULL;
+	*/
+
+	return elem;
+}
+
+int MeshIO::write(std::ostream &out)
+{
+	/*
+	if(!_mesh)
+	{
+		std::cout << "OGSMeshIO cannot write: no mesh set!" << std::endl;
+		return 0;
+	}
+
+	setPrecision(9);
+
+	out << "#FEM_MSH" << std::endl;
+
+	out << "$PCS_TYPE" << std::endl << "  " << _mesh->pcs_name << std::endl;
+
+	out << "$NODES" << std::endl << "  ";
+	const size_t n_nodes(_mesh->GetNodesNumber(false));
+	out << n_nodes << std::endl;
+	for (size_t i(0); i < n_nodes; i++)
+	{
+		double const* const coords (_mesh->nod_vector[i]->getData());
+		out << i << " " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl;
+	}
+
+	out << "$ELEMENTS" << std::endl << "  ";
+	writeElementsExceptLines(_mesh->ele_vector, out);
+
+	out << " $LAYER" << std::endl;
+	out << "  ";
+	out << _mesh->_n_msh_layer << std::endl;
+	out << "#STOP" << std::endl;
+	*/
+	return 1;
+}
+
+void MeshIO::setMesh(const MeshLib::Mesh* mesh)
+{
+	_mesh = mesh;
+}
+
+} // end namespace FileIO
diff --git a/FileIO/MeshIO.h b/FileIO/MeshIO.h
new file mode 100644
index 00000000000..57dfceeaf6b
--- /dev/null
+++ b/FileIO/MeshIO.h
@@ -0,0 +1,54 @@
+/**
+ * MeshIO.h
+ *
+ *      Date: 2012/05/08
+ *      Author: KR
+ */
+
+#ifndef MESHIO_H_
+#define MESHIO_H_
+
+#include "Writer.h"
+
+#include <sstream>
+#include <iostream>
+#include <vector>
+
+namespace MeshLib
+{
+	class Mesh;
+	class Node;
+	class Element;
+}
+
+namespace FileIO
+{
+class MeshIO : public Writer
+{
+public:
+	/// Constructor.
+	MeshIO();
+
+	virtual ~MeshIO() {};
+
+	/// Read mesh from file.
+	MeshLib::Mesh* loadMeshFromFile(const std::string& fileName);
+
+	/// Set mesh for writing.
+	void setMesh(const MeshLib::Mesh*  mesh);
+
+protected:
+	/// Write mesh to stream.
+	int write(std::ostream &out);
+
+private:
+	MeshLib::Element* readElement(const std::string& line, const std::vector<MeshLib::Node*> &nodes);
+
+	const MeshLib::Mesh* _mesh;
+
+};  /* class */
+
+} /* namespace */
+
+#endif /* MESHIO_H_ */
+
diff --git a/FileIO/Writer.cpp b/FileIO/Writer.cpp
new file mode 100644
index 00000000000..06f6c8f1429
--- /dev/null
+++ b/FileIO/Writer.cpp
@@ -0,0 +1,65 @@
+/**
+ * \file Writer.cpp
+ * 13/02/2012 LB Initial implementation
+ *
+ * Implementation of the Writer class
+ */
+
+// ** INCLUDES **
+#include "Writer.h"
+
+#include <fstream>
+
+namespace FileIO
+{
+
+Writer::Writer()
+{
+}
+
+std::string Writer::writeToString()
+{
+	// Empty stream and clear error states.
+	_out.str("");
+	_out.clear();
+
+	if (this->write(_out))
+		return _out.str();
+	else
+		return std::string("");
+}
+
+int Writer::writeToFile(std::string const& filename)
+{
+	std::string file_content = this->writeToString();
+	if (!file_content.empty())
+	{
+		std::ofstream fileStream;
+		fileStream.open (filename.c_str());
+
+		// check file stream
+		if (!fileStream)
+		{
+			std::cerr << "Could not open file " << filename << " !" << std::endl;
+			return 0;
+		}
+
+		fileStream << file_content;
+
+		fileStream.close();
+		return 1;
+	}
+	return 0;
+}
+
+void Writer::setPrecision(unsigned int precision)
+{
+	_out.precision(precision);
+}
+
+void Writer::setFormat(std::ios_base::fmtflags flags)
+{
+	_out.setf(flags);
+}
+
+} // namespace FileIO
diff --git a/FileIO/Writer.h b/FileIO/Writer.h
new file mode 100644
index 00000000000..f02dec1591f
--- /dev/null
+++ b/FileIO/Writer.h
@@ -0,0 +1,53 @@
+/**
+ * \file Writer.h
+ * 13/02/2012 LB Initial implementation
+ */
+
+#ifndef WRITER_H
+#define WRITER_H
+
+#include <string>
+#include <iostream>
+#include <sstream>
+
+namespace FileIO
+{
+
+/// @brief Base class which enables writing an object to string, stringstream
+/// or file. Also formatting (precision, scientific notation of decimal values)
+/// can be set.
+///
+/// When subclassing you only need to implement void write(std::ostream& stream).
+class Writer
+{
+public:
+	Writer();
+	virtual ~Writer() {};
+
+	/// @brief Writes the object to a string.
+	std::string writeToString();
+
+	/// @brief Writes the object to the given file.
+	int writeToFile(std::string const& filename);
+
+	/// @brief Sets the decimal precision.
+	void setPrecision(unsigned int precision);
+
+	/// @brief Sets the format (either ios::scientific or ios::fixed);
+	void setFormat(std::ios_base::fmtflags flags);
+
+protected:
+	/// @brief Writes the object to the given stream.
+	/// This method must be implemented by a subclass.
+	virtual int write(std::ostream& stream) = 0;
+
+	/// @brief The stream to write to.
+	std::stringstream _out;
+
+private:
+
+};
+
+} // namespace FileIO
+
+#endif // WRITER_H
-- 
GitLab