From 069afb4a8cc78504956808548562aa2ef5fab166 Mon Sep 17 00:00:00 2001
From: Thomas Fischer <thomas.fischer@ufz.de>
Date: Tue, 18 Sep 2012 10:42:46 +0200
Subject: [PATCH] class TetGenInterface uses now new mesh structures (Node and
 Element) to read TetGen mesh removed unused experimental code for TetGen file
 output

---
 FileIO/MeshIO/TetGenInterface.cpp | 316 ++++++------------------------
 FileIO/MeshIO/TetGenInterface.h   |  24 ++-
 2 files changed, 76 insertions(+), 264 deletions(-)

diff --git a/FileIO/MeshIO/TetGenInterface.cpp b/FileIO/MeshIO/TetGenInterface.cpp
index e0cb783304d..87faa8a7205 100644
--- a/FileIO/MeshIO/TetGenInterface.cpp
+++ b/FileIO/MeshIO/TetGenInterface.cpp
@@ -12,22 +12,22 @@
 #include <cstddef>
 #include <string>
 
-// FileIO
-#include "MeshIO/TetGenInterface.h"
-
-// Base
+// BaseLib
 #include "StringTools.h"
 
-/* TODO6
-// MSH
-#include "msh_elem.h"
-#include "msh_mesh.h"
-#include "msh_node.h"
+// FileIO
+#include "TetGenInterface.h"
+
+// MeshLib
+#include "Mesh.h"
+#include "Node.h"
+#include "Elements/Element.h"
+#include "Elements/Tet.h"
 
 namespace FileIO
 {
 TetGenInterface::TetGenInterface() :
-	_mesh (NULL), _zero_based_idx (false)
+	_nodes(), _elements(), _zero_based_idx (false)
 {
 }
 
@@ -35,153 +35,7 @@ TetGenInterface::~TetGenInterface()
 {
 }
 
-void TetGenInterface::writeTetGenMesh(std::string const& nodes_fname, std::string const& ele_fname,
-				MeshLib::Mesh const* const mesh) const
-{
-	writeTetGenNodes(nodes_fname, mesh);
-	writeTetGenElements(ele_fname, mesh);
-}
-
-void TetGenInterface::writeTetGenNodes(std::string const& nodes_fname, MeshLib::Mesh const*const mesh) const
-{
-	std::ofstream out(nodes_fname.c_str());
-	if (out) {
-		std::vector<MeshLib::CElem*> const& elements(mesh->getElementVector());
-		const size_t n_elements(elements.size());
-		size_t n_prisms(0);
-		for (size_t k(0); k<n_elements; k++) {
-			if (elements[k]->GetElementType() == MshElemType::PRISM) {
-				n_prisms++;
-			}
-		}
-		const size_t n_nodes(mesh->GetNodesNumber(false));
-		out << n_nodes+4*n_prisms << " 3 0 0" << std::endl;
-		std::vector<MeshLib::CNode*> const& nodes(mesh->getNodeVector());
-		for (size_t k(0); k<n_nodes; k++) {
-			double const*const node(nodes[k]->getData());
-			out << k << " " << node[0] << " " << node[1] << " " << node[2] << std::endl;
-		}
-		// write additional nodes for prisms
-		std::vector<size_t> idxs;
-		for (size_t k(0), idx(n_nodes); k<n_elements; k++) {
-			if (elements[k]->GetElementType() == MshElemType::PRISM) {
-				elements[k]->getNodeIndices(idxs);
-				double const*const n0((nodes[idxs[0]])->getData());
-				double const*const n1((nodes[idxs[1]])->getData());
-				double const*const n2((nodes[idxs[2]])->getData());
-				double const*const n3((nodes[idxs[3]])->getData());
-				double const*const n4((nodes[idxs[4]])->getData());
-				double const*const n5((nodes[idxs[5]])->getData());
-
-				idxs.clear();
-
-				// compute centroid of the prism
-				const double centroid[3] = {(n0[0]+n1[0]+n2[0]+n3[0]+n4[0]+n5[0])/6,
-										(n0[1]+n1[1]+n2[1]+n3[1]+n4[1]+n5[1])/6,
-										(n0[2]+n1[2]+n2[2]+n3[2]+n4[2]+n5[2])/6};
-
-				// center of first rectangle surface
-				const double center0[3] = {(n0[0]+n1[0]+n3[0]+n4[0])/4, (n0[1]+n1[1]+n3[1]+n4[1])/4, (n0[2]+n1[2]+n3[2]+n4[2])/4};
-				// center of second rectangle surface
-				const double center1[3] = {(n1[0]+n2[0]+n4[0]+n5[0])/4, (n1[1]+n2[1]+n4[1]+n5[1])/4, (n1[2]+n2[2]+n4[2]+n5[2])/4};
-				// center of third rectangle surface
-				const double center2[3] = {(n0[0]+n2[0]+n3[0]+n5[0])/4, (n0[1]+n2[1]+n3[1]+n5[1])/4, (n0[2]+n2[2]+n3[2]+n5[2])/4};
-
-				out << idx++ << " " << centroid[0] << " " << centroid[1] << " " << centroid[2] << std::endl;
-				out << idx++ << " " << center0[0] << " " << center0[1] << " " << center0[2] << std::endl;
-				out << idx++ << " " << center1[0] << " " << center1[1] << " " << center1[2] << std::endl;
-				out << idx++ << " " << center2[0] << " " << center2[1] << " " << center2[2] << std::endl;
-			}
-		}
-		out.close();
-	} else {
-		std::cout << "cold not open file for writing nodes" << std::endl;
-	}
-}
-
-void TetGenInterface::writeTetGenElements(std::string const& ele_fname, MeshLib::CFEMesh const*const mesh) const
-{
-	std::ofstream out(ele_fname.c_str());
-	if (out) {
-		std::vector<MeshLib::CElem*> const& elements(mesh->getElementVector());
-		const size_t n_elements(elements.size());
-		// count number of prisms, tetrahedras, hexahedras
-		size_t n_prisms(0), n_tets(0), n_hexs(0);
-		for (size_t k(0); k<n_elements; k++) {
-			switch (elements[k]->GetElementType()) {
-			case MshElemType::PRISM:
-				n_prisms++;
-				break;
-			case MshElemType::TETRAHEDRON:
-				n_tets++;
-				break;
-			case MshElemType::HEXAHEDRON:
-				n_hexs++;
-				break;
-			default:
-				std::cout << "count elements - element type not yet supported" << std::endl;
-			} // end case
-		} // end for
-
-		const size_t n_tetrahedras(n_tets+14*n_prisms);
-		const size_t nodes_offset(mesh->GetNodesNumber(false));
-		size_t cnt_prisms(0);
-		std::vector<size_t> idxs; // node indices
-		out << n_tetrahedras << " 4 0 0" << std::endl;
-		for (size_t k(0), cnt(0); k<n_elements; k++) {
-			elements[k]->getNodeIndices(idxs);
-			switch (elements[k]->GetElementType()) {
-			case MshElemType::PRISM:
-			{
-				out << cnt++ << " " << idxs[0] << " " << idxs[1] << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[3] << " " << idxs[5] << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				//
-				out << cnt++ << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				//
-				out << cnt++ << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				//
-				out << cnt++ << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-				out << cnt++ << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4 << std::endl;
-
-				cnt_prisms++;
-
-				break;
-			}
-			case MshElemType::TETRAHEDRON:
-				out << cnt++ << " " << idxs[0] << " " << idxs[1] << " " << idxs[2] << " " << idxs[3] << std::endl;
-				break;
-			case MshElemType::HEXAHEDRON:
-				std::cout << "element type HEXAHEDRON not yet supported" << std::endl;
-				break;
-			case MshElemType::PYRAMID:
-				std::cout << "element type PYRAMID not yet supported" << std::endl;
-				break;
-			case MshElemType::LINE:
-				std::cout << "element type LINE not yet supported" << std::endl;
-				break;
-			case MshElemType::QUAD:
-				std::cout << "element type QUAD not yet supported" << std::endl;
-				break;
-			default:
-				std::cout << "element type not yet supported" << std::endl;
-			} // end case
-			idxs.clear();
-		} // end for
-		out.close();
-	} else {
-		std::cout << "cold not open file for writing elements" << std::endl;
-	}
-}
-
-MeshLib::CFEMesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fname,
+MeshLib::Mesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fname,
                                                    std::string const& ele_fname)
 {
 	std::ifstream ins_nodes (nodes_fname.c_str());
@@ -198,23 +52,27 @@ MeshLib::CFEMesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fnam
 		return NULL;
 	}
 
-	_mesh = new MeshLib::CFEMesh();
-
-	if (!readNodesFromStream (ins_nodes))
-	{
-		delete _mesh;
+	if (!readNodesFromStream (ins_nodes)) {
+		// remove nodes read until now
+		for (std::size_t k(0); k<_nodes.size(); k++) {
+			delete _nodes[k];
+		}
 		return NULL;
 	}
 
-	_mesh->InitialNodesNumber();
-
-	if (!readElementsFromStream (ins_ele))
-	{
-		delete _mesh;
+	if (!readElementsFromStream (ins_ele)) {
+		// remove elements read until now
+		for (std::size_t k(0); k<_elements.size(); k++) {
+			delete _elements[k];
+		}
+		// remove nodes
+		for (std::size_t k(0); k<_nodes.size(); k++) {
+			delete _nodes[k];
+		}
 		return NULL;
 	}
 
-	return _mesh;
+	return new MeshLib::Mesh(nodes_fname, _nodes, _elements);
 }
 
 bool TetGenInterface::readNodesFromStream (std::ifstream &ins)
@@ -266,8 +124,7 @@ bool TetGenInterface::parseNodesFileHeader(std::string &line,
 		n_nodes = str2number<size_t> (line.substr(pos_beg, pos_end - pos_beg));
 	else
 	{
-		std::cout <<
-		"TetGenInterface::parseNodesFileHeader could not correct read TetGen mesh header - number of nodes"
+		std::cout << "TetGenInterface::parseNodesFileHeader could not correct read TetGen mesh header - number of nodes"
 		          << std::endl;
 		return false;
 	}
@@ -294,70 +151,49 @@ bool TetGenInterface::parseNodesFileHeader(std::string &line,
 
 bool TetGenInterface::parseNodes(std::ifstream& ins, size_t n_nodes, size_t dim)
 {
-	size_t pos_beg, pos_end;
+	std::size_t pos_beg, pos_end;
 	std::string line;
 	double* coordinates (static_cast<double*> (alloca (sizeof(double) * dim)));
 
-	for (size_t k(0); k < n_nodes && !ins.fail(); k++)
-	{
-		getline (ins, line);
-		if (!ins.fail())
-		{
-			if (!line.empty())
-			{
+	for (std::size_t k(0); k < n_nodes && !ins.fail(); k++) {
+		getline(ins, line);
+		if (!ins.fail()) {
+			if (!line.empty()) {
 				pos_end = 0;
 				// read id
 				size_t id;
 				pos_beg = line.find_first_not_of(" ", pos_end);
 				pos_end = line.find_first_of(" \n", pos_beg);
-				if (pos_beg != std::string::npos && pos_end != std::string::npos)
-				{
-					id =
-					        str2number<size_t>(line.substr(pos_beg, pos_end -
-					                                       pos_beg));
+				if (pos_beg != std::string::npos && pos_end != std::string::npos) {
+					id = str2number<size_t> (line.substr(pos_beg, pos_end - pos_beg));
 					if (k == 0 && id == 0)
 						_zero_based_idx = true;
-				}
-				else
-				{
-					std::cout << "error reading id of node " << k <<
-					" in TetGenInterface::parseNodes" << std::endl;
+				} else {
+					std::cout << "error reading id of node " << k
+									<< " in TetGenInterface::parseNodes" << std::endl;
 					return false;
 				}
 				// read coordinates
-				for (size_t i(0); i < dim; i++)
-				{
+				for (size_t i(0); i < dim; i++) {
 					pos_beg = line.find_first_not_of(" ", pos_end);
 					pos_end = line.find_first_of(" \n", pos_beg);
-					if (pos_end == std::string::npos)
-						pos_end = line.size();
+					if (pos_end == std::string::npos) pos_end = line.size();
 					if (pos_beg != std::string::npos)
-						coordinates[i] =
-						        str2number<double>(line.substr(pos_beg,
-						                                       pos_end -
-						                                       pos_beg));
-					else
-					{
-						std::cout << "error reading coordinate " << i <<
-						" of node " << k <<
-						" in TetGenInterface::parseNodes" <<
-						std::endl;
+						coordinates[i] = str2number<double> (
+										line.substr(pos_beg, pos_end - pos_beg));
+					else {
+						std::cout << "error reading coordinate " << i << " of node " << k
+										<< " in TetGenInterface::parseNodes" << std::endl;
 						return false;
 					}
 				}
-				if (!_zero_based_idx)
-					id--;
+				if (!_zero_based_idx) id--;
 				// since CFEMesh is our friend we can access private data of mesh
-				_mesh->nod_vector.push_back(new MeshLib::CNode(id, coordinates[0],
-				                                               coordinates[1],
-				                                               coordinates[2]));
+				_nodes.push_back(new MeshLib::Node(coordinates, id));
 				// read attributes and boundary markers ... - at the moment we do not use this information
 			}
-		}
-		else
-		{
-			std::cout << "error reading node " << k <<
-			" in TetGenInterface::parseNodes" << std::endl;
+		} else {
+			std::cout << "error reading node " << k << " in TetGenInterface::parseNodes" << std::endl;
 			return false;
 		}
 	}
@@ -454,11 +290,8 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_
 				pos_beg = line.find_first_not_of(" ", pos_end);
 				pos_end = line.find_first_of(" \n", pos_beg);
 				if (pos_beg != std::string::npos && pos_end != std::string::npos)
-					id =
-					        str2number<size_t>(line.substr(pos_beg, pos_end -
-					                                       pos_beg));
-				else
-				{
+					id = str2number<size_t>(line.substr(pos_beg, pos_end - pos_beg));
+				else {
 					std::cout << "error reading id of tetrahedra " << k <<
 					" in TetGenInterface::parseElements" << std::endl;
 					return false;
@@ -472,54 +305,37 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_
 						pos_end = line.size();
 					if (pos_beg != std::string::npos && pos_end !=
 					    std::string::npos)
-						ids[i] =
-						        str2number<size_t>(line.substr(pos_beg,
-						                                       pos_end -
-						                                       pos_beg));
+						ids[i] = str2number<std::size_t>(line.substr(pos_beg, pos_end - pos_beg));
 					else
 					{
-						std::cout << "error reading node " << i <<
-						" of tetrahedra " << k <<
-						" in TetGenInterface::parseElements" <<
-						std::endl;
+						std::cout << "error reading node " << i << " of tetrahedra " << k <<
+							" in TetGenInterface::parseElements" << std::endl;
 						return false;
 					}
 				}
-				if (!_zero_based_idx)
-				{
+				if (!_zero_based_idx) {
 					id--;
 					for (size_t i(0); i < n_nodes_per_tet; i++)
 						ids[i]--;
 				}
-				// since CFEMesh is our friend we can access private data of mesh
-				MeshLib::CElem* elem (new MeshLib::CElem(id));
-				elem->setElementProperties (MshElemType::TETRAHEDRON, false);
-				std::vector<MeshLib::CNode*> ele_nodes(n_nodes_per_tet);
-				for (size_t i(0); i < n_nodes_per_tet; i++) {
-					ele_nodes[i] = _mesh->nod_vector[ids[i]];
-				}
-				elem->setNodes (ele_nodes);
-				_mesh->ele_vector.push_back(elem);
+
 				// read region attribute - this is something like material group
-				if (region_attribute)
-				{
+				unsigned region (0);
+				if (region_attribute) {
 					pos_beg = line.find_first_not_of(" ", pos_end);
 					pos_end = line.find_first_of(" ", pos_beg);
-					if (pos_end == std::string::npos)
-						pos_end = line.size();
-					if (pos_beg != std::string::npos && pos_end !=
-					    std::string::npos)
-						elem->setPatchIndex (str2number<int>(line.substr(
-						                                             pos_beg,
-						                                             pos_end
-						                                             - pos_beg)));
-					else
-					{
+					if (pos_end == std::string::npos) pos_end = line.size();
+					if (pos_beg != std::string::npos && pos_end != std::string::npos)
+						region = str2number<unsigned> (line.substr(pos_beg, pos_end - pos_beg));
+					else {
 						std::cout << "error reading region attribute of tetrahedra " << k
 										<< " in TetGenInterface::parseElements" << std::endl;
 						return false;
 					}
 				}
+				// insert new element into vector
+				_elements.push_back (new MeshLib::Tet(_nodes[ids[0]], _nodes[ids[1]], _nodes[ids[2]], _nodes[ids[3]], region));
+
 			}
 		}
 		else
@@ -531,6 +347,4 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_
 	return true;
 }
 
-}
-*/
-
+} // end namespace FileIO
diff --git a/FileIO/MeshIO/TetGenInterface.h b/FileIO/MeshIO/TetGenInterface.h
index ef52061de25..d5f621f8dff 100644
--- a/FileIO/MeshIO/TetGenInterface.h
+++ b/FileIO/MeshIO/TetGenInterface.h
@@ -12,9 +12,13 @@
 #ifndef TETGENINTERFACE_H_
 #define TETGENINTERFACE_H_
 
-// forward declaration of mesh class
+#include <vector>
+
+// forward declaration of class Node and Element
 namespace MeshLib
 {
+	class Node;
+	class Element;
 	class Mesh;
 }
 
@@ -29,14 +33,6 @@ public:
 	TetGenInterface();
 	virtual ~TetGenInterface();
 
-	/**
-	 * write a mesh into TetGen mesh file format
-	 * @param nodes_fname
-	 * @param ele_fname
-	 * @param mesh
-	 */
-	void writeTetGenMesh (std::string const& nodes_fname, std::string const& ele_fname, MeshLib::Mesh const*const mesh) const;
-
 	/**
 	 * Method reads the TetGen mesh from node file and element file.
 	 * @param nodes_fname file name of the nodes file
@@ -52,8 +48,6 @@ public:
 	friend class MeshLib::Mesh;
 
 private:
-	void writeTetGenNodes(std::string const& nodes_fname, MeshLib::Mesh const*const mesh) const;
-	void writeTetGenElements(std::string const& ele_fname, MeshLib::Mesh const*const mesh) const;
 	/**
 	 * Method reads the nodes from stream and stores them in the node vector of the mesh class.
 	 * For this purpose it uses methods parseNodesFileHeader() and parseNodes().
@@ -110,9 +104,13 @@ private:
 	                   bool region_attribute);
 
 	/**
-	 * the mesh that is returned if all data is read
+	 * the nodes later on handed over to the mesh are stored in this vector
+	 */
+	std::vector<MeshLib::Node*> _nodes;
+	/**
+	 * the elements (tetrahedrons) later on handed over to the mesh are stored in this vector
 	 */
-	MeshLib::Mesh* _mesh;
+	std::vector<MeshLib::Element*> _elements;
 	/**
 	 * the value is true if the indexing is zero based, else false
 	 */
-- 
GitLab