From ef6972606e6e6d4693c63c1c863fd2e64fee047f Mon Sep 17 00:00:00 2001
From: Timon Roemer <t.roemer@vis.rwth-aachen.de>
Date: Wed, 17 Jul 2024 18:15:29 +0200
Subject: [PATCH] Starts implementing MagicWand

---
 Content/MagicWandMap.umap                | Bin 0 -> 43101 bytes
 Content/MagicWandPawn.uasset             | Bin 0 -> 68061 bytes
 Content/MetaPointMap.umap                | Bin 45108 -> 45078 bytes
 Source/MetaCastBachelor/DensityField.cpp |  36 ++-
 Source/MetaCastBachelor/DensityField.h   |   8 +-
 Source/MetaCastBachelor/MagicWand.cpp    | 315 +++++++++++++++++++++++
 Source/MetaCastBachelor/MagicWand.h      |  57 ++++
 Source/MetaCastBachelor/MetaPoint.cpp    | 196 ++++++++------
 Source/MetaCastBachelor/MetaPoint.h      |   1 +
 Source/MetaCastBachelor/PointCloud.cpp   |   2 +-
 Source/MetaCastBachelor/PointCloud.h     |   2 +-
 Source/MetaCastBachelor/Utilities.cpp    |   4 +-
 12 files changed, 524 insertions(+), 97 deletions(-)
 create mode 100644 Content/MagicWandMap.umap
 create mode 100644 Content/MagicWandPawn.uasset
 create mode 100644 Source/MetaCastBachelor/MagicWand.cpp
 create mode 100644 Source/MetaCastBachelor/MagicWand.h

diff --git a/Content/MagicWandMap.umap b/Content/MagicWandMap.umap
new file mode 100644
index 0000000000000000000000000000000000000000..432e39ca2127b23880bf35d2220201a73ca86de3
GIT binary patch
literal 43101
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
JHiQXM4**AMl}!Ku

literal 0
HcmV?d00001

diff --git a/Content/MagicWandPawn.uasset b/Content/MagicWandPawn.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..9472186a5940e9e6147f87a741f1b214548baeff
GIT binary patch
literal 68061
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
R7J)3M_G^NQSCAM;JpgmlwgvzI

literal 0
HcmV?d00001

diff --git a/Content/MetaPointMap.umap b/Content/MetaPointMap.umap
index a90f205a3061d3582938745c1b4c3550588e57fa..e65a8b10eadfdfb9712a93fbbe490b559b6eb5ed 100644
GIT binary patch
delta 712
zcmdn;fN9zTrVV!(1y0K>4tlaj(R1<@Gl#pY`En+|VJu*Jw0?3NlN8gl^_#1hE;ut5
zO!jt5XOc^p>=-IF`J9^z(+LPO&skxzpSucU(BxwGc*YBpFT2MxB_vOdah96w=i$QC
zn+(>l&clW2FGQ5j(}hVZ1uP2E+vlmm6r2fGf6mi|sUZ_C<L9Nq#G3`?_IbH5ZHF*H
zdicCmn6~ADW&FHd7-c3;_Ks(YEd&eX`4~*L^ATZUFNShmnASp>&I*&?`KU0Jmw;vZ
ze03&A`ARVDfN@=zUQ~c(z*hLFF#V_iJIl|{g-Nv%EVItfg(;^REXwEa!ZZ`Y%=33)
zItF2$^LJtTTn$zWGQ}@Ig-N#-tiCV6g=u{)Sms@T3sYSklxZ-zE>MI?rykC|7bwDX
z3&Q0Ka$)LdfXe7ho)sj)B-scy?Oc!xlU@s0MlaZf$*~*E1X;N*ScPfJIxzQLunW@x
z7}H>KU5E%%;CiqONMXQSmd%$!qM5kNbq!7R3=H&4Ehn3YFBABA|JkvH@6USA4Y?OC
zW_#qq=C|QuY|IJ{s*@ELNlccD6JgAnd^gU3%aZ{LTqozo*{GIe6s4xd7iH$97c+c?
z%B+UcI*brTE?A=vgu}q#F*!HRe6n9W8#j{X&3W;)LafHd#`aGqFI*(CnWJbuqX2tP
g>`Rw~i+-z|{MLV%{a1RjVzI&GfKaK;f+fl}06Qf4?*IS*

delta 738
zcmbRCfN9GErVV!(1zZo@o;}Tp({cJcTj@8ZQ`;xMVJu)`*f2ScNs5VO!{#cc3(kyv
zlfB*2nQRg!Gloh{&U03n{LW2<=^2Ep=kCH-FuB-0p7Gt}%kJ?^b;*-soTVoFdAKmG
zPKIkZ=b^$RodTBO^K@bINP)}rd8#lKW`bqTdAcyo%LL2ldATrYXMvd@`__4>FkOXk
z-+8$(UCD*Z<aw(wT1}qp9nVx<2odx#m~7`G!lYUZ<+?DPhB848_fcV*S^}2o^VOLg
z<txE-4aRk0VygtpfNbRRQ(+RT1Ut*m&xOeuBD2oVg{i9=EXwEa!n7U2%=33)dIDjd
z^LJqqtbv>27ofuAT?<y<7vRElwiYbo7ich9E>MJNP92o%!sJyCWg1Mr7bwE?1H$DC
za$#E50F}|1JS#|o$-EJ4+PNSXCZ86tj9#z{Q+zj=*%$1>bZH%!=@()!SuR9`=^l*h
z!j!)rECcf0he<4(FNH)iahd5Fn(CPv=@}VJHV<DWFk{}~;KPZhyf<099zIxiMtbwx
za4|M!27A@Xg|j3k%f*Q>R!%+_XTTM~00kkFbK`7Git`c+;++kQ;*AUp;th?=;}i2T
za}!H4^Ya+KLKUut(mIR~Mh)1UXb6XaA$)RfocUz?cs42AW^E3LuN7iWOH12)q3|T5
mfOXAjqcd`Wt_`jyr>@#K(|s~yqr{{x$w^(3n?DyT+W-J&p!Mwl

