diff --git a/GeoLib/Surface.cpp b/GeoLib/Surface.cpp
index 3b8b55fad2946baf4e0e27a80d20ebe157245ffb..2f2be4148d08df5efcec3dce6b5a0165f74eb72b 100644
--- a/GeoLib/Surface.cpp
+++ b/GeoLib/Surface.cpp
@@ -1,8 +1,4 @@
 /**
- * \file
- * \author Thomas Fischer
- * \date   2010-04-22
- * \brief  Implementation of the Surface class.
  *
  * \copyright
  * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
@@ -15,7 +11,7 @@
 #include <list>
 
 // ThirdParty/logog
-#include "logog/include/logog.hpp"
+#include <logog/include/logog.hpp>
 
 #include "Surface.h"
 
@@ -31,20 +27,38 @@
 
 namespace GeoLib
 {
-Surface::Surface (const std::vector<Point*> &pnt_vec) :
-    GeoObject(), _sfc_pnts(pnt_vec), _bounding_volume(nullptr),
-    _surface_grid(nullptr)
-{}
+Surface::Surface(const std::vector<Point*>& pnt_vec)
+    : GeoObject(),
+      _sfc_pnts(pnt_vec),
+      _bounding_volume(nullptr),
+      _surface_grid(nullptr)
+{
+}
+
+Surface::Surface(Surface const& src)
+    : _sfc_pnts(src._sfc_pnts),
+      _bounding_volume(new AABB(*(src._bounding_volume))),
+      _surface_grid(nullptr)
+{
+    _sfc_triangles.reserve(src._sfc_triangles.size());
+    std::transform(src._sfc_triangles.cbegin(),
+                   src._sfc_triangles.cend(),
+                   std::back_inserter(_sfc_triangles),
+                   [](Triangle* t) { return new Triangle(*t); });
+}
 
-Surface::~Surface ()
+Surface::~Surface()
 {
     for (std::size_t k(0); k < _sfc_triangles.size(); k++)
         delete _sfc_triangles[k];
 }
 
-void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c)
+void Surface::addTriangle(std::size_t pnt_a,
+                          std::size_t pnt_b,
+                          std::size_t pnt_c)
 {
-    assert (pnt_a < _sfc_pnts.size() && pnt_b < _sfc_pnts.size() && pnt_c < _sfc_pnts.size());
+    assert(pnt_a < _sfc_pnts.size() && pnt_b < _sfc_pnts.size() &&
+           pnt_c < _sfc_pnts.size());
 
     // Check if two points of the triangle have identical IDs
     if (pnt_a == pnt_b || pnt_a == pnt_c || pnt_b == pnt_c)
@@ -54,92 +68,108 @@ void Surface::addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_
     _surface_grid.reset();
 
     _sfc_triangles.push_back(new Triangle(_sfc_pnts, pnt_a, pnt_b, pnt_c));
-    if (!_bounding_volume) {
+    if (!_bounding_volume)
+    {
         std::vector<std::size_t> ids(3);
         ids[0] = pnt_a;
         ids[1] = pnt_b;
         ids[2] = pnt_c;
         _bounding_volume.reset(new AABB(_sfc_pnts, ids));
-    } else {
+    }
+    else
+    {
         _bounding_volume->update(*_sfc_pnts[pnt_a]);
         _bounding_volume->update(*_sfc_pnts[pnt_b]);
         _bounding_volume->update(*_sfc_pnts[pnt_c]);
     }
 }
 
-Surface* Surface::createSurface(const Polyline &ply)
+Surface* Surface::createSurface(const Polyline& ply)
 {
-    if (!ply.isClosed()) {
+    if (!ply.isClosed())
+    {
         WARN("Error in Surface::createSurface() - Polyline is not closed.");
         return nullptr;
     }
 
-    if (ply.getNumberOfPoints() > 2) {
-        // create empty surface
-        Surface *sfc(new Surface(ply.getPointsVec()));
-
-        Polygon* polygon (new Polygon (ply));
-        polygon->computeListOfSimplePolygons ();
-
-        // create surfaces from simple polygons
-        const std::list<GeoLib::Polygon*>& list_of_simple_polygons (polygon->getListOfSimplePolygons());
-        for (std::list<GeoLib::Polygon*>::const_iterator simple_polygon_it (list_of_simple_polygons.begin());
-            simple_polygon_it != list_of_simple_polygons.end(); ++simple_polygon_it) {
-
-            std::list<GeoLib::Triangle> triangles;
-            GeoLib::EarClippingTriangulation(*simple_polygon_it, triangles);
+    if (ply.getNumberOfPoints() <= 2)
+    {
+        WARN(
+            "Error in Surface::createSurface() - Polyline consists of less "
+            "than three points and therefore cannot be triangulated.");
+        return nullptr;
+    }
 
-            // add Triangles to Surface
-            std::list<GeoLib::Triangle>::const_iterator it (triangles.begin());
-            while (it != triangles.end()) {
-                sfc->addTriangle ((*it)[0], (*it)[1], (*it)[2]);
-                ++it;
-            }
-        }
-        delete polygon;
-        if (sfc->getNTriangles() == 0) {
-            WARN("Surface::createSurface(): Triangulation does not contain any triangle.");
-            delete sfc;
-            return nullptr;
+    // create empty surface
+    Surface* sfc(new Surface(ply.getPointsVec()));
+
+    Polygon* polygon(new Polygon(ply));
+    polygon->computeListOfSimplePolygons();
+
+    // create surfaces from simple polygons
+    const std::list<GeoLib::Polygon*>& list_of_simple_polygons(
+        polygon->getListOfSimplePolygons());
+    for (std::list<GeoLib::Polygon*>::const_iterator simple_polygon_it(
+             list_of_simple_polygons.begin());
+         simple_polygon_it != list_of_simple_polygons.end();
+         ++simple_polygon_it)
+    {
+        std::list<GeoLib::Triangle> triangles;
+        GeoLib::EarClippingTriangulation(*simple_polygon_it, triangles);
+
+        // add Triangles to Surface
+        std::list<GeoLib::Triangle>::const_iterator it(triangles.begin());
+        while (it != triangles.end())
+        {
+            sfc->addTriangle((*it)[0], (*it)[1], (*it)[2]);
+            ++it;
         }
-        return sfc;
-    } else {
-        WARN("Error in Surface::createSurface() - Polyline consists of less than three points and therefore cannot be triangulated.");
+    }
+    delete polygon;
+    if (sfc->getNTriangles() == 0)
+    {
+        WARN(
+            "Surface::createSurface(): Triangulation does not contain any "
+            "triangle.");
+        delete sfc;
         return nullptr;
     }
-
+    return sfc;
 }
 
-std::size_t Surface::getNTriangles () const
+std::size_t Surface::getNTriangles() const
 {
     return _sfc_triangles.size();
 }
 
-const Triangle* Surface::operator[] (std::size_t i) const
+const Triangle* Surface::operator[](std::size_t i) const
 {
-    assert (i < _sfc_triangles.size());
+    assert(i < _sfc_triangles.size());
     return _sfc_triangles[i];
 }
 
 bool Surface::isPntInBoundingVolume(MathLib::Point3d const& pnt) const
 {
-    return _bounding_volume->containsPoint (pnt);
+    return _bounding_volume->containsPoint(pnt);
 }
 
 bool Surface::isPntInSfc(MathLib::Point3d const& pnt) const
 {
     // Mutable _surface_grid is constructed if method is called the first time.
-    if (_surface_grid == nullptr) {
+    if (_surface_grid == nullptr)
+    {
         _surface_grid.reset(new SurfaceGrid(this));
     }
     return _surface_grid->isPointInSurface(
         pnt, std::numeric_limits<double>::epsilon());
 }
 
-const Triangle* Surface::findTriangle (MathLib::Point3d const& pnt) const
+const Triangle* Surface::findTriangle(MathLib::Point3d const& pnt) const
 {
-    for (std::size_t k(0); k<_sfc_triangles.size(); k++) {
-        if (_sfc_triangles[k]->containsPoint (pnt)) {
+    for (std::size_t k(0); k < _sfc_triangles.size(); k++)
+    {
+        if (_sfc_triangles[k]->containsPoint(pnt))
+        {
             return _sfc_triangles[k];
         }
     }
diff --git a/GeoLib/Surface.h b/GeoLib/Surface.h
index 28c96d077caa394e02e58e4bce333a325206ed6d..e94fe2eca155c5c026002f9b9d35ecad4b140296 100644
--- a/GeoLib/Surface.h
+++ b/GeoLib/Surface.h
@@ -1,8 +1,4 @@
 /**
- * \file
- * \author Thomas Fischer
- * \date   2010-01-22
- * \brief  Definition of the Surface class.
  *
  * \copyright
  * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
@@ -36,31 +32,36 @@ class SurfaceGrid;
  * to a vector of (pointers to) points (_sfc_pnts) and a vector that stores
  * the Triangles consisting of points from _sfc_pnts.
  * */
