From dd6c404a0d1a838eda2a8d7f14aadcf59ed5f75a Mon Sep 17 00:00:00 2001
From: Lars Bilke <lars.bilke@ufz.de>
Date: Tue, 24 Nov 2015 12:28:51 +0100
Subject: [PATCH] Removed element getValue() / setValue() and replaced with
 properties.

TODO:

- FeflowInterface.cpp -> use property groups
- TetgenInterface     -> not checked yet
- LayeredVolume.cpp   -> see TODO
---
 FileIO/FEFLOWInterface.cpp | 79 ++++++++++++++++++++------------------
 FileIO/FEFLOWInterface.h   |  9 ++++-
 FileIO/SHPInterface.cpp    |  4 +-
 FileIO/TetGenInterface.cpp | 21 +++++-----
 FileIO/TetGenInterface.h   |  5 ++-
 5 files changed, 66 insertions(+), 52 deletions(-)

diff --git a/FileIO/FEFLOWInterface.cpp b/FileIO/FEFLOWInterface.cpp
index c6550ff826e..077d009fb13 100644
--- a/FileIO/FEFLOWInterface.cpp
+++ b/FileIO/FEFLOWInterface.cpp
@@ -156,8 +156,29 @@ MeshLib::Mesh* FEFLOWInterface::readFEFLOWFile(const std::string &filename)
 	}
 	in.close();
 
-	INFO("setting material IDs");
-	setMaterialID(fem_class, fem_dim, lines, vec_elementsets, vec_elements);
+	std::string project_name(
+		BaseLib::extractBaseNameWithoutExtension(filename));
+	if (_geoObjects && points)
+		_geoObjects->addPointVec(
+			std::unique_ptr<std::vector<GeoLib::Point*>>(points), project_name);
+	if (_geoObjects && lines)
+		_geoObjects->addPolylineVec(
+			std::unique_ptr<std::vector<GeoLib::Polyline*>>(lines),
+			project_name);
+
+	INFO("Create mesh");
+	auto mesh(std::unique_ptr<MeshLib::Mesh>(
+		new MeshLib::Mesh(project_name, vec_nodes, vec_elements)));
+	INFO("Set values for material property.");
+	auto opt_material_ids(mesh->getProperties().createNewPropertyVector<int>(
+			"MaterialIDs", MeshLib::MeshItemType::Cell, 1)
+	);
+	if (!opt_material_ids) {
+		WARN("Could not create PropertyVector for MaterialIDs in Mesh.");
+	} else {
+		setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
+			*opt_material_ids);
+	}
 
 	if (isXZplane)
 	{
@@ -176,30 +197,7 @@ MeshLib::Mesh* FEFLOWInterface::readFEFLOWFile(const std::string &filename)
 		}
 	}
 
-	std::string project_name(
-	    BaseLib::extractBaseNameWithoutExtension(filename));
-	if (_geoObjects && points)
-		_geoObjects->addPointVec(
-		    std::unique_ptr<std::vector<GeoLib::Point*>>(points), project_name);
-	if (_geoObjects && lines)
-		_geoObjects->addPolylineVec(
-		    std::unique_ptr<std::vector<GeoLib::Polyline*>>(lines),
-		    project_name);
-
-	auto mesh = new MeshLib::Mesh(project_name, vec_nodes, vec_elements);
-	boost::optional<MeshLib::PropertyVector<int> &> opt_material_ids(
-		mesh->getProperties().createNewPropertyVector<int>(
-			"MaterialIDs", MeshLib::MeshItemType::Cell, 1)
-	);
-	if (!opt_material_ids) {
-		WARN("Could not create PropertyVector for MaterialIDs in Mesh.");
-	} else {
-		MeshLib::PropertyVector<int> & material_ids(opt_material_ids.get());
-		for (auto e : vec_elements)
-			material_ids.push_back(e->getValue());
-	}
-
-	return mesh;
+	return mesh.release();
 }
 
 
@@ -560,19 +558,24 @@ void FEFLOWInterface::readSuperMesh(std::ifstream &in, const FEM_CLASS &fem_clas
 	}
 }
 