diff --git a/Source/MetaCastBachelor/DensityField.cpp b/Source/MetaCastBachelor/DensityField.cpp
index 6c6af6b..0af1af8 100644
--- a/Source/MetaCastBachelor/DensityField.cpp
+++ b/Source/MetaCastBachelor/DensityField.cpp
@@ -5,7 +5,7 @@
 
 // INITIALIZATION FUNCTIONS
 
-FDensityField::FDensityField(): XNum(0), YNum(0), ZNum(0), XStep(0), YStep(0), ZStep(0), VoxelPointLookupTable(nullptr)
+FDensityField::FDensityField(): XNum(0), YNum(0), ZNum(0), XStep(0), YStep(0), ZStep(0), MaxDensity(0), MinDensity(0), AvgDensity(0), VoxelPointLookupTable(nullptr)
 {
 	VoxelList = TArray<FVoxel>();
 }
@@ -17,8 +17,8 @@ void FDensityField::InitializeDensityField(const APointCloud* PointCloud, const
 	VoxelPointLookupTable = new FVoxelPointLookupTable();
 	VoxelPointLookupTable->Initialize(PointCloud->PositionVectors, this);
 	
-	CalculateVoxelDensities_2(PointCloud, PointCloud->InfluenceRadius);
-	//CalculateVoxelDensitiesByNumber(PointCloud, 4);
+	//CalculateVoxelDensities_2(PointCloud, PointCloud->InfluenceRadius);
+	CalculateVoxelDensitiesSimple(PointCloud, PointCloud->InfluenceRadius);
 	CalculateAndStoreGradients();
 }
 
@@ -101,7 +101,7 @@ void FDensityField::CalculateVoxelDensities(const APointCloud* PointCloud, const
 	        }
 	    }
 	}
-	double MaxDensity = 0.0;
+	MaxDensity = 0.0;
 	for (const auto& Node : VoxelList)
 	{
 		if (Node.GetVoxelDensity() > MaxDensity)
@@ -118,7 +118,7 @@ void FDensityField::CalculateVoxelDensities(const APointCloud* PointCloud, const
 
 }
 
-void FDensityField::CalculateVoxelDensitiesByNumber(const APointCloud* PointCloud, const float InfluenceRadius)
+void FDensityField::CalculateVoxelDensitiesSimple(const APointCloud* PointCloud, const float InfluenceRadius)
 {
     if (!PointCloud)
         return;
@@ -160,7 +160,8 @@ void FDensityField::CalculateVoxelDensitiesByNumber(const APointCloud* PointClou
 
                         if (Distance < InfluenceRadius)
                         {
-                            VoxelList[Index].AddToVoxelDensity(1.0);  // Simply increment the density count
+	                        const float Weight = FUtilities::SmoothingKernel(Distance, InfluenceRadius);
+                            VoxelList[Index].AddToVoxelDensity(Weight);  // Simply increment the density count
                         }
                     }
                 }
@@ -168,15 +169,21 @@ void FDensityField::CalculateVoxelDensitiesByNumber(const APointCloud* PointClou
         }
     }
 
-    double MaxDensity = 0.0;
+    MaxDensity = MIN_flt;
+    MinDensity = MAX_FLT;
+	AvgDensity = 0;
     for (const auto& Node : VoxelList)
     {
-        if (Node.GetVoxelDensity() > MaxDensity)
-        {
-            MaxDensity = Node.GetVoxelDensity();
-        }
+	    const float Dens = Node.GetVoxelDensity();
+    	MaxDensity = FMath::Max(Dens, MaxDensity);
+    	MinDensity = FMath::Min(Dens, MinDensity);
+    	AvgDensity += Dens;
     }
-    UE_LOG(LogTemp, Log, TEXT("Maximum density found: %f"), MaxDensity);
+	AvgDensity /= VoxelList.Num();
+	
+	UE_LOG(LogTemp, Log, TEXT("Maximum density found: %f"), MaxDensity);
+	UE_LOG(LogTemp, Log, TEXT("Minimum density found: %f"), MinDensity);
+	UE_LOG(LogTemp, Log, TEXT("Average density found: %f"), AvgDensity);
 
 	const double EndTime = FPlatformTime::Seconds();  // End timing
 	const double ElapsedTime = EndTime - StartTime;  // Calculate elapsed time
@@ -412,14 +419,15 @@ void FDensityField::CalculateAndStoreGradients()
 
 //	DEBUG FUNCTIONS
 
