diff --git a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/BoundingBox.java b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/BoundingBox.java
index dabb5a6fd0d54bd642f2119de2d54d9a71c604a1..16be89d8468556b2e6e9634b91e24850a5f307b8 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/BoundingBox.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/BoundingBox.java
@@ -1,6 +1,7 @@
 package cz.fidentis.analyst.symmetry;
 
 import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 import java.util.List;
 import javax.vecmath.Vector3d;
 
@@ -89,8 +90,8 @@ public class BoundingBox {
      * Recomputes the BoundingBox from all points
     */
     private void validateMinMax() {
-        minPoint = new MeshPoint(new Vector3d(Double.MAX_VALUE,Double.MAX_VALUE,Double.MAX_VALUE), null, null);
-        maxPoint = new MeshPoint(new Vector3d(-100000.0,-100000.0,-100000.0), null, null);
+        minPoint = new MeshPointImpl(new Vector3d(Double.MAX_VALUE,Double.MAX_VALUE,Double.MAX_VALUE), null, null);
+        maxPoint = new MeshPointImpl(new Vector3d(-100000.0,-100000.0,-100000.0), null, null);
  
         for (int i = 0; i < points.size(); i++) {
             MeshPoint point = points.get(i);
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/Plane.java b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/Plane.java
index c68e0f4e051c56fc1225b3efa130d435cb1a23b1..6e4243b00667a7ea82338544d348974d72639298 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/Plane.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/Plane.java
@@ -2,6 +2,7 @@ package cz.fidentis.analyst.symmetry;
 
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 
 /**
  *
@@ -80,7 +81,7 @@ public class Plane {
         facet.getVertices().clear();
         
         for (int i = 0; i < points.length; i++) {
-            facet.addVertex(new MeshPoint(points[i].getPosition(),normals[i].getPosition(),null));
+            facet.addVertex(new MeshPointImpl(points[i].getPosition(),normals[i].getPosition(),null));
         }
         return planeMesh;
     }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
index e42754f6b17476f8e63a68baead6b8d8464de4f5..b638bb6709e4f76f658e54eec475103e54804537 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/SymmetryEstimator.java
@@ -3,6 +3,7 @@ package cz.fidentis.analyst.symmetry;
 import cz.fidentis.analyst.mesh.core.CornerTableRow;
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -165,14 +166,14 @@ public class SymmetryEstimator {
     public MeshPoint[] calculateNormals() {
         MeshPoint[] newNormals = new MeshPoint[facet.getNumberOfVertices()];
         for (int i = 0; i < facet.getNumberOfVertices(); i++) {
-            newNormals[i] = new MeshPoint(new Vector3d(0, 0, 0), null, null);
+            newNormals[i] = new MeshPointImpl(new Vector3d(0, 0, 0), null, null);
         }
         for (Triangle t : triangles) {
             MeshPoint triangleNormal = (facet.getVertices().get(t.vertex3).subtractPosition
         (facet.getVertices().get(t.vertex1))).crossProduct(facet.getVertices().get(t.vertex2).subtractPosition(facet.getVertices().get(t.vertex1)));
-            newNormals[t.vertex1] = newNormals[t.vertex1].addPosition(new MeshPoint(triangleNormal.getPosition(), null, null));
-            newNormals[t.vertex2] = newNormals[t.vertex2].addPosition(new MeshPoint(triangleNormal.getPosition(), null, null));
-            newNormals[t.vertex3] = newNormals[t.vertex3].addPosition(new MeshPoint(triangleNormal.getPosition(), null, null));
+            newNormals[t.vertex1] = newNormals[t.vertex1].addPosition(new MeshPointImpl(triangleNormal.getPosition(), null, null));
+            newNormals[t.vertex2] = newNormals[t.vertex2].addPosition(new MeshPointImpl(triangleNormal.getPosition(), null, null));
+            newNormals[t.vertex3] = newNormals[t.vertex3].addPosition(new MeshPointImpl(triangleNormal.getPosition(), null, null));
         }
         for (int i = 0; i < newNormals.length; i++){ 
             if (newNormals[i].getPosition().x != 0 && newNormals[i].getPosition().y != 0 && newNormals[i].getPosition().z != 0) {
@@ -368,10 +369,10 @@ public class SymmetryEstimator {
         List<Integer> trianglesNeighbours = getNeighbours(centerIndex);
 
         if (trianglesNeighbours.isEmpty()) {
-            return new MeshPoint(new Vector3d(), new Vector3d(), new Vector3d());
+            return new MeshPointImpl(new Vector3d(), new Vector3d(), new Vector3d());
         }
         double areaSum = 0;
-        MeshPoint pointSum = new MeshPoint(new Vector3d(), new Vector3d(), new Vector3d());
+        MeshPoint pointSum = new MeshPointImpl(new Vector3d(), new Vector3d(), new Vector3d());
         for (int i = 0; i < trianglesNeighbours.size(); i++) {
             Triangle t = triangles[trianglesNeighbours.get(i)];
             Triangle tNext = triangles[trianglesNeighbours.get((i + 1) % trianglesNeighbours.size())];
@@ -420,8 +421,8 @@ public class SymmetryEstimator {
         double areaSum = 0;
 
         for (int i = 0; i < triangleNeighbours.size(); i++) {
-            MeshPoint v1 = new MeshPoint(new Vector3d(), new Vector3d(), new Vector3d());
-            MeshPoint v2 = new MeshPoint(new Vector3d(), new Vector3d(), new Vector3d());
+            MeshPoint v1 = new MeshPointImpl(new Vector3d(), new Vector3d(), new Vector3d());
+            MeshPoint v2 = new MeshPointImpl(new Vector3d(), new Vector3d(), new Vector3d());
             Triangle t = triangles[triangleNeighbours.get(i)];
             
             MeshPoint tVertex1 = facet.getVertices().get(t.vertex1);
@@ -505,7 +506,7 @@ public class SymmetryEstimator {
         
         plane.normalize();
         
-        MeshPoint normal = new MeshPoint((new Vector3d(plane.a, plane.b, plane.c)),new Vector3d(), new Vector3d());
+        MeshPoint normal = new MeshPointImpl((new Vector3d(plane.a, plane.b, plane.c)),new Vector3d(), new Vector3d());
         double d = plane.d;
         double maxCurvRatio = 1.0 / minCurvRatio;
         int votes = 0;
@@ -522,13 +523,13 @@ public class SymmetryEstimator {
  
                     MeshPoint ni;
             
-                    ni = new MeshPoint (new Vector3d(normals[points.get(i)].getPosition().x,normals[points.get(i)].getPosition().y,
+                    ni = new MeshPointImpl(new Vector3d(normals[points.get(i)].getPosition().x,normals[points.get(i)].getPosition().y,
                            normals[points.get(i)].getPosition().z), new Vector3d(), new Vector3d());
                         
                     ni = ni.dividePosition(ni.abs());
                         
                     MeshPoint nj;
-                    nj = new MeshPoint (new Vector3d(normals[points.get(j)].getPosition().x,normals[points.get(j)].getPosition().y,
+                    nj = new MeshPointImpl(new Vector3d(normals[points.get(j)].getPosition().x,normals[points.get(j)].getPosition().y,
                                normals[points.get(j)].getPosition().z), new Vector3d(), new Vector3d());
                     nj = nj.dividePosition(nj.abs());
 
@@ -624,7 +625,7 @@ public class SymmetryEstimator {
                                 (normal.getPosition().y * avrg.getPosition().y) - (normal.getPosition().z * avrg.getPosition().z);
                        
                         MeshPoint ni;
-                        ni = new MeshPoint (new Vector3d(normals[significantPoints.get(i)].getPosition().x,
+                        ni = new MeshPointImpl(new Vector3d(normals[significantPoints.get(i)].getPosition().x,
                                 normals[significantPoints.get(i)].getPosition().y,
                                 normals[significantPoints.get(i)].getPosition().z),
                                 new Vector3d(), new Vector3d());
@@ -632,7 +633,7 @@ public class SymmetryEstimator {
                         ni = ni.dividePosition(ni.abs());
                         
                         MeshPoint nj;
-                        nj = new MeshPoint (new Vector3d(normals[significantPoints.get(j)].getPosition().x,
+                        nj = new MeshPointImpl(new Vector3d(normals[significantPoints.get(j)].getPosition().x,
                                 normals[significantPoints.get(j)].getPosition().y,
                                 normals[significantPoints.get(j)].getPosition().z),
                                 new Vector3d(), new Vector3d());
@@ -678,9 +679,9 @@ public class SymmetryEstimator {
             }
         }
         Plane finalPlane = new Plane(0, 0, 0, 0);
-        MeshPoint refDir = new MeshPoint(new Vector3d(finalPlanes.get(0).a, finalPlanes.get(0).b, finalPlanes.get(0).c), new Vector3d(), new Vector3d());
+        MeshPoint refDir = new MeshPointImpl(new Vector3d(finalPlanes.get(0).a, finalPlanes.get(0).b, finalPlanes.get(0).c), new Vector3d(), new Vector3d());
         for (int i = 0; i < finalPlanes.size(); i++) {
-            MeshPoint normDir = new MeshPoint(new Vector3d(finalPlanes.get(i).a, finalPlanes.get(i).b, finalPlanes.get(i).c), new Vector3d(), new Vector3d());
+            MeshPoint normDir = new MeshPointImpl(new Vector3d(finalPlanes.get(i).a, finalPlanes.get(i).b, finalPlanes.get(i).c), new Vector3d(), new Vector3d());
             if (normDir.dotProduct(refDir) < 0) {
                 finalPlane.a -= finalPlanes.get(i).a;
                 finalPlane.b -= finalPlanes.get(i).b;
@@ -710,7 +711,7 @@ public class SymmetryEstimator {
      * @return mesh that represents facet with computed plane of approximate symmetry
      */
     public SymmetryEstimator mergeWithPlane(Plane plane) {
-        MeshPoint normal = new MeshPoint(new Vector3d(plane.a, plane.b, plane.c), new Vector3d(), new Vector3d());
+        MeshPoint normal = new MeshPointImpl(new Vector3d(plane.a, plane.b, plane.c), new Vector3d(), new Vector3d());
         MeshPoint midPoint = boundingBox.getMidPoint();
 
         double alpha = -((plane.a * midPoint.getPosition().x) + 
@@ -724,11 +725,11 @@ public class SymmetryEstimator {
                 midPointOnPlane.getPosition().z + plane.d;
 
         MeshPoint a;
-        if (Math.abs(normal.dotProduct(new MeshPoint(new Vector3d(0.0, 1.0, 0.0), new Vector3d(), new Vector3d()))) 
-                > Math.abs(normal.dotProduct(new MeshPoint(new Vector3d (1.0, 0.0, 0.0), new Vector3d(), new Vector3d())))) {
-                a = normal.crossProduct(new MeshPoint(new Vector3d(1.0, 0.0, 0.0), new Vector3d(), new Vector3d()));
+        if (Math.abs(normal.dotProduct(new MeshPointImpl(new Vector3d(0.0, 1.0, 0.0), new Vector3d(), new Vector3d()))) 
+                > Math.abs(normal.dotProduct(new MeshPointImpl(new Vector3d (1.0, 0.0, 0.0), new Vector3d(), new Vector3d())))) {
+                a = normal.crossProduct(new MeshPointImpl(new Vector3d(1.0, 0.0, 0.0), new Vector3d(), new Vector3d()));
         } else {
-            a = normal.crossProduct(new MeshPoint(new Vector3d(0.0, 1.0, 0.0), new Vector3d(), new Vector3d()));
+            a = normal.crossProduct(new MeshPointImpl(new Vector3d(0.0, 1.0, 0.0), new Vector3d(), new Vector3d()));
         }
         a = a.dividePosition(a.abs());
 
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
index a9c59105ee017853cc37270a86e9b41885f6a1e9..3e225c924fc77b29688773d28d320e743334b0f5 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java
@@ -25,9 +25,8 @@ public class MeshFacet {
      * @param facet copied MeshFacet
      */
     public MeshFacet(MeshFacet facet) {
-        for (MeshPoint vertex :
-                facet.vertices) {
-            vertices.add(new MeshPoint(vertex));
+        for (MeshPoint vertex: facet.vertices) {
+            vertices.add(new MeshPointImpl(vertex));
         }
         cornerTable = new CornerTable(facet.cornerTable);
     }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
index 6ba54c95d91e4243ca93418205f715a10f932135..8b5b6252de21eaf5ce27b630311959441b5a9e1d 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPoint.java
@@ -1,266 +1,130 @@
-package cz.fidentis.analyst.mesh.core;
-
-import javax.vecmath.Vector3d;
-
-/**
- * MeshPoint represents a point with position, normal, and texture coordinates
- *
- * @author Matej Lukes
- */
-public class MeshPoint {
-    private final Vector3d position, normal, texCoord;
-
-    /**
-     * constructor of meshPoint
-     *
-     * @param position position of MeshPoint
-     * @param normal   normal of MeshPoint
-     * @param texCoord coordinates in texture
-     */
-    public MeshPoint(Vector3d position, Vector3d normal, Vector3d texCoord) {
-        if (position == null) {
-            throw new NullPointerException("position cannot be null");
-        }
-
-        this.position = position;
-        this.normal = normal;
-        this.texCoord = texCoord;
-    }
-
-    /**
-     * copy constructor of meshPoint
-     * @param meshPoint copied meshPoint
-     */
-    public MeshPoint(MeshPoint meshPoint) {
-        this.position = new Vector3d(meshPoint.position);
-        this.normal = new Vector3d(meshPoint.normal);
-        this.texCoord = new Vector3d(meshPoint.texCoord);
-
-    }
-
-    /**
-     * @return normal
-     */
-    public Vector3d getNormal() {
-        return normal;
-    }
-
-    /**
-     * @return position
-     */
-    public Vector3d getPosition() {
-        return position;
-    }
-
-    /**
-     * @return texture coordinates
-     */
-    public Vector3d getTexCoord() {
-        return texCoord;
-    }
-
-    /**
-     * returns new instance of MeshPoint with subtracted position
-     *
-     * @param subtrahend position to be subtracted
-     * @return subtracted MeshPoint
-     */
-    public MeshPoint subtractPosition(MeshPoint subtrahend) {
-        return subtractPosition(subtrahend.position);
-    }
-
-    /**
-     * returns new instance of MeshPoint with subtracted position
-     *
-     * @param subtrahend position to be subtracted
-     * @return subtracted MeshPoint
-     */
-    public MeshPoint subtractPosition(Vector3d subtrahend) {
-        Vector3d newPosition = new Vector3d(position);
-        newPosition.sub(subtrahend);
-        return new MeshPoint(new Vector3d(newPosition), normal, new Vector3d(texCoord));
-    }
-
-    /**
-     * returns new instance of MeshPoint with added position
-     *
-     * @param addend position to be added
-     * @return added MeshPoint
-     */
-    public MeshPoint addPosition(MeshPoint addend) {
-        return addPosition(addend.position);
-    }
-
-    /**
-     * returns new instance of MeshPoint with added position
-     *
-     * @param addend position to be added
-     * @return added MeshPoint
-     */
-    public MeshPoint addPosition(Vector3d addend) {
-        Vector3d newPosition = new Vector3d(position);
-        newPosition.add(addend);
-        return new MeshPoint(new Vector3d(newPosition), normal, new Vector3d(texCoord));
-    }
-
-    /**
-     * returns new instance of MeshPoint with multiplied position by number
-     * 
-     * @param number Number for multiplying
-     * @return multiplied MeshPoint
-     */
-    public MeshPoint multiplyPosition(double number) {
-        if (normal != null) {
-            if (texCoord != null) 
-                return new MeshPoint(new Vector3d(this.getPosition().x * number,
-                        this.getPosition().y * number, this.getPosition().z * number),
-                        new Vector3d(normal), new Vector3d(texCoord));
-            else
-                return new MeshPoint(new Vector3d(this.getPosition().x * number,
-                        this.getPosition().y * number, this.getPosition().z * number),
-                        new Vector3d(normal), null);
-        }
-        return new MeshPoint(new Vector3d(this.getPosition().x * number,
-                        this.getPosition().y * number, this.getPosition().z * number),
-                        null, null);        
-    }
-
-    /**
-     * returns new instance of MeshPoint with divided position by number
-     * 
-     * @param number Number for division
-     * @return divided MeshPoint
-     */
-    public MeshPoint dividePosition(double number) {
-        if (normal != null) {
-            if (texCoord != null) 
-                return new MeshPoint(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
-                        this.getPosition().z / number), new Vector3d(normal), new Vector3d(texCoord));
-            else
-                return new MeshPoint(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
-                        this.getPosition().z / number), new Vector3d(normal), null);
-        }
-        return new MeshPoint(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
-                this.getPosition().z / number), null, null);
-    }
-    
-    /**
-     * Returns the cross product of two points.
-     * 
-     * @param meshPoint Second argument of the cross product operation.
-     * @return MeshPoint representing the resulting vector.
-     */
-    public MeshPoint crossProduct(MeshPoint meshPoint) {
-        if (normal != null) {
-            if (texCoord != null) 
-                return new MeshPoint(new Vector3d
-                (this.position.y * meshPoint.position.z - this.position.z * meshPoint.position.y,
-                this.position.z * meshPoint.position.x - this.position.x * meshPoint.position.z,
-                this.position.x * meshPoint.position.y - this.position.y * meshPoint.position.x),
-                new Vector3d(normal), new Vector3d(texCoord));
-            else
-                return new MeshPoint(new Vector3d
-                (this.position.y * meshPoint.position.z - this.position.z * meshPoint.position.y,
-                this.position.z * meshPoint.position.x - this.position.x * meshPoint.position.z,
-                this.position.x * meshPoint.position.y - this.position.y * meshPoint.position.x),
-                new Vector3d(normal), null);
-        }
-        return new MeshPoint(new Vector3d
-                (this.position.y * meshPoint.position.z - this.position.z * meshPoint.position.y,
-                this.position.z * meshPoint.position.x - this.position.x * meshPoint.position.z,
-                this.position.x * meshPoint.position.y - this.position.y * meshPoint.position.x),
-                null, null);
-    }
-
-    /**
-     * returns the dot product of two points
-     * 
-     * @param meshPoint Second argument of the dot product operation
-     * @return dot product of two instances of MeshPoint 
-     */
-    public double dotProduct(MeshPoint meshPoint) {
-        return (this.position.x * meshPoint.position.x + this.position.y * meshPoint.position.y + this.position.z * meshPoint.position.z);
-    }
-    
-    /**
-     * returns absolute value of MeshPoint
-     * 
-     * @return absolute value of MeshPoint
-     */
-    public double abs() {
-        return Math.sqrt(this.getPosition().x * this.getPosition().x + 
-                this.getPosition().y * this.getPosition().y + this.getPosition().z * this.getPosition().z);
-    }
-
-    /**
-     * returns new instance of MeshPoint with subtracted normal
-     *
-     * @param subtrahend normal to be subtracted
-     * @return subtracted MeshPoint
-     */
-    public MeshPoint subtractNormal(MeshPoint subtrahend) {
-        return subtractNormal(subtrahend.normal);
-    }
-
-    /**
-     * returns new instance of MeshPoint with subtracted normal
-     *
-     * @param subtrahend normal to be subtracted
-     * @return subtracted MeshPoint
-     */
-    public MeshPoint subtractNormal(Vector3d subtrahend) {
-        Vector3d newNormal = new Vector3d(normal);
-        newNormal.sub(subtrahend);
-        newNormal.normalize();
-        return new MeshPoint(new Vector3d(position), newNormal, new Vector3d(texCoord));
-    }
-
-    /**
-     * returns new instance of MeshPoint with added normal
-     *
-     * @param addend normal to be added
-     * @return added MeshPoint
-     */
-    public MeshPoint addNormal(MeshPoint addend) {
-        return addNormal(addend.normal);
-    }
-
-    /**
-     * returns new instance of MeshPoint with added normal
-     *
-     * @param addend normal to be added
-     * @return added MeshPoint
-     */
-    public MeshPoint addNormal(Vector3d addend) {
-        Vector3d newNormal = new Vector3d(normal);
-        newNormal.add(addend);
-        newNormal.normalize();
-        return new MeshPoint(new Vector3d(position), newNormal, new Vector3d(texCoord));
-    }
-
-    /**
-     * @param obj compared object
-     * @return true if positions, normals and texture coordinates are equal, false otherwise
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof MeshPoint)) {
-            return false;
-        }
-
-        MeshPoint meshPointObj = (MeshPoint) obj;
-        return this.position.equals(meshPointObj.position)
-                && this.normal.equals(meshPointObj.normal)
-                && this.texCoord.equals(meshPointObj.texCoord);
-    }
-
-    /**
-     * returns hash of MeshPoint
-     *
-     * @return hash
-     */
-    @Override
-    public int hashCode() {
-        return position.hashCode() + normal.hashCode() + texCoord.hashCode();
-    }
-}
+package cz.fidentis.analyst.mesh.core;
+
+import javax.vecmath.Vector3d;
+
+/**
+ * MeshPoint represents a point with position, normal, and texture coordinates
+ *
+ * @author Matej Lukes
+ */
+public interface MeshPoint {
+    
+    /**
+     * @return normal
+     */
+    Vector3d getNormal();
+
+    /**
+     * @return position
+     */
+    Vector3d getPosition();
+
+    /**
+     * @return texture coordinates
+     */
+    Vector3d getTexCoord();
+
+    /**
+     * returns new instance of MeshPoint with subtracted position
+     *
+     * @param subtrahend position to be subtracted
+     * @return subtracted MeshPoint
+     */
+    MeshPoint subtractPosition(MeshPoint subtrahend);
+
+    /**
+     * returns new instance of MeshPoint with subtracted position
+     *
+     * @param subtrahend position to be subtracted
+     * @return subtracted MeshPoint
+     */
+    MeshPoint subtractPosition(Vector3d subtrahend);
+
+    /**
+     * returns new instance of MeshPoint with added position
+     *
+     * @param addend position to be added
+     * @return added MeshPoint
+     */
+    MeshPoint addPosition(MeshPoint addend);
+
+    /**
+     * returns new instance of MeshPoint with added position
+     *
+     * @param addend position to be added
+     * @return added MeshPoint
+     */
+    MeshPoint addPosition(Vector3d addend);
+
+    /**
+     * returns new instance of MeshPoint with multiplied position by number
+     * 
+     * @param number Number for multiplying
+     * @return multiplied MeshPoint
+     */
+    MeshPoint multiplyPosition(double number);
+
+    /**
+     * returns new instance of MeshPoint with divided position by number
+     * 
+     * @param number Number for division
+     * @return divided MeshPoint
+     */
+    MeshPoint dividePosition(double number);
+    
+    /**
+     * Returns the cross product of two points.
+     * 
+     * @param meshPoint Second argument of the cross product operation.
+     * @return MeshPoint representing the resulting vector.
+     */
+    MeshPoint crossProduct(MeshPoint meshPoint);
+
+    /**
+     * returns the dot product of two points
+     * 
+     * @param meshPoint Second argument of the dot product operation
+     * @return dot product of two instances of MeshPoint 
+     */
+    double dotProduct(MeshPoint meshPoint);
+    
+    /**
+     * returns absolute value of MeshPoint
+     * 
+     * @return absolute value of MeshPoint
+     */
+    double abs();
+
+    /**
+     * returns new instance of MeshPoint with subtracted normal
+     *
+     * @param subtrahend normal to be subtracted
+     * @return subtracted MeshPoint
+     */
+    MeshPoint subtractNormal(MeshPoint subtrahend);
+
+    /**
+     * returns new instance of MeshPoint with subtracted normal
+     *
+     * @param subtrahend normal to be subtracted
+     * @return subtracted MeshPoint
+     */
+    MeshPoint subtractNormal(Vector3d subtrahend);
+
+    /**
+     * returns new instance of MeshPoint with added normal
+     *
+     * @param addend normal to be added
+     * @return added MeshPoint
+     */
+    MeshPoint addNormal(MeshPoint addend);
+
+    /**
+     * returns new instance of MeshPoint with added normal
+     *
+     * @param addend normal to be added
+     * @return added MeshPoint
+     */
+    MeshPoint addNormal(Vector3d addend);
+
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPointImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPointImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..8284ac9a209f679198abdfdff8ce2a645b09c270
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshPointImpl.java
@@ -0,0 +1,200 @@
+package cz.fidentis.analyst.mesh.core;
+
+import javax.vecmath.Vector3d;
+
+/**
+ * MeshPoint represents a point with position, normal, and texture coordinates.
+ *
+ * @author Matej Lukes
+ */
+public class MeshPointImpl implements MeshPoint {
+    
+    private final Vector3d position, normal, texCoord;
+
+    /**
+     * constructor of meshPoint
+     *
+     * @param position position of MeshPoint
+     * @param normal   normal of MeshPoint
+     * @param texCoord coordinates in texture
+     */
+    public MeshPointImpl(Vector3d position, Vector3d normal, Vector3d texCoord) {
+        if (position == null) {
+            throw new NullPointerException("position cannot be null");
+        }
+
+        this.position = new Vector3d(position);
+        this.normal = new Vector3d(normal);
+        this.texCoord = new Vector3d(texCoord);
+    }
+
+    /**
+     * copy constructor of meshPoint
+     * 
+     * @param meshPoint copied meshPoint
+     */
+    public MeshPointImpl(MeshPoint meshPoint) {
+        this(meshPoint.getPosition(), meshPoint.getNormal(), meshPoint.getTexCoord());
+
+    }
+
+    @Override
+    public Vector3d getNormal() {
+        return normal;
+    }
+
+    @Override
+    public Vector3d getPosition() {
+        return position;
+    }
+
+    @Override
+    public Vector3d getTexCoord() {
+        return texCoord;
+    }
+
+    @Override
+    public MeshPoint subtractPosition(MeshPoint subtrahend) {
+        return subtractPosition(subtrahend.getPosition());
+    }
+
+    @Override
+    public MeshPoint subtractPosition(Vector3d subtrahend) {
+        Vector3d newPosition = new Vector3d(position);
+        newPosition.sub(subtrahend);
+        return new MeshPointImpl(new Vector3d(newPosition), normal, new Vector3d(texCoord));
+    }
+
+    @Override
+    public MeshPoint addPosition(MeshPoint addend) {
+        return addPosition(addend.getPosition());
+    }
+
+    @Override
+    public MeshPoint addPosition(Vector3d addend) {
+        Vector3d newPosition = new Vector3d(position);
+        newPosition.add(addend);
+        return new MeshPointImpl(new Vector3d(newPosition), normal, new Vector3d(texCoord));
+    }
+
+    @Override
+    public MeshPoint multiplyPosition(double number) {
+        if (normal != null) {
+            if (texCoord != null) {
+                return new MeshPointImpl(new Vector3d(this.getPosition().x * number,
+                        this.getPosition().y * number, this.getPosition().z * number),
+                        new Vector3d(normal), new Vector3d(texCoord));
+            } else {
+                return new MeshPointImpl(new Vector3d(this.getPosition().x * number,
+                        this.getPosition().y * number, this.getPosition().z * number),
+                        new Vector3d(normal), null);
+            }
+        }
+        return new MeshPointImpl(new Vector3d(this.getPosition().x * number,
+                        this.getPosition().y * number, this.getPosition().z * number),
+                        null, null);        
+    }
+
+    @Override
+    public MeshPoint dividePosition(double number) {
+        if (normal != null) {
+            if (texCoord != null) {
+                return new MeshPointImpl(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
+                        this.getPosition().z / number), new Vector3d(normal), new Vector3d(texCoord));
+            } else {
+                return new MeshPointImpl(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
+                        this.getPosition().z / number), new Vector3d(normal), null);
+            }
+        }
+        return new MeshPointImpl(new Vector3d(this.getPosition().x / number, this.getPosition().y / number,
+                this.getPosition().z / number), null, null);
+    }
+    
+    @Override
+    public MeshPoint crossProduct(MeshPoint meshPoint) {
+        if (normal != null) {
+            if (texCoord != null) {
+                return new MeshPointImpl(new Vector3d
+                (this.position.y * meshPoint.getPosition().z - this.position.z * meshPoint.getPosition().y,
+                this.position.z * meshPoint.getPosition().x - this.position.x * meshPoint.getPosition().z,
+                this.position.x * meshPoint.getPosition().y - this.position.y * meshPoint.getPosition().x),
+                new Vector3d(normal), new Vector3d(texCoord));
+            } else {
+                return new MeshPointImpl(new Vector3d
+                (this.position.y * meshPoint.getPosition().z - this.position.z * meshPoint.getPosition().y,
+                this.position.z * meshPoint.getPosition().x - this.position.x * meshPoint.getPosition().z,
+                this.position.x * meshPoint.getPosition().y - this.position.y * meshPoint.getPosition().x),
+                new Vector3d(normal), null);
+            }
+        }
+        return new MeshPointImpl(new Vector3d
+                (this.position.y * meshPoint.getPosition().z - this.position.z * meshPoint.getPosition().y,
+                this.position.z * meshPoint.getPosition().x - this.position.x * meshPoint.getPosition().z,
+                this.position.x * meshPoint.getPosition().y - this.position.y * meshPoint.getPosition().x),
+                null, null);
+    }
+
+    @Override
+    public double dotProduct(MeshPoint meshPoint) {
+        return (this.position.x * meshPoint.getPosition().x + this.position.y * meshPoint.getPosition().y + this.position.z * meshPoint.getPosition().z);
+    }
+    
+    @Override
+    public double abs() {
+        return Math.sqrt(this.getPosition().x * this.getPosition().x + 
+                this.getPosition().y * this.getPosition().y + this.getPosition().z * this.getPosition().z);
+    }
+
+    @Override
+    public MeshPoint subtractNormal(MeshPoint subtrahend) {
+        return subtractNormal(subtrahend.getNormal());
+    }
+
+    @Override
+    public MeshPoint subtractNormal(Vector3d subtrahend) {
+        Vector3d newNormal = new Vector3d(normal);
+        newNormal.sub(subtrahend);
+        newNormal.normalize();
+        return new MeshPointImpl(new Vector3d(position), newNormal, new Vector3d(texCoord));
+    }
+
+    @Override
+    public MeshPoint addNormal(MeshPoint addend) {
+        return addNormal(addend.getNormal());
+    }
+
+    @Override
+    public MeshPoint addNormal(Vector3d addend) {
+        Vector3d newNormal = new Vector3d(normal);
+        newNormal.add(addend);
+        newNormal.normalize();
+        return new MeshPointImpl(new Vector3d(position), newNormal, new Vector3d(texCoord));
+    }
+
+    /**
+     * @param obj compared object
+     * @return true if positions, normals and texture coordinates are equal, false otherwise
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof MeshPointImpl)) {
+            return false;
+        }
+
+        MeshPointImpl meshPointObj = (MeshPointImpl) obj;
+        return this.position.equals(meshPointObj.position)
+                && this.normal.equals(meshPointObj.normal)
+                && this.texCoord.equals(meshPointObj.texCoord);
+    }
+
+    /**
+     * returns hash of MeshPoint
+     *
+     * @return hash
+     */
+    @Override
+    public int hashCode() {
+        return position.hashCode() + normal.hashCode() + texCoord.hashCode();
+    }
+
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjExporter.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjExporter.java
index d3bed5084fa65398b8e1931b5d14ff4d69413968..e518c9adee25c1e061d031795743492c7e5dcf10 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjExporter.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjExporter.java
@@ -19,7 +19,7 @@ public class MeshObjExporter {
     /**
      * Model to be exported
      */
-    MeshModel model;
+    private MeshModel model;
     
     /**
      *
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
index 12ef65c44b81a258c918368b250925240a628e94..eb3e48c2f660245388c6d5aed0b804cbc6f066fc 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/MeshObjLoader.java
@@ -14,6 +14,7 @@ import cz.fidentis.analyst.mesh.core.CornerTableRow;
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshModel;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 
 import javax.vecmath.Vector3d;
 import java.io.File;
@@ -178,7 +179,7 @@ public class MeshObjLoader {
                 final OBJTexCoord texCoord = model.getTexCoord(reference);
                 texCoords = new Vector3d(texCoord.u, texCoord.v, texCoord.w);
             }
-            result.add(new MeshPoint(coords, norm, texCoords));
+            result.add(new MeshPointImpl(coords, norm, texCoords));
         }
         if (result.size() != 3) {
             throw new IOException("Mesh contains non-triangular face");
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/ModelFileFilter.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/ModelFileFilter.java
index 2507d8778dab9612a6cb0901d279105c2392b021..17a5f729bcf869daaa0225876d6c3d57a31d9f44 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/ModelFileFilter.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/io/ModelFileFilter.java
@@ -18,8 +18,7 @@ public class ModelFileFilter extends FileFilter {
      * @param extension Extentions of files
      * @param description Description
      */
-    public ModelFileFilter(String[] extension, String description)
-    {
+    public ModelFileFilter(String[] extension, String description) {
         this.extension = extension;
         this.description = description;
     }
@@ -30,8 +29,7 @@ public class ModelFileFilter extends FileFilter {
      * @return Whether file has chosen extension or not 
      */
     @Override
-    public boolean accept(File f)
-    {
+    public boolean accept(File f) {
         boolean accepted = false;
         for (String extension1 : extension) {
             if (f.isDirectory() || f.getName().endsWith(extension1)) {
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/io/MeshObjLoaderTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/io/MeshObjLoaderTest.java
index 96295a00a3df442f23a41367b27780d8f1856586..c6df9b5ad44b3f161bad6ec8b5fb1f61c39b5091 100644
--- a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/io/MeshObjLoaderTest.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/io/MeshObjLoaderTest.java
@@ -13,6 +13,7 @@ import com.mokiat.data.front.parser.OBJVertex;
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshModel;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -20,9 +21,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import javax.vecmath.Vector3d;
 
@@ -191,7 +190,7 @@ public class MeshObjLoaderTest {
                         final OBJTexCoord texCoord = model.getTexCoord(reference);
                         texCoords = new Vector3d(texCoord.u, texCoord.v, texCoord.w);
                     }
-                    points.add(new MeshPoint(coords, norm, texCoords));
+                    points.add(new MeshPointImpl(coords, norm, texCoords));
                 }
             }
         }