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>2021-02-16 01:30:26 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-02-16 01:30:26 +0300
commitf69a0f1175603e87558e0587e5a29ea882ef7e9b (patch)
treecd8534e3c6188c0cb5727697d8699bfc419b9d45
parenta78703662ec6bfb575df283c1e1b4e4776723b43 (diff)
v2.4.6v2.4.6
* **(Improvement) Calibration - Elephant Foot:** (#145) * Remove text from bottom layers to prevent islands from not adhering to plate * Add a option to extrude text up to a height * **(Improvement) Calibration - Exposure time finder:** (#144) * Increase the left and right margin to 10mm * Allow to iterate over pixel brightness and generate dimmed objects to test multiple times at once * **(Fix) File format PWS:** * Some files would produce black layers if pixels are not full whites, Antialiasing level was not inherit from source * Antialiasing level was forced 1 and not read the value from file properties * Antialiasing threshold pixel math was producing the wrong pixel value * **(Fix) Raw images (jpg, png, etc):** (#146) * Set layer height to be 0.01mm by default to allow the use of some tools * When add layers by clone or other tool it don't update layers height, positions, indexes, leading to crashes * **(Fix) Actions - Import Layers:** (#146, #147) * ROI calculation error leading to not process images that can potential fit inside the volumes * Out-of-bounds calculation for Stack type * Replace type was calculating out-of-bounds calculation like Stack type when is not required to and can lead to skip images * Better image ROI colection for Insert and Replace types instead of capture the center most * (Fix) Settings window: Force a redraw on open to fix auto sizes
-rw-r--r--CHANGELOG.md22
-rw-r--r--CREDITS.md3
-rw-r--r--CreateRelease.WPF.ps14
-rw-r--r--UVtools.Core/Extensions/EmguExtensions.cs27
-rw-r--r--UVtools.Core/FileFormats/FileFormat.cs17
-rw-r--r--UVtools.Core/FileFormats/ImageFile.cs2
-rw-r--r--UVtools.Core/FileFormats/PhotonWorkshopFile.cs15
-rw-r--r--UVtools.Core/Layer/Layer.cs61
-rw-r--r--UVtools.Core/Objects/ExposureItem.cs36
-rw-r--r--UVtools.Core/Operations/OperationCalibrateElephantFoot.cs122
-rw-r--r--UVtools.Core/Operations/OperationCalibrateExposureFinder.cs255
-rw-r--r--UVtools.Core/Operations/OperationLayerImport.cs51
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml46
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml113
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs14
-rw-r--r--UVtools.WPF/Program.cs7
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
-rw-r--r--UVtools.WPF/Windows/SettingsWindow.axaml.cs5
19 files changed, 619 insertions, 185 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 392e1a7..59f1166 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,27 @@
# Changelog
+## 15/02/2021 - v2.4.6
+
+* **(Improvement) Calibration - Elephant Foot:** (#145)
+ * Remove text from bottom layers to prevent islands from not adhering to plate
+ * Add a option to extrude text up to a height
+* **(Improvement) Calibration - Exposure time finder:** (#144)
+ * Increase the left and right margin to 10mm
+ * Allow to iterate over pixel brightness and generate dimmed objects to test multiple times at once
+* **(Fix) File format PWS:**
+ * Some files would produce black layers if pixels are not full whites, Antialiasing level was not inherit from source
+ * Antialiasing level was forced 1 and not read the value from file properties
+ * Antialiasing threshold pixel math was producing the wrong pixel value
+* **(Fix) Raw images (jpg, png, etc):** (#146)
+ * Set layer height to be 0.01mm by default to allow the use of some tools
+ * When add layers by clone or other tool it don't update layers height, positions, indexes, leading to crashes
+* **(Fix) Actions - Import Layers:** (#146, #147)
+ * ROI calculation error leading to not process images that can potential fit inside the volumes
+ * Out-of-bounds calculation for Stack type
+ * Replace type was calculating out-of-bounds calculation like Stack type when is not required to and can lead to skip images
+ * Better image ROI colection for Insert and Replace types instead of capture the center most
+* (Fix) Settings window: Force a redraw on open to fix auto sizes
+
## 12/02/2021 - v2.4.5
* (Add) Setting: Expand and show tool descriptions by default
diff --git a/CREDITS.md b/CREDITS.md
index 913d275..3fdba55 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -46,4 +46,5 @@
* Claus Pfeilschifter
* Chris Taatgen
* Andrew Griffiths
-* Abhinav Sinha \ No newline at end of file
+* Abhinav Sinha
+* Randy Savell \ No newline at end of file
diff --git a/CreateRelease.WPF.ps1 b/CreateRelease.WPF.ps1
index 607d0f4..ded2d46 100644
--- a/CreateRelease.WPF.ps1
+++ b/CreateRelease.WPF.ps1
@@ -29,9 +29,9 @@ class FixedEncoder : System.Text.UTF8Encoding {
####################################
### Configuration ###
####################################
-$enableMSI = $true
+$enableMSI = $false
$buildOnly = $null
-#$buildOnly = ""#"win-x64"
+#$buildOnly = "osx-x64"#"win-x64"
# Profilling
$stopWatch = New-Object -TypeName System.Diagnostics.Stopwatch
$deployStopWatch = New-Object -TypeName System.Diagnostics.Stopwatch
diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs
index b5ed369..2eaa12a 100644
--- a/UVtools.Core/Extensions/EmguExtensions.cs
+++ b/UVtools.Core/Extensions/EmguExtensions.cs
@@ -8,6 +8,7 @@
using System;
using System.Drawing;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
@@ -275,15 +276,25 @@ namespace UVtools.Core.Extensions
return mat;
}
- public static Mat RoiFromCenter(this Mat mat, Size size)
+ public static Mat RoiFromCenter(this Mat mat, Size targetSize, Rectangle roi)
{
- if (size == mat.Size) return mat;
- return new Mat(mat, new Rectangle(
- mat.Size.Width / 2 - size.Width / 2,
- mat.Size.Height / 2 - size.Height / 2,
- size.Width,
- size.Height
- ));
+ if (targetSize == mat.Size) return mat;
+ var newMat = InitMat(targetSize);
+
+ var roiMat = new Mat(mat, roi);
+
+
+ //int xStart = mat.Width / 2 - targetSize.Width / 2;
+ //int yStart = mat.Height / 2 - targetSize.Height / 2;
+
+ var newMatRoi = new Mat(newMat, new Rectangle(
+ targetSize.Width / 2 - roi.Width / 2,
+ targetSize.Height / 2 - roi.Height / 2,
+ roi.Width,
+ roi.Height
+ ));
+ roiMat.CopyTo(newMatRoi);
+ return newMat;
}
}
diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs
index 074070f..69cb349 100644
--- a/UVtools.Core/FileFormats/FileFormat.cs
+++ b/UVtools.Core/FileFormats/FileFormat.cs
@@ -37,9 +37,14 @@ namespace UVtools.Core.FileFormats
private const string ExtractConfigFileName = "Configuration";
private const string ExtractConfigFileExtension = "ini";
+ public const ushort DefaultBottomLayerCount = 4;
+
+ public const float DefaultBottomExposureTime = 30;
public const float DefaultBottomLiftHeight = 5;
public const float DefaultLiftHeight = 5;
public const float DefaultBottomLiftSpeed = 100;
+
+ public const float DefaultExposureTime = 3;
public const float DefaultLiftSpeed = 100;
public const float DefaultRetractSpeed = 100;
public const float DefaultBottomLightOffDelay = 0;
@@ -639,7 +644,10 @@ namespace UVtools.Core.FileFormats
public virtual uint LayerCount
{
get => LayerManager?.Count ?? 0;
- set { }
+ set {
+ RaisePropertyChanged();
+ RaisePropertyChanged(nameof(NormalLayerCount));
+ }
}
#region Universal Properties
@@ -647,7 +655,7 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// Gets or sets the number of initial layer count
/// </summary>
- public virtual ushort BottomLayerCount { get; set; }
+ public virtual ushort BottomLayerCount { get; set; } = DefaultBottomLayerCount;
/// <summary>
/// Gets the number of normal layer count
@@ -657,12 +665,12 @@ namespace UVtools.Core.FileFormats
/// <summary>
/// Gets or sets the initial exposure time for <see cref="BottomLayerCount"/> in seconds
/// </summary>
- public virtual float BottomExposureTime { get; set; }
+ public virtual float BottomExposureTime { get; set; } = DefaultBottomExposureTime;
/// <summary>
/// Gets or sets the normal layer exposure time in seconds
/// </summary>
- public virtual float ExposureTime { get; set; }
+ public virtual float ExposureTime { get; set; } = DefaultExposureTime;
/// <summary>
/// Gets or sets the bottom layer off time in seconds
@@ -1074,6 +1082,7 @@ namespace UVtools.Core.FileFormats
for (var i = 0; i < ThumbnailsCount; i++)
{
Thumbnails[i] = image.Clone();
+ if (ThumbnailsOriginalSize is null || i >= ThumbnailsOriginalSize.Length) continue;
if (Thumbnails[i].Size != ThumbnailsOriginalSize[i])
{
CvInvoke.Resize(Thumbnails[i], Thumbnails[i], ThumbnailsOriginalSize[i]);
diff --git a/UVtools.Core/FileFormats/ImageFile.cs b/UVtools.Core/FileFormats/ImageFile.cs
index c97ff1d..da2cec9 100644
--- a/UVtools.Core/FileFormats/ImageFile.cs
+++ b/UVtools.Core/FileFormats/ImageFile.cs
@@ -66,7 +66,7 @@ namespace UVtools.Core.FileFormats
set { }
}
- public override float LayerHeight { get; set; } = 0;
+ public override float LayerHeight { get; set; } = 0.01f;
/*public override float PrintTime { get; } = 0;
public override float UsedMaterial { get; } = 0;
public override float MaterialCost { get; } = 0;
diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
index 610b6a7..5447c13 100644
--- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
+++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
@@ -505,7 +505,7 @@ namespace UVtools.Core.FileFormats
rawData.Add(by);
}
- for (byte aalevel = 0; aalevel < Parent.AntiAliasing; aalevel++)
+ for (byte aalevel = 1; aalevel <= Parent.AntiAliasing; aalevel++)
{
obit = false;
rep = 0;
@@ -516,7 +516,9 @@ namespace UVtools.Core.FileFormats
// aa 2: 255 127
// aa 4: 255 191 127 63
// aa 8: 255 223 191 159 127 95 63 31
- byte threshold = (byte)(256 / Parent.AntiAliasing * aalevel - 1);
+ //byte threshold = (byte)(256 / Parent.AntiAliasing * aalevel - 1);
+ // threshold := byte(int(255 * (level + 1) / (levels + 1))) + 1
+ byte threshold = (byte) (255 * aalevel / (Parent.AntiAliasing + 1) + 1);
for (int pixel = 0; pixel < imageLength; pixel++)
@@ -845,8 +847,13 @@ namespace UVtools.Core.FileFormats
public override byte AntiAliasing
{
- get => 4;
- set { }
+ get => (byte) HeaderSettings.AntiAliasing;
+ set
+ {
+ HeaderSettings.AntiAliasing = value.Clamp(1, 16);
+ ValidateAntiAliasingLevel();
+ RaisePropertyChanged();
+ }
}
public override float LayerHeight
diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs
index 74ca871..6da632c 100644
--- a/UVtools.Core/Layer/Layer.cs
+++ b/UVtools.Core/Layer/Layer.cs
@@ -205,26 +205,13 @@ namespace UVtools.Core
{
_compressedBytes = value;
IsModified = true;
- if (!ReferenceEquals(ParentLayerManager, null))
+ if (ParentLayerManager is not null)
ParentLayerManager.BoundingRectangle = Rectangle.Empty;
+ RaisePropertyChanged();
}
}
/// <summary>
- /// Gets a computed layer filename, padding zeros are equal to layer count digits
- /// </summary>
- public string Filename => FormatFileName("layer");
-
- /// <summary>
- /// Gets if layer has been modified
- /// </summary>
- public bool IsModified
- {
- get => _isModified;
- set => RaiseAndSetIfChanged(ref _isModified, value);
- }
-
- /// <summary>
/// Gets or sets a new image instance
/// </summary>
public Mat LayerMat
@@ -232,7 +219,7 @@ namespace UVtools.Core
get
{
Mat mat = new();
- CvInvoke.Imdecode(CompressedBytes, ImreadModes.Grayscale, mat);
+ CvInvoke.Imdecode(_compressedBytes, ImreadModes.Grayscale, mat);
return mat;
}
set
@@ -252,26 +239,34 @@ namespace UVtools.Core
{
get
{
- Mat mat = LayerMat;
+ var mat = LayerMat;
CvInvoke.CvtColor(mat, mat, ColorConversion.Gray2Bgr);
return mat;
}
}
+ /// <summary>
+ /// Gets a computed layer filename, padding zeros are equal to layer count digits
+ /// </summary>
+ public string Filename => FormatFileName("layer");
+
+ /// <summary>
+ /// Gets if layer has been modified
+ /// </summary>
+ public bool IsModified
+ {
+ get => _isModified;
+ set => RaiseAndSetIfChanged(ref _isModified, value);
+ }
+
#endregion
#region Constructor
- public Layer(uint index, byte[] compressedBytes, LayerManager parentLayerManager)
+
+ public Layer(uint index, LayerManager parentLayerManager)
{
ParentLayerManager = parentLayerManager;
- Index = index;
- //Filename = filename ?? $"Layer{index}.png";
- CompressedBytes = compressedBytes;
- IsModified = false;
- /*if (compressedBytes.Length > 0)
- {
- GetBoundingRectangle();
- }*/
+ _index = index;
if (parentLayerManager is null) return;
_positionZ = SlicerFile.GetHeightFromLayer(index);
@@ -282,13 +277,23 @@ namespace UVtools.Core
_lightPwm = SlicerFile.GetInitialLayerValueOrNormal(index, SlicerFile.BottomLightPWM, SlicerFile.LightPWM);
}
+ public Layer(uint index, byte[] compressedBytes, LayerManager parentLayerManager) : this(index, parentLayerManager)
+ {
+ CompressedBytes = compressedBytes;
+ _isModified = false;
+ /*if (compressedBytes.Length > 0)
+ {
+ GetBoundingRectangle();
+ }*/
+ }
+
public Layer(uint index, byte[] compressedBytes, FileFormat slicerFile) : this(index, compressedBytes, slicerFile.LayerManager)
{}
- public Layer(uint index, Mat layerMat, LayerManager parentLayerManager) : this(index, new byte[0], parentLayerManager)
+ public Layer(uint index, Mat layerMat, LayerManager parentLayerManager) : this(index, parentLayerManager)
{
LayerMat = layerMat;
- IsModified = false;
+ _isModified = false;
}
public Layer(uint index, Mat layerMat, FileFormat slicerFile) : this(index, layerMat, slicerFile.LayerManager) { }
diff --git a/UVtools.Core/Objects/ExposureItem.cs b/UVtools.Core/Objects/ExposureItem.cs
index 374a567..817ee78 100644
--- a/UVtools.Core/Objects/ExposureItem.cs
+++ b/UVtools.Core/Objects/ExposureItem.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace UVtools.Core.Objects
{
@@ -12,7 +8,7 @@ namespace UVtools.Core.Objects
private decimal _layerHeight;
private decimal _bottomExposure;
private decimal _exposure;
-
+ private byte _brightness = byte.MaxValue;
/// <summary>
/// Gets or sets the layer height in millimeters
@@ -42,25 +38,41 @@ namespace UVtools.Core.Objects
set => RaiseAndSetIfChanged(ref _exposure, Math.Round(value, 2));
}
- public bool IsValid => _layerHeight > 0 && _bottomExposure > 0 && _exposure > 0;
+ /// <summary>
+ /// Gets or sets the brightness level
+ /// </summary>
+ public byte Brightness
+ {
+ get => _brightness;
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _brightness, value)) return;
+ RaisePropertyChanged(nameof(BrightnessPercent));
+ }
+ }
+
+ public decimal BrightnessPercent => Math.Round(_brightness * 100m / byte.MaxValue, 2);
+
+ public bool IsValid => _layerHeight > 0 && _bottomExposure > 0 && _exposure > 0 && _brightness > 0;
public ExposureItem() { }
- public ExposureItem(decimal layerHeight, decimal bottomExposure = 0, decimal exposure = 0)
+ public ExposureItem(decimal layerHeight, decimal bottomExposure = 0, decimal exposure = 0, byte brightness = 255)
{
_layerHeight = Math.Round(layerHeight, 2);
_bottomExposure = Math.Round(bottomExposure, 2);
_exposure = Math.Round(exposure, 2);
+ _brightness = brightness;
}
public override string ToString()
{
- return $"{nameof(LayerHeight)}: {LayerHeight}mm, {nameof(BottomExposure)}: {BottomExposure}s, {nameof(Exposure)}: {Exposure}s";
+ return $"{nameof(LayerHeight)}: {_layerHeight}mm, {nameof(BottomExposure)}: {_bottomExposure}s, {nameof(Exposure)}: {_exposure}s, {nameof(Brightness)}: {_brightness} ({BrightnessPercent} %)";
}
private bool Equals(ExposureItem other)
{
- return _layerHeight == other._layerHeight && _bottomExposure == other._bottomExposure && _exposure == other._exposure;
+ return _layerHeight == other._layerHeight && _bottomExposure == other._bottomExposure && _exposure == other._exposure && _brightness == other._brightness;
}
public override bool Equals(object obj)
@@ -70,7 +82,7 @@ namespace UVtools.Core.Objects
public override int GetHashCode()
{
- return HashCode.Combine(_layerHeight, _bottomExposure, _exposure);
+ return HashCode.Combine(_layerHeight, _bottomExposure, _exposure, _brightness);
}
public int CompareTo(ExposureItem other)
@@ -81,7 +93,9 @@ namespace UVtools.Core.Objects
if (layerHeightComparison != 0) return layerHeightComparison;
var bottomExposureComparison = _bottomExposure.CompareTo(other._bottomExposure);
if (bottomExposureComparison != 0) return bottomExposureComparison;
- return _exposure.CompareTo(other._exposure);
+ var exposureComparison = _exposure.CompareTo(other._exposure);
+ if (exposureComparison != 0) return exposureComparison;
+ return _brightness.CompareTo(other._brightness);
}
}
}
diff --git a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs
index 0b3f789..3b77e81 100644
--- a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs
+++ b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs
@@ -34,6 +34,8 @@ namespace UVtools.Core.Operations
private decimal _normalExposure = 12;
private decimal _partScale = 1;
private byte _margin = 30;
+ private bool _extrudeText = true;
+ private decimal _textHeight = 1;
private bool _enableAntiAliasing = true;
private bool _mirrorOutput;
private bool _isErodeEnabled = true;
@@ -46,6 +48,7 @@ namespace UVtools.Core.Operations
private byte _dimmingEndBrightness = 200;
private byte _dimmingBrightnessSteps = 20;
private bool _outputOriginalPart = true;
+
#endregion
@@ -99,6 +102,7 @@ namespace UVtools.Core.Operations
var result = $"[Layer Height: {_layerHeight}] " +
$"[Layers: {_bottomLayers}/{_normalLayers}] " +
$"[Exposure: {_bottomExposure}/{_normalExposure}] " +
+ $"[Extrude: {_extrudeText} {_textHeight}mm]" +
$"[Scale: {_partScale}] [Margin: {_margin}] [ORI: {_outputOriginalPart}]" +
$"[E: {_erodeStartIteration}-{_erodeEndIteration} S{_erodeIterationSteps}] " +
$"[D: W{_dimmingWallThickness} B{_dimmingStartBrightness}-{_dimmingEndBrightness} S{_dimmingBrightnessSteps}] " +
@@ -170,7 +174,7 @@ namespace UVtools.Core.Operations
}
}
- public uint LayerCount => (uint)(_bottomLayers + _normalLayers);
+ public uint LayerCount => (uint)(_bottomLayers + _normalLayers + (_extrudeText ? Math.Floor(_textHeight / _layerHeight) : 0));
public decimal BottomHeight => Math.Round(LayerHeight * BottomLayers, 2);
public decimal NormalHeight => Math.Round(LayerHeight * NormalLayers, 2);
@@ -201,6 +205,18 @@ namespace UVtools.Core.Operations
set => RaiseAndSetIfChanged(ref _margin, value);
}
+ public bool ExtrudeText
+ {
+ get => _extrudeText;
+ set => RaiseAndSetIfChanged(ref _extrudeText, value);
+ }
+
+ public decimal TextHeight
+ {
+ get => _textHeight;
+ set => RaiseAndSetIfChanged(ref _textHeight, value);
+ }
+
public bool OutputOriginalPart
{
get => _outputOriginalPart;
@@ -354,10 +370,10 @@ namespace UVtools.Core.Operations
#endregion
#region Equality
-
+
private bool Equals(OperationCalibrateElephantFoot other)
{
- return _layerHeight == other._layerHeight && _syncLayers == other._syncLayers && _bottomLayers == other._bottomLayers && _normalLayers == other._normalLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _partScale == other._partScale && _margin == other._margin && _isErodeEnabled == other._isErodeEnabled && _erodeStartIteration == other._erodeStartIteration && _erodeEndIteration == other._erodeEndIteration && _erodeIterationSteps == other._erodeIterationSteps && _isDimmingEnabled == other._isDimmingEnabled && _dimmingWallThickness == other._dimmingWallThickness && _dimmingStartBrightness == other._dimmingStartBrightness && _dimmingEndBrightness == other._dimmingEndBrightness && _dimmingBrightnessSteps == other._dimmingBrightnessSteps && _outputOriginalPart == other._outputOriginalPart && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput;
+ return _layerHeight == other._layerHeight && _syncLayers == other._syncLayers && _bottomLayers == other._bottomLayers && _normalLayers == other._normalLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _partScale == other._partScale && _margin == other._margin && _extrudeText == other._extrudeText && _textHeight == other._textHeight && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _isErodeEnabled == other._isErodeEnabled && _erodeStartIteration == other._erodeStartIteration && _erodeEndIteration == other._erodeEndIteration && _erodeIterationSteps == other._erodeIterationSteps && _isDimmingEnabled == other._isDimmingEnabled && _dimmingWallThickness == other._dimmingWallThickness && _dimmingStartBrightness == other._dimmingStartBrightness && _dimmingEndBrightness == other._dimmingEndBrightness && _dimmingBrightnessSteps == other._dimmingBrightnessSteps && _outputOriginalPart == other._outputOriginalPart;
}
public override bool Equals(object obj)
@@ -376,8 +392,9 @@ namespace UVtools.Core.Operations
hashCode.Add(_normalExposure);
hashCode.Add(_partScale);
hashCode.Add(_margin);
+ hashCode.Add(_extrudeText);
+ hashCode.Add(_textHeight);
hashCode.Add(_enableAntiAliasing);
- hashCode.Add(_outputOriginalPart);
hashCode.Add(_mirrorOutput);
hashCode.Add(_isErodeEnabled);
hashCode.Add(_erodeStartIteration);
@@ -388,7 +405,7 @@ namespace UVtools.Core.Operations
hashCode.Add(_dimmingStartBrightness);
hashCode.Add(_dimmingEndBrightness);
hashCode.Add(_dimmingBrightnessSteps);
-
+ hashCode.Add(_outputOriginalPart);
return hashCode.ToHashCode();
}
@@ -402,11 +419,12 @@ namespace UVtools.Core.Operations
/// <returns></returns>
public Mat[] GetLayers()
{
- Mat[] layers = new Mat[2];
+ Mat[] layers = new Mat[3];
var anchor = new Point(-1, -1);
var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);
layers[0] = EmguExtensions.InitMat(SlicerFile.Resolution);
+ layers[2] = layers[0].Clone();
LineType lineType = _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected;
int length = (int) (250 * _partScale);
int triangleLength = (int) (50 * _partScale);
@@ -488,26 +506,41 @@ namespace UVtools.Core.Operations
void addText(Mat mat, ushort number, params string[] text)
{
- CvInvoke.PutText(mat, number.ToString(), new Point((int) (100 * _partScale), (int) (55 * _partScale)), font, 1.5 * (double) _partScale, EmguExtensions.BlackByte, (int) (4 * _partScale), lineType);
- CvInvoke.PutText(mat, "UVtools EP", new Point(fontStartX, fontStartY), font, 0.8 * (double) _partScale, EmguExtensions.BlackByte, (int) (2 * _partScale), lineType);
- CvInvoke.PutText(mat, $"{Microns}um", new Point(fontStartX, fontStartY + fontMargin), font, fontScale, EmguExtensions.BlackByte, fontThickness, lineType);
- CvInvoke.PutText(mat, $"{BottomExposure}|{NormalExposure}s", new Point(fontStartX, fontStartY + fontMargin * 2), font, fontScale, EmguExtensions.BlackByte, fontThickness, lineType);
+ var color = _extrudeText ? EmguExtensions.WhiteByte : EmguExtensions.BlackByte;
+ CvInvoke.PutText(mat, number.ToString(), new Point((int) (100 * _partScale), (int) (55 * _partScale)), font, 1.5 * (double) _partScale, color, (int) (4 * _partScale), lineType);
+ CvInvoke.PutText(mat, "UVtools EP", new Point(fontStartX, fontStartY), font, 0.8 * (double) _partScale, color, (int) (2 * _partScale), lineType);
+ CvInvoke.PutText(mat, $"{Microns}um", new Point(fontStartX, fontStartY + fontMargin), font, fontScale, color, fontThickness, lineType);
+ CvInvoke.PutText(mat, $"{BottomExposure}|{NormalExposure}s", new Point(fontStartX, fontStartY + fontMargin * 2), font, fontScale, color, fontThickness, lineType);
if (text is null) return;
for (var i = 0; i < text.Length; i++)
{
CvInvoke.PutText(mat, text[i], new Point(fontStartX, fontStartY + fontMargin * (i + 3)), font,
- fontScale, EmguExtensions.BlackByte, fontThickness, lineType);
+ fontScale, color, fontThickness, lineType);
}
}
ushort count = 0;
+ layers[1] = layers[0].Clone();
+
if (OutputOriginalPart)
{
- using var roi = new Mat(layers[0], new Rectangle(new Point(currentX, currentY), shape.Size));
- shape.CopyTo(roi);
- addText(roi, ++count, "ORI");
+ using var roi0 = new Mat(layers[0], new Rectangle(new Point(currentX, currentY), shape.Size));
+ shape.CopyTo(roi0);
+
+ using var roi1 = new Mat(layers[1], new Rectangle(new Point(currentX, currentY), shape.Size));
+ shape.CopyTo(roi1);
+
+ if (_extrudeText)
+ {
+ using var roi2 = new Mat(layers[2], new Rectangle(new Point(currentX, currentY), shape.Size));
+ addText(roi2, ++count, "ORI");
+ }
+ else
+ {
+ addText(roi1, ++count, "ORI");
+ }
}
else
{
@@ -515,7 +548,7 @@ namespace UVtools.Core.Operations
}
- layers[1] = layers[0].Clone();
+
if (IsErodeEnabled)
{
@@ -541,7 +574,16 @@ namespace UVtools.Core.Operations
using (var roi = new Mat(layers[1], new Rectangle(new Point(currentX, currentY), shape.Size)))
{
shape.CopyTo(roi);
- addText(roi, count, $"E: {iteration}i");
+ if (_extrudeText)
+ {
+ using var roi1 = new Mat(layers[2], new Rectangle(new Point(currentX, currentY), shape.Size));
+ addText(roi1, count, $"E: {iteration}i");
+ }
+ else
+ {
+ addText(roi, count, $"E: {iteration}i");
+ }
+
}
using (var roi = new Mat(layers[0],
@@ -550,7 +592,7 @@ namespace UVtools.Core.Operations
{
CvInvoke.Erode(shape, erode, ErodeKernel.Matrix, ErodeKernel.Anchor, iteration, BorderType.Reflect101, default);
erode.CopyTo(roi);
- addText(roi, count, $"E: {iteration}i");
+ //addText(roi, count, $"E: {iteration}i");
}
}
}
@@ -578,7 +620,15 @@ namespace UVtools.Core.Operations
using (var roi = new Mat(layers[1], new Rectangle(new Point(currentX, currentY), shape.Size)))
{
shape.CopyTo(roi);
- addText(roi, count, $"W: {DimmingWallThickness}", $"B: {brightness}");
+ if (_extrudeText)
+ {
+ using var roi1 = new Mat(layers[2], new Rectangle(new Point(currentX, currentY), shape.Size));
+ addText(roi1, count, $"W: {DimmingWallThickness}", $"B: {brightness}");
+ }
+ else
+ {
+ addText(roi, count, $"W: {DimmingWallThickness}", $"B: {brightness}");
+ }
}
using (var roi = new Mat(layers[0],
@@ -595,7 +645,7 @@ namespace UVtools.Core.Operations
CvInvoke.BitwiseAnd(diff, mask, target);
CvInvoke.Add(erode, target, target);
target.CopyTo(roi);
- addText(roi, count, $"W: {DimmingWallThickness}", $"B: {brightness}");
+ //addText(roi, count, $"W: {DimmingWallThickness}", $"B: {brightness}");
}
}
}
@@ -649,30 +699,46 @@ namespace UVtools.Core.Operations
progress++;
- var bottomLayer = new Layer(0, layers[0], SlicerFile.LayerManager)
- {
- IsModified = true
- };
+ var bottomLayer = new Layer(0, layers[0], SlicerFile.LayerManager);
+
+ Layer extrudeLayer = null;
+ var moveOp = new OperationMove(SlicerFile, bottomLayer.BoundingRectangle);
+ moveOp.Execute(layers[0]);
+ moveOp.Execute(layers[1]);
+
var layer = new Layer(0, layers[1], SlicerFile.LayerManager)
{
IsModified = true
};
- var moveOp = new OperationMove(SlicerFile, bottomLayer.BoundingRectangle);
- moveOp.Execute(layers[0]);
- moveOp.Execute(layers[1]);
+ if (_extrudeText)
+ {
+ moveOp.Execute(layers[2]);
+ extrudeLayer = new Layer(0, layers[2], SlicerFile.LayerManager)
+ {
+ IsModified = true
+ };
+
+ }
bottomLayer.LayerMat = layers[0];
- layer.LayerMat = layers[1];
progress++;
for (uint layerIndex = 0;
- layerIndex < LayerCount;
+ layerIndex < _bottomLayers + _normalLayers;
layerIndex++)
{
newLayers[layerIndex] = SlicerFile.GetInitialLayerValueOrNormal(layerIndex, bottomLayer.Clone(), layer.Clone());
}
+ if (_extrudeText)
+ {
+ for (uint layerIndex = (uint) (_bottomLayers + _normalLayers); layerIndex < LayerCount; layerIndex++)
+ {
+ newLayers[layerIndex] = extrudeLayer.Clone();
+ }
+ }
+
foreach (var mat in layers)
{
mat.Dispose();
diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
index f66a3e7..9fd4d25 100644
--- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
+++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
@@ -9,7 +9,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
@@ -45,7 +44,7 @@ namespace UVtools.Core.Operations
private decimal _bottomExposure = 60;
private decimal _normalExposure = 12;
private decimal _topBottomMargin = 5;
- private decimal _leftRightMargin = 5;
+ private decimal _leftRightMargin = 10;
private byte _chamferLayers = 5;
private byte _erodeBottomIterations = 0;
private decimal _partMargin = 0;
@@ -67,9 +66,16 @@ namespace UVtools.Core.Operations
private byte _textThickness = 2;
private string _text = "ABGHJKLMQRSTUVWXZ%&#";
+ private bool _multipleBrightness;
+ private CalibrateExposureFinderMultipleBrightnessExcludeFrom _multipleBrightnessExcludeFrom = CalibrateExposureFinderMultipleBrightnessExcludeFrom.BottomAndBase;
+ private string _multipleBrightnessValues = "255, 242, 230, 217, 204, 191";
+ private decimal _multipleBrightnessGenExposureTime;
+
+
private bool _multipleLayerHeight;
private decimal _multipleLayerHeightMaximum = 0.1m;
private decimal _multipleLayerHeightStep = 0.01m;
+
private bool _multipleExposures;
private ExposureGenTypes _exposureGenType = ExposureGenTypes.Linear;
private bool _exposureGenIgnoreBaseExposure;
@@ -82,7 +88,6 @@ namespace UVtools.Core.Operations
private ObservableCollection<ExposureItem> _exposureTable = new();
private CalibrateExposureFinderShapes _holeShape = CalibrateExposureFinderShapes.Square;
-
#endregion
#region Overrides
@@ -147,6 +152,14 @@ namespace UVtools.Core.Operations
}
}
+ if (_multipleBrightness)
+ {
+ if (MultipleBrightnessValuesArray.Length == 0)
+ {
+ sb.AppendLine($"[MB]: Multiple brightness tests are enabled but no valid values are set, use from 1 to 255.");
+ }
+ }
+
return new StringTag(sb.ToString());
}
@@ -220,13 +233,21 @@ namespace UVtools.Core.Operations
public decimal BottomExposure
{
get => _bottomExposure;
- set => RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2));
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2))) return;
+ RaisePropertyChanged(nameof(MultipleBrightnessTable));
+ }
}
public decimal NormalExposure
{
get => _normalExposure;
- set => RaiseAndSetIfChanged(ref _normalExposure, Math.Round(value, 2));
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _normalExposure, Math.Round(value, 2))) return;
+ RaisePropertyChanged(nameof(MultipleBrightnessTable));
+ }
}
public decimal TopBottomMargin
@@ -337,9 +358,9 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(mmStr)) continue;
if (!decimal.TryParse(mmStr, out var mm)) continue;
- if(mm <= 0) continue;
- var mmPx = (int) Math.Floor(mm * Ppmm);
- if(holes.Contains(mmPx) || mmPx > 500) continue;
+ var mmPx = (int)Math.Floor(mm * Ppmm);
+ if (mmPx <= 0 || mmPx > 500) continue;
+ if(holes.Contains(mmPx)) continue;
holes.Add((int)Math.Floor(mm * Ppmm));
}
}
@@ -350,8 +371,8 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(pxStr)) continue;
if (!int.TryParse(pxStr, out var px)) continue;
- if (px <= 0) continue;
- if (holes.Contains(px) || px > 500) continue;
+ if (px <= 0 || px > 500) continue;
+ if (holes.Contains(px)) continue;
holes.Add(px);
}
}
@@ -411,9 +432,9 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(mmStr)) continue;
if (!decimal.TryParse(mmStr, out var mm)) continue;
- if (mm <= 0) continue;
var mmPx = (int)Math.Floor(mm * Xppmm);
- if (bars.Contains(mmPx) || mmPx > 500) continue;
+ if (mmPx <= 0 || mmPx > 500) continue;
+ if (bars.Contains(mmPx)) continue;
bars.Add((int)Math.Floor(mm * Xppmm));
}
}
@@ -424,8 +445,8 @@ namespace UVtools.Core.Operations
{
if (string.IsNullOrWhiteSpace(pxStr)) continue;
if (!int.TryParse(pxStr, out var px)) continue;
- if (px <= 0) continue;
- if (bars.Contains(px) || px > 500) continue;
+ if (px <= 0 || px > 500) continue;
+ if (bars.Contains(px)) continue;
bars.Add(px);
}
}
@@ -475,6 +496,72 @@ namespace UVtools.Core.Operations
}
}
+ public bool MultipleBrightness
+ {
+ get => _multipleBrightness;
+ set => RaiseAndSetIfChanged(ref _multipleBrightness, value);
+ }
+
+ public CalibrateExposureFinderMultipleBrightnessExcludeFrom MultipleBrightnessExcludeFrom
+ {
+ get => _multipleBrightnessExcludeFrom;
+ set => RaiseAndSetIfChanged(ref _multipleBrightnessExcludeFrom, value);
+ }
+
+ public string MultipleBrightnessValues
+ {
+ get => _multipleBrightnessValues;
+ set
+ {
+ if(!RaiseAndSetIfChanged(ref _multipleBrightnessValues, value)) return;
+ RaisePropertyChanged(nameof(MultipleBrightnessTable));
+ }
+ }
+
+ public List<ExposureItem> MultipleBrightnessTable
+ {
+ get
+ {
+ var brightnesses = MultipleBrightnessValuesArray;
+ return brightnesses.Select(brightness => (ExposureItem)
+ new(
+ _layerHeight,
+ Math.Round(brightness * _bottomExposure / byte.MaxValue, 2),
+ Math.Round(brightness * _normalExposure / byte.MaxValue, 2),
+ brightness)).ToList();
+ }
+ }
+
+ public decimal MultipleBrightnessGenExposureTime
+ {
+ get => _multipleBrightnessGenExposureTime;
+ set => RaiseAndSetIfChanged(ref _multipleBrightnessGenExposureTime, value);
+ }
+
+ /// <summary>
+ /// Gets all holes in pixels and ordered
+ /// </summary>
+ public byte[] MultipleBrightnessValuesArray
+ {
+ get
+ {
+ List<byte> values = new();
+
+ var split = _multipleBrightnessValues.Split(',', StringSplitOptions.TrimEntries);
+ foreach (var brightnessStr in split)
+ {
+ if (string.IsNullOrWhiteSpace(brightnessStr)) continue;
+ if (!byte.TryParse(brightnessStr, out var brightness)) continue;
+ if (brightness <= 0 || brightness > 255) continue;
+ if (values.Contains(brightness)) continue;
+ values.Add(brightness);
+ }
+
+ return values.OrderByDescending(brightness => brightness).ToArray();
+ }
+ }
+
+
public bool MultipleLayerHeight
{
get => _multipleLayerHeight;
@@ -611,6 +698,10 @@ namespace UVtools.Core.Operations
_exposureGenManualBottom = (decimal) SlicerFile.BottomExposureTime;
if (_exposureGenManualNormal == 0)
_exposureGenManualNormal = (decimal)SlicerFile.ExposureTime;
+ if (_multipleBrightnessGenExposureTime == 0)
+ {
+ _multipleBrightnessGenExposureTime = (decimal)SlicerFile.ExposureTime;
+ }
if (!SlicerFile.HavePrintParameterPerLayerModifier(FileFormat.PrintParameterModifier.ExposureSeconds))
{
@@ -638,6 +729,14 @@ namespace UVtools.Core.Operations
public static Array MeasuresItems => Enum.GetValues(typeof(Measures));
+ public enum CalibrateExposureFinderMultipleBrightnessExcludeFrom : byte
+ {
+ None,
+ Bottom,
+ BottomAndBase
+ }
+ public static Array MultipleBrightnessExcludeFromItems => Enum.GetValues(typeof(CalibrateExposureFinderMultipleBrightnessExcludeFrom));
+
public enum ExposureGenTypes : byte
{
Linear,
@@ -649,11 +748,9 @@ namespace UVtools.Core.Operations
#region Equality
-
-
private bool Equals(OperationCalibrateExposureFinder other)
{
- return _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _unitOfMeasure == other._unitOfMeasure && _holeDiametersMm == other._holeDiametersMm && _holeDiametersPx == other._holeDiametersPx && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && _exposureGenManualLayerHeight == other._exposureGenManualLayerHeight && _exposureGenManualBottom == other._exposureGenManualBottom && _exposureGenManualNormal == other._exposureGenManualNormal && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape;
+ return _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape;
}
public override bool Equals(object obj)
@@ -679,8 +776,8 @@ namespace UVtools.Core.Operations
hashCode.Add(_featuresHeight);
hashCode.Add(_featuresMargin);
hashCode.Add((int) _unitOfMeasure);
- hashCode.Add(_holeDiametersMm);
hashCode.Add(_holeDiametersPx);
+ hashCode.Add(_holeDiametersMm);
hashCode.Add(_barSpacing);
hashCode.Add(_barLength);
hashCode.Add(_barVerticalSplitter);
@@ -690,6 +787,9 @@ namespace UVtools.Core.Operations
hashCode.Add(_textScale);
hashCode.Add(_textThickness);
hashCode.Add(_text);
+ hashCode.Add(_multipleBrightness);
+ hashCode.Add((int) _multipleBrightnessExcludeFrom);
+ hashCode.Add(_multipleBrightnessValues);
hashCode.Add(_multipleLayerHeight);
hashCode.Add(_multipleLayerHeightMaximum);
hashCode.Add(_multipleLayerHeightStep);
@@ -699,9 +799,6 @@ namespace UVtools.Core.Operations
hashCode.Add(_exposureGenBottomStep);
hashCode.Add(_exposureGenNormalStep);
hashCode.Add(_exposureGenTests);
- hashCode.Add(_exposureGenManualLayerHeight);
- hashCode.Add(_exposureGenManualBottom);
- hashCode.Add(_exposureGenManualNormal);
hashCode.Add(_exposureTable);
hashCode.Add((int) _holeShape);
return hashCode.ToHashCode();
@@ -1039,6 +1136,10 @@ namespace UVtools.Core.Operations
var anchor = new Point(-1, -1);
using var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);
+ var brightnesses = MultipleBrightnessValuesArray;
+
+ if (brightnesses.Length == 0 || !_multipleBrightness) brightnesses = new[] {byte.MaxValue};
+
void AddLayer(decimal currentHeight, decimal layerHeight, decimal bottomExposure, decimal normalExposure)
{
var layerDifference = currentHeight / layerHeight;
@@ -1046,59 +1147,96 @@ namespace UVtools.Core.Operations
if (!layerDifference.IsInteger()) return; // Not at right height to process with layer height
//Debug.WriteLine($"{currentHeight} / {layerHeight} = {layerDifference}, Floor={Math.Floor(layerDifference)}");
+ using Mat mat = EmguExtensions.InitMat(SlicerFile.Resolution);
+ int layerCountOnHeight = (int)Math.Floor(currentHeight / layerHeight);
+ bool isBottomLayer = layerCountOnHeight <= _bottomLayers;
+ bool isBaseLayer = currentHeight <= _baseHeight;
+ ushort microns = (ushort)Math.Floor(layerHeight * 1000);
Point position;
- ExposureItem key = new(layerHeight, bottomExposure, normalExposure);
+ bool addSomething = false;
- if (table.TryGetValue(key, out var pos))
- {
- position = pos;
- }
- else
+ foreach(var brightness in brightnesses)
{
- if (currentX + layers[0].Width + sideMarginPx > SlicerFile.ResolutionX)
+ var bottomExposureTemp = bottomExposure;
+ var normalExposureTemp = normalExposure;
+ ExposureItem key = new(layerHeight, bottomExposure, normalExposure, brightness);
+
+ if (table.TryGetValue(key, out var pos))
{
- currentX = sideMarginPx;
- currentY += layers[0].Height + (int)Math.Floor(_partMargin * Yppmm);
+ position = pos;
}
-
- if (currentY + layers[0].Height + topBottomMarginPx > SlicerFile.ResolutionY)
+ else
{
- return; // Reach the end
+ if (currentX + layers[0].Width + sideMarginPx > SlicerFile.ResolutionX)
+ {
+ currentX = sideMarginPx;
+ currentY += layers[0].Height + (int)Math.Floor(_partMargin * Yppmm);
+ }
+
+ if (currentY + layers[0].Height + topBottomMarginPx > SlicerFile.ResolutionY)
+ {
+ break; // Reach the end
+ }
+
+ position = new Point(currentX, currentY);
+ table.Add(key, new Point(currentX, currentY));
+
+ currentX += layers[0].Width + (int)Math.Floor(_partMargin * Xppmm);
}
- position = new Point(currentX, currentY);
- table.Add(key, new Point(currentX, currentY));
+
+ Mat matRoi = new(mat, new Rectangle(position, layers[0].Size));
- currentX += layers[0].Width + (int)Math.Floor(_partMargin * Xppmm);
- }
+ layers[isBaseLayer ? 0 : 1].CopyTo(matRoi);
- ushort microns = (ushort)Math.Floor(layerHeight * 1000);
+ if (isBottomLayer && _erodeBottomIterations > 0)
+ {
+ CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default);
+ }
- Mat mat = EmguExtensions.InitMat(SlicerFile.Resolution);
- Mat matRoi = new(mat, new Rectangle(position, layers[0].Size));
+ if (layerCountOnHeight < _chamferLayers)
+ {
+ CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
+ }
- int layerCountOnHeight = (int)Math.Floor(currentHeight / layerHeight);
- bool isBottomLayer = layerCountOnHeight <= _bottomLayers;
- bool isBaseLayer = currentHeight <= _baseHeight;
- layers[isBaseLayer ? 0 : 1].CopyTo(matRoi);
+ if (_multipleBrightness && brightness < 255)
+ {
+ // normalExposure - 255
+ // x - brightness
+ normalExposureTemp = Math.Round(normalExposure * brightness / byte.MaxValue, 2);
+ if (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None)
+ {
+ bottomExposureTemp = Math.Round(bottomExposure * brightness / byte.MaxValue, 2);
+ }
+ }
- if (isBottomLayer && _erodeBottomIterations > 0)
- {
- CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default);
- }
+ var textHeightStart = matRoi.Height - featuresMarginY - TextMarkingSpacing;
+ CvInvoke.PutText(matRoi, $"{microns}u", new Point(TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{microns}u", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{bottomExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ CvInvoke.PutText(matRoi, $"{normalExposureTemp}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- if (layerCountOnHeight < _chamferLayers)
- {
- CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
+ if(_multipleBrightness)
+ {
+ CvInvoke.PutText(matRoi, brightness.ToString(), new Point(matRoi.Width / 3, 35), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ if (brightness < 255 &&
+ (_multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.None ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.Bottom && !isBottomLayer ||
+ _multipleBrightnessExcludeFrom == CalibrateExposureFinderMultipleBrightnessExcludeFrom.BottomAndBase && !isBottomLayer && !isBaseLayer)
+ )
+ {
+ using var pattern = matRoi.CloneBlank();
+ pattern.SetTo(new MCvScalar(brightness));
+ CvInvoke.BitwiseAnd(matRoi, pattern, matRoi, matRoi);
+ }
+ }
+
+ addSomething = true;
}
- var textHeightStart = matRoi.Height - featuresMarginY - TextMarkingSpacing;
- CvInvoke.PutText(matRoi, $"{microns}u", new Point(TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{bottomExposure}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{normalExposure}s", new Point(TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.WhiteByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{microns}u", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{bottomExposure}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- CvInvoke.PutText(matRoi, $"{normalExposure}s", new Point(matRoi.Width - featuresMarginX * 2 - holes[^1] + TextMarkingStartX, textHeightStart + TextMarkingLineBreak * 2), TextMarkingFontFace, TextMarkingScale, EmguExtensions.BlackByte, TextMarkingThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
+ if (!addSomething) return;
Layer layer = new(layerIndex++, mat, SlicerFile)
{
@@ -1112,7 +1250,6 @@ namespace UVtools.Core.Operations
IsModified = true
};
newLayers.Add(layer);
- mat.Dispose();
progress++;
}
diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs
index 86b2b94..c85273d 100644
--- a/UVtools.Core/Operations/OperationLayerImport.cs
+++ b/UVtools.Core/Operations/OperationLayerImport.cs
@@ -11,6 +11,7 @@ using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
@@ -304,37 +305,43 @@ namespace UVtools.Core.Operations
{
case ImportTypes.Insert:
if (SlicerFile.Resolution != fileFormat.Resolution &&
- (SlicerFile.Resolution.Width < fileFormat.LayerManager.BoundingRectangle.Width ||
- SlicerFile.Resolution.Height < fileFormat.LayerManager.BoundingRectangle.Height)) continue;
+ (SlicerFile.Resolution.Width < fileFormatBoundingRectangle.Width ||
+ SlicerFile.Resolution.Height < fileFormatBoundingRectangle.Height)) continue;
SlicerFile.LayerManager.Reallocate(_startLayerIndex, fileFormat.LayerCount);
break;
case ImportTypes.Replace:
case ImportTypes.Stack:
if (SlicerFile.Resolution != fileFormat.Resolution &&
- (SlicerFile.Resolution.Width < fileFormat.LayerManager.BoundingRectangle.Width ||
- SlicerFile.Resolution.Height < fileFormat.LayerManager.BoundingRectangle.Height)) continue;
+ (SlicerFile.Resolution.Width < fileFormatBoundingRectangle.Width ||
+ SlicerFile.Resolution.Height < fileFormatBoundingRectangle.Height)) continue;
- if(fileFormatBoundingRectangle.Width >= SlicerFile.ResolutionX || fileFormatBoundingRectangle.Height >= SlicerFile.ResolutionY)
- continue;
+ //if(fileFormatBoundingRectangle.Width >= SlicerFile.ResolutionX || fileFormatBoundingRectangle.Height >= SlicerFile.ResolutionY)
+ // continue;
- int x = 0;
- int y = 0;
-
- if (boundingRectangle.Right + _stackMargin + fileFormatBoundingRectangle.Width <
- SlicerFile.ResolutionX)
- {
- x = boundingRectangle.Right + _stackMargin;
- }
- else
+ if (_importType == ImportTypes.Stack)
{
- y = boundingRectangle.Bottom + _stackMargin;
- }
+ int x = 0;
+ int y = 0;
+
+ if (boundingRectangle.Right + _stackMargin + fileFormatBoundingRectangle.Width <
+ SlicerFile.ResolutionX)
+ {
+ x = boundingRectangle.Right + _stackMargin;
+ }
+ else
+ {
+ y = boundingRectangle.Bottom + _stackMargin;
+ }
- if (y >= SlicerFile.ResolutionY)
- continue;
+ if (x + fileFormatBoundingRectangle.Width >= SlicerFile.ResolutionX)
+ continue;
+ if (y + fileFormatBoundingRectangle.Height >= SlicerFile.ResolutionY)
+ continue;
- roiRectangle = new Rectangle(x, y, fileFormatBoundingRectangle.Width, fileFormatBoundingRectangle.Height);
+ roiRectangle = new Rectangle(x, y, fileFormatBoundingRectangle.Width,
+ fileFormatBoundingRectangle.Height);
+ }
if (_extendBeyondLayerCount)
{
@@ -385,7 +392,7 @@ namespace UVtools.Core.Operations
}
using var layer = fileFormat[i].LayerMat;
- using var layerRoi = layer.RoiFromCenter(SlicerFile.Resolution);
+ using var layerRoi = layer.RoiFromCenter(SlicerFile.Resolution, fileFormatBoundingRectangle);
SlicerFile[layerIndex] = new Layer(layerIndex, layerRoi, SlicerFile);
break;
@@ -400,7 +407,7 @@ namespace UVtools.Core.Operations
}
using var layer = fileFormat[i].LayerMat;
- using var layerRoi = layer.RoiFromCenter(SlicerFile.Resolution);
+ using var layerRoi = layer.RoiFromCenter(SlicerFile.Resolution, fileFormatBoundingRectangle);
SlicerFile[layerIndex] = new Layer(layerIndex, layerRoi, SlicerFile);
break;
}
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index de882cc..e9bad39 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>2.4.5</Version>
+ <Version>2.4.6</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml
index c424156..badccba 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateElephantFootControl.axaml
@@ -9,7 +9,7 @@
<Grid ColumnDefinitions="Auto,10,350">
<StackPanel Spacing="10">
<Grid
- 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,10,Auto"
ColumnDefinitions="Auto,10,150,5,Auto,20,Auto,10,150,5,Auto"
>
@@ -21,8 +21,7 @@
Minimum="0.01"
Maximum="0.30"
FormatString="F02"
- Value="{Binding Operation.LayerHeight}"
- />
+ Value="{Binding Operation.LayerHeight}"/>
<TextBlock Grid.Row="0" Grid.Column="4"
VerticalAlignment="Center"
Text="mm"/>
@@ -110,7 +109,6 @@
VerticalAlignment="Center"
Text="Margin:"/>
<NumericUpDown Grid.Row="6" Grid.Column="8"
-
Increment="1"
Minimum="0"
Maximum="255"
@@ -119,7 +117,35 @@
VerticalAlignment="Center"
Text="px"/>
- <StackPanel Grid.Row="8" Grid.Column="0"
+ <TextBlock Grid.Row="8" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Markings:"/>
+
+ <ToggleSwitch Grid.Row="8" Grid.Column="2"
+ Grid.ColumnSpan="2"
+ OffContent="Intrude text" OnContent="Extrude text"
+ IsChecked="{Binding Operation.ExtrudeText}"/>
+
+ <TextBlock Grid.Row="8" Grid.Column="6"
+ VerticalAlignment="Center"
+ IsEnabled="{Binding Operation.ExtrudeText}"
+ Text="Text height:"/>
+
+ <NumericUpDown Grid.Row="8" Grid.Column="8"
+ Increment="0.5"
+ Minimum="0.5"
+ Maximum="10"
+ FormatString="F2"
+ IsEnabled="{Binding Operation.ExtrudeText}"
+ Value="{Binding Operation.TextHeight}"/>
+
+ <TextBlock Grid.Row="8" Grid.Column="10"
+ VerticalAlignment="Center"
+ IsEnabled="{Binding Operation.ExtrudeText}"
+ Text="mm"/>
+
+
+ <StackPanel Grid.Row="10" Grid.Column="0"
VerticalAlignment="Center"
Spacing="0">
<TextBlock
@@ -132,7 +158,7 @@
</StackPanel>
- <StackPanel Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="9"
+ <StackPanel Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="9"
VerticalAlignment="Center"
Spacing="0">
<TextBlock FontWeight="Bold">
@@ -149,17 +175,17 @@
Text="{Binding Operation.ObjectCount}"/>
</StackPanel>
- <CheckBox Grid.Row="8" Grid.Column="6"
+ <CheckBox Grid.Row="10" Grid.Column="6"
Grid.ColumnSpan="5"
IsChecked="{Binding Operation.EnableAntiAliasing}"
Content="Enable Anti-Aliasing" />
-
- <CheckBox Grid.Row="10" Grid.Column="0"
+
+ <CheckBox Grid.Row="12" Grid.Column="0"
Grid.ColumnSpan="6"
IsChecked="{Binding Operation.OutputOriginalPart}"
Content="Output an unmodified part (The original)" />
- <CheckBox Grid.Row="10" Grid.Column="6"
+ <CheckBox Grid.Row="12" Grid.Column="6"
Grid.ColumnSpan="5"
ToolTip.Tip="Most of the printers requires a mirror output to print with the correct orientation"
IsChecked="{Binding Operation.MirrorOutput}"
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
index f375bff..507a922 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
@@ -415,6 +415,119 @@
</Expander>
</Border>
+ <Border BorderBrush="Black"
+ BorderThickness="1"
+ Padding="5">
+ <Expander IsExpanded="True">
+ <Expander.Header>
+ <TextBlock Text="Multiple brightness"
+ FontWeight="Bold"
+ Cursor="Hand"/>
+
+ </Expander.Header>
+
+ <StackPanel Spacing="10">
+
+ <TextBlock Text="Only printers able to do Anti-Aliasing and enabled on file can support this, make sure your is supported or else it can print a full white or full black model.
+&#x0a;Also take into consideration some printers/formats have fixed usable AA levels and all in between will be threshold, study this first.
+&#x0a;If your printer is able to do 'Multiple exposures times per layer', please use that method instead of this (More accurate and AA threshold free)."/>
+
+ <CheckBox
+ Content="Enable - For advanced users only!"
+ IsChecked="{Binding Operation.MultipleBrightness}"/>
+
+ <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,200,5,Auto,20,Auto,10,Auto,5,Auto,5,Auto"
+ IsEnabled="{Binding Operation.MultipleBrightness}">
+
+ <TextBlock Grid.Row="0" Grid.Column="0"
+ ToolTip.Tip="Do not change brightness from the selected layers. Full brightness of 255 is applied to the skip layers."
+ Text="Exclude from:"
+ VerticalAlignment="Center"/>
+ <ComboBox Grid.Row="0" Grid.Column="2"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Stretch"
+ Items="{Binding Operation.MultipleBrightnessExcludeFromItems}"
+ SelectedItem="{Binding Operation.MultipleBrightnessExcludeFrom}"/>
+ <TextBlock Grid.Row="0" Grid.Column="4"
+ Text="layers"
+ VerticalAlignment="Center"/>
+
+ <TextBlock Grid.Row="0" Grid.Column="6"
+ ToolTip.Tip="Append a brightness level to the list by giving a desired exposure time. Supplied time must be lower than the commun exposure time or you need to increase it on the commun 'Normal Exposure'."
+ Text="Generate by exposure time:"
+ VerticalAlignment="Center"/>
+
+ <NumericUpDown Grid.Row="0" Grid.Column="8"
+ Increment="0.10"
+ Minimum="0.10"
+ Maximum="{Binding Operation.NormalExposure}"
+ FormatString="F02"
+ Value="{Binding Operation.MultipleBrightnessGenExposureTime}"/>
+
+ <TextBlock Grid.Row="0" Grid.Column="10"
+ Text="s"
+ VerticalAlignment="Center"/>
+
+ <Button
+ Grid.Row="0" Grid.Column="12" VerticalContentAlignment="Center"
+ HorizontalContentAlignment="Center"
+ VerticalAlignment="Stretch"
+ Command="{Binding BrightnessExposureGenAdd}">
+ <StackPanel Orientation="Horizontal" Spacing="10">
+ <Image Source="/Assets/Icons/plus-16x16.png"/>
+ <TextBlock
+ VerticalAlignment="Center"
+ Text="Add"/>
+ </StackPanel>
+ </Button>
+
+ <TextBlock Grid.Row="2" Grid.Column="0"
+ Text="Brightnesses:"
+ ToolTip.Tip="From 1-255, where 1 is almost black and 255 is full white. No half numbers are allowed."
+ VerticalAlignment="Center"/>
+
+ <TextBox Grid.Row="2" Grid.Column="2"
+ Grid.ColumnSpan="11"
+ Text="{Binding Operation.MultipleBrightnessValues}"/>
+ </Grid>
+
+
+ <DataGrid
+ Name="BrightnessTable"
+ CanUserReorderColumns="True"
+ CanUserResizeColumns="True"
+ CanUserSortColumns="True"
+ GridLinesVisibility="Horizontal"
+ IsReadOnly="True"
+ ClipboardCopyMode="IncludeHeader"
+ VerticalAlignment="Stretch"
+ Margin="0,-10,0,0"
+ IsEnabled="{Binding Operation.MultipleBrightness}"
+ Items="{Binding Operation.MultipleBrightnessTable}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="Brightness"
+ Binding="{Binding Brightness}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Percent (%)"
+ Binding="{Binding BrightnessPercent}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Bottom exposure (s)"
+ Binding="{Binding BottomExposure}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Exposure (s)"
+ Binding="{Binding Exposure}"
+ Width="Auto" />
+ </DataGrid.Columns>
+
+ </DataGrid>
+
+
+
+ </StackPanel>
+ </Expander>
+ </Border>
+
<Border BorderBrush="Black"
BorderThickness="1"
Padding="5"
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
index e92c190..4a901ed 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
using System.Timers;
using Avalonia;
@@ -7,6 +8,7 @@ using Avalonia.Media.Imaging;
using Avalonia.Threading;
using DynamicData;
using MessageBox.Avalonia.Enums;
+using UVtools.Core.Extensions;
using UVtools.Core.FileFormats;
using UVtools.Core.Objects;
using UVtools.Core.Operations;
@@ -83,6 +85,18 @@ namespace UVtools.WPF.Controls.Calibrators
}
}
+ public void BrightnessExposureGenAdd()
+ {
+ var values = Operation.MultipleBrightnessValuesArray.ToList();
+ // normal exposure - 255
+ // wanted - x
+ byte brightness = (byte)Math.Round(Operation.MultipleBrightnessGenExposureTime * byte.MaxValue / Operation.NormalExposure).Clamp(1, byte.MaxValue);
+ if (values.Contains(brightness)) return;
+ values.Add(brightness);
+ values.Sort((b, b1) => b1.CompareTo(b));
+ Operation.MultipleBrightnessValues = string.Join(", ", values);
+ }
+
public async void GenerateExposureTable()
{
if (Operation.ExposureTable.Count > 0)
diff --git a/UVtools.WPF/Program.cs b/UVtools.WPF/Program.cs
index 2045a79..26e70d7 100644
--- a/UVtools.WPF/Program.cs
+++ b/UVtools.WPF/Program.cs
@@ -22,8 +22,7 @@ namespace UVtools.WPF
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
- BuildAvaloniaApp()
- .StartWithClassicDesktopLifetime(args);
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
private static async void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
@@ -45,8 +44,8 @@ namespace UVtools.WPF
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
- .With(new Win32PlatformOptions { AllowEglInitialization = true})
- .With(new X11PlatformOptions { UseGpu = true, UseEGL = true })
+ .With(new Win32PlatformOptions { AllowEglInitialization = true/*, UseWgl = true*/})
+ .With(new X11PlatformOptions { UseGpu = true/*, UseEGL = true*/ })
.With(new MacOSPlatformOptions { ShowInDock = true })
.With(new AvaloniaNativePlatformOptions { UseGpu = true })
.UseSkia()
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index ddc666e..170a4a5 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
- <Version>2.4.5</Version>
+ <Version>2.4.6</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml.cs b/UVtools.WPF/Windows/SettingsWindow.axaml.cs
index 8cbcd29..edc4bc4 100644
--- a/UVtools.WPF/Windows/SettingsWindow.axaml.cs
+++ b/UVtools.WPF/Windows/SettingsWindow.axaml.cs
@@ -86,12 +86,15 @@ namespace UVtools.WPF.Windows
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
- SizeToContent = SizeToContent.Manual;
+ //SizeToContent = SizeToContent.Manual;
Position = new PixelPoint(
(int)(App.MainWindow.Position.X + App.MainWindow.Width / 2 - Width / 2),
App.MainWindow.Position.Y + 20
);
+
+ SelectedTabIndex = 1;
+ SelectedTabIndex = 0;
}
protected override void OnClosed(EventArgs e)