-void FDensityField::DrawDebugVoxelDensity(const UWorld* World, const AActor* Actor, const float Duration, const float Scale, const float DensityThreshold) const
+void FDensityField::DrawDebugVoxelDensity(const UWorld* World, const AActor* Actor, const float Duration, const float Scale, const float DensityThreshold)
 {
 	if (!World || !Actor)
 	{
 		return;
 	}
 
-	double MinDensity = DBL_MAX, MaxDensity = 0;
+	MinDensity = DBL_MAX;
+	MaxDensity = 0;
 	for (const FVoxel& Node : VoxelList)
 	{
 		const double LogDensity = log10(Node.GetVoxelDensity() + 1);  // Avoiding log(0)
diff --git a/Source/MetaCastBachelor/DensityField.h b/Source/MetaCastBachelor/DensityField.h
index 5a3cd26..1e86417 100644
--- a/Source/MetaCastBachelor/DensityField.h
+++ b/Source/MetaCastBachelor/DensityField.h
@@ -42,12 +42,18 @@ class FDensityField
     float XStep, YStep, ZStep;
 	FVector GridOrigin;
 
+	
+
 	void CalculateVoxelDensities(const APointCloud* PointCloud, float InfluenceRadius, float Sigma);
-	void CalculateVoxelDensitiesByNumber(const APointCloud* PointCloud, float InfluenceRadius);
+	void CalculateVoxelDensitiesSimple(const APointCloud* PointCloud, float InfluenceRadius);
 	void CalculateAndStoreGradients();
+	void DrawDebugVoxelDensity(const UWorld* World, const AActor* Actor, float Duration, float Scale, float DensityThreshold);
 	void InitializeDataStructures(const FVector& MinBounds, const FVector& MaxBounds, int32 XAxisNum, int32 YAxisNum, int32 ZAxisNum);
 	
 public:
+	double MaxDensity;
+	double MinDensity;
+	double AvgDensity;
 	FVoxelPointLookupTable* VoxelPointLookupTable;
 	mutable FCriticalSection DataGuard;
 	// CONSTRUCTOR
diff --git a/Source/MetaCastBachelor/MagicWand.cpp b/Source/MetaCastBachelor/MagicWand.cpp
new file mode 100644
index 0000000..360602a
--- /dev/null
+++ b/Source/MetaCastBachelor/MagicWand.cpp
@@ -0,0 +1,315 @@
+#include "MagicWand.h"
+#include "Utilities.h"
+#include "Generators/MarchingCubes.h"
+
+UMagicWand::UMagicWand() : World(nullptr)
+{
+	// Create the procedural mesh component
+	ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
+	SelectedClusterIndices.Reserve(100000);
+}
+
+void UMagicWand::BeginPlay()
+{
+	Super::BeginPlay();
+
+	World = GetWorld();
+	
+	if (!World) {
+		UE_LOG(LogTemp, Warning, TEXT("Invalid world provided."));
+	}
+
+	ProceduralMesh->AttachToComponent(MyPointCloud->PointCloudVisualizer, FAttachmentTransformRules::SnapToTargetIncludingScale);
+	ProceduralMesh->SetMaterial(0, SelectionVolumeMat);
+	ProceduralMesh->SetMaterial(1, SelectionVolumeMat);
+	ProceduralMesh->SetMaterial(2, SelectionVolumeMat);
+	ProceduralMesh->bCastDynamicShadow = false;
+	ProceduralMesh->bRenderCustomDepth = true;
+	ProceduralMesh->SetCastShadow(false);
+	ProceduralMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
+	ProceduralMesh->SetMobility(EComponentMobility::Movable);
+	ProceduralMesh->SetVisibility(true);
+
+}
+
+void UMagicWand::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	AccumulatedTime += DeltaTime;
+
+	ProceduralMesh->SetVisibility(Select);
+
+	if (Select)
+	{
+		PerformMagicWandSelection(SelectionObject->GetComponentLocation());
+	}
+}
+
+void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
+{
+    if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num())
+    {
+        UE_LOG(LogTemp, Warning, TEXT("PerformMagicWandSelection: Positions and SelectionFlags array sizes do not match."));
+        return;
+    }
+
+    // Find the closest point to the input position as the seed
+    int32 SeedIndex = INDEX_NONE;
+    float MinDistance = FLT_MAX;
+
+    for (int32 i = 0; i < MyPointCloud->PositionVectors.Num(); i++)
+    {
+        FVector CurrentPoint = MyPointCloud->PositionVectors[i];
+        CurrentPoint = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(CurrentPoint);
+
+        const float Distance = FVector::Dist(InputPosition, CurrentPoint);
+        if (Distance < MinDistance)
+        {
+            MinDistance = Distance;
+            SeedIndex = i;
+        }
+    }
+
+    if (SeedIndex != INDEX_NONE)
+    {
+        // Clear previous selection
+        SelectedClusterIndices.Empty();
+        for (bool& Flag : MyPointCloud->SelectionFlags)
+        {
+            Flag = false;
+        }
+
+        // Expand selection from the seed
+        ExpandSelection(SeedIndex);
+
+    	for (int32 i = 0; i < SelectedClusterIndices.Num(); i++)
+        {
+	        const int Index = SelectedClusterIndices[i];
+            MyPointCloud->SelectionFlags[Index] = true;
+        }
+    }
+}
+
+void UMagicWand::ExpandSelection(const int32 SeedIndex)
+{
+    TQueue<int32> ToProcess;
+    ToProcess.Enqueue(SeedIndex);
+    SelectedClusterIndices.Add(SeedIndex);
+    MyPointCloud->SelectionFlags[SeedIndex] = true;
+
+    while (!ToProcess.IsEmpty())
+    {
+        int32 CurrentIndex;
+        ToProcess.Dequeue(CurrentIndex);
+        FVector CurrentPoint = MyPointCloud->PositionVectors[CurrentIndex];
+        CurrentPoint = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(CurrentPoint);
+
+        for (int32 i = 0; i < MyPointCloud->PositionVectors.Num(); i++)
+        {
+            if (!MyPointCloud->SelectionFlags[i])
+            {
+                FVector Point = MyPointCloud->PositionVectors[i];
+                Point = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(Point);
+
+                if (FVector::Dist(CurrentPoint, Point) <= ProximityThreshold)
+                {
+                    ToProcess.Enqueue(i);
+                    SelectedClusterIndices.Add(i);
+                    MyPointCloud->SelectionFlags[i] = true;
+                }
+            }
+        }
+    }
+}
+
+
+void UMagicWand::EraseParticles(const FVector& InputPosition)
+{
+	
+}
+
+void UMagicWand::HandleMetaSelectReleased(const FInputActionInstance& Instance)
+{
+	Super::HandleMetaSelectReleased(Instance);
+
+	//ProceduralMesh->ClearAllMeshSections();
+	//ProceduralMesh->SetVisibility(false);
+
+
+	AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
+	{
+		MyPointCloud->ColorPointsInVoxels(FloodedIndices);
+	});
+}
+
+void UMagicWand::HandleMetaSelectPressed(const FInputActionInstance& Instance)
+{
+	Super::HandleMetaSelectPressed(Instance);
+
+	UE_LOG(LogTemp, Warning, TEXT("PerformMagicWandSelection"));
+	InitMagicWandSelection();
+}
+
+void UMagicWand::InitMagicWandSelection()
+{	
+	const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
+	MyDensityField = MyPointCloud->MyDensityField;
+
+	// Convert the world position of the selection object to the local position relative to the point cloud
+	const FVector SelectionLocalPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition);
+	
+	ProceduralMesh->ClearAllMeshSections();
+	World = GetWorld();
+	
+	AbortMarchingCubes = true;
+	AccumulatedTime = 0.0f;
+}
+
+void UMagicWand::SelectParticles(const FVector& InputPosition)
+{
+	if (AccumulatedTime >=  1 / EvaluationsPerSecond)
+	{
+		AccumulatedTime = -10000;
+
+		AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
+		{
+			const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
+			
+			
+		});
+	}
+}
+
+void UMagicWand::GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const
+{
+	TArray<FVector> Vertices;
+	TArray<int32> Triangles;
+	TArray<FColor> VertexColors;
+
+	// Generate cube vertices and triangles for each voxel
+	for (const int32 VoxelIndex : Voxels)
+	{
+		if(!MyDensityField->IsValidIndex(VoxelIndex))
+		{
+			continue;
+		}
+
+		TArray<FVector> VoxelCorners = MyDensityField->IndexToVoxelCornersWorld(VoxelIndex);
+
+		// Add vertices for the voxel
+		const int32 BaseIndex = Vertices.Num();
+		Vertices.Append(VoxelCorners);
+
+		// Define the triangles (12 triangles for 6 faces of the cube)
+		// Each face of the cube has 2 triangles (6 faces * 2 triangles per face = 12 triangles)
+		Triangles.Append({
+			BaseIndex + 0, BaseIndex + 1, BaseIndex + 2, BaseIndex + 0, BaseIndex + 2, BaseIndex + 3, // Bottom face
+			BaseIndex + 4, BaseIndex + 6, BaseIndex + 5, BaseIndex + 4, BaseIndex + 7, BaseIndex + 6, // Top face
+			BaseIndex + 0, BaseIndex + 4, BaseIndex + 1, BaseIndex + 1, BaseIndex + 4, BaseIndex + 5, // Front face
+			BaseIndex + 1, BaseIndex + 5, BaseIndex + 2, BaseIndex + 2, BaseIndex + 5, BaseIndex + 6, // Right face
+			BaseIndex + 2, BaseIndex + 6, BaseIndex + 3, BaseIndex + 3, BaseIndex + 6, BaseIndex + 7, // Back face
+			BaseIndex + 3, BaseIndex + 7, BaseIndex + 0, BaseIndex + 0, BaseIndex + 7, BaseIndex + 4  // Left face
+		});
+		
+		// Add red color for each corner vertex
+		for (int32 i = 0; i < 8; ++i)
+		{
+			VertexColors.Add(FColor::Green);
+		}
+	}
+
+	// Create the mesh section
+	AsyncTask(ENamedThreads::Type::GameThread, [this, Vertices, Triangles, VertexColors]()
+	{
+		//CreateMeshSections(Vertices, Triangles, VertexColors, 1000);
+		ProceduralMesh->CreateMeshSection(0, Vertices, Triangles, TArray<FVector>(), TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), false);
+		ProceduralMesh->SetVisibility(true);
+	});
+}
+
+void UMagicWand::GenerateVoxelMeshSmooth(const TArray<int32> Voxels)
+{
+	if(IsMarchingCubesRunning)
+		return;
+
+	IsMarchingCubesRunning = true;
+	
+	FScopeLock Lock(&ProceduralMeshGuard);
+	AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this, Voxels]()
+	{
+		FVector Min(FLT_MAX, FLT_MAX, FLT_MAX);
+		FVector Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+		
+		for(const int FloodedIndex : Voxels)
+		{
+			Min = FVector::Min(Min, MyDensityField->IndexToVoxelPosition(FloodedIndex));
+			Max = FVector::Max(Max, MyDensityField->IndexToVoxelPosition(FloodedIndex));
+		}
+
+		UE::Geometry::FMarchingCubes MarchingCubes;
+		MarchingCubes.Bounds = UE::Geometry::TAxisAlignedBox3(Min, Max);
+		MarchingCubes.CubeSize = MarchingCubeSize == 0 ? MyDensityField->GetStep().X : MarchingCubeSize;
+		MarchingCubes.CancelF = [this]() {
+			return AbortMarchingCubes;
+		};
+		MarchingCubes.IsoValue = 0;
+
+		AbortMarchingCubes = false;
+		// Define the implicit function
+		MarchingCubes.Implicit = [this, Voxels](const FVector3d& Pos) {
+			const FVector PosConverted = FVector(Pos.X, Pos.Y, Pos.Z);
+			const int Index = MyDensityField->WorldPositionToIndex(PosConverted);
+			return Voxels.Contains(Index) ? 1 : -1;
+		};
+
+		MarchingCubes.bParallelCompute = true;
+		const UE::Geometry::FMeshShapeGenerator& Generator = MarchingCubes.Generate();
+		TArray<FVector3d> Vertices3d = Generator.Vertices;
+		TArray<UE::Geometry::FIndex3i> Triangles = Generator.Triangles;
+		TArray<FVector3f> Normals3F = Generator.Normals;
+
+		// Convert FVector3d to FVector
+		TArray<FVector> Vertices;
+		Vertices.Reserve(Generator.Vertices.Num());
+		for (const FVector3d& Vertex : Vertices3d)
+		{
+			Vertices.Add(FVector(Vertex.X, Vertex.Y, Vertex.Z));
+		}
+
+		// Convert FIndex3i to int32
+		TArray<int32> Indices;
+		Indices.Reserve(Generator.Triangles.Num() * 3);
+		for (const UE::Geometry::FIndex3i& Triangle : Triangles)
+		{
+			Indices.Add(Triangle.A);
+			Indices.Add(Triangle.B);
+			Indices.Add(Triangle.C);
+		}
+
+		// Convert FVector3f to FVector
+		TArray<FVector> Normals;
+		Normals.Reserve(Generator.Normals.Num());
+		for (const FVector3f& Normal : Normals3F)
+		{
+			Normals.Add(FVector(Normal.X, Normal.Y, Normal.Z));
+		}
+
+		TArray<FColor> VertexColors;
+		VertexColors.Reserve(Vertices.Num());
+		for (int32 i = 0; i < Vertices.Num(); ++i)
+		{
+			VertexColors.Add(FColor::Green);
+		}
+
+
+		AsyncTask(ENamedThreads::Type::GameThread, [this, Vertices, Indices, Normals, VertexColors]()
+		{
+			FScopeLock MeshLock(&ProceduralMeshGuard);
+			ProceduralMesh->CreateMeshSection(0, Vertices, Indices, Normals, TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), false);
+			ProceduralMesh->SetVisibility(true);
+			AccumulatedTime = 0.0f;
+			IsMarchingCubesRunning = false;
+		});
+	});
+}
\ No newline at end of file
diff --git a/Source/MetaCastBachelor/MagicWand.h b/Source/MetaCastBachelor/MagicWand.h
new file mode 100644
index 0000000..f20239e
--- /dev/null
+++ b/Source/MetaCastBachelor/MagicWand.h
@@ -0,0 +1,57 @@
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ProceduralMeshComponent.h"
+#include "MetaCastBaseline.h"
+#include "Generators/MarchingCubes.h"
+#include "MagicWand.generated.h"
+
+UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
+class UMagicWand : public UMetaCastBaseline
+{
+	GENERATED_BODY()
+	
+	FDensityField* MyDensityField;
+	UPROPERTY()
+	UWorld* World;
+	bool IsMarchingCubesRunning = false;
+	bool AbortMarchingCubes = false;
+
+	// Critical section to protect shared variables
+	mutable FCriticalSection ProceduralMeshGuard;
+
+	UPROPERTY()
+	UProceduralMeshComponent* ProceduralMesh;
+	UPROPERTY(EditAnywhere)
+	UMaterialInterface* SelectionVolumeMat;
+	TArray<int32> FloodedIndices;
+	UPROPERTY(EditAnywhere)
+	float MarchingCubeSize = 0;
+	UPROPERTY(EditAnywhere)
+	int EvaluationsPerSecond = 10;
+	float AccumulatedTime = 0.0;
+	UPROPERTY(EditAnywhere)
+	float ProximityThreshold = 0.1f;
+	TArray<int32> SelectedClusterIndices;
+
+	
+public:
+	UMagicWand();
+	
+	virtual void BeginPlay() override;
+		
+	virtual void SelectParticles(const FVector& InputPosition) override;
+	virtual void EraseParticles(const FVector& InputPosition) override;
+
+	virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override;
+	virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override;
+	void InitMagicWandSelection();
+
+	void GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const;
+	void GenerateVoxelMeshSmooth(const TArray<int32> Voxels);
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
+	void PerformMagicWandSelection(const FVector& InputPosition);
+	void ExpandSelection(int32 SeedIndex);
+};
\ No newline at end of file
diff --git a/Source/MetaCastBachelor/MetaPoint.cpp b/Source/MetaCastBachelor/MetaPoint.cpp
index 6b45ec3..2e908f0 100644
--- a/Source/MetaCastBachelor/MetaPoint.cpp
+++ b/Source/MetaCastBachelor/MetaPoint.cpp
@@ -1,6 +1,7 @@
 #include "MetaPoint.h"
 #include "Utilities.h"
 #include "Generators/MarchingCubes.h"
+#include "UObject/GCObjectScopeGuard.h"
 
 UMetaPoint::UMetaPoint() : LocalMaximumIndex(0), MyDensityField(nullptr), MetaPointThreshold(0), World(nullptr)
 {
@@ -52,14 +53,13 @@ void UMetaPoint::HandleMetaSelectReleased(const FInputActionInstance& Instance)
 {
 	Super::HandleMetaSelectReleased(Instance);
 
-	//ProceduralMesh->ClearAllMeshSections();
-	//ProceduralMesh->SetVisibility(false);
+	ProceduralMesh->ClearAllMeshSections();
+	ProceduralMesh->SetVisibility(false);
 
-	MyPointCloud->ColorPointsInVoxels(FloodedIndices);
 
 	AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
 	{
-		
+		MyPointCloud->ColorPointsInVoxels(FloodedIndices);
 	});
 }
 
@@ -70,6 +70,17 @@ void UMetaPoint::HandleMetaSelectPressed(const FInputActionInstance& Instance)
 	InitMetaPointSelection();
 }
 
+void UMetaPoint::HandleMetaEraseReleased(const FInputActionInstance& Instance)
+{
+	Super::HandleMetaEraseReleased(Instance);
+
+	//deselect all particles
+	for (int32 i = 0; i < MyPointCloud->SelectionFlags.Num(); ++i)
+	{
+		MyPointCloud->SelectionFlags[i] = false;
+	}
+}
+
 void UMetaPoint::InitMetaPointSelection()
 {	
 	const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
@@ -114,7 +125,7 @@ void UMetaPoint::SelectParticles(const FVector& InputPosition)
 		AccumulatedTime = -10000;
 
 		FScopeLock Lock(&FloodFillingGuard); 
-		AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
+		AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
 		{
 			const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
 			
@@ -133,13 +144,19 @@ void UMetaPoint::SelectParticles(const FVector& InputPosition)
 			LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, SelectionLocalPosition);
 
 			// Convert the local maximum back to world coordinates
-			//LocalMaximumIndex = MyDensityField->WorldPositionToIndex(LocalMaximum);
+			LocalMaximumIndex = MyDensityField->WorldPositionToIndex(LocalMaximum);
 
-			MetaPointThreshold = FUtilities::InterpolateDensityAtPosition(MyDensityField, SelectionLocalPosition);
+			const float Dist = FVector::Distance(SelectStartPosition, SelectionLocalPosition);
+			UE_LOG(LogTemp, Warning, TEXT("Dist: %f"), Dist);
+			float InitThreshold = FUtilities::InterpolateDensityAtPosition(MyDensityField, SelectStartPosition);
+			float Thr = MyDensityField->MaxDensity - (Dist / 100.0f) * (MyDensityField->MaxDensity - MyDensityField->MinDensity) - InitThreshold;
 
-			const float MaxDistance = FVector::Distance(SelectStartPosition, SelectionLocalPosition);
-			FloodedIndices = FUtilities::FloodFilling_2(MyDensityField, LocalMaximumIndex, MetaPointThreshold, MaxDistance);
+			MetaPointThreshold = FUtilities::InterpolateDensityAtPosition(MyDensityField, SelectionLocalPosition);
 			
+			const float MaxDistance = FVector::Distance(SelectStartPosition, SelectionLocalPosition);
+			//FloodedIndices = FUtilities::FloodFilling_2(MyDensityField, LocalMaximumIndex, MetaPointThreshold, MaxDistance);
+			FloodedIndices = FUtilities::FloodFilling(MyDensityField, LocalMaximumIndex, MetaPointThreshold);
+
 			GenerateVoxelMeshSmooth(FloodedIndices);
 		});
 	}
@@ -197,83 +214,106 @@ void UMetaPoint::GenerateVoxelMeshSmooth(const TArray<int32> Voxels)
 	if(IsMarchingCubesRunning)
 		return;
 
+	if(Voxels.IsEmpty())
+	{
+		AccumulatedTime = 0;
+		ProceduralMesh->ClearAllMeshSections();
+		ProceduralMesh->SetVisibility(false);
+		return;
+	}
+
 	IsMarchingCubesRunning = true;
 	
-	FScopeLock Lock(&ProceduralMeshGuard);
-	AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this, Voxels]()
+	FVector Min(FLT_MAX, FLT_MAX, FLT_MAX);
+	FVector Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+	
+	for(const int FloodedIndex : Voxels)
 	{
-		FVector Min(FLT_MAX, FLT_MAX, FLT_MAX);
-		FVector Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-		
-		for(const int FloodedIndex : Voxels)
-		{
-			Min = FVector::Min(Min, MyDensityField->IndexToVoxelPosition(FloodedIndex));
-			Max = FVector::Max(Max, MyDensityField->IndexToVoxelPosition(FloodedIndex));
-		}
+		Min = FVector::Min(Min, MyDensityField->IndexToVoxelPosition(FloodedIndex));
+		Max = FVector::Max(Max, MyDensityField->IndexToVoxelPosition(FloodedIndex));
+	}
+	
+	UE::Geometry::FMarchingCubes MarchingCubes;
+	MarchingCubes.Bounds = UE::Geometry::TAxisAlignedBox3(Min, Max);
+	//MarchingCubes.CubeSize = MarchingCubeSize == 0 ? MyDensityField->GetStep().X : MarchingCubeSize;
 
-		UE::Geometry::FMarchingCubes MarchingCubes;
-		MarchingCubes.Bounds = UE::Geometry::TAxisAlignedBox3(Min, Max);
-		MarchingCubes.CubeSize = MarchingCubeSize == 0 ? MyDensityField->GetStep().X : MarchingCubeSize;
-		MarchingCubes.CancelF = [this]() {
-			return AbortMarchingCubes;
-		};
-		MarchingCubes.IsoValue = 0;
-
-		AbortMarchingCubes = false;
-		// Define the implicit function
-		MarchingCubes.Implicit = [this, Voxels](const FVector3d& Pos) {
-			const FVector PosConverted = FVector(Pos.X, Pos.Y, Pos.Z);
-			const int Index = MyDensityField->WorldPositionToIndex(PosConverted);
-			return Voxels.Contains(Index) ? 1 : -1;
-		};
-
-		MarchingCubes.bParallelCompute = true;
-		const UE::Geometry::FMeshShapeGenerator& Generator = MarchingCubes.Generate();
-		TArray<FVector3d> Vertices3d = Generator.Vertices;
-		TArray<UE::Geometry::FIndex3i> Triangles = Generator.Triangles;
-		TArray<FVector3f> Normals3F = Generator.Normals;
-
-		// Convert FVector3d to FVector
-		TArray<FVector> Vertices;
-		Vertices.Reserve(Generator.Vertices.Num());
-		for (const FVector3d& Vertex : Vertices3d)
-		{
-			Vertices.Add(FVector(Vertex.X, Vertex.Y, Vertex.Z));
-		}
+	const float Volume = MarchingCubes.Bounds.Volume();
 
