Skip to content

Commit

Permalink
v3.4.0
Browse files Browse the repository at this point in the history
- **Tools:**
   - (Add) PCB exposure: Converts a gerber file to a pixel perfect image given your printer LCD/resolution to exposure the copper traces.
   - (Improvement) Export settings now indent the XML to be more user friendly to edit
   - (Improvement) Layer import: Allow to have profiles
   - (Improvement) Layer import: Validates if selected files exists before execute
   - (Fix) Lithophane: Disallow having start threshold equal to end threshold
- (Add) Windows explorer: Right-click on files will show "Open with UVtools" on context menu which opens the selected file on UVtools (Windows MSI only)
- (Improvement) Island and overhang detection: Ignore detection on all layers that are in direct contact with the plate (On same first layer position)
- (Improvement) Cmd: Better error messages for convert command when using shared extensions and no extension
  • Loading branch information
sn4k3 committed May 2, 2022
1 parent 2625c13 commit 3130ebe
Show file tree
Hide file tree
Showing 45 changed files with 2,750 additions and 301 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 02/05/2022 - v3.4.0

- **Tools:**
- (Add) PCB exposure: Converts a gerber file to a pixel perfect image given your printer LCD/resolution to exposure the copper traces.
- (Improvement) Export settings now indent the XML to be more user friendly to edit
- (Improvement) Layer import: Allow to have profiles
- (Improvement) Layer import: Validates if selected files exists before execute
- (Fix) Lithophane: Disallow having start threshold equal to end threshold
- (Add) Windows explorer: Right-click on files will show "Open with UVtools" on context menu which opens the selected file on UVtools (Windows MSI only)
- (Improvement) Island and overhang detection: Ignore detection on all layers that are in direct contact with the plate (On same first layer position)
- (Improvement) Cmd: Better error messages for convert command when using shared extensions and no extension

## 14/04/2022 - v3.3.2