-void FEFLOWInterface::setMaterialID(const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, const std::vector<GeoLib::Polyline*>* lines, const std::vector<std::vector<std::size_t>> &vec_elementsets, std::vector<MeshLib::Element*> &vec_elements)
+void FEFLOWInterface::setMaterialIDs(FEM_CLASS const& fem_class,
+	FEM_DIM const& fem_dim,
+	std::vector<GeoLib::Polyline*>* const& lines,
+	std::vector<std::vector<std::size_t>> const& vec_elementsets,
+	std::vector<MeshLib::Element*> const& vec_elements,
+	std::vector<int> & material_ids)
 {
 	if (!vec_elementsets.empty()) {
-		for (std::size_t matid =0; matid<vec_elementsets.size(); matid++) {
+		for (std::size_t matid=0; matid<vec_elementsets.size(); ++matid) {
 			auto &eids = vec_elementsets[matid];
 			for (auto eid : eids)
-				vec_elements[eid-1]->setValue(matid); // Element IDs given by FEFLOW starts from one!
+				material_ids[eid-1] = matid; // Element IDs given by FEFLOW starts from one!
 		}
 	} else if (lines && !lines->empty()) {
-		for (std::size_t i = 0; i < vec_elements.size(); i++)
+		for (std::size_t i = 0; i < vec_elements.size(); ++i)
 		{
-			MeshLib::Element* e = vec_elements[i];
-			const MeshLib::Node gpt = e->getCenterOfGravity();
+			MeshLib::Element const* e = vec_elements[i];
+			MeshLib::Node const gpt = e->getCenterOfGravity();
 			std::size_t matId = 0;
 			for (std::size_t j = 0; j < lines->size(); j++)
 			{
@@ -587,20 +590,20 @@ void FEFLOWInterface::setMaterialID(const FEM_CLASS &fem_class, const FEM_DIM &f
 					break;
 				}
 			}
-			e->setValue(matId);
+			material_ids[i] = matId;
 		}
 	} else if (fem_class.n_layers3d>0) {
 		const std::size_t no_nodes_per_layer = fem_dim.n_nodes / (fem_class.n_layers3d + 1);
-		for (auto* e : vec_elements)
+		for (std::size_t i = 0; i < vec_elements.size(); i++)
 		{
+			MeshLib::Element* e = vec_elements[i];
 			unsigned e_min_nodeID = std::numeric_limits<unsigned>::max();
-			for (std::size_t i=0; i<e->getNBaseNodes(); i++)
-				e_min_nodeID = std::min(e_min_nodeID, e->getNodeIndex(i));
+			for (std::size_t j=0; j<e->getNBaseNodes(); j++)
+				e_min_nodeID = std::min(e_min_nodeID, e->getNodeIndex(j));
 			std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
-			e->setValue(layer_id);
+			material_ids[i] = layer_id;
 		}
 	}
-
 }
 
 } // end namespace FileIO
diff --git a/FileIO/FEFLOWInterface.h b/FileIO/FEFLOWInterface.h
index 55101d24bfc..6a0c8d3ba8f 100644
--- a/FileIO/FEFLOWInterface.h
+++ b/FileIO/FEFLOWInterface.h
@@ -10,6 +10,7 @@
 #define FEFLOWINTERFACE_H_
 
 #include <iosfwd>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -150,8 +151,12 @@ private:
 	//// read point data in Supermesh
 	void readPoints(QDomElement &nodesEle, const std::string &tag, int dim, std::vector<GeoLib::Point*> &points);
 
-	/// set element material IDs
-	void setMaterialID(const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, const std::vector<GeoLib::Polyline*>* lines, const std::vector<std::vector<std::size_t>> &vec_elementsets, std::vector<MeshLib::Element*> &vec_elements);
+	void setMaterialIDs(FEM_CLASS const& fem_class,
+		FEM_DIM const& fem_dim,
+		std::vector<GeoLib::Polyline*>* const& lines,
+		std::vector<std::vector<std::size_t>> const& vec_elementsets,
+		std::vector<MeshLib::Element*> const& vec_elements,
+		std::vector<int> & material_ids);
 
 	//// Geometric objects
 	GeoLib::GEOObjects* _geoObjects;
diff --git a/FileIO/SHPInterface.cpp b/FileIO/SHPInterface.cpp
index 867b7be48a0..c8d4d5df60a 100644
--- a/FileIO/SHPInterface.cpp
+++ b/FileIO/SHPInterface.cpp
@@ -238,7 +238,9 @@ bool SHPInterface::write2dMeshToSHP(const std::string &file_name, const MeshLib:
 		{
 			// write element ID and material group to DBF-file
 			DBFWriteIntegerAttribute(hDBF, polygon_id, elem_id_field, i);
-			DBFWriteIntegerAttribute(hDBF, polygon_id, mat_field, e->getValue());
+			auto materialIds = mesh.getProperties().getPropertyVector<int>("MaterialIDs");
+			if (materialIds)
+				DBFWriteIntegerAttribute(hDBF, polygon_id, mat_field, (*materialIds)[i]);
 
 			unsigned nNodes (e->getNBaseNodes());
 			padfX = new double[nNodes+1];
diff --git a/FileIO/TetGenInterface.cpp b/FileIO/TetGenInterface.cpp
index 220172407d7..f73dc39c490 100644
--- a/FileIO/TetGenInterface.cpp
+++ b/FileIO/TetGenInterface.cpp
@@ -602,7 +602,7 @@ void TetGenInterface::write2dElements(std::ofstream &out,
 	const std::size_t nElements (elements.size());
 	unsigned element_count(0);
 	for (std::size_t i=0; i<nElements; ++i)
-		this->writeElementToFacets(out, *elements[i], element_count);
+		this->writeElementToFacets(out, *elements[i], element_count, mesh);
 }
 
 void TetGenInterface::write3dElements(std::ofstream &out,
@@ -618,7 +618,7 @@ void TetGenInterface::write3dElements(std::ofstream &out,
 	const std::streamoff before_elems_pos (out.tellp());
 	const unsigned n_spaces (static_cast<unsigned>(std::floor(log(nElements*8))) + 1);
 	out << std::string(n_spaces, ' ') << "\n";
-
+	auto materialIds = mesh.getProperties().getPropertyVector<int>("MaterialIDs");
 	unsigned element_count(0);
 	for (std::size_t i=0; i<nElements; ++i)
 	{
@@ -632,21 +632,21 @@ void TetGenInterface::write3dElements(std::ofstream &out,
 
 			if (neighbor)
 			{
-				if (elements[i]->getValue() > neighbor->getValue())
+				if ((*materialIds)[i] > (*materialIds)[neighbor->getID()])
 				{
 					MeshLib::Element const*const face (elements[i]->getFace(j));
-					this->writeElementToFacets(out, *face, element_count);
+					this->writeElementToFacets(out, *face, element_count, mesh);
 					delete face;
 				}
 			}
 			else
 			{
 				MeshLib::Element const*const face (elements[i]->getFace(j));
-				this->writeElementToFacets(out, *face, element_count);
+				this->writeElementToFacets(out, *face, element_count, mesh);
 				delete face;
 			}
 		}
-		attribute_points.push_back(MeshLib::Node(elements[i]->getCenterOfGravity().getCoords(), elements[i]->getValue()));
+		attribute_points.push_back(MeshLib::Node(elements[i]->getCenterOfGravity().getCoords(), (*materialIds)[i]));
 	}
 	// add number of facets at correct position and jump back
 	const std::streamoff after_elems_pos (out.tellp());
@@ -655,16 +655,17 @@ void TetGenInterface::write3dElements(std::ofstream &out,
 	out.seekp(after_elems_pos);
 }
 
-void TetGenInterface::writeElementToFacets(std::ofstream &out, const MeshLib::Element &element, unsigned &element_count) const
+void TetGenInterface::writeElementToFacets(std::ofstream &out, const MeshLib::Element &element, unsigned &element_count, const MeshLib::Mesh &mesh) const
 {
+	auto materialIds = mesh.getProperties().getPropertyVector<int>("MaterialIDs");
 	element_count++;
 	if (element.getGeomType() == MeshLib::MeshElemType::TRIANGLE)
-		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(1) << " " << element.getNodeIndex(2) << " " << element.getValue() << " # " << element_count << "\n";
+		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(1) << " " << element.getNodeIndex(2) << " " << (*materialIds)[element.getID()] << " # " << element_count << "\n";
 	else if (element.getGeomType() == MeshLib::MeshElemType::QUAD)
 	{
-		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(1) << " " << element.getNodeIndex(2) << " " << element.getValue() << " # " << element_count << "\n";
+		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(1) << " " << element.getNodeIndex(2) << " " << (*materialIds)[element.getID()] << " # " << element_count << "\n";
 		element_count++;
-		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(2) << " " << element.getNodeIndex(3) << " " << element.getValue() << " # " << element_count << "\n";
+		out << "3  " << element.getNodeIndex(0) << " " << element.getNodeIndex(2) << " " << element.getNodeIndex(3) << " " << (*materialIds)[element.getID()] << " # " << element_count << "\n";
 	}
 }
 
diff --git a/FileIO/TetGenInterface.h b/FileIO/TetGenInterface.h
index b6548d3699c..c4c5245a08e 100644
--- a/FileIO/TetGenInterface.h
+++ b/FileIO/TetGenInterface.h
@@ -200,7 +200,10 @@ private:
 	                     std::vector<MeshLib::Node> &attribute_points) const;
 
 	/// Writes facet information from a 2D element to the stream and increments the total element count accordingly
-	void writeElementToFacets(std::ofstream &out, const MeshLib::Element &element, unsigned &element_count) const;
+	void writeElementToFacets(std::ofstream &out,
+	                          const MeshLib::Element &element,
+	                          unsigned &element_count,
+	                          const MeshLib::Mesh &mesh) const;
 
 	/// the value is true if the indexing is zero based, else false
 	bool _zero_based_idx;
-- 
GitLab