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-07 10:27:28 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2021-02-07 10:27:28 +0300
commit6c6b4251dbe1b8a91836c4cdf683191d9baf9a7f (patch)
tree28afa29deded9d5c3e94d9cd9e4b729e03a55ec9
parent0ba61780b7ba662814b040d43bcf60847955ba18 (diff)
v2.4.1v2.4.1
* **(Fix) Exposure time finder:** * Use a spiral square instead of configurable shapes to match the exact precise set pixels * Set pixels as default values * Optimized the pixel values to always produce a closed shape * Rename cylinder to hole * Crash when diameters are empty * Profiles was not saving
-rw-r--r--CHANGELOG.md11
-rw-r--r--UVtools.Core/Objects/ExposureItem.cs87
-rw-r--r--UVtools.Core/Operations/OperationCalibrateExposureFinder.cs369
-rw-r--r--UVtools.Core/Operations/OperationDynamicLayerHeight.cs50
-rw-r--r--UVtools.Core/UVtools.Core.csproj2
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml25
-rw-r--r--UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs12
-rw-r--r--UVtools.WPF/Structures/OperationProfiles.cs1
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj2
9 files changed, 248 insertions, 311 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42d7f3b..599ba09 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
# Changelog
+## 07/02/2021 - v2.4.1
+
+* **(Fix) Exposure time finder:**
+ * Use a spiral square instead of configurable shapes to match the exact precise set pixels
+ * Set pixels as default values
+ * Optimized the pixel values to always produce a closed shape
+ * Rename cylinder to hole
+ * Crash when diameters are empty
+ * Profiles was not saving
+
+
## 06/02/2021 - v2.4.0
* (Upgrade) EmguCV/OpenCV to v4.5.1
diff --git a/UVtools.Core/Objects/ExposureItem.cs b/UVtools.Core/Objects/ExposureItem.cs
new file mode 100644
index 0000000..374a567
--- /dev/null
+++ b/UVtools.Core/Objects/ExposureItem.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UVtools.Core.Objects
+{
+ [Serializable]
+ public sealed class ExposureItem : BindableBase, IComparable<ExposureItem>
+ {
+ private decimal _layerHeight;
+ private decimal _bottomExposure;
+ private decimal _exposure;
+
+
+ /// <summary>
+ /// Gets or sets the layer height in millimeters
+ /// </summary>
+ public decimal LayerHeight
+ {
+ get => _layerHeight;
+ set => RaiseAndSetIfChanged(ref _layerHeight, Math.Round(value, 2));
+ }
+
+
+ /// <summary>
+ /// Gets or sets the bottom exposure in seconds
+ /// </summary>
+ public decimal BottomExposure
+ {
+ get => _bottomExposure;
+ set => RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2));
+ }
+
+ /// <summary>
+ /// Gets or sets the bottom exposure in seconds
+ /// </summary>
+ public decimal Exposure
+ {
+ get => _exposure;
+ set => RaiseAndSetIfChanged(ref _exposure, Math.Round(value, 2));
+ }
+
+ public bool IsValid => _layerHeight > 0 && _bottomExposure > 0 && _exposure > 0;
+
+ public ExposureItem() { }
+
+ public ExposureItem(decimal layerHeight, decimal bottomExposure = 0, decimal exposure = 0)
+ {
+ _layerHeight = Math.Round(layerHeight, 2);
+ _bottomExposure = Math.Round(bottomExposure, 2);
+ _exposure = Math.Round(exposure, 2);
+ }
+
+ public override string ToString()
+ {
+ return $"{nameof(LayerHeight)}: {LayerHeight}mm, {nameof(BottomExposure)}: {BottomExposure}s, {nameof(Exposure)}: {Exposure}s";
+ }
+
+ private bool Equals(ExposureItem other)
+ {
+ return _layerHeight == other._layerHeight && _bottomExposure == other._bottomExposure && _exposure == other._exposure;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return ReferenceEquals(this, obj) || obj is ExposureItem other && Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(_layerHeight, _bottomExposure, _exposure);
+ }
+
+ public int CompareTo(ExposureItem other)
+ {
+ if (ReferenceEquals(this, other)) return 0;
+ if (ReferenceEquals(null, other)) return 1;
+ var layerHeightComparison = _layerHeight.CompareTo(other._layerHeight);
+ if (layerHeightComparison != 0) return layerHeightComparison;
+ var bottomExposureComparison = _bottomExposure.CompareTo(other._bottomExposure);
+ if (bottomExposureComparison != 0) return bottomExposureComparison;
+ return _exposure.CompareTo(other._exposure);
+ }
+ }
+}
diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
index 183d20e..7342149 100644
--- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
+++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs
@@ -13,7 +13,6 @@ using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
@@ -26,89 +25,6 @@ namespace UVtools.Core.Operations
[Serializable]
public sealed class OperationCalibrateExposureFinder : Operation
{
- #region Sub classes
-
- [Serializable]
- public sealed class ExposureItem : BindableBase, IComparable<ExposureItem>
- {
- private decimal _layerHeight;
- private decimal _bottomExposure;
- private decimal _exposure;
-
-
- /// <summary>
- /// Gets or sets the layer height in millimeters
- /// </summary>
- public decimal LayerHeight
- {
- get => _layerHeight;
- set => RaiseAndSetIfChanged(ref _layerHeight, Math.Round(value, 2));
- }
-
-
- /// <summary>
- /// Gets or sets the bottom exposure in seconds
- /// </summary>
- public decimal BottomExposure
- {
- get => _bottomExposure;
- set => RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2));
- }
-
- /// <summary>
- /// Gets or sets the bottom exposure in seconds
- /// </summary>
- public decimal Exposure
- {
- get => _exposure;
- set => RaiseAndSetIfChanged(ref _exposure, Math.Round(value, 2));
- }
-
- public bool IsValid => _layerHeight > 0 && _bottomExposure > 0 && _exposure > 0;
-
- public ExposureItem() { }
-
- public ExposureItem(decimal layerHeight, decimal bottomExposure = 0, decimal exposure = 0)
- {
- _layerHeight = Math.Round(layerHeight, 2);
- _bottomExposure = Math.Round(bottomExposure, 2);
- _exposure = Math.Round(exposure, 2);
- }
-
- public override string ToString()
- {
- return $"{nameof(LayerHeight)}: {LayerHeight}mm, {nameof(BottomExposure)}: {BottomExposure}s, {nameof(Exposure)}: {Exposure}s";
- }
-
- private bool Equals(ExposureItem other)
- {
- return _layerHeight == other._layerHeight && _bottomExposure == other._bottomExposure && _exposure == other._exposure;
- }
-
- public override bool Equals(object obj)
- {
- return ReferenceEquals(this, obj) || obj is ExposureItem other && Equals(other);
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(_layerHeight, _bottomExposure, _exposure);
- }
-
- public int CompareTo(ExposureItem other)
- {
- if (ReferenceEquals(this, other)) return 0;
- if (ReferenceEquals(null, other)) return 1;
- var layerHeightComparison = _layerHeight.CompareTo(other._layerHeight);
- if (layerHeightComparison != 0) return layerHeightComparison;
- var bottomExposureComparison = _bottomExposure.CompareTo(other._bottomExposure);
- if (bottomExposureComparison != 0) return bottomExposureComparison;
- return _exposure.CompareTo(other._exposure);
- }
- }
-
- #endregion
-
#region Constants
const byte TextSpacing = 60;
@@ -136,16 +52,15 @@ namespace UVtools.Core.Operations
private bool _enableAntiAliasing = true;
private bool _mirrorOutput;
private decimal _baseHeight = 1;
- private decimal _cylinderHeight = 1;
- private decimal _cylinderMargin = 1.5m;
- private Measures _unitOfMeasure = Measures.Millimeters;
- private string _cylinderDiametersMm = "0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0";
- private string _cylinderDiametersPx = "1, 2, 3, 4, 5, 7, 10 ,15, 20";
+ private decimal _holeHeight = 1;
+ private decimal _holeMargin = 1.5m;
+ private Measures _unitOfMeasure = Measures.Pixels;
+ private string _holeDiametersMm = "0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0";
+ private string _holeDiametersPx = "1, 2, 4, 6, 9, 12, 16, 20, 25, 30, 36";
private bool _multipleLayerHeight;
private decimal _multipleLayerHeightMaximum = 0.1m;
private decimal _multipleLayerHeightStep = 0.01m;
private bool _multipleExposures;
- private Shapes _shape = Shapes.Circle;
private ExposureGenTypes _exposureGenType = ExposureGenTypes.Linear;
private bool _exposureGenIgnoreBaseExposure;
private decimal _exposureGenBottomStep = 0.5m;
@@ -194,7 +109,7 @@ namespace UVtools.Core.Operations
sb.AppendLine("Display height must be a positive value.");
}
- if (Cylinders.Length <= 0)
+ if (Holes.Length <= 0)
{
sb.AppendLine("No objects to output.");
}
@@ -228,10 +143,10 @@ namespace UVtools.Core.Operations
var result = $"[Layer Height: {_layerHeight}] " +
$"[Bottom layers: {_bottomLayers}] " +
$"[Exposure: {_bottomExposure}/{_normalExposure}] " +
- $"[TB:{_topBottomMargin} LR:{_leftRightMargin} PM:{_partMargin} CM:{_cylinderMargin}] " +
+ $"[TB:{_topBottomMargin} LR:{_leftRightMargin} PM:{_partMargin} CM:{_holeMargin}] " +
$"[Chamfer: {_chamferLayers}] [Erode: {_erodeBottomIterations}] " +
- $"[Obj height: {_cylinderHeight}] " +
- $"[Cylinders: {Cylinders.Length}] " +
+ $"[Obj height: {_holeHeight}] " +
+ $"[Holes: {Holes.Length}] " +
$"[AA: {_enableAntiAliasing}] [Mirror: {_mirrorOutput}]";
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
@@ -350,19 +265,19 @@ namespace UVtools.Core.Operations
set => RaiseAndSetIfChanged(ref _baseHeight, Math.Round(value, 2));
}
- public decimal CylinderHeight
+ public decimal HoleHeight
{
- get => _cylinderHeight;
- set => RaiseAndSetIfChanged(ref _cylinderHeight, Math.Round(value, 2));
+ get => _holeHeight;
+ set => RaiseAndSetIfChanged(ref _holeHeight, Math.Round(value, 2));
}
- public decimal CylinderMargin
+ public decimal HoleMargin
{
- get => _cylinderMargin;
- set => RaiseAndSetIfChanged(ref _cylinderMargin, Math.Round(value, 2));
+ get => _holeMargin;
+ set => RaiseAndSetIfChanged(ref _holeMargin, Math.Round(value, 2));
}
- public decimal TotalHeight => BaseHeight + CylinderHeight;
+ public decimal TotalHeight => BaseHeight + HoleHeight;
public Measures UnitOfMeasure
{
@@ -376,66 +291,60 @@ namespace UVtools.Core.Operations
public bool IsUnitOfMeasureMm => _unitOfMeasure == Measures.Millimeters;
- public string CylinderDiametersMm
+ public string HoleDiametersMm
{
- get => _cylinderDiametersMm;
- set => RaiseAndSetIfChanged(ref _cylinderDiametersMm, value);
+ get => _holeDiametersMm;
+ set => RaiseAndSetIfChanged(ref _holeDiametersMm, value);
}
- public string CylinderDiametersPx
+ public string HoleDiametersPx
{
- get => _cylinderDiametersPx;
- set => RaiseAndSetIfChanged(ref _cylinderDiametersPx, value);
+ get => _holeDiametersPx;
+ set => RaiseAndSetIfChanged(ref _holeDiametersPx, value);
}
/// <summary>
- /// Gets all cylinders in pixels and ordered
+ /// Gets all holes in pixels and ordered
/// </summary>
- public int[] Cylinders
+ public int[] Holes
{
get
{
- List<int> cylinders = new();
+ List<int> holes = new();
if (_unitOfMeasure == Measures.Millimeters)
{
- var split = _cylinderDiametersMm.Split(',', StringSplitOptions.TrimEntries);
+ var split = _holeDiametersMm.Split(',', StringSplitOptions.TrimEntries);
foreach (var mmStr in split)
{
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(cylinders.Contains(mmPx)) continue;
- cylinders.Add((int)Math.Floor(mm * Ppmm));
+ if(holes.Contains(mmPx) || mmPx > 500) continue;
+ holes.Add((int)Math.Floor(mm * Ppmm));
}
}
else
{
- var split = _cylinderDiametersPx.Split(',', StringSplitOptions.TrimEntries);
+ var split = _holeDiametersPx.Split(',', StringSplitOptions.TrimEntries);
foreach (var pxStr in split)
{
if (string.IsNullOrWhiteSpace(pxStr)) continue;
if (!int.TryParse(pxStr, out var px)) continue;
if (px <= 0) continue;
- if (cylinders.Contains(px)) continue;
- cylinders.Add(px);
+ if (holes.Contains(px) || px > 500) continue;
+ holes.Add(px);
}
}
- return cylinders.OrderBy(pixels => pixels).ToArray();
+ return holes.OrderBy(pixels => pixels).ToArray();
}
}
- public Shapes Shape
- {
- get => _shape;
- set => RaiseAndSetIfChanged(ref _shape, value);
- }
-
- public int GetCylindersLength(int[] cylinders)
+ public int GetHolesLength(int[] holes)
{
- return (int) (cylinders.Sum() + (cylinders.Length-1) * _cylinderMargin * Yppmm);
+ return (int) (holes.Sum(i => Math.Sqrt(i)) + (double) ((holes.Length-1) * _holeMargin * Yppmm));
}
public bool MultipleLayerHeight
@@ -588,20 +497,12 @@ namespace UVtools.Core.Operations
public enum Measures : byte
{
- Millimeters,
Pixels,
+ Millimeters,
}
public static Array MeasuresItems => Enum.GetValues(typeof(Measures));
- public enum Shapes : byte
- {
- Circle,
- Square
- }
-
- public static Array ShapesItems => Enum.GetValues(typeof(Shapes));
-
public enum ExposureGenTypes : byte
{
Linear,
@@ -615,7 +516,7 @@ namespace UVtools.Core.Operations
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 && _cylinderHeight == other._cylinderHeight && _cylinderMargin == other._cylinderMargin && _unitOfMeasure == other._unitOfMeasure && _cylinderDiametersMm == other._cylinderDiametersMm && _cylinderDiametersPx == other._cylinderDiametersPx && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _shape == other._shape && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && Equals(_exposureTable, other._exposureTable);
+ 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 && _holeHeight == other._holeHeight && _holeMargin == other._holeMargin && _unitOfMeasure == other._unitOfMeasure && _holeDiametersMm == other._holeDiametersMm && _holeDiametersPx == other._holeDiametersPx && _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);
}
public override bool Equals(object obj)
@@ -638,16 +539,15 @@ namespace UVtools.Core.Operations
hashCode.Add(_enableAntiAliasing);
hashCode.Add(_mirrorOutput);
hashCode.Add(_baseHeight);
- hashCode.Add(_cylinderHeight);
- hashCode.Add(_cylinderMargin);
+ hashCode.Add(_holeHeight);
+ hashCode.Add(_holeMargin);
hashCode.Add((int) _unitOfMeasure);
- hashCode.Add(_cylinderDiametersMm);
- hashCode.Add(_cylinderDiametersPx);
+ hashCode.Add(_holeDiametersMm);
+ hashCode.Add(_holeDiametersPx);
hashCode.Add(_multipleLayerHeight);
hashCode.Add(_multipleLayerHeightMaximum);
hashCode.Add(_multipleLayerHeightStep);
hashCode.Add(_multipleExposures);
- hashCode.Add((int) _shape);
hashCode.Add((int) _exposureGenType);
hashCode.Add(_exposureGenIgnoreBaseExposure);
hashCode.Add(_exposureGenBottomStep);
@@ -711,14 +611,16 @@ namespace UVtools.Core.Operations
ExposureTable = new(list);
}
- public Mat[] GetLayers()
+ public unsafe Mat[] GetLayers()
{
- var cylinders = Cylinders;
- int cylinderMarginX = (int) (Xppmm * _cylinderMargin);
- int cylinderMarginY = (int) (Yppmm * _cylinderMargin);
+ var holes = Holes;
+ if (holes.Length <= 0) return null;
+ int holeMarginX = (int) (Xppmm * _holeMargin);
+ int holeMarginY = (int) (Yppmm * _holeMargin);
+ int maxArea = (int) Math.Sqrt(holes[^1]);
Rectangle rect = new Rectangle(new Point(1, 1),
- new Size(cylinderMarginX * 4 + cylinders[^1] * 2,
- cylinderMarginY * 3 + GetCylindersLength(cylinders) + TextSpacing));
+ new Size(holeMarginX * 4 + maxArea * 2,
+ holeMarginY * 4 + GetHolesLength(holes) + TextSpacing));
var layers = new Mat[2];
layers[0] = EmguExtensions.InitMat(rect.Size.Inflate(2));
@@ -726,119 +628,110 @@ namespace UVtools.Core.Operations
layers[1] = layers[0].Clone();
CvInvoke.Rectangle(layers[1], new Rectangle(0, 0, rect.Size.Width / 2, layers[0].Height), EmguExtensions.BlackByte, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- //int holeXPos = (int) Math.Round(Xppmm * (CylinderMargin + maxCylinder / 2));
- // Print holes
- int holeXPos = 0;
- int holeYPos = 0;
- for (var layerIndex = 0; layerIndex < layers.Length; layerIndex++)
+ var span1 = layers[0].GetBytePointer();
+ var span2 = layers[1].GetBytePointer();
+
+ void DrawSpiralHole(int x, int y, int pixels, byte color)
{
- var layer = layers[layerIndex];
- holeYPos = cylinderMarginY;
- for (int i = 0; i < cylinders.Length; i++)
+ // 0 = Down, 1 = Left, 2 = Up, 3 = Right
+ byte stepState = 3;
+ int xStep = 1;
+ int yStep = 0;
+ int xCheck = 0;
+ int yCheck = 1;
+
+ int pixelPos = layers[0].GetPixelPos(x, y);
+
+ span1[pixelPos] = color;
+ span2[pixelPos] = color;
+
+ Debug.WriteLine($"START: {x}/{x+xCheck}, {y}/{y+yCheck}");
+
+ for (int i = 1; i < pixels; i++)
{
- var diameter = cylinders[i];
- var radius = diameter / 2;
+ x += xStep;
+ y += yStep;
- switch (_shape)
- {
- case Shapes.Circle:
- holeXPos = rect.X + cylinderMarginX + cylinders[^1] - radius;
- holeYPos += radius;
- break;
- case Shapes.Square:
- holeXPos = rect.X + cylinderMarginX + cylinders[^1] - diameter;
- break;
- }
-
+ if (x < 0 || y < 0 || x >= layers[0].Width || y >= layers[0].Height) break;
- // Left side
- if (layerIndex == 1)
- {
- if (diameter == 1)
- {
- layer.SetByte(holeXPos, holeYPos, 255);
- }
- else
- {
- switch (_shape)
- {
- case Shapes.Circle:
- CvInvoke.Circle(layers[layerIndex],
- new Point(holeXPos, holeYPos),
- radius, EmguExtensions.WhiteByte, -1,
- _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- break;
- case Shapes.Square:
- CvInvoke.Rectangle(layers[layerIndex],
- new Rectangle(new Point(holeXPos, holeYPos), new Size(diameter, diameter)),
- EmguExtensions.WhiteByte, -1,
- _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- break;
- }
-
- }
- }
+ Debug.WriteLine($"{x}/{x + xCheck}, {y}/{y + yCheck}");
+ pixelPos = layers[1].GetPixelPos(x, y);
+ span1[pixelPos] = color;
+ span2[pixelPos] = color;
- //holeXPos = layers[0].Width - holeXPos;
- switch (_shape)
- {
- case Shapes.Circle:
- holeXPos = layers[0].Width - rect.X - cylinderMarginX - cylinders[^1] + radius;
- break;
- case Shapes.Square:
- holeXPos = layers[0].Width - rect.X - cylinderMarginX - cylinders[^1];
- break;
- }
+ xCheck = x + xCheck;
+ yCheck = y + yCheck;
+ if (xCheck < 0 || yCheck < 0 || xCheck >= layers[0].Width || yCheck >= layers[0].Height) break;
+ pixelPos = layers[1].GetPixelPos(xCheck, yCheck);
- // Right side
- if (diameter == 1)
+ if (color > 0 && span2[pixelPos] == 0)
{
- layer.SetByte(holeXPos, holeYPos, 0);
+ stepState++;
}
- else
+ else if (color == 0 && span2[pixelPos] > 0)
{
- switch (_shape)
- {
- case Shapes.Circle:
- CvInvoke.Circle(layers[layerIndex],
- new Point(holeXPos, holeYPos),
- radius, EmguExtensions.BlackByte, -1,
- _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- break;
- case Shapes.Square:
- CvInvoke.Rectangle(layers[layerIndex],
- new Rectangle(new Point(holeXPos, holeYPos), new Size(diameter, diameter)),
- EmguExtensions.BlackByte, -1,
- _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
- break;
- }
+ stepState++;
}
+ if (stepState > 3) stepState = 0;
- holeYPos += cylinderMarginY;
-
- switch (_shape)
+ switch (stepState)
{
- case Shapes.Circle:
- holeYPos += radius;
+ case 0: // Down
+ xStep = 0;
+ yStep = 1;
+ xCheck = -1;
+ yCheck = 0;
+ break;
+ case 1: // Left
+ xStep = -1;
+ yStep = 0;
+ xCheck = 0;
+ yCheck = -1;
break;
- case Shapes.Square:
- holeYPos += diameter;
+ case 2: // Up
+ xStep = 0;
+ yStep = -1;
+ xCheck = 1;
+ yCheck = 0;
+ break;
+ case 3: // Right
+ xStep = 1;
+ yStep = 0;
+ xCheck = 0;
+ yCheck = 1;
break;
}
-
-
}
}
+ //int holeXPos = (int) Math.Round(Xppmm * (HoleMargin + maxCylinder / 2));
+ // Print holes
+ int holeXPos = 0;
+ int holeYPos = holeMarginY;
+ for (int i = 0; i < holes.Length; i++)
+ {
+ int diameter = holes[i];
+ int radius = (int) Math.Sqrt(diameter);
+ //holeXPos = rect.X + holeMarginX + maxArea - radius;
+ holeXPos = rect.X + holeMarginX + maxArea / 2;
+ holeYPos += radius;
+
+ // Left Side, positive
+ DrawSpiralHole(holeXPos, holeYPos, diameter, 255);
+ //holeXPos = layers[0].Width - rect.X - holeMarginX - maxArea + radius;
+ holeXPos = layers[0].Width - holeXPos;
+ // Right side, negative
+ DrawSpiralHole(holeXPos, holeYPos, diameter, 0);
+
+ holeYPos += holeMarginY + radius;
+ }
+
/*if (_mirrorOutput)
{
Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, FlipType.Horizontal));
}*/
-
- //layers[^1].Save("E:\\layer.png");
-
return layers;
}
@@ -856,7 +749,7 @@ namespace UVtools.Core.Operations
CvInvoke.Line(thumbnail, new Point(thumbnail.Width - xSpacing, 0), new Point(thumbnail.Width - xSpacing, ySpacing + 5), new MCvScalar(255, 27, 245), 3);
CvInvoke.PutText(thumbnail, "Exposure Time Cal.", new Point(xSpacing, ySpacing * 2), fontFace, fontScale, new MCvScalar(0, 255, 255), fontThickness);
CvInvoke.PutText(thumbnail, $"{Microns}um @ {BottomExposure}s/{NormalExposure}s", new Point(xSpacing, ySpacing * 3), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
- CvInvoke.PutText(thumbnail, $"Objects: {Cylinders.Length}", new Point(xSpacing, ySpacing * 4), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
+ CvInvoke.PutText(thumbnail, $"Objects: {Holes.Length}", new Point(xSpacing, ySpacing * 4), fontFace, fontScale, EmguExtensions.White3Byte, fontThickness);
return thumbnail;
}
@@ -881,7 +774,7 @@ namespace UVtools.Core.Operations
uint layerIndex = 0;
int currentX = sideMarginPx;
int currentY = topBottomMarginPx;
- int cylinderMarginY = (int)(Yppmm * _cylinderMargin);
+ int holeMarginY = (int)(Yppmm * _holeMargin);
var anchor = new Point(-1, -1);
using var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);
@@ -939,7 +832,7 @@ namespace UVtools.Core.Operations
CvInvoke.Erode(matRoi, matRoi, kernel, anchor, _chamferLayers - layerCountOnHeight, BorderType.Reflect101, default);
}
- var textHeightStart = matRoi.Height - cylinderMarginY - TextSpacing;
+ var textHeightStart = matRoi.Height - holeMarginY - TextSpacing;
CvInvoke.PutText(matRoi, $"{microns}u", new Point(TextStartX, textHeightStart), FontFace, TextScale, EmguExtensions.WhiteByte, TextThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
CvInvoke.PutText(matRoi, $"{bottomExposure}s", new Point(TextStartX, textHeightStart + TextLineBreak), FontFace, TextScale, EmguExtensions.WhiteByte, TextThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
CvInvoke.PutText(matRoi, $"{normalExposure}s", new Point(TextStartX, textHeightStart + TextLineBreak * 2), FontFace, TextScale, EmguExtensions.WhiteByte, TextThickness, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected);
diff --git a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs
index 3615714..27d7eaf 100644
--- a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs
+++ b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs
@@ -53,56 +53,6 @@ namespace UVtools.Core.Operations
}
}
- [Serializable]
- public sealed class ExposureItem : BindableBase
- {
- private decimal _layerHeight;
- private decimal _bottomExposure;
- private decimal _exposure;
-
-
- /// <summary>
- /// Gets or sets the layer height in millimeters
- /// </summary>
- public decimal LayerHeight
- {
- get => _layerHeight;
- set => RaiseAndSetIfChanged(ref _layerHeight, Math.Round(value, 2));
- }
-
-
- /// <summary>
- /// Gets or sets the bottom exposure in seconds
- /// </summary>
- public decimal BottomExposure
- {
- get => _bottomExposure;
- set => RaiseAndSetIfChanged(ref _bottomExposure, Math.Round(value, 2));
- }
-
- /// <summary>
- /// Gets or sets the bottom exposure in seconds
- /// </summary>
- public decimal Exposure
- {
- get => _exposure;
- set => RaiseAndSetIfChanged(ref _exposure, Math.Round(value, 2));
- }
-
- public ExposureItem() { }
-
- public ExposureItem(decimal layerHeight, decimal bottomExposure = 0, decimal exposure = 0)
- {
- _layerHeight = Math.Round(layerHeight, 2);
- _bottomExposure = Math.Round(bottomExposure, 2);
- _exposure = Math.Round(exposure, 2);
- }
-
- public override string ToString()
- {
- return $"{nameof(LayerHeight)}: {LayerHeight}mm, {nameof(BottomExposure)}: {BottomExposure}s, {nameof(Exposure)}: {Exposure}s";
- }
- }
#endregion
#region Constants
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index 2ca19df..bcaf156b 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.0</Version>
+ <Version>2.4.1</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
index 13e29fc..e2dec88 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml
@@ -208,7 +208,7 @@
Text="mm"/>
<TextBlock Grid.Row="0" Grid.Column="6"
- Text="Cylinder height:"
+ Text="Hole height:"
VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="0" Grid.Column="8"
ClipValueToMinMax="True"
@@ -216,13 +216,13 @@
Minimum="1"
Maximum="100"
FormatString="F02"
- Value="{Binding Operation.CylinderHeight}"/>
+ Value="{Binding Operation.HoleHeight}"/>
<TextBlock Grid.Row="0" Grid.Column="10"
VerticalAlignment="Center"
Text="mm"/>
<TextBlock Grid.Row="0" Grid.Column="12"
- Text="Cylinder margin:"
+ Text="Hole margin:"
VerticalAlignment="Center"/>
<NumericUpDown Grid.Row="0" Grid.Column="14"
ClipValueToMinMax="True"
@@ -230,25 +230,16 @@
Minimum="1"
Maximum="100"
FormatString="F02"
- Value="{Binding Operation.CylinderMargin}"/>
+ Value="{Binding Operation.HoleMargin}"/>
<TextBlock Grid.Row="0" Grid.Column="16"
VerticalAlignment="Center"
Text="mm"/>
<TextBlock Grid.Row="2" Grid.Column="0"
- Text="Shape:"
- VerticalAlignment="Center"/>
-
- <ComboBox Grid.Row="2" Grid.Column="2"
- HorizontalAlignment="Stretch"
- Items="{Binding Operation.ShapesItems}"
- SelectedItem="{Binding Operation.Shape}"/>
-
- <TextBlock Grid.Row="2" Grid.Column="6"
Text="Unit of measure:"
VerticalAlignment="Center"/>
- <ComboBox Grid.Row="2" Grid.Column="8"
+ <ComboBox Grid.Row="2" Grid.Column="2"
HorizontalAlignment="Stretch"
Items="{Binding Operation.MeasuresItems}"
SelectedItem="{Binding Operation.UnitOfMeasure}"/>
@@ -263,12 +254,12 @@
<TextBox Grid.Row="4" Grid.Column="2"
Grid.ColumnSpan="13"
IsVisible="{Binding Operation.IsUnitOfMeasureMm}"
- Text="{Binding Operation.CylinderDiametersMm}"/>
+ Text="{Binding Operation.HoleDiametersMm}"/>
<TextBox Grid.Row="4" Grid.Column="2"
Grid.ColumnSpan="13"
IsVisible="{Binding !Operation.IsUnitOfMeasureMm}"
- Text="{Binding Operation.CylinderDiametersPx}"/>
+ Text="{Binding Operation.HoleDiametersPx}"/>
<TextBlock Grid.Row="4" Grid.Column="16"
IsVisible="{Binding Operation.IsUnitOfMeasureMm}"
@@ -585,7 +576,7 @@ Multiplier: Current exposure * layer height * step * test number."
<Image Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Top"
- MaxHeight="800"
+ MaxHeight="600"
Stretch="Uniform"
Source="{Binding PreviewImage}"/>
</Grid>
diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
index c5be0cf..e92c190 100644
--- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
+++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml.cs
@@ -8,6 +8,7 @@ using Avalonia.Threading;
using DynamicData;
using MessageBox.Avalonia.Enums;
using UVtools.Core.FileFormats;
+using UVtools.Core.Objects;
using UVtools.Core.Operations;
using UVtools.WPF.Controls.Tools;
using UVtools.WPF.Extensions;
@@ -72,10 +73,13 @@ namespace UVtools.WPF.Controls.Calibrators
{
var layers = Operation.GetLayers();
_previewImage?.Dispose();
- PreviewImage = layers[^1].ToBitmap();
- foreach (var layer in layers)
+ if (layers is not null)
{
- layer.Dispose();
+ PreviewImage = layers[^1].ToBitmap();
+ foreach (var layer in layers)
+ {
+ layer.Dispose();
+ }
}
}
@@ -130,7 +134,7 @@ namespace UVtools.WPF.Controls.Calibrators
$"Are you sure you want to remove the {_exposureTable.SelectedItems.Count} selected entries?"
) != ButtonResult.Yes) return;
- Operation.ExposureTable.RemoveMany(_exposureTable.SelectedItems.Cast<OperationCalibrateExposureFinder.ExposureItem>());
+ Operation.ExposureTable.RemoveMany(_exposureTable.SelectedItems.Cast<ExposureItem>());
}
}
}
diff --git a/UVtools.WPF/Structures/OperationProfiles.cs b/UVtools.WPF/Structures/OperationProfiles.cs
index 5796fe8..6300e69 100644
--- a/UVtools.WPF/Structures/OperationProfiles.cs
+++ b/UVtools.WPF/Structures/OperationProfiles.cs
@@ -47,6 +47,7 @@ namespace UVtools.WPF.Structures
[XmlElement(typeof(OperationResize))]
[XmlElement(typeof(OperationRotate))]
[XmlElement(typeof(OperationThreshold))]
+ [XmlElement(typeof(OperationCalibrateExposureFinder))]
[XmlElement(typeof(OperationCalibrateElephantFoot))]
[XmlElement(typeof(OperationCalibrateXYZAccuracy))]
[XmlElement(typeof(OperationCalibrateTolerance))]
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 45fa8f8..06daa35 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.0</Version>
+ <Version>2.4.1</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">