Skip to content
Snippets Groups Projects
Commit 01357f06 authored by Timon Römer's avatar Timon Römer
Browse files

Adds MagicWand with KDTree

parent 17190a20
No related branches found
No related tags found
No related merge requests found
No preview for this file type
No preview for this file type
UEPlugin-Kdtree @ 94ef56d4
Subproject commit 94ef56d465cf19d96e17b6e34c3a3739e1384a7e
#include "MagicWand.h"
#include "KdtreeBPLibrary.h"
#include "Utilities.h"
#include "Generators/MarchingCubes.h"
......@@ -88,7 +90,7 @@ void UMagicWand::InitMagicWandSelection()
World = GetWorld();
AbortMarchingCubes = true;
AccumulatedTime = 0.0f;
//AccumulatedTime = 0.0f;
}
void UMagicWand::SelectParticles(const FVector& InputPosition)
......@@ -97,6 +99,7 @@ void UMagicWand::SelectParticles(const FVector& InputPosition)
{
AccumulatedTime = -10000;
UE_LOG(LogTemp, Warning, TEXT("Input recognized!"));
AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
{
const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation();
......@@ -104,7 +107,7 @@ void UMagicWand::SelectParticles(const FVector& InputPosition)
PerformMagicWandSelection(SelectionLocalPosition);
UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
//UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
});
}
......@@ -118,6 +121,8 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
return;
}
UE_LOG(LogTemp, Warning, TEXT("Starting Selection!"));
//UE_LOG(LogTemp, Warning, TEXT("Looking for Seed Index:"));
// Find the closest point to the input position as the seed
const int32 InputVoxelIndex = MyDensityField->WorldPositionToIndex(InputPosition);
......@@ -126,6 +131,27 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
int32 SeedIndex = INDEX_NONE;
float MinDistance = FLT_MAX;
for(int NeighborDistance = 0; NeighborDistance < 3; ++NeighborDistance)
{
const int NumNeighbors = Neighbors.Num();
for (int i = 0; i < NumNeighbors; ++i)
{
const int CurrentNeighborIndex = Neighbors[i];
TArray<int32> NeighborsOfNeighbors = MyDensityField->IndexToVoxelNeighbors(CurrentNeighborIndex);
for (int CurrentNeighborOfNeighborIndex : NeighborsOfNeighbors)
{
if (!Neighbors.Contains(CurrentNeighborOfNeighborIndex))
{
Neighbors.Add(CurrentNeighborOfNeighborIndex);
}
}
}
}
for (const int CurrentNeighborIndex : Neighbors)
{
TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentNeighborIndex);
......@@ -149,54 +175,51 @@ void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition)
//Expand selection from the seed
ExpandSelection(SeedIndex);
}else
{
AccumulatedTime = 0;
}
}
void UMagicWand::ExpandSelection(const int32 SeedIndex)
{
UE_LOG(LogTemp, Warning, TEXT("Expanding!"));
TQueue<int32> ToProcess;
ToProcess.Enqueue(SeedIndex);
SelectedClusterIndices.Add(SeedIndex);
MyPointCloud->SelectionFlags[SeedIndex] = true;
const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold;
TArray<int> Indices;
TArray<FVector> Data;
while (!ToProcess.IsEmpty())
{
int32 CurrentQueuePointIndex;
ToProcess.Dequeue(CurrentQueuePointIndex);
FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex];
const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex];
const int32 CurrentVoxelQueueIndex = MyDensityField->WorldPositionToIndex(CurrentQueuePointPosition);
Indices.Empty();
Data.Empty();
/*
TArray<int32> Neighbors = MyDensityField->IndexToVoxelNeighbors(CurrentVoxelQueueIndex);
Neighbors.Add(CurrentVoxelQueueIndex);
UKdtreeBPLibrary::CollectFromKdtree(MyPointCloud->MyKdTree, CurrentQueuePointPosition, MyPointCloud->InfluenceRadius, Indices, Data);
for (const int CurrentVoxelNeighborIndex : Neighbors)
for(int i = 0; i < Indices.Num(); ++i)
{
TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentVoxelNeighborIndex);
const int CurrentPointComparisonIndex = Indices[i];
for(const int32 CurrentPointComparisonIndex : PointIndices)
{
if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex])
{
continue;
}
FVector CurrentComparisonPosition = MyDensityField->IndexToVoxelPosition(CurrentPointComparisonIndex);
if (FVector::Dist(CurrentQueuePointPosition, CurrentComparisonPosition) <= ProximityThreshold)
{
ToProcess.Enqueue(CurrentPointComparisonIndex);
SelectedClusterIndices.Add(CurrentPointComparisonIndex);
MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true;
}
}
}*/
// -------------------
/*
const int32 StartX = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.X - ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X));
const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.X + ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X));
const int32 StartY = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Y - ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y));
......@@ -205,24 +228,23 @@ void UMagicWand::ExpandSelection(const int32 SeedIndex)
const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Z + ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z));
/*
UE_LOG(LogTemp, Warning, TEXT("CurrentQueuePointPosition: %s"), *CurrentQueuePointPosition.ToString());
UE_LOG(LogTemp, Warning, TEXT("StartX: %d"), StartX);
UE_LOG(LogTemp, Warning, TEXT("EndX: %d"), EndX);
UE_LOG(LogTemp, Warning, TEXT("StartY: %d"), StartY);
UE_LOG(LogTemp, Warning, TEXT("EndY: %d"), EndY);
UE_LOG(LogTemp, Warning, TEXT("StartZ: %d"), StartZ);
UE_LOG(LogTemp, Warning, TEXT("EndZ: %d"), EndZ);*/
ParallelFor(EndZ - StartZ + 1, [&](const int32 ZOffset) {
const int32 Z = StartZ + ZOffset;
UE_LOG(LogTemp, Warning, TEXT("EndZ: %d"), EndZ);
for (int32 Z = StartZ; Z <= EndZ; ++Z)
{
for (int32 Y = StartY; Y <= EndY; ++Y)
{
for (int32 X = StartX; X <= EndX; ++X)
{
const int32 CurrentVoxelComparisonIndex = MyDensityField->GridPositionToIndex(X, Y, Z);
/*
if(!MyDensityField->IsValidIndex(CurrentVoxelComparisonIndex))
{
continue;
......@@ -238,26 +260,21 @@ void UMagicWand::ExpandSelection(const int32 SeedIndex)
}
FVector CurrentComparisonPosition = MyPointCloud->PositionVectors[CurrentPointComparisonIndex];
const double Distance = FVector::Distance(CurrentQueuePointPosition, CurrentComparisonPosition);
//UE_LOG(LogTemp, Warning, TEXT("CurrentQueuePointPosition: %s"), *CurrentQueuePointPosition.ToString());
//UE_LOG(LogTemp, Warning, TEXT("CurrentComparisonPosition: %s"), *CurrentComparisonPosition.ToString());
//UE_LOG(LogTemp, Warning, TEXT("Distance: %f"), Distance);
const double SquaredDistance = FVector::DistSquared(CurrentQueuePointPosition, CurrentComparisonPosition);
if (Distance <= ProximityThreshold)
if (SquaredDistance <= SquaredProximityThreshold)
{
ToProcess.Enqueue(CurrentPointComparisonIndex);
SelectedClusterIndices.Add(CurrentPointComparisonIndex);
//SelectedClusterIndices.Add(CurrentPointComparisonIndex);
MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true;
}
}
}
}
});
}*/
}
UE_LOG(LogTemp, Warning, TEXT("Calculations done!"));
AccumulatedTime = 0;
}
......
......@@ -30,6 +30,7 @@ class UMagicWand : public UMetaCastBaseline
float MarchingCubeSize = 0;
UPROPERTY(EditAnywhere)
int EvaluationsPerSecond = 10;
UPROPERTY(EditAnywhere)
float AccumulatedTime = 0.0;
UPROPERTY(EditAnywhere)
float ProximityThreshold = 0.1f;
......
......@@ -10,7 +10,7 @@ public class MetaCastBachelor : ModuleRules
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ProceduralMeshComponent", "EnhancedInput"});
PrivateDependencyModuleNames.AddRange(new string[] {"GPUPointCloudRenderer", "GPUPointCloudRendererEditor", "RWTHVRToolkit", "ProceduralMeshComponent"});
PrivateDependencyModuleNames.AddRange(new string[] {"GPUPointCloudRenderer", "GPUPointCloudRendererEditor", "RWTHVRToolkit", "ProceduralMeshComponent", "Kdtree"});
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
......
#include "MetaPoint.h"
#include "Utilities.h"
#include "Generators/MarchingCubes.h"
#include "UObject/GCObjectScopeGuard.h"
UMetaPoint::UMetaPoint() : LocalMaximumIndex(0), MyDensityField(nullptr), MetaPointThreshold(0), World(nullptr)
{
......
#include "PointCloud.h"
#include "KdtreeBPLibrary.h"
#include "PointCloudDataReader.h"
// Sets default values
APointCloud::APointCloud()
: MyDensityField(nullptr), PointCloudVisualizer(nullptr), SelectedMaterial(nullptr), UnselectedMaterial(nullptr)
: MyDensityField(nullptr), MyKdTree(), PointCloudVisualizer(nullptr), SelectedMaterial(nullptr), UnselectedMaterial(nullptr)
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
......@@ -18,6 +19,10 @@ void APointCloud::BeginPlay()
ReadPointCloudFromFile(PointInputData, FlagInputData);
InitPointCloudVisualizer();
SetupDensityFieldFromPointCloud();
UKdtreeBPLibrary::BuildKdtree(MyKdTree, PositionVectors);
//UKdtreeBPLibrary::DumpKdtreeToConsole(MyKdTree);
UKdtreeBPLibrary::ValidateKdtree(MyKdTree);
}
void APointCloud::ReadPointCloudFromFile(const FFilePath FileNamePoints, const FFilePath FileNameFlags)
......
#pragma once
#include "CoreMinimal.h"
#include "GPUPointCloudRendererComponent.h"
#include "KdtreeCommon.h"
#include "GameFramework/Actor.h"
#include "MetaCastBachelor/DensityField.h"
#include "PointCloud.generated.h"
......@@ -12,29 +13,30 @@ class APointCloud : public AActor
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
float InfluenceRadius = 3.0f;
mutable FCriticalSection DataGuard;
FDensityField* MyDensityField;
FVector MinBounds;
FVector MaxBounds;
FKdtree MyKdTree;
UPROPERTY()
TArray<FVector> PositionVectors;
UPROPERTY()
TArray<bool> DefaultFlags;
UPROPERTY()
TArray<bool> SelectionFlags;
UPROPERTY()
TArray<FColor> PointColors;
mutable FCriticalSection DataGuard;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Bounds")
FVector MinBounds;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Bounds")
FVector MaxBounds;
UPROPERTY()
UGPUPointCloudRendererComponent* PointCloudVisualizer;
UPROPERTY(EditAnywhere)
float InfluenceRadius = 3.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Visualization")
float SplatSize = 1.0f;
......@@ -50,7 +52,6 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
UMaterialInterface* UnselectedMaterial;
// Sets default values for this actor's properties
APointCloud();
void InitPointCloudVisualizer();
void UpdateBounds();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment