diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini
index 19b59fc6679ce83857ad5936b684a8ae7cbf3c46..05ba680c81fb1b6a8ffa562e19b877c137bd4e96 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
Binary files a/Content/MetaPointMap.umap and b/Content/MetaPointMap.umap differ
diff --git a/Content/MetaPointMap_BuiltData.uasset b/Content/MetaPointMap_BuiltData.uasset
index 1bf02fa1814c30bc66b1c21252e01906ddb1ac28..24285dcf828b76f9af8653034e84014cb1f8e362 100644
Binary files a/Content/MetaPointMap_BuiltData.uasset and b/Content/MetaPointMap_BuiltData.uasset differ
diff --git a/Content/SelectionVolume.uasset b/Content/SelectionVolume.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..73d06d7c6830ac1fc883baf71e935610588d84e9
Binary files /dev/null and b/Content/SelectionVolume.uasset differ
diff --git a/Source/MetaCastBachelor/DensityField.cpp b/Source/MetaCastBachelor/DensityField.cpp
index 0cfcdc980f62fdcada431c3185338949ad7cb496..3aa6e9bcc1397e4cdfae5b1ab8fb2388fe6895b7 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 3e71da479c4f0d9aac7150ba865f808cf39928f1..7477fd5c318dc75b9d8a4a11a527eaaaf6160fb5 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 2e920d0f027e3aac7dc5e336b74444c611bdf2d4..dd70f5d1ad2ca193c7bfb2668b6b6e6dbc197ff4 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 c95ffd91893f145d901f80b2ad764472104b68f3..ce3e88b1466bceed87a1c4f53bb1e05394e40320 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 a5a93cf2dfb359253ef3d3c918e80dfee4409b63..d6482df6e1cee64a437fc509e340452d6b98d930 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 939fe9769c638d432410ff049faa3f206a36b063..343a2ee4f57a50551b4b9088c17277e65e9153ac 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 72313c10410e4cf42b9138d7e62023d5a9c58b72..6d406d74976619aeb28b4b9419e1dd45daf112f1 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);
 };