-class Surface : public GeoObject
+class Surface final : public GeoObject
 {
 public:
-    Surface(const std::vector<Point*> &pnt_vec);
-    virtual ~Surface ();
+    explicit Surface(const std::vector<Point*>& pnt_vec);
+    Surface(Surface const& src);
+    ~Surface();
 
-    /// return a geometry type
-    virtual GEOTYPE getGeoType() const {return GEOTYPE::SURFACE;}
+    Surface(Surface && src) = delete;
+    Surface& operator=(Surface const& src) = delete;
+    Surface& operator=(Surface && src) = delete;
 
+    /// return a geometry type
+    GEOTYPE getGeoType() const override { return GEOTYPE::SURFACE; }
     /**
      * adds three indices describing a triangle and updates the bounding box
      * */
-    void addTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c);
+    void addTriangle(std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c);
 
     /// Triangulates a new surface based on closed polyline.
-    static Surface* createSurface(const Polyline &ply);
+    static Surface* createSurface(const Polyline& ply);
 
     /**
      * returns the number of triangles describing the Surface
      * */
-    std::size_t getNTriangles () const;
+    std::size_t getNTriangles() const;
 
-    /** \brief const access operator for the access to the i-th Triangle of the surface.
+    /** \brief const access operator for the access to the i-th Triangle of the
+     * surface.
     */
-    const Triangle* operator[] (std::size_t i) const;
+    const Triangle* operator[](std::size_t i) const;
 
     /**
      * is the given point in the bounding volume of the surface
@@ -82,17 +83,15 @@ public:
      */
     const Triangle* findTriangle(MathLib::Point3d const& pnt) const;
 
-    const std::vector<Point*> *getPointVec() const { return &_sfc_pnts; }
-
+    const std::vector<Point*>* getPointVec() const { return &_sfc_pnts; }
     /**
      * method allows access to the internal axis aligned bounding box
      * @return axis aligned bounding box
      */
-    AABB const& getAABB () const { return *_bounding_volume; }
-
+    AABB const& getAABB() const { return *_bounding_volume; }
 protected:
     /** a vector of pointers to Points */
-    const std::vector<Point*> &_sfc_pnts;
+    const std::vector<Point*>& _sfc_pnts;
     /** position of pointers to the geometric points */
     std::vector<Triangle*> _sfc_triangles;
     /** bounding volume is an axis aligned bounding box */
@@ -103,7 +102,6 @@ protected:
     /// called and a valid surface grid is not existing.
     mutable std::unique_ptr<SurfaceGrid> _surface_grid;
 };
-
 }
 
 #endif /* SURFACE_H_ */
diff --git a/GeoLib/Triangle.cpp b/GeoLib/Triangle.cpp
index 02d4be34bd6fa6fa651f17bc0b0344e58f668579..5480a9c28499593c3bfcf3ebc23b75826d885c3f 100644
--- a/GeoLib/Triangle.cpp
+++ b/GeoLib/Triangle.cpp
@@ -1,8 +1,4 @@
 /**
- * \file
- * \author Thomas Fischer
- * \date   2010-06-06
- * \brief  Implementation of the Triangle class.
  *
  * \copyright
  * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
@@ -21,29 +17,12 @@
 
 namespace GeoLib {
 
-Triangle::Triangle (std::vector<Point *> const &pnt_vec) :
-    _pnts(pnt_vec), _initialized (false), _longest_edge (0.0)
-{
-    assert(!_pnts.empty());
-    _pnt_ids[0] = std::numeric_limits<std::size_t>::max();
-    _pnt_ids[1] = std::numeric_limits<std::size_t>::max();
-    _pnt_ids[2] = std::numeric_limits<std::size_t>::max();
-}
-
 Triangle::Triangle (std::vector<Point *> const &pnt_vec,
     std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c) :
-    _pnts(pnt_vec), _initialized (true), _longest_edge (0.0)
+    _pnts(pnt_vec), _pnt_ids( {{pnt_a, pnt_b, pnt_c}} )
 {
     assert(!_pnts.empty());
-    _pnt_ids[0] = pnt_a;
-    _pnt_ids[1] = pnt_b;
-    _pnt_ids[2] = pnt_c;
-    _longest_edge = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[1]]);
-    double tmp (MathLib::sqrDist (*_pnts[_pnt_ids[1]], *_pnts[_pnt_ids[2]]));
-    if (tmp > _longest_edge) _longest_edge = tmp;
-    tmp = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[2]]);
-    if (tmp > _longest_edge) _longest_edge = tmp;
-    _longest_edge = sqrt (_longest_edge);
+    assert (pnt_a < _pnts.size() && pnt_b < _pnts.size() && pnt_c < _pnts.size());
 }
 
 void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c)
@@ -52,13 +31,6 @@ void Triangle::setTriangle (std::size_t pnt_a, std::size_t pnt_b, std::size_t pn
     _pnt_ids[0] = pnt_a;
     _pnt_ids[1] = pnt_b;
     _pnt_ids[2] = pnt_c;
-
-    _longest_edge = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[1]]);
-    double tmp (MathLib::sqrDist (*_pnts[_pnt_ids[1]], *_pnts[_pnt_ids[2]]));
-    if (tmp > _longest_edge) _longest_edge = tmp;
-    tmp = MathLib::sqrDist (*_pnts[_pnt_ids[0]], *_pnts[_pnt_ids[2]]);
-    if (tmp > _longest_edge) _longest_edge = tmp;
-    _longest_edge = sqrt (_longest_edge);
 }
 
 bool Triangle::containsPoint(MathLib::Point3d const& q, double eps) const
@@ -90,7 +62,9 @@ bool Triangle::containsPoint2D (Point const& pnt) const
     const double upper (1+delta);
 
     // check if u0 and u1 fulfills the condition (with some delta)
-    if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper && y[0] + y[1] <= upper) {
+    if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper &&
+        y[0] + y[1] <= upper)
+    {
         return true;
     }
     return false;
diff --git a/GeoLib/Triangle.h b/GeoLib/Triangle.h
index 0f88e4515a00a70fa1acbe92618cd965c58e47b6..75f82cb3fdd89d75c6dc36a6d6fe5eac4d219d9d 100644
--- a/GeoLib/Triangle.h
+++ b/GeoLib/Triangle.h
@@ -1,8 +1,4 @@
 /**
- * \file
- * \author Thomas Fischer
- * \date   2010-03-23
- * \brief  Definition of the Triangle class.
  *
  * \copyright
  * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
@@ -26,21 +22,19 @@ class Point;
 /** \brief Class Triangle consists of a reference to a point vector and
  * a vector that stores the indices in the point vector.
  * A surface is composed by triangles. The class Surface stores the position
- * of pointers to the points of triangles in the m_sfc_pnt_ids vector.
+ * of pointers to the points of triangles in the _pnt_ids vector.
  * */
