From f342a2158b154917d3d18967d44338effa851776 Mon Sep 17 00:00:00 2001 From: Samuele Lorefice Date: Mon, 7 Apr 2025 09:45:34 +0200 Subject: [PATCH] Command line argument parsing added, general logging cleanup. Buildchain improvements --- .../.idea/riderPublish.xml | 10 ++ ...apCreator.run.xml => Run SDF Tool.run.xml} | 9 +- SDFMapCreator.sln | 1 + SDFMapCreator/Program.cs | 95 ++++++++++++------ SDFMapCreator/SDFMapCreator.csproj | 62 ++++++------ SDFMapCreator/SdfKernels.cs | 6 +- SDFMapCreator/copyImages.sh | 9 ++ SDFMapCreator/{ => images}/1.png | Bin SDFMapCreator/{ => images}/2.png | Bin SDFMapCreator/{ => images}/TestPattern.png | Bin SDFMapCreator/{ => images}/spherecut.png | Bin SDFMapCreator/{ => images}/spherecut32.png | Bin SDFMapCreator/{ => images}/sphereempty.png | Bin SDFMapCreator/{ => images}/spherefull.png | Bin SDFMapCreator/{ => images}/spherefull32.png | Bin SDFMapCreator/{ => images}/spherehalf.png | Bin SDFMapCreator/{ => images}/spherehalf32.png | Bin 17 files changed, 125 insertions(+), 67 deletions(-) create mode 100644 .idea/.idea.SDFMapCreator/.idea/riderPublish.xml rename .run/{SDFMapCreator.run.xml => Run SDF Tool.run.xml} (57%) create mode 100644 SDFMapCreator/copyImages.sh rename SDFMapCreator/{ => images}/1.png (100%) rename SDFMapCreator/{ => images}/2.png (100%) rename SDFMapCreator/{ => images}/TestPattern.png (100%) rename SDFMapCreator/{ => images}/spherecut.png (100%) rename SDFMapCreator/{ => images}/spherecut32.png (100%) rename SDFMapCreator/{ => images}/sphereempty.png (100%) rename SDFMapCreator/{ => images}/spherefull.png (100%) rename SDFMapCreator/{ => images}/spherefull32.png (100%) rename SDFMapCreator/{ => images}/spherehalf.png (100%) rename SDFMapCreator/{ => images}/spherehalf32.png (100%) diff --git a/.idea/.idea.SDFMapCreator/.idea/riderPublish.xml b/.idea/.idea.SDFMapCreator/.idea/riderPublish.xml new file mode 100644 index 0000000..2dcb008 --- /dev/null +++ b/.idea/.idea.SDFMapCreator/.idea/riderPublish.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.run/SDFMapCreator.run.xml b/.run/Run SDF Tool.run.xml similarity index 57% rename from .run/SDFMapCreator.run.xml rename to .run/Run SDF Tool.run.xml index ad24374..c976ccd 100644 --- a/.run/SDFMapCreator.run.xml +++ b/.run/Run SDF Tool.run.xml @@ -1,7 +1,7 @@ - - \ No newline at end of file diff --git a/SDFMapCreator.sln b/SDFMapCreator.sln index 6512174..f6f5aa1 100644 --- a/SDFMapCreator.sln +++ b/SDFMapCreator.sln @@ -12,5 +12,6 @@ Global {915A479D-55CC-4B48-B7C0-75E0B8978698}.Debug|Any CPU.Build.0 = Debug|Any CPU {915A479D-55CC-4B48-B7C0-75E0B8978698}.Release|Any CPU.ActiveCfg = Release|Any CPU {915A479D-55CC-4B48-B7C0-75E0B8978698}.Release|Any CPU.Build.0 = Release|Any CPU + {915A479D-55CC-4B48-B7C0-75E0B8978698}.Debug|Any CPU.Deploy.0 = Debug|Any CPU EndGlobalSection EndGlobal diff --git a/SDFMapCreator/Program.cs b/SDFMapCreator/Program.cs index f5f470b..c2f517a 100644 --- a/SDFMapCreator/Program.cs +++ b/SDFMapCreator/Program.cs @@ -1,15 +1,40 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using CommandLine; namespace SDFMapCreator; +public class Options { + [Option('d', "debug", Required = false, HelpText = "Enable debug mode.")] + public bool Debug { get; set; } = false; + [Option('D', "imgDirectory", Required = true, HelpText = "Input Images directory.")] + public string ImgDirectory { get; set; } = "images"; + [Option('i', "images", Required = true, HelpText = "Images file names separated by ';' and in the correct order.")] + public string Images { get; set; } = ""; + [Option('o', "output", Required = true, HelpText = "Output file path.")] + public string OutputFile { get; set; } = "output.png"; + [Option('b', "blur", Required = false, HelpText = "How many blur iterations to run.")] + public int BlurIterations { get; set; } = 10; + [Option('r', "radius", Required = false, HelpText = "Blur radius.")] + public float BlurRadius { get; set; } = 100f; + [Option('s', "step", Required = false, HelpText = "Blur step size.")] + public float BlurStep { get; set; } = 0.5f; + [Option("sigma", Required = false, HelpText = "Blur sigma value (weighting).")] + public float BlurSigma { get; set; } = 1f; +} + public static class Program { + #region Magic Values const float MAX = 1f; const float MIN = 0f; static readonly int MAX_THREADS = Environment.ProcessorCount - 2; - static bool debug = true; static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS }; + static char PSep => Path.DirectorySeparatorChar; + #endregion + + static Options options = null!; + static List Images = new(); static List ImageMasks = new(); static List TransitionMasks = new(); @@ -22,23 +47,32 @@ public static class Program { static void ConsoleUpdateLine(string s) => Console.Write("\r" + s); public static void Main(string[] args) { - Console.WriteLine("Reading images..."); + var parser = Parser.Default; + + parser.ParseArguments(args) + .WithParsed(o => options = o) + .WithNotParsed(o => { + Environment.Exit(1); + }); - if (debug) { - if (!Directory.Exists("Debug")) Directory.CreateDirectory("Debug"); + string debugPath = $"{Environment.CurrentDirectory}{PSep}Debug"; + if (options.Debug) { + if (!Directory.Exists(debugPath)) Directory.CreateDirectory(debugPath); Console.WriteLine("Debug mode enabled."); } - - var imagesPath = "images"; - for (var i = 0; i < 8; i++) { - var pixels = ImageUtil.LoadImage($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png"); + Console.WriteLine("Reading images..."); + var imageNames = options.Images.Split(';'); + for (var i = 0; i < imageNames.GetLength(0); i++) { + string imgPath = $"{options.ImgDirectory}{PSep}{imageNames[i]}"; + ConsoleUpdateLine($"Reading image {imgPath}"); + var pixels = ImageUtil.LoadImage(imgPath); Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1))); } - + Console.WriteLine("\n"); //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."); + Console.WriteLine("\nError: Not all images have the same resolution."); Environment.Exit(1); } @@ -46,7 +80,8 @@ public static class Program { height = (uint)Images[0].Height; // sum all images together - if(debug) Images[0].Pixels.SaveImage("Debug/Sum0.png"); + var sumPath = $"{debugPath}{PSep}Sum"; + if(options.Debug) Images[0].Pixels.SaveImage($"{sumPath}0.png"); for (int i = 1; i < Images.Count; i++) { for (int x = 0; x < Images[i].Width; x++) { @@ -56,18 +91,19 @@ public static class Program { Images[i].Pixels[x, y].Z = MathF.Min(Images[i - 1].Pixels[x, y].Z + Images[i].Pixels[x, y].X, MAX); } } - - if(debug)Images[i].Pixels.SaveImage($"Debug/Sum{i}.png"); + if(options.Debug)Images[i].Pixels.SaveImage($"{sumPath}{i}.png"); } - - Console.WriteLine("Creating masks..."); + Console.WriteLine("\nCreating masks..."); for (var i = 0; i < Images.Count; i++) { //for each image pair, create a mask + ConsoleUpdateLine($"Creating mask {i}..."); + var selfMask = SelfMask(Images[i].Pixels); ImageMasks.Add(new(selfMask, Images[i], new())); - if (debug) selfMask.SaveImage($"Debug/selfMask{i}.png"); + if (options.Debug) selfMask.SaveImage($"{debugPath}{PSep}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])); } @@ -78,15 +114,16 @@ public static class Program { ConsoleUpdateLine($"Edge detecting mask {ImageMasks.IndexOf(mask)}..."); EdgeDetect(mask); } - if (debug) + + if (options.Debug) for (var i = 0; i < TransitionMasks.Count; i++) - ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png"); + ImageMasks[i].Mask.SaveImage($"{debugPath}{PSep}mask{i}.png"); Console.WriteLine("Creating SDFs..."); for (var i = 0; i < ImageMasks.Count; i++) { var mask = ImageMasks[i]; SDFs.Add(SDF(mask)); - if (debug) SDFs[i].SDF.SaveImage($"Debug/sdf{i}.png"); + if (options.Debug) SDFs[i].SDF.SaveImage($"{debugPath}{PSep}sdf{i}.png"); } Console.WriteLine("Creating gradients..."); @@ -94,7 +131,7 @@ public static class Program { ConsoleUpdateLine($"Generating gradient {i}..."); var gradientData = Gradient(TransitionMasks[i], SDFs[i], SDFs[i + 1]); Gradients.Add(gradientData); - if (debug) gradientData.SaveImage($"Debug/gradient{i}.png"); + if (options.Debug) gradientData.SaveImage($"{debugPath}{PSep}gradient{i}.png"); } // generate final image @@ -110,7 +147,7 @@ public static class Program { for (var i = 0; i < Gradients.Count; i++) { var mask = ImageMasks[i + 1]; var gradient = Gradients[i]; - Console.WriteLine($"Applying gradient {i}..., {currStep} -> {currStep + stepIncrement}"); + Console.WriteLine($"Applying gradient {i}..., Step: {currStep:F2} -> Next: {(currStep + stepIncrement):F2}"); for (var x = 0; x < mask.Mask.GetLength(0); x++) { for (var y = 0; y < mask.Mask.GetLength(1); y++) { if (mask.Mask[x,y].X == 0) continue; @@ -122,21 +159,21 @@ public static class Program { currStep += stepIncrement; } - finalImage.SaveImage("Debug/Final.png"); + finalImage.SaveImage($"{options.OutputFile}.png"); // apply directional blur - var iterations = 1; - var radius = 100f; - var step = .5f; - var sigma = 1f; + var iterations = options.BlurIterations; + var radius = options.BlurRadius; + var step = options.BlurStep; + var sigma = options.BlurSigma; var totalMask = SelfMask(Images[^1].Pixels); - totalMask.SaveImage("Debug/TotalMask.png"); + totalMask.SaveImage($"{debugPath}{PSep}TotalMask.png"); for (var i = 0; i < iterations; i++) { Console.WriteLine($"Applying directional blur {i + 1}/{iterations}..."); finalImage = DirectionalBlur(finalImage, totalMask, radius, step, sigma); } - finalImage.SaveImage("finalBlur.png"); + finalImage.SaveImage(options.OutputFile); Console.WriteLine("Done!"); } diff --git a/SDFMapCreator/SDFMapCreator.csproj b/SDFMapCreator/SDFMapCreator.csproj index 825581d..a2ee636 100644 --- a/SDFMapCreator/SDFMapCreator.csproj +++ b/SDFMapCreator/SDFMapCreator.csproj @@ -21,59 +21,59 @@ - - Always - - - Always - - - PreserveNewest - - Always + Never - Always + Never - Always + Never - Always + Never - Always + Never - Always + Never - Always + Never - Always + Never - - Always + + Never - - Always + + Never - - Always + + Never - - Always + + Never - - Always + + Never - - Always + + Never - - Always + + Never + + + Never + + + Never + + + Never diff --git a/SDFMapCreator/SdfKernels.cs b/SDFMapCreator/SdfKernels.cs index fb5b02e..da10bfe 100644 --- a/SDFMapCreator/SdfKernels.cs +++ b/SDFMapCreator/SdfKernels.cs @@ -25,19 +25,19 @@ public partial class SdfKernels { Console.WriteLine("Reading available accelerators (CUDA only)..."); foreach (var device in gpuContext.GetCudaDevices()) { using var accelerator = device.CreateAccelerator(gpuContext); - Console.WriteLine($"{GetInfoString(accelerator)}"); + Console.WriteLine($"Found accelerator: {accelerator.Name} {accelerator.AcceleratorType}"); } Console.WriteLine("Reading available accelerators (OpenCL only)..."); foreach (var device in gpuContext.GetCLDevices()) { using var accelerator = device.CreateAccelerator(gpuContext); - Console.WriteLine($"{GetInfoString(accelerator)}"); + Console.WriteLine($"Found accelerator: {accelerator.Name} {accelerator.AcceleratorType}"); } Console.WriteLine("Reading available accelerators (CPU only)..."); foreach (var device in gpuContext.GetCPUDevices()) { using var accelerator = device.CreateAccelerator(gpuContext); - Console.WriteLine($"{GetInfoString(accelerator)}"); + Console.WriteLine($"Found accelerator: {accelerator.Name} {accelerator.AcceleratorType}"); } } diff --git a/SDFMapCreator/copyImages.sh b/SDFMapCreator/copyImages.sh new file mode 100644 index 0000000..eda9e83 --- /dev/null +++ b/SDFMapCreator/copyImages.sh @@ -0,0 +1,9 @@ +if [ -d ./bin/Debug/net8.0/ ]; then + echo "Copying images to bin/Debug" + cp -r ./images ./bin/Debug/net8.0/ +fi + +if [ -d ./bin/Release/net8.0/ ]; then + echo "Copying images to bin/Release" + cp -r ./images ./bin/Release/net8.0/ +fi \ No newline at end of file diff --git a/SDFMapCreator/1.png b/SDFMapCreator/images/1.png similarity index 100% rename from SDFMapCreator/1.png rename to SDFMapCreator/images/1.png diff --git a/SDFMapCreator/2.png b/SDFMapCreator/images/2.png similarity index 100% rename from SDFMapCreator/2.png rename to SDFMapCreator/images/2.png diff --git a/SDFMapCreator/TestPattern.png b/SDFMapCreator/images/TestPattern.png similarity index 100% rename from SDFMapCreator/TestPattern.png rename to SDFMapCreator/images/TestPattern.png diff --git a/SDFMapCreator/spherecut.png b/SDFMapCreator/images/spherecut.png similarity index 100% rename from SDFMapCreator/spherecut.png rename to SDFMapCreator/images/spherecut.png diff --git a/SDFMapCreator/spherecut32.png b/SDFMapCreator/images/spherecut32.png similarity index 100% rename from SDFMapCreator/spherecut32.png rename to SDFMapCreator/images/spherecut32.png diff --git a/SDFMapCreator/sphereempty.png b/SDFMapCreator/images/sphereempty.png similarity index 100% rename from SDFMapCreator/sphereempty.png rename to SDFMapCreator/images/sphereempty.png diff --git a/SDFMapCreator/spherefull.png b/SDFMapCreator/images/spherefull.png similarity index 100% rename from SDFMapCreator/spherefull.png rename to SDFMapCreator/images/spherefull.png diff --git a/SDFMapCreator/spherefull32.png b/SDFMapCreator/images/spherefull32.png similarity index 100% rename from SDFMapCreator/spherefull32.png rename to SDFMapCreator/images/spherefull32.png diff --git a/SDFMapCreator/spherehalf.png b/SDFMapCreator/images/spherehalf.png similarity index 100% rename from SDFMapCreator/spherehalf.png rename to SDFMapCreator/images/spherehalf.png diff --git a/SDFMapCreator/spherehalf32.png b/SDFMapCreator/images/spherehalf32.png similarity index 100% rename from SDFMapCreator/spherehalf32.png rename to SDFMapCreator/images/spherehalf32.png