174 lines
5.8 KiB
Diff
174 lines
5.8 KiB
Diff
diff --git a/UVtools.Cmd/Program.cs b/UVtools.Cmd/Program.cs
|
|
index 6d2d1ff..38da048 100644
|
|
--- a/UVtools.Cmd/Program.cs
|
|
+++ b/UVtools.Cmd/Program.cs
|
|
@@ -45,6 +45,7 @@ public static async Task<int> Main(params string[] args)
|
|
ExtractCommand.CreateCommand(),
|
|
CopyParametersCommand.CreateCommand(),
|
|
SetThumbnailCommand.CreateCommand(),
|
|
+ PcbExposeCommand.CreateCommand(),
|
|
|
|
CompareCommand.CreateCommand(),
|
|
|
|
diff --git a/UVtools.Cmd/Symbols/PcbExposeCommand.cs b/UVtools.Cmd/Symbols/PcbExposeCommand.cs
|
|
new file mode 100644
|
|
index 0000000..e67e876
|
|
--- /dev/null
|
|
+++ b/UVtools.Cmd/Symbols/PcbExposeCommand.cs
|
|
@@ -0,0 +1,155 @@
|
|
+/*
|
|
+ * GNU AFFERO GENERAL PUBLIC LICENSE
|
|
+ * Version 3, 19 November 2007
|
|
+ * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
+ * Everyone is permitted to copy and distribute verbatim copies
|
|
+ * of this license document, but changing it is not allowed.
|
|
+ */
|
|
+
|
|
+using System;
|
|
+using System.CommandLine;
|
|
+using System.IO;
|
|
+using UVtools.Core.FileFormats;
|
|
+using UVtools.Core.Operations;
|
|
+
|
|
+namespace UVtools.Cmd.Symbols;
|
|
+
|
|
+internal static class PcbExposeCommand
|
|
+{
|
|
+ internal static Command CreateCommand()
|
|
+ {
|
|
+ var gerberArgument = new Argument<FileInfo[]>("gerber-files")
|
|
+ {
|
|
+ Description = "One or more Gerber/drill files (.gbr .gtl .gbl .gts .gbs .drl etc.)",
|
|
+ };
|
|
+
|
|
+ var exposureOption = new Option<decimal>("-e", "--exposure")
|
|
+ {
|
|
+ Description = "Exposure time in seconds (0 = keep value from input file)",
|
|
+ DefaultValueFactory = _ => 0m,
|
|
+ };
|
|
+
|
|
+ var invertOption = new Option<bool>("-i", "--invert")
|
|
+ {
|
|
+ Description = "Invert image color",
|
|
+ };
|
|
+
|
|
+ var mirrorOption = new Option<bool>("-m", "--mirror")
|
|
+ {
|
|
+ Description = "Mirror the image horizontally",
|
|
+ };
|
|
+
|
|
+ var mergeOption = new Option<bool>("--merge")
|
|
+ {
|
|
+ Description = "Merge all gerber files into a single layer",
|
|
+ };
|
|
+
|
|
+ var invertPolarityOption = new Option<bool>("--invert-polarity")
|
|
+ {
|
|
+ Description = "Invert Gerber drawing polarity for all supplied files",
|
|
+ };
|
|
+
|
|
+ var antiAliasingOption = new Option<bool>("--aa")
|
|
+ {
|
|
+ Description = "Enable anti-aliasing",
|
|
+ };
|
|
+
|
|
+ var offsetXOption = new Option<decimal>("--offset-x")
|
|
+ {
|
|
+ Description = "X offset in mm",
|
|
+ DefaultValueFactory = _ => 0m,
|
|
+ };
|
|
+
|
|
+ var offsetYOption = new Option<decimal>("--offset-y")
|
|
+ {
|
|
+ Description = "Y offset in mm",
|
|
+ DefaultValueFactory = _ => 0m,
|
|
+ };
|
|
+
|
|
+ var command = new Command("pcb-expose", "Inject a Gerber file into a slicer file for PCB UV exposure")
|
|
+ {
|
|
+ GlobalArguments.InputFileArgument,
|
|
+ gerberArgument,
|
|
+
|
|
+ exposureOption,
|
|
+ invertOption,
|
|
+ mirrorOption,
|
|
+ mergeOption,
|
|
+ invertPolarityOption,
|
|
+ antiAliasingOption,
|
|
+ offsetXOption,
|
|
+ offsetYOption,
|
|
+ GlobalOptions.OutputFile,
|
|
+ };
|
|
+
|
|
+ command.SetAction(result =>
|
|
+ {
|
|
+ var inputFile = result.GetRequiredValue(GlobalArguments.InputFileArgument);
|
|
+ var gerbers = result.GetRequiredValue(gerberArgument);
|
|
+ var exposure = result.GetValue(exposureOption);
|
|
+ var invert = result.GetValue(invertOption);
|
|
+ var mirror = result.GetValue(mirrorOption);
|
|
+ var merge = result.GetValue(mergeOption);
|
|
+ var invertPolarity = result.GetValue(invertPolarityOption);
|
|
+ var aa = result.GetValue(antiAliasingOption);
|
|
+ var offsetX = result.GetValue(offsetXOption);
|
|
+ var offsetY = result.GetValue(offsetYOption);
|
|
+ var outputFile = result.GetValue(GlobalOptions.OutputFile);
|
|
+
|
|
+ if (gerbers.Length == 0)
|
|
+ {
|
|
+ Program.WriteLineError("Specify at least one gerber file.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ foreach (var g in gerbers)
|
|
+ {
|
|
+ if (!g.Exists)
|
|
+ {
|
|
+ Program.WriteLineError($"Gerber file not found: {g.FullName}");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ var slicerFile = Program.OpenInputFile(inputFile);
|
|
+
|
|
+ var op = new OperationPCBExposure(slicerFile)
|
|
+ {
|
|
+ MergeFiles = merge,
|
|
+ Mirror = mirror,
|
|
+ InvertColor = invert,
|
|
+ EnableAntiAliasing = aa,
|
|
+ OffsetX = offsetX,
|
|
+ OffsetY = offsetY,
|
|
+ };
|
|
+
|
|
+ if (exposure > 0)
|
|
+ op.ExposureTime = exposure;
|
|
+
|
|
+ foreach (var g in gerbers)
|
|
+ op.Files.Add(new OperationPCBExposure.PCBExposureFile(g.FullName, invertPolarity));
|
|
+
|
|
+ var spawnError = op.ValidateSpawn();
|
|
+ if (!string.IsNullOrWhiteSpace(spawnError))
|
|
+ {
|
|
+ Program.WriteLineError(spawnError);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ var validationError = op.ValidateInternally();
|
|
+ if (!string.IsNullOrWhiteSpace(validationError))
|
|
+ {
|
|
+ Program.WriteLineError(validationError.TrimEnd());
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Program.ProgressBarWork(
|
|
+ $"PCB exposure: {string.Join(", ", Array.ConvertAll(gerbers, g => g.Name))}",
|
|
+ () => op.Execute(Program.Progress));
|
|
+
|
|
+ Program.SaveFile(slicerFile, outputFile);
|
|
+ });
|
|
+
|
|
+ return command;
|
|
+ }
|
|
+}
|