From 01357f06534e0558e64f8be1c7936c4b4f45945f Mon Sep 17 00:00:00 2001
From: Timon Roemer <t.roemer@vis.rwth-aachen.de>
Date: Fri, 19 Jul 2024 14:11:56 +0200
Subject: [PATCH] Adds MagicWand with KDTree

---
 Content/BP_PointCloud.uasset                  | Bin 24133 -> 27728 bytes
 Content/MagicWandMap.umap                     | Bin 43795 -> 43681 bytes
 Plugins/UEPlugin-Kdtree                       |   1 +
 Source/MetaCastBachelor/MagicWand.cpp         | 143 ++++++++++--------
 Source/MetaCastBachelor/MagicWand.h           |   1 +
 .../MetaCastBachelor.Build.cs                 |   2 +-
 Source/MetaCastBachelor/MetaPoint.cpp         |   1 -
 Source/MetaCastBachelor/PointCloud.cpp        |   7 +-
 Source/MetaCastBachelor/PointCloud.h          |  27 ++--
 9 files changed, 103 insertions(+), 79 deletions(-)
 create mode 160000 Plugins/UEPlugin-Kdtree

diff --git a/Content/BP_PointCloud.uasset b/Content/BP_PointCloud.uasset
index b730c627f98a9a952404a479005bc656cb881805..630f4bc467f5517f4b0d0712ef2c32feeb0479c6 100644
GIT binary patch
delta 7103
zcmX@Qhw;J<#tBcDetS&jW|Er3$immmz`(%E#K6GBz`!t{cd}2kdME=F2rw`({1jwh
zkYZq9c*)Da@Kc<DfsuiMAytBbAy<Ndp;Ll^VbaInp=J^Hz1o=0&$gRlKW8qR^VU`0
z`~6#|-w(3<7@7@I4>G5Davx)`(o+cr2ALeF@lfjj|NsAgdoVC0GB7YG<ZNbUYGV}P
zVPIfzD$UGE@lGizN=;>Oh*94+xs!PvFDnBBgG*vbA_J$V^S#aHEH#V*93U4}q$Zb^
zq%veqf3j-xX4adGY!M7cqdS;3H?mhSf;APV=A<#iFY5K0{FB3npPhk$p}3@|G`WOf
zisH10$*!E9U{xU?%T_8FS5EHZyd}ZUz`&p%oLrPyP@)fY$e&YlBP1tJw3D9P!quZF
z335$pT4HHVNqjs+g;Rh}W>QgNQ6+=+8{U<Z1-LKBh%hiPcpLfUr=-R^C+6h1mF6Xv
zWaj5Fe4oDL%;X2$M(QBfKy)*l?T+~l3N8p2VVK5xf6mE5JVmCw3=9kqCj~>??=9NW
z!3h#{4vq)e!C-j#(ov9!VX4U_`9%!NWLQ!rPv!BdPlASbHk5w%|Ns9&DBBrIgD7n3
zN<k6~3=D+SmEl%b&wy-kIc|k;b#MRw|6fI<x@v;z>KPc`{Qv(youER9x(p)KWfG~b
zpq@yD#Hwo~(!3C;x_W$Z_xk_;|0Pg`_|(1n|Nnm_5$az4|Np-ZRUO1%sZc?fAs_>D
zp<>u9u7S#dC{O_bq6w*kC16x_5c?UB4NL}^h9gxYt4kqL9n5p67DF`GK<x+f(!eBY
zc7ln)f(;aed05oJeAfV#1Lcw?C>xu_Fm;lkpsv88@W&(pWl(+a&PQ&tvw)1+_y7O@
zfB66ZKU6707L)-hWVk`aIRgX3NAJlWMdc<h7SIucmF9*F3=9{b(tms=e-u@l%q^lI
z1rjNOngA-PcS6}`{7{s{L4`p|)<W5>{tzXCB5I$I+yknpilIt085kIJp=_f7uySo7
z6){k81+o}q+GiGsd^|+jTUbE~Bmyd_U`lM5AxeTm!6qOp0a*qz#Q~&;fq|hf0z(N%
zGf0UKRLQv*u#(ln3R0lj3RKd;ESdmfFfcGkC4!Z33yP@yM)DcR6}2FOfdO0{UtxoA
zRwYe-=c6_`TSP$$<eq$pC<DmzT2OXfCfG!6Q3WYb^#LjzKz4!L#SdaIFfgpZR01*$
zq~saYl<iqyQ%(!2h=Ga?kVcR+Ea}e821|E~D(Hax3X%dP3N8i)22h0qQqB!E31l)z
z?EU}$|0kapm0$%+PEPbRoFvFKSzb(qqfml@L4tvSVRF5=_~axpQMOtM28P!jn`^}u
zG09GP{r^8R10xt(FbIHYS1`%Qz&QDUr2FLa1{|BaCBsA}Ki82{=7UN(Gn6r8G2}9&
zGAJ_mFr+e+G88kUF{CjtGU!cyprdLi3RUOBV9empP{5GNkj9X};KGo^kjs$E;LcFS
zkk639P|A?SP{5GSz{sEv(luFMp2Oai!Ggh=!JWaB!I{C7!I;66!HvO*!HL0`!IHs>
z!JNU8!HvP0!HmI@!JNT~!HU6x!IHt9!JNT`!IHs*!E|z*zNWhZ-1aPn5{5j6G=@?J
zeFi76-7XBd3`q<n3?&R{3?&Tu7;f=mNP)V^5bUPuN_?t@4EhX43|0(=3}y_*3}y_v
z3?2-23?NaEJ50bXvz&ZN$&k?q7G&oB3`t=Bl{2I<fY=~cFf#B$T?P^X`5q*zh$L?e
zw)3naha@6|QN!0{@&g@R?ofDmn}T)R*W}<Y0mniaI9wSS%s}Fd;*%AO#AT69&_|0e
zbFg`?VAm!wFfv$x^~r$rsk<-~fb9um2w+HN$Yw|bo2}0f4rPI485u0We&&_qn5?O1
zz-To&N^c{hHOQ37hWZAKHegn}z7eA>m~~&@i_s3u@;9(xv<K@wZ(zgd02VVeG+}fE
zi>)>EVRQnE$s6@CI)ho4jkFkDK&;Km#)nuZ|2N~)G+{7dP-4(wP-3uPP-3uRPy!_a
zsE8qh0bI;%@;zf!W)lYU$uZ_2+G6r9OKDzE)IoHaG8jxgXIVHo+k$WMYs(N2&1}kG
zIQgBWDzhnr(d0Q+p_9K_%7NKJ*2<zK3`Gp345?t7jTkJ!_83mSXCW_X%3ucOMKe@0
zC@~m;*-8wi4Ca&jjI}jQ!R|zMuPInJNCe?tGX?{&d(9XOC&!puPd;ne$7nWrfw?Fz
zC;>wJYsO$Qxz0+T*^I$-@&j{oUNf-0AakHHjAoPXnQL$Mx9(uc0Cg-D?7ai-RDcQ&
zPY}Vtz~Bm{L8T0s3964k#SDmJ1|k?37~qnivIbOKfy6O%f=a{K$@UK7LNF<?Z6MA1
zn8Kg}TX^zB2XQr9kZB+cD&9fud=MK}zp8^c3=9nBlg~Mbt3^P0;4<4B%7F=*feJoQ
z&t~#R0SQS(G+B@{KtiC3M@BLL#AIM#fawLf9VC=6`J<?YT_A|bz`&pfrD1v*7#JGt
zVJ^dCfq;Z8$Srs*5s;Xy;v}Gl$D#zdMWE^)<Pg`%Nls>h=q@$^`L>>w!J}Qb{JHz=
zCAx?HbnTCWITEA~Z-gN$1Vuea11OeZQD_7bU;uSSL1ik4W?&G6ih*h+7jU0!vV*gT
z7ThRM69T4R8mg9&0ZIR4eP>mK6ThO>%Pbr%48Q*W|E~<!3T2?RA3@2*3n~Q*m03`}
zHYij$wV}MQ$x1GriZJ)-Kt*AC=0f@CdfvM92*UJ$q7$SnY;u>Yk|<0RBoYK7KpAQB
zL01tYCnyi(HV_lkAqCN}-~eYOP`JTs^T`|BWF?J3YOo|naOA31$seAwg7>p~$ND{i
z)`Cg0IIU-N0_8J4xMd($a}%~;@;^5LMC>szFxWty12YII{WCB)PZo3&hbKcfs8TCX
zfY)0>c^Dc${{R2q0xAj1@1S4+3xPWSAO_4|4j>K#0|Q3!Q^3f;;D}2y0W^AI50!<*
zEi7My1Jc*Yd;j%m8ms(Pwr%Y*Iq|ImW+6xus5}DEpr+KCExS{scHVYv*Ri@i#Y*@a
zHZiTqj=mCH;Fcjsn={D&jLx8D*W|Un`kEju`<2(U|7Vf*Up6&u{+a(0=dg)IO?LE^
z<OH=Zv6xa1(lNvEqimYsIhXEJ=HknJw}@gB3kGRsU|;|TDM$fi5Cq&-3`s0XPc1=a
zf`);>8eG66qH_d_C8!XXVq$Qf{83b!1>Cgk^VBp1B`A;#$cpP%)kK9hiMcHOzh%qS
zcv-Lo=wdM--zkNIv>;{PXJ{Fo0X5jfm7bd3o3P2fDaWVx;EcPHAj{CjBtW6B%z$q4
z^Z)<<Gr}ARvK169;*%G9%1mDGt2%jt6N{t<NEj)rp(J2?oC)|Rz69(GHPd<Wc6UW3
zB`8k~N`oVXfq_8<%4blW{L9^%(+<iFn{4NiA&EEPPQLCTV2hksK_xUuJILs~3&E>H
zJXW}^R$L{Z`Tt!7HZgZlJaEc_w1DDa@<#y?R*;W;q3P9F_4e<}tcRKodTw6#k@v>!
zs~R9v(8chkRhk5>58TDu-4*R|X8j8c3=A{~bpsy(M(4?m0ph9whI41`F<I?8C2Og#
z)>&m1Q0a{>hAWJHz+wD0&{*}1ae!~G;VHL?qB8IJUoGwgnSw5cJB;538c+V>E5OJ(
z`J=BequXRhUy;d@ei};XnHUtW&|rg5@Z3d{DDs0?!T?VDxT9zRBTb^HAOI9ajy}Sg
zpf>AOJKKA^wAkIdZ;GcFOE+D@CWb4T{J_x!D!M_suBGHJ)t-09aaFzavfJ?+K4BBX
z9aU?6^%=P)8wLqONjY$2MF#0`dP74?7g}9>6jh#lD#&%Rf*S|+Dm9+G5(zfQ11mJ}
z7cbj`QHvK?2?`ow_*oO~Vj=O!VP?v~^ZUP;MPL)d8xoQ*H-Nkj3P+F$ARDA6?+DQh
z0Tnc09!Q#jfdNzxmlTzzGJtXiRtb<9SS3IvfSM|zll?+1#pOX<1_lO@a;Mbv%)Ee{
z#7YM1$@4-r8KWnk2(=Q2wPQglobz*XGK)cT1)`fJ!x9-8<tJB%%Q8ZhZ$2Cz%*ZG@
zSv=B72xczGp&^;c*>EGLMusqoPJR{H&nQ2+DoP%vck+>_y2(1BlHhR}kIC-QI*bC7
z_q$7)A%_ddtzsYo)RKhKAg_R#pa!xyn8m>0I{9O)2&WK~7diPsv?-$qsMV(hYjc4+
zU7#jaJX8_Zw$SAK7y&a=s0xf08LZWg>_oWpCV#LOQG>e&Y6RS|pn)_L=SkvsM`)~o
z9!___dLPK{@CW%e2F160&`~^)TVO43(7YCi4_C;<z`y`f2nre*kPNn<1}Si!%ob-4
E01(j0EC2ui

delta 5267
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

diff --git a/Content/MagicWandMap.umap b/Content/MagicWandMap.umap
index 1db0e16a514f1f959cebb98ac2a2e703aacb7123..bd7492ae734fcd1e7e27825d4ae8845abe574fec 100644
GIT binary patch
delta 13486
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
H{wfmyAzE?0

delta 14212
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
ZTLLwJ0X+GGIlzTuqzeBC)a2Y%CIH99mV5vJ

diff --git a/Plugins/UEPlugin-Kdtree b/Plugins/UEPlugin-Kdtree
new file mode 160000
index 0000000..94ef56d
--- /dev/null
+++ b/Plugins/UEPlugin-Kdtree
@@ -0,0 +1 @@
+Subproject commit 94ef56d465cf19d96e17b6e34c3a3739e1384a7e
diff --git a/Source/MetaCastBachelor/MagicWand.cpp b/Source/MetaCastBachelor/MagicWand.cpp
index 8541999..4b2f64b 100644
--- a/Source/MetaCastBachelor/MagicWand.cpp
+++ b/Source/MetaCastBachelor/MagicWand.cpp
@@ -1,4 +1,6 @@
 #include "MagicWand.h"
+
+#include "KdtreeBPLibrary.h"
 #include "Utilities.h"
 #include "Generators/MarchingCubes.h"
 
@@ -88,7 +90,7 @@ void UMagicWand::InitMagicWandSelection()
 	World = GetWorld();
 	
 	AbortMarchingCubes = true;
-	AccumulatedTime = 0.0f;
+	//AccumulatedTime = 0.0f;
 }
 
 void UMagicWand::SelectParticles(const FVector& InputPosition)
@@ -96,7 +98,8 @@ void UMagicWand::SelectParticles(const FVector& InputPosition)
 	if (AccumulatedTime >=  1 / EvaluationsPerSecond)
 	{
 		AccumulatedTime = -10000;
-		
+
+		UE_LOG(LogTemp, Warning, TEXT("Input recognized!"));
 		AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
 		{
 			const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
@@ -104,7 +107,7 @@ void UMagicWand::SelectParticles(const FVector& InputPosition)
 
 			PerformMagicWandSelection(SelectionLocalPosition);
 
-			UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
+			//UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
 		});
 		
 	}
@@ -118,6 +121,8 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
         return;
     }
 
+	UE_LOG(LogTemp, Warning, TEXT("Starting Selection!"));
+
 	//UE_LOG(LogTemp, Warning, TEXT("Looking for Seed Index:"));
     // Find the closest point to the input position as the seed
     const int32 InputVoxelIndex = MyDensityField->WorldPositionToIndex(InputPosition);
@@ -126,21 +131,42 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
     int32 SeedIndex = INDEX_NONE;
     float MinDistance = FLT_MAX;
 
-    for (const int CurrentNeighborIndex : Neighbors)
-    {
-	    TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentNeighborIndex);
 
-    	for(const int32 CurrentIndex : PointIndices)
-    	{
-    		FVector CurrentPosition = MyDensityField->IndexToVoxelPosition(CurrentIndex);
-    		const float Distance = FVector::Dist(InputPosition, CurrentPosition);
-    		if (Distance < MinDistance)
-    		{
-    			MinDistance = Distance;
-    			SeedIndex = CurrentIndex;
-    		}
-    	}
-    }
+	for(int NeighborDistance = 0; NeighborDistance < 3; ++NeighborDistance)
+	{
+		const int NumNeighbors = Neighbors.Num();
+
+		for (int i = 0; i < NumNeighbors; ++i)
+		{
+			const int CurrentNeighborIndex = Neighbors[i];
+			TArray<int32> NeighborsOfNeighbors = MyDensityField->IndexToVoxelNeighbors(CurrentNeighborIndex);
+
+			for (int CurrentNeighborOfNeighborIndex : NeighborsOfNeighbors)
+			{
+				if (!Neighbors.Contains(CurrentNeighborOfNeighborIndex))
+				{
+					Neighbors.Add(CurrentNeighborOfNeighborIndex);
+				}
+			}
+		}
+	}
+	
+    
+	for (const int CurrentNeighborIndex : Neighbors)
+	{
+		TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentNeighborIndex);
+
+		for(const int32 CurrentIndex : PointIndices)
+		{
+			FVector CurrentPosition = MyDensityField->IndexToVoxelPosition(CurrentIndex);
+			const float Distance = FVector::Dist(InputPosition, CurrentPosition);
+			if (Distance < MinDistance)
+			{
+				MinDistance = Distance;
+				SeedIndex = CurrentIndex;
+			}
+		}
+	}
 
     if (SeedIndex != INDEX_NONE)
     {
@@ -149,80 +175,76 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
     	
         //Expand selection from the seed
         ExpandSelection(SeedIndex);
+    }else
+    {
+	    AccumulatedTime = 0;
     }
-
-	
 }
 
 void UMagicWand::ExpandSelection(const int32 SeedIndex)
 {
+	UE_LOG(LogTemp, Warning, TEXT("Expanding!"));
     TQueue<int32> ToProcess;
     ToProcess.Enqueue(SeedIndex);
 	
     SelectedClusterIndices.Add(SeedIndex);
     MyPointCloud->SelectionFlags[SeedIndex] = true;
+
+	const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold;
+	TArray<int> Indices;
+	TArray<FVector> Data;
 	
     while (!ToProcess.IsEmpty())
     {
         int32 CurrentQueuePointIndex;
         ToProcess.Dequeue(CurrentQueuePointIndex);
 
-        FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex];
+        const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex];
 
-    	const int32 CurrentVoxelQueueIndex = MyDensityField->WorldPositionToIndex(CurrentQueuePointPosition);
-
-    	/*
-    	TArray<int32> Neighbors = MyDensityField->IndexToVoxelNeighbors(CurrentVoxelQueueIndex);
-    	Neighbors.Add(CurrentVoxelQueueIndex);
+    	Indices.Empty();
+    	Data.Empty();
     	
-    	for (const int CurrentVoxelNeighborIndex : Neighbors)
-    	{    		
-    		TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentVoxelNeighborIndex);
-
-    		for(const int32 CurrentPointComparisonIndex : PointIndices)
-    		{
-    			if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex])
-    			{
-    				continue;
-    			}
-    			FVector CurrentComparisonPosition = MyDensityField->IndexToVoxelPosition(CurrentPointComparisonIndex);
-
-    			if (FVector::Dist(CurrentQueuePointPosition, CurrentComparisonPosition) <= ProximityThreshold)
-    			{
-    				ToProcess.Enqueue(CurrentPointComparisonIndex);
-    				SelectedClusterIndices.Add(CurrentPointComparisonIndex);
-    				MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true;
-    			}
-    		}
-    	}*/
-		// -------------------
+    	UKdtreeBPLibrary::CollectFromKdtree(MyPointCloud->MyKdTree, CurrentQueuePointPosition, MyPointCloud->InfluenceRadius, Indices, Data);
 
+		for(int i = 0; i < Indices.Num(); ++i)
+		{
+			const int CurrentPointComparisonIndex = Indices[i];
+			
+			if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex])
+			{
+				continue;
+			}
+			
+			ToProcess.Enqueue(CurrentPointComparisonIndex);
+			MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true;
+		}
+    	
+    	/*
     	const int32 StartX = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.X - ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X));
     	const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.X + ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X));
     	const int32 StartY = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Y - ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y));
     	const int32 EndY = FMath::Min(MyDensityField->GetYNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Y + ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y));
     	const int32 StartZ = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Z - ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z));
     	const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Z + ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z));
-
-
-    	/*
+    	
+    	
     	UE_LOG(LogTemp, Warning, TEXT("CurrentQueuePointPosition: %s"), *CurrentQueuePointPosition.ToString());
     	UE_LOG(LogTemp, Warning, TEXT("StartX: %d"), StartX);
     	UE_LOG(LogTemp, Warning, TEXT("EndX: %d"), EndX);
     	UE_LOG(LogTemp, Warning, TEXT("StartY: %d"), StartY);
     	UE_LOG(LogTemp, Warning, TEXT("EndY: %d"), EndY);
     	UE_LOG(LogTemp, Warning, TEXT("StartZ: %d"), StartZ);
-    	UE_LOG(LogTemp, Warning, TEXT("EndZ: %d"), EndZ);*/
+    	UE_LOG(LogTemp, Warning, TEXT("EndZ: %d"), EndZ);
 
-    	ParallelFor(EndZ - StartZ + 1, [&](const int32 ZOffset) {
-		    const int32 Z = StartZ + ZOffset;
-			
+    	for (int32 Z = StartZ; Z <= EndZ; ++Z)
+    	{			
     		for (int32 Y = StartY; Y <= EndY; ++Y)
     		{
 				for (int32 X = StartX; X <= EndX; ++X)
 				{
 					const int32 CurrentVoxelComparisonIndex = MyDensityField->GridPositionToIndex(X, Y, Z);
 
+					/*
 					if(!MyDensityField->IsValidIndex(CurrentVoxelComparisonIndex))
 					{
 						continue;
@@ -238,26 +260,21 @@ void UMagicWand::ExpandSelection(const int32 SeedIndex)
 						}
     					
 						FVector CurrentComparisonPosition = MyPointCloud->PositionVectors[CurrentPointComparisonIndex];
-						const double Distance = FVector::Distance(CurrentQueuePointPosition, CurrentComparisonPosition);
-
-						//UE_LOG(LogTemp, Warning, TEXT("CurrentQueuePointPosition: %s"), *CurrentQueuePointPosition.ToString());
-						//UE_LOG(LogTemp, Warning, TEXT("CurrentComparisonPosition: %s"), *CurrentComparisonPosition.ToString());
+						const double SquaredDistance = FVector::DistSquared(CurrentQueuePointPosition, CurrentComparisonPosition);
 
-						//UE_LOG(LogTemp, Warning, TEXT("Distance: %f"), Distance);
-
-						if (Distance <= ProximityThreshold)
+						if (SquaredDistance <= SquaredProximityThreshold)
 						{
 							ToProcess.Enqueue(CurrentPointComparisonIndex);
-							SelectedClusterIndices.Add(CurrentPointComparisonIndex);
+							//SelectedClusterIndices.Add(CurrentPointComparisonIndex);
 							MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true;
 						}
 					}
 				}
 			}
-		});
-    	
+		}*/
     }
 
+	UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
 	AccumulatedTime = 0;
 }
 
diff --git a/Source/MetaCastBachelor/MagicWand.h b/Source/MetaCastBachelor/MagicWand.h
index a59cde4..e84de2e 100644
--- a/Source/MetaCastBachelor/MagicWand.h
+++ b/Source/MetaCastBachelor/MagicWand.h
@@ -30,6 +30,7 @@ class UMagicWand : public UMetaCastBaseline
 	float MarchingCubeSize = 0;
 	UPROPERTY(EditAnywhere)
 	int EvaluationsPerSecond = 10;
+	UPROPERTY(EditAnywhere)
 	float AccumulatedTime = 0.0;
 	UPROPERTY(EditAnywhere)
 	float ProximityThreshold = 0.1f;
diff --git a/Source/MetaCastBachelor/MetaCastBachelor.Build.cs b/Source/MetaCastBachelor/MetaCastBachelor.Build.cs
index 89ad2bf..26018c6 100644
--- a/Source/MetaCastBachelor/MetaCastBachelor.Build.cs
+++ b/Source/MetaCastBachelor/MetaCastBachelor.Build.cs
@@ -10,7 +10,7 @@ public class MetaCastBachelor : ModuleRules
 	
 		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ProceduralMeshComponent", "EnhancedInput"});
 
-		PrivateDependencyModuleNames.AddRange(new string[] {"GPUPointCloudRenderer", "GPUPointCloudRendererEditor", "RWTHVRToolkit", "ProceduralMeshComponent"});
+		PrivateDependencyModuleNames.AddRange(new string[] {"GPUPointCloudRenderer", "GPUPointCloudRendererEditor", "RWTHVRToolkit", "ProceduralMeshComponent", "Kdtree"});
 
 		// Uncomment if you are using Slate UI
 		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
diff --git a/Source/MetaCastBachelor/MetaPoint.cpp b/Source/MetaCastBachelor/MetaPoint.cpp
index 2e908f0..e42fe89 100644
--- a/Source/MetaCastBachelor/MetaPoint.cpp
+++ b/Source/MetaCastBachelor/MetaPoint.cpp
@@ -1,7 +1,6 @@
 #include "MetaPoint.h"
 #include "Utilities.h"
 #include "Generators/MarchingCubes.h"
-#include "UObject/GCObjectScopeGuard.h"
 
 UMetaPoint::UMetaPoint() : LocalMaximumIndex(0), MyDensityField(nullptr), MetaPointThreshold(0), World(nullptr)
 {
diff --git a/Source/MetaCastBachelor/PointCloud.cpp b/Source/MetaCastBachelor/PointCloud.cpp
index d319ce9..a5f6813 100644
--- a/Source/MetaCastBachelor/PointCloud.cpp
+++ b/Source/MetaCastBachelor/PointCloud.cpp
@@ -1,9 +1,10 @@
 #include "PointCloud.h"
+#include "KdtreeBPLibrary.h"
 #include "PointCloudDataReader.h"
 
 // Sets default values
 APointCloud::APointCloud()
-	: MyDensityField(nullptr), PointCloudVisualizer(nullptr), SelectedMaterial(nullptr), UnselectedMaterial(nullptr)
+	: MyDensityField(nullptr), MyKdTree(), PointCloudVisualizer(nullptr), SelectedMaterial(nullptr), UnselectedMaterial(nullptr)
 {
 	// Set this actor to call Tick() every frame.
 	PrimaryActorTick.bCanEverTick = true;
@@ -18,6 +19,10 @@ void APointCloud::BeginPlay()
 	ReadPointCloudFromFile(PointInputData, FlagInputData);
 	InitPointCloudVisualizer();
 	SetupDensityFieldFromPointCloud();
+	
+	UKdtreeBPLibrary::BuildKdtree(MyKdTree, PositionVectors);
+	//UKdtreeBPLibrary::DumpKdtreeToConsole(MyKdTree);
+	UKdtreeBPLibrary::ValidateKdtree(MyKdTree);
 }
 
 void APointCloud::ReadPointCloudFromFile(const FFilePath FileNamePoints, const FFilePath FileNameFlags)
diff --git a/Source/MetaCastBachelor/PointCloud.h b/Source/MetaCastBachelor/PointCloud.h
index 9de2a62..68b6499 100644
--- a/Source/MetaCastBachelor/PointCloud.h
+++ b/Source/MetaCastBachelor/PointCloud.h
@@ -1,6 +1,7 @@
 #pragma once
 #include "CoreMinimal.h"
 #include "GPUPointCloudRendererComponent.h"
+#include "KdtreeCommon.h"
 #include "GameFramework/Actor.h"
 #include "MetaCastBachelor/DensityField.h"
 #include "PointCloud.generated.h"
@@ -12,29 +13,30 @@ class APointCloud : public AActor
 	GENERATED_BODY()
 	
 public:
-	UPROPERTY(EditAnywhere)
-	float InfluenceRadius = 3.0f;
-
+	mutable FCriticalSection DataGuard;
 	FDensityField* MyDensityField;
+	FVector MinBounds;
+	FVector MaxBounds;
+	FKdtree MyKdTree;
+
 	UPROPERTY()
 	TArray<FVector> PositionVectors;
+	
 	UPROPERTY()
 	TArray<bool> DefaultFlags;
+	
 	UPROPERTY()
 	TArray<bool> SelectionFlags;
+	
 	UPROPERTY()
 	TArray<FColor> PointColors;
-	mutable FCriticalSection DataGuard;
 
-	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Bounds")
-	FVector MinBounds;
-
-	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Bounds")
-	FVector MaxBounds;
-	
 	UPROPERTY()
 	UGPUPointCloudRendererComponent* PointCloudVisualizer;
-	
+
+	UPROPERTY(EditAnywhere)
+	float InfluenceRadius = 3.0f;
+
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Visualization")
 	float SplatSize = 1.0f;
 	
@@ -49,8 +51,7 @@ public:
 	
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
 	UMaterialInterface* UnselectedMaterial;
-
-	// Sets default values for this actor's properties
+	
 	APointCloud();
 	void InitPointCloudVisualizer();
 	void UpdateBounds();
-- 
GitLab