From 074f176b6695b2923a9f7730fa9f15862eff00bd Mon Sep 17 00:00:00 2001
From: Timon Roemer <t.roemer@vis.rwth-aachen.de>
Date: Thu, 11 Jul 2024 18:27:36 +0200
Subject: [PATCH] Adds FloodFilling on different threads

---
 Config/DefaultEngine.ini                 |   6 +-
 Content/MetaPointMap.umap                | Bin 43192 -> 45708 bytes
 Content/MetaPointMap_BuiltData.uasset    | Bin 42891 -> 42891 bytes
 Content/SelectionVolume.uasset           | Bin 0 -> 8780 bytes
 Source/MetaCastBachelor/DensityField.cpp | 247 +++++++++++++----------
 Source/MetaCastBachelor/DensityField.h   |  25 +--
 Source/MetaCastBachelor/MetaPoint.cpp    | 126 +++++++++---
 Source/MetaCastBachelor/MetaPoint.h      |  16 ++
 Source/MetaCastBachelor/PointCloud.cpp   |  10 +-
 Source/MetaCastBachelor/Utilities.cpp    | 129 ++++++++++--
 Source/MetaCastBachelor/Utilities.h      |   1 +
 11 files changed, 386 insertions(+), 174 deletions(-)
 create mode 100644 Content/SelectionVolume.uasset

diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini
index 19b59fc..05ba680 100644
--- a/Config/DefaultEngine.ini
+++ b/Config/DefaultEngine.ini
@@ -125,7 +125,11 @@ r.Shadow.Virtual.Enable = 1
 r.Mobile.AntiAliasing=3
 r.AntiAliasingMethod=3
 vr.InstancedStereo=True
-r.MobileHDR=True
+r.MobileHDR=False
+r.MSAACount=4
+r.Mobile.ShadingPath=1
+r.ForwardShading=True
+r.CustomDepth=1
 
 [/Script/HardwareTargeting.HardwareTargetingSettings]
 TargetedHardwareClass = Mobile
diff --git a/Content/MetaPointMap.umap b/Content/MetaPointMap.umap
index add3f06500b1b576fa486e1ede28b8e2d591a298..651dc1767d85ce66c1085a001440e676d242a400 100644
GIT binary patch
literal 45708
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
W01M5sdlrE#r}k@tHi>}5K<WV|$z3x5

literal 43192
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
ZA%a2=gv;((1hSmkuL&C)IM}Q;4*<CJk4pdm

diff --git a/Content/MetaPointMap_BuiltData.uasset b/Content/MetaPointMap_BuiltData.uasset
index 1bf02fa1814c30bc66b1c21252e01906ddb1ac28..24285dcf828b76f9af8653034e84014cb1f8e362 100644
GIT binary patch
delta 179
zcmeA^&(wXMX@e1?z=x;Pl(KwZIknvQC=nTAp19eGF^z@IfI&>zjC=ArRxLIIhC|%k
z(>C8@jbUMA+-%L2%Pim!bM5YC*$}VQBCbW^2i!_F@8FGN5=h&7y{oB6$zjW{ZG30d
zoo7x~oGG%|O2Cy-;73aU|IuZMUYk~?rr(?*?6A3C@JTGDXmfrGi@;2;p05r?JG@tL
VZ@Y5l%(mLe59f<))-Fjf1^^DkNt6Hp

delta 179
zcmeA^&(wXMX@e1?K!wx7n@pkS9VaCiq)*Ikd9m4vF^z@IkYS-+aL(j)tXgb_45eau
zA2;7)jbUMA-fYd4%Pg?5KgdAmRlQ@c=X|G&1@FT)@8FGN5=abMzIy(P=}yzzH*5Xe
z?6YjL;!KgvRsyb!0yCzid{DR$?AGDuyh;Dew(!mUf=^;GMVs?mSOl84)n}~Ku6Ccn
V{-AR2`_r>0Kb$YJS-T{`7yvruOiBO%

diff --git a/Content/SelectionVolume.uasset b/Content/SelectionVolume.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..73d06d7c6830ac1fc883baf71e935610588d84e9
GIT binary patch
literal 8780
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

literal 0
HcmV?d00001

diff --git a/Source/MetaCastBachelor/DensityField.cpp b/Source/MetaCastBachelor/DensityField.cpp
index 0cfcdc9..3aa6e9b 100644
--- a/Source/MetaCastBachelor/DensityField.cpp
+++ b/Source/MetaCastBachelor/DensityField.cpp
@@ -25,7 +25,7 @@ void FDensityField::InitializeDensityField(const FVector& MinBounds, const FVect
 			for (int32 X = 0; X < XAxisNum; X++)
 			{
 				FVector Position(MinBounds.X + X * XStep, MinBounds.Y + Y * YStep, MinBounds.Z + Z * ZStep);
-				FVector GridPosition(X, Y, Z);
+				FIntVector3 GridPosition(X, Y, Z);
 				VoxelList.Add(FVoxel(Position, GridPosition));
 			}
 		}
@@ -140,7 +140,6 @@ void FDensityField::CalculateAndStoreGradients()
 	UE_LOG(LogTemp, Log, TEXT("Gradient calculation completed."));
 }
 
-
 //	DEBUG FUNCTIONS
 
 void FDensityField::DrawDebugVoxelDensity(const UWorld* World, const AActor* Actor, const float Duration, const float Scale, const float DensityThreshold) const
@@ -183,16 +182,11 @@ void FDensityField::DrawDebugVoxelDensity(const UWorld* World, const AActor* Act
 	UE_LOG(LogTemp, Log, TEXT("DensityField drawn with gradient colors using logarithmic scaling!"));
 }
 
-//	CONVERSION FUNCTIONS
-
-int32 FDensityField::GridPositionToIndex(const int32 X, const int32 Y, const int32 Z) const
-{
-    return Z * XNum * YNum + Y * XNum + X;
-}
+//	WORLD POSITION CONVERSION FUNCTIONS
 
 int32 FDensityField::WorldPositionToIndex(const FVector &Position) const {
 	// Convert world position to grid position
-	const FVector GridPosition = WorldToGridPosition(Position);
+	const FIntVector3 GridPosition = WorldToGridPosition(Position);
 
 	// Check if the grid position is valid
 	if (!IsValidGridPosition(GridPosition.X, GridPosition.Y, GridPosition.Z)) {
@@ -203,12 +197,12 @@ int32 FDensityField::WorldPositionToIndex(const FVector &Position) const {
 	return GridPositionToIndex(GridPosition.X, GridPosition.Y, GridPosition.Z);
 }
 
-FVector FDensityField::WorldToGridPosition(const FVector& Position) const
+FIntVector3 FDensityField::WorldToGridPosition(const FVector& Position) const
 {
 	if (XStep == 0 || YStep == 0 || ZStep == 0)
 	{
 		UE_LOG(LogTemp, Warning, TEXT("Grid steps are zero, cannot convert position to grid coordinates."));
-		return FVector(-1, -1, -1);  // Return an invalid grid position if any grid step is zero
+		return FIntVector3(-1, -1, -1);  // Return an invalid grid position if any grid step is zero
 	}
 
 	// Calculate the grid coordinates by subtracting the grid origin and dividing by the grid step sizes
@@ -220,20 +214,55 @@ FVector FDensityField::WorldToGridPosition(const FVector& Position) const
 	if (GridX < 0 || GridX >= XNum || GridY < 0 || GridY >= YNum || GridZ < 0 || GridZ >= ZNum)
 	{
 		UE_LOG(LogTemp, Warning, TEXT("Position out of grid bounds, returning invalid grid coordinates."));
-		return FVector(-1, -1, -1);  // Return an invalid grid position if out of bounds
+		return FIntVector3(-1, -1, -1);  // Return an invalid grid position if out of bounds
 	}
 
-	return FVector(GridX, GridY, GridZ);
+	return FIntVector3(GridX, GridY, GridZ);
 }
 
-bool FDensityField::IsValidGridPosition(const int32 XBin, const int32 YBin, const int32 ZBin) const
+//	GRID POSITION CONVERSION FUNCTIONS
+
+int32 FDensityField::GridPositionToIndex(const int32 X, const int32 Y, const int32 Z) const
 {
-	// Check if the provided indices are within the grid bounds
-	return (XBin >= 0 && XBin < XNum) &&
-		   (YBin >= 0 && YBin < YNum) &&
-		   (ZBin >= 0 && ZBin < ZNum);
+    return Z * XNum * YNum + Y * XNum + X;
+}
+
+double FDensityField::GridPositionToVoxelDensity(const int32 XBin, const int32 YBin, const int32 ZBin) const
+{
+	// First, check if the provided indices are valid
+	if (IsValidGridPosition(XBin, YBin, ZBin))
+	{
+		// Convert 3D grid coordinates to a linear index
+		const int32 Index = GridPositionToIndex(XBin, YBin, ZBin);
+		
+		return IndexToVoxelDensity(Index);
+	}
+	
+	// Return 0 if the indices are out of bounds or the index is invalid
+	return 0.0;
+}
+
+FVector FDensityField::GridPositionToVoxelGradient(const int32 XBin, const int32 YBin, const int32 ZBin) const
+{
+	// First, check if the provided indices are valid
+	if (IsValidGridPosition(XBin, YBin, ZBin))
+	{
+		// Convert 3D grid coordinates to a linear index
+		const int32 Index = GridPositionToIndex(XBin, YBin, ZBin);
+		
+		// Ensure the index is within the valid range
+		if (VoxelList.IsValidIndex(Index))
+		{
+			// Return the gradient at the calculated index
+			return VoxelList[Index].GetVoxelGradient();
+		}
+	}
+	// Return 0 if the indices are out of bounds or the index is invalid
+	return FVector::Zero();
 }
 
+//	INDEX CONVERSION FUNCTIONS
+
 FVector FDensityField::IndexToVoxelGradient(const int32 Index) const
 {
 	if (VoxelList.IsValidIndex(Index))
@@ -252,30 +281,107 @@ FVector FDensityField::IndexToVoxelPosition(const int32 Index) const
 	return -FVector::One();
 }
 
-FVector FDensityField::IndexToGridPosition(const int32 Index) const
+FIntVector3 FDensityField::IndexToGridPosition(const int32 Index) const
 {
 	if (IsValidIndex(Index))
 	{
 		return VoxelList[Index].GetVoxelGridPos();
 	}
-	return -FVector::One();
+	return FIntVector3(-1, -1, -1);
 }
 
+TArray<FVector> FDensityField::IndexToVoxelCornersWorld(const int32 Index) const
+{
+	TArray<FVector> Corners;
+    
+	if (!VoxelList.IsValidIndex(Index))
+	{
+		return Corners; // Return an empty array if the index is invalid
+	}
+    
+	FVector VoxelPosition = VoxelList[Index].GetVoxelPosition();
+    
+	FVector HalfStep = FVector(XStep, YStep, ZStep) * 0.5f;
+    
+	// Define the 8 corners relative to the voxel's center position
+	Corners.Add(VoxelPosition + FVector(-HalfStep.X, -HalfStep.Y, -HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(HalfStep.X, -HalfStep.Y, -HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(HalfStep.X, HalfStep.Y, -HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(-HalfStep.X, HalfStep.Y, -HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(-HalfStep.X, -HalfStep.Y, HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(HalfStep.X, -HalfStep.Y, HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(HalfStep.X, HalfStep.Y, HalfStep.Z));
+	Corners.Add(VoxelPosition + FVector(-HalfStep.X, HalfStep.Y, HalfStep.Z));
+    
+	return Corners;
+}
 
-//	GETTER AND SETTER FUNCTIONS
+TArray<int32> FDensityField::IndexToVoxelNeighbors(const int32 Index) const
+{
+	TArray<int32> Neighbors;
+	if (IsValidIndex(Index))
+	{
+		const FIntVector3 Pos = IndexToGridPosition(Index);
+		const int32 X = Pos.X;
+		const int32 Y = Pos.Y;
+		const int32 Z = Pos.Z;
 
-FVector FDensityField::GetGridOrigin() const
+		// List all potential neighbors
+		TArray<FIntVector> PotentialNeighbors = {
+			FIntVector(X + 1, Y, Z), FIntVector(X - 1, Y, Z),
+			FIntVector(X, Y + 1, Z), FIntVector(X, Y - 1, Z),
+			FIntVector(X, Y, Z + 1), FIntVector(X, Y, Z - 1)
+		};
+
+		for (const FIntVector& NeighborPos : PotentialNeighbors)
+		{
+			if (IsValidGridPosition(NeighborPos.X, NeighborPos.Y, NeighborPos.Z))
+			{
+				int NeighborIndex = GridPositionToIndex(NeighborPos.X, NeighborPos.Y, NeighborPos.Z);
+				Neighbors.Add(NeighborIndex);
+			}
+		}
+	}
+	return Neighbors;
+}
+
+double FDensityField::IndexToVoxelDensity(const int32 Index) const
 {
-	return GridOrigin;
+	if (VoxelList.IsValidIndex(Index))
+	{
+		return VoxelList[Index].GetVoxelDensity();
+	}
+	return 0.0;
+}
+
+//	VALIDITY FUNCTIONS
+
+bool FDensityField::IsValidIndex(const int32 Index) const {
+	return VoxelList.IsValidIndex(Index);
 }
 
-double FDensityField::GetVoxelDensityFromIndex(const int32 Index) const
+bool FDensityField::IsValidWorldPosition(const FVector& Position) const
 {
-    if (VoxelList.IsValidIndex(Index))
-    {
-        return VoxelList[Index].GetVoxelDensity();
-    }
-    return 0.0;
+	// Convert the world position to grid coordinates
+	const FIntVector3 GridPosition = WorldToGridPosition(Position);
+
+	// Check if the grid position is within the valid bounds
+	return IsValidGridPosition(GridPosition.X, GridPosition.Y, GridPosition.Z);
+}
+
+bool FDensityField::IsValidGridPosition(const int32 XBin, const int32 YBin, const int32 ZBin) const
+{
+	// Check if the provided indices are within the grid bounds
+	return (XBin >= 0 && XBin < XNum) &&
+		   (YBin >= 0 && YBin < YNum) &&
+		   (ZBin >= 0 && ZBin < ZNum);
+}
+
+//	GETTER AND SETTER FUNCTIONS
+
+FVector FDensityField::GetGridOrigin() const
+{
+	return GridOrigin;
 }
 
 int32 FDensityField::GetVoxelNumber() const
@@ -283,7 +389,7 @@ int32 FDensityField::GetVoxelNumber() const
     return VoxelList.Num();
 }
 
-void FDensityField::SetVoxelDensity(const int32 Index, const double Density)
+void FDensityField::SetVoxelDensityByIndex(const int32 Index, const double Density)
 {
     if (VoxelList.IsValidIndex(Index))
     {
@@ -291,7 +397,7 @@ void FDensityField::SetVoxelDensity(const int32 Index, const double Density)
     }
 }
 
-void FDensityField::SetVoxelGradient(const int32 Index, const FVector& Gradient)
+void FDensityField::SetVoxelGradientByIndex(const int32 Index, const FVector& Gradient)
 {
     if (VoxelList.IsValidIndex(Index))
     {
@@ -299,40 +405,6 @@ void FDensityField::SetVoxelGradient(const int32 Index, const FVector& Gradient)
     }
 }
 
-double FDensityField::GetVoxelDensityFromGridPosition(const int32 XBin, const int32 YBin, const int32 ZBin) const
-{
-	// First, check if the provided indices are valid
-	if (IsValidGridPosition(XBin, YBin, ZBin))
-	{
-		// Convert 3D grid coordinates to a linear index
-		const int32 Index = GridPositionToIndex(XBin, YBin, ZBin);
-		
-		return GetVoxelDensityFromIndex(Index);
-	}
-	
-	// Return 0 if the indices are out of bounds or the index is invalid
-	return 0.0;
-}
-
-FVector FDensityField::GetVoxelGradientFromGridPosition(const int32 XBin, const int32 YBin, const int32 ZBin) const
-{
-	// First, check if the provided indices are valid
-	if (IsValidGridPosition(XBin, YBin, ZBin))
-	{
-		// Convert 3D grid coordinates to a linear index
-		const int32 Index = GridPositionToIndex(XBin, YBin, ZBin);
-		
-		// Ensure the index is within the valid range
-		if (VoxelList.IsValidIndex(Index))
-		{
-			// Return the gradient at the calculated index
-			return VoxelList[Index].GetVoxelGradient();
-		}
-	}
-	// Return 0 if the indices are out of bounds or the index is invalid
-	return FVector::Zero();
-}
-
 FVector FDensityField::GetStep() const
 {
 	return FVector(XStep, YStep, ZStep);
@@ -348,47 +420,4 @@ int32 FDensityField::GetYNum() const {
 
 int32 FDensityField::GetZNum() const {
 	return ZNum;
-}
-
-bool FDensityField::IsValidWorldPosition(const FVector& Position) const
-{
-	// Convert the world position to grid coordinates
-	const FVector GridPosition = WorldToGridPosition(Position);
-
-	// Check if the grid position is within the valid bounds
-	return IsValidGridPosition(GridPosition.X, GridPosition.Y, GridPosition.Z);
-}
-
-TArray<int32> FDensityField::GetNeighborsFromIndex(const int32 Index) const
-{
-	TArray<int32> Neighbors;
-	if (VoxelList.IsValidIndex(Index))
-	{
-		const int32 X = VoxelList[Index].GetVoxelGridPos().X;
-		const int32 Y = VoxelList[Index].GetVoxelGridPos().Y;
-		const int32 Z = VoxelList[Index].GetVoxelGridPos().Z;
-
-		// List all potential neighbors
-		TArray<FIntVector> PotentialNeighbors = {
-			FIntVector(X+1, Y, Z), FIntVector(X-1, Y, Z),
-			FIntVector(X, Y+1, Z), FIntVector(X, Y-1, Z),
-			FIntVector(X, Y, Z+1), FIntVector(X, Y, Z-1)
-		};
-
-		for (const FIntVector& NeighborPos : PotentialNeighbors)
-		{
-			if (NeighborPos.X >= 0 && NeighborPos.X < XNum &&
-				NeighborPos.Y >= 0 && NeighborPos.Y < YNum &&
-				NeighborPos.Z >= 0 && NeighborPos.Z < ZNum)
-			{
-				int NeighborIndex = GridPositionToIndex(NeighborPos.Z, NeighborPos.Y, NeighborPos.Z);
-				Neighbors.Add(NeighborIndex);
-			}
-		}
-	}
-	return Neighbors;
-}
-
-bool FDensityField::IsValidIndex(const int32 Index) const {
-	return VoxelList.IsValidIndex(Index);
-}
+}
\ No newline at end of file
diff --git a/Source/MetaCastBachelor/DensityField.h b/Source/MetaCastBachelor/DensityField.h
index 3e71da4..7477fd5 100644
--- a/Source/MetaCastBachelor/DensityField.h
+++ b/Source/MetaCastBachelor/DensityField.h
@@ -12,17 +12,17 @@ struct FVoxel
 
 private:
     FVector WorldPosition;
-	FVector GridPosition;
+	FIntVector3 GridPosition;
     double VoxelDensity;
     FVector VoxelGradient;
 	double ClosePointsNumber;
 
 public:
-    FVoxel() : WorldPosition(FVector::ZeroVector), GridPosition(FVector::ZeroVector), VoxelDensity(0.0), VoxelGradient(FVector::ZeroVector), ClosePointsNumber(0.0) {}
-    FVoxel(const FVector &InPosition, const FVector &InGridPos) : WorldPosition(InPosition), GridPosition(InGridPos), VoxelDensity(0.0), VoxelGradient(FVector::ZeroVector), ClosePointsNumber(0.0) {}
+    FVoxel() : WorldPosition(FVector::ZeroVector), GridPosition(FIntVector3::ZeroValue), VoxelDensity(0.0), VoxelGradient(FVector::ZeroVector), ClosePointsNumber(0.0) {}
+    FVoxel(const FVector &InPosition, const FIntVector3 &InGridPos) : WorldPosition(InPosition), GridPosition(InGridPos), VoxelDensity(0.0), VoxelGradient(FVector::ZeroVector), ClosePointsNumber(0.0) {}
 	
     double GetVoxelDensity() const { return VoxelDensity; }
-	FVector GetVoxelGridPos() const { return GridPosition; }
+	FIntVector3 GetVoxelGridPos() const { return GridPosition; }
     FVector GetVoxelPosition() const { return WorldPosition; }
     FVector GetVoxelGradient() const { return VoxelGradient; }
 	double GetClosePointsNumber() const { return ClosePointsNumber; }
@@ -73,26 +73,27 @@ public:
 
 	// CONVERSION FUNCTIONS
 	int32 WorldPositionToIndex(const FVector& Position) const;
-	FVector WorldToGridPosition(const FVector& Position) const;
+	FIntVector3 WorldToGridPosition(const FVector& Position) const;
 	bool IsValidGridPosition(int32 XBin, int32 YBin, int32 ZBin) const;
 	int32 GridPositionToIndex(int32 X, int32 Y, int32 Z) const;
+	TArray<FVector> IndexToVoxelCornersWorld(const int32 Index) const;
 	
 	// GETTER AND SETTER FUNCTIONS
 	FVector GetGridOrigin() const;
     FVector IndexToVoxelGradient(int32 Index) const;
     FVector IndexToVoxelPosition(int32 Index) const;
-    FVector IndexToGridPosition(int32 Index) const;
+	FIntVector3 IndexToGridPosition(int32 Index) const;
 	int32 GetVoxelNumber() const;
-    double GetVoxelDensityFromIndex(int32 Index) const;
-	double GetVoxelDensityFromGridPosition(int32 XBin, int32 YBin, int32 ZBin) const;
-	FVector GetVoxelGradientFromGridPosition(int32 XBin, int32 YBin, int32 ZBin) const;
+    double IndexToVoxelDensity(int32 Index) const;
+	double GridPositionToVoxelDensity(int32 XBin, int32 YBin, int32 ZBin) const;
+	FVector GridPositionToVoxelGradient(int32 XBin, int32 YBin, int32 ZBin) const;
 	FVector GetStep() const;
 	int32 GetXNum() const;
 	int32 GetYNum() const;
 	int32 GetZNum() const;
 	bool IsValidWorldPosition(const FVector& Position) const;
-	TArray<int32> GetNeighborsFromIndex(const int32 Index) const;
+	TArray<int32> IndexToVoxelNeighbors(const int32 Index) const;
 	bool IsValidIndex(int32 Index) const;
-	void SetVoxelDensity(int32 Index, double Density);
-    void SetVoxelGradient(int32 Index, const FVector& Gradient);
+	void SetVoxelDensityByIndex(int32 Index, double Density);
+    void SetVoxelGradientByIndex(int32 Index, const FVector& Gradient);
 };
diff --git a/Source/MetaCastBachelor/MetaPoint.cpp b/Source/MetaCastBachelor/MetaPoint.cpp
index 2e920d0..dd70f5d 100644
--- a/Source/MetaCastBachelor/MetaPoint.cpp
+++ b/Source/MetaCastBachelor/MetaPoint.cpp
@@ -1,18 +1,30 @@
 #include "MetaPoint.h"
 #include "Utilities.h"
 
-UMetaPoint::UMetaPoint() : Index(0), MyDensityField(nullptr), Threshold(0), MyProceduralMesh(nullptr)
+UMetaPoint::UMetaPoint() : Index(0), MyDensityField(nullptr), Threshold(0), World(nullptr), MyProceduralMesh(nullptr)
 {
 	// Initialize the Marching Cubes algorithm
 	MyMarchingCubes = new MarchingCubes();
+
+	// Create the procedural mesh component
+	ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
 }
 
 void UMetaPoint::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);
+}
 
 void UMetaPoint::EraseParticles(const FVector& InputPosition)
 {
@@ -31,20 +43,10 @@ void UMetaPoint::HandleMetaSelectPressed(const FInputActionInstance& Instance)
 	FindAndMarkLocalMaximum();
 }
 
-
 // Method to perform gradient ascent to find the local maximum density starting from a given position.
 void UMetaPoint::FindAndMarkLocalMaximum()
-{
-	const UWorld* World = GetWorld();
-	
-	if (!World || !MyPointCloud) {
-		UE_LOG(LogTemp, Warning, TEXT("Invalid world or point cloud context provided."));
-		return;
-	}
-	
+{	
 	const FVector WorldPosition = SelectionObject->GetComponentLocation();
-	UE_LOG(LogTemp, Log, TEXT("World Position: %s"), *WorldPosition.ToString());
-
 	MyDensityField = MyPointCloud->MyDensityField;
 
 	// Convert the world position of the selection object to the local position relative to the point cloud
@@ -52,39 +54,115 @@ void UMetaPoint::FindAndMarkLocalMaximum()
 
 	// Perform gradient ascent to find the local maximum starting from the converted local position
 	LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, StartPosition);
-	UE_LOG(LogTemp, Log, TEXT("Local maximum found at world position: %s"), *WorldMaximum.ToString());
 
 	// Convert the local maximum back to world coordinates
 	Index = MyDensityField->WorldPositionToIndex(LocalMaximum);
 
 	Threshold = FUtilities::InterpolateDensityAtPosition(MyDensityField, LocalMaximum);
 	TestingThresholdFactor = 1;
+
+	// Initialize Visited array to false for all voxels
+	Visited.Init(false, MyDensityField->GetVoxelNumber());
+
+	// Initialize IndicesToVisit with the starting index
+	IndicesToVisit.Empty();
+	IndicesToVisit.Add(Index);
+
+	// Clear FloodedIndices
+	FloodedIndices.Empty();
+	
+	World = GetWorld();
 }
 
 void UMetaPoint::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
 {
 	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 
-	TestingThresholdFactor -= DeltaTime * 0.1f;
+	//TestingThresholdFactor -= DeltaTime * 0.1f;
+
+	AccumulatedTime += DeltaTime;
+
+	constexpr float DecayRate = 0.1f; // Adjust this value to control the rate of decay
+	TestingThresholdFactor *= FMath::Exp(-DecayRate * DeltaTime);
+
+	// Ensure TestingThresholdFactor never goes below a small threshold to prevent it from becoming zero
+	constexpr float MinThreshold = 0.001f; // Adjust as needed
+	if (TestingThresholdFactor < MinThreshold)
+	{
+		TestingThresholdFactor = MinThreshold;
+	}
 }
 
 void UMetaPoint::SelectParticles(const FVector& InputPosition)
 {
-	const UWorld* World = GetWorld();
-	WorldMaximum = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(LocalMaximum);
-	
+	//WorldMaximum = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(LocalMaximum);
 	// Draw a debug sphere at the location of the local maximum in the world
-	DrawDebugSphere(World, WorldMaximum, SelectionRadius / 2, 32, FColor::Red, false, 0);
-	auto Voxels = FUtilities::FloodFilling(MyDensityField, Index, Threshold * TestingThresholdFactor);
+	//DrawDebugSphere(World, WorldMaximum, SelectionRadius / 2, 32, FColor::Red, false, 0);
 
-	for (const int32 Index2 : Voxels)
+	if (AccumulatedTime >=  0.1f)
 	{
-		MyPointCloud->DrawVoxel(Index2, 0);
-	}
-}
+		AccumulatedTime = -10.0f;
 
+		AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
+		{
+			//TArray<int32> Voxels = FUtilities::FloodFilling(MyDensityField, Index, Threshold * TestingThresholdFactor);
+			FUtilities::FloodFilling_2(MyDensityField, Threshold * TestingThresholdFactor, Visited, IndicesToVisit, FloodedIndices, IndicesToVisit);
 
+			auto Voxels = FloodedIndices;
+			AsyncTask(ENamedThreads::GameThread, [this, Voxels]()
+			{
+				GenerateVoxelMesh(FloodedIndices);
 
+				AccumulatedTime = 0.0f;
+			});
+		});
+	}
+}
 
+void UMetaPoint::GenerateVoxelMesh(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);
+
+		// Convert corners to world space
+		for (FVector& Corner : VoxelCorners)
+		{
+			//Corner = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(Corner);
+		}
+
+		// 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::Red);
+		}
+	}
 
+	// Create the mesh section
+	ProceduralMesh->CreateMeshSection(0, Vertices, Triangles, TArray<FVector>(), TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), true);
+}
diff --git a/Source/MetaCastBachelor/MetaPoint.h b/Source/MetaCastBachelor/MetaPoint.h
index c95ffd9..ce3e88b 100644
--- a/Source/MetaCastBachelor/MetaPoint.h
+++ b/Source/MetaCastBachelor/MetaPoint.h
@@ -18,6 +18,20 @@ class UMetaPoint : public UMetaCastBaseline
 	FVector LocalMaximum;
 	FDensityField* MyDensityField;
 	float Threshold;
+	UPROPERTY()
+	UWorld* World;
+	float AccumulatedTime = 0.0;
+
+	UPROPERTY()
+	UProceduralMeshComponent* ProceduralMesh;
+
+	UPROPERTY(EditAnywhere)
+	UMaterialInterface* SelectionVolumeMat;
+
+	TArray<bool> Visited;
+	TArray<int32> IndicesToVisit;
+	TArray<int32> FloodedIndices;
+	TArray<int32> RevisitIndices;
 	
 public:
 
@@ -38,6 +52,8 @@ public:
 	virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override;
 	void FindAndMarkLocalMaximum();
 
+	void GenerateVoxelMesh(const TArray<int32>& Voxels) const;
+
 	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
 };
 
diff --git a/Source/MetaCastBachelor/PointCloud.cpp b/Source/MetaCastBachelor/PointCloud.cpp
index a5a93cf..d6482df 100644
--- a/Source/MetaCastBachelor/PointCloud.cpp
+++ b/Source/MetaCastBachelor/PointCloud.cpp
@@ -91,7 +91,7 @@ void APointCloud::SetupDensityFieldFromPointCloud() const
 	constexpr int32 ZAxisNum = 100; // Number of divisions in the grid along the Z-axis
 	MyDensityField->InitializeDensityField(MinBounds, MaxBounds, XAxisNum, YAxisNum, ZAxisNum);
 
-	constexpr float InfluenceRadius = 0.5f; // Half the size of a voxel
+	constexpr float InfluenceRadius = 5.0f; // Half the size of a voxel
 	constexpr float Sigma = 3.0f;  // Standard deviation for the Gaussian kernel
 	MyDensityField->CalculateVoxelDensities(this, InfluenceRadius, Sigma);
 
@@ -102,6 +102,7 @@ void APointCloud::SetupDensityFieldFromPointCloud() const
 		//MyDensityField->DrawDebugVoxelDensity(World, this, 100.0f, 1.0f, 0.8f);
 	}
 }
+
 void APointCloud::UpdateSelection()
 {
 	for (int32 i = 0; i < PositionVectors.Num(); i++)
@@ -118,7 +119,7 @@ void APointCloud::UpdateSelection()
 	PointCloudVisualizer->SetInputAndConvert2(PositionVectors, PointColors);
 }
 
-void APointCloud::DrawVoxel(const int Index, float Time) const
+void APointCloud::DrawVoxel(const int Index, const float Time) const
 {
 	if(!MyDensityField->IsValidIndex(Index))
 	{
@@ -129,11 +130,8 @@ void APointCloud::DrawVoxel(const int Index, float Time) const
 	const FVector VoxelWorldPosition = PointCloudVisualizer->GetComponentTransform().TransformPosition(MyDensityField->IndexToVoxelPosition(Index));
 	const FVector WorldScale = PointCloudVisualizer->GetComponentScale();
 
-	// Scale the voxel size by the component's world scale to ensure it reflects the actual dimensions
-	FVector ScaledVoxelSize = GetActorRightVector();
-
 	// Draw the debug box with the correct world space dimensions
-	DrawDebugBox(GetWorld(), VoxelWorldPosition, VoxelHalfExtents, this->GetActorQuat(), FColor::Green, false, Time, 0, 0.1f);
+	DrawDebugBox(GetWorld(), VoxelWorldPosition, VoxelHalfExtents * WorldScale, this->GetActorQuat(), FColor::Green, false, Time, 0, 0.1f);
 
 }
 
diff --git a/Source/MetaCastBachelor/Utilities.cpp b/Source/MetaCastBachelor/Utilities.cpp
index 939fe97..343a2ee 100644
--- a/Source/MetaCastBachelor/Utilities.cpp
+++ b/Source/MetaCastBachelor/Utilities.cpp
@@ -41,14 +41,14 @@ double FUtilities::InterpolateDensityAtPosition(const FDensityField* DensityFiel
     const float YFraction = GridPos.Y - YBin;
     const float ZFraction = GridPos.Z - ZBin;
 
-    const double D000 = DensityField->GetVoxelDensityFromGridPosition(XBin, YBin, ZBin);
-    const double D100 = DensityField->GetVoxelDensityFromGridPosition(XBin + 1, YBin, ZBin);
-    const double D010 = DensityField->GetVoxelDensityFromGridPosition(XBin, YBin + 1, ZBin);
-    const double D001 = DensityField->GetVoxelDensityFromGridPosition(XBin, YBin, ZBin + 1);
-    const double D101 = DensityField->GetVoxelDensityFromGridPosition(XBin + 1, YBin, ZBin + 1);
-    const double D011 = DensityField->GetVoxelDensityFromGridPosition(XBin, YBin + 1, ZBin + 1);
-    const double D110 = DensityField->GetVoxelDensityFromGridPosition(XBin + 1, YBin + 1, ZBin);
-    const double D111 = DensityField->GetVoxelDensityFromGridPosition(XBin + 1, YBin + 1, ZBin + 1);
+    const double D000 = DensityField->GridPositionToVoxelDensity(XBin, YBin, ZBin);
+    const double D100 = DensityField->GridPositionToVoxelDensity(XBin + 1, YBin, ZBin);
+    const double D010 = DensityField->GridPositionToVoxelDensity(XBin, YBin + 1, ZBin);
+    const double D001 = DensityField->GridPositionToVoxelDensity(XBin, YBin, ZBin + 1);
+    const double D101 = DensityField->GridPositionToVoxelDensity(XBin + 1, YBin, ZBin + 1);
+    const double D011 = DensityField->GridPositionToVoxelDensity(XBin, YBin + 1, ZBin + 1);
+    const double D110 = DensityField->GridPositionToVoxelDensity(XBin + 1, YBin + 1, ZBin);
+    const double D111 = DensityField->GridPositionToVoxelDensity(XBin + 1, YBin + 1, ZBin + 1);
 
     // Trilinear interpolation
     const double DX00 = FMath::Lerp(D000, D100, XFraction);
@@ -81,14 +81,14 @@ FVector FUtilities::InterpolateGradientAtPosition(const FDensityField* DensityFi
 	float ZFraction = GridPos.Z - ZBin;
 
 	// Fetch gradients from corners of the cell
-	FVector G000 = DensityField->GetVoxelGradientFromGridPosition(XBin, YBin, ZBin);
-	FVector G100 = DensityField->GetVoxelGradientFromGridPosition(XBin + 1, YBin, ZBin);
-	FVector G010 = DensityField->GetVoxelGradientFromGridPosition(XBin, YBin + 1, ZBin);
-	FVector G001 = DensityField->GetVoxelGradientFromGridPosition(XBin, YBin, ZBin + 1);
-	FVector G110 = DensityField->GetVoxelGradientFromGridPosition(XBin + 1, YBin + 1, ZBin);
-	FVector G101 = DensityField->GetVoxelGradientFromGridPosition(XBin + 1, YBin, ZBin + 1);
-	FVector G011 = DensityField->GetVoxelGradientFromGridPosition(XBin, YBin + 1, ZBin + 1);
-	FVector G111 = DensityField->GetVoxelGradientFromGridPosition(XBin + 1, YBin + 1, ZBin + 1);
+	FVector G000 = DensityField->GridPositionToVoxelGradient(XBin, YBin, ZBin);
+	FVector G100 = DensityField->GridPositionToVoxelGradient(XBin + 1, YBin, ZBin);
+	FVector G010 = DensityField->GridPositionToVoxelGradient(XBin, YBin + 1, ZBin);
+	FVector G001 = DensityField->GridPositionToVoxelGradient(XBin, YBin, ZBin + 1);
+	FVector G110 = DensityField->GridPositionToVoxelGradient(XBin + 1, YBin + 1, ZBin);
+	FVector G101 = DensityField->GridPositionToVoxelGradient(XBin + 1, YBin, ZBin + 1);
+	FVector G011 = DensityField->GridPositionToVoxelGradient(XBin, YBin + 1, ZBin + 1);
+	FVector G111 = DensityField->GridPositionToVoxelGradient(XBin + 1, YBin + 1, ZBin + 1);
 
 	// Interpolate along x for each of the yz pairs
 	FVector G00 = FMath::Lerp(G000, G100, XFraction);
@@ -152,7 +152,7 @@ FVector FUtilities::FollowGradientToMaximum(const FDensityField* DensityField, c
 
 TArray<int32> FUtilities::FloodFilling(const FDensityField* DensityField, const int32 StartIndex, const float Threshold)
 {
-	UE_LOG(LogTemp, Warning, TEXT("T: %f"), Threshold);
+	//UE_LOG(LogTemp, Warning, TEXT("Threshold for FloodFilling: %f"), Threshold);
 	
 	TArray<int32> VisitedIndices;
 	if (!DensityField) {
@@ -178,23 +178,108 @@ TArray<int32> FUtilities::FloodFilling(const FDensityField* DensityField, const
 			Visited[CurrentIndex] = true;
 			VisitedIndices.Add(CurrentIndex);
 
-			TArray<int32> Neighbors = DensityField->GetNeighborsFromIndex(CurrentIndex);
-			UE_LOG(LogTemp, Log, TEXT("Visiting Node %d at Position %s with %d neighbors."), CurrentIndex, *DensityField->IndexToGridPosition(CurrentIndex).ToString(), Neighbors.Num());
+			TArray<int32> Neighbors = DensityField->IndexToVoxelNeighbors(CurrentIndex);
+			//UE_LOG(LogTemp, Log, TEXT("Visiting Node %d at Position %s with %d neighbors."), CurrentIndex, *DensityField->IndexToGridPosition(CurrentIndex).ToString(), Neighbors.Num());
             
 			for (int32 NeighborIndex : Neighbors)
 			{
-				if (DensityField->GetVoxelDensityFromIndex(NeighborIndex) > Threshold && !Visited[NeighborIndex]) {
+				const double NeighborDensity = DensityField->IndexToVoxelDensity(NeighborIndex);
+				//UE_LOG(LogTemp, Log, TEXT("Lookign at Neighbor %d at Position %s with density: %f."), NeighborIndex, *DensityField->IndexToGridPosition(NeighborIndex).ToString(), NeighborDensity);
+				
+				if (NeighborDensity > Threshold && !Visited[NeighborIndex]) {
 					Stack.Push(NeighborIndex);
+					//UE_LOG(LogTemp, Log, TEXT("Pushing Neighbor %d to stack."), NeighborIndex);
 				}
 			}
 		}
 	}
 
 	// Logging final details
-	UE_LOG(LogTemp, Log, TEXT("Flood filling completed from start index %d. Total voxels selected: %d"), StartIndex, VisitedIndices.Num());
+	//UE_LOG(LogTemp, Log, TEXT("Flood filling completed from start index %d. Total voxels selected: %d"), StartIndex, VisitedIndices.Num());
 	for (const int32 idx : VisitedIndices) {
-		UE_LOG(LogTemp, Log, TEXT("Selected Voxel Index: %d at Grid Position: %s"), idx, *DensityField->IndexToGridPosition(idx).ToString());
+		//UE_LOG(LogTemp, Log, TEXT("Selected Voxel Index: %d at Grid Position: %s"), idx, *DensityField->IndexToGridPosition(idx).ToString());
 	}
 
 	return VisitedIndices;
 }
+
+/*
+TArray<int32> FUtilities::FloodFilling_2(const FDensityField* DensityField, const float Threshold, TArray<bool>& Visited, TArray<int32>& IndicesToVisit, TArray<int32>& FloodedIndices)
+{	
+	if (!DensityField) {
+		UE_LOG(LogTemp, Warning, TEXT("DensityField is null."));
+		return FloodedIndices;
+	}
+
+	while (IndicesToVisit.Num() > 0)
+	{
+		int32 CurrentIndex = IndicesToVisit.Pop();
+		if (!Visited[CurrentIndex])
+		{
+			Visited[CurrentIndex] = true;
+			FloodedIndices.Add(CurrentIndex);
+
+			TArray<int32> Neighbors = DensityField->IndexToVoxelNeighbors(CurrentIndex);
+            
+			for (int32 NeighborIndex : Neighbors)
+			{
+				const double NeighborDensity = DensityField->IndexToVoxelDensity(NeighborIndex);
+				
+				if (NeighborDensity > Threshold && !Visited[NeighborIndex]) {
+					IndicesToVisit.Push(NeighborIndex);
+				}
+			}
+		}
+	}
+
+	return FloodedIndices;
+}*/
+
+void FUtilities::FloodFilling_2(const FDensityField* DensityField, const float Threshold, TArray<bool>& VisitedIndices, TArray<int32>& IndicesToVisit, TArray<int32>& FloodedIndices, TArray<int32>& PotentialRevisit)
+{
+	if (!DensityField) {
+		UE_LOG(LogTemp, Warning, TEXT("DensityField is null."));
+		return;
+	}
+
+	TArray<int32> CurrentPotentialRevisit;
+
+	constexpr int MaxIterations = 100;
+	int IterationCount = 0;
+	while (IndicesToVisit.Num() > 0)
+	{
+		IterationCount++;
+		if(IterationCount > MaxIterations)
+		{
+			while (IndicesToVisit.Num() > 0) {
+				CurrentPotentialRevisit.Add(IndicesToVisit.Pop());
+			}
+			break;
+		}
+		
+		int32 CurrentIndex = IndicesToVisit.Pop();
+		VisitedIndices[CurrentIndex] = true;
+		const double CurrentDensity = DensityField->IndexToVoxelDensity(CurrentIndex);
+
+		if (CurrentDensity >= Threshold) {
+			FloodedIndices.Add(CurrentIndex);
+
+			TArray<int32> Neighbors = DensityField->IndexToVoxelNeighbors(CurrentIndex);
+			for (int32 NeighborIndex : Neighbors)
+			{
+				if (!VisitedIndices[NeighborIndex])
+				{
+					IndicesToVisit.Push(NeighborIndex);
+				}
+			}
+		} else {
+			CurrentPotentialRevisit.Add(CurrentIndex);
+		}
+	}
+
+	// Update PotentialRevisit with the new list from this run
+	PotentialRevisit = CurrentPotentialRevisit;
+}
+
+
+
diff --git a/Source/MetaCastBachelor/Utilities.h b/Source/MetaCastBachelor/Utilities.h
index 72313c1..6d406d7 100644
--- a/Source/MetaCastBachelor/Utilities.h
+++ b/Source/MetaCastBachelor/Utilities.h
@@ -11,4 +11,5 @@ public:
 	static float GaussianKernel(float Distance, float Sigma);
 	static FVector FollowGradientToMaximum(const FDensityField* DensityField, const FVector& StartPosition);
 	static TArray<int32> FloodFilling(const FDensityField* DensityField, const int32 StartIndex, const float Threshold);
+	static void FloodFilling_2(const FDensityField* DensityField, const float Threshold, TArray<bool>& VisitedIndices, TArray<int32>& IndicesToVisit, TArray<int32>& FloodedIndices, TArray<int32>& PotentialRevisit);
 };
-- 
GitLab