diff --git a/SDFMapCreator.sln.DotSettings.user b/SDFMapCreator.sln.DotSettings.user
index 0c42637..c9bd358 100644
--- a/SDFMapCreator.sln.DotSettings.user
+++ b/SDFMapCreator.sln.DotSettings.user
@@ -6,6 +6,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
<AssemblyExplorer>
diff --git a/SDFMapCreator/Program.cs b/SDFMapCreator/Program.cs
index 7000caf..143a26a 100644
--- a/SDFMapCreator/Program.cs
+++ b/SDFMapCreator/Program.cs
@@ -7,9 +7,7 @@ public class Program {
private const float MAX = 1f;
private const float MIN = 0f;
private static readonly int MAX_THREADS = Environment.ProcessorCount - 2;
- private const bool outputMasks = true;
- private const bool outputSDFs = true;
- private const bool outputGradients = true;
+ private static bool debug = true;
static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS };
static List Images = new();
static List ImageMasks = new();
@@ -24,15 +22,18 @@ public class Program {
public static void Main(string[] args) {
Console.WriteLine("Reading images...");
-
-/*
+
+ if(debug) {
+ if (!Directory.Exists("Debug")) Directory.CreateDirectory("Debug");
+ Console.WriteLine("Debug mode enabled.");
+ }
+
var imagesPath = "images";
for (int i = 0; i < 8; i++) {
var pixels = ImageUtil.LoadImage($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
}
-*/
-
+/*
var pixels = ImageUtil.LoadImage($"./sphereempty.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
pixels = ImageUtil.LoadImage($"./spherehalf.png");
@@ -41,59 +42,50 @@ public class Program {
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
pixels = ImageUtil.LoadImage($"./spherefull.png");
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
-
+*/
+
//check if all the images in Images are the same resolution
if (Images.Select(img => (img.Width, img.Height)).Distinct().Count() > 1) {
Console.WriteLine("Error: Not all images have the same resolution.");
Environment.Exit(1);
}
-
- for (int i = 1; i < Images.Count; i++) {
- for (int x = 0; x < Images[i].Width; x++) {
- for (int y = 0; y < Images[i].Height; y++) {
- Images[i].Pixels[x, y].X = MathF.Min(Images[i - 1].Pixels[x, y].X + Images[i].Pixels[x, y].X, MAX);
- Images[i].Pixels[x, y].Y = MathF.Min(Images[i - 1].Pixels[x, y].Y + Images[i].Pixels[x, y].X, MAX);
- Images[i].Pixels[x, y].Z = MathF.Min(Images[i - 1].Pixels[x, y].Z + Images[i].Pixels[x, y].X, MAX);
- }
- }
- Images[i].Pixels.SaveImage($"./Sum{i}.png");
- }
-
- Console.WriteLine("Creating masks...");
- //for each image pair, create a mask
+
width = (uint)Images[0].Width;
height = (uint)Images[0].Height;
- for (int i = 0; i < Images.Count; i++) {
- ImageMasks.Add(new(SelfMask(Images[i].Pixels, width, height), Images[i], new()));
- if (i < Images.Count - 1) {
- Console.WriteLine($"Creating mask {i}...");
- var mask = GetABMask(Images[i].Pixels, Images[i + 1].Pixels, width, height);
- TransitionMasks.Add(new(mask, Images[i], Images[i + 1]));
- }
+
+ Console.WriteLine("Creating masks...");
+ for (int i = 0; i < Images.Count; i++) { //for each image pair, create a mask
+ var selfMask = SelfMask(Images[i].Pixels);
+ ImageMasks.Add(new(selfMask, Images[i], new()));
+ if (debug) selfMask.SaveImage($"Debug/selfMask{i}.png");
+ if (i >= Images.Count - 1) continue;
+ ConsoleUpdateLine($"Creating mask {i}...");
+ var mask = GetABMask(Images[i].Pixels, Images[i + 1].Pixels);
+ TransitionMasks.Add(new(mask, Images[i], Images[i + 1]));
+ if (debug) mask.SaveImage($"Debug/mask{i}.png");
}
-
- Console.WriteLine("Edge detecting masks...");
+
//EdgeDetect all masks
- foreach (var t in ImageMasks) EdgeDetect(t);
-
- if (outputMasks) {
- Console.WriteLine("Writing masks...");
- for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"mask{i}.png");
+ Console.WriteLine("\nEdge detecting masks...");
+ foreach (var mask in ImageMasks) {
+ ConsoleUpdateLine($"Edge detecting mask {ImageMasks.IndexOf(mask)}...");
+ EdgeDetect(mask);
}
+ if (debug) for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png");
Console.WriteLine("Creating SDFs...");
for (var i = 0; i < ImageMasks.Count; i++) {
var mask = ImageMasks[i];
SDFs.Add(SDF(mask));
- if (outputSDFs) SDFs[i].SDF.SaveImage($"sdf{i}.png");
+ if (debug) SDFs[i].SDF.SaveImage($"Debug/sdf{i}.png");
}
Console.WriteLine("Creating gradients...");
for (var i = 0; i < TransitionMasks.Count; i++) {
- Console.WriteLine($"Generating gradient {i}...");
+ ConsoleUpdateLine($"Generating gradient {i}...");
var gradientData = Gradient(TransitionMasks[i], SDFs[i], SDFs[i + 1]);
Gradients.Add(gradientData);
- if (outputGradients) gradientData.SaveImage($"gradient{i}.png");
+ if (debug) gradientData.SaveImage($"Debug/gradient{i}.png");
}
// generate final image
@@ -136,8 +128,6 @@ public class Program {
}
private static void EdgeDetect(MaskData maskData) {
- uint width = (uint)maskData.Image.Width;
- uint height = (uint)maskData.Image.Height;
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("Running edge detection...");
@@ -155,8 +145,6 @@ public class Program {
}
static Vector3[,] Gradient(TransitionMaskData mask, SDFData sdfA, SDFData sdfB) {
- uint width = (uint)mask.ImageA.Width;
- uint height = (uint)mask.ImageA.Height;
int iterCount = 0;
var sw = new Stopwatch();
sw.Start();
@@ -191,43 +179,13 @@ public class Program {
}
static SDFData SDF(MaskData mask) {
- var width = (uint)mask.Mask.GetLength(0);
- var height = (uint)mask.Mask.GetLength(1);
- float AbsMax = MIN;
int iterCount = 0;
var sw = new Stopwatch();
sw.Start();
- /*Parallel.For(0, width * height, parallelOptions, (i) =>
- {
- //convert 1D index to 2D index
- var x = (int)(i % width);
- var y = (int)(i / width);
- Vector2 p = new(x / (float)width, y / (float)height); //get the pixel position as a Vector2
- float minDist = MAX + 1; //initialize the minimum distance to the maximum possible value
-
- //loop through all the pixels in the mask
- foreach (var edge in mask.Edges) {
- Vector2 edgeNorm = new(edge.X / (float)width, edge.Y / (float)height);
- float dist = Vector2.DistanceSquared(p, edgeNorm);
- if (dist < minDist) minDist = dist;
- }
-
- if (minDist > MAX)
- minDist = MAX;
-
- temp[x, y] = new(minDist);
- if (minDist > AbsMax) AbsMax = minDist;
- iterCount++;
- if (iterCount % (width * height / 100) == 0) {
- ConsoleUpdateLine(
- $"Progress: {iterCount / (float)(width * height):P}% | {iterCount / (sw.Elapsed.TotalSeconds):N0} pixels/s");
- }
- });*/
kernels.Sdf(mask.Edges.ToArray(), (int)width, (int)height, out var temp);
- Console.WriteLine(
- $"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
+ Console.WriteLine($"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({iterCount / sw.Elapsed.TotalSeconds:N0} pixels/s)");
return new(temp);
}
@@ -252,12 +210,12 @@ public class Program {
private static float EuclideanDistance(Vector2 a, Vector2 b) =>
MathF.Sqrt(MathF.Pow(a.X - b.X, 2) + MathF.Pow(a.Y - b.Y, 2));
- static Vector3[,] GetABMask(Vector3[,] A, Vector3[,] B, uint resX, uint resY) {
+ static Vector3[,] GetABMask(Vector3[,] A, Vector3[,] B) {
kernels.ABMask(A, B, out var temp);
return temp;
}
- static Vector3[,] SelfMask(Vector3[,] A, uint resX, uint resY) {
+ static Vector3[,] SelfMask(Vector3[,] A) {
kernels.SelfMask(A, out var temp);
return temp;
}
diff --git a/SDFMapCreator/SdfKernels.cs b/SDFMapCreator/SdfKernels.cs
index 5cea7c4..02b0b6f 100644
--- a/SDFMapCreator/SdfKernels.cs
+++ b/SDFMapCreator/SdfKernels.cs
@@ -27,11 +27,13 @@ public partial class SdfKernels {
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
Console.WriteLine($"{GetInfoString(accelerator)}");
}
+
Console.WriteLine("Reading available accelerators (OpenCL only)...");
foreach (var device in gpuContext.GetCLDevices()) {
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
Console.WriteLine($"{GetInfoString(accelerator)}");
}
+
Console.WriteLine("Reading available accelerators (CPU only)...");
foreach (var device in gpuContext.GetCPUDevices()) {
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
@@ -130,7 +132,7 @@ public partial class SdfKernels {
sdf = buffer.GetAsArray2D();
}
- public void Gradient(ref Vector3[,] mask, ref Vector3[,] sdfa, ref Vector3[,] sdfb, out Vector3[,] gradient) {
+ public void Gradient(Vector3[,] mask, Vector3[,] sdfa, Vector3[,] sdfb, out Vector3[,] gradient) {
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
int width = mask.GetLength(0);
int height = mask.GetLength(1);