-		// Convert FIndex3i to int32
-		TArray<int32> Indices;
-		Indices.Reserve(Generator.Triangles.Num() * 3);
-		for (const UE::Geometry::FIndex3i& Triangle : Triangles)
-		{
-			Indices.Add(Triangle.A);
-			Indices.Add(Triangle.B);
-			Indices.Add(Triangle.C);
-		}
+	// Logarithmic scaling of the cube size based on volume
+	if(Volume > 50000) {
+		MarchingCubes.CubeSize = (3.0f * log10((Volume + 500) / 1000) - 3);
+	}else if(Volume > 500000)
+	{
+		MarchingCubes.CubeSize = 9;
+	}else {
+		MarchingCubes.CubeSize = MyDensityField->GetStep().X;
+	}
 
-		// Convert FVector3f to FVector
-		TArray<FVector> Normals;
-		Normals.Reserve(Generator.Normals.Num());
-		for (const FVector3f& Normal : Normals3F)
-		{
-			Normals.Add(FVector(Normal.X, Normal.Y, Normal.Z));
-		}
+	MarchingCubes.CubeSize = FMath::Clamp(MarchingCubes.CubeSize, MyDensityField->GetStep().X, 10.0f);
 
-		TArray<FColor> VertexColors;
-		VertexColors.Reserve(Vertices.Num());
-		for (int32 i = 0; i < Vertices.Num(); ++i)
-		{
-			VertexColors.Add(FColor::Green);
-		}
+	MarchingCubes.CancelF = [this]() {
+		return AbortMarchingCubes;
+	};
+	MarchingCubes.IsoValue = 0;
+	MarchingCubes.bEnableValueCaching = true;
+	AbortMarchingCubes = false;
 
+	// Define the implicit function
+	MarchingCubes.Implicit = [this, Voxels](const FVector3d& Pos) {
+		const FVector PosConverted = FVector(Pos.X, Pos.Y, Pos.Z);
+		const int Index = MyDensityField->WorldPositionToIndex(PosConverted);
+		return Voxels.Contains(Index) ? 1 : -1;
+	};
 
-		AsyncTask(ENamedThreads::Type::GameThread, [this, Vertices, Indices, Normals, VertexColors]()
-		{
-			FScopeLock MeshLock(&ProceduralMeshGuard);
-			ProceduralMesh->CreateMeshSection(0, Vertices, Indices, Normals, TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), false);
-			ProceduralMesh->SetVisibility(true);
-			AccumulatedTime = 0.0f;
-			IsMarchingCubesRunning = false;
-		});
+	MarchingCubes.bParallelCompute = true;
+	MarchingCubes.RootMode = UE::Geometry::ERootfindingModes::Bisection;
+
+	const UE::Geometry::FMeshShapeGenerator& Generator = MarchingCubes.Generate();
+	
+	TArray<FVector3d> Vertices3d = Generator.Vertices;
+	TArray<UE::Geometry::FIndex3i> Triangles = Generator.Triangles;
+	TArray<FVector3f> Normals3F = Generator.Normals;
+
+	// Convert FVector3d to FVector
+	TArray<FVector> Vertices;
+	Vertices.Reserve(Generator.Vertices.Num());
+	for (const FVector3d& Vertex : Vertices3d)
+	{
+		Vertices.Add(FVector(Vertex.X, Vertex.Y, Vertex.Z));
+	}
+
+	// Convert FIndex3i to int32
+	TArray<int32> Indices;
+	Indices.Reserve(Generator.Triangles.Num() * 3);
+	for (const UE::Geometry::FIndex3i& Triangle : Triangles)
+	{
+		Indices.Add(Triangle.A);
+		Indices.Add(Triangle.B);
+		Indices.Add(Triangle.C);
+	}
+
+	// Convert FVector3f to FVector
+	TArray<FVector> Normals;
+	Normals.Reserve(Generator.Normals.Num());
+	for (const FVector3f& Normal : Normals3F)
+	{
+		Normals.Add(FVector(Normal.X, Normal.Y, Normal.Z));
+	}
+
+	TArray<FColor> VertexColors;
+	VertexColors.Reserve(Vertices.Num());
+	for (int32 i = 0; i < Vertices.Num(); ++i)
+	{
+		VertexColors.Add(FColor::Green);
+	}
+
+
+	AsyncTask(ENamedThreads::Type::GameThread, [this, Vertices, Indices, Normals, VertexColors]()
+	{
+		FScopeLock MeshLock(&ProceduralMeshGuard);
+		ProceduralMesh->CreateMeshSection(0, Vertices, Indices, Normals, TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), false);
+		ProceduralMesh->SetVisibility(true);
+		AccumulatedTime = 0.0f;
+		IsMarchingCubesRunning = false;
 	});
 }
\ No newline at end of file
diff --git a/Source/MetaCastBachelor/MetaPoint.h b/Source/MetaCastBachelor/MetaPoint.h
index 20cd30e..8a8591c 100644
--- a/Source/MetaCastBachelor/MetaPoint.h
+++ b/Source/MetaCastBachelor/MetaPoint.h
@@ -58,6 +58,7 @@ public:
 
 	virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override;
 	virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override;
+	virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override;
 	void InitMetaPointSelection();
 
 	void GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const;
diff --git a/Source/MetaCastBachelor/PointCloud.cpp b/Source/MetaCastBachelor/PointCloud.cpp
index aad4992..d319ce9 100644
--- a/Source/MetaCastBachelor/PointCloud.cpp
+++ b/Source/MetaCastBachelor/PointCloud.cpp
@@ -134,7 +134,7 @@ void APointCloud::DrawVoxel(const int Index, const float Time) const
 
 }
 
-void APointCloud::ColorPointsInVoxels(const TArray<int32>& VoxelIndices)
+void APointCloud::ColorPointsInVoxels(const TArray<int32> VoxelIndices)
 {
 	FScopeLock Lock(&DataGuard);
 	if (!MyDensityField)
diff --git a/Source/MetaCastBachelor/PointCloud.h b/Source/MetaCastBachelor/PointCloud.h
index 90e89d2..9de2a62 100644
--- a/Source/MetaCastBachelor/PointCloud.h
+++ b/Source/MetaCastBachelor/PointCloud.h
@@ -67,7 +67,7 @@ public:
 
 	void UpdateSelection();
 	void DrawVoxel(const int Index, float Time) const;
-	void ColorPointsInVoxels(const TArray<int32>& VoxelIndices);
+	void ColorPointsInVoxels(const TArray<int32> VoxelIndices);
 
 	UFUNCTION(BlueprintCallable)
 	void ReadPointCloudFromFile(FFilePath FileNamePoints, FFilePath FileNameFlags);
diff --git a/Source/MetaCastBachelor/Utilities.cpp b/Source/MetaCastBachelor/Utilities.cpp
index 76b42e3..c3581b9 100644
--- a/Source/MetaCastBachelor/Utilities.cpp
+++ b/Source/MetaCastBachelor/Utilities.cpp
@@ -106,7 +106,7 @@ float FUtilities::GaussianKernel(const float Distance, const float Sigma) {
 
 float FUtilities::SmoothingKernel(const float Distance, const float Radius) {
 	const float Value = FMath::Max(0.0f, Radius * Radius - Distance * Distance);
-	return Value * Value * Value;
+	return (Value * Value) / 5;
 }
 
 FVector FUtilities::FollowGradientToMaximum(const FDensityField* DensityField, const FVector& StartPosition)
@@ -116,7 +116,7 @@ FVector FUtilities::FollowGradientToMaximum(const FDensityField* DensityField, c
 
 	int Iterations = 0;
 	constexpr int MaxIterations = 100;  // Prevent infinite loops
-	constexpr float StepSize = 0.05f;  // Define a reasonable step size
+	constexpr float StepSize = 0.05f;  // Define step size
 
 	while (Iterations < MaxIterations)
 	{
-- 
GitLab