diff --git a/CHANGELOG.md b/CHANGELOG.md
index e860122..600081d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## 02/04/2022 - v3.2.1
+
+- **AnyCubic file format:**
+ - (Fix) Lift height and speed are not being correctly set on old version, keeping a constant value (#441)
+ - (Fix) Retract speed getter was not return value from TSMC if using version 516
+- **Tool - Infill:**
+ - (Add) Waves infill type
+ - (Add) Concentric infill type
+ - (Add) Gyroid infill type (#443)
+ - (Change) Increase the default spacing from 200px to 300px
+ - (Improvement) Fastter infill processing by use the model bounds
+- (Add) `FormatSpeedUnit` property to file formats to get the speed unit which the file use internally
+- (Fix) UI: ROI rectangle can overlap scroll bars while selecting
+
## 26/03/2022 - v3.2.0
- **Core:**
diff --git a/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs b/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
index 71d8ed8..e2133df 100644
--- a/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
+++ b/UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs
@@ -10,6 +10,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics;
using System.Drawing;
using System.Runtime.CompilerServices;
using Avalonia;
@@ -1074,7 +1075,10 @@ public class AdvancedImageBox : UserControl
HorizontalScrollBar.Scroll += ScrollBarOnScroll;
VerticalScrollBar.Scroll += ScrollBarOnScroll;
- ViewPort.PointerWheelChanged += FillContainerOnPointerWheelChanged;
+ ViewPort.PointerPressed += ViewPortOnPointerPressed;
+ ViewPort.PointerLeave += ViewPortOnPointerLeave;
+ ViewPort.PointerMoved += ViewPortOnPointerMoved;
+ ViewPort.PointerWheelChanged += ViewPortOnPointerWheelChanged;
}
private void InitializeComponent()
@@ -1088,7 +1092,6 @@ public class AdvancedImageBox : UserControl
{
if (!_canRender) return;
if (renderOnlyCursorTracker && _trackerImage is null) return;
-
InvalidateVisual();
}
@@ -1096,7 +1099,8 @@ public class AdvancedImageBox : UserControl
{
//Debug.WriteLine($"Render: {DateTime.Now.Ticks}");
base.Render(context);
-
+
+ var viewPortSize = ViewPortSize;
// Draw Grid
var gridCellSize = GridCellSize;
if (ShowGrid & gridCellSize > 0 && (!IsHorizontalBarVisible || !IsVerticalBarVisible))
@@ -1105,11 +1109,11 @@ public class AdvancedImageBox : UserControl
var gridColor = GridColor;
var altColor = GridColorAlternate;
var currentColor = gridColor;
- for (int y = 0; y < ViewPortSize.Height; y += gridCellSize)
+ for (int y = 0; y < viewPortSize.Height; y += gridCellSize)
{
var firstRowColor = currentColor;
- for (int x = 0; x < ViewPortSize.Width; x += gridCellSize)
+ for (int x = 0; x < viewPortSize.Width; x += gridCellSize)
{
context.FillRectangle(currentColor, new Rect(x, y, gridCellSize, gridCellSize));
currentColor = ReferenceEquals(currentColor, gridColor) ? altColor : gridColor;
@@ -1127,15 +1131,17 @@ public class AdvancedImageBox : UserControl
var image = Image;
if (image is null) return;
+ var imageViewPort = GetImageViewPort();
+
+
// Draw iamge
context.DrawImage(image,
GetSourceImageRegion(),
- GetImageViewPort()
+ imageViewPort
);
var zoomFactor = ZoomFactor;
-
-
+
if (HaveTrackerImage && _pointerPosition.X >= 0 && _pointerPosition.Y >= 0)
{
var destSize = TrackerImageAutoZoom
@@ -1155,22 +1161,21 @@ public class AdvancedImageBox : UserControl
// Draw pixel grid
if (zoomFactor > PixelGridZoomThreshold && SizeMode == SizeModes.Normal)
{
- var viewport = GetImageViewPort();
var offsetX = Offset.X % zoomFactor;
var offsetY = Offset.Y % zoomFactor;
Pen pen = new(PixelGridColor);
- for (double x = viewport.X + zoomFactor - offsetX; x < viewport.Right; x += zoomFactor)
+ for (double x = imageViewPort.X + zoomFactor - offsetX; x < imageViewPort.Right; x += zoomFactor)
{
- context.DrawLine(pen, new Point(x, viewport.X), new Point(x, viewport.Bottom));
+ context.DrawLine(pen, new Point(x, imageViewPort.X), new Point(x, imageViewPort.Bottom));
}
- for (double y = viewport.Y + zoomFactor - offsetY; y < viewport.Bottom; y += zoomFactor)
+ for (double y = imageViewPort.Y + zoomFactor - offsetY; y < imageViewPort.Bottom; y += zoomFactor)
{
- context.DrawLine(pen, new Point(viewport.Y, y), new Point(viewport.Right, y));
+ context.DrawLine(pen, new Point(imageViewPort.Y, y), new Point(imageViewPort.Right, y));
}
- context.DrawRectangle(pen, viewport);
+ context.DrawRectangle(pen, imageViewPort);
}
if (!SelectionRegion.IsEmpty)
@@ -1178,7 +1183,7 @@ public class AdvancedImageBox : UserControl
var rect = GetOffsetRectangle(SelectionRegion);
var selectionColor = SelectionColor;
context.FillRectangle(selectionColor, rect);
- Color color = Color.FromArgb(255, selectionColor.Color.R, selectionColor.Color.G, selectionColor.Color.B);
+ var color = Color.FromArgb(255, selectionColor.Color.R, selectionColor.Color.G, selectionColor.Color.B);
context.DrawRectangle(new Pen(color.ToUint32()), rect);
}
}
@@ -1248,7 +1253,7 @@ public class AdvancedImageBox : UserControl
base.OnScrollChanged(e);
}*/
- private void FillContainerOnPointerWheelChanged(object? sender, PointerWheelEventArgs e)
+ private void ViewPortOnPointerWheelChanged(object? sender, PointerWheelEventArgs e)
{
e.Handled = true;
if (Image is null) return;
@@ -1265,9 +1270,8 @@ public class AdvancedImageBox : UserControl
}
}
- protected override void OnPointerPressed(PointerPressedEventArgs e)
+ private void ViewPortOnPointerPressed(object? sender, PointerPressedEventArgs e)
{
- base.OnPointerPressed(e);
if (e.Handled
|| _isPanning
|| _isSelecting
@@ -1307,6 +1311,49 @@ public class AdvancedImageBox : UserControl
_startMousePosition = location;
}
+ /*protected override void OnPointerPressed(PointerPressedEventArgs e)
+ {
+ base.OnPointerPressed(e);
+
+ if (e.Handled
+ || _isPanning
+ || _isSelecting
+ || Image is null) return;
+
+ var pointer = e.GetCurrentPoint(this);
+
+ if (SelectionMode != SelectionModes.None)
+ {
+ if (!(
+ pointer.Properties.IsLeftButtonPressed && (SelectWithMouseButtons & MouseButtons.LeftButton) != 0 ||
+ pointer.Properties.IsMiddleButtonPressed && (SelectWithMouseButtons & MouseButtons.MiddleButton) != 0 ||
+ pointer.Properties.IsRightButtonPressed && (SelectWithMouseButtons & MouseButtons.RightButton) != 0
+ )
+ ) return;
+ IsSelecting = true;
+ }
+ else
+ {
+ if (!(
+ pointer.Properties.IsLeftButtonPressed && (PanWithMouseButtons & MouseButtons.LeftButton) != 0 ||
+ pointer.Properties.IsMiddleButtonPressed && (PanWithMouseButtons & MouseButtons.MiddleButton) != 0 ||
+ pointer.Properties.IsRightButtonPressed && (PanWithMouseButtons & MouseButtons.RightButton) != 0
+ )
+ || !AutoPan
+ || SizeMode != SizeModes.Normal
+
+ ) return;
+
+ IsPanning = true;
+ }
+
+ var location = pointer.Position;
+
+ if (location.X > ViewPortSize.Width) return;
+ if (location.Y > ViewPortSize.Height) return;
+ _startMousePosition = location;
+ }*/
+
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
@@ -1316,20 +1363,111 @@ public class AdvancedImageBox : UserControl
IsSelecting = false;
}
- protected override void OnPointerLeave(PointerEventArgs e)
+ private void ViewPortOnPointerLeave(object? sender, PointerEventArgs e)
{
- base.OnPointerLeave(e);
PointerPosition = new Point(-1, -1);
TriggerRender(true);
e.Handled = true;
}
- protected override void OnPointerMoved(PointerEventArgs e)
+ /*protected override void OnPointerLeave(PointerEventArgs e)
+ {
+ base.OnPointerLeave(e);
+ PointerPosition = new Point(-1, -1);
+ TriggerRender(true);
+ e.Handled = true;
+ }*/
+
+ private void ViewPortOnPointerMoved(object? sender, PointerEventArgs e)
{
- base.OnPointerMoved(e);
if (e.Handled) return;
- var pointer = e.GetCurrentPoint(this);
+ var pointer = e.GetCurrentPoint(ViewPort);
+ PointerPosition = pointer.Position;
+
+ if (!_isPanning && !_isSelecting)
+ {
+ TriggerRender(true);
+ return;
+ }
+
+ if (_isPanning)
+ {
+ double x;
+ double y;
+
+ if (!InvertMousePan)
+ {
+ x = _startScrollPosition.X + (_startMousePosition.X - _pointerPosition.X);
+ y = _startScrollPosition.Y + (_startMousePosition.Y - _pointerPosition.Y);
+ }
+ else
+ {
+ x = (_startScrollPosition.X - (_startMousePosition.X - _pointerPosition.X));
+ y = (_startScrollPosition.Y - (_startMousePosition.Y - _pointerPosition.Y));
+ }
+
+ Offset = new Vector(x, y);
+ }
+ else if (_isSelecting)
+ {
+ var viewPortPoint = new Point(
+ Math.Min(_pointerPosition.X, ViewPort.Bounds.Right),
+ Math.Min(_pointerPosition.Y, ViewPort.Bounds.Bottom));
+
+ double x;
+ double y;
+ double w;
+ double h;
+
+ var imageOffset = GetImageViewPort().Position;
+
+ if (viewPortPoint.X < _startMousePosition.X)
+ {
+ x = viewPortPoint.X;
+ w = _startMousePosition.X - viewPortPoint.X;
+ }
+ else
+ {
+ x = _startMousePosition.X;
+ w = viewPortPoint.X - _startMousePosition.X;
+ }
+
+ if (viewPortPoint.Y < _startMousePosition.Y)
+ {
+ y = viewPortPoint.Y;
+ h = _startMousePosition.Y - viewPortPoint.Y;
+ }
+ else
+ {
+ y = _startMousePosition.Y;
+ h = viewPortPoint.Y - _startMousePosition.Y;
+ }
+
+ x -= imageOffset.X - Offset.X;
+ y -= imageOffset.Y - Offset.Y;
+
+ var zoomFactor = ZoomFactor;
+ x /= zoomFactor;
+ y /= zoomFactor;
+ w /= zoomFactor;
+ h /= zoomFactor;
+
+ if (w > 0 && h > 0)
+ {
+ SelectionRegion = FitRectangle(new Rect(x, y, w, h));
+ }
+ }
+
+ e.Handled = true;
+ }
+
+ /*protected override void OnPointerMoved(PointerEventArgs e)
+ {
+ base.OnPointerMoved(e);
+ if (e.Handled || !ViewPort.IsPointerOver) return;
+
+ var pointer = e.GetCurrentPoint(ViewPort);
PointerPosition = pointer.Position;
if (!_isPanning && !_isSelecting)
@@ -1396,14 +1534,15 @@ public class AdvancedImageBox : UserControl
w /= zoomFactor;
h /= zoomFactor;
- if (w != 0 && h != 0)
+ if (w > 0 && h > 0)
{
+
SelectionRegion = FitRectangle(new Rect(x, y, w, h));
}
}
e.Handled = true;
- }
+ }*/
#endregion
#region Zoom and Size modes
@@ -1729,7 +1868,7 @@ public class AdvancedImageBox : UserControl
var scaled = GetScaledRectangle(source);
var offsetX = viewport.Left - Offset.X;
var offsetY = viewport.Top - Offset.Y;
-
+
return new(new Point(scaled.Left + offsetX, scaled.Top + offsetY), scaled.Size);
}
@@ -2151,7 +2290,8 @@ public class AdvancedImageBox : UserControl
///
public Rect GetImageViewPort()
{
- if (!IsImageLoaded || (ViewPortSize.Width == 0 && ViewPortSize.Height == 0)) return Rect.Empty;
+ var viewPortSize = ViewPortSize;
+ if (!IsImageLoaded || (viewPortSize.Width == 0 && viewPortSize.Height == 0)) return Rect.Empty;
double xOffset = 0;
double yOffset = 0;
@@ -2163,28 +2303,28 @@ public class AdvancedImageBox : UserControl
case SizeModes.Normal:
if (AutoCenter)
{
- xOffset = (!IsHorizontalBarVisible ? (ViewPortSize.Width - ScaledImageWidth) / 2 : 0);
- yOffset = (!IsVerticalBarVisible ? (ViewPortSize.Height - ScaledImageHeight) / 2 : 0);
+ xOffset = (!IsHorizontalBarVisible ? (viewPortSize.Width - ScaledImageWidth) / 2 : 0);
+ yOffset = (!IsVerticalBarVisible ? (viewPortSize.Height - ScaledImageHeight) / 2 : 0);
}
- width = Math.Min(ScaledImageWidth - Math.Abs(Offset.X), ViewPortSize.Width);
- height = Math.Min(ScaledImageHeight - Math.Abs(Offset.Y), ViewPortSize.Height);
+ width = Math.Min(ScaledImageWidth - Math.Abs(Offset.X), viewPortSize.Width);
+ height = Math.Min(ScaledImageHeight - Math.Abs(Offset.Y), viewPortSize.Height);
break;
case SizeModes.Stretch:
- width = ViewPortSize.Width;
- height = ViewPortSize.Height;
+ width = viewPortSize.Width;
+ height = viewPortSize.Height;
break;
case SizeModes.Fit:
var image = Image;
- double scaleFactor = Math.Min(ViewPortSize.Width / image!.Size.Width, ViewPortSize.Height / image.Size.Height);
+ double scaleFactor = Math.Min(viewPortSize.Width / image!.Size.Width, viewPortSize.Height / image.Size.Height);
width = Math.Floor(image.Size.Width * scaleFactor);
height = Math.Floor(image.Size.Height * scaleFactor);
if (AutoCenter)
{
- xOffset = (ViewPortSize.Width - width) / 2;
- yOffset = (ViewPortSize.Height - height) / 2;
+ xOffset = (viewPortSize.Width - width) / 2;
+ yOffset = (viewPortSize.Height - height) / 2;
}
break;
diff --git a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
index 5a23b57..676fb95 100644
--- a/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
+++ b/UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj
@@ -14,7 +14,7 @@
true
AvaloniaUI Controls
- AdvancedImageBox: Pan, zoom, cursor, pixel grid and selections image box
- 2.0.0
+ 2.0.1
enable
https://github.com/sn4k3/UVtools
README.md
diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs
index aae8bd6..243b669 100644
--- a/UVtools.Core/Extensions/EmguExtensions.cs
+++ b/UVtools.Core/Extensions/EmguExtensions.cs
@@ -174,24 +174,18 @@ public static class EmguExtensions
///
///
public static unsafe byte* GetBytePointer(this Mat mat)
- {
- return (byte*)mat.DataPointer.ToPointer();
- }
+ => (byte*)mat.DataPointer.ToPointer();
///
/// Gets the whole data span to manipulate or read pixels
///
///
///
- public static unsafe Span GetDataByteSpan(this Mat mat)
- {
- return new(mat.DataPointer.ToPointer(), mat.GetLength());
- }
+ public static unsafe Span GetDataByteSpan(this Mat mat)
+ => new(mat.DataPointer.ToPointer(), mat.GetLength());
- public static unsafe Span GetDataByteSpan(this Mat mat, int length, int offset = 0)
- {
- return new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
- }
+ public static unsafe Span GetDataByteSpan(this Mat mat, int length, int offset = 0)
+ => new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
///
/// Gets the data span to manipulate or read pixels given a length and offset
@@ -201,10 +195,8 @@ public static class EmguExtensions
///
///
///
- public static unsafe Span GetDataSpan(this Mat mat, int length = 0, int offset = 0)
- {
- return new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
- }
+ public static unsafe Span GetDataSpan(this Mat mat, int length = 0, int offset = 0)
+ => new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
///
/// Gets a single pixel span to manipulate or read pixels
@@ -214,10 +206,8 @@ public static class EmguExtensions
///
///
///
- public static Span GetPixelSpan(this Mat mat, int x, int y)
- {
- return mat.GetDataSpan(mat.NumberOfChannels, mat.GetPixelPos(x, y));
- }
+ public static Span GetPixelSpan(this Mat mat, int x, int y)
+ => mat.GetDataSpan(mat.NumberOfChannels, mat.GetPixelPos(x, y));
///
/// Gets a single pixel span to manipulate or read pixels
@@ -226,10 +216,8 @@ public static class EmguExtensions
///
///
///
- public static Span GetPixelSpan(this Mat mat, int pos)
- {
- return mat.GetDataSpan(mat.NumberOfChannels, pos);
- }
+ public static Span GetPixelSpan(this Mat mat, int pos)
+ => mat.GetDataSpan(mat.NumberOfChannels, pos);
///
/// Gets a row span to manipulate or read pixels
@@ -240,10 +228,8 @@ public static class EmguExtensions
///
///
///
- public static unsafe Span GetRowSpan(this Mat mat, int y, int length = 0, int offset = 0)
- {
- return new(IntPtr.Add(mat.DataPointer, y * mat.GetRealStep() + offset).ToPointer(), length <= 0 ? mat.GetRealStep() : length);
- }
+ public static unsafe Span GetRowSpan(this Mat mat, int y, int length = 0, int offset = 0)
+ => new(IntPtr.Add(mat.DataPointer, y * mat.GetRealStep() + offset).ToPointer(), length <= 0 ? mat.GetRealStep() : length);
///
/// Gets a col span to manipulate or read pixels
@@ -325,7 +311,7 @@ public static class EmguExtensions
}
///
- /// Gets the total length of this
+ /// Gets the total length of this
///
///
/// The total length of this
@@ -471,6 +457,23 @@ public static class EmguExtensions
return src.CreateMask(vec);
}
+ public static Mat TrimByBounds(this Mat src)
+ {
+ var rect = CvInvoke.BoundingRectangle(src);
+ if (rect.Size == Size.Empty) return src.New();
+ if (src.Size == rect.Size) return src.Clone();
+ using var roi = src.Roi(rect);
+ return roi.Clone();
+ }
+
+ public static void TrimByBounds(this Mat src, Mat dst)
+ {
+ var mat = src.TrimByBounds();
+ CvInvoke.Swap(mat, dst);
+ src.Dispose();
+ }
+
+
#endregion
#region Copy methods
diff --git a/UVtools.Core/FileFormats/CXDLPFile.cs b/UVtools.Core/FileFormats/CXDLPFile.cs
index a90faf2..eea39a5 100644
--- a/UVtools.Core/FileFormats/CXDLPFile.cs
+++ b/UVtools.Core/FileFormats/CXDLPFile.cs
@@ -407,6 +407,8 @@ public class CXDLPFile : FileFormat
new(typeof(CXDLPFile), "cxdlp", "Creality CXDLP"),
};
+ public override SpeedUnit FormatSpeedUnit => SpeedUnit.MillimetersPerSecond;
+
public override PrintParameterModifier[]? PrintParameterModifiers { get; } =
{
PrintParameterModifier.BottomLayerCount,
@@ -577,8 +579,8 @@ public class CXDLPFile : FileFormat
public override float BottomLiftSpeed
{
- get => SpeedConverter.Convert(SlicerInfoSettings.BottomLiftSpeed, SpeedUnit.MillimetersPerSecond, DefaultSpeedUnit);
- set => base.BottomLiftSpeed = SlicerInfoSettings.BottomLiftSpeed = SlicerInfoSettings.BottomLiftSpeed = (ushort)SpeedConverter.Convert(value, DefaultSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ get => SpeedConverter.Convert(SlicerInfoSettings.BottomLiftSpeed, FormatSpeedUnit, CoreSpeedUnit);
+ set => base.BottomLiftSpeed = SlicerInfoSettings.BottomLiftSpeed = SlicerInfoSettings.BottomLiftSpeed = (ushort)SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
}
public override float LiftHeight
@@ -589,16 +591,16 @@ public class CXDLPFile : FileFormat
public override float LiftSpeed
{
- get => SpeedConverter.Convert(SlicerInfoSettings.LiftSpeed, SpeedUnit.MillimetersPerSecond, DefaultSpeedUnit);
- set => base.LiftSpeed = SlicerInfoSettings.LiftSpeed = (ushort)SpeedConverter.Convert(value, DefaultSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ get => SpeedConverter.Convert(SlicerInfoSettings.LiftSpeed, FormatSpeedUnit, CoreSpeedUnit);
+ set => base.LiftSpeed = SlicerInfoSettings.LiftSpeed = (ushort)SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
}
public override float BottomRetractSpeed => RetractSpeed;
public override float RetractSpeed
{
- get => SpeedConverter.Convert(SlicerInfoSettings.RetractSpeed, SpeedUnit.MillimetersPerSecond, DefaultSpeedUnit);
- set => base.RetractSpeed = SlicerInfoSettings.RetractSpeed = (ushort)SpeedConverter.Convert(value, DefaultSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ get => SpeedConverter.Convert(SlicerInfoSettings.RetractSpeed, FormatSpeedUnit, CoreSpeedUnit);
+ set => base.RetractSpeed = SlicerInfoSettings.RetractSpeed = (ushort)SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
}
public override byte BottomLightPWM
diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs
index d651bdc..8f10c8e 100644
--- a/UVtools.Core/FileFormats/FileFormat.cs
+++ b/UVtools.Core/FileFormats/FileFormat.cs
@@ -44,7 +44,7 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable
/// Gets the file format type
///
@@ -1004,8 +1006,11 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable
public abstract FileExtension[] FileExtensions { get; }
- public FileDecodeType DecodeType { get; private set; } = FileDecodeType.Full;
-
+ ///
+ /// The speed unit used by this file format in his internal data
+ ///
+ public virtual SpeedUnit FormatSpeedUnit => CoreSpeedUnit;
+
///
/// Gets the available
///
diff --git a/UVtools.Core/FileFormats/JXSFile.cs b/UVtools.Core/FileFormats/JXSFile.cs
index bc8758a..098042a 100644
--- a/UVtools.Core/FileFormats/JXSFile.cs
+++ b/UVtools.Core/FileFormats/JXSFile.cs
@@ -53,11 +53,11 @@ public class JXSFile : FileFormat
[DisplayName("nJobName")] public string JobName { get; set; } = string.Empty;
[DisplayName("NumBottomLayers")] public ushort BottomLayerCount { get; set; } = DefaultBottomLayerCount;
[DisplayName("LiftDistance1")] public float LiftHeight1 { get; set; } = DefaultBottomLiftHeight;
- [DisplayName("LiftFeedrate1")] public float LiftSpeed1 { get; set; } = SpeedConverter.Convert(DefaultLiftSpeed, SpeedUnit.MillimetersPerMinute, SpeedUnit.MillimetersPerSecond);
+ [DisplayName("LiftFeedrate1")] public float LiftSpeed1 { get; set; } = DefaultLiftSpeed;
[DisplayName("LiftDistance2")] public float LiftHeight2 { get; set; } = DefaultLiftHeight2;
- [DisplayName("LiftFeedrate2")] public float LiftSpeed2 { get; set; } = SpeedConverter.Convert(DefaultLiftSpeed2, SpeedUnit.MillimetersPerMinute, SpeedUnit.MillimetersPerSecond);
- [DisplayName("BottomLiftFeedrate")] public float BottomLiftSpeed { get; set; } = SpeedConverter.Convert(DefaultBottomLiftSpeed, SpeedUnit.MillimetersPerMinute, SpeedUnit.MillimetersPerSecond);
- [DisplayName("RetractFeedrate")] public float RetractSpeed { get; set; } = SpeedConverter.Convert(DefaultRetractSpeed, SpeedUnit.MillimetersPerMinute, SpeedUnit.MillimetersPerSecond);
+ [DisplayName("LiftFeedrate2")] public float LiftSpeed2 { get; set; } = DefaultLiftSpeed2;
+ [DisplayName("BottomLiftFeedrate")] public float BottomLiftSpeed { get; set; } = DefaultBottomLiftSpeed;
+ [DisplayName("RetractFeedrate")] public float RetractSpeed { get; set; } = DefaultRetractSpeed;
[DisplayName("ZMoveTimeCompensation")] public uint WaitTimeBeforeCure { get; set; } = 1500;
[DisplayName("ZMoveTimeCompensationBottom")] public uint BottomWaitTimeBeforeCure { get; set; } = 8000;
public string OnLightCode { get; set; } = "M106 S255";
@@ -80,8 +80,8 @@ public class JXSFile : FileFormat
#endregion
#region Properties
- public JXSConfig ConfigFile { get; set; } = new ();
- public JXSControl ControlFile { get; set; } = new ();
+ public JXSConfig ConfigFile { get; set; } = new();
+ public JXSControl ControlFile { get; set; } = new();
public override FileFormatType FileType => FileFormatType.Archive;
diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
index 0e656ef..19b1d4d 100644
--- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
+++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs
@@ -15,6 +15,7 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using UVtools.Core.Converters;
using UVtools.Core.Extensions;
using UVtools.Core.Layers;
using UVtools.Core.Operations;
@@ -287,18 +288,18 @@ public class PhotonWorkshopFile : FileFormat
///
/// 58
///
- [FieldOrder(7)] public float LiftHeight { get; set; } = 6;
+ [FieldOrder(7)] public float LiftHeight { get; set; } = DefaultLiftHeight;
///
/// Gets the lift speed in mm/s
/// 5C
///
- [FieldOrder(8)] public float LiftSpeed { get; set; } = 3; // mm/s
+ [FieldOrder(8)] public float LiftSpeed { get; set; } = SpeedConverter.Convert(DefaultLiftSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond); // mm/s
///
/// Gets the retract speed in mm/s
/// 60
///
- [FieldOrder(9)] public float RetractSpeed { get; set; } = 3; // mm/s
+ [FieldOrder(9)] public float RetractSpeed { get; set; } = SpeedConverter.Convert(DefaultRetractSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond); // mm/s
///
/// 64
@@ -557,7 +558,7 @@ public class PhotonWorkshopFile : FileFormat
LayerHeight = layer.RelativePositionZ;
ExposureTime = layer.ExposureTime;
LiftHeight = layer.LiftHeight;
- LiftSpeed = (float) Math.Round(layer.LiftSpeed / 60, 2);
+ LiftSpeed = SpeedConverter.Convert(layer.LiftSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
NonZeroPixelCount = layer.NonZeroPixelCount;
}
@@ -566,7 +567,7 @@ public class PhotonWorkshopFile : FileFormat
// Don't forget to compute LayerHeight outside here
layer.ExposureTime = ExposureTime;
layer.LiftHeight = LiftHeight;
- layer.LiftSpeed = (float)Math.Round(LiftSpeed * 60, 2);
+ layer.LiftSpeed = SpeedConverter.Convert(LiftSpeed, SpeedUnit.MillimetersPerSecond, CoreSpeedUnit);
}
public Mat Decode(bool consumeData = true)
@@ -942,18 +943,18 @@ public class PhotonWorkshopFile : FileFormat
[FieldOrder(1)] public uint Unknown0 { get; set; } = 24;
[FieldOrder(2)] public uint Unknown1 { get; set; } = 2;
[FieldOrder(3)] public float BottomLiftHeight1 { get; set; }
- [FieldOrder(4)] public float BottomLiftSpeed1 { get; set; }
- [FieldOrder(5)] public float BottomRetractSpeed1 { get; set; }
+ [FieldOrder(4)] public float BottomLiftSpeed1 { get; set; } = SpeedConverter.Convert(DefaultBottomLiftSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ [FieldOrder(5)] public float BottomRetractSpeed1 { get; set; } = SpeedConverter.Convert(DefaultBottomRetractSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
[FieldOrder(6)] public float BottomLiftHeight2 { get; set; }
- [FieldOrder(7)] public float BottomLiftSpeed2 { get; set; }
- [FieldOrder(8)] public float BottomRetractSpeed2 { get; set; }
+ [FieldOrder(7)] public float BottomLiftSpeed2 { get; set; } = SpeedConverter.Convert(DefaultBottomLiftSpeed2, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ [FieldOrder(8)] public float BottomRetractSpeed2 { get; set; } = SpeedConverter.Convert(DefaultBottomRetractSpeed2, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
[FieldOrder(9)] public uint Unknown2 { get; set; } = 2;
[FieldOrder(10)] public float LiftHeight1 { get; set; }
- [FieldOrder(11)] public float LiftSpeed1 { get; set; }
- [FieldOrder(12)] public float RetractSpeed1 { get; set; }
+ [FieldOrder(11)] public float LiftSpeed1 { get; set; } = SpeedConverter.Convert(DefaultLiftSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ [FieldOrder(12)] public float RetractSpeed1 { get; set; } = SpeedConverter.Convert(DefaultRetractSpeed, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
[FieldOrder(13)] public float LiftHeight2 { get; set; }
- [FieldOrder(14)] public float LiftSpeed2 { get; set; }
- [FieldOrder(15)] public float RetractSpeed2 { get; set; }
+ [FieldOrder(14)] public float LiftSpeed2 { get; set; } = SpeedConverter.Convert(DefaultLiftSpeed2, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
+ [FieldOrder(15)] public float RetractSpeed2 { get; set; } = SpeedConverter.Convert(DefaultRetractSpeed2, CoreSpeedUnit, SpeedUnit.MillimetersPerSecond);
public Extra()
{
@@ -1043,10 +1044,10 @@ public class PhotonWorkshopFile : FileFormat
new(typeof(PhotonWorkshopFile), "pwms", "Photon Mono SE (PWMS)"),
new(typeof(PhotonWorkshopFile), "pwma", "Photon Mono 4K (PWMA)"),
new(typeof(PhotonWorkshopFile), "pmsq", "Photon Mono SQ (PMSQ)"),
-
-
};
+ public override SpeedUnit FormatSpeedUnit => SpeedUnit.MillimetersPerSecond;
+
public override PrintParameterModifier[]? PrintParameterModifiers
{
get
@@ -1297,11 +1298,7 @@ public class PhotonWorkshopFile : FileFormat
public override float BottomLiftHeight
{
- get
- {
- if (FileMarkSettings.Version >= VERSION_516) return ExtraSettings.BottomLiftHeight1;
- return base.BottomLiftHeight;
- }
+ get => FileMarkSettings.Version >= VERSION_516 ? ExtraSettings.BottomLiftHeight1 : base.BottomLiftHeight;
set
{
value = (float)Math.Round(value, 2);
@@ -1321,26 +1318,20 @@ public class PhotonWorkshopFile : FileFormat
public override float BottomLiftSpeed
{
- get
- {
- if (FileMarkSettings.Version >= VERSION_516) return (float)Math.Round(ExtraSettings.BottomLiftSpeed1 * 60, 2);
- return base.BottomLiftSpeed;
- }
+ get => FileMarkSettings.Version >= VERSION_516
+ ? SpeedConverter.Convert(ExtraSettings.BottomLiftSpeed1, FormatSpeedUnit, CoreSpeedUnit)
+ : base.BottomLiftSpeed;
set
{
value = (float)Math.Round(value, 2);
- ExtraSettings.BottomLiftSpeed1 = (float)Math.Round(value / 60, 2);
+ ExtraSettings.BottomLiftSpeed1 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.BottomLiftSpeed = value;
}
}
public override float LiftHeight
{
- get
- {
- if (FileMarkSettings.Version >= VERSION_516) return ExtraSettings.LiftHeight1;
- return HeaderSettings.LiftHeight;
- }
+ get => FileMarkSettings.Version >= VERSION_516 ? ExtraSettings.LiftHeight1 : HeaderSettings.LiftHeight;
set
{
value = (float)Math.Round(value, 2);
@@ -1354,21 +1345,17 @@ public class PhotonWorkshopFile : FileFormat
layer.LiftHeight = base.LiftHeight;
}
}
- else base.LiftHeight = value;
+ else base.LiftHeight = HeaderSettings.LiftHeight = value;
}
}
public override float LiftSpeed
{
- get
- {
- if (FileMarkSettings.Version >= VERSION_516) return (float)Math.Round(ExtraSettings.LiftSpeed1 * 60, 2);
- return (float)Math.Round(HeaderSettings.LiftSpeed * 60, 2);
- }
+ get => SpeedConverter.Convert(FileMarkSettings.Version >= VERSION_516 ? ExtraSettings.LiftSpeed1 : HeaderSettings.LiftSpeed, FormatSpeedUnit, CoreSpeedUnit);
set
{
value = (float)Math.Round(value, 2);
- HeaderSettings.LiftSpeed = ExtraSettings.LiftSpeed1 = (float)Math.Round(value / 60, 2);
+ HeaderSettings.LiftSpeed = ExtraSettings.LiftSpeed1 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.LiftSpeed = value;
}
}
@@ -1388,12 +1375,12 @@ public class PhotonWorkshopFile : FileFormat
public override float BottomLiftSpeed2
{
- get => FileMarkSettings.Version >= VERSION_516 ? (float)Math.Round(ExtraSettings.BottomLiftSpeed2 * 60, 2) : 0;
+ get => FileMarkSettings.Version >= VERSION_516 ? SpeedConverter.Convert(ExtraSettings.BottomLiftSpeed2, FormatSpeedUnit, CoreSpeedUnit) : 0;
set
{
if (FileMarkSettings.Version < VERSION_516) return;
value = (float)Math.Round(value, 2);
- ExtraSettings.BottomLiftSpeed2 = (float)Math.Round(value / 60, 2);
+ ExtraSettings.BottomLiftSpeed2 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.BottomLiftSpeed2 = value;
}
}
@@ -1413,67 +1400,59 @@ public class PhotonWorkshopFile : FileFormat
public override float LiftSpeed2
{
- get => FileMarkSettings.Version >= VERSION_516 ? (float)Math.Round(ExtraSettings.LiftSpeed2 * 60, 2) : 0;
+ get => FileMarkSettings.Version >= VERSION_516 ? SpeedConverter.Convert(ExtraSettings.LiftSpeed2, FormatSpeedUnit, CoreSpeedUnit) : 0;
set
{
if (FileMarkSettings.Version < VERSION_516) return;
- base.LiftSpeed2 = ExtraSettings.LiftSpeed2 = (float)Math.Round(value / 60, 2);
+ value = (float)Math.Round(value, 2);
+ ExtraSettings.LiftSpeed2 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
+ base.LiftSpeed2 = value;
}
}
public override float BottomRetractSpeed
{
- get
- {
- if (FileMarkSettings.Version >= VERSION_516) return (float)Math.Round(ExtraSettings.BottomRetractSpeed1 * 60, 2);
- return RetractSpeed;
- }
+ get => FileMarkSettings.Version >= VERSION_516 ? SpeedConverter.Convert(ExtraSettings.BottomRetractSpeed1, FormatSpeedUnit, CoreSpeedUnit) : RetractSpeed;
set
{
value = (float)Math.Round(value, 2);
- if (FileMarkSettings.Version >= VERSION_516)
- {
- ExtraSettings.BottomRetractSpeed1 = (float)Math.Round(value / 60, 2);
- }
- else
- {
- RetractSpeed = value;
- }
+ if (FileMarkSettings.Version < VERSION_516) return;
+ ExtraSettings.BottomRetractSpeed1 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
}
}
public override float RetractSpeed
{
- get => (float)Math.Round(HeaderSettings.RetractSpeed * 60, 2);
+ get => SpeedConverter.Convert(FileMarkSettings.Version >= VERSION_516 ? ExtraSettings.RetractSpeed1 : HeaderSettings.RetractSpeed, FormatSpeedUnit, CoreSpeedUnit);
set
{
value = (float)Math.Round(value, 2);
- ExtraSettings.RetractSpeed1 = HeaderSettings.RetractSpeed = (float) Math.Round(value / 60, 2);
+ ExtraSettings.RetractSpeed1 = HeaderSettings.RetractSpeed = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.RetractSpeed = value;
}
}
public override float BottomRetractSpeed2
{
- get => FileMarkSettings.Version >= VERSION_516 ? (float)Math.Round(ExtraSettings.BottomRetractSpeed2 * 60, 2) : 0;
+ get => FileMarkSettings.Version >= VERSION_516 ? SpeedConverter.Convert(ExtraSettings.BottomRetractSpeed2, FormatSpeedUnit, CoreSpeedUnit) : 0;
set
{
if (FileMarkSettings.Version < VERSION_516) return;
value = (float)Math.Round(value, 2);
- ExtraSettings.BottomRetractSpeed2 = (float)Math.Round(value / 60, 2);
+ ExtraSettings.BottomRetractSpeed2 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.BottomRetractSpeed2 = value;
}
}
public override float RetractSpeed2
{
- get => FileMarkSettings.Version >= VERSION_516 ? (float)Math.Round(ExtraSettings.RetractSpeed2 * 60, 2) : 0;
+ get => FileMarkSettings.Version >= VERSION_516 ? SpeedConverter.Convert(ExtraSettings.RetractSpeed2, FormatSpeedUnit, CoreSpeedUnit) : 0;
set
{
if (FileMarkSettings.Version < VERSION_516) return;
value = (float)Math.Round(value, 2);
- ExtraSettings.RetractSpeed2 = (float)Math.Round(value / 60, 2);
+ ExtraSettings.RetractSpeed2 = SpeedConverter.Convert(value, CoreSpeedUnit, FormatSpeedUnit);
base.RetractSpeed2 = value;
}
}
diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs
index c22cee7..a1c51ee 100644
--- a/UVtools.Core/Operations/Operation.cs
+++ b/UVtools.Core/Operations/Operation.cs
@@ -461,6 +461,13 @@ public abstract class Operation : BindableBase, IDisposable
return HaveROI ? _roi.Size : fallbackSize;
}
+ public Size GetRoiSizeOrVolumeSize() => GetRoiSizeOrVolumeSize(_originalBoundingRectangle.Size);
+
+ public Size GetRoiSizeOrVolumeSize(Size fallbackSize)
+ {
+ return HaveROI ? _roi.Size : fallbackSize;
+ }
+
public Mat GetRoiOrDefault(Mat defaultMat)
{
diff --git a/UVtools.Core/Operations/OperationInfill.cs b/UVtools.Core/Operations/OperationInfill.cs
index 5e2e5d6..9085ad3 100644
--- a/UVtools.Core/Operations/OperationInfill.cs
+++ b/UVtools.Core/Operations/OperationInfill.cs
@@ -10,8 +10,10 @@ using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
+using System.Linq;
using System.Threading.Tasks;
using UVtools.Core.Extensions;
using UVtools.Core.FileFormats;
@@ -25,8 +27,8 @@ public sealed class OperationInfill : Operation
private InfillAlgorithm _infillType = InfillAlgorithm.CubicCrossAlternating;
private ushort _wallThickness = 64;
private ushort _infillThickness = 45;
- private ushort _infillSpacing = 200;
- private ushort _infillBrightness = 255;
+ private ushort _infillSpacing = 300;
+ private byte _infillBrightness = 255;
private bool _reinforceInfill;
#endregion
@@ -55,6 +57,12 @@ public sealed class OperationInfill : Operation
[Description("Straight pillars (Weak)")]
Pillars,
+ [Description("Concentric (Weak)")]
+ Concentric,
+
+ [Description("Waves (Medium)")]
+ Waves,
+
[Description("Cubic cross: Fixed pilars with crossing sections (Optimal)")]
CubicCross,
@@ -65,7 +73,10 @@ public sealed class OperationInfill : Operation
CubicStar,
[Description("Honeycomb (Strong)")]
- Honeycomb
+ Honeycomb,
+
+ [Description("Gyroid (Strong)")]
+ Gyroid,
}
#endregion
@@ -82,7 +93,7 @@ public sealed class OperationInfill : Operation
set => RaiseAndSetIfChanged(ref _wallThickness, value);
}
- public ushort InfillBrightness
+ public byte InfillBrightness
{
get => _infillBrightness;
set => RaiseAndSetIfChanged(ref _infillBrightness, value);
@@ -149,7 +160,11 @@ public sealed class OperationInfill : Operation
Mat? mask = null;
if (_infillType == InfillAlgorithm.Honeycomb)
{
- mask = GetHoneycombMask(GetRoiSizeOrDefault());
+ mask = GetHoneycombMask(GetRoiSizeOrVolumeSize());
+ }
+ else if (_infillType == InfillAlgorithm.Concentric)
+ {
+ mask = GetConcentricMask(GetRoiSizeOrVolumeSize());
}
Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.GetParallelOptions(progress), layerIndex =>
@@ -176,7 +191,7 @@ public sealed class OperationInfill : Operation
Mat? patternMask = null;
using Mat erode = new ();
using Mat diff = new ();
- var target = GetRoiOrDefault(mat);
+ var target = GetRoiOrVolumeBounds(mat);
using var mask = GetMask(mat);
bool disposeTargetMask = true;
@@ -203,10 +218,6 @@ public sealed class OperationInfill : Operation
firstPattern = false;
accumulator += _infillThickness;
}
- else
- {
- //accumulator += _infillSpacing;
- }
}
if (firstPattern)
@@ -319,7 +330,7 @@ public sealed class OperationInfill : Operation
CvInvoke.Repeat(infillPattern, target.Rows / infillPattern.Rows + 1,
target.Cols / infillPattern.Cols + 1, matPattern);
- patternMask = new Mat(matPattern, new Rectangle(0, 0, target.Width, target.Height));
+ patternMask = matPattern.Roi(target);
disposeTargetMask = true;
}
else if (_infillType == InfillAlgorithm.Honeycomb)
@@ -335,6 +346,124 @@ public sealed class OperationInfill : Operation
disposeTargetMask = true;
}
}
+ else if (_infillType == InfillAlgorithm.Concentric)
+ {
+ if (arguments.Length >= 2)
+ {
+ patternMask = (Mat)arguments[1];
+ disposeTargetMask = false;
+ }
+ else
+ {
+ patternMask = GetConcentricMask(target.Size);
+ disposeTargetMask = true;
+ }
+ }
+ else if (_infillType == InfillAlgorithm.Waves)
+ {
+ var sineHeight = 100;
+ var sineWidth = 100;
+ var radius = (ushort)(_infillThickness / 2);
+
+ var points = new List();
+
+ bool isHorizontal = true;
+ float accumulator = 0;
+ for (int i = 0; i <= layerIndex; i++)
+ {
+ accumulator += SlicerFile[index].RelativePositionZ;
+ if (accumulator >= 2)
+ {
+ isHorizontal = !isHorizontal;
+ accumulator = 0;
+ }
+ }
+
+ //using var infillPattern = EmguExtensions.InitMat(new Size(_infillSpacing, _infillSpacing));
+ //using var matPattern = new Mat();
+ using var infillPattern = mat.NewBlank();
+
+ int maxY = 0;
+
+ if (isHorizontal)
+ {
+ for (int x = 0; x < mat.Width; x += radius)
+ {
+ int y = (int) (Math.Sin((double) x / sineWidth /*+ sineWidth * layerIndex*/) * sineHeight / 2.0 +
+ sineHeight / 2.0 + radius);
+ points.Add(new Point(x, y));
+ maxY = Math.Max(maxY, y);
+ }
+ var infillPatternRoi = infillPattern.Roi(new Size(infillPattern.Width, maxY + radius + 2 + _infillSpacing));
+ CvInvoke.Polylines(infillPatternRoi, points.ToArray(), false, infillColor, _infillThickness);
+
+ CvInvoke.Repeat(infillPatternRoi, target.Rows / infillPatternRoi.Rows + 1, 1, infillPattern);
+ }
+ else
+ {
+ for (int y = 0; y < mat.Height; y += radius)
+ {
+ int x = (int)(Math.Sin((double)y / sineWidth /*+ sineWidth * layerIndex*/) * sineHeight / 2.0 +
+ sineHeight / 2.0 + radius);
+ points.Add(new Point(x, y));
+ maxY = Math.Max(maxY, x);
+ }
+ var infillPatternRoi = infillPattern.Roi(new Size(maxY + radius + 2 + _infillSpacing, infillPattern.Height));
+ CvInvoke.Polylines(infillPatternRoi, points.ToArray(), false, infillColor, _infillThickness);
+ CvInvoke.Repeat(infillPatternRoi, 1, target.Cols / infillPatternRoi.Cols + 1, infillPattern);
+
+ }
+ points.Clear();
+
+ patternMask = infillPattern.Roi(target);
+ disposeTargetMask = true;
+ }
+ else if (_infillType == InfillAlgorithm.Gyroid)
+ {
+ patternMask = target.NewBlank();
+
+ var scaleRatio = 0.0012 / (_infillSpacing + _infillThickness / 2);
+ //var scaleX = 0.04 * _infillSpacing * Math.PI / target.Width;
+ //var scaleY = 0.04 * _infillSpacing * Math.PI / target.Height;
+ var scaleX = scaleRatio * mat.Width;
+ var scaleY = scaleRatio * mat.Height;
+
+ //const double scaleZ = 2.0 * Math.PI;
+ //var dz = 2.0 * scaleZ / LayerRangeCount; // z step
+ //var zz = 0.05 * (SlicerFile[index].LayerHeight / 0.05f) * (layerIndex + 1);
+ float zz = 0;
+ for (var i = LayerIndexStart; i <= index; i++)
+ {
+ zz += SlicerFile[i].RelativePositionZ;
+ }
+
+ for (int y = 0; y < patternMask.Height; y++)
+ {
+ var span = patternMask.GetRowSpan(y);
+ var yy = y * scaleY; // y position of pixel
+ for (int x = 0; x < patternMask.Width; x++)
+ {
+ var xx = x * scaleX; // x position of pixel
+
+ var d = Math.Sin(xx) * Math.Cos(yy) // compute gyroid equation
+ + Math.Sin(yy) * Math.Cos(zz)
+ + Math.Sin(zz) * Math.Cos(xx);
+ //if (d > 1e-6) continue; // Far from surface
+ if (Math.Abs(d) - 0.006*_infillThickness > 0) continue;
+ //if (d - 0.05 > 1e-6) continue;
+
+ span[x] = _infillBrightness;
+ }
+ }
+
+
+ //using var contours = patternMask.FindContours();
+ //CvInvoke.DrawContours(patternMask, contours, -1, infillColor, _infillThickness);
+
+ disposeTargetMask = true;
+ }
+
+
//patternMask.Save("D:\\pattern.png");
CvInvoke.Erode(target, erode, kernel, anchor, WallThickness, BorderType.Reflect101,
default);
@@ -390,5 +519,58 @@ public sealed class OperationInfill : Operation
return patternMask;
}
+ public Mat GetConcentricMask(Size targetSize)
+ {
+ var patternMask = EmguExtensions.InitMat(targetSize);
+
+ //var halfInfillSpacing = _infillSpacing / 2;
+ //var halfThickenss = _infillThickness / 2;
+ int multiplicator = 1;
+ byte position = 0;
+
+ int x = patternMask.Width / 2;
+ int y = patternMask.Height / 2;
+
+ Point[] directions = {
+ new(0, -_infillSpacing), // top
+ new(_infillSpacing, 0), // right
+ new(0, _infillSpacing), // bottom
+ new(-_infillSpacing, 0), // left
+ };
+
+ bool[] hitLimits =
+ {
+ false,
+ false,
+ false,
+ false
+ };
+
+ var points = new List {new(x, y)};
+
+ while (hitLimits.Any(hitLimit => !hitLimit))
+ {
+ x += directions[position].X * multiplicator;
+ y += directions[position].Y * multiplicator;
+ if (x < 0 || y < 0 || x >= patternMask.Width || y >= patternMask.Height) hitLimits[position] = true;
+ points.Add(new Point(x, y));
+ position++;
+ if (position == 2)
+ {
+ multiplicator++;
+ }
+ else if (position == 4)
+ {
+ multiplicator++;
+ position = 0;
+ }
+ }
+
+
+ CvInvoke.Polylines(patternMask, points.ToArray(), false, new MCvScalar(_infillBrightness), _infillThickness);
+
+ return patternMask;
+ }
+
#endregion
}
\ No newline at end of file
diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj
index f54b303..c9bc034 100644
--- a/UVtools.Core/UVtools.Core.csproj
+++ b/UVtools.Core/UVtools.Core.csproj
@@ -1,75 +1,85 @@
-
- net6.0
- true
- LICENSE
- PTRTECH
- Tiago Conceição
- Git
- https://github.com/sn4k3/UVtools
- https://github.com/sn4k3/UVtools
- MSLA/DLP, file analysis, calibration, repair, conversion and manipulation
- 3.2.0
- Copyright © 2020 PTRTECH
- UVtools.png
- AnyCPU;x64
- false
-
- msla, dlp, resin, printer, slicer, 3d printing, image processing, layers
- UVtools.ico
- README.md
- enable
-
+
+ net6.0
+ true
+ LICENSE
+ PTRTECH
+ Tiago Conceição
+ Git
+ https://github.com/sn4k3/UVtools
+ https://github.com/sn4k3/UVtools
+ MSLA/DLP, file analysis, calibration, repair, conversion and manipulation
+ 3.2.1
+ Copyright © 2020 PTRTECH
+ UVtools.png
+ AnyCPU;x64
+ false
+
+ msla, dlp, resin, printer, slicer, 3d printing, image processing, layers
+ UVtools.ico
+ README.md
+ enable
+
-
- true
-
-
+
+ true
+
+
-
- true
-
+
+ true
+
-
- true
-
+
+ true
+
-
- true
-
+
+ true
+
-
-
-
+
+
+
-
-
- True
-
-
-
- True
- \
-
-
- True
-
-
-
+
+
+ True
+
+
+
+ True
+ \
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @(ReleaseNoteLines, '%0a')
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/UVtools.InstallerMM/UVtools.InstallerMM.wxs b/UVtools.InstallerMM/UVtools.InstallerMM.wxs
index bd403a9..cc40285 100644
--- a/UVtools.InstallerMM/UVtools.InstallerMM.wxs
+++ b/UVtools.InstallerMM/UVtools.InstallerMM.wxs
@@ -2,7 +2,7 @@
-
+
diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml
index 15c9a9c..95b010c 100644
--- a/UVtools.WPF/MainWindow.axaml
+++ b/UVtools.WPF/MainWindow.axaml
@@ -13,2106 +13,2104 @@
MinHeight="600"
DragDrop.AllowDrop="True">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
+
-
-
+
+
+
+
-
+
-
+
+
+
-
-
+
-
+
+
+
+
+
+
-
-
+
-
+
-
+
-
+
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+ i:Attached.Icon="far fa-edit"/>
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
+
+
+
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+ IsEnabled="{Binding #IssuesGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
+ i:Attached.Icon="fas fa-eye-slash"
+ Command="{Binding OnClickIssueIgnore}"/>
-
+ IsEnabled="{Binding #IssuesGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
+ i:Attached.Icon="fas fa-trash-alt"
+ Command="{Binding OnClickIssueRemove}"/>
-
+
-
+
-
+
-
+ Icon="fas fa-sync-alt"
+ Spacing="5"
+ Text="Detect ⮟"
+ Command="{Binding OnClickDetectIssues}">
-
-
-
-
-
-
+
+
+
+
+
+
-
+ Minimum="0"
+ Maximum="{Binding SlicerFile.LastLayerIndex}"
+ Increment="1"
+ Width="110"
+ Value="{Binding ResinTrapDetectionStartLayer}"/>
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
-
-
+
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
-
-
+
-
-
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
-
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.PixelBrightness}"/>
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+ Value="{Binding DrawingPixelText.FontScale}"/>
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
-
+ Value="{Binding DrawingPixelText.RemovePixelBrightness}"/>
+
-
-
+
-
+ Value="{Binding DrawingPixelText.PixelBrightness}"/>
+
-
-
+
+
-
-
+
+
-
+
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
-
+ Value="{Binding DrawingPixelEraser.PixelBrightness}"/>
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
-
+ Value="{Binding DrawingPixelSupport.PixelBrightness}"/>
+
-
-
+
+
-
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
-
-
-
+
-
-
+
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
+
-
+
+
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
-
+
-
-
+
+
+
-
-
+
-
+
+
-
-
-
-
-
-
-
-
-
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+ Command="{Binding ZoomToFitPrintVolume}"
+ Margin="5,0,0,0"
+ Text="{Binding LayerBoundsStr}"
+ Spacing="5"
+ Icon="fas fa-expand"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Text="{Binding LayerROIStr}"
+ Spacing="5"
+ Icon="far fa-object-group">
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+ Text="{Binding LayerPixelPicker}"
+ Spacing="5"
+ Icon="fas fa-map-marker-alt"/>
-
+ Margin="2,0,0,0"
+ Command="{Binding ZoomToNormal}"
+ Text="{Binding LayerZoomStr}"
+ Spacing="5"
+ Icon="fas fa-search-plus"/>
-
+ Command="{Binding ZoomToFitSimple}"
+ Margin="2,0,0,0"
+ Text="{Binding LayerResolutionStr}"
+ Spacing="5"
+ Icon="fas fa-expand"/>
-
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/UVtools.WPF/Program.cs b/UVtools.WPF/Program.cs
index 27672a8..0fb088d 100644
--- a/UVtools.WPF/Program.cs
+++ b/UVtools.WPF/Program.cs
@@ -38,42 +38,9 @@ public static class Program
return;
}
- //var mat = EmguExtensions.InitMat(new System.Drawing.Size(2000, 1080));
- /*const byte z = 1;
- int pixel = 1000;
-
- for (int y = 0; y < mat.Height; y+=200)
- for (int x = 0; x < mat.Width; x+=1)
- {
- float x1 = x / (float)mat.Width;
- float y1 = y / (float)mat.Height;
-
- //var result = Math.Sin(x1) * Math.Cos(y1) + Math.Sin(y1) * Math.Cos(1) + Math.Sin(1) * Math.Cos(x1);
- //mat.SetByte((int) result* mat.Width, 255);
-
- //CvInvoke.Circle(mat, new Point(x, (int)pixelY + y), 1, EmguExtensions.WhiteColor, -1, LineType.AntiAlias);
- }*/
-
-
- /*var sineHeight = 100;
- var sineWidth = 100;
- byte radius = 10;
-
- for (int y1 = 0; y1 < mat.Height; y1 += sineHeight)
- for (int x = 0; x < mat.Width; x++)
- {
- int y2 = (int)(Math.Sin((double)x / sineWidth) * sineHeight / 2.0 + sineHeight / 2.0 + radius);
-
- CvInvoke.Circle(mat, new Point(x, y1+y2), radius, EmguExtensions.WhiteColor, -1, LineType.AntiAlias);
- }
-
- CvInvoke.Imshow("gyroid", mat);
- CvInvoke.WaitKey();
- return;*/
-
/*Slicer slicer = new(Size.Empty, SizeF.Empty, "D:\\Cube100x100x100.stl");
var slices = slicer.SliceModel(0.05f);
-
+
foreach (var slice in slices)
{
using var mat = EmguExtensions.InitMat(new Size(1000, 1000));
diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj
index 40f70d1..b41492a 100644
--- a/UVtools.WPF/UVtools.WPF.csproj
+++ b/UVtools.WPF/UVtools.WPF.csproj
@@ -12,7 +12,7 @@
LICENSE
https://github.com/sn4k3/UVtools
Git
- 3.2.0
+ 3.2.1
AnyCPU;x64
UVtools.png
README.md
@@ -44,9 +44,9 @@
-
-
-
+
+
+
diff --git a/build/createRelease.ps1 b/build/createRelease.ps1
index 40efdd9..b670883 100644
--- a/build/createRelease.ps1
+++ b/build/createRelease.ps1
@@ -202,6 +202,7 @@ $releaseFolder = "$project\bin\$buildWith\net$netVersion"
$objFolder = "$project\obj\$buildWith\net$netVersion"
$publishFolder = "publish"
$platformsFolder = "$buildFolder\platforms"
+$changelogFile = "$rootFolder\CHANGELOG.md"
#$version = (Get-Command "$releaseFolder\UVtools.dll").FileVersionInfo.ProductVersion
$projectXml = [Xml] (Get-Content "$project\$project.csproj")
@@ -277,6 +278,27 @@ $runtimes =
}
}
+# Set release notes on projects
+$changelog = Get-Content -Path "$changelogFile"
+$foundHashTag = $false
+$sb = [System.Text.StringBuilder]::new()
+foreach($line in $changelog) {
+ $line = $line.TrimEnd()
+ if($line -eq '') { continue }
+ if($line.StartsWith("##")) {
+ if(!$foundHashTag)
+ {
+ $foundHashTag = $true
+ continue
+ }
+ else { break }
+ }
+ elseif($foundHashTag){
+ [void]$sb.AppendLine($line)
+ }
+}
+Write-Host $sb.ToString()
+
if($null -ne $enableNugetPublish -and $enableNugetPublish)
{
@@ -388,7 +410,8 @@ if($null -ne $enableMSI -and $enableMSI)
{
$deployStopWatch.Restart()
$runtime = 'win-x64'
- if (Test-Path -Path $msiSourceFiles) {
+
+ if ((Test-Path -Path $msiSourceFiles) -and ((Get-ChildItem "$msiSourceFiles" | Measure-Object).Count) -gt 0) {
$msiTargetFile = "$publishFolder\${software}_${runtime}_v$version.msi"
Write-Output "################################"
Write-Output "Clean and build MSI components manifest file"