-class Triangle
+class Triangle final
 {
 public:
-    /**
-     * construction of object, initialization of reference to point vector
-     */
-    Triangle (std::vector<Point *> const &pnt_vec);
-
     /**
      * construction of object, initialization of reference to point vector,
      * saves the three indices describing a triangle
      */
-    Triangle (std::vector<Point *> const &pnt_vec, std::size_t pnt_a, std::size_t pnt_b, std::size_t pnt_c);
+    Triangle(std::vector<Point*> const& pnt_vec,
+             std::size_t pnt_a,
+             std::size_t pnt_b,
+             std::size_t pnt_c);
 
     /**
      * saves three indices describing a triangle
@@ -50,7 +44,8 @@ public:
     /** \brief const access operator to access the index
      * of the i-th triangle point
     */
-    const std::size_t& operator[] (std::size_t i) const {
+    const std::size_t& operator[](std::size_t i) const
+    {
         assert (i < 3);
         return _pnt_ids[i];
     }
@@ -58,7 +53,8 @@ public:
     /**
      * \brief const access operator to access the i-th triangle Point
      */
-    const Point* getPoint (std::size_t i) const {
+    const Point* getPoint(std::size_t i) const
+    {
         assert (i < 3);
         return _pnts[_pnt_ids[i]];
     }
@@ -69,7 +65,9 @@ public:
      * @param eps Checks the 'epsilon'-neighbourhood
      * @return true, if point is in triangle, else false
      */
-    bool containsPoint(MathLib::Point3d const& q, double eps = std::numeric_limits<float>::epsilon()) const;
+    bool containsPoint(
+        MathLib::Point3d const& q,
+        double eps = std::numeric_limits<float>::epsilon()) const;
 
     /**
      * projects the triangle points to the x-y-plane and
@@ -77,15 +75,13 @@ public:
      * @param pnt the point to test for
      * @return true, if the point is into the projected triangle
      */
-    bool containsPoint2D (Point const& pnt) const;
+    bool containsPoint2D(Point const& pnt) const;
 
-protected:
-    /** a vector of pointers to points */
-    const std::vector<Point*> &_pnts;
-    /** position of pointers to the geometric points */
-    std::size_t _pnt_ids[3];
-    bool _initialized;
-    double _longest_edge;
+private:
+    /// a vector of pointers to points the triangle is based on
+    std::vector<Point*> const& _pnts;
+    /// position of pointers to the geometric points
+    std::array<std::size_t, 3> _pnt_ids;
 };
 
 void getPlaneCoefficients(Triangle const& tri, double c[3]);