Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2022-10-30 02:52:49 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2022-10-30 02:52:49 +0300
commit6dc26f74342411760a5905860ef863ece03a3239 (patch)
tree5e706336595126cccc175c7af4c182df9ce4f6a0 /UVtools.Core
parent38201dfb83e46ee269cd940c5684dd4e97bc61fe (diff)
v3.8.0v3.8.0
- **File formats:** - (Add) Property: DisplayTotalOnTime - (Add) Property: DisplayTotalOffTime - (Add) SL1File Property: high_viscosity_tilt_time - **Tools** - **I printed this file** - (Add) Display on time for the print information - (Improvement) Labels on numeric box - (Improvement) Show print time label formatted as hh:mm:ss - **PCB Exposure:** - (Improvement) Increase "Exposure time" maximum from 200s to 1000s (#592) - (Fix) Set `BottomLightHeight` to 0 - (Fix) Set `TransitionLayerCount` to 0 - **Issues:** - (Improvement) Overhang detection by using a dynamic cross kernel - (Improvement) Bring back the discard logic of "false-positive" islands based on overhang detection but improve the threshold of the detection to be safer (#591, #591) - **PrusaSlicer:** - (Change) Elegoo Mars 2 to use file version 4 - (Change) Elegoo Mars 2 Pro to use file version 4 - (Add) Status bar: On and Off time (hh:mm:ss) as tooltip in the Print time label - (Improvement) When any of libcvextern dependencies are missing, it try to show the missing libraries in the error message (Linux only) - (Improvement) Auto-upgrade procedure for non-Windows systems - (Improvement) macOS arm64 (M1/M2) can now run natively if installed via the auto installer script - (Fix) Error on Mat cache manager when file have only one layer - (Fix) Suggestion "Transition layer count" shows as never applied when using with file formats that use in-firmware transition layers - (Upgrade) openCV from 4.5.4 to 4.6.0 - Custom library is now built to strip unused dependencies and reduce library size - (Remove) arch and rhel packages in favor of a generic linux
Diffstat (limited to 'UVtools.Core')
-rw-r--r--UVtools.Core/Extensions/RectangleExtensions.cs9
-rw-r--r--UVtools.Core/FileFormats/FileFormat.cs50
-rw-r--r--UVtools.Core/FileFormats/SL1File.cs3
-rw-r--r--UVtools.Core/Managers/IssueManager.cs49
-rw-r--r--UVtools.Core/Managers/KernelCacheManager.cs5
-rw-r--r--UVtools.Core/Managers/MatCacheManager.cs2
-rw-r--r--UVtools.Core/Objects/KernelConfiguration.cs14
-rw-r--r--UVtools.Core/Operations/OperationCalculator.cs3
-rw-r--r--UVtools.Core/Operations/OperationIPrintedThisFile.cs16
-rw-r--r--UVtools.Core/Operations/OperationPCBExposure.cs8
-rw-r--r--UVtools.Core/Printer/Machine.cs32
-rw-r--r--UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs21
-rw-r--r--UVtools.Core/UVtools.Core.csproj8
13 files changed, 172 insertions, 48 deletions
diff --git a/UVtools.Core/Extensions/RectangleExtensions.cs b/UVtools.Core/Extensions/RectangleExtensions.cs
index 7678488..05fbb41 100644
--- a/UVtools.Core/Extensions/RectangleExtensions.cs
+++ b/UVtools.Core/Extensions/RectangleExtensions.cs
@@ -16,4 +16,13 @@ public static class RectangleExtensions
return new Point(src.Left + src.Width / 2, src.Top + src.Height / 2);
}
+ public static Rectangle OffsetBy(this Rectangle src, int x, int y)
+ {
+ var rect = src;
+ rect.Offset(x, y);
+ return rect;
+ }
+
+ public static Rectangle OffsetBy(this Rectangle src, Point position) => src.OffsetBy(position.X, position.Y);
+
} \ No newline at end of file
diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs
index a252117..136fe24 100644
--- a/UVtools.Core/FileFormats/FileFormat.cs
+++ b/UVtools.Core/FileFormats/FileFormat.cs
@@ -2746,6 +2746,10 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
if(!RaiseAndSetIfChanged(ref _printTime, value)) return;
RaisePropertyChanged(nameof(PrintTimeHours));
RaisePropertyChanged(nameof(PrintTimeString));
+ RaisePropertyChanged(nameof(DisplayTotalOnTime));
+ RaisePropertyChanged(nameof(DisplayTotalOnTimeString));
+ RaisePropertyChanged(nameof(DisplayTotalOffTime));
+ RaisePropertyChanged(nameof(DisplayTotalOffTimeString));
}
}
@@ -2843,7 +2847,45 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
get
{
var printTime = PrintTime;
- return TimeSpan.FromSeconds(printTime >= float.PositiveInfinity ? 0 : printTime).ToString("hh\\hmm\\m");
+ return TimeSpan.FromSeconds(float.IsPositiveInfinity(printTime) || float.IsNaN(printTime) ? 0 : printTime).ToString("hh\\hmm\\m");
+ }
+ }
+
+ /// <summary>
+ /// Gets the total time in seconds the display will remain on exposing the layers during the print
+ /// </summary>
+ public float DisplayTotalOnTime => (float)Math.Round(this.Sum(layer => layer.ExposureTime), 2);
+
+ /// <summary>
+ /// Gets the total time formatted in hours, minutes and seconds the display will remain on exposing the layers during the print
+ /// </summary>
+ public string DisplayTotalOnTimeString => TimeSpan.FromSeconds(DisplayTotalOnTime).ToString("hh\\hmm\\mss\\s");
+
+ /// <summary>
+ /// Gets the total time in seconds the display will remain off during the print.
+ /// This is the difference between <see cref="PrintTime"/> and <see cref="DisplayTotalOnTime"/>
+ /// </summary>
+ public float DisplayTotalOffTime
+ {
+ get
+ {
+ var printTime = PrintTime;
+ if (float.IsPositiveInfinity(printTime) || float.IsNaN(printTime)) return float.NaN;
+ var value = (float) Math.Round(PrintTime - DisplayTotalOnTime, 2);
+ return value <= 0 ? float.NaN : value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the total time formatted in hours, minutes and seconds the display will remain off during the print.
+ /// This is the difference between <see cref="PrintTime"/> and <see cref="DisplayTotalOnTime"/>
+ /// </summary>
+ public string DisplayTotalOffTimeString
+ {
+ get
+ {
+ var time = DisplayTotalOffTime;
+ return TimeSpan.FromSeconds(float.IsPositiveInfinity(time) || float.IsNaN(time) ? 0 : time).ToString("hh\\hmm\\mss\\s");
}
}
@@ -3916,6 +3958,12 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
}
/// <summary>
+ /// Gets the transition step time from <see cref="BottomExposureTime"/> and <see cref="ExposureTime"/>, value is returned as positive from normal perspective and logic (Longer - shorter)
+ /// </summary>
+ /// <returns>Seconds</returns>
+ public float GetTransitionStepTime() => GetTransitionStepTime(TransitionLayerCount);
+
+ /// <summary>
/// Gets the transition layer count based on long and short exposure time
/// </summary>
/// <param name="longExposureTime">The long exposure time</param>
diff --git a/UVtools.Core/FileFormats/SL1File.cs b/UVtools.Core/FileFormats/SL1File.cs
index 417e71d..21af6a3 100644
--- a/UVtools.Core/FileFormats/SL1File.cs
+++ b/UVtools.Core/FileFormats/SL1File.cs
@@ -100,6 +100,7 @@ public class SL1File : FileFormat
public float FastTiltTime { get; set; } = 5;
public float SlowTiltTime { get; set; } = 8;
+ public float HighViscosityTiltTime { get; set; } = 10;
public float AreaFill { get; set; } = 50;
#endregion
@@ -312,7 +313,7 @@ public class SL1File : FileFormat
public string PrinterModel { get; set; } = "SL1";
public string PrinterProfile { get; set; } = About.Software;
public string PrinterVariant { get; set; } = "default";
- public string PrusaSlicerVersion { get; set; } = "PrusaSlicer-2.3.3+win64-202107161027";
+ public string PrusaSlicerVersion { get; set; } = "PrusaSlicer-2.5.0+win64-202209060714";
public float UsedMaterial { get; set; }
public override string ToString()
diff --git a/UVtools.Core/Managers/IssueManager.cs b/UVtools.Core/Managers/IssueManager.cs
index 2a3f333..80d02d0 100644
--- a/UVtools.Core/Managers/IssueManager.cs
+++ b/UVtools.Core/Managers/IssueManager.cs
@@ -192,6 +192,9 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
var firstLayer = SlicerFile.FirstLayer;
+ int overhangsIterations = overhangConfig.ErodeIterations;
+ using var overhangsKernel = EmguExtensions.GetDynamicKernel(ref overhangsIterations, ElementShape.Cross);
+
// Detect contours
Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndexInt =>
{
@@ -330,7 +333,8 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
// Overhangs
- var overhangCount = 0;
+ //var overhangCount = 0;
+ var overhangs = new List<MainIssue>();
//if (!islandConfig.Enabled && overhangConfig.Enabled ||
// (islandConfig.Enabled && overhangConfig.Enabled && overhangConfig.IndependentFromIslands))
if (overhangConfig.Enabled)
@@ -354,8 +358,8 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
CvInvoke.Subtract(image.RoiMat, previousImage.RoiMat, overhangImage);
CvInvoke.Threshold(overhangImage, overhangImage, 127, 255, ThresholdType.Binary);
- CvInvoke.Erode(overhangImage, overhangImage, EmguExtensions.Kernel3x3Rectangle,
- EmguExtensions.AnchorCenter, overhangConfig.ErodeIterations, BorderType.Default, default);
+ CvInvoke.Erode(overhangImage, overhangImage, overhangsKernel,
+ EmguExtensions.AnchorCenter, overhangsIterations, BorderType.Default, default);
//CvInvoke.MorphologyEx(subtractedImage, subtractedImage, MorphOp.Open, EmguExtensions.Kernel3x3Rectangle,
// EmguExtensions.AnchorCenter, 2, BorderType.Reflect101, default);
@@ -366,12 +370,13 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
foreach (var contourGroup in contoursInGroups)
{
if (contourGroup[0].Size < 3) continue; // Single contour, single line, ignore
- overhangCount++;
var area = EmguContours.GetContourArea(contourGroup);
if (area >= overhangConfig.RequiredPixelsToConsider)
{
var rect = CvInvoke.BoundingRectangle(contourGroup[0]);
- AddIssue(new MainIssue(MainIssue.IssueType.Overhang, new IssueOfContours(layer, contourGroup.ToArrayOfArray(), rect, area)));
+ var overhangIssue = new MainIssue(MainIssue.IssueType.Overhang, new IssueOfContours(layer, contourGroup.ToArrayOfArray(), rect, area));
+ overhangs.Add(overhangIssue);
+ AddIssue(overhangIssue);
}
}
}
@@ -481,16 +486,20 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
pixelsSupportingIsland >= Math.Max(1, points.Count / 2))
isIsland = false; // Not a island, but maybe weak bounding...*/
- IssueOfPoints? island = null;
- if (pixelsSupportingIsland < requiredSupportingPixels)
- {
- island = new IssueOfPoints(layer, points.ToArray(), new Rectangle(rect.Location.OffsetBy(image.RoiLocation), rect.Size));
- }
+ if (pixelsSupportingIsland >= requiredSupportingPixels) continue;
+
+ var islandBoundingRectangle = rect.OffsetBy(image.RoiLocation);
// Check for overhangs in islands
- if (island is not null && islandConfig.EnhancedDetection && pixelsSupportingIsland >= 10 &&
- (!overhangConfig.Enabled || (overhangConfig.Enabled && overhangCount > 0)))
+ if (islandConfig.EnhancedDetection && pixelsSupportingIsland >= 10 && pixelsSupportingIsland >= requiredSupportingPixels / 4)
+ // && (!overhangConfig.Enabled || (overhangConfig.Enabled && overhangCount > 0))
{
+ if (overhangConfig.Enabled && // No overhangs nor intersecting = discard island
+ overhangs.TrueForAll(overhang => !overhang.BoundingRectangle.IntersectsWith(islandBoundingRectangle)))
+ {
+ continue;
+ }
+
using var islandRoi = image.RoiMat.Roi(rect);
using var previousIslandRoi = previousImage.RoiMat.Roi(rect);
@@ -501,8 +510,8 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
CvInvoke.Subtract(islandRoi, previousIslandRoi, islandOverhangMat);
CvInvoke.Threshold(islandOverhangMat, islandOverhangMat, 127, 255, ThresholdType.Binary);
- CvInvoke.Erode(islandOverhangMat, islandOverhangMat, EmguExtensions.Kernel3x3Rectangle,
- EmguExtensions.AnchorCenter, overhangConfig.ErodeIterations, BorderType.Default, default);
+ CvInvoke.Erode(islandOverhangMat, islandOverhangMat, overhangsKernel,
+ EmguExtensions.AnchorCenter, overhangsIterations, BorderType.Default, default);
}
using var subtractedImage = islandOverhangMat.Roi(rect);
@@ -517,22 +526,20 @@ public sealed class IssueManager : RangeObservableCollection<MainIssue>
{
int labelX = rect.X + x;
int labelY = rect.Y + y;
- if (labelSpan[labelY, labelX] != i || subtractedSpan.DangerousGetReferenceAt(y, x) == 0)
- continue;
+ if (labelSpan[labelY, labelX] != i || subtractedSpan.DangerousGetReferenceAt(y, x) == 0) continue;
overhangPixels++;
}
- if(!ReferenceEquals(overhangImage, islandOverhangMat)) islandOverhangMat.Dispose();
+ if (!ReferenceEquals(overhangImage, islandOverhangMat)) islandOverhangMat.Dispose();
if (overhangPixels < overhangConfig.RequiredPixelsToConsider) // No overhang = no island
{
- island = null;
+ continue;
}
-
}
-
- if (island is not null) AddIssue(new MainIssue(MainIssue.IssueType.Island, island));
+
+ AddIssue(new MainIssue(MainIssue.IssueType.Island, new IssueOfPoints(layer, points, islandBoundingRectangle)));
}
}
}
diff --git a/UVtools.Core/Managers/KernelCacheManager.cs b/UVtools.Core/Managers/KernelCacheManager.cs
index 909eafd..340c45c 100644
--- a/UVtools.Core/Managers/KernelCacheManager.cs
+++ b/UVtools.Core/Managers/KernelCacheManager.cs
@@ -9,6 +9,7 @@
using Emgu.CV;
using System;
using System.Collections.Concurrent;
+using Emgu.CV.CvEnum;
using UVtools.Core.Extensions;
namespace UVtools.Core.Managers;
@@ -19,6 +20,8 @@ public class KernelCacheManager : IDisposable
public bool UseDynamicKernel { get; set; }
+ public ElementShape DynamicKernelShape { get; set; } = ElementShape.Ellipse;
+
private readonly Mat _defaultKernel;
public KernelCacheManager(bool useDynamicKernel = false, Mat? defaultKernel = null)
@@ -30,7 +33,7 @@ public class KernelCacheManager : IDisposable
public Mat Get(ref int iterations)
{
if (!UseDynamicKernel) return _defaultKernel;
- var mat = _kernelCache.GetOrAdd(iterations, i => EmguExtensions.GetDynamicKernel(ref i));
+ var mat = _kernelCache.GetOrAdd(iterations, i => EmguExtensions.GetDynamicKernel(ref i, DynamicKernelShape));
iterations = 1;
return mat;
}
diff --git a/UVtools.Core/Managers/MatCacheManager.cs b/UVtools.Core/Managers/MatCacheManager.cs
index 9ffef33..79a36de 100644
--- a/UVtools.Core/Managers/MatCacheManager.cs
+++ b/UVtools.Core/Managers/MatCacheManager.cs
@@ -105,7 +105,7 @@ public class MatCacheManager : IDisposable
public MatCacheManager(FileFormat slicerFile, uint layerIndexStart, uint layerIndexEnd, ushort cacheCount = 0, byte elementsPerCache = 1)
{
if (cacheCount == 0) cacheCount = (ushort)(Environment.ProcessorCount * 5);
- if (layerIndexEnd == 0) layerIndexEnd = slicerFile.LayerCount;
+ if (layerIndexEnd == 0) layerIndexEnd = slicerFile.LayerCount > 0 ? slicerFile.LayerCount - 1 : 0;
SlicerFile = slicerFile;
LayerIndexStart = layerIndexStart;
LayerIndexEnd = layerIndexEnd;
diff --git a/UVtools.Core/Objects/KernelConfiguration.cs b/UVtools.Core/Objects/KernelConfiguration.cs
index dac6fce..9c967bb 100644
--- a/UVtools.Core/Objects/KernelConfiguration.cs
+++ b/UVtools.Core/Objects/KernelConfiguration.cs
@@ -32,6 +32,8 @@ public sealed class KernelConfiguration : BindableBase, IDisposable
private int _anchorY = -1;
private Mat? _kernelMat;
private readonly object _mutex = new();
+ private ElementShape _dynamicKernelShape = ElementShape.Ellipse;
+
#endregion
#region Properties
@@ -45,6 +47,16 @@ public sealed class KernelConfiguration : BindableBase, IDisposable
}
}
+ public ElementShape DynamicKernelShape
+ {
+ get => _dynamicKernelShape;
+ set
+ {
+ if (!RaiseAndSetIfChanged(ref _dynamicKernelShape, value)) return;
+ _kernelCache.DynamicKernelShape = value;
+ }
+ }
+
public int AnchorX
{
get => _anchorX;
@@ -227,7 +239,7 @@ public sealed class KernelConfiguration : BindableBase, IDisposable
public Mat? GetKernel(ref int iterations)
{
- if (!UseDynamicKernel) return KernelMat;
+ if (!_useDynamicKernel) return KernelMat;
return _kernelCache.Get(ref iterations);
}
diff --git a/UVtools.Core/Operations/OperationCalculator.cs b/UVtools.Core/Operations/OperationCalculator.cs
index ec529cc..1be34b5 100644
--- a/UVtools.Core/Operations/OperationCalculator.cs
+++ b/UVtools.Core/Operations/OperationCalculator.cs
@@ -60,8 +60,7 @@ public class OperationCalculator : Operation
(decimal)SlicerFile.LiftHeight, (decimal)SlicerFile.BottomLiftHeight,
(decimal)SlicerFile.LiftSpeed, (decimal)SlicerFile.BottomLiftSpeed,
(decimal)SlicerFile.RetractSpeed, (decimal)SlicerFile.RetractSpeed);
- CalcOptimalModelTilt = new OptimalModelTilt(SlicerFile.Resolution, SlicerFile.Display,
- (decimal)SlicerFile.LayerHeight);
+ CalcOptimalModelTilt = new OptimalModelTilt(SlicerFile.Resolution, SlicerFile.Display, (decimal)SlicerFile.LayerHeight);
}
#endregion
diff --git a/UVtools.Core/Operations/OperationIPrintedThisFile.cs b/UVtools.Core/Operations/OperationIPrintedThisFile.cs
index 8dbdf3d..f29cb1c 100644
--- a/UVtools.Core/Operations/OperationIPrintedThisFile.cs
+++ b/UVtools.Core/Operations/OperationIPrintedThisFile.cs
@@ -39,7 +39,7 @@ public class OperationIPrintedThisFile : Operation
public override string Description => "Select a material and consume resin from stock and print time.";
public override string ConfirmationText =>
- $"consume {FinalVolume}ml and {FinalPrintTimeHours:F4}h on:\n{_materialItem} ?";
+ $"consume {FinalVolume}ml and {FinalPrintTimeString:F4}h on:\n{_materialItem} ?";
public override string ProgressTitle =>
$"Consuming";
@@ -68,7 +68,7 @@ public class OperationIPrintedThisFile : Operation
public override string ToString()
{
- var result = $"{FinalVolume}ml {FinalPrintTimeHours:F4}h on {_materialItem?.Name}";
+ var result = $"{FinalVolume}ml {FinalPrintTimeString:F4}h on {_materialItem?.Name}";
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
}
@@ -87,7 +87,7 @@ public class OperationIPrintedThisFile : Operation
get => _volume;
set
{
- if(!RaiseAndSetIfChanged(ref _volume, value)) return;
+ if(!RaiseAndSetIfChanged(ref _volume, Math.Max(0, value))) return;
RaisePropertyChanged(nameof(FinalVolume));
}
}
@@ -99,16 +99,16 @@ public class OperationIPrintedThisFile : Operation
get => _printTime;
set
{
- if(!RaiseAndSetIfChanged(ref _printTime, value)) return;
- RaisePropertyChanged(nameof(PrintTimeHours));
+ if(!RaiseAndSetIfChanged(ref _printTime, Math.Max(0, value))) return;
+ RaisePropertyChanged(nameof(PrintTimeString));
RaisePropertyChanged(nameof(FinalPrintTime));
- RaisePropertyChanged(nameof(FinalPrintTimeHours));
+ RaisePropertyChanged(nameof(FinalPrintTimeString));
}
}
- public float PrintTimeHours => _printTime / 60 / 60;
+ public string PrintTimeString => TimeSpan.FromSeconds(_printTime).ToString("hh\\hmm\\mss\\s");
public float FinalPrintTime => _printTime * (float)_multiplier;
- public float FinalPrintTimeHours => FinalPrintTime / 60 / 60;
+ public string FinalPrintTimeString => TimeSpan.FromSeconds(FinalPrintTime).ToString("hh\\hmm\\mss\\s");
/// <summary>
/// Number of times this file has been printed
diff --git a/UVtools.Core/Operations/OperationPCBExposure.cs b/UVtools.Core/Operations/OperationPCBExposure.cs
index 3b50b45..017a1aa 100644
--- a/UVtools.Core/Operations/OperationPCBExposure.cs
+++ b/UVtools.Core/Operations/OperationPCBExposure.cs
@@ -145,7 +145,7 @@ public class OperationPCBExposure : Operation
public decimal ExposureTime
{
get => _exposureTime;
- set => RaiseAndSetIfChanged(ref _exposureTime, Math.Round(value, 2));
+ set => RaiseAndSetIfChanged(ref _exposureTime, Math.Round(Math.Max(0, value), 2));
}
public GerberMidpointRounding SizeMidpointRounding
@@ -291,10 +291,16 @@ public class OperationPCBExposure : Operation
SlicerFile.SuppressRebuildPropertiesWork(() =>
{
SlicerFile.LayerHeight = (float) _layerHeight;
+ SlicerFile.TransitionLayerCount = 0;
SlicerFile.BottomLayerCount = 1;
SlicerFile.BottomExposureTime = (float) _exposureTime;
SlicerFile.ExposureTime = (float)_exposureTime;
+ SlicerFile.BottomLiftHeightTotal = 0;
SlicerFile.LiftHeightTotal = 0;
+ /*SlicerFile.BottomLiftSpeed = 300;
+ SlicerFile.BottomLiftSpeed2 = 300;
+ SlicerFile.LiftSpeed = 300;
+ SlicerFile.LiftSpeed2 = 300;*/
SlicerFile.SetNoDelays();
SlicerFile.Layers = layers.ToArray();
diff --git a/UVtools.Core/Printer/Machine.cs b/UVtools.Core/Printer/Machine.cs
index 53a9b65..24d6a50 100644
--- a/UVtools.Core/Printer/Machine.cs
+++ b/UVtools.Core/Printer/Machine.cs
@@ -12,13 +12,20 @@ using System.Drawing;
using System.IO;
using System.Text;
using UVtools.Core.Extensions;
+using UVtools.Core.Objects;
namespace UVtools.Core.Printer
{
- public class Machine
+ public class Machine : BindableBase
{
+ #region Members
+ private float _totalPrintTime;
+ private float _totalDisplayOnTime;
+ #endregion
+
#region Properties
- public PrinterBrand Brand { get; set; }
+
+ public PrinterBrand Brand { get; set; } = PrinterBrand.Generic;
public string Name { get; set; } = FileFormats.FileFormat.DefaultMachineName;
public string Model { get; set; } = FileFormats.FileFormat.DefaultMachineName;
@@ -35,6 +42,27 @@ namespace UVtools.Core.Printer
public FlipDirection DisplayMirror { get; set; }
public object? Tag { get; set; }
+
+ public float TotalPrintTime
+ {
+ get => _totalPrintTime;
+ set => RaiseAndSetIfChanged(ref _totalPrintTime, (float)Math.Max(0f, Math.Round(value, 2)));
+ }
+
+ public string TotalPrintTimeString => TimeSpan.FromSeconds(_totalPrintTime).ToString("hh\\hmm\\mss\\s");
+
+ public float TotalDisplayOnTime
+ {
+ get => _totalDisplayOnTime;
+ set => RaiseAndSetIfChanged(ref _totalDisplayOnTime, (float)Math.Max(0f, Math.Round(value, 2)));
+ }
+
+ public string DisplayTotalOnTimeString => TimeSpan.FromSeconds(_totalDisplayOnTime).ToString("hh\\hmm\\mss\\s");
+
+ public float TotalDisplayOffTime => TotalPrintTime - TotalDisplayOnTime;
+
+ public string DisplayTotalOffTimeString => TimeSpan.FromSeconds(TotalDisplayOffTime).ToString("hh\\hmm\\mss\\s");
+
#endregion
#region Constructor
diff --git a/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs b/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs
index 7cc84b5..433daf0 100644
--- a/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs
+++ b/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs
@@ -8,6 +8,7 @@
using System;
using System.Text;
+using UVtools.Core.FileFormats;
using UVtools.Core.Operations;
namespace UVtools.Core.Suggestions;
@@ -47,7 +48,9 @@ public sealed class SuggestionTransitionLayerCount : Suggestion
|| SlicerFile.BottomLayerCount + _minimumTransitionLayerCount > SlicerFile.LayerCount
|| SlicerFile.MaximumPossibleTransitionLayerCount < _minimumTransitionLayerCount) return true;
- var actualTransitionLayerCount = SlicerFile.ParseTransitionLayerCountFromLayers();
+ var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
+ ? SlicerFile.TransitionLayerCount
+ : SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
if (actualTransitionLayerCount == suggestedTransitionLayerCount) return true;
@@ -72,8 +75,12 @@ public sealed class SuggestionTransitionLayerCount : Suggestion
{
get
{
- var actualTransitionDecrementTime = SlicerFile.ParseTransitionStepTimeFromLayers();
- var actualTransitionLayerCount = SlicerFile.ParseTransitionLayerCountFromLayers();
+ var actualTransitionDecrementTime = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
+ ? SlicerFile.GetTransitionStepTime()
+ : SlicerFile.ParseTransitionStepTimeFromLayers();
+ var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
+ ? SlicerFile.TransitionLayerCount
+ : SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTime(suggestedTransitionLayerCount);
@@ -93,8 +100,12 @@ public sealed class SuggestionTransitionLayerCount : Suggestion
{
get
{
- var actualTransitionDecrementTime = SlicerFile.ParseTransitionStepTimeFromLayers();
- var actualTransitionLayerCount = SlicerFile.ParseTransitionLayerCountFromLayers();
+ var actualTransitionDecrementTime = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
+ ? SlicerFile.GetTransitionStepTime()
+ : SlicerFile.ParseTransitionStepTimeFromLayers();
+ var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
+ ? SlicerFile.TransitionLayerCount
+ : SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTime(suggestedTransitionLayerCount);
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 0cd165f..350bf5a 100644
--- a/UVtools.Core/UVtools.Core.csproj
+++ b/UVtools.Core/UVtools.Core.csproj
@@ -10,7 +10,7 @@
<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.7.2</Version>
+ <Version>3.8.0</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
@@ -70,9 +70,9 @@
<PackageReference Include="AnimatedGif" Version="1.0.5" />
<PackageReference Include="BinarySerializer" Version="8.6.2.2" />
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.0.0" />
- <PackageReference Include="Emgu.CV" Version="4.5.5.4823" />
- <PackageReference Include="Emgu.CV.runtime.ubuntu.20.04-x64" Version="4.5.4.4788" />
- <PackageReference Include="Emgu.CV.runtime.windows" Version="4.5.4.4788" />
+ <PackageReference Include="Emgu.CV" Version="4.6.0.5131" />
+ <PackageReference Include="Emgu.CV.runtime.ubuntu-x64" Version="4.6.0.5131" />
+ <PackageReference Include="Emgu.CV.runtime.windows" Version="4.6.0.5131" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
<PackageReference Include="KdTree" Version="1.4.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.3.1" />