diff --git a/MeshLib/MeshSurfaceExtraction.cpp b/MeshLib/MeshSurfaceExtraction.cpp
index 80d490202701e36a24155d570b13067d1e1dc895..d9af34468011223b0622c4c0dcf87d433518d0bf 100644
--- a/MeshLib/MeshSurfaceExtraction.cpp
+++ b/MeshLib/MeshSurfaceExtraction.cpp
@@ -62,7 +62,7 @@ void MeshSurfaceExtraction::getSurfaceAreaForNodes(const MeshLib::Mesh &mesh, st
 		ERR ("Error in MeshSurfaceExtraction::getSurfaceAreaForNodes() - Given mesh is no surface mesh (dimension != 2).");
 }
 
-MeshLib::Mesh* MeshSurfaceExtraction::getMeshSurface(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir)
+MeshLib::Mesh* MeshSurfaceExtraction::getMeshSurface(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir, bool keep3dMeshIds)
 {
 	INFO ("Extracting mesh surface...");
 	const std::vector<MeshLib::Element*> all_elements (mesh.getElements());
@@ -98,7 +98,19 @@ MeshLib::Mesh* MeshSurfaceExtraction::getMeshSurface(const MeshLib::Mesh &mesh,
 		delete *elem;
 	}
 
-	return new Mesh("SurfaceMesh", sfc_nodes, new_elements);
+	std::vector<std::size_t> id_map;
+	if (keep3dMeshIds)
+	{
+		id_map.reserve(mesh.getNNodes());
+		std::size_t idx(0);
+		std::generate(id_map.begin(), id_map.end(), [&sfc_nodes, &idx](){ return sfc_nodes[idx++]->getID(); });
+	}
+	MeshLib::Mesh* result (new Mesh("SurfaceMesh", sfc_nodes, new_elements));
+	if (keep3dMeshIds)
+		for (MeshLib::Node* node : sfc_nodes)
+			node->setID(id_map[node->getID()]);
+
+	return result;
 }
 
 void MeshSurfaceExtraction::get2DSurfaceElements(const std::vector<MeshLib::Element*> &all_elements, std::vector<MeshLib::Element*> &sfc_elements, const MathLib::Vector3 &dir, unsigned mesh_dimension)
diff --git a/MeshLib/MeshSurfaceExtraction.h b/MeshLib/MeshSurfaceExtraction.h
index 2f55f97d43c9dcd17c7233d8701142dd53cf90f4..f15545e0d938a1db140f16c4a152d0d6ed441276 100644
--- a/MeshLib/MeshSurfaceExtraction.h
+++ b/MeshLib/MeshSurfaceExtraction.h
@@ -42,8 +42,14 @@ public:
 	/// Returns the surface nodes of a layered mesh.
 	static std::vector<GeoLib::PointWithID*> getSurfaceNodes(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir);
 
-	/// Returns the 2d-element mesh representing the surface of the given layered mesh.
-	static MeshLib::Mesh* getMeshSurface(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir);
+	/**
+	 * Returns the 2d-element mesh representing the surface of the given layered mesh.
+	 * \param mesh          The original mesh
+	 * \param dir           The direction in which face normals have to point to be considered surface elements
+	 * \param keep3dMeshIds If true, ids of mesh nodes are set to ids in original mesh, otherwise node ids are reset (as usual when creating a mesh)
+	 * \return              A 2D mesh representing the surface in direction dir
+	 */
+	static MeshLib::Mesh* getMeshSurface(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir, bool keep3dMeshIds = false);
 
 private:
 	/// Functionality needed for getSurfaceNodes() and getMeshSurface()
diff --git a/MeshLib/Node.h b/MeshLib/Node.h
index 48684bb6d22e1bacbe86980c3f1d3fde082e9c8c..b0b646ff763537d2dca26aa92a17bd1ce1f41ee3 100644
--- a/MeshLib/Node.h
+++ b/MeshLib/Node.h
@@ -39,6 +39,7 @@ class Node : public GeoLib::PointWithID
 	friend bool MeshLayerMapper::LayerMapping(MeshLib::Mesh &mesh, const GeoLib::Raster &raster, const unsigned nLayers,
 		                                      const unsigned layer_id, double noDataReplacementValue);
 	friend MeshLib::Mesh* MeshLayerMapper::blendLayersWithSurface(MeshLib::Mesh &mesh, const unsigned nLayers, const std::string &dem_raster);
+	friend MeshLib::Mesh* MeshSurfaceExtraction::getMeshSurface(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir, bool keep3dMeshIds);
 
 	/* friend classes: */
 	friend class Mesh;