From 9470cd0107af2d305c2d568d12acc7e78f71238f Mon Sep 17 00:00:00 2001
From: Maria Kocurekova <xkocure1@fi.muni.cz>
Date: Tue, 24 Nov 2020 21:13:21 +0100
Subject: [PATCH] #35 KdTree class and KdNode class - the first implementation

---
 FIDENTIS-Analyst-parent.iml                   |  12 -
 GUI/GUI.iml                                   |  23 --
 MeshModel/MeshModel.iml                       |  49 ---
 .../fidentis/analyst/mesh/KdTree/KdNode.java  |  66 ++++
 .../analyst/mesh/KdTree/KdTreeImpl.java       | 326 ++++++++++++++++++
 .../analyst/mesh/KdTree/KdTreeImplTests.java  | 106 ++++++
 Renderer/Renderer.iml                         |  14 -
 application/FIDENTIS-Analyst-app.iml          | 111 ------
 branding/FIDENTIS-Analyst-branding.iml        |  14 -
 9 files changed, 498 insertions(+), 223 deletions(-)
 delete mode 100644 FIDENTIS-Analyst-parent.iml
 delete mode 100644 GUI/GUI.iml
 delete mode 100644 MeshModel/MeshModel.iml
 create mode 100644 MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
 create mode 100644 MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
 create mode 100644 MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java
 delete mode 100644 Renderer/Renderer.iml
 delete mode 100644 application/FIDENTIS-Analyst-app.iml
 delete mode 100644 branding/FIDENTIS-Analyst-branding.iml

diff --git a/FIDENTIS-Analyst-parent.iml b/FIDENTIS-Analyst-parent.iml
deleted file mode 100644
index 4fd5057c..00000000
--- a/FIDENTIS-Analyst-parent.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/GUI/GUI.iml b/GUI/GUI.iml
deleted file mode 100644
index c8d17b0f..00000000
--- a/GUI/GUI.iml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.jogamp.jogl:jogl-all:2.0-rc11" level="project" />
-    <orderEntry type="module" module-name="MeshModel" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.github.mokiat:java-data-front:v2.0.0" level="project" />
-    <orderEntry type="library" name="Maven: javax.vecmath:vecmath:1.5.2" level="project" />
-  </component>
-</module>
diff --git a/MeshModel/MeshModel.iml b/MeshModel/MeshModel.iml
deleted file mode 100644
index 80a28bc5..00000000
--- a/MeshModel/MeshModel.iml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/../application/src/test/java" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <content url="file://$MODULE_DIR$/../application/src/test/java" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:7.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.beust:jcommander:1.72" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.google.inject:guice:no_aop:4.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: javax.inject:javax.inject:1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: aopalliance:aopalliance:1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.google.guava:guava:19.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: com.github.mokiat:java-data-front:v2.0.0" level="project" />
-    <orderEntry type="library" name="Maven: javax.vecmath:vecmath:1.5.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:7.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.beust:jcommander:1.72" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.google.inject:guice:no_aop:4.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: javax.inject:javax.inject:1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: aopalliance:aopalliance:1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.google.guava:guava:19.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
new file mode 100644
index 00000000..f0c30dd5
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
@@ -0,0 +1,66 @@
+package cz.fidentis.analyst.mesh.KdTree;
+
+import cz.fidentis.analyst.mesh.core.MeshPoint;
+
+
+public class KdNode {
+    private int index;
+    // represents index of vertices in the class MashFacetImpl in the attribute vertices
+    private final int depth;
+    private MeshPoint id;
+
+    private KdNode lesser = null;
+    private KdNode greater = null;
+    private KdNode parent;
+
+    public KdNode(int index, int depth, MeshPoint id, KdNode parent) {
+        this.index = index;
+        this.depth = depth;
+        this.id = id;
+        this.parent = parent;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
+    public MeshPoint getId() {
+        return id;
+    }
+
+    public KdNode getLesser() {
+        return lesser;
+    }
+
+    public KdNode getGreater() {
+        return greater;
+    }
+
+    public KdNode getParent() {
+        return parent;
+    }
+
+    public KdNode setId(MeshPoint id) {
+        this.id = id;
+        return this;
+    }
+
+    public KdNode setLesser(KdNode lesser) {
+        this.lesser = lesser;
+        return this;
+    }
+
+    public KdNode setGreater(KdNode greater) {
+        this.greater = greater;
+        return this;
+    }
+
+    public KdNode setParent(KdNode parent) {
+        this.parent = parent;
+        return this;
+    }
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
new file mode 100644
index 00000000..43e339e5
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
@@ -0,0 +1,326 @@
+package cz.fidentis.analyst.mesh.KdTree;
+
+import cz.fidentis.analyst.mesh.core.MeshPoint;
+
+
+import javax.vecmath.Vector3d;
+import java.util.*;
+
+public class KdTreeImpl {
+    private final KdNode root;
+    private final List<MeshPoint> points;
+
+    //private Map<MeshPoint, Integer> pointsWithIndex = new HashMap<>();
+
+    private final static int X_AXIS = 0;
+    private final static int Y_AXIS = 1;
+    private final static int Z_AXIS = 2;
+
+
+
+
+    public KdTreeImpl(List<MeshPoint> points) {
+        if(points == null || points.isEmpty()){
+            this.root = null;
+            this.points = null;
+            return;
+        }
+
+        this.points = points;
+
+        List<Integer> pointsCopy = new ArrayList<>(points.size());
+        for(int i = 0; i < points.size(); i++){
+            pointsCopy.add(i);
+        }
+
+        pointsCopy = deleteDuplicates(points); //(pointsCopy,
+
+        List<Integer> sortedByX = sortPoints(pointsCopy, X_AXIS, points);
+        List<Integer> sortedByY = sortPoints(pointsCopy, Y_AXIS, points);
+        List<Integer> sortedByZ = sortPoints(pointsCopy, Z_AXIS, points);
+
+
+        root = buildTree(null, sortedByX, sortedByY, sortedByZ, 0, points);
+
+    }
+
+    private boolean comparePointsOnLevel(MeshPoint p1, MeshPoint p2, int level){
+        if(level % 3 == 0){
+            return p1.getPosition().x <= p2.getPosition().x;
+        }else if(level % 3 == 1){
+            return p1.getPosition().y <= p2.getPosition().y;
+        }else if(level % 3 == 2){
+            return p1.getPosition().z <= p2.getPosition().z;
+        }
+
+        return false;
+    }
+
+    private List<Integer> merge(List<Integer> left, List<Integer> right, int level, List<MeshPoint> points){
+        List<Integer> mergedList = new ArrayList<>(left.size() + right.size());
+
+        int fromLeft = 0;
+        int fromRight = 0;
+
+        while(fromLeft < left.size() || fromRight < right.size()){
+            if(fromLeft < left.size() && fromRight < right.size()){
+                if(comparePointsOnLevel(points.get(left.get(fromLeft)), points.get(right.get(fromRight)), level)){
+                    mergedList.add(left.get(fromLeft));
+                    fromLeft++;
+                }else{
+                    mergedList.add(right.get(fromRight));
+                    fromRight++;
+                }
+            }else if(fromLeft < left.size()){
+                mergedList.add(left.get(fromLeft));
+                fromLeft++;
+            }else if(fromRight < right.size()){
+                mergedList.add(right.get(fromRight));
+                fromRight++;
+            }
+        }
+
+        return mergedList;
+    }
+
+    private List<Integer> mergeSort(List<Integer> points, int level, List<MeshPoint> p){
+        if(points.size() <= 1){
+            return points;
+        }
+
+        List<Integer> left;
+        List<Integer> right;
+
+        int mid = (points.size()/2);
+
+        left = points.subList(0, mid);
+        right = points.subList(mid, points.size());
+
+
+        left = mergeSort(left, level, p);
+        right = mergeSort(right, level, p);
+
+        return merge(left, right, level, p);
+    }
+
+    private List<Integer> sortPoints(List<Integer> points, int level, List<MeshPoint> p){
+        List<Integer> sortedList = new ArrayList<>(points.size());
+
+        sortedList.addAll(points);
+
+        sortedList = mergeSort(sortedList,level, p);
+
+        return sortedList;
+
+    }
+
+
+    private List<Integer> deleteDuplicates(List<MeshPoint> points){ // List<Integer> list
+        List<Vector3d> noDuplicates = new ArrayList<>();
+        List<Integer> noDupIndex = new ArrayList<>();
+
+        for(int i = 0; i < points.size(); i++){
+            if(!noDuplicates.contains(points.get(i).getPosition())){
+                noDuplicates.add(points.get(i).getPosition());
+                noDupIndex.add(i);
+            }
+        }
+
+        return noDupIndex;
+    }
+
+
+    private KdNode buildTree(KdNode parent, List<Integer> byX, List<Integer> byY, List<Integer> byZ, int level, List<MeshPoint> points) {
+        KdNode node = null;
+        int mid;
+        int midIndex;
+
+        if(byX.size() > 0 && byY.size() > 0 && byZ.size() > 0){
+            mid = (byX.size() / 2);
+
+            List<Integer> leftX = new ArrayList<>(mid);
+            List<Integer> leftY = new ArrayList<>(mid);
+            List<Integer> leftZ = new ArrayList<>(mid);
+
+            //split lists in half, set middle element as new KdNode to be returned
+            //first list to be split based on level, rest so that they contain points in first list
+            //but also keep the ordering by their axis
+            if (level % 3 == 0){
+                midIndex = byX.get(mid);
+                node = new KdNode(midIndex, level, points.get(byX.get(mid)), parent);
+
+                splitTree(mid, leftX, byX, leftY, byY, leftZ, byZ);
+
+            }else if(level % 3 == 1){
+                midIndex = byY.get(mid);
+                node = new KdNode(midIndex, level, points.get(byY.get(mid)), parent);
+
+                splitTree(mid, leftY, byY, leftX, byX, leftZ, byZ);
+
+            }else{
+                midIndex = byZ.get(mid);
+                node = new KdNode(midIndex, level, points.get(byZ.get(mid)), parent);
+
+                splitTree(mid, leftZ, byZ, leftY, byY, leftX, byX);
+
+            }
+
+            //removes current middle node from each all lists, in case there were duplicates
+            byX.removeAll(Collections.singleton(midIndex));
+            byY.removeAll(Collections.singleton(midIndex));
+            byZ.removeAll(Collections.singleton(midIndex));
+            leftX.removeAll(Collections.singleton(midIndex));
+            leftY.removeAll(Collections.singleton(midIndex));
+            leftZ.removeAll(Collections.singleton(midIndex));
+
+            node.setLesser(buildTree(node, leftX, leftY, leftZ, level + 1, points));
+            node.setGreater(buildTree(node, byX, byY, byZ, level + 1, points));
+        }
+
+        return node;
+    }
+
+    private void splitTree(int mid, List<Integer> leftMain, List<Integer> mainList, List<Integer> leftSecond,
+                           List<Integer> secondList, List<Integer> leftThird, List<Integer> thirdList){
+        for (int i = 0; i < mid; i++) {
+
+            leftMain.add(mainList.get(0));
+
+            mainList.remove(0);
+        }
+
+        splitArray(leftMain, leftSecond, secondList);
+        splitArray(leftMain, leftThird, thirdList);
+    }
+
+    private void splitArray(List<Integer> leftMain, List<Integer> leftSecond, List<Integer> secondList){
+        for(int i = secondList.size() - 1; i >= 0; i--){
+            if(leftMain.contains(secondList.get(i))){
+                leftSecond.add(0, secondList.get(i));
+                secondList.remove(i);
+            }
+        }
+    }
+    public MeshPoint nearestNeighbour(MeshPoint p){
+        KdNode nn = nearestNeighbourNode(p);
+
+        if(nn == null){
+            return null;
+        }
+
+        return nn.getId();
+    }
+
+    public boolean containPoint(MeshPoint p){
+        MeshPoint found = nearestNeighbour(p);
+
+        if(found == null){
+            return false;
+        }
+
+        return found.equals(p);
+    }
+
+     public double distancePoints(MeshPoint point1, MeshPoint point2) {
+        return Math.sqrt(Math.pow(point1.getPosition().x - point2.getPosition().x, 2)
+                + Math.pow(point1.getPosition().y - point2.getPosition().y, 2)
+                + Math.pow(point1.getPosition().z - point2.getPosition().z, 2));
+    }
+
+    private double minDistanceIntersection(MeshPoint searched, MeshPoint p2, int level){
+        if(level % 3 == 0){
+            return Math.abs(searched.getPosition().x - p2.getPosition().x);
+        }else if(level % 3 == 1){
+            return Math.abs(searched.getPosition().y - p2.getPosition().y);
+        }else{
+            return Math.abs(searched.getPosition().z - p2.getPosition().z);
+        }
+    }
+
+
+
+    public KdNode nearestNeighbourNode(MeshPoint p) {
+        if(p == null || this.root == null){
+            return null;
+        }
+
+        double minDistance = Double.MAX_VALUE;
+        double distOnAxis;
+        KdNode near = root;
+        KdNode searched = root;
+
+        Queue<KdNode> queue = new LinkedList<>();
+
+        while(searched != null){
+            if(distancePoints(p, searched.getId()) < minDistance){
+                near = searched;
+                minDistance = distancePoints(p, searched.getId());
+            }
+
+            if(comparePointsOnLevel(p, searched.getId(), searched.getDepth())){
+                searched = searched.getLesser();
+            }else{
+                searched = searched.getGreater();
+            }
+        }
+
+        queue.add(root);
+
+        //second search to find vertex that could be potentially closer than
+        //nearest vertex already found
+        while (!queue.isEmpty()) {
+
+            //if min distance is 0, break cycle (nothing can be closer)
+            if(minDistance == 0){
+                break;
+            }
+
+            searched = queue.poll();
+
+            if (distancePoints(p, searched.getId()) < minDistance) {
+                near = searched;
+                minDistance = distancePoints(p, searched.getId());
+            }
+
+            distOnAxis = minDistanceIntersection(searched.getId(), p, searched.getDepth());
+
+            if (distOnAxis > minDistance) {
+                if (comparePointsOnLevel(p, searched.getId(), searched.getDepth())) {
+                    if (searched.getLesser() != null) {
+                        queue.add(searched.getLesser());
+                    }
+                } else {
+                    if (searched.getGreater() != null) {
+                        queue.add(searched.getGreater());
+                    }
+                }
+            } else {
+                if (searched.getLesser() != null) {
+                    queue.add(searched.getLesser());
+                }
+                if (searched.getGreater() != null) {
+                    queue.add(searched.getGreater());
+                }
+            }
+        }
+
+        return near;
+
+    }
+
+    /**
+     * Find index of MeshPoint in MeshFacetImpl -> vertices
+     * @param p MeshPoint
+     * @return index of MeshPoint in MeshFacetImpl -> vertices
+     */
+    public Integer nearestNeighbourIndex(MeshPoint p){
+        KdNode nn = nearestNeighbourNode(p);
+
+        if(nn == null){
+            return null;
+        }
+
+        return nn.getIndex();
+    }
+
+}
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java
new file mode 100644
index 00000000..f6cf8f5e
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java
@@ -0,0 +1,106 @@
+package cz.fidentis.analyst.mesh.KdTree;
+
+import cz.fidentis.analyst.mesh.core.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
+import org.junit.Test;
+
+import javax.vecmath.Vector3d;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import static org.junit.Assert.*;
+
+
+public class KdTreeImplTests {
+    private Vector3d position = new Vector3d(0.1f, 0.5f, 0.7f);
+    private Vector3d normalAndTextCoord = new Vector3d(0,0,0);
+
+    @Test
+    public void testPut(){
+        MeshPoint p = new MeshPointImpl(position,normalAndTextCoord,normalAndTextCoord);
+
+        List<MeshPoint> points = new LinkedList<>();
+        points.add(p);
+        KdTreeImpl tree = new KdTreeImpl(points);
+
+        assertTrue(tree.containPoint(p));
+    }
+
+    @Test
+    public void testPutNothing(){
+        MeshPoint p = new MeshPointImpl(position,normalAndTextCoord,normalAndTextCoord);
+
+        List<MeshPoint> points = new LinkedList<>();
+        KdTreeImpl tree = new KdTreeImpl(points);
+
+        assertFalse(tree.containPoint(p));
+    }
+
+    public double distancePoints(MeshPoint point1, MeshPoint point2) {
+        return Math.sqrt(Math.pow(point1.getPosition().x - point2.getPosition().x, 2)
+                + Math.pow(point1.getPosition().y - point2.getPosition().y, 2)
+                + Math.pow(point1.getPosition().z - point2.getPosition().z, 2));
+    }
+
+
+    private MeshPoint findClosestSequential(List<MeshPoint> points, MeshPoint p){
+        if(points.isEmpty()){
+            return null;
+        }
+
+        MeshPoint closest = points.get(0);
+        double dis = distancePoints(closest, p);
+
+        for(MeshPoint cl : points){
+            if(distancePoints(cl, p) < dis){
+                dis = distancePoints(cl, p);
+                closest = cl;
+            }
+        }
+
+        return closest;
+    }
+
+    @Test
+    public void testFindClosestAlreadyIn(){
+        List<MeshPoint> points = new LinkedList<>();
+         Vector3d positionOfPoints;
+
+        for(int i = 0; i < 10; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+        KdTreeImpl tree = new KdTreeImpl(points);
+        Random r = new Random();
+
+        MeshPoint p = points.get(r.nextInt(points.size()));
+        MeshPoint found = tree.nearestNeighbour(p);
+
+        assertEquals(found, p);
+        assertTrue(distancePoints(found, p) == 0.0f);
+    }
+
+    @Test
+    public void testFindClosestNotInTree(){
+        List<MeshPoint> points = new LinkedList<>();
+        Vector3d positionOfPoints;
+
+        for(int i = 0; i < 10; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+        KdTreeImpl tree = new KdTreeImpl(points);
+
+        MeshPoint p = new MeshPointImpl(new Vector3d(2.5f, 0.3f, 1.2f), normalAndTextCoord,normalAndTextCoord);
+        MeshPoint found = tree.nearestNeighbour(p);
+
+        MeshPoint seq = findClosestSequential(points, p);
+
+        assertEquals(found, seq);
+        assertTrue(distancePoints(found, p) == distancePoints(seq, p));
+    }
+
+}
diff --git a/Renderer/Renderer.iml b/Renderer/Renderer.iml
deleted file mode 100644
index 14061d54..00000000
--- a/Renderer/Renderer.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/application/FIDENTIS-Analyst-app.iml b/application/FIDENTIS-Analyst-app.iml
deleted file mode 100644
index f7dd0b48..00000000
--- a/application/FIDENTIS-Analyst-app.iml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:asm-all-5.0.1:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-filesystems:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-modules:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-util:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-util-lookup:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-bootstrap:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-util-ui:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-libs-asm:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-core-startup-base:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.ow2.asm:asm-all:5.0.1" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot-fx:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot-script:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-boot:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-geo:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-json:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html-sound:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:net-java-html:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:swing-layout-1.0.4:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-libs-javafx:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-awt:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-dialogs:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-windows:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-intent:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-progress:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-progress-nb:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-queries:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-swing-outline:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-actions:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-explorer:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-filesystems-nb:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-io:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-loaders:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-nodes:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-text:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-core:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-core-startup:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-execution:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-core-windows:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-options-api:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-swing-tabcontrol:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-editor-mimelookup:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-libs-jna:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-libs-jna-platform:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-libs-osgi:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-keyring:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-openide-filesystems-compat8:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-io:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-modules-options-keymap:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-swing-plaf:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-sampler:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-spi-quicksearch:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-settings:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:org-netbeans-html-ko4j:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:org-netbeans-html-xhr4j:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.main:4.2.1" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.framework:4.2.1" level="project" />
-    <orderEntry type="library" name="Maven: net.java.dev.jna:jna-platform:4.2.2" level="project" />
-    <orderEntry type="library" name="Maven: net.java.dev.jna:jna:4.2.2" level="project" />
-    <orderEntry type="library" name="Maven: junit:junit:4.12" level="project" />
-    <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:osgi.core-5.0.0:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:osgi.cmpn-4.2:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:testng-6.8.1-dist:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-autoupdate-services:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-sendopts:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:updater:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-core-ui:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-libs-felix:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-modules-autoupdate-cli:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-autoupdate-ui:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-modules-favorites:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-modules-masterfs:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-modules-print:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: javax.help:javahelp:2.0.05" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.modules:org-netbeans-modules-keyring-fallback:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-core-netigso:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.external:org.eclipse.osgi_3.9.1.v20140110-1610:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-htmlui:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-templates:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-lib-uihandler:RELEASE82" level="project" />
-    <orderEntry type="module" module-name="FIDENTIS-Analyst-branding" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.netbeans.api:org-netbeans-modules-nbjunit:RELEASE82" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.netbeans.modules:org-netbeans-insane:RELEASE82" level="project" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-libs-junit4:RELEASE82" level="project" />
-    <orderEntry type="module" module-name="MeshModel" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core-utils:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:vecmath:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: java3d:j3d-core:1.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.github.mokiat:java-data-front:v2.0.0" level="project" />
-    <orderEntry type="library" name="Maven: javax.vecmath:vecmath:1.5.2" level="project" />
-    <orderEntry type="module" module-name="Renderer" />
-    <orderEntry type="module" module-name="GUI" />
-    <orderEntry type="library" name="Maven: org.jogamp.jogl:jogl-all:2.0-rc11" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.0" level="project" />
-  </component>
-</module>
diff --git a/branding/FIDENTIS-Analyst-branding.iml b/branding/FIDENTIS-Analyst-branding.iml
deleted file mode 100644
index 14061d54..00000000
--- a/branding/FIDENTIS-Analyst-branding.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: org.netbeans.api:org-netbeans-api-annotations-common:RELEASE82" level="project" />
-  </component>
-</module>
\ No newline at end of file
-- 
GitLab