diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2022-04-06 20:17:48 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2022-04-06 20:17:48 +0300 |
commit | 331d37be7c8e3dfcbf08a4896fff1103b519d977 (patch) | |
tree | 8ad40f70b9e1943ea5c1fbf8a86f28e696e887a5 | |
parent | 7538d49acafb7667efd3f38fd84e7c5f7de8f241 (diff) |
v3.2.2 - Birthday release 🎁 (2 years old) 🥳v3.2.2
- **Settings:**
- (Add) Remove source file after automatic conversion (#444)
- (Add) Remove source file after manual conversion (#444)
- (Add) **Average resin bottle cost:** The average cost per one resin bottle of 1000ml.
Used to calculate the material cost when the file lacks that information.
Use 0 to disable this feature and only show the cost if file have that information.
If this value is changed, you need to reload the current file to update the cost.
- (Change) Move "Expand and show tool descriptions by default" to From `General` to `Tools` tab (Setting will reset to default)
- **File formats:**
- (Add) Property `StartingMaterialMilliliters`: Gets the starting material milliliters when the file was loaded
- (Add) Property `StartingMaterialCost`: Gets the starting material cost when the file was loaded
- (Add) Property `MaterialMilliliterCost`: Gets the material cost per one milliliter
- (Improvement) Update `MaterialCost` when `MaterialMilliliters` changes (#449)
- **Raft relief:**
- (Add) Linked lines: Remove the raft, keep supports and link them with lines
- (Improvement) Change the supports detection parameters to be more effective and precise on detect the starting layer
- (Fix) Brightness percentage not getting updated
- (Fix) Remove anti-aliased edges from Tabs
- (Improvement) Core: Minor clean-up
- (Fix) Issue repair error when 'Auto repair layers and issues on file load' is enabled (#446)
- (Fix) UI: Selecting a object with ROI when flip is verically, will cause 1px up-shift on the preview
- (Fix) macOS permission error due loss of attributes on the build script, WSL have bug with mv, using ln&rm instead
33 files changed, 674 insertions, 212 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 600081d..e9ffca0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## 06/04/2022 - v3.2.2 + +- **Settings:** + - (Add) Remove source file after automatic conversion (#444) + - (Add) Remove source file after manual conversion (#444) + - (Add) **Average resin bottle cost:** The average cost per one resin bottle of 1000ml. + Used to calculate the material cost when the file lacks that information. + Use 0 to disable this feature and only show the cost if file have that information. + If this value is changed, you need to reload the current file to update the cost. + - (Change) Move "Expand and show tool descriptions by default" to From `General` to `Tools` tab (Setting will reset to default) +- **File formats:** + - (Add) Property `StartingMaterialMilliliters`: Gets the starting material milliliters when the file was loaded + - (Add) Property `StartingMaterialCost`: Gets the starting material cost when the file was loaded + - (Add) Property `MaterialMilliliterCost`: Gets the material cost per one milliliter + - (Improvement) Update `MaterialCost` when `MaterialMilliliters` changes (#449) +- **Raft relief:** + - (Add) Linked lines: Remove the raft, keep supports and link them with lines + - (Improvement) Change the supports detection parameters to be more effective and precise on detect the starting layer + - (Fix) Brightness percentage not getting updated + - (Fix) Remove anti-aliased edges from Tabs +- (Improvement) Core: Minor clean-up +- (Fix) Issue repair error when 'Auto repair layers and issues on file load' is enabled (#446) +- (Fix) UI: Selecting a object with ROI when flip is verically, will cause 1px up-shift on the preview +- (Fix) macOS permission error due loss of attributes on the build script, WSL have bug with mv, using ln&rm instead + ## 02/04/2022 - v3.2.1 - **AnyCubic file format:** diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 0000000..1ebb05c --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,23 @@ +- **Settings:** + - (Add) Remove source file after automatic conversion (#444) + - (Add) Remove source file after manual conversion (#444) + - (Add) **Average resin bottle cost:** The average cost per one resin bottle of 1000ml. + Used to calculate the material cost when the file lacks that information. + Use 0 to disable this feature and only show the cost if file have that information. + If this value is changed, you need to reload the current file to update the cost. + - (Change) Move "Expand and show tool descriptions by default" to From `General` to `Tools` tab (Setting will reset to default) +- **File formats:** + - (Add) Property `StartingMaterialMilliliters`: Gets the starting material milliliters when the file was loaded + - (Add) Property `StartingMaterialCost`: Gets the starting material cost when the file was loaded + - (Add) Property `MaterialMilliliterCost`: Gets the material cost per one milliliter + - (Improvement) Update `MaterialCost` when `MaterialMilliliters` changes (#449) +- **Raft relief:** + - (Add) Linked lines: Remove the raft, keep supports and link them with lines + - (Improvement) Change the supports detection parameters to be more effective and precise on detect the starting layer + - (Fix) Brightness percentage not getting updated + - (Fix) Remove anti-aliased edges from Tabs +- (Improvement) Core: Minor clean-up +- (Fix) Issue repair error when 'Auto repair layers and issues on file load' is enabled (#446) +- (Fix) UI: Selecting a object with ROI when flip is verically, will cause 1px up-shift on the preview +- (Fix) macOS permission error due loss of attributes on the build script, WSL have bug with mv, using ln&rm instead + diff --git a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj index 676fb95..a3f8722 100644 --- a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj +++ b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj @@ -2,7 +2,7 @@ <PropertyGroup> <TargetFramework>net6.0</TargetFramework> - <Authors>Tiago Conceição</Authors> + <Authors>Tiago Conceição, sn4k3</Authors> <Company>PTRTECH</Company> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageLicenseFile>LICENSE</PackageLicenseFile> diff --git a/UVtools.Cmd/UVtools.Cmd.csproj b/UVtools.Cmd/UVtools.Cmd.csproj index 9240a90..0f7493f 100644 --- a/UVtools.Cmd/UVtools.Cmd.csproj +++ b/UVtools.Cmd/UVtools.Cmd.csproj @@ -6,7 +6,7 @@ <AssemblyName>UVtoolsCmd</AssemblyName> <ApplicationIcon>UVtools.ico</ApplicationIcon> <Version>1.0.0</Version> - <Authors>Tiago Conceição</Authors> + <Authors>Tiago Conceição, sn4k3</Authors> <Company>PTRTECH</Company> <PackageLicenseFile>LICENSE</PackageLicenseFile> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> diff --git a/UVtools.Core/About.cs b/UVtools.Core/About.cs index db116bf..b41c27b 100644 --- a/UVtools.Core/About.cs +++ b/UVtools.Core/About.cs @@ -7,27 +7,162 @@ */ using System; +using System.IO; +using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using UVtools.Core.Extensions; +using UVtools.Core.FileFormats; namespace UVtools.Core; public static class About { public const string Software = "UVtools"; + public static Version Version => CoreAssembly.GetName().Version!; + public static string VersionStr => Version.ToString(3); + public static string VersionArch => $"{VersionStr} {RuntimeInformation.ProcessArchitecture}"; public static string SoftwareWithVersion => $"{Software} v{VersionStr}"; + public static string SoftwareWithVersionArch => $"{Software} v{VersionArch}"; public const string Author = "Tiago Conceição"; - public const string Company = "PTRTECH"; public const string License = "GNU Affero General Public License v3.0 (AGPL)"; public const string LicenseUrl = "https://github.com/sn4k3/UVtools/blob/master/LICENSE"; public const string Website = "https://github.com/sn4k3/UVtools"; public const string Donate = "https://paypal.me/SkillTournament"; public const string Sponsor = "https://github.com/sponsors/sn4k3"; - public const string DemoFile = "UVtools_demo_file.sl1"; + #region Assembly properties + public static Assembly CoreAssembly => Assembly.GetExecutingAssembly(); - public static Version Version => CoreAssembly.GetName().Version!; - public static string VersionStr => Version.ToString(3); - public static string Arch => Environment.Is64BitOperatingSystem ? "64-bits" : "32-bits"; + public static string AssemblyVersion => CoreAssembly.GetName().Version?.ToString()!; + + public static string AssemblyName => Assembly.GetExecutingAssembly().GetName().Name!; + + public static string AssemblyTitle + { + get + { + var attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); + if (attributes.Length > 0) + { + var titleAttribute = (AssemblyTitleAttribute)attributes[0]; + if (titleAttribute.Title != string.Empty) + { + return titleAttribute.Title; + } + } + return Path.GetFileNameWithoutExtension(CoreAssembly.Location); + } + } + + public static string AssemblyDescription + { + get + { + var attributes = CoreAssembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); + if (attributes.Length == 0) + { + return string.Empty; + } + + var description = ((AssemblyDescriptionAttribute)attributes[0]).Description + $"{Environment.NewLine}{Environment.NewLine}Available File Formats:"; + + return FileFormat.AvailableFormats.SelectMany(fileFormat => fileFormat.FileExtensions).Aggregate(description, (current, fileExtension) => current + $"{Environment.NewLine}- {fileExtension.Description} (.{fileExtension.Extension})"); + } + } + + public static string AssemblyProduct + { + get + { + var attributes = CoreAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyProductAttribute)attributes[0]).Product; + } + } + + public static string AssemblyCopyright + { + get + { + var attributes = CoreAssembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyCopyrightAttribute)attributes[0]).Copyright; + } + } + + public static string AssemblyCompany + { + get + { + var attributes = CoreAssembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyCompanyAttribute)attributes[0]).Company; + } + } + #endregion + + public static string SystemBits => Environment.Is64BitOperatingSystem ? "64-bits" : "32-bits"; + + /// <summary> + /// Gets UVtools born date and time + /// </summary> + public static DateTime Born => new(2020, 4, 6, 20, 33, 14); + + /// <summary> + /// Gets UVtools years + /// </summary> + public static int YearsOld => Born.Age(); + + /// <summary> + /// Return full age in a readable string + /// </summary> + public static string AgeStr + { + get + { + var sb = new StringBuilder($"{YearsOld} years"); + var born = Born; + var now = DateTime.Now; + + var months = 12 + now.Month - born.Month + (now.Day >= born.Day ? 0 : -1); + if (months >= 12) months -= 12; + if (months > 0) sb.Append($", {months} month(s)"); + + + + var days = 31 + now.Day - born.Day; + if (days >= 31) days -= 31; + if (days > 0) sb.Append($", {days} day(s)"); + + var hours = 12 + now.Hour - born.Hour; + if (hours >= 12) hours -= 12; + if (hours > 0) sb.Append($", {hours} hour(s)"); + + var minutes = 60 + now.Minute - born.Minute; + if (minutes >= 60) minutes -= 60; + if (minutes > 0) sb.Append($", {minutes} minutes(s)"); + + var seconds = 60 + now.Second - born.Second; + if (seconds >= 60) seconds -= 60; + if (seconds > 0) sb.Append($", {seconds} seconds(s)"); + + + return sb.ToString(); + } + } + + /// <summary> + /// Checks if today is UVtools birthday + /// </summary> + public static bool IsBirthday + { + get + { + var born = Born; + var now = DateTime.Now; + return born.Month == now.Month && born.Day == now.Day; + } + } + + public const string DemoFile = "UVtools_demo_file.sl1"; - public static Assembly CoreAssembly => Assembly.GetExecutingAssembly(); }
\ No newline at end of file diff --git a/UVtools.Core/CoreSettings.cs b/UVtools.Core/CoreSettings.cs index f048af2..10246be 100644 --- a/UVtools.Core/CoreSettings.cs +++ b/UVtools.Core/CoreSettings.cs @@ -71,7 +71,13 @@ public static class CoreSettings /// <summary> /// Gets or sets the default compression type for layers /// </summary> - public static Layer.LayerCompressionCodec DefaultLayerCompressionCodec { get; set; } = Layer.LayerCompressionCodec.Png; + public static LayerCompressionCodec DefaultLayerCompressionCodec { get; set; } = LayerCompressionCodec.Png; + + /// <summary> + /// <para>The average resin 1000ml bottle cost, to use when bottle cost is not available.</para> + /// <para>Use 0 to disable.</para> + /// </summary> + public static float AverageResin1000MlBottleCost = 60f; /// <summary> /// Gets the default folder to save the settings diff --git a/UVtools.Core/EmguCV/EmguContours.cs b/UVtools.Core/EmguCV/EmguContours.cs index 958cfd8..d8c0639 100644 --- a/UVtools.Core/EmguCV/EmguContours.cs +++ b/UVtools.Core/EmguCV/EmguContours.cs @@ -6,10 +6,13 @@ * of this license document, but changing it is not allowed. */ +using System; +using System.Collections; using Emgu.CV; using Emgu.CV.Util; using System.Collections.Generic; using System.Drawing; +using System.Linq; using System.Threading.Tasks; using UVtools.Core.Extensions; @@ -19,8 +22,71 @@ namespace UVtools.Core.EmguCV; /// Utility methods for contour handling. /// Use only with Tree type /// </summary> -public static class EmguContours +public class EmguContours : IReadOnlyList<EmguContour>, IDisposable { + private readonly EmguContour[] _contours; + + public IEnumerator<EmguContour> GetEnumerator() + { + return ((IEnumerable<EmguContour>)_contours).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _contours.GetEnumerator(); + } + + public int Count => _contours.Length; + + + + public EmguContour this[int index] => _contours[index]; + + public EmguContours(VectorOfVectorOfPoint vectorOfPointsOfPoints) + { + _contours = new EmguContour[vectorOfPointsOfPoints.Size]; + for (int i = 0; i < _contours.Length; i++) + { + _contours[i] = new EmguContour(vectorOfPointsOfPoints[i]); + } + } + + public (int Index, EmguContour Contour, double Distance)[][] CalculateCentroidDistances(bool includeOwn = false, bool sortByDistance = true) + { + var items = new (int Index, EmguContour Contour, double Distance)[Count][]; + for (int i = 0; i < Count; i++) + { + items[i] = new (int Index, EmguContour Contour, double Distance)[Count-1]; + int count = 0; + for (int x = 0; x < Count; x++) + { + if (x == i) + { + if (includeOwn) + { + items[i][count] = new(x, this[x], 0); + } + continue; + } + items[i][count] = new (x, this[x], PointExtensions.FindLength(this[i].Centroid, this[x].Centroid)); + + count++; + } + + if(sortByDistance) items[i] = items[i].OrderBy(tuple => tuple.Distance).ToArray(); + } + + return items; + } + + public void Dispose() + { + foreach (var contour in _contours) + { + contour.Dispose(); + } + } + /// <summary> /// Gets contours inside a point /// </summary> diff --git a/UVtools.Core/Extensions/DateTimeExtensions.cs b/UVtools.Core/Extensions/DateTimeExtensions.cs index ebb132e..9186d5d 100644 --- a/UVtools.Core/Extensions/DateTimeExtensions.cs +++ b/UVtools.Core/Extensions/DateTimeExtensions.cs @@ -47,4 +47,36 @@ public static class DateTimeExtensions { return DateTime.UnixEpoch.AddMinutes(minutes); } + + /// <summary> + /// Calculates the age in years of the current System.DateTime object today. + /// </summary> + /// <param name="birthDate">The date of birth</param> + /// <returns>Age in years today. 0 is returned for a future date of birth.</returns> + public static int Age(this DateTime birthDate) + { + return Age(birthDate, DateTime.Today); + } + + /// <summary> + /// Calculates the age in years of the current System.DateTime object on a later date. + /// </summary> + /// <param name="birthDate">The date of birth</param> + /// <param name="laterDate">The date on which to calculate the age.</param> + /// <returns>Age in years on a later day. 0 is returned as minimum.</returns> + public static int Age(this DateTime birthDate, DateTime laterDate) + { + var age = laterDate.Year - birthDate.Year; + + if (age > 0) + { + age -= Convert.ToInt32(laterDate.Date < birthDate.Date.AddYears(age)); + } + else + { + age = 0; + } + + return age; + } }
\ No newline at end of file diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 12ad9e4..6102aef 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -2725,7 +2725,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor } /// <summary> - /// Gets the starting material milliliters when the file loaded + /// Gets the starting material milliliters when the file was loaded /// </summary> public float StartingMaterialMilliliters { get; private set; } @@ -2749,7 +2749,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor if (StartingMaterialMilliliters > 0 && StartingMaterialCost > 0) { - MaterialCost = _materialMilliliters * StartingMaterialCost / StartingMaterialMilliliters; + MaterialCost = GetMaterialCostPer(_materialMilliliters); } //RaisePropertyChanged(nameof(MaterialCost)); } @@ -2768,7 +2768,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor } /// <summary> - /// Gets the starting material cost when the file loaded + /// Gets the starting material cost when the file was loaded /// </summary> public float StartingMaterialCost { get; private set; } @@ -2782,6 +2782,13 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor } /// <summary> + /// Gets the material cost per one milliliter + /// </summary> + public float MaterialMilliliterCost => StartingMaterialMilliliters > 0 ? StartingMaterialCost / StartingMaterialMilliliters : 0; + + public float GetMaterialCostPer(float milliliters, byte roundDigits = 3) => (float)Math.Round(MaterialMilliliterCost * milliliters, roundDigits); + + /// <summary> /// Gets the material name /// </summary> public virtual string? MaterialName @@ -3313,7 +3320,11 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor IsModified = false; StartingMaterialMilliliters = MaterialMilliliters; StartingMaterialCost = MaterialCost; - + if (StartingMaterialCost <= 0) + { + StartingMaterialCost = StartingMaterialMilliliters * CoreSettings.AverageResin1000MlBottleCost / 1000f; + MaterialCost = StartingMaterialCost; + } progress.ThrowIfCancellationRequested(); @@ -4629,7 +4640,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor /// </summary> /// <param name="newCodec">The new method to change to</param> /// <param name="progress"></param> - public void ChangeLayersCompressionMethod(Layer.LayerCompressionCodec newCodec, OperationProgress? progress = null) + public void ChangeLayersCompressionMethod(LayerCompressionCodec newCodec, OperationProgress? progress = null) { progress ??= new OperationProgress($"Changing layers compression codec to {newCodec}"); progress.Reset("Layers", LayerCount); diff --git a/UVtools.Core/GCode/GCodeBuilder.cs b/UVtools.Core/GCode/GCodeBuilder.cs index 98b224f..1cacb93 100644 --- a/UVtools.Core/GCode/GCodeBuilder.cs +++ b/UVtools.Core/GCode/GCodeBuilder.cs @@ -309,7 +309,7 @@ public class GCodeBuilder : BindableBase public void AppendUVtools() { - AppendComment($"Generated by {About.Software} v{About.VersionStr} {About.Arch} @ {DateTime.UtcNow}"); + AppendComment($"Generated by {About.Software} v{About.VersionStr} {About.SystemBits} @ {DateTime.UtcNow}"); } public void AppendStartGCode() diff --git a/UVtools.Core/Layers/Layer.cs b/UVtools.Core/Layers/Layer.cs index 2015ac7..4db7a9e 100644 --- a/UVtools.Core/Layers/Layer.cs +++ b/UVtools.Core/Layers/Layer.cs @@ -25,29 +25,29 @@ using UVtools.Core.Operations; namespace UVtools.Core.Layers; +#region Enums + +public enum LayerCompressionCodec : byte +{ + [Description("PNG: Compression=High Speed=Slow (Use with low RAM)")] + Png, + [Description("GZip: Compression=Medium Speed=Medium (Optimal)")] + GZip, + [Description("Deflate: Compression=Medium Speed=Medium (Optimal)")] + Deflate, + [Description("LZ4: Compression=Low Speed=Fast (Use with high RAM)")] + Lz4, + //[Description("None: Compression=None Speed=Fastest (Your soul belongs to RAM)")] + //None +} + +#endregion + /// <summary> /// Represent a Layer /// </summary> public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint> { - #region Enums - - public enum LayerCompressionCodec : byte - { - [Description("PNG: Compression=High Speed=Slow (Use with low RAM)")] - Png, - [Description("GZip: Compression=Medium Speed=Medium (Optimal)")] - GZip, - [Description("Deflate: Compression=Medium Speed=Medium (Optimal)")] - Deflate, - [Description("LZ4: Compression=Low Speed=Fast (Use with high RAM)")] - Lz4, - //[Description("None: Compression=None Speed=Fastest (Your soul belongs to RAM)")] - //None - } - - #endregion - #region Constants public const byte HeightPrecision = 3; public const decimal HeightPrecisionIncrement = 0.001M; diff --git a/UVtools.Core/Operations/OperationLayerExportImage.cs b/UVtools.Core/Operations/OperationLayerExportImage.cs index 918c66b..5fbc7ca 100644 --- a/UVtools.Core/Operations/OperationLayerExportImage.cs +++ b/UVtools.Core/Operations/OperationLayerExportImage.cs @@ -216,7 +216,7 @@ public sealed class OperationLayerExportImage : Operation using TextWriter tw = new StreamWriter(fileFullPath); tw.WriteLine("<!--"); - tw.WriteLine($"# Generated by {About.Software} v{About.VersionStr} {About.Arch} @ {DateTime.UtcNow} #"); + tw.WriteLine($"# Generated by {About.Software} v{About.VersionStr} {About.SystemBits} @ {DateTime.UtcNow} #"); tw.WriteLine($"File: {SlicerFile.Filename}"); tw.WriteLine($"{SlicerFile[layerIndex].ToString().Replace(", ", "\n")}"); tw.WriteLine("-->"); diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs index 9725317..3b4ccef 100644 --- a/UVtools.Core/Operations/OperationRaftRelief.cs +++ b/UVtools.Core/Operations/OperationRaftRelief.cs @@ -30,6 +30,9 @@ public class OperationRaftRelief : Operation [Description("Relief: Drill raft to relief pressure and remove some mass")] Relief, + [Description("Linked lines: Remove the raft, keep supports and link them with lines")] + LinkedLines, + [Description("Dimming: Darkens the raft to cure it less")] Dimming, @@ -45,12 +48,15 @@ public class OperationRaftRelief : Operation private RaftReliefTypes _reliefType = RaftReliefTypes.Relief; private uint _maskLayerIndex; private byte _ignoreFirstLayers; - private byte _brightness; + private byte _lowBrightness; private byte _dilateIterations = 15;// +/- 1.5mm radius private byte _wallMargin = 40; // +/- 2mm private byte _holeDiameter = 80; // +/- 4mm private byte _holeSpacing = 40; // +/- 2mm - private byte _tabBrightness = byte.MaxValue; + private byte _linkedLineThickness = 26; + private byte _linkedMinimumLinks = 4; + private bool _linkedExternalSupports = true; + private byte _highBrightness = byte.MaxValue; private ushort _tabTriangleBase = 200; private ushort _tabTriangleHeight = 250; @@ -60,7 +66,7 @@ public class OperationRaftRelief : Operation public override string IconClass => "fas fa-bowling-ball"; public override string Title => "Raft relief"; public override string Description => - "Relief raft by adding holes in between to reduce FEP suction, save resin and easier to remove the prints."; + "Relief raft with a strategy to remove mass, reduce FEP suction, spare resin and easier to remove the prints."; public override string ConfirmationText => $"relief the raft"; @@ -70,8 +76,7 @@ public class OperationRaftRelief : Operation public override string ProgressAction => "Relieved layers"; - public override LayerRangeSelection StartLayerRangeSelection => - LayerRangeSelection.None; + public override LayerRangeSelection StartLayerRangeSelection => LayerRangeSelection.None; public override string? ValidateInternally() { @@ -80,7 +85,11 @@ public class OperationRaftRelief : Operation { if(_tabTriangleHeight == 0) sb.AppendLine("The tab height can't be 0"); if(_tabTriangleBase == 0) sb.AppendLine("The tab base can't be 0"); - if(_tabBrightness == 0) sb.AppendLine("The tab brightness can't be 0"); + if(_highBrightness == 0) sb.AppendLine("The tab brightness can't be 0"); + } + else if (_reliefType == RaftReliefTypes.LinkedLines) + { + if(_linkedLineThickness < 4) sb.AppendLine("The link thickness can't be less than 4"); } return sb.ToString(); @@ -88,7 +97,7 @@ public class OperationRaftRelief : Operation public override string ToString() { - var result = $"[{_reliefType}] [Mask layer: {_maskLayerIndex}] [Ignore: {_ignoreFirstLayers}] [B: {_brightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]"; + var result = $"[{_reliefType}] [Mask layer: {_maskLayerIndex}] [Ignore: {_ignoreFirstLayers}] [B: {_lowBrightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]"; if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}"; return result; } @@ -110,6 +119,7 @@ public class OperationRaftRelief : Operation { if(!RaiseAndSetIfChanged(ref _reliefType, value)) return; RaisePropertyChanged(nameof(IsRelief)); + RaisePropertyChanged(nameof(IsLinkedLines)); RaisePropertyChanged(nameof(IsDimming)); RaisePropertyChanged(nameof(IsDecimate)); RaisePropertyChanged(nameof(IsTabs)); @@ -118,6 +128,7 @@ public class OperationRaftRelief : Operation } public bool IsRelief => _reliefType == RaftReliefTypes.Relief; + public bool IsLinkedLines => _reliefType == RaftReliefTypes.LinkedLines; public bool IsDimming => _reliefType == RaftReliefTypes.Dimming; public bool IsDecimate => _reliefType == RaftReliefTypes.Decimate; public bool IsTabs => _reliefType == RaftReliefTypes.Tabs; @@ -134,17 +145,27 @@ public class OperationRaftRelief : Operation set => RaiseAndSetIfChanged(ref _ignoreFirstLayers, value); } - public byte Brightness + public byte LowBrightness { - get => _brightness; + get => _lowBrightness; set { - if (!RaiseAndSetIfChanged(ref _brightness, value)) return; + if (!RaiseAndSetIfChanged(ref _lowBrightness, value)) return; RaisePropertyChanged(nameof(BrightnessPercent)); } } - public decimal BrightnessPercent => Math.Round((_reliefType == RaftReliefTypes.Tabs ? _tabBrightness : _brightness) * 100 / 255M, 2); + public byte HighBrightness + { + get => _highBrightness; + set + { + if(!RaiseAndSetIfChanged(ref _highBrightness, Math.Max((byte) 1, value))) return; + RaisePropertyChanged(nameof(BrightnessPercent)); + } + } + + public decimal BrightnessPercent => Math.Round((_reliefType is RaftReliefTypes.LinkedLines or RaftReliefTypes.Tabs ? _highBrightness : _lowBrightness) * 100 / 255M, 2); public byte DilateIterations { @@ -170,10 +191,22 @@ public class OperationRaftRelief : Operation set => RaiseAndSetIfChanged(ref _holeSpacing, value); } - public byte TabBrightness + public byte LinkedLineThickness { - get => _tabBrightness; - set => RaiseAndSetIfChanged(ref _tabBrightness, Math.Max((byte)1, value)); + get => _linkedLineThickness; + set => RaiseAndSetIfChanged(ref _linkedLineThickness, Math.Max((byte)4, value)); + } + + public byte LinkedMinimumLinks + { + get => _linkedMinimumLinks; + set => RaiseAndSetIfChanged(ref _linkedMinimumLinks, value); + } + + public bool LinkedExternalSupports + { + get => _linkedExternalSupports; + set => RaiseAndSetIfChanged(ref _linkedExternalSupports, value); } public ushort TabTriangleBase @@ -198,7 +231,7 @@ public class OperationRaftRelief : Operation protected bool Equals(OperationRaftRelief other) { - return _reliefType == other._reliefType && _maskLayerIndex == other._maskLayerIndex && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing && _tabTriangleBase == other._tabTriangleBase && _tabTriangleHeight == other._tabTriangleHeight; + return _reliefType == other._reliefType && _maskLayerIndex == other._maskLayerIndex && _ignoreFirstLayers == other._ignoreFirstLayers && _lowBrightness == other._lowBrightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing && _linkedLineThickness == other._linkedLineThickness && _linkedMinimumLinks == other._linkedMinimumLinks && _linkedExternalSupports == other._linkedExternalSupports && _highBrightness == other._highBrightness && _tabTriangleBase == other._tabTriangleBase && _tabTriangleHeight == other._tabTriangleHeight; } public override bool Equals(object? obj) @@ -215,11 +248,15 @@ public class OperationRaftRelief : Operation hashCode.Add((int) _reliefType); hashCode.Add(_maskLayerIndex); hashCode.Add(_ignoreFirstLayers); - hashCode.Add(_brightness); + hashCode.Add(_lowBrightness); hashCode.Add(_dilateIterations); hashCode.Add(_wallMargin); hashCode.Add(_holeDiameter); hashCode.Add(_holeSpacing); + hashCode.Add(_linkedLineThickness); + hashCode.Add(_linkedMinimumLinks); + hashCode.Add(_linkedExternalSupports); + hashCode.Add(_highBrightness); hashCode.Add(_tabTriangleBase); hashCode.Add(_tabTriangleHeight); return hashCode.ToHashCode(); @@ -248,7 +285,8 @@ public class OperationRaftRelief : Operation { progress.ThrowIfCancellationRequested(); supportsMat = GetRoiOrDefault(SlicerFile[firstSupportLayerIndex].LayerMat); - var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.Gradient, 1, 5, 80, 35, 5, 200); + //var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.Gradient, 1, 5, 80, 35, 5, 255); // OLD + var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.GradientAlt, 1.5, 25, 300, 0.80, 5, 255); if (circles.Length >= minSupportsRequired) break; supportsMat.Dispose(); @@ -263,20 +301,21 @@ public class OperationRaftRelief : Operation if (supportsMat is null || /*firstSupportLayerIndex == 0 ||*/ _ignoreFirstLayers >= firstSupportLayerIndex) return false; Mat? patternMat = null; + using var supportsMatOriginal = supportsMat.Clone(); - if (DilateIterations > 0) + if (_dilateIterations > 0) { CvInvoke.Dilate(supportsMat, supportsMat, CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), new Point(-1, -1)), - new Point(-1, -1), DilateIterations, BorderType.Reflect101, new MCvScalar()); + new Point(-1, -1), _dilateIterations, BorderType.Reflect101, new MCvScalar()); } - var color = new MCvScalar(255 - Brightness); + var color = new MCvScalar(255 - _lowBrightness); switch (ReliefType) { case RaftReliefTypes.Relief: - patternMat = EmguExtensions.InitMat(supportsMat.Size); + patternMat = supportsMat.NewBlank(); int shapeSize = HoleDiameter + HoleSpacing; using (var shape = EmguExtensions.InitMat(new Size(shapeSize, shapeSize))) { @@ -296,6 +335,61 @@ public class OperationRaftRelief : Operation } break; + case RaftReliefTypes.LinkedLines: + { + using var contours = new EmguContours(supportsMatOriginal.FindContours()); + using var supportsRedraw = _linkedExternalSupports ? supportsMatOriginal.Clone() : null; + using var supportsBrightnessCorrection = _highBrightness < byte.MaxValue ? supportsMat.Clone() : null; + + var centroidDistance = contours.CalculateCentroidDistances(false, true); + + var links = Math.Min(_linkedMinimumLinks, contours.Count-1); + var linkColor = new MCvScalar(_highBrightness); + + //var listPoints = new List<Point>(); + + for (int i = 0; i < contours.Count; i++) + { + if(contours[i].Centroid.IsAnyNegative()) continue; + //listPoints.Add(contours[i].Centroid); + + // Link all centroids to each other to calculate the external contour + if (_linkedExternalSupports) + { + for (int x = 0; x < contours.Count; x++) + { + if (x == i) continue; + if (contours[x].Centroid.IsAnyNegative()) continue; + CvInvoke.Line(supportsRedraw, contours[i].Centroid, contours[x].Centroid, linkColor, 4); + } + } + + for (int link = 0; link < links; link++) + { + CvInvoke.Line(supportsMat, contours[i].Centroid, centroidDistance[i][link].Contour.Centroid, linkColor, _linkedLineThickness); + } + } + + + //CvInvoke.Polylines(supportsMat, listPoints.ToArray(), false, linkColor, _linkedLineThickness); + // Link external centroids + if (_linkedExternalSupports) + { + using var externalContours = supportsRedraw!.FindContours(RetrType.External); + CvInvoke.DrawContours(supportsMat, externalContours, -1, linkColor, _linkedLineThickness); + } + + // Fix original supports brightness + if (_highBrightness < byte.MaxValue) + { + supportsBrightnessCorrection!.CopyTo(supportsMat, supportsBrightnessCorrection); + } + + // Close minor holes, round imperfections, stronger joints + CvInvoke.MorphologyEx(supportsMat, supportsMat, MorphOp.Close, EmguExtensions.Kernel3x3Rectangle, new Point(-1, -1), 1, BorderType.Reflect101, default); + + break; + } case RaftReliefTypes.Dimming: patternMat = EmguExtensions.InitMat(supportsMat.Size, color); break; @@ -324,6 +418,7 @@ public class OperationRaftRelief : Operation } break; + case RaftReliefTypes.LinkedLines: case RaftReliefTypes.Decimate: supportsMat.CopyTo(target); break; @@ -348,7 +443,7 @@ public class OperationRaftRelief : Operation new Point(-1, 0), // Left }; - var color = new MCvScalar(_tabBrightness); + var color = new MCvScalar(_highBrightness); for (var i = 0; i < contours.Size; i++) { @@ -419,9 +514,9 @@ public class OperationRaftRelief : Operation break; } - CvInvoke.Ellipse(mat, new Point(x, y), new Size(triangleBaseRadius, (int)(triangleBaseRadius / 1.5)), 90 * dir, 0, 180, EmguExtensions.WhiteColor, -1, LineType.AntiAlias); + CvInvoke.Ellipse(mat, new Point(x, y), new Size(triangleBaseRadius, (int)(triangleBaseRadius / 1.5)), 90 * dir, 0, 180, EmguExtensions.WhiteColor, -1); using var vec = new VectorOfPoint(polygon); - CvInvoke.FillPoly(mat, vec, color, LineType.AntiAlias); + CvInvoke.FillPoly(mat, vec, color); } } diff --git a/UVtools.Core/Operations/OperationRepairLayers.cs b/UVtools.Core/Operations/OperationRepairLayers.cs index f1b5bec..f839390 100644 --- a/UVtools.Core/Operations/OperationRepairLayers.cs +++ b/UVtools.Core/Operations/OperationRepairLayers.cs @@ -159,8 +159,7 @@ public class OperationRepairLayers : Operation set => RaiseAndSetIfChanged(ref _noiseRemovalIterations, value); } - [XmlIgnore] - public IslandDetectionConfiguration? IslandDetectionConfig { get; set; } + [XmlIgnore] public IslandDetectionConfiguration IslandDetectionConfig { get; set; } = new(); #endregion @@ -205,8 +204,8 @@ public class OperationRepairLayers : Operation var issues = SlicerFile.IssueManager.GetVisible().ToList(); // Remove islands if (//Issues is not null - IslandDetectionConfig is not null - && _repairIslands + //IslandDetectionConfig is not null + _repairIslands && _removeIslandsBelowEqualPixelCount > 0 && _removeIslandsRecursiveIterations != 1) { @@ -282,7 +281,7 @@ public class OperationRepairLayers : Operation if (islandsToProcess.Count == 0) { - var islandConfig = IslandDetectionConfig?.Clone() ?? new IslandDetectionConfiguration(); + var islandConfig = IslandDetectionConfig.Clone(); var overhangConfig = new OverhangDetectionConfiguration(false); var touchingBoundsConfig = new TouchingBoundDetectionConfiguration(false); var printHeightConfig = new PrintHeightDetectionConfiguration(false); @@ -292,12 +291,12 @@ public class OperationRepairLayers : Operation islandConfig.Enabled = true; islandsToProcess = SlicerFile.IssueManager.DetectIssues(islandConfig, overhangConfig, resinTrapsConfig, touchingBoundsConfig, printHeightConfig, emptyLayersConfig, progress); - islandsToProcess?.RemoveAll(mainIssue => SlicerFile.IssueManager.IgnoredIssues.Contains(mainIssue)); + islandsToProcess.RemoveAll(mainIssue => SlicerFile.IssueManager.IgnoredIssues.Contains(mainIssue)); } - var issuesGroup = IssueManager.GetIssuesBy(islandsToProcess!, MainIssue.IssueType.Island).GroupBy(issue => issue.LayerIndex); + var issuesGroup = IssueManager.GetIssuesBy(islandsToProcess, MainIssue.IssueType.Island).GroupBy(issue => issue.LayerIndex); - progress.Reset("Attempt to attach islands below", (uint) islandsToProcess!.Count); + progress.Reset("Attempt to attach islands below", (uint) islandsToProcess.Count); var sync = new object(); Parallel.ForEach(issuesGroup, CoreSettings.GetParallelOptions(progress), group => { @@ -310,7 +309,7 @@ public class OperationRepairLayers : Operation for (var layerIndex = startLayer+1; layerIndex >= lowestPossibleLayer; layerIndex--) { - Debug.WriteLine(layerIndex); + //Debug.WriteLine(layerIndex); Monitor.Enter(SlicerFile[layerIndex].Mutex); matCache.Add((uint) layerIndex, SlicerFile[layerIndex].LayerMat); matCacheModified.Add((uint) layerIndex, false); @@ -319,7 +318,7 @@ public class OperationRepairLayers : Operation foreach (IssueOfPoints issue in group) { int foundAt = startLayer == 0 ? 0 : - 1; - var requiredSupportingPixels = Math.Max(1, issue.PixelsCount * IslandDetectionConfig!.RequiredPixelsToSupportMultiplier); + var requiredSupportingPixels = Math.Max(1, issue.PixelsCount * IslandDetectionConfig.RequiredPixelsToSupportMultiplier); for (var layerIndex = startLayer; layerIndex >= lowestPossibleLayer && foundAt < 0; layerIndex--) { diff --git a/UVtools.Core/RELEASE_NOTES.md b/UVtools.Core/RELEASE_NOTES.md deleted file mode 100644 index 5efb19e..0000000 --- a/UVtools.Core/RELEASE_NOTES.md +++ /dev/null @@ -1,12 +0,0 @@ -- **AnyCubic file format:** - - (Fix) Lift height and speed are not being correctly set on old version, keeping a constant value (#441) - - (Fix) Retract speed getter was not return value from TSMC if using version 516 -- **Tool - Infill:** - - (Add) Waves infill type - - (Add) Concentric infill type - - (Add) Gyroid infill type (#443) - - (Change) Increase the default spacing from 200px to 300px - - (Improvement) Fastter infill processing by use the model bounds -- (Add) `FormatSpeedUnit` property to file formats to get the speed unit which the file use internally -- (Fix) UI: ROI rectangle can overlap scroll bars while selecting - diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 5321ef9..69928f1 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -5,12 +5,12 @@ <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageLicenseFile>LICENSE</PackageLicenseFile> <Company>PTRTECH</Company> - <Authors>Tiago Conceição</Authors> + <Authors>Tiago Conceição, sn4k3</Authors> <RepositoryType>Git</RepositoryType> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl> <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description> - <Version>3.2.1</Version> + <Version>3.2.2</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> @@ -50,7 +50,7 @@ </None> <None Include="..\README.md"> <Pack>True</Pack> - <PackagePath>\</PackagePath> + <PackagePath></PackagePath> </None> <None Include="..\UVtools.CAD\UVtools.png"> <Pack>True</Pack> @@ -74,7 +74,7 @@ </ItemGroup> <Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec"> - <ReadLinesFromFile File="RELEASE_NOTES.md"> + <ReadLinesFromFile File="..\RELEASE_NOTES.md"> <Output TaskParameter="Lines" ItemName="ReleaseNoteLines" /> </ReadLinesFromFile> <PropertyGroup> diff --git a/UVtools.InstallerMM/UVtools.InstallerMM.wxs b/UVtools.InstallerMM/UVtools.InstallerMM.wxs index cc40285..fb18481 100644 --- a/UVtools.InstallerMM/UVtools.InstallerMM.wxs +++ b/UVtools.InstallerMM/UVtools.InstallerMM.wxs @@ -2,7 +2,7 @@ <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <?define ComponentRules="OneToOne"?> <!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module --> - <?define SourceDir="..\publish\UVtools_win-x64_v3.2.1"?> + <?define SourceDir="..\publish\UVtools_win-x64_v3.2.2"?> <Module Id="UVtools" Language="1033" Version="1.0.0.0"> <Package Id="12aaa1cf-ff06-4a02-abd5-2ac01ac4f83b" Manufacturer="PTRTECH" InstallerVersion="200" Keywords="MSLA, DLP" Description="MSLA/DLP, file analysis, repair, conversion and manipulation" InstallScope="perMachine" Platform="x64" /> <Directory Id="TARGETDIR" Name="SourceDir"> diff --git a/UVtools.WPF/App.axaml.cs b/UVtools.WPF/App.axaml.cs index 7003486..61f3b8b 100644 --- a/UVtools.WPF/App.axaml.cs +++ b/UVtools.WPF/App.axaml.cs @@ -330,10 +330,10 @@ public class App : Application #endregion - #region Assembly Attribute Accessors + #region Assembly properties + public static Assembly WpfAssembly => Assembly.GetExecutingAssembly(); - public static Version Version => Assembly.GetExecutingAssembly().GetName().Version!; - public static string VersionStr => Version.ToString(3); + public static string AssemblyVersion => WpfAssembly.GetName().Version?.ToString()!; public static string AssemblyName => Assembly.GetExecutingAssembly().GetName().Name!; @@ -341,32 +341,30 @@ public class App : Application { get { - object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); + var attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); if (attributes.Length > 0) { - AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; - if (titleAttribute.Title != "") + var titleAttribute = (AssemblyTitleAttribute)attributes[0]; + if (titleAttribute.Title != string.Empty) { return titleAttribute.Title; } } - return Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location); + return Path.GetFileNameWithoutExtension(WpfAssembly.Location); } } - public static string AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version?.ToString()!; - public static string AssemblyDescription { get { - object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); + var attributes = WpfAssembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); if (attributes.Length == 0) { - return ""; + return string.Empty; } - string description = ((AssemblyDescriptionAttribute)attributes[0]).Description + $"{Environment.NewLine}{Environment.NewLine}Available File Formats:"; + var description = ((AssemblyDescriptionAttribute)attributes[0]).Description + $"{Environment.NewLine}{Environment.NewLine}Available File Formats:"; return FileFormat.AvailableFormats.SelectMany(fileFormat => fileFormat.FileExtensions).Aggregate(description, (current, fileExtension) => current + $"{Environment.NewLine}- {fileExtension.Description} (.{fileExtension.Extension})"); } @@ -376,12 +374,8 @@ public class App : Application { get { - object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); - if (attributes.Length == 0) - { - return ""; - } - return ((AssemblyProductAttribute)attributes[0]).Product; + var attributes = WpfAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyProductAttribute)attributes[0]).Product; } } @@ -389,12 +383,8 @@ public class App : Application { get { - object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); - if (attributes.Length == 0) - { - return ""; - } - return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; + var attributes = WpfAssembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyCopyrightAttribute)attributes[0]).Copyright; } } @@ -402,14 +392,9 @@ public class App : Application { get { - object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); - if (attributes.Length == 0) - { - return ""; - } - return ((AssemblyCompanyAttribute)attributes[0]).Company; + var attributes = WpfAssembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); + return attributes.Length == 0 ? string.Empty : ((AssemblyCompanyAttribute)attributes[0]).Company; } } - #endregion }
\ No newline at end of file diff --git a/UVtools.WPF/Assets/Styles/Styles.xaml b/UVtools.WPF/Assets/Styles/Styles.xaml index bcfcfbd..05e5ccf 100644 --- a/UVtools.WPF/Assets/Styles/Styles.xaml +++ b/UVtools.WPF/Assets/Styles/Styles.xaml @@ -248,6 +248,14 @@ </Setter> </Style> + <Style Selector="TextBox.ValueLabel_euro, NumericUpDown.ValueLabel_euro /template/ TextBox"> + <Setter Property="InnerRightContent"> + <Template> + <TextBox Classes="NumericUpDownValueLabel" Text="€" ToolTip.Tip="Euros" /> + </Template> + </Setter> + </Style> + <!-- <Style Selector="NumericUpDown /template/ TextBox:not(.empty)"> <Setter Property="MinWidth" Value="0"/> diff --git a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml index 71323e1..eb49faa 100644 --- a/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml +++ b/UVtools.WPF/Controls/Tools/ToolRaftReliefControl.axaml @@ -8,13 +8,12 @@ <Grid ColumnDefinitions="Auto,10,200,5,Auto" - RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto" - > + RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"> <TextBlock Text="Relief type:" VerticalAlignment="Center"/> - <ComboBox Grid.Row="0" - Grid.Column="2" - HorizontalAlignment="Stretch" + <ComboBox Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3" + Width="458" + HorizontalAlignment="Left" Items="{Binding Operation.ReliefType, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}" SelectedItem="{Binding Operation.ReliefType, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/> @@ -31,6 +30,7 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_layers" Minimum="0" Maximum="{Binding SlicerFile.LastLayerIndex}" + Increment="1" Value="{Binding Operation.MaskLayerIndex}"/> <StackPanel Grid.Row="2" Grid.Column="4" Orientation="Horizontal" Spacing="5"> @@ -50,6 +50,7 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_layers" Minimum="0" Maximum="255" + Increment="1" Value="{Binding Operation.IgnoreFirstLayers}"/> <TextBlock Grid.Row="4" Grid.Column="4" @@ -65,7 +66,8 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_sun" Minimum="0" Maximum="255" - Value="{Binding Operation.Brightness}"> + Increment="1" + Value="{Binding Operation.LowBrightness}"> <NumericUpDown.IsVisible> <MultiBinding Converter="{x:Static BoolConverters.Or}"> <Binding Path="Operation.IsRelief"/> @@ -78,8 +80,15 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_sun" Minimum="0" Maximum="255" - IsVisible="{Binding Operation.IsTabs}" - Value="{Binding Operation.TabBrightness}"/> + Increment="1" + Value="{Binding Operation.HighBrightness}"> + <NumericUpDown.IsVisible> + <MultiBinding Converter="{x:Static BoolConverters.Or}"> + <Binding Path="Operation.IsLinkedLines"/> + <Binding Path="Operation.IsTabs"/> + </MultiBinding> + </NumericUpDown.IsVisible> + </NumericUpDown> <TextBlock Grid.Row="6" Grid.Column="4" IsVisible="{Binding !Operation.IsDecimate}" @@ -96,10 +105,16 @@ you must manually input the layer index of the last raft where it ends and suppo </TextBlock> <TextBlock Grid.Row="8" Grid.Column="0" - IsVisible="{Binding Operation.IsDecimate}" ToolTip.Tip="Raft will be replaced by the present supports and then dilated by this value to thicken the supports and increase the adhesion. 
Use large numbers with tiny supports for best adhesion." - Text="Dilate supports by:" VerticalAlignment="Center"/> + Text="Dilate supports by:" VerticalAlignment="Center"> + <TextBlock.IsVisible> + <MultiBinding Converter="{x:Static BoolConverters.Or}"> + <Binding Path="Operation.IsLinkedLines"/> + <Binding Path="Operation.IsDecimate"/> + </MultiBinding> + </TextBlock.IsVisible> + </TextBlock> <TextBlock Grid.Row="8" Grid.Column="0" IsVisible="{Binding Operation.IsTabs}" @@ -109,6 +124,7 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_px" Minimum="0" Maximum="255" + Increment="1" IsVisible="{Binding !Operation.IsTabs}" Value="{Binding Operation.DilateIterations}"/> @@ -117,6 +133,7 @@ you must manually input the layer index of the last raft where it ends and suppo Classes="ValueLabel ValueLabel_px" Minimum="5" Maximum="65535" + Increment="1" IsVisible="{Binding Operation.IsTabs}" Value="{Binding Operation.TabTriangleBase}"/> @@ -132,14 +149,20 @@ you must manually input the layer index of the last raft where it ends and suppo </TextBlock> <TextBlock Grid.Row="10" Grid.Column="0" + IsVisible="{Binding Operation.IsLinkedLines}" + ToolTip.Tip="Each support will be linked to the nearby neighbours at least the defined times." + Text="Minimum links:" VerticalAlignment="Center"/> + + <TextBlock Grid.Row="10" Grid.Column="0" IsVisible="{Binding Operation.IsTabs}" Text="Tab triangle height:" VerticalAlignment="Center"/> <NumericUpDown Grid.Row="10" Grid.Column="2" Classes="ValueLabel ValueLabel_px" - Minimum="1" - Maximum="255" - Value="{Binding Operation.WallMargin}"> + Minimum="1" + Maximum="255" + Increment="1" + Value="{Binding Operation.WallMargin}"> <NumericUpDown.IsVisible> <MultiBinding Converter="{x:Static BoolConverters.Or}"> <Binding Path="Operation.IsRelief"/> @@ -149,9 +172,25 @@ you must manually input the layer index of the last raft where it ends and suppo </NumericUpDown> <NumericUpDown Grid.Row="10" Grid.Column="2" + Classes="ValueLabel ValueLabel_times" + Minimum="0" + Maximum="255" + Increment="1" + IsVisible="{Binding Operation.IsLinkedLines}" + Value="{Binding Operation.LinkedMinimumLinks}"/> + + <CheckBox Grid.Row="10" Grid.Column="4" + VerticalAlignment="Center" + Content="Links outer-most supports" + ToolTip.Tip="Links outer-most supports all together, creating a perimeter around inner supports." + IsVisible="{Binding Operation.IsLinkedLines}" + IsChecked="{Binding Operation.LinkedExternalSupports}"/> + + <NumericUpDown Grid.Row="10" Grid.Column="2" Classes="ValueLabel ValueLabel_px" Minimum="5" Maximum="65535" + Increment="1" IsVisible="{Binding Operation.IsTabs}" Value="{Binding Operation.TabTriangleHeight}"/> @@ -161,12 +200,25 @@ you must manually input the layer index of the last raft where it ends and suppo Text="Hole diameter:" VerticalAlignment="Center" IsVisible="{Binding Operation.IsRelief}"/> + <TextBlock Grid.Row="12" Grid.Column="0" + Text="Line thickness:" VerticalAlignment="Center" + IsVisible="{Binding Operation.IsLinkedLines}"/> + <NumericUpDown Grid.Row="12" Grid.Column="2" Classes="ValueLabel ValueLabel_px" - Minimum="10" - Maximum="255" - Value="{Binding Operation.HoleDiameter}" - IsVisible="{Binding Operation.IsRelief}"/> + Minimum="10" + Maximum="255" + Increment="1" + Value="{Binding Operation.HoleDiameter}" + IsVisible="{Binding Operation.IsRelief}"/> + + <NumericUpDown Grid.Row="12" Grid.Column="2" + Classes="ValueLabel ValueLabel_px" + Minimum="4" + Maximum="255" + Increment="1" + IsVisible="{Binding Operation.IsLinkedLines}" + Value="{Binding Operation.LinkedLineThickness}"/> <TextBlock Grid.Row="14" Grid.Column="0" @@ -175,10 +227,11 @@ you must manually input the layer index of the last raft where it ends and suppo <NumericUpDown Grid.Row="14" Grid.Column="2" Classes="ValueLabel ValueLabel_px" - Minimum="10" - Maximum="255" - Value="{Binding Operation.HoleSpacing}" - IsVisible="{Binding Operation.IsRelief}"/> + Minimum="10" + Maximum="255" + Increment="1" + Value="{Binding Operation.HoleSpacing}" + IsVisible="{Binding Operation.IsRelief}"/> </Grid> diff --git a/UVtools.WPF/ErrorLog.cs b/UVtools.WPF/ErrorLog.cs index 17e1a4f..0955aed 100644 --- a/UVtools.WPF/ErrorLog.cs +++ b/UVtools.WPF/ErrorLog.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.IO; +using UVtools.Core; namespace UVtools.WPF; @@ -15,7 +16,7 @@ public static class ErrorLog try { File.AppendAllText(FullPath, - $"[v{App.VersionStr}] ({errorType}) @ {DateTime.Now}: {text}{Environment.NewLine}"); + $"[v{About.VersionStr}] ({errorType}) @ {DateTime.Now}: {text}{Environment.NewLine}"); } catch (Exception exception) { diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs index c554a53..b8bb051 100644 --- a/UVtools.WPF/MainWindow.LayerPreview.cs +++ b/UVtools.WPF/MainWindow.LayerPreview.cs @@ -1540,7 +1540,7 @@ public partial class MainWindow if (_showLayerImageFlippedVertically) { - rectangle.Location = new Point(rectangle.X, LayerCache.Image.Height - 1 - rectangle.Bottom); + rectangle.Location = new Point(rectangle.X, LayerCache.Image.Height - rectangle.Bottom); } } diff --git a/UVtools.WPF/MainWindow.axaml.cs b/UVtools.WPF/MainWindow.axaml.cs index 3a53925..7165d44 100644 --- a/UVtools.WPF/MainWindow.axaml.cs +++ b/UVtools.WPF/MainWindow.axaml.cs @@ -885,6 +885,13 @@ public partial class MainWindow : WindowEx return true; }, TimeSpan.FromSeconds(1)); Program.ProgramStartupTime.Stop(); + + /*if (About.IsBirthday) + { + this.MessageBoxInfo($"Age: {About.AgeStr}\n" + + $"This message will only show today, see you in next year!\n" + + $"Thank you for using {About.Software}.", $"Today it's the {About.Software} birthday!").ConfigureAwait(false); + }*/ } private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -1260,7 +1267,7 @@ public partial class MainWindow : WindowEx { var result = await this.MessageBoxWithHeaderQuestion( - $"Do you like to auto-update {About.Software} v{App.VersionStr} to v{VersionChecker.Version}?", + $"Do you like to auto-update {About.Software} v{About.VersionStr} to v{VersionChecker.Version}?", "Yes: Auto update \n" + "No: Manual update \n" + "Cancel: No action \n\n" + @@ -1322,7 +1329,7 @@ public partial class MainWindow : WindowEx title += $"File: {SlicerFile.Filename} ({Math.Round(LastStopWatch.ElapsedMilliseconds / 1000m, 2)}s) "; } - title += $"Version: {App.VersionStr} RAM: {SizeExtensions.SizeSuffix(Environment.WorkingSet)}"; + title += $"Version: {About.VersionStr} RAM: {SizeExtensions.SizeSuffix(Environment.WorkingSet)}"; if (IsFileLoaded) { @@ -1755,8 +1762,7 @@ public partial class MainWindow : WindowEx if (SlicerFile.IssueManager.Count > 0) { SelectedTabItem = TabIssues; - if (Settings.Issues.AutoRepairIssuesOnLoad) - await RunOperation(ToolRepairLayersControl.GetOperationRepairLayers()); + if (Settings.Issues.AutoRepairIssuesOnLoad) await RunOperation(ToolRepairLayersControl.GetOperationRepairLayers()); } } else diff --git a/UVtools.WPF/Structures/AppVersionChecker.cs b/UVtools.WPF/Structures/AppVersionChecker.cs index b569571..d12d733 100644 --- a/UVtools.WPF/Structures/AppVersionChecker.cs +++ b/UVtools.WPF/Structures/AppVersionChecker.cs @@ -146,11 +146,11 @@ public class AppVersionChecker : BindableBase string tag_name = json["tag_name"]?.ToString(); if (string.IsNullOrEmpty(tag_name)) return false; tag_name = tag_name.Trim(' ', 'v', 'V'); - Debug.WriteLine($"Version checker: v{App.VersionStr} <=> v{tag_name}"); + Debug.WriteLine($"Version checker: v{About.VersionStr} <=> v{tag_name}"); Version checkVersion = new(tag_name); Changelog = json["body"]?.ToString(); //if (string.Compare(tag_name, App.VersionStr, StringComparison.OrdinalIgnoreCase) > 0) - if (App.Version.CompareTo(checkVersion) < 0) + if (About.Version.CompareTo(checkVersion) < 0) { Debug.WriteLine($"New version detected: {DownloadLink}\n" + $"{_changelog}"); @@ -246,7 +246,7 @@ public class AppVersionChecker : BindableBase { stream.NewLine = "\n"; await stream.WriteLineAsync("#!/bin/bash"); - await stream.WriteLineAsync($"echo {About.Software} v{App.Version} updater script"); + await stream.WriteLineAsync($"echo {About.Software} v{About.Version} updater script"); await stream.WriteLineAsync($"cd '{App.ApplicationPath}'"); await stream.WriteLineAsync($"killall {About.Software}"); await stream.WriteLineAsync("sleep 0.5"); diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index b41492a..b688f5d 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -4,7 +4,7 @@ <TargetFramework>net6.0</TargetFramework> <AssemblyName>UVtools</AssemblyName> <ApplicationIcon>UVtools.ico</ApplicationIcon> - <Authors>Tiago Conceição</Authors> + <Authors>Tiago Conceição, sn4k3</Authors> <Company>PTRTECH</Company> <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description> <Copyright>Copyright © 2020 PTRTECH</Copyright> @@ -12,7 +12,7 @@ <PackageLicenseFile>LICENSE</PackageLicenseFile> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <RepositoryType>Git</RepositoryType> - <Version>3.2.1</Version> + <Version>3.2.2</Version> <Platforms>AnyCPU;x64</Platforms> <PackageIcon>UVtools.png</PackageIcon> <PackageReadmeFile>README.md</PackageReadmeFile> @@ -44,9 +44,9 @@ <PackageReference Include="Avalonia.Desktop" Version="0.10.13" /> <PackageReference Include="Avalonia.Diagnostics" Version="0.10.13" /> <PackageReference Include="MessageBox.Avalonia" Version="2.0.0" /> - <PackageReference Include="Projektanker.Icons.Avalonia" Version="4.3.0" /> - <PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="4.3.0" /> - <PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="4.3.0" /> + <PackageReference Include="Projektanker.Icons.Avalonia" Version="4.4.0" /> + <PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="4.4.0" /> + <PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="4.4.0" /> <PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.12" /> </ItemGroup> <ItemGroup> @@ -76,11 +76,11 @@ </None> <None Include="..\README.md" Link="README.md"> <Pack>True</Pack> - <PackagePath>\</PackagePath> + <PackagePath></PackagePath> </None> <None Include="..\UVtools.CAD\UVtools.png"> <Pack>True</Pack> - <PackagePath>\</PackagePath> + <PackagePath></PackagePath> </None> <None Include="..\UVtools.CAD\UVtools_demo_file.sl1" Link="UVtools_demo_file.sl1"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs index 72591dd..898fd6f 100644 --- a/UVtools.WPF/UserSettings.cs +++ b/UVtools.WPF/UserSettings.cs @@ -43,13 +43,12 @@ public sealed class UserSettings : BindableBase private bool _loadDemoFileOnStartup = true; private bool _loadLastRecentFileOnStartup; private int _maxDegreeOfParallelism = -1; - private Layer.LayerCompressionCodec _layerCompressionCodec = CoreSettings.DefaultLayerCompressionCodec; - + private LayerCompressionCodec _layerCompressionCodec = CoreSettings.DefaultLayerCompressionCodec; + private float _averageResin1000MlBottleCost = CoreSettings.AverageResin1000MlBottleCost; private bool _windowsCanResize; private bool _windowsTakeIntoAccountScreenScaling = true; private ushort _windowsHorizontalMargin = 100; private ushort _windowsVerticalMargin = 60; - private bool _expandDescriptions = true; private byte _defaultOpenFileExtensionIndex; private string _defaultDirectoryOpenFile; private string _defaultDirectorySaveFile; @@ -102,12 +101,18 @@ public sealed class UserSettings : BindableBase set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, Math.Min(value, Environment.ProcessorCount)); } - public Layer.LayerCompressionCodec LayerCompressionCodec + public LayerCompressionCodec LayerCompressionCodec { get => _layerCompressionCodec; set => RaiseAndSetIfChanged(ref _layerCompressionCodec, value); } + public float AverageResin1000MlBottleCost + { + get => _averageResin1000MlBottleCost; + set => RaiseAndSetIfChanged(ref _averageResin1000MlBottleCost, value); + } + public bool WindowsCanResize { get => _windowsCanResize; @@ -132,12 +137,6 @@ public sealed class UserSettings : BindableBase set => RaiseAndSetIfChanged(ref _windowsVerticalMargin, value); } - public bool ExpandDescriptions - { - get => _expandDescriptions; - set => RaiseAndSetIfChanged(ref _expandDescriptions, value); - } - public byte DefaultOpenFileExtensionIndex { get => _defaultOpenFileExtensionIndex; @@ -1372,10 +1371,17 @@ public sealed class UserSettings : BindableBase [Serializable] public sealed class ToolsUserSettings : BindableBase { + private bool _expandDescriptions = true; private bool _restoreLastUsedSettings; private bool _lastUsedSettingsKeepOnCloseFile = true; private bool _lastUsedSettingsPriorityOverDefaultProfile = true; + public bool ExpandDescriptions + { + get => _expandDescriptions; + set => RaiseAndSetIfChanged(ref _expandDescriptions, value); + } + public bool RestoreLastUsedSettings { get => _restoreLastUsedSettings; @@ -1571,7 +1577,7 @@ public sealed class UserSettings : BindableBase [NotNull] public string AppVersion { - get => _appVersion ??= App.Version.ToString(); + get => _appVersion ??= About.VersionStr; set => RaiseAndSetIfChanged(ref _appVersion, value); } @@ -1656,6 +1662,7 @@ public sealed class UserSettings : BindableBase CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; CoreSettings.DefaultLayerCompressionCodec = _instance.General.LayerCompressionCodec; + CoreSettings.AverageResin1000MlBottleCost = _instance.General.AverageResin1000MlBottleCost; if (_instance.Network.RemotePrinters.Count == 0) { @@ -1879,6 +1886,7 @@ public sealed class UserSettings : BindableBase _instance.ModifiedDateTime = DateTime.Now; CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; CoreSettings.DefaultLayerCompressionCodec = _instance.General.LayerCompressionCodec; + CoreSettings.AverageResin1000MlBottleCost = _instance.General.AverageResin1000MlBottleCost; try { XmlExtensions.SerializeToFile(_instance, FilePath, XmlExtensions.SettingsIndent); @@ -1891,7 +1899,7 @@ public sealed class UserSettings : BindableBase public static void SetVersion() { - Instance.AppVersion = App.Version.ToString(); + Instance.AppVersion = About.VersionStr; } public static object[] PackObjects => diff --git a/UVtools.WPF/Windows/AboutWindow.axaml b/UVtools.WPF/Windows/AboutWindow.axaml index 0e85338..c39f539 100644 --- a/UVtools.WPF/Windows/AboutWindow.axaml +++ b/UVtools.WPF/Windows/AboutWindow.axaml @@ -3,6 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="clr-namespace:UVtools.WPF.Controls" + xmlns:core="clr-namespace:UVtools.Core;assembly=UVtools.Core" mc:Ignorable="d" d:DesignWidth="960" d:DesignHeight="700" x:Class="UVtools.WPF.Windows.AboutWindow" Width="960" Height="710" @@ -18,7 +19,7 @@ <Grid ColumnDefinitions="Auto,*"> <controls:ButtonWithIcon Grid.Column="0" - Command="{Binding CopyInformationToClipboard}" + Command="{Binding CopyEssentialInformation}" Padding="10" VerticalContentAlignment="Center" HorizontalAlignment="Right" @@ -144,16 +145,17 @@ <Border> <Grid - RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,*" + RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,5,*" Margin="20"> - <TextBlock Grid.Row="0" Text="{Binding Software}" FontWeight="Bold"/> - <TextBlock Grid.Row="2" Text="{Binding Version}"/> - <TextBlock Grid.Row="4" Text="{Binding Copyright}"/> - <TextBlock Grid.Row="6" Text="{Binding Company}"/> + <TextBlock Grid.Row="0" Text="{Binding Source={x:Static core:About.Software}}" FontWeight="Bold"/> + <TextBlock Grid.Row="2" Text="{Binding Source={x:Static core:About.VersionArch}, StringFormat=Version: {0}}"/> + <TextBlock Grid.Row="4" Text="{Binding Source={x:Static core:About.AssemblyCopyright}}"/> + <TextBlock Grid.Row="6" Text="{Binding Source={x:Static core:About.Author}}"/> + <!--<TextBlock Grid.Row="8" Text="{Binding AgeStr, StringFormat=Age: {0}}"/>--> <controls:ButtonWithIcon Grid.Row="8" VerticalAlignment="Center" Command="{Binding OpenLicense}" - Text="{Binding License}" + Text="{Binding Source={x:Static core:About.License}}" Icon="fas fa-balance-scale"/> <TabControl Grid.Row="10"> @@ -162,7 +164,7 @@ IsReadOnly="True" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" - Text="{Binding Description}"/> + Text="{Binding Source={x:Static core:About.AssemblyDescription}}"/> </TabItem> <TabItem Header="OpenCV"> diff --git a/UVtools.WPF/Windows/AboutWindow.axaml.cs b/UVtools.WPF/Windows/AboutWindow.axaml.cs index c0c3919..a4a8966 100644 --- a/UVtools.WPF/Windows/AboutWindow.axaml.cs +++ b/UVtools.WPF/Windows/AboutWindow.axaml.cs @@ -13,14 +13,8 @@ namespace UVtools.WPF.Windows; public class AboutWindow : WindowEx { - public string Software => About.Software; - public string Version => $"Version: {App.VersionStr} {RuntimeInformation.ProcessArchitecture}"; - public string Copyright => App.AssemblyCopyright; - public string Company => App.AssemblyCompany; - public string License => About.License; - public string Description => App.AssemblyDescription; - public string OpenCVBuildInformation => CvInvoke.BuildInformation; - public string LoadedAssemblies + public static string OpenCVBuildInformation => CvInvoke.BuildInformation; + public static string LoadedAssemblies { get { @@ -36,14 +30,14 @@ public class AboutWindow : WindowEx } } - public string OSDescription => $"{RuntimeInformation.OSDescription} {RuntimeInformation.OSArchitecture}"; + public static string OSDescription => $"{RuntimeInformation.OSDescription} {RuntimeInformation.OSArchitecture}"; - public string RuntimeDescription => RuntimeInformation.RuntimeIdentifier; + public static string RuntimeDescription => RuntimeInformation.RuntimeIdentifier; - public string FrameworkDescription => RuntimeInformation.FrameworkDescription; - public string AvaloniaUIDescription => typeof(AvaloniaObject).Assembly.GetName().Version.ToString(3); + public static string FrameworkDescription => RuntimeInformation.FrameworkDescription; + public static string AvaloniaUIDescription => typeof(AvaloniaObject).Assembly.GetName().Version!.ToString(3); - public string OpenCVVersion + public static string OpenCVVersion { get { @@ -56,11 +50,11 @@ public class AboutWindow : WindowEx } } - public string ProcessorName => SystemAware.GetProcessorName(); + public static string ProcessorName => SystemAware.GetProcessorName(); - public int ProcessorCount => Environment.ProcessorCount; + public static int ProcessorCount => Environment.ProcessorCount; - public string MemoryRAMDescription + public static string MemoryRAMDescription { get { @@ -85,7 +79,7 @@ public class AboutWindow : WindowEx get { var result = new StringBuilder(); - for (int i = 0; i < Screens.All.Count; i++) + for (var i = 0; i < Screens.All.Count; i++) { var onScreen = Screens.ScreenFromVisual(App.MainWindow); var screen = Screens.All[i]; @@ -116,7 +110,7 @@ public class AboutWindow : WindowEx private string GetEssentialInformation() { var message = new StringBuilder(); - message.AppendLine($"{About.SoftwareWithVersion}"); + message.AppendLine($"{About.SoftwareWithVersionArch}"); message.AppendLine($"Operative system: {OSDescription}"); message.AppendLine($"Processor: {ProcessorName}"); message.AppendLine($"Processor cores: {ProcessorCount}"); @@ -129,24 +123,25 @@ public class AboutWindow : WindowEx message.AppendLine("Sreens, resolution, working area, usable area:"); message.AppendLine(ScreensDescription); message.AppendLine(); - message.AppendLine($"Path: {App.ApplicationPath}"); + message.AppendLine($"Path: {App.ApplicationPath}"); + message.AppendLine($"Executable: {App.AppExecutable}"); return message.ToString(); } public void CopyEssentialInformation() { - Application.Current.Clipboard.SetTextAsync(GetEssentialInformation()); + Application.Current?.Clipboard?.SetTextAsync(GetEssentialInformation()); } public void CopyOpenCVInformationToClipboard() { - Application.Current.Clipboard.SetTextAsync(CvInvoke.BuildInformation); + Application.Current?.Clipboard?.SetTextAsync(CvInvoke.BuildInformation); } public void CopyLoadedAssembliesToClipboard() { - Application.Current.Clipboard.SetTextAsync(LoadedAssemblies); + Application.Current?.Clipboard?.SetTextAsync(LoadedAssemblies); } public async void CopyInformationToClipboard() @@ -156,6 +151,6 @@ public class AboutWindow : WindowEx message.AppendLine(CvInvoke.BuildInformation); message.AppendLine("Loaded Assemblies:"); message.AppendLine(LoadedAssemblies); - await Application.Current.Clipboard.SetTextAsync(message.ToString()); + await Application.Current?.Clipboard?.SetTextAsync(message.ToString())!; } }
\ No newline at end of file diff --git a/UVtools.WPF/Windows/BenchmarkWindow.axaml.cs b/UVtools.WPF/Windows/BenchmarkWindow.axaml.cs index 46ead58..b7686e6 100644 --- a/UVtools.WPF/Windows/BenchmarkWindow.axaml.cs +++ b/UVtools.WPF/Windows/BenchmarkWindow.axaml.cs @@ -526,7 +526,7 @@ public class BenchmarkWindow : WindowEx public void TestPNGCompress(BenchmarkResolution resolution) { - Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Png); + Layer.CompressMat(Mats[resolution], LayerCompressionCodec.Png); } public void TestPNGDecompress(BenchmarkResolution resolution) @@ -534,7 +534,7 @@ public class BenchmarkWindow : WindowEx public void TestGZipCompress(BenchmarkResolution resolution) { - Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.GZip); + Layer.CompressMat(Mats[resolution], LayerCompressionCodec.GZip); } public void TestGZipDecompress(BenchmarkResolution resolution) @@ -542,7 +542,7 @@ public class BenchmarkWindow : WindowEx public void TestDeflateCompress(BenchmarkResolution resolution) { - Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Deflate); + Layer.CompressMat(Mats[resolution], LayerCompressionCodec.Deflate); } public void TestDeflateDecompress(BenchmarkResolution resolution) @@ -550,7 +550,7 @@ public class BenchmarkWindow : WindowEx public void TestLZ4Compress(BenchmarkResolution resolution) { - Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Lz4); + Layer.CompressMat(Mats[resolution], LayerCompressionCodec.Lz4); } public void TestLZ4Decompress(BenchmarkResolution resolution) diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml index 9740d8b..e5b44ab 100644 --- a/UVtools.WPF/Windows/SettingsWindow.axaml +++ b/UVtools.WPF/Windows/SettingsWindow.axaml @@ -50,8 +50,8 @@ <StackPanel Orientation="Vertical"> <TextBlock Classes="GroupBoxHeader" Text="Tasks"/> <StackPanel Margin="10" Orientation="Vertical" Spacing="10"> - <Grid RowDefinitions="Auto,10,Auto" - ColumnDefinitions="Auto,10,150,5,Auto,20,Auto,2,Auto,2,Auto,2,Auto,2,Auto,2,Auto,2,Auto"> + <Grid RowDefinitions="Auto,10,Auto,10,Auto" + ColumnDefinitions="Auto,10,180,5,Auto,20,Auto,2,Auto,2,Auto,2,Auto,2,Auto,2,Auto,2,Auto"> <TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" @@ -135,6 +135,29 @@ HorizontalAlignment="Stretch" Items="{Binding Settings.General.LayerCompressionCodec, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}" SelectedItem="{Binding Settings.General.LayerCompressionCodec, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/> + + <TextBlock Grid.Row="4" Grid.Column="0" + VerticalAlignment="Center" + ToolTip.Tip="The average cost per one resin bottle of 1000ml. +
Used to calculate the material cost when the file lacks that information. +
Use 0 to disable this feature and only show the cost if file have that information. +
If this value is changed, you need to reload the current file to update the cost." + Text="Average resin bottle cost:"/> + + <NumericUpDown Grid.Row="4" Grid.Column="2" + Classes="ValueLabel ValueLabel_euro" + VerticalAlignment="Center" + ToolTip.Tip="The average cost per one resin bottle of 1000ml. +
Used to calculate the material cost when the file lacks that information. +
Use 0 to disable this feature and only show the cost if file have that information. +
If this value is changed, you need to reload the current file to update the cost." + Minimum="0" + Maximum="10000" + Increment="1" + Value="{Binding Settings.General.AverageResin1000MlBottleCost}"/> + <TextBlock Grid.Row="4" Grid.Column="4" Grid.ColumnSpan="15" + VerticalAlignment="Center" + Text="/ 1000ml bottle"/> </Grid> </StackPanel> @@ -188,10 +211,6 @@ Increment="1" Value="{Binding Settings.General.WindowsVerticalMargin}"/> </Grid> - - <CheckBox IsChecked="{Binding Settings.General.ExpandDescriptions}" - ToolTip.Tip="Disable this if you want to gain some vertical space for windows, you can still toggle the descriptions and read them if required." - Content="Expand and show tool descriptions by default"/> </StackPanel> </StackPanel> @@ -1848,8 +1867,12 @@ <StackPanel Orientation="Vertical"> <TextBlock Classes="GroupBoxHeader" Text="Common"/> <StackPanel Margin="10" Orientation="Vertical" Spacing="10"> - <CheckBox IsChecked="{Binding Settings.Tools.RestoreLastUsedSettings}" - Content="Keep and restore the last used settings on operations per user session/instance"/> + <CheckBox IsChecked="{Binding Settings.Tools.ExpandDescriptions}" + ToolTip.Tip="Disable this if you want to gain some vertical space for windows, you can still toggle the descriptions and read them if required." + Content="Expand and show descriptions by default"/> + + <CheckBox IsChecked="{Binding Settings.Tools.RestoreLastUsedSettings}" + Content="Keep and restore the last used settings on operations per user session/instance"/> <ToggleSwitch IsChecked="{Binding Settings.Tools.LastUsedSettingsKeepOnCloseFile}" OffContent="Discard the session when closing or loading files" diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml.cs b/UVtools.WPF/Windows/SettingsWindow.axaml.cs index ca2f68b..bd6d512 100644 --- a/UVtools.WPF/Windows/SettingsWindow.axaml.cs +++ b/UVtools.WPF/Windows/SettingsWindow.axaml.cs @@ -8,6 +8,7 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.Threading; using MessageBox.Avalonia.Enums; +using UVtools.Core; using UVtools.Core.FileFormats; using UVtools.Core.Network; using UVtools.Core.Objects; @@ -63,7 +64,7 @@ public class SettingsWindow : WindowEx public SettingsWindow() { - Title += $" [v{App.VersionStr}]"; + Title += $" [v{About.VersionStr}]"; SettingsBackup = UserSettings.Instance.Clone(); var fileFormats = new List<string> diff --git a/UVtools.WPF/Windows/ToolWindow.axaml b/UVtools.WPF/Windows/ToolWindow.axaml index 3ad837b..4f9a59f 100644 --- a/UVtools.WPF/Windows/ToolWindow.axaml +++ b/UVtools.WPF/Windows/ToolWindow.axaml @@ -20,7 +20,7 @@ Padding="10" IsVisible="{Binding Description, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> <Expander - IsExpanded="{Binding Settings.General.ExpandDescriptions}" + IsExpanded="{Binding Settings.Tools.ExpandDescriptions}" Header="Description (Click to toggle)"> <TextBox Classes="TransparentReadOnly" HorizontalAlignment="Left" diff --git a/build/createRelease.ps1 b/build/createRelease.ps1 index 1726b7f..3b5a59f 100644 --- a/build/createRelease.ps1 +++ b/build/createRelease.ps1 @@ -298,7 +298,7 @@ foreach($line in $changelog) { } } Write-Host $sb.ToString() -Set-Content -Path "UVtools.Core/RELEASE_NOTES.md" -Value $sb.ToString() +Set-Content -Path "$rootFolder/RELEASE_NOTES.md" -Value $sb.ToString() if($null -ne $enableNugetPublish -and $enableNugetPublish) |