diff --git a/Gui/DataView/CMakeLists.txt b/Gui/DataView/CMakeLists.txt
index 661fc1fff5528694a73bd868a4028c2caa75b075..21a66b87756a4b3c9e3f9d0845b7a0ebbfc52dc6 100644
--- a/Gui/DataView/CMakeLists.txt
+++ b/Gui/DataView/CMakeLists.txt
@@ -28,7 +28,6 @@ set( SOURCES
 	ModelTreeItem.cpp
 	MeshLayerEditDialog.cpp
 	MshItem.cpp
-	MshLayerMapper.cpp
 	MshModel.cpp
 	MshQualitySelectionDialog.cpp
 	MshTabWidget.cpp
@@ -98,7 +97,6 @@ set( HEADERS
 	GeoTreeItem.h
 	ModelTreeItem.h
 	MshItem.h
-	MshLayerMapper.h
 	ProcessItem.h
 )
 
diff --git a/Gui/DataView/CondFromRasterDialog.cpp b/Gui/DataView/CondFromRasterDialog.cpp
index 538e1b3c4a097a1f5eb63be2893040324f18f781..5c1da975ae053353c3ad963571f73f1c1d0eae13 100644
--- a/Gui/DataView/CondFromRasterDialog.cpp
+++ b/Gui/DataView/CondFromRasterDialog.cpp
@@ -52,15 +52,15 @@ void CondFromRasterDialog::on_selectButton_pressed()
 	QString geotiffExtension("");
 #endif
 	QString fileName = QFileDialog::getOpenFileName(this, "Select raster file",
-					settings.value("lastOpenedConditionsFileDirectory").toString(), QString(
-									"Raster files (*.asc *.grd);;") .arg(geotiffExtension));
+	                                                settings.value("lastOpenedRasterFileDirectory").toString(), 
+	                                                QString("Raster files (*.asc *.grd);;").arg(geotiffExtension));
 
 	if (!fileName.isEmpty())
 	{
 		this->rasterEdit->setText(fileName);
 
-		QDir dir = QDir(fileName);
-		settings.setValue("lastOpenedConditionsFileDirectory", dir.absolutePath());
+		QFileInfo fi(fileName);
+		settings.setValue("lastOpenedRasterFileDirectory", fi.absolutePath());
 	}
 }
 
diff --git a/Gui/DataView/MeshLayerEditDialog.cpp b/Gui/DataView/MeshLayerEditDialog.cpp
index 9db1c4b653222f6239492fc371493e418f5b60e6..5692a07ce325ae833b948273d37df2874fcb4cab 100644
--- a/Gui/DataView/MeshLayerEditDialog.cpp
+++ b/Gui/DataView/MeshLayerEditDialog.cpp
@@ -15,11 +15,15 @@
 
 #include "MeshLayerEditDialog.h"
 
+// ThirdParty/logog
+#include "logog/include/logog.hpp"
+
 #include "OGSError.h"
 #include "StringTools.h"
 #include "Mesh.h"
 
 #include <QCheckBox>
+#include <QFileInfo>
 #include <QFileDialog>
 #include <QPushButton>
 #include <QSettings>
@@ -188,7 +192,7 @@ void MeshLayerEditDialog::accept()
 				const std::string imgPath ( this->_edits[0]->text().toStdString() );
 				const double noDataReplacementValue = this->_noDataReplacementEdit->text().toDouble();
 				if (!imgPath.empty())
-					result = MshLayerMapper::LayerMapping(new_mesh, imgPath, nLayers, 0, noDataReplacementValue);
+					result = MeshLayerMapper::LayerMapping(*new_mesh, imgPath, nLayers, 0, noDataReplacementValue);
 			}
 			else
 			{
@@ -197,12 +201,11 @@ void MeshLayerEditDialog::accept()
 				{
 					// "100" is just a default size to have any value for extruding 2D elements.
 					// The actual mapping based on a raster file will be performed later.
-					float thickness = (_use_rasters) ? 100 : (this->_edits[i]->text().toFloat());
-					if (thickness > std::numeric_limits<float>::epsilon())
-						layer_thickness.push_back(thickness);
+					const float thickness = (_use_rasters) ? 100 : (this->_edits[i]->text().toFloat());
+					layer_thickness.push_back(thickness);
 				}
 
-				new_mesh = MshLayerMapper::CreateLayers(_msh, layer_thickness);
+				new_mesh = MeshLayerMapper::CreateLayers(*_msh, layer_thickness);
 
 				if (_use_rasters)
 				{
@@ -212,13 +215,13 @@ void MeshLayerEditDialog::accept()
 						const double noDataReplacement = (i==0) ? 0.0 : -9999.0;
 						if (!imgPath.empty())
 						{
-							result = MshLayerMapper::LayerMapping(new_mesh, imgPath, nLayers, i, noDataReplacement);
+							result = MeshLayerMapper::LayerMapping(*new_mesh, imgPath, nLayers, i, noDataReplacement);
 							if (result==0) break;
 						}
 					}
 					if (this->_edits[0]->text().length()>0)
 					{
-						MeshLib::Mesh* final_mesh = MshLayerMapper::blendLayersWithSurface(new_mesh, nLayers, this->_edits[0]->text().toStdString());
+						MeshLib::Mesh* final_mesh = MeshLayerMapper::blendLayersWithSurface(*new_mesh, nLayers, this->_edits[0]->text().toStdString());
 						delete new_mesh;
 						new_mesh = final_mesh;
 					}
@@ -250,9 +253,9 @@ void MeshLayerEditDialog::getFileName()
 	QPushButton* button = dynamic_cast<QPushButton*>(this->sender());
 	QSettings settings;
 	QString filename = QFileDialog::getOpenFileName(this, "Select raster file to open",
-	                                                settings.value("lastOpenedFileDirectory").toString(),
+	                                                settings.value("lastOpenedRasterFileDirectory").toString(),
 	                                                "ASCII raster files (*.asc);;All files (* *.*)");
 	_fileButtonMap[button]->setText(filename);
-	QDir dir = QDir(filename);
-	settings.setValue("lastOpenedFileDirectory", dir.absolutePath());
+	QFileInfo fi(filename);
+	settings.setValue("lastOpenedRasterFileDirectory", fi.absolutePath());
 }
diff --git a/Gui/DataView/MeshLayerEditDialog.h b/Gui/DataView/MeshLayerEditDialog.h
index 1b02632fb182eced09000282a8ec44f8d92e767e..89fabac92366e00ed6a5e243e4f2f92d362ffa1c 100644
--- a/Gui/DataView/MeshLayerEditDialog.h
+++ b/Gui/DataView/MeshLayerEditDialog.h
@@ -18,7 +18,7 @@
 #include "ui_MeshLayerEdit.h"
 #include <QDialog>
 
-#include "MshLayerMapper.h"
+#include "MeshGenerators/MeshLayerMapper.h"
 
 class QPushButton;
 class QCheckBox;
diff --git a/MathLib/MathTools.cpp b/MathLib/MathTools.cpp
index 7de70163cbea2329342798b05848b02c8f505e3c..651fa75369b10a4218753378150339db1694d346 100644
--- a/MathLib/MathTools.cpp
+++ b/MathLib/MathTools.cpp
@@ -86,13 +86,4 @@ double calcTetrahedronVolume(const double* x1, const double* x2, const double* x
 	          + (x1[2] - x4[2]) * ((x2[0] - x4[0]) * (x3[1] - x4[1]) - (x2[1] - x4[1]) * (x3[0] - x4[0]))) / 6.0;
 }
 
-void MPhi2D(double* vf, double r, double s)
-{
-	vf[0] = (1.0 + r) * (1.0 + s);
-	vf[1] = (1.0 - r) * (1.0 + s);
-	vf[2] = (1.0 - r) * (1.0 - s);
-	vf[3] = (1.0 + r) * (1.0 - s);
-	for (unsigned i = 0; i < 4; i++)
-		vf[i] *= 0.25;
-}
 } // namespace
diff --git a/MathLib/MathTools.h b/MathLib/MathTools.h
index f205d25b598c700d82d2edbdf60929117d9c3f22..585d141b14c405b6143eeb70d2ac50a59fc559ab 100644
--- a/MathLib/MathTools.h
+++ b/MathLib/MathTools.h
@@ -177,8 +177,6 @@ T fastpow (T base, std::size_t exp)
 	return result;
 }
 
-/// 2D linear interpolation function (TODO adopted from geo_mathlib)
-void MPhi2D(double* vf, double r, double s);
 } // namespace
 
 #endif /* MATHTOOLS_H_ */
diff --git a/Gui/DataView/MshLayerMapper.cpp b/MeshLib/MeshGenerators/MeshLayerMapper.cpp
similarity index 50%
rename from Gui/DataView/MshLayerMapper.cpp
rename to MeshLib/MeshGenerators/MeshLayerMapper.cpp
index 24b3731ffdabcfe21321966ed758c29973f0a686..ffaa8c575c49c79e4ee86c3cdcfb420921170ebf 100644
--- a/Gui/DataView/MshLayerMapper.cpp
+++ b/MeshLib/MeshGenerators/MeshLayerMapper.cpp
@@ -1,8 +1,8 @@
 /**
- * \file
+ * \file   MeshLayerMapper.cpp
  * \author Karsten Rink
  * \date   2010-11-01
- * \brief  Implementation of the MshLayerMapper class.
+ * \brief  Implementation of the MeshLayerMapper class.
  *
  * \copyright
  * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
@@ -18,7 +18,7 @@
 // ThirdParty/logog
 #include "logog/include/logog.hpp"
 
-#include "MshLayerMapper.h"
+#include "MeshLayerMapper.h"
 // GeoLib
 #include "Raster.h"
 
@@ -33,199 +33,182 @@
 #include "MathTools.h"
 
 
-MeshLib::Mesh* MshLayerMapper::CreateLayers(const MeshLib::Mesh* mesh, const std::vector<float> &thickness)
+MeshLib::Mesh* MeshLayerMapper::CreateLayers(const MeshLib::Mesh &mesh, const std::vector<float> &layer_thickness_vector)
 {
-	std::size_t nLayers(thickness.size());
-	bool throw_error(false);
-	for (unsigned i=0; i<nLayers; ++i)
-		if (thickness[i]<=0)
-			throw_error = true;
-	if (nLayers < 1 || mesh->getDimension() != 2)
-		throw_error = true;
-
-	if (throw_error)
+	std::vector<float> thickness;
+	for (std::size_t i=0; i<layer_thickness_vector.size(); ++i)
+		if (layer_thickness_vector[i] > std::numeric_limits<float>::epsilon())
+			thickness.push_back(layer_thickness_vector[i]);
+		else
+			WARN ("Ignoring layer %d with thickness %f.", i, layer_thickness_vector[i]);
+
+	const std::size_t nLayers(thickness.size());
+	if (nLayers < 1 || mesh.getDimension() != 2)
 	{
 		ERR("MshLayerMapper::CreateLayers(): A 2D mesh with nLayers > 0 is required as input.");
 		return nullptr;
 	}
 
-	const size_t nNodes = mesh->getNNodes();
+	const size_t nNodes = mesh.getNNodes();
 	// count number of 2d elements in the original mesh
-	const std::size_t nElems (std::count_if(mesh->getElements().begin(), mesh->getElements().end(),
+	const std::size_t nElems (std::count_if(mesh.getElements().begin(), mesh.getElements().end(),
 			[](MeshLib::Element const* elem) { return (elem->getDimension() == 2);}));
 
-	const std::vector<MeshLib::Node*> nodes = mesh->getNodes();
-	const std::vector<MeshLib::Element*> elems = mesh->getElements();
-	std::vector<MeshLib::Node*> new_nodes(nNodes + (nLayers * nNodes));
-	std::vector<MeshLib::Element*> new_elems(nElems * nLayers);
-	double z_offset(0.0);
+	const std::size_t nOrgElems (mesh.getNElements());
+	const std::vector<MeshLib::Node*> &nodes = mesh.getNodes();
+	const std::vector<MeshLib::Element*> &elems = mesh.getElements();
+	std::vector<MeshLib::Node*> new_nodes;
+	new_nodes.reserve(nNodes + (nLayers * nNodes));
+	std::vector<MeshLib::Element*> new_elems;
+	new_elems.reserve(nElems * nLayers);
+	double z_offset (0.0);
 
 	for (unsigned layer_id = 0; layer_id <= nLayers; ++layer_id)
 	{
 		// add nodes for new layer
 		unsigned node_offset (nNodes * layer_id);
-		unsigned elem_offset (nElems * (layer_id-1));
-		if (layer_id>0) z_offset += thickness[layer_id-1];
+		if (layer_id > 0) z_offset += thickness[layer_id-1];
 		for (unsigned i = 0; i < nNodes; ++i)
 		{
 			const double* coords = nodes[i]->getCoords();
-			new_nodes[node_offset+i] = new MeshLib::Node(coords[0], coords[1], coords[2]-z_offset, node_offset+i);
+			new_nodes.push_back (new MeshLib::Node(coords[0], coords[1], coords[2]-z_offset, node_offset+i));
 		}
 
 		// starting with 2nd layer create prism or hex elements connecting the last layer with the current one
+		const unsigned elem_offset (nElems * (layer_id-1));
 		if (layer_id > 0)
 		{
-			if (thickness[layer_id-1] > 0)
+			node_offset -= nNodes;
+			const unsigned mat_id (nLayers - layer_id);
+
+			for (unsigned i = 0; i < nOrgElems; ++i)
 			{
-				node_offset -= nNodes;
-				const unsigned mat_id (nLayers - layer_id);
+				const MeshLib::Element* sfc_elem( elems[i] );
+				if (sfc_elem->getDimension() != 2)
+				{
+					WARN("MshLayerMapper::CreateLayers() - Method can only handle 2D mesh elements.");
+					WARN("Skipping Element %d of type \"%s\".", i, MeshElemType2String(sfc_elem->getGeomType()).c_str());
+					continue;
+				}
+				
+				const unsigned nElemNodes(sfc_elem->getNNodes());
+				MeshLib::Node** e_nodes = new MeshLib::Node*[2*nElemNodes];
 
-				// counts the 2d elements (within the layer),
-				// used as a part of index computation in new_elems
-				std::size_t cnt(0);
-				for (unsigned i = 0; i < mesh->getNElements(); ++i)
+				for (unsigned j=0; j<nElemNodes; ++j)
 				{
-					const MeshLib::Element* sfc_elem( elems[i] );
-					if (sfc_elem->getDimension() == 2)
-					{
-						const unsigned nElemNodes(sfc_elem->getNNodes());
-						MeshLib::Node** e_nodes = new MeshLib::Node*[2*nElemNodes];
-
-						for (unsigned j=0; j<nElemNodes; ++j)
-						{
-							const unsigned node_id = sfc_elem->getNode(j)->getID() + node_offset;
-							e_nodes[j] = new_nodes[node_id+nNodes];
-							e_nodes[j+nElemNodes] = new_nodes[node_id];
-						}
-						if (sfc_elem->getGeomType() == MeshElemType::TRIANGLE)	// extrude triangles to prism
-							new_elems[elem_offset+cnt] = new MeshLib::Prism(e_nodes, mat_id);
-						else if (sfc_elem->getGeomType() == MeshElemType::QUAD)	// extrude quads to hexes
-							new_elems[elem_offset+cnt] = new MeshLib::Hex(e_nodes, mat_id);
-						cnt++;
-					}
-					else
-					{
-						WARN("MshLayerMapper::CreateLayers() - Method can only handle 2D mesh elements.");
-						WARN("Skipping Element %d of type \"%s\".", i, MeshElemType2String(sfc_elem->getGeomType()).c_str());
-					}
+					const unsigned node_id = sfc_elem->getNode(j)->getID() + node_offset;
+					e_nodes[j] = new_nodes[node_id+nNodes];
+					e_nodes[j+nElemNodes] = new_nodes[node_id];
 				}
-			}
-			else
-			{
-				ERR("Error in MshLayerMapper::CreateLayers() - Layer thickness for layer %d is %f (needs to be >0).", (layer_id-1), thickness[layer_id-1]);
-				return nullptr;
+				if (sfc_elem->getGeomType() == MeshElemType::TRIANGLE)	// extrude triangles to prism
+					new_elems.push_back (new MeshLib::Prism(e_nodes, mat_id));
+				else if (sfc_elem->getGeomType() == MeshElemType::QUAD)	// extrude quads to hexes
+					new_elems.push_back (new MeshLib::Hex(e_nodes, mat_id));
 			}
 		}
 	}
 	return new MeshLib::Mesh("SubsurfaceMesh", new_nodes, new_elems);
 }
 
-int MshLayerMapper::LayerMapping(MeshLib::Mesh* new_mesh, const std::string &rasterfile,
+int MeshLayerMapper::LayerMapping(MeshLib::Mesh &new_mesh, const std::string &rasterfile,
                                  const unsigned nLayers, const unsigned layer_id, double noDataReplacementValue = 0.0)
 {
-	if (new_mesh == nullptr)
+	if (nLayers < layer_id)
 	{
-		ERR("MshLayerMapper::LayerMapping() - Passed Mesh is NULL.");
+		ERR("MshLayerMapper::LayerMapping() - Mesh has only %d Layers, cannot assign layer %d.", nLayers, layer_id);
 		return 0;
 	}
 
-	if (nLayers >= layer_id)
+	const GeoLib::Raster *raster(GeoLib::Raster::getRasterFromASCFile(rasterfile));
+	if (! raster) {
+		ERR("MshLayerMapper::LayerMapping - could not read raster file %s", rasterfile.c_str());
+		return 0;
+	}
+	const double x0(raster->getOrigin()[0]);
+	const double y0(raster->getOrigin()[1]);
+	const double delta(raster->getRasterPixelDistance());
+	const double no_data(raster->getNoDataValue());
+	const std::size_t width(raster->getNCols());
+	const std::size_t height(raster->getNRows());
+	double const*const elevation(raster->begin());
+
+	const std::pair<double, double> xDim(x0, x0 + width * delta); // extension in x-dimension
+	const std::pair<double, double> yDim(y0, y0 + height * delta); // extension in y-dimension
+
+	const size_t nNodes (new_mesh.getNNodes());
+	const size_t nNodesPerLayer (nNodes / (nLayers+1));
+
+	const size_t firstNode (layer_id * nNodesPerLayer);
+	const size_t lastNode  (firstNode + nNodesPerLayer);
+
+	const double half_delta = 0.5*delta;
+	const std::vector<MeshLib::Node*> &nodes = new_mesh.getNodes();
+	for (unsigned i = firstNode; i < lastNode; ++i)
 	{
-		GeoLib::Raster *raster(GeoLib::Raster::getRasterFromASCFile(rasterfile));
-		if (! raster) {
-			ERR("MshLayerMapper::LayerMapping - could not read raster file %s", rasterfile.c_str());
-			return 0;
-		}
-		const double x0(raster->getOrigin()[0]);
-		const double y0(raster->getOrigin()[1]);
-		const double delta(raster->getRasterPixelDistance());
-		const double no_data(raster->getNoDataValue());
-		const std::size_t width(raster->getNCols());
-		const std::size_t height(raster->getNRows());
-		double const*const elevation(raster->begin());
-
-		const std::pair<double, double> xDim(x0, x0 + width * delta); // extension in x-dimension
-		const std::pair<double, double> yDim(y0, y0 + height * delta); // extension in y-dimension
+		const double* coords (nodes[i]->getCoords());
 
-		const size_t nNodes = new_mesh->getNNodes();
-		const size_t nNodesPerLayer = nNodes / (nLayers+1);
-
-		const size_t firstNode = layer_id * nNodesPerLayer;
-		const size_t lastNode  = firstNode + nNodesPerLayer;
-
-		const double half_delta = 0.5*delta;
-		const std::vector<MeshLib::Node*> nodes = new_mesh->getNodes();
-		for (unsigned i = firstNode; i < lastNode; ++i)
+		if (!isNodeOnRaster(*nodes[i], xDim, yDim))
 		{
-			const double* coords = nodes[i]->getCoords();
+			// use either default value or elevation from layer above
+			const double new_elevation = (layer_id == 0) ? noDataReplacementValue : (*nodes[i-nNodesPerLayer])[2];
+			nodes[i]->updateCoordinates(coords[0], coords[1], noDataReplacementValue);
+			continue;
+		}
 
-			if (!isNodeOnRaster(*nodes[i], xDim, yDim))
+		// position in raster
+		const double xPos ((coords[0] - xDim.first) / delta);
+		const double yPos ((coords[1] - yDim.first) / delta);
+		// raster cell index
+		const size_t xIdx (static_cast<size_t>(floor(xPos)));
+		const size_t yIdx (static_cast<size_t>(floor(yPos)));
+
+		// weights for bilinear interpolation		
+		const double xShift = fabs(xPos-(xIdx+half_delta))/delta;
+		const double yShift = fabs(yPos-(yIdx+half_delta))/delta;
+		std::array<double,4> weight = { (1-xShift)*(1-xShift), xShift*(1-yShift), xShift*yShift, (1-xShift)*yShift };
+
+		// neightbors to include in interpolation
+		const int xShiftIdx = (xPos-xIdx-half_delta>=0) ? 1 : -1;
+		const int yShiftIdx = (yPos-yIdx-half_delta>=0) ? 1 : -1;
+		const std::array<int,4> x_nb = { 0, xShiftIdx, xShiftIdx, 0 };
+		const std::array<int,4> y_nb = { 0, 0, yShiftIdx, yShiftIdx };
+
+		// get pixel values
+		std::array<double,4>  pix_val;
+		unsigned no_data_count (0);
+		for (unsigned j=0; j<4; ++j)
+		{
+			pix_val[j] = elevation[(yIdx + y_nb[j])*width + (xIdx + x_nb[j])];
+			if (fabs(pix_val[j] - no_data) < std::numeric_limits<double>::epsilon())
 			{
-				if (layer_id == 0) // use default value
-					nodes[i]->updateCoordinates(coords[0], coords[1], noDataReplacementValue);
-				else // use z-value from layer above
-					nodes[i]->updateCoordinates(coords[0], coords[1], (*nodes[i-nNodesPerLayer])[2]);
-				continue;
+				weight[j] = 0;
+				no_data_count++;
 			}
+		}
 
-			// position in raster
-			const double xPos ((coords[0] - xDim.first) / delta);
-			const double yPos ((coords[1] - yDim.first) / delta);
-			// raster cell index
-			const size_t xIdx (static_cast<size_t>(floor(xPos)));
-			const size_t yIdx (static_cast<size_t>(floor(yPos)));
-
-			// deviation of mesh node from centre of raster cell ( in [-1:1) because it is normalised by delta/2 )
-			const double xShift = (xPos-xIdx-half_delta)/half_delta;
-			const double yShift = (yPos-yIdx-half_delta)/half_delta;
-
-			const int xShiftIdx = static_cast<int>((xShift>=0) ? ceil(xShift) : floor(xShift));
-			const int yShiftIdx = static_cast<int>((yShift>=0) ? ceil(yShift) : floor(yShift));
-
-			// determining the neighbouring pixels that add weight to the interpolation
-			const int x_nb[4] = {0, xShiftIdx, xShiftIdx, 0};
-			const int y_nb[4] = {0, 0, yShiftIdx, yShiftIdx};
-
-			double locZ[4];
-			locZ[0] = elevation[yIdx*width + xIdx];
-			if (fabs(locZ[0] - no_data) > std::numeric_limits<double>::epsilon())
-			{
-				for (unsigned j=1; j<4; ++j)
-				{
-					locZ[j] = elevation[(yIdx+y_nb[j])*width + (xIdx+x_nb[j])];
-					if (fabs(locZ[j] - no_data) < std::numeric_limits<double>::epsilon())
-						locZ[j]=locZ[0];
-				}
-
-				double ome[4];
-				double xi = 1-fabs(xShift);
-				double eta = 1-fabs(xShift);
-				MathLib::MPhi2D(ome, xi, eta);
-
-				double z(0.0);
-				for(unsigned j = 0; j < 4; ++j)
-					z += ome[j] * locZ[j];
-
-				nodes[i]->updateCoordinates(coords[0], coords[1], z);
-			}
-			else
+		// adjust weights if necessary
+		if (no_data_count > 0)
+		{
+			if (no_data_count == 4) // if there is absolutely no data just use the default value
 			{
-				if (layer_id == 0) // use default value
-					nodes[i]->updateCoordinates(coords[0], coords[1], noDataReplacementValue);
-				else // use z-value from layer above
-					nodes[i]->updateCoordinates(coords[0], coords[1], (*nodes[i-nNodesPerLayer])[2]);
+				const double new_elevation = (layer_id == 0) ? noDataReplacementValue : (*nodes[i-nNodesPerLayer])[2];
+				nodes[i]->updateCoordinates(coords[0], coords[1], noDataReplacementValue);
+				continue;
 			}
+			const double norm = 4/(4-no_data_count);
+			std::for_each(weight.begin(), weight.end(), [&norm](double &val){val*=norm;});
 		}
 
-		delete raster;
-		return 1;
+		// new value
+		double z = MathLib::scalarProduct<double,4>(weight.data(), pix_val.data());
+		nodes[i]->updateCoordinates(coords[0], coords[1], z);
 	}
-	else
-		ERR("MshLayerMapper::LayerMapping() - Mesh has only %d Layers, cannot assign layer %d.", nLayers, layer_id);
-	return 0;
+
+	delete raster;
+	return 1;
 }
 
-bool MshLayerMapper::isNodeOnRaster(const MeshLib::Node &node,
+bool MeshLayerMapper::isNodeOnRaster(const MeshLib::Node &node,
                                     const std::pair<double, double> &xDim,
                                     const std::pair<double, double> &yDim)
 {
@@ -235,16 +218,16 @@ bool MshLayerMapper::isNodeOnRaster(const MeshLib::Node &node,
 	return true;
 }
 
-MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const unsigned nLayers, const std::string &dem_raster)
+MeshLib::Mesh* MeshLayerMapper::blendLayersWithSurface(MeshLib::Mesh &mesh, const unsigned nLayers, const std::string &dem_raster)
 {
 	// construct surface mesh from DEM
 	const MathLib::Vector3 dir(0,0,1);
-	MeshLib::Mesh* dem = MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh, dir);
-	MshLayerMapper::LayerMapping(dem, dem_raster, 0, 0);
-	const std::vector<MeshLib::Node*> dem_nodes (dem->getNodes());
+	MeshLib::Mesh* dem = MeshLib::MeshSurfaceExtraction::getMeshSurface(mesh, dir);
+	MeshLayerMapper::LayerMapping(*dem, dem_raster, 0, 0);
+	const std::vector<MeshLib::Node*> &dem_nodes (dem->getNodes());
 
-	const std::vector<MeshLib::Node*> mdl_nodes (mesh->getNodes());
-	const size_t nNodes = mesh->getNNodes();
+	const std::vector<MeshLib::Node*> &mdl_nodes (mesh.getNodes());
+	const size_t nNodes (mesh.getNNodes());
 	const size_t nNodesPerLayer = nNodes / (nLayers+1);
 	std::vector<bool> is_surface_node(nNodes, false);
 	std::vector<bool> nodes_below_surface(nNodes, false);
@@ -268,7 +251,7 @@ MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const
 	// if node < dem-node: do nothing
 	// if node > dem-node:
 	//		if first node above surface: map to dem and mark as surface node
-	//		else remove node (i.e. don't copy them)
+	//		else remove node (i.e. don't copy it)
 	for (int layer_id=nLayers-1; layer_id>=0; --layer_id)
 	{
 		const size_t firstNode = layer_id * nNodesPerLayer;
@@ -292,6 +275,8 @@ MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const
 			}
 		}
 	}
+	delete dem; // no longer needed
+
 	// copy valid nodes to new node vector
 	std::vector<MeshLib::Node*> new_nodes;
 	std::vector<int> node_index_map(nNodes, -1);
@@ -304,8 +289,8 @@ MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const
 		}
 
 	// copy elements (old elements need to have at least 4 nodes remaining and form a 3d element
-	const std::vector<MeshLib::Element*> mdl_elements (mesh->getElements());
-	const size_t nElems = mesh->getNElements();
+	const std::vector<MeshLib::Element*> &mdl_elements (mesh.getElements());
+	const size_t nElems (mesh.getNElements());
 	std::vector<MeshLib::Element*> new_elements;
 	for (unsigned j=0; j<nElems; ++j)
 	{
@@ -332,7 +317,7 @@ MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const
 				if (!nodes_below_surface[elem->getNode(i)->getID()])
 					top_idx = i-3;
 
-			// construct pyrmid element based on missing node
+			// construct pyramid element based on missing node
 			unsigned idx1 ((top_idx+1)%3);
 			unsigned idx2 ((top_idx+2)%3);
 			e_nodes[0] = new_nodes[node_index_map[elem->getNode(idx1)->getID()]];
diff --git a/Gui/DataView/MshLayerMapper.h b/MeshLib/MeshGenerators/MeshLayerMapper.h
similarity index 81%
rename from Gui/DataView/MshLayerMapper.h
rename to MeshLib/MeshGenerators/MeshLayerMapper.h
index 6f483272ed3e1d47aed1a48bcb098e41ae1ea056..bcbd9a7da94e38a561fa583aec776ed439c7115d 100644
--- a/Gui/DataView/MshLayerMapper.h
+++ b/MeshLib/MeshGenerators/MeshLayerMapper.h
@@ -1,8 +1,8 @@
 /**
- * \file
+ * \file   MeshLayerMapper.h
  * \author Karsten Rink
  * \date   2010-11-01
- * \brief  Definition of the MshLayerMapper class.
+ * \brief  Definition of the MeshLayerMapper class.
  *
  * \copyright
  * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
@@ -12,8 +12,8 @@
  *
  */
 
-#ifndef MSHLAYERMAPPER_H
-#define MSHLAYERMAPPER_H
+#ifndef MESHLAYERMAPPER_H
+#define MESHLAYERMAPPER_H
 
 #include <string>
 
@@ -27,11 +27,11 @@ namespace MeshLib {
 /**
  * \brief Manipulating and adding layers to an existing mesh
  */
-class MshLayerMapper
+class MeshLayerMapper
 {
 public:
-	MshLayerMapper() {}
-	~MshLayerMapper() {}
+	MeshLayerMapper() {}
+	~MeshLayerMapper() {}
 
 	/**
 	 * Based on a triangle-or quad mesh this method creates a 3D mesh with with a given number of prism- or hex-layers
@@ -40,13 +40,13 @@ public:
 	 * \param thickness The thickness of each of these newly added layers
 	 * \return A mesh with the requested number of layers of prism/hex elements
 	 */
-	static MeshLib::Mesh* CreateLayers(const MeshLib::Mesh* mesh, const std::vector<float> &thickness);
+	static MeshLib::Mesh* CreateLayers(const MeshLib::Mesh &mesh, const std::vector<float> &layer_thickness_vector);
 
 	/**
 	 * Maps the z-values of nodes in the designated layer of the given mesh according to the given raster.
 	 * Note: This only results in a valid mesh if the layers don't intersect each other.
 	 */
-	static int LayerMapping(MeshLib::Mesh* msh, const std::string &rasterfile,
+	static int LayerMapping(MeshLib::Mesh &mesh, const std::string &rasterfile,
                             const unsigned nLayers, const unsigned layer_id, double noDataReplacementValue);
 
 	/**
@@ -55,7 +55,7 @@ public:
 	 * remedied at the end of method upon creating the actual mesh from the new node- and element-vector as the mesh-constructor checks for such
 	 * nodes and removes them. This note is just to call this issue to attention in case this methods is changed.
 	 */
-	static MeshLib::Mesh* blendLayersWithSurface(MeshLib::Mesh* mesh, const unsigned nLayers, const std::string &dem_raster);
+	static MeshLib::Mesh* blendLayersWithSurface(MeshLib::Mesh &mesh, const unsigned nLayers, const std::string &dem_raster);
 
 private:
 	/// Checks if the given mesh is within the dimensions given by xDim and yDim.
@@ -64,4 +64,4 @@ private:
 	                           const std::pair<double, double> &yDim);
 };
 
-#endif //MSHLAYERMAPPER_H
+#endif //MESHLAYERMAPPER_H
diff --git a/MeshLib/Node.h b/MeshLib/Node.h
index e6000a6cd5d1e06584a308f48b60168c2a6e40c7..8bdb813c93418f5dc983fde85c54f4038c2f28a4 100644
--- a/MeshLib/Node.h
+++ b/MeshLib/Node.h
@@ -24,9 +24,7 @@
 #include "Mesh.h"
 #include "MeshEditing/removeMeshNodes.h"
 #include "MeshSurfaceExtraction.h"
-#ifdef OGS_BUILD_GUI
-	#include "../Gui/DataView/MshLayerMapper.h"
-#endif
+#include "MeshGenerators/MeshLayerMapper.h"
 
 namespace MeshLib {
 
@@ -38,11 +36,10 @@ class Element;
 class Node : public GeoLib::PointWithID
 {
 	/* friend functions: */
-#ifdef OGS_BUILD_GUI
-	friend int MshLayerMapper::LayerMapping(MeshLib::Mesh* msh, const std::string &rasterfile, const unsigned nLayers,
+	friend int MeshLayerMapper::LayerMapping(MeshLib::Mesh &mesh, const std::string &rasterfile, const unsigned nLayers,
 		                                    const unsigned layer_id, double noDataReplacementValue);
-	friend MeshLib::Mesh* MshLayerMapper::blendLayersWithSurface(MeshLib::Mesh* mesh, const unsigned nLayers, const std::string &dem_raster);
-#endif
+	friend MeshLib::Mesh* MeshLayerMapper::blendLayersWithSurface(MeshLib::Mesh &mesh, const unsigned nLayers, const std::string &dem_raster);
+
 	/* friend classes: */
 	friend class Mesh;
 	friend class MeshRevision;