From f42912667f4d3a9c76844742c7fab223efb44e04 Mon Sep 17 00:00:00 2001
From: Maria Kocurekova <xkocure1@fi.muni.cz>
Date: Thu, 21 Jan 2021 10:09:59 +0100
Subject: [PATCH] #35 - add visitor

---
 .../fidentis/analyst/mesh/KdTree/KdNode.java  |  10 +-
 .../analyst/mesh/KdTree/KdTreeImpl.java       |  38 ++++--
 .../mesh/visitors/KdTreeBuildVisitor.java     |  19 +++
 .../analyst/mesh/KdTree/kdTreeTest.java       | 118 +++++++++++++++++-
 4 files changed, 169 insertions(+), 16 deletions(-)
 create mode 100644 MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java

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
index 77dfc3ac..842e024d 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
@@ -3,6 +3,7 @@ package cz.fidentis.analyst.mesh.KdTree;
 import cz.fidentis.analyst.mesh.core.MeshFacet;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -28,10 +29,13 @@ public class KdNode {
     }
 
     //return only one index (index of MeshPoint in the first MeshFacet)
-    public int getIndex() {
+   /* public int getIndex() {
         Map.Entry<MeshFacet, Integer> entry = facets.entrySet().iterator().next();
         return entry.getValue();
-    }
+    }*/
+    public Map<MeshFacet, Integer> getIndex(){
+       return Collections.unmodifiableMap(facets);
+   }
 
     public int getDepth() {
         return depth;
@@ -66,7 +70,7 @@ public class KdNode {
     }
 
     public Map<MeshFacet, Integer> getFacets() {
-        return facets;
+        return Collections.unmodifiableMap(facets);
     }
 
     public KdNode setParent(KdNode parent) {
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
index 52c5c890..c49d4a91 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
@@ -1,6 +1,7 @@
 package cz.fidentis.analyst.mesh.KdTree;
 
 import cz.fidentis.analyst.mesh.core.MeshFacet;
+import cz.fidentis.analyst.mesh.core.MeshFacetImpl;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
 
 import java.util.*;
@@ -78,22 +79,43 @@ public class KdTreeImpl {
     private final Comparator<Integer> zIndexComparatorF = Comparator.comparingDouble(i -> Objects.requireNonNull(findPointFacetIndex(i)).getPoint().getPosition().z);
 
 
-    public  KdTreeImpl(List<MeshFacet> facets) {
+
+
+    KdTreeImpl(Set<MeshPoint> points) {
+        if(points == null) {
+            this.root = null;
+            this.facets = null;
+            return;
+        }
+        MeshFacet newFacet = new MeshFacetImpl();
+        for(MeshPoint point : points) {
+            newFacet.addVertex(point);
+        }
+        this.facets = new LinkedList<>(Collections.singleton(newFacet));
+        prepareForBuildTree();
+
+    }
+
+    public KdTreeImpl(MeshFacet facet) {
+        this(new LinkedList<>(Collections.singleton(facet)));
+    }
+
+    KdTreeImpl(List<MeshFacet> facets) {
         if(facets == null ||  facets.isEmpty() || facets.get(0).getVertices().isEmpty() ){
             this.root = null;
             this.facets = null;
             return;
         }
+        this.facets = facets;
+        prepareForBuildTree();
+    }
 
+    private void prepareForBuildTree() {
         int countOfVertices = 0;
         for (MeshFacet facet : facets) {
             countOfVertices += facet.getVertices().size();
         }
 
-
-
-        this.facets = facets;
-
         List<Integer> sortedByX = sortPointsF( X_AXIS);
         List<Integer> sortedByY = sortPointsF( Y_AXIS);
         List<Integer> sortedByZ = sortPointsF( Z_AXIS);
@@ -125,6 +147,9 @@ public class KdTreeImpl {
         }
     }
 
+
+
+
     private Triple findPointFacetIndex(int index) {
         Triple result;
         int countOfCheckedVertices = 0;
@@ -164,7 +189,6 @@ public class KdTreeImpl {
     }
 
 
-
     private List<Integer> sortPointsF(int level){
         int countOfVertices = 0;
         for (MeshFacet facet : facets) {
@@ -415,7 +439,7 @@ public class KdTreeImpl {
      * @param p MeshPoint
      * @return index of MeshPoint in MeshFacetImpl -> vertices
      */
-    public Integer nearestNeighbourIndex(MeshPoint p){
+    public Map<MeshFacet, Integer> nearestNeighbourIndex(MeshPoint p){
         KdNode nn = nearestNeighbourNode(p);
 
         if(nn == null){
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java
new file mode 100644
index 00000000..ac0212ba
--- /dev/null
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java
@@ -0,0 +1,19 @@
+package cz.fidentis.analyst.mesh.visitors;
+
+import cz.fidentis.analyst.mesh.KdTree.KdTreeImpl;
+
+import cz.fidentis.analyst.mesh.core.MeshFacet;
+
+
+public class KdTreeBuildVisitor implements Visitor {
+    private KdTreeImpl kdTree;
+
+    @Override
+    public void visitMeshFacet(MeshFacet facet) {
+        kdTree = new KdTreeImpl(facet);
+    }
+
+    public KdTreeImpl getKdTree() {
+        return kdTree;
+    }
+}
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
index eeec7de1..9a1d2766 100644
--- a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
@@ -6,9 +6,7 @@ import cz.fidentis.analyst.mesh.core.MeshPointImpl;
 import org.junit.jupiter.api.Test;
 
 import javax.vecmath.Vector3d;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 
 import static org.junit.jupiter.api.Assertions.*;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -234,10 +232,118 @@ public class kdTreeTest {
         Random r = new Random();
 
         MeshPoint p = points.get(r.nextInt(points.size()));
-        int found = tree.nearestNeighbourIndex(p);
 
-        assertEquals(points.get(found), p);
-        assertEquals(0.0f, distancePoints(points.get(found), p));
+        MeshPoint foundP = tree.nearestNeighbour(p);
+        Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p);
+        Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next();
+
+        assertEquals(foundP, p);
+        assertEquals(entry.getKey().getVertex(entry.getValue()),p );
+
+
+    }
+
+    @Test
+    public void testIndexFoundTwoFacetsAllDuplicates(){
+        List<MeshFacet> facets = new LinkedList<>();
+
+        MeshFacet facet1 = new MeshFacetImpl();
+        MeshFacet facet2 = new MeshFacetImpl();
+
+
+        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));
+            facet1.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+        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));
+            facet2.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+
+        facets.add(facet1);
+        facets.add(facet2);
+        KdTreeImpl tree = new KdTreeImpl(facets);
+
+        Random r = new Random();
+
+        MeshPoint p = points.get(r.nextInt(points.size()));
+
+        MeshPoint foundP = tree.nearestNeighbour(p);
+        Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p);
+        Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next();
+
+        assertEquals(foundP, p);
+        assertEquals(entry.getKey().getVertex(entry.getValue()),p );
+
+        MeshFacet second = (new ArrayList<MeshFacet>(found.keySet())).get(1);
+        int secondIndex = (new ArrayList<Integer>(found.values())).get(1);
+        assertEquals(second.getVertex(secondIndex),p );
+
+        assertEquals(0.0f, distancePoints(second.getVertex(secondIndex), entry.getKey().getVertex(entry.getValue())));
+    }
+
+
+    @Test
+    public void testOneFacetNearNeighbourIndex(){
+        MeshFacet facet1 = new MeshFacetImpl();
+
+
+        List<MeshPoint> points = new LinkedList<>();
+        Vector3d positionOfPoints;
+
+        for(int i = 1; i < 20; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+            facet1.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+        KdTreeImpl tree = new KdTreeImpl(facet1);
+
+        Random r = new Random();
+
+        MeshPoint p = points.get(r.nextInt(points.size()));
+
+        MeshPoint foundP = tree.nearestNeighbour(p);
+        Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p);
+        Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next();
+
+        assertEquals(foundP, p);
+        assertEquals(entry.getKey().getVertex(entry.getValue()),p );
+
+
+    }
+
+    @Test
+    public void testSetOfPointsNearNeighbourIndex(){
+        Set<MeshPoint> points = new HashSet<>();
+        List<MeshPoint> pointsList = new LinkedList<>();
+        Vector3d positionOfPoints;
+
+        for(int i = 1; i < 20; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+            pointsList.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+        KdTreeImpl tree = new KdTreeImpl(points);
+
+        Random r = new Random();
+        MeshPoint p = pointsList.get(r.nextInt(points.size()));
+
+        MeshPoint foundP = tree.nearestNeighbour(p);
+        Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p);
+        Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next();
+
+        assertEquals(foundP, p);
+        assertEquals(entry.getKey().getVertex(entry.getValue()),p );
+
+
     }
 
 /*
-- 
GitLab