- **UI:**
Expand Down
19 changes: 9 additions & 10 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
- **UI:**
- (Add) Setting: Restore window last position - If enabled, it will restore the main window last known client position on startup (#460)
- (Add) Setting: Restore window last size - If enabled, it will restore the main window last known client size on startup (#460)
- (Improvement) If there are missing dependencies it will show a proper window with information instead of crashing application without any visuals
- (Improvement) Start maximized is set before windows spawn to prevent the flicker effect on main window
- (Add) File formats: Property `IsUsingTSMC` - Indicates whatever file globals are using TSMC or not
- (Change) Lithophane: Noise removal and gap closing iterations defaults to 0
- (Fix) Anycubic files: Printers are unable to use TSMC values after save (#457)
- (Fix) Pixel Editor button is hidden when using screens with scalling > 100% [dirty-fix] (#458)
- (Upgrade) .NET from 6.0.3 to 6.0.4
- **Tools:**
- (Add) PCB exposure: Converts a gerber file to a pixel perfect image given your printer LCD/resolution to exposure the copper traces.
- (Improvement) Export settings now indent the XML to be more user friendly to edit
- (Improvement) Layer import: Allow to have profiles
- (Improvement) Layer import: Validates if selected files exists before execute
- (Fix) Lithophane: Disallow having start threshold equal to end threshold
- (Add) Windows explorer: Right-click on files will show "Open with UVtools" on context menu which opens the selected file on UVtools (Windows MSI only)
- (Improvement) Island and overhang detection: Ignore detection on all layers that are in direct contact with the plate (On same first layer position)
- (Improvement) Cmd: Better error messages for convert command when using shared extensions and no extension

103 changes: 103 additions & 0 deletions Scripts/010 Editor/osf.bt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//------------------------------------------------
//--- 010 Editor v8.0.1 Binary Template
//
// File: osf (vlare)
// Authors: Tiago Conceição
//------------------------------------------------

BigEndian();

struct PREVIEW {
BitfieldDisablePadding();
uint PreviewLength:24 <fgcolor=cBlack, bgcolor=cRed>;
ubyte PreviewData[PreviewLength] <fgcolor=cBlack, bgcolor=cGreen>;
};

struct HEADER {
uint HeaderLength <fgcolor=cBlack, bgcolor=cRed>;
ushort Version <fgcolor=cBlack, bgcolor=cRed>; // 1
ubyte ImageLog <fgcolor=cBlack, bgcolor=cRed>; // log 2


PREVIEW preview;
PREVIEW preview;
PREVIEW preview;
PREVIEW preview;

ushort ResolutionX <fgcolor=cBlack, bgcolor=cRed>;
ushort ResolutionY <fgcolor=cBlack, bgcolor=cRed>;
ushort PixelUmMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (um, magnification 100 times: such as 100um write 10000, the same below)
ubyte Mirror <fgcolor=cBlack, bgcolor=cRed>; // (0x00 not mirrored, 0x01 X-axis mirroring, 0x02 Y-axis mirroring, 0x03 XY-axis mirroring)
ubyte BottomLightPWM <fgcolor=cBlack, bgcolor=cRed>;
ubyte LightPWM <fgcolor=cBlack, bgcolor=cRed>;
ubyte AntiAliasEnabled <fgcolor=cBlack, bgcolor=cRed>;
ubyte DistortionEnabled <fgcolor=cBlack, bgcolor=cRed>;
ubyte DelayedExposureActivationEnabled <fgcolor=cBlack, bgcolor=cRed>;
uint LayerCount <fgcolor=cBlack, bgcolor=cYellow>;
ushort NumberParameterSets <fgcolor=cBlack, bgcolor=cRed>; // 1
uint LastLayerIndex <fgcolor=cBlack, bgcolor=cYellow>;
uint LayerHeightUmMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (um magnification 100 times)
ubyte BottomLayersCount <fgcolor=cBlack, bgcolor=cRed>;

uint ExposureTimeMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint BottomExposureTimeMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint SupportDelayTimeMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint BottomSupportDelayTimeMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
ubyte TransitionLayers <fgcolor=cBlack, bgcolor=cRed>;
ubyte TransitionType <fgcolor=cBlack, bgcolor=cRed>; // (0x00 linear transition)
uint TransitionLayerIntervalTimeDifferenceMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint WaitTimeAfterCureMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint WaitTimeAfterLiftMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100
uint WaitTimeBeforeCureMagnified100Times:24 <fgcolor=cBlack, bgcolor=cRed>; // s * 100

uint BottomLiftHeightSlowMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint BottomLiftHeightTotalMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint LiftHeightSlowMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint LiftHeightTotalMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint BottomRetractHeightTotalMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint RetractHeightSlowMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)
uint RetractHeightTotalMagnified1000Times:24 <fgcolor=cBlack, bgcolor=cRed>; // (magnification 1000 times)

ubyte AccelerationType <fgcolor=cBlack, bgcolor=cRed>; // (0x00: S-shaped acceleration, 0x01: T-shaped acceleration, Default Value: S-shaped acceleration, currently only supports S-shaped acceleration)

ushort BottomLiftSpeedStartMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort BottomLiftSpeedSlowMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort BottomLiftSpeedFastMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ubyte BottomLiftAccelerationChange <fgcolor=cBlack, bgcolor=cRed>; // 5

ushort LiftSpeedStartMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort LiftSpeedSlowMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort LiftSpeedFastMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ubyte LiftAccelerationChange <fgcolor=cBlack, bgcolor=cRed>; // 5

ushort BottomRetractSpeedStartMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort BottomRetractSpeedSlowMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort BottomRetractFastMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ubyte BottomRetractAccelerationChange <fgcolor=cBlack, bgcolor=cRed>; // 5

ushort RetractSpeedStartMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort RetractSpeedSlowMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ushort RetractFastMagnified100Times <fgcolor=cBlack, bgcolor=cRed>; // (magnification 100 times)
ubyte RetractAccelerationChange <fgcolor=cBlack, bgcolor=cRed>; // 5

ubyte Reserved[23] <fgcolor=cWhite, bgcolor=cBlack>;

ubyte ProtocolType <fgcolor=cBlack, bgcolor=cRed>; // 0
} header;


struct LAYER_DEF {
ushort Mark <fgcolor=cBlack, bgcolor=cRed>; // (OD OA begins, indicating that the model + support is included; the beginning of 0D 0B, indicating that the layer only has support data)
uint NumberOfPixels <fgcolor=cBlack, bgcolor=cRed>;
ushort StartY <fgcolor=cBlack, bgcolor=cRed>;
};


struct LAYERS {

local int i = 0;
for( i = 0; i < header.LayerCount; i++ ){
LAYER_DEF layerDef <fgcolor=cBlack, bgcolor=cYellow>;
}

} layers;
8 changes: 4 additions & 4 deletions UVtools.Cmd/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ internal static void WriteWarning(object? obj)
{
if (Quiet) return;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(obj);
Console.Write(obj);
Console.ResetColor();
}

Expand All @@ -190,12 +190,12 @@ internal static void WriteError(object? obj, bool exit = false)
return;
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(obj);
Console.Write(obj);
Console.ResetColor();
if (exit) Environment.Exit(-1);
}

internal static void WriteLineError(object? obj, bool exit = true)
internal static void WriteLineError(object? obj, bool exit = true, bool prependError = true)
{
if (Quiet)
{
Expand All @@ -204,7 +204,7 @@ internal static void WriteLineError(object? obj, bool exit = true)
}

var str = obj?.ToString();
if(str is not null && !str.StartsWith("Error:")) str = $"Error: {str}";
if(str is not null && prependError && !str.StartsWith("Error:")) str = $"Error: {str}";

Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(str);
Expand Down
80 changes: 70 additions & 10 deletions UVtools.Cmd/Symbols/ConvertCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System;
using System.CommandLine;
using System.IO;
using System.Linq;
using UVtools.Core.Extensions;
using UVtools.Core.FileFormats;

namespace UVtools.Cmd.Symbols;
Expand All @@ -28,22 +30,40 @@ internal static Command CreateCommand()

command.SetHandler((FileInfo inputFile, string targetTypeExt, FileInfo? outputFile, ushort version, bool noOverwrite) =>
{
var targetType = FileFormat.FindByType(targetTypeExt);
if (targetType is null)
{
targetType = FileFormat.FindByExtensionOrFilePath(targetTypeExt, out var fileFormatsSharingExt);
if (targetType is not null && fileFormatsSharingExt > 1)
{
Program.WriteLineError($"The extension '{targetTypeExt}' is shared by multiple encoders, use the strict encoder name instead.", false);
Program.WriteLineError($"Available {FileFormat.AvailableFormats.Length} encoders:", false, false);
foreach (var fileFormat in FileFormat.AvailableFormats)
{
Program.WriteLineError($"{fileFormat.GetType().Name.RemoveFromEnd("File".Length)} ({string.Join(", ", fileFormat.FileExtensions.Select(extension => extension.Extension))})", false, false);
}
Environment.Exit(-1);
return;
}
}
var targetType = FileFormat.FindByAnyMeans(targetTypeExt);
if (targetType is null)
{
Program.WriteLineError($"Unable to find a valid convert type candidate from {targetTypeExt}.");
Program.WriteLineError($"Unable to find a valid encoder from {targetTypeExt}.", false);
Program.WriteLineError($"Available {FileFormat.AvailableFormats.Length} encoders:", false, false);
foreach (var fileFormat in FileFormat.AvailableFormats)
{
Program.WriteLineError($"{fileFormat.GetType().Name.RemoveFromEnd("File".Length)} ({string.Join(", ", fileFormat.FileExtensions.Select(extension => extension.Extension))})", false, false);
}
Environment.Exit(-1);
return;
}
string? outputFilePath;
if (outputFile is not null)
string inputFileName = FileFormat.GetFileNameStripExtensions(inputFile.Name)!;
if (outputFile is null)
{
outputFilePath = outputFile.FullName;
}
else
{
outputFilePath = FileFormat.GetFileNameStripExtensions(inputFile.Name)!;
outputFilePath = inputFileName;
if (targetType.FileExtensions.Length == 1)
{
outputFilePath = Path.Combine(inputFile.DirectoryName!, $"{outputFilePath}.{targetType.FileExtensions[0].Extension}");
Expand All @@ -53,22 +73,62 @@ internal static Command CreateCommand()
var ext = FileExtension.Find(targetTypeExt);
if (ext is null)
{
Program.WriteLineError($"Unable to construct the output filename from {targetTypeExt}, there are {targetType.FileExtensions.Length} extensions on this format, please specify an output file.");
Program.WriteLineError($"Unable to construct the output filename and guess the extension from the {targetTypeExt} encoder.", false);
Program.WriteLineError($"There are {targetType.FileExtensions.Length} possible extensions on this format ({string.Join(", ", targetType.FileExtensions.Select(extension => extension.Extension))}), please specify an output file.", false, false);
return;
}
outputFilePath = Path.Combine(inputFile.DirectoryName!, $"{outputFilePath}.{ext.Extension}");
}
}
else
{
outputFilePath = string.Format(outputFile.FullName, inputFileName);
}
var outputFileName = Path.GetFileName(outputFilePath);
var outputFileDirectory = Path.GetDirectoryName(outputFilePath)!;
if (outputFileName == string.Empty)
{
Program.WriteLineError("No output file was specified.");
return;
}
if (!outputFileName.Contains('.'))
{
if (targetType.IsExtensionValid(outputFileName))
{
outputFileName = $"{inputFileName}.{outputFileName}";
outputFilePath = Path.Combine(outputFileDirectory, outputFileName);
}
else if (targetType.FileExtensions.Length == 1)
{
outputFileName = $"{outputFileName}.{targetType.FileExtensions[0].Extension}";
outputFilePath = Path.Combine(outputFileDirectory, outputFileName);
}
}
if (!targetType.IsExtensionValid(outputFileName, true))
{
Program.WriteLineError($"The extension on '{outputFileName}' file is not valid for the {targetType.GetType().Name} encoder.", false);
Program.WriteLineError($"Available {targetType.FileExtensions.Length} extension(s):", false, false);
foreach (var fileExtension in targetType.FileExtensions)
{
Program.WriteLineError(fileExtension.Extension, false, false);
}
Environment.Exit(-1);
return;
}
if (noOverwrite && File.Exists(outputFilePath))
{
Program.WriteLineError($"{outputFileName} already exits! --no-overwrite is enabled.");
return;
}
var slicerFile = Program.OpenInputFile(inputFile);
Program.ProgressBarWork($"Converting to {outputFileName}",
Expand Down
2 changes: 1 addition & 1 deletion UVtools.Cmd/UVtools.Cmd.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>UVtoolsCmd</AssemblyName>
<ApplicationIcon>UVtools.ico</ApplicationIcon>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<Authors>Tiago Conceição, sn4k3</Authors>
<Company>PTRTECH</Company>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
Expand Down
26 changes: 23 additions & 3 deletions UVtools.Core/Extensions/EmguExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ public static int GetPixelPos(this Mat mat, Point point)
public static byte[] GetBytes(this Mat mat)
{
var data = new byte[mat.GetLength()];
Marshal.Copy(mat.DataPointer, data, 0, data.Length);
//Marshal.Copy(mat.DataPointer, data, 0, data.Length);
mat.CopyTo(data);
return data;
}

Expand Down Expand Up @@ -428,8 +429,10 @@ public static void SetByte(this Mat mat, int x, int y, byte[] value) =>
/// </summary>
/// <param name="mat"></param>
/// <param name="value"></param>
public static void SetBytes(this Mat mat, byte[] value) =>
Marshal.Copy(value, 0, mat.DataPointer, value.Length);
public static void SetBytes(this Mat mat, byte[] value)
{
mat.SetTo(value);
}

/// <summary>
/// Gets PNG byte array
Expand Down Expand Up @@ -477,6 +480,23 @@ public static Mat CropByBounds(this Mat src, bool cloneInsteadRoi = false)
return roi;
}

public static Mat CropByBounds(this Mat src, ushort margin) => src.CropByBounds(new Size(margin, margin));

public static Mat CropByBounds(this Mat src, Size margin)
{
var rect = CvInvoke.BoundingRectangle(src);
if (rect.Size == Size.Empty) return src.New();
using var roi = src.Size == rect.Size ? src.Roi(src.Size) : src.Roi(rect);

var numberOfChannels = roi.NumberOfChannels;
var cropped = new Mat(roi.Rows + margin.Height * 2, roi.Cols + margin.Width * 2, roi.Depth, numberOfChannels);

using var dest = new Mat(cropped, new Rectangle(margin.Width, margin.Height, roi.Width, roi.Height));
roi.CopyTo(dest);

return cropped;
}

public static void CropByBounds(this Mat src, Mat dst)
{
using var mat = src.CropByBounds();
Expand Down
10 changes: 2 additions & 8 deletions UVtools.Core/FileFormats/CXDLPFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -659,16 +659,10 @@ protected override void EncodeInternally(OperationProgress progress)
{
using var outputFile = new FileStream(TemporaryOutputFileFullPath, FileMode.Create, FileAccess.ReadWrite);

if (string.IsNullOrWhiteSpace(MachineName))
{
throw new InvalidDataException("Unable to detect the printer model from resolution, check if resolution is well defined on slicer for your printer model.");
}


if (!MachineName.StartsWith("CL-") && !MachineName.StartsWith("CT"))
if (string.IsNullOrWhiteSpace(MachineName) || (!MachineName.StartsWith("CL-") && !MachineName.StartsWith("CT")))
{
bool found = false;
foreach (var machine in Printer.Machine.Machines
foreach (var machine in Machine.Machines
.Where(machine => machine.Brand == PrinterBrand.Creality
&& (machine.Model.StartsWith("CL-") || machine.Model.StartsWith("CT"))
))
Expand Down
10 changes: 9 additions & 1 deletion UVtools.Core/FileFormats/FileExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace UVtools.Core.FileFormats;

Expand Down Expand Up @@ -136,6 +137,13 @@ FileFormatType is null
return FileFormat.FindExtension(extension);
}


public static IEnumerable<FileExtension> FindAll(string extension)
{
if (string.IsNullOrWhiteSpace(extension)) return Enumerable.Empty<FileExtension>();
if (extension.StartsWith('.')) extension = extension.Remove(1);
return FileFormat.FindExtensions(extension);
}


#endregion
}
Loading

0 comments on commit 3130ebe

Please sign in to comment.