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

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Conceição <Tiago_caza@hotmail.com>2022-04-02 05:14:28 +0300
committerTiago Conceição <Tiago_caza@hotmail.com>2022-04-02 05:14:28 +0300
commitd38e9ee62dccf8c7cabc770c6d74f93ae9d5fe51 (patch)
tree1788f280278d969b3edb3c23278a6523c43a87b1
parent6d1972ed8f9dcdf85cad41aa5337b64ce27b573e (diff)
v3.2.1v3.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
-rw-r--r--CHANGELOG.md14
-rw-r--r--UVtools.AvaloniaControls/AdvancedImageBox.axaml.cs210
-rw-r--r--UVtools.AvaloniaControls/UVtools.AvaloniaControls.csproj2
-rw-r--r--UVtools.Core/Extensions/EmguExtensions.cs59
-rw-r--r--UVtools.Core/FileFormats/CXDLPFile.cs14
-rw-r--r--UVtools.Core/FileFormats/FileFormat.cs11
-rw-r--r--UVtools.Core/FileFormats/JXSFile.cs12
-rw-r--r--UVtools.Core/FileFormats/PhotonWorkshopFile.cs101
-rw-r--r--UVtools.Core/Operations/Operation.cs7
-rw-r--r--UVtools.Core/Operations/OperationInfill.cs204
-rw-r--r--UVtools.Core/UVtools.Core.csproj140
-rw-r--r--UVtools.InstallerMM/UVtools.InstallerMM.wxs2
-rw-r--r--UVtools.WPF/MainWindow.axaml3996
-rw-r--r--UVtools.WPF/Program.cs35
-rw-r--r--UVtools.WPF/UVtools.WPF.csproj8
-rw-r--r--build/createRelease.ps125
16 files changed, 2585 insertions, 2255 deletions
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)
+ {
+ PointerPosition = new Point(-1, -1);
+ TriggerRender(true);
+ e.Handled = true;
+ }
+
+ /*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)
+ {
+ if (e.Handled) return;
+
+ 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)
+ /*protected override void OnPointerMoved(PointerEventArgs e)
{
base.OnPointerMoved(e);
- if (e.Handled) return;
+ if (e.Handled || !ViewPort.IsPointerOver) return;
- var pointer = e.GetCurrentPoint(this);
+ 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
/// <returns></returns>
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 @@
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<Description>AvaloniaUI Controls
- AdvancedImageBox: Pan, zoom, cursor, pixel grid and selections image box</Description>
- <Version>2.0.0</Version>
+ <Version>2.0.1</Version>
<Nullable>enable</Nullable>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
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
/// <param name="mat"></param>
/// <returns></returns>
public static unsafe byte* GetBytePointer(this Mat mat)
- {
- return (byte*)mat.DataPointer.ToPointer();
- }
+ => (byte*)mat.DataPointer.ToPointer();
/// <summary>
/// Gets the whole data span to manipulate or read pixels
/// </summary>
/// <param name="mat"></param>
/// <returns></returns>
- public static unsafe Span<byte> GetDataByteSpan(this Mat mat)
- {
- return new(mat.DataPointer.ToPointer(), mat.GetLength());
- }
+ public static unsafe Span<byte> GetDataByteSpan(this Mat mat)
+ => new(mat.DataPointer.ToPointer(), mat.GetLength());
- public static unsafe Span<byte> 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<byte> GetDataByteSpan(this Mat mat, int length, int offset = 0)
+ => new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
/// <summary>
/// Gets the data span to manipulate or read pixels given a length and offset
@@ -201,10 +195,8 @@ public static class EmguExtensions
/// <param name="length"></param>
/// <param name="offset"></param>
/// <returns></returns>
- public static unsafe Span<T> GetDataSpan<T>(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<T> GetDataSpan<T>(this Mat mat, int length = 0, int offset = 0)
+ => new(IntPtr.Add(mat.DataPointer, offset).ToPointer(), length <= 0 ? mat.GetLength() : length);
/// <summary>
/// Gets a single pixel span to manipulate or read pixels
@@ -214,10 +206,8 @@ public static class EmguExtensions
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
- public static Span<T> GetPixelSpan<T>(this Mat mat, int x, int y)
- {
- return mat.GetDataSpan<T>(mat.NumberOfChannels, mat.GetPixelPos(x, y));
- }
+ public static Span<T> GetPixelSpan<T>(this Mat mat, int x, int y)
+ => mat.GetDataSpan<T>(mat.NumberOfChannels, mat.GetPixelPos(x, y));
/// <summary>
/// Gets a single pixel span to manipulate or read pixels
@@ -226,10 +216,8 @@ public static class EmguExtensions
/// <param name="mat"></param>
/// <param name="pos"></param>
/// <returns></returns>
- public static Span<T> GetPixelSpan<T>(this Mat mat, int pos)
- {
- return mat.GetDataSpan<T>(mat.NumberOfChannels, pos);
- }
+ public static Span<T> GetPixelSpan<T>(this Mat mat, int pos)
+ => mat.GetDataSpan<T>(mat.NumberOfChannels, pos);
/// <summary>
/// Gets a row span to manipulate or read pixels
@@ -240,10 +228,8 @@ public static class EmguExtensions
/// <param name="length"></param>
/// <param name="offset"></param>
/// <returns></returns>
- public static unsafe Span<T> GetRowSpan<T>(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<T> GetRowSpan<T>(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);
/// <summary>
/// Gets a col span to manipulate or read pixels
@@ -325,7 +311,7 @@ public static class EmguExtensions
}
/// <summary>
- /// Gets the total length of this <see cref="Mat"/></param>
+ /// Gets the total length of this <see cref="Mat"/>
/// </summary>
/// <param name="mat"></param>
/// <returns>The total length of this <see cref="Mat"/></returns>
@@ -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<FileFor
{
#region Constants
- public const SpeedUnit DefaultSpeedUnit = SpeedUnit.MillimetersPerMinute;
+ public const SpeedUnit CoreSpeedUnit = SpeedUnit.MillimetersPerMinute;
public const string TemporaryFileAppend = ".tmp";
public const ushort ExtraPrintTime = 300;
@@ -994,6 +994,8 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
#region Properties
+ public FileDecodeType DecodeType { get; private set; } = FileDecodeType.Full;
+
/// <summary>
/// Gets the file format type
/// </summary>
@@ -1004,8 +1006,11 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
/// </summary>
public abstract FileExtension[] FileExtensions { get; }
- public FileDecodeType DecodeType { get; private set; } = FileDecodeType.Full;
-
+ /// <summary>
+ /// The speed unit used by this file format in his internal data
+ /// </summary>
+ public virtual SpeedUnit FormatSpeedUnit => CoreSpeedUnit;
+
/// <summary>
/// Gets the available <see cref="PrintParameterModifier"/>
/// </summary>
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
/// <summary>
/// 58
/// </summary>
- [FieldOrder(7)] public float LiftHeight { get; set; } = 6;
+ [FieldOrder(7)] public float LiftHeight { get; set; } = DefaultLiftHeight;
/// <summary>
/// Gets the lift speed in mm/s
/// 5C
/// </summary>
- [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
/// <summary>
/// Gets the retract speed in mm/s
/// 60
/// </summary>
- [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
/// <summary>
/// 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<Point>();
+
+ 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<byte>(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<Point> {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 @@
<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>net6.0</TargetFramework>
- <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
- <PackageLicenseFile>LICENSE</PackageLicenseFile>
- <Company>PTRTECH</Company>
- <Authors>Tiago Conceição</Authors>
- <RepositoryType>Git</RepositoryType>
- <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
- <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
- <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
- <Version>3.2.0</Version>
- <Copyright>Copyright © 2020 PTRTECH</Copyright>
- <PackageIcon>UVtools.png</PackageIcon>
- <Platforms>AnyCPU;x64</Platforms>
- <SignAssembly>false</SignAssembly>
- <PackageIconUrl />
- <PackageTags>msla, dlp, resin, printer, slicer, 3d printing, image processing, layers</PackageTags>
- <ApplicationIcon>UVtools.ico</ApplicationIcon>
- <PackageReadmeFile>README.md</PackageReadmeFile>
- <Nullable>enable</Nullable>
- </PropertyGroup>
+ <PropertyGroup>
+ <TargetFramework>net6.0</TargetFramework>
+ <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
+ <PackageLicenseFile>LICENSE</PackageLicenseFile>
+ <Company>PTRTECH</Company>
+ <Authors>Tiago Conceição</Authors>
+ <RepositoryType>Git</RepositoryType>
+ <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
+ <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
+ <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
+ <Version>3.2.1</Version>
+ <Copyright>Copyright © 2020 PTRTECH</Copyright>
+ <PackageIcon>UVtools.png</PackageIcon>
+ <Platforms>AnyCPU;x64</Platforms>
+ <SignAssembly>false</SignAssembly>
+ <PackageIconUrl />
+ <PackageTags>msla, dlp, resin, printer, slicer, 3d printing, image processing, layers</PackageTags>
+ <ApplicationIcon>UVtools.ico</ApplicationIcon>
+ <PackageReadmeFile>README.md</PackageReadmeFile>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <DocumentationFile></DocumentationFile>
- </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DocumentationFile></DocumentationFile>
+ </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
- <ItemGroup>
- <Content Include="UVtools.ico" />
- </ItemGroup>
+ <ItemGroup>
+ <Content Include="UVtools.ico" />
+ </ItemGroup>
- <ItemGroup>
- <None Include="..\LICENSE">
- <Pack>True</Pack>
- <PackagePath></PackagePath>
- </None>
- <None Include="..\README.md">
- <Pack>True</Pack>
- <PackagePath>\</PackagePath>
- </None>
- <None Include="..\UVtools.CAD\UVtools.png">
- <Pack>True</Pack>
- <PackagePath></PackagePath>
- </None>
- </ItemGroup>
+ <ItemGroup>
+ <None Include="..\LICENSE">
+ <Pack>True</Pack>
+ <PackagePath></PackagePath>
+ </None>
+ <None Include="..\README.md">
+ <Pack>True</Pack>
+ <PackagePath>\</PackagePath>
+ </None>
+ <None Include="..\UVtools.CAD\UVtools.png">
+ <Pack>True</Pack>
+ <PackagePath></PackagePath>
+ </None>
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="AnimatedGif" Version="1.0.5" />
+ <PackageReference Include="BinarySerializer" Version="8.6.2.2" />
+ <PackageReference Include="Emgu.CV" Version="4.5.5.4823" />
+ <PackageReference Include="Emgu.CV.runtime.ubuntu.20.04-x64" Version="4.5.4.4788" />
+ <PackageReference Include="Emgu.CV.runtime.windows" Version="4.5.5.4823" />
+ <PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
+ <PackageReference Include="KdTree" Version="1.4.1" />
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.1.0" />
+ <PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
+ <PackageReference Include="System.Memory" Version="4.5.4" />
+ <PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" />
+ <PackageReference Include="System.Text.Json" Version="6.0.2" />
+ </ItemGroup>
+
+ <Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec">
+ <ReadLinesFromFile File="../CHANGELOG.md">
+ <Output TaskParameter="Lines" ItemName="ReleaseNoteLines" />
+ </ReadLinesFromFile>
+ <PropertyGroup>
+ <PackageReleaseNotes>@(ReleaseNoteLines, '%0a')</PackageReleaseNotes>
+ </PropertyGroup>
+ </Target>
- <ItemGroup>
- <PackageReference Include="AnimatedGif" Version="1.0.5" />
- <PackageReference Include="BinarySerializer" Version="8.6.2.2" />
- <PackageReference Include="Emgu.CV" Version="4.5.5.4823" />
- <PackageReference Include="Emgu.CV.runtime.ubuntu.20.04-x64" Version="4.5.4.4788" />
- <PackageReference Include="Emgu.CV.runtime.windows" Version="4.5.5.4823" />
- <PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
- <PackageReference Include="KdTree" Version="1.4.1" />
- <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.1.0" />
- <PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
- <PackageReference Include="System.Memory" Version="4.5.4" />
- <PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" />
- <PackageReference Include="System.Text.Json" Version="6.0.2" />
- </ItemGroup>
</Project>
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 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ComponentRules="OneToOne"?>
<!-- SourceDir instructs IsWiX the location of the directory that contains files for this merge module -->
- <?define SourceDir="..\publish\UVtools_win-x64_v3.2.0"?>
+ <?define SourceDir="..\publish\UVtools_win-x64_v3.2.1"?>
<Module Id="UVtools" Language="1033" Version="1.0.0.0">
<Package Id="12aaa1cf-ff06-4a02-abd5-2ac01ac4f83b" Manufacturer="PTRTECH" InstallerVersion="200" Keywords="MSLA, DLP" Description="MSLA/DLP, file analysis, repair, conversion and manipulation" InstallScope="perMachine" Platform="x64" />
<Directory Id="TARGETDIR" Name="SourceDir">
diff --git a/UVtools.WPF/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">
- <Grid RowDefinitions="*" ColumnDefinitions="*">
- <DockPanel Grid.Row="0" Grid.Column="0" IsEnabled="{Binding IsGUIEnabled}">
- <Menu DockPanel.Dock="Top">
- <MenuItem Name="MainMenu.File" Header="_File">
- <MenuItem Name="MainMenu.File.Open"
- Header="_Open"
- HotKey="Ctrl+O" InputGesture="Ctrl+O"
- Command="{Binding MenuFileOpenClicked}"
- i:MenuItem.Icon="fas fa-file-import"/>
-
- <MenuItem Name="MainMenu.File.OpenNewWindow"
- Header="Open in _new window"
- HotKey="Ctrl+Shift+O" InputGesture="Ctrl+Shift+O"
- Command="{Binding MenuFileOpenNewWindowClicked}"
- i:MenuItem.Icon="fas fa-file-import"/>
-
- <MenuItem Name="MainMenu.File.OpenRecent"
- Header="Open recent"
- ToolTip.ShowDelay="2000"
- ToolTip.Tip="On a file:
+ <Grid RowDefinitions="*" ColumnDefinitions="*">
+ <DockPanel Grid.Row="0" Grid.Column="0" IsEnabled="{Binding IsGUIEnabled}">
+ <Menu DockPanel.Dock="Top">
+ <MenuItem Name="MainMenu.File" Header="_File">
+ <MenuItem Name="MainMenu.File.Open"
+ Header="_Open"
+ HotKey="Ctrl+O" InputGesture="Ctrl+O"
+ Command="{Binding MenuFileOpenClicked}"
+ i:MenuItem.Icon="fas fa-file-import"/>
+
+ <MenuItem Name="MainMenu.File.OpenNewWindow"
+ Header="Open in _new window"
+ HotKey="Ctrl+Shift+O" InputGesture="Ctrl+Shift+O"
+ Command="{Binding MenuFileOpenNewWindowClicked}"
+ i:MenuItem.Icon="fas fa-file-import"/>
+
+ <MenuItem Name="MainMenu.File.OpenRecent"
+ Header="Open recent"
+ ToolTip.ShowDelay="2000"
+ ToolTip.Tip="On a file:
&#x0a;Shift + Click: Open file in a new window
&#x0a;Shift + Ctrl + Click: Remove file from list
&#x0a;Ctrl + Click: Purge non-existing files"
- Items="{Binding MenuFileOpenRecentItems}"
- i:MenuItem.Icon="fas fa-file-import"/>
+ Items="{Binding MenuFileOpenRecentItems}"
+ i:MenuItem.Icon="fas fa-file-import"/>
- <MenuItem Name="MainMenu.File.OpenInPartialMode"
- Header="Open in partial mode"
- Command="{Binding MenuFileOpenInPartialModeClicked}"
- ToolTip.Tip="Open a file only to see and/or edit properties.
+ <MenuItem Name="MainMenu.File.OpenInPartialMode"
+ Header="Open in partial mode"
+ Command="{Binding MenuFileOpenInPartialModeClicked}"
+ ToolTip.Tip="Open a file only to see and/or edit properties.
&#x0a;Layer images won't be loaded and most tools won't run in this mode."
- i:MenuItem.Icon="fas fa-file-import"/>
-
- <MenuItem Name="MainMenu.File.Reload"
- Header="_Reload"
- HotKey="Ctrl+F5" InputGesture="Ctrl+F5"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding ReloadFile}"
- i:MenuItem.Icon="mdi-file-restore"/>
-
- <MenuItem Name="MainMenu.File.Save"
- Header="_Save"
- HotKey="Ctrl+S" InputGesture="Ctrl+S"
- IsEnabled="{Binding CanSave}"
- Command="{Binding MenuFileSaveClicked}"
- i:MenuItem.Icon="fas fa-save"/>
-
- <MenuItem Name="MainMenu.File.SaveAs"
- Header="Save _as"
- HotKey="Ctrl+Shift+S" InputGesture="Ctrl+Shift+S"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding MenuFileSaveAsClicked}"
- i:MenuItem.Icon="fas fa-save"/>
-
- <MenuItem Name="MainMenu.File.SendTo"
- Header="Send to"
- IsEnabled="{Binding IsFileLoaded}"
- Items="{Binding MenuFileSendToItems}"
- i:MenuItem.Icon="fas fa-share-square"/>
-
- <MenuItem Name="MainMenu.File.Close"
- Header="_Close"
- HotKey="Ctrl+W" InputGesture="Ctrl+W"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding OnMenuFileCloseFile}"
- i:MenuItem.Icon="fas fa-sign-out-alt"/>
-
- <Separator/>
-
- <MenuItem Header="I _printed this file" HotKey="Ctrl+P" InputGesture="Ctrl+P"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding IPrintedThisFile}"
- i:MenuItem.Icon="fas fa-flask"/>
-
- <MenuItem Name="MainMenu.File.OpenContainingFileFolder"
- Header="Open containing fo_lder"
- HotKey="Ctrl+Shift+L" InputGesture="Ctrl+Shift+L"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding MenuFileOpenContainingFolderClicked}"
- i:MenuItem.Icon="fas fa-folder-open"/>
-
- <MenuItem Name="MainMenu.File.Extract"
- Header="_Extract file contents" HotKey="Ctrl+E" InputGesture="Ctrl+E"
- IsEnabled="{Binding IsFileLoaded}"
- Command="{Binding ExtractFile}"
- i:MenuItem.Icon="fas fa-box-open"/>
-
- <MenuItem Name="MainMenu.File.Terminal"
- HotKey="Ctrl+Shift+T" InputGesture="Ctrl+Shift+T"
- Header="_Terminal"
- Command="{Binding OpenTerminal}"
- IsEnabled="{Binding IsFileLoaded}"
- i:MenuItem.Icon="fas fa-terminal"/>
-
-
- <MenuItem Name="MainMenu.File.Convert"
- Header="_Convert to"
- IsEnabled="{Binding IsFileLoaded}"
- IsVisible="{Binding MenuFileConvertItems, Converter={x:Static ObjectConverters.IsNotNull}}"
- Items="{Binding MenuFileConvertItems}"
- i:MenuItem.Icon="fas fa-exchange-alt"/>
-
- <Separator/>
-
- <MenuItem Name="MainMenu.File.Fullscreen"
- Header="_Fullscreen"
- InputGesture="F11" HotKey="F11"
- Command="{Binding OnMenuFileFullscreen}"
- i:MenuItem.Icon="fas fa-window-maximize"/>
-
- <MenuItem Name="MainMenu.File.Settings"
- Header="_Settings"
- InputGesture="F12" HotKey="F12"
- Command="{Binding MenuFileSettingsClicked}"
- i:MenuItem.Icon="fas fa-cog"/>
-
- <Separator/>
-
- <MenuItem Name="MainMenu.File.Exit"
- Header="_Exit"
- InputGesture="Alt+F4"
- Command="{Binding Close}"
- i:MenuItem.Icon="fas fa-door-open"/>
- </MenuItem>
-
- <MenuItem Header="_Tools"
- IsVisible="{Binding IsFileLoaded}"
- IsEnabled="{Binding IsFileLoaded}"
- Items="{Binding MenuTools}">
- </MenuItem>
-
- <MenuItem Header="_Calibration"
- IsVisible="{Binding IsFileLoaded}"
- IsEnabled="{Binding IsFileLoaded}"
- Items="{Binding MenuCalibration}">
- </MenuItem>
-
-
- <MenuItem Header="_Help">
- <MenuItem Header="_About"
- InputGesture="F1" HotKey="F1"
- Command="{Binding MenuHelpAboutClicked}"
- i:MenuItem.Icon="fas fa-info-circle"/>
-
- <MenuItem Header="_Website"
- InputGesture="Ctrl + F1" HotKey="Ctrl + F1"
- Command="{Binding OpenHomePage}"
- i:MenuItem.Icon="fab fa-edge"/>
-
- <MenuItem Header="Wi_ki &amp; tutorials"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://github.com/sn4k3/UVtools/wiki"
- i:MenuItem.Icon="fab fa-wikipedia-w"/>
-
- <MenuItem Header="_Facebook group"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://www.facebook.com/groups/uvtools"
- i:MenuItem.Icon="fab fa-facebook"/>
-
- <MenuItem Header="_Donate"
- Command="{Binding OpenDonateWebsite}"
- i:MenuItem.Icon="fas fa-donate"/>
-
- <MenuItem Header="_Sponsor"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://github.com/sponsors/sn4k3"
- i:MenuItem.Icon="fas fa-heart"/>
-
- <Separator/>
-
- <MenuItem Header="_Material manager"
- HotKey="F10"
- InputGesture="F10"
- Command="{Binding MenuHelpMaterialManagerClicked}"
- i:MenuItem.Icon="fas fa-flask"/>
-
- <MenuItem Header="_Install profiles into PrusaSlicer"
- Command="{Binding MenuHelpInstallProfilesClicked}"
- i:MenuItem.Icon="fas fa-list"/>
-
- <Separator/>
-
- <MenuItem Header="_Benchmark"
- Command="{Binding MenuHelpBenchmarkClicked}"
- i:MenuItem.Icon="fas fa-microchip"/>
-
- <Separator/>
-
- <MenuItem Header="_Open settings folder"
- Command="{Binding MenuHelpOpenSettingsFolderClicked}"
- i:MenuItem.Icon="fas fa-folder-open"/>
-
- <Separator/>
-
- <MenuItem Header="_Report a issue"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://github.com/sn4k3/UVtools/issues/new?assignees=sn4k3&amp;labels=&amp;template=bug_report.md&amp;title=%5BBUG%5D+"
- i:MenuItem.Icon="fas fa-bug"/>
-
- <MenuItem Header="Ask a _question"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://github.com/sn4k3/UVtools/discussions/categories/q-a"
- i:MenuItem.Icon="fas fa-question"/>
-
- <MenuItem Header="Suggest an improvement or new features"
- Command="{Binding OpenWebsite}"
- CommandParameter="https://github.com/sn4k3/UVtools/discussions/categories/ideas"
- i:MenuItem.Icon="fas fa-lightbulb"/>
-
- </MenuItem>
-
- <MenuItem Background="LimeGreen"
- IsVisible="{Binding VersionChecker.HaveNewVersion}"
- Header="{Binding VersionChecker.VersionAnnouncementText}"
- Command="{Binding MenuNewVersionClicked}">
- </MenuItem>
-
- </Menu>
-
- <Border Padding="5" DockPanel.Dock="Bottom" IsVisible="{Binding IsFileLoaded}">
- <WrapPanel
- Orientation="Horizontal"
- VerticalAlignment="Center">
- <TextBlock Text="{Binding SlicerFile.LayerHeight, StringFormat=Layer height: \{0\}mm}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseBottomLayerCount}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseBottomLayerCount}"
- Text="{Binding SlicerFile.BottomLayerCount, StringFormat=Bottom layers: {0}}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyExposureTime}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyExposureTime}"
- Text="{Binding SlicerFile.ExposureRepresentation, StringFormat=Exposure: {0}}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}"
- Text="{Binding SlicerFile.LiftRepresentation, StringFormat=Lift: {0}}"/>
-
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}"
- Text="{Binding SlicerFile.RetractRepresentation, StringFormat=Retract: {0}}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}"
- Text="{Binding SlicerFile.LightOffDelayRepresentation, StringFormat=Light-off: {0}}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyWaitTime}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyWaitTime}"
- ToolTip.Tip="Wait time: Before cure / After cure / After lift"
- Text="{Binding SlicerFile.WaitTimeRepresentation, StringFormat=Wait time: {0}}"/>
-
- <TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}"
- Text="{Binding SlicerFile.PrintTimeString, StringFormat=Print time: \{0\}}"/>
-
-
- <TextBlock IsVisible="{Binding SlicerFile.MaterialMilliliters}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.MaterialMilliliters}"
- Text="{Binding SlicerFile.MaterialMilliliters, StringFormat=Used material: \{0\}ml}"/>
-
-
- <TextBlock IsVisible="{Binding SlicerFile.MaterialCost}" Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.MaterialCost}" Text="{Binding SlicerFile.MaterialCost, StringFormat=Material cost: \{0\}€}"/>
-
-
- <TextBlock IsVisible="{Binding SlicerFile.MaterialName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
- Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.MaterialName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
- Text="{Binding SlicerFile.MaterialName, StringFormat=Material: \{0\}}"/>
-
-
- <TextBlock IsVisible="{Binding SlicerFile.MachineName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
- Text=" | "/>
- <TextBlock IsVisible="{Binding SlicerFile.MachineName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
- Text="{Binding SlicerFile.MachineName, StringFormat=Machine: \{0\}}"/>
- </WrapPanel>
- </Border>
-
- <TabControl
- DockPanel.Dock="Left"
- Width="400"
- SelectedItem="{Binding SelectedTabItem}">
- <TabControl.Styles>
- <Style Selector="TabItem">
- <Setter Property="FontSize" Value="32"/>
- </Style>
- </TabControl.Styles>
- <TabItem
- Name="TabInformation"
- ToolTip.Tip="Information"
- IsEnabled="{Binding IsFileLoaded}">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-info-circle"/>
- <!--<TextBlock Margin="5,0,0,0">Information</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid ColumnDefinitions="*" IsVisible="{Binding IsFileLoaded}">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto" MaxHeight="400"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*" MinHeight="200"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto" MinHeight="220"/>
- </Grid.RowDefinitions>
- <!-- Thumbnails -->
- <StackPanel Grid.Row="0"
- IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
+ i:MenuItem.Icon="fas fa-file-import"/>
+
+ <MenuItem Name="MainMenu.File.Reload"
+ Header="_Reload"
+ HotKey="Ctrl+F5" InputGesture="Ctrl+F5"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding ReloadFile}"
+ i:MenuItem.Icon="mdi-file-restore"/>
+
+ <MenuItem Name="MainMenu.File.Save"
+ Header="_Save"
+ HotKey="Ctrl+S" InputGesture="Ctrl+S"
+ IsEnabled="{Binding CanSave}"
+ Command="{Binding MenuFileSaveClicked}"
+ i:MenuItem.Icon="fas fa-save"/>
+
+ <MenuItem Name="MainMenu.File.SaveAs"
+ Header="Save _as"
+ HotKey="Ctrl+Shift+S" InputGesture="Ctrl+Shift+S"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding MenuFileSaveAsClicked}"
+ i:MenuItem.Icon="fas fa-save"/>
+
+ <MenuItem Name="MainMenu.File.SendTo"
+ Header="Send to"
+ IsEnabled="{Binding IsFileLoaded}"
+ Items="{Binding MenuFileSendToItems}"
+ i:MenuItem.Icon="fas fa-share-square"/>
+
+ <MenuItem Name="MainMenu.File.Close"
+ Header="_Close"
+ HotKey="Ctrl+W" InputGesture="Ctrl+W"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding OnMenuFileCloseFile}"
+ i:MenuItem.Icon="fas fa-sign-out-alt"/>
+
+ <Separator/>
+
+ <MenuItem Header="I _printed this file" HotKey="Ctrl+P" InputGesture="Ctrl+P"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding IPrintedThisFile}"
+ i:MenuItem.Icon="fas fa-flask"/>
+
+ <MenuItem Name="MainMenu.File.OpenContainingFileFolder"
+ Header="Open containing fo_lder"
+ HotKey="Ctrl+Shift+L" InputGesture="Ctrl+Shift+L"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding MenuFileOpenContainingFolderClicked}"
+ i:MenuItem.Icon="fas fa-folder-open"/>
+
+ <MenuItem Name="MainMenu.File.Extract"
+ Header="_Extract file contents" HotKey="Ctrl+E" InputGesture="Ctrl+E"
+ IsEnabled="{Binding IsFileLoaded}"
+ Command="{Binding ExtractFile}"
+ i:MenuItem.Icon="fas fa-box-open"/>
+
+ <MenuItem Name="MainMenu.File.Terminal"
+ HotKey="Ctrl+Shift+T" InputGesture="Ctrl+Shift+T"
+ Header="_Terminal"
+ Command="{Binding OpenTerminal}"
+ IsEnabled="{Binding IsFileLoaded}"
+ i:MenuItem.Icon="fas fa-terminal"/>
+
+
+ <MenuItem Name="MainMenu.File.Convert"
+ Header="_Convert to"
+ IsEnabled="{Binding IsFileLoaded}"
+ IsVisible="{Binding MenuFileConvertItems, Converter={x:Static ObjectConverters.IsNotNull}}"
+ Items="{Binding MenuFileConvertItems}"
+ i:MenuItem.Icon="fas fa-exchange-alt"/>
+
+ <Separator/>
+
+ <MenuItem Name="MainMenu.File.Fullscreen"
+ Header="_Fullscreen"
+ InputGesture="F11" HotKey="F11"
+ Command="{Binding OnMenuFileFullscreen}"
+ i:MenuItem.Icon="fas fa-window-maximize"/>
+
+ <MenuItem Name="MainMenu.File.Settings"
+ Header="_Settings"
+ InputGesture="F12" HotKey="F12"
+ Command="{Binding MenuFileSettingsClicked}"
+ i:MenuItem.Icon="fas fa-cog"/>
+
+ <Separator/>
+
+ <MenuItem Name="MainMenu.File.Exit"
+ Header="_Exit"
+ InputGesture="Alt+F4"
+ Command="{Binding Close}"
+ i:MenuItem.Icon="fas fa-door-open"/>
+ </MenuItem>
+
+ <MenuItem Header="_Tools"
+ IsVisible="{Binding IsFileLoaded}"
+ IsEnabled="{Binding IsFileLoaded}"
+ Items="{Binding MenuTools}">
+ </MenuItem>
+
+ <MenuItem Header="_Calibration"
+ IsVisible="{Binding IsFileLoaded}"
+ IsEnabled="{Binding IsFileLoaded}"
+ Items="{Binding MenuCalibration}">
+ </MenuItem>
+
+
+ <MenuItem Header="_Help">
+ <MenuItem Header="_About"
+ InputGesture="F1" HotKey="F1"
+ Command="{Binding MenuHelpAboutClicked}"
+ i:MenuItem.Icon="fas fa-info-circle"/>
+
+ <MenuItem Header="_Website"
+ InputGesture="Ctrl + F1" HotKey="Ctrl + F1"
+ Command="{Binding OpenHomePage}"
+ i:MenuItem.Icon="fab fa-edge"/>
+
+ <MenuItem Header="Wi_ki &amp; tutorials"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://github.com/sn4k3/UVtools/wiki"
+ i:MenuItem.Icon="fab fa-wikipedia-w"/>
+
+ <MenuItem Header="_Facebook group"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://www.facebook.com/groups/uvtools"
+ i:MenuItem.Icon="fab fa-facebook"/>
+
+ <MenuItem Header="_Donate"
+ Command="{Binding OpenDonateWebsite}"
+ i:MenuItem.Icon="fas fa-donate"/>
+
+ <MenuItem Header="_Sponsor"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://github.com/sponsors/sn4k3"
+ i:MenuItem.Icon="fas fa-heart"/>
+
+ <Separator/>
+
+ <MenuItem Header="_Material manager"
+ HotKey="F10"
+ InputGesture="F10"
+ Command="{Binding MenuHelpMaterialManagerClicked}"
+ i:MenuItem.Icon="fas fa-flask"/>
+
+ <MenuItem Header="_Install profiles into PrusaSlicer"
+ Command="{Binding MenuHelpInstallProfilesClicked}"
+ i:MenuItem.Icon="fas fa-list"/>
+
+ <Separator/>
+
+ <MenuItem Header="_Benchmark"
+ Command="{Binding MenuHelpBenchmarkClicked}"
+ i:MenuItem.Icon="fas fa-microchip"/>
+
+ <Separator/>
+
+ <MenuItem Header="_Open settings folder"
+ Command="{Binding MenuHelpOpenSettingsFolderClicked}"
+ i:MenuItem.Icon="fas fa-folder-open"/>
+
+ <Separator/>
+
+ <MenuItem Header="_Report a issue"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://github.com/sn4k3/UVtools/issues/new?assignees=sn4k3&amp;labels=&amp;template=bug_report.md&amp;title=%5BBUG%5D+"
+ i:MenuItem.Icon="fas fa-bug"/>
+
+ <MenuItem Header="Ask a _question"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://github.com/sn4k3/UVtools/discussions/categories/q-a"
+ i:MenuItem.Icon="fas fa-question"/>
+
+ <MenuItem Header="Suggest an improvement or new features"
+ Command="{Binding OpenWebsite}"
+ CommandParameter="https://github.com/sn4k3/UVtools/discussions/categories/ideas"
+ i:MenuItem.Icon="fas fa-lightbulb"/>
+
+ </MenuItem>
+
+ <MenuItem Background="LimeGreen"
+ IsVisible="{Binding VersionChecker.HaveNewVersion}"
+ Header="{Binding VersionChecker.VersionAnnouncementText}"
+ Command="{Binding MenuNewVersionClicked}">
+ </MenuItem>
+
+ </Menu>
+
+ <Border Padding="5" DockPanel.Dock="Bottom" IsVisible="{Binding IsFileLoaded}">
+ <WrapPanel
+ Orientation="Horizontal"
+ VerticalAlignment="Center">
+ <TextBlock Text="{Binding SlicerFile.LayerHeight, StringFormat=Layer height: \{0\}mm}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseBottomLayerCount}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseBottomLayerCount}"
+ Text="{Binding SlicerFile.BottomLayerCount, StringFormat=Bottom layers: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyExposureTime}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyExposureTime}"
+ Text="{Binding SlicerFile.ExposureRepresentation, StringFormat=Exposure: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLiftHeight}"
+ Text="{Binding SlicerFile.LiftRepresentation, StringFormat=Lift: {0}}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseRetractSpeed}"
+ Text="{Binding SlicerFile.RetractRepresentation, StringFormat=Retract: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyLightOffDelay}"
+ Text="{Binding SlicerFile.LightOffDelayRepresentation, StringFormat=Light-off: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyWaitTime}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.CanUseAnyWaitTime}"
+ ToolTip.Tip="Wait time: Before cure / After cure / After lift"
+ Text="{Binding SlicerFile.WaitTimeRepresentation, StringFormat=Wait time: {0}}"/>
+
+ <TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.PrintTimeHours}"
+ Text="{Binding SlicerFile.PrintTimeString, StringFormat=Print time: \{0\}}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialMilliliters}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialMilliliters}"
+ Text="{Binding SlicerFile.MaterialMilliliters, StringFormat=Used material: \{0\}ml}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialCost}" Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialCost}" Text="{Binding SlicerFile.MaterialCost, StringFormat=Material cost: \{0\}€}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
+ Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.MaterialName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
+ Text="{Binding SlicerFile.MaterialName, StringFormat=Material: \{0\}}"/>
+
+
+ <TextBlock IsVisible="{Binding SlicerFile.MachineName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
+ Text=" | "/>
+ <TextBlock IsVisible="{Binding SlicerFile.MachineName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
+ Text="{Binding SlicerFile.MachineName, StringFormat=Machine: \{0\}}"/>
+ </WrapPanel>
+ </Border>
+
+ <TabControl
+ DockPanel.Dock="Left"
+ Width="400"
+ SelectedItem="{Binding SelectedTabItem}">
+ <TabControl.Styles>
+ <Style Selector="TabItem">
+ <Setter Property="FontSize" Value="32"/>
+ </Style>
+ </TabControl.Styles>
+ <TabItem
+ Name="TabInformation"
+ ToolTip.Tip="Information"
+ IsEnabled="{Binding IsFileLoaded}">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-info-circle"/>
+ <!--<TextBlock Margin="5,0,0,0">Information</TextBlock>!-->
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid ColumnDefinitions="*" IsVisible="{Binding IsFileLoaded}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto" MaxHeight="400"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*" MinHeight="200"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto" MinHeight="220"/>
+ </Grid.RowDefinitions>
+ <!-- Thumbnails -->
+ <StackPanel Grid.Row="0"
+ IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
+ Orientation="Horizontal"
+ Spacing="5"
+ VerticalAlignment="Center">
+ <Button IsEnabled="{Binding ThumbnailCanGoPrevious}"
+ i:Attached.Icon="fas fa-caret-left"
+ Command="{Binding ThumbnailGoPrevious}"/>
+
+ <TextBlock VerticalAlignment="Center">
+ <TextBlock.Text>
+ <MultiBinding StringFormat="{}{0}/{1}">
+ <Binding Path="VisibleThumbnailIndex"/>
+ <Binding Path="SlicerFile.CreatedThumbnailsCount"/>
+ </MultiBinding>
+ </TextBlock.Text>
+ </TextBlock>
+
+ <Button IsEnabled="{Binding ThumbnailCanGoNext}"
+ i:Attached.Icon="fas fa-caret-right"
+ Command="{Binding ThumbnailGoNext}"/>
+
+ </StackPanel>
+
+ <StackPanel Grid.Row="0"
+ IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
+ Orientation="Horizontal"
+ Spacing="2"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center">
+ <TextBlock VerticalAlignment="Center"
+ Text="{Binding VisibleThumbnailResolution}"/>
+
+ <Button IsEnabled="{Binding VisibleThumbnailIndex}"
+ ToolTip.Tip="Replace the current preview image"
+ i:Attached.Icon="fas fa-file-image"
+ Command="{Binding OnClickThumbnailImport}"/>
+
+ <Button IsEnabled="{Binding VisibleThumbnailIndex}"
+ ToolTip.Tip="Save thumbnail image to a file"
+ i:Attached.Icon="fas fa-save"
+ Command="{Binding OnClickThumbnailSave}"/>
+
+ </StackPanel>
+
+ <!-- Preview image -->
+ <Image Grid.Row="1"
+ IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
+ Stretch="Uniform"
+ Source="{Binding VisibleThumbnailImage}"/>
+
+ <GridSplitter Grid.Row="2" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext" Height="5"/>
+
+ <!-- Properties -->
+ <StackPanel
+ IsVisible="{Binding SlicerProperties.Count}"
+ Grid.Row="3"
Orientation="Horizontal"
Spacing="5"
VerticalAlignment="Center">
- <Button IsEnabled="{Binding ThumbnailCanGoPrevious}"
- i:Attached.Icon="fas fa-caret-left"
- Command="{Binding ThumbnailGoPrevious}"/>
-
- <TextBlock VerticalAlignment="Center">
- <TextBlock.Text>
- <MultiBinding StringFormat="{}{0}/{1}">
- <Binding Path="VisibleThumbnailIndex"/>
- <Binding Path="SlicerFile.CreatedThumbnailsCount"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
-
- <Button IsEnabled="{Binding ThumbnailCanGoNext}"
- i:Attached.Icon="fas fa-caret-right"
- Command="{Binding ThumbnailGoNext}"/>
-
- </StackPanel>
-
- <StackPanel Grid.Row="0"
- IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
+
+ <TextBlock
+ VerticalAlignment="Center"
+ Text="{Binding SlicerProperties.Count, StringFormat=Properties: \{0\}}"/>
+
+ <TextBlock VerticalAlignment="Center" Text="|"/>
+
+ <TextBlock
+ VerticalAlignment="Center"
+ Text="{Binding SlicerFile.Configs.Length, StringFormat=Groups: \{0\}}"/>
+
+ </StackPanel>
+
+ <StackPanel
+ IsVisible="{Binding SlicerProperties.Count}"
+ Grid.Row="3"
Orientation="Horizontal"
Spacing="2"
HorizontalAlignment="Right"
VerticalAlignment="Center">
- <TextBlock VerticalAlignment="Center"
- Text="{Binding VisibleThumbnailResolution}"/>
-
- <Button IsEnabled="{Binding VisibleThumbnailIndex}"
- ToolTip.Tip="Replace the current preview image"
- i:Attached.Icon="fas fa-file-image"
- Command="{Binding OnClickThumbnailImport}"/>
-
- <Button IsEnabled="{Binding VisibleThumbnailIndex}"
- ToolTip.Tip="Save thumbnail image to a file"
- i:Attached.Icon="fas fa-save"
- Command="{Binding OnClickThumbnailSave}"/>
-
- </StackPanel>
-
- <!-- Preview image -->
- <Image Grid.Row="1"
- IsVisible="{Binding SlicerFile.CreatedThumbnailsCount}"
- Stretch="Uniform"
- Source="{Binding VisibleThumbnailImage}"/>
-
- <GridSplitter Grid.Row="2" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext" Height="5"/>
-
- <!-- Properties -->
- <StackPanel
- IsVisible="{Binding SlicerProperties.Count}"
- Grid.Row="3"
- Orientation="Horizontal"
- Spacing="5"
- VerticalAlignment="Center">
-
- <TextBlock
- VerticalAlignment="Center"
- Text="{Binding SlicerProperties.Count, StringFormat=Properties: \{0\}}"/>
- <TextBlock VerticalAlignment="Center" Text="|"/>
-
- <TextBlock
- VerticalAlignment="Center"
- Text="{Binding SlicerFile.Configs.Length, StringFormat=Groups: \{0\}}"/>
-
- </StackPanel>
-
- <StackPanel
- IsVisible="{Binding SlicerProperties.Count}"
- Grid.Row="3"
- Orientation="Horizontal"
- Spacing="2"
- HorizontalAlignment="Right"
- VerticalAlignment="Center">
-
- <uc:ButtonWithIcon
- Name="PropertiesSaveButton"
- IsEnabled="{Binding SlicerFile.CreatedThumbnailsCount}"
- ToolTip.Tip="Save properties to a file or clipboard"
- Icon="fas fa-save"
- Spacing="3"
- Text="⮟"
- Command="{Binding OpenContextMenu}"
- CommandParameter="PropertiesSave">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu Name="PropertiesSaveContextMenu" PlacementMode="Bottom">
- <MenuItem
- Command="{Binding OnClickPropertiesSaveFile}"
- Header="To File"
- i:MenuItem.Icon="far fa-save"/>
-
- <MenuItem
- Command="{Binding OnClickPropertiesSaveClipboard}"
- Header="To Clipboard"
- i:MenuItem.Icon="far fa-clipboard"/>
-
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
- </StackPanel>
-
- <DataGrid IsVisible="{Binding SlicerProperties.Count}"
- Name="PropertiesGrid"
- Grid.Row="4"
- CanUserReorderColumns="True"
- CanUserResizeColumns="True"
- CanUserSortColumns="True"
- GridLinesVisibility="Horizontal"
- IsReadOnly="True"
- SelectionMode="Extended"
- ClipboardCopyMode="IncludeHeader"
- Items="{Binding SlicerProperties}">
- <DataGrid.Columns>
- <DataGridTextColumn Header="Name"
- Binding="{Binding Name}"
- Width="Auto" />
- <DataGridTextColumn Header="Value"
- Binding="{Binding Value}"
- Width="Auto" />
- <DataGridTextColumn Header="Group"
- Binding="{Binding Group}"
- Width="Auto" />
- </DataGrid.Columns>
-
- </DataGrid>
-
- <GridSplitter Grid.Row="5" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext"/>
-
- <TextBlock Grid.Row="5"
- Text="Layer data"
- ToolTip.Tip="Shows the properties for the current selected layer"
- FontWeight="Bold"
- TextAlignment="Center"/>
-
- <!-- Layer data -->
-
- <DataGrid Grid.Row="6"
- IsVisible="{Binding IsFileLoaded}"
- Name="CurrentLayerGrid"
- CanUserReorderColumns="False"
- CanUserResizeColumns="False"
- CanUserSortColumns="False"
- GridLinesVisibility="Horizontal"
- IsReadOnly="True"
- ClipboardCopyMode="IncludeHeader"
- Items="{Binding CurrentLayerProperties}">
- <DataGrid.Columns>
- <DataGridTextColumn Header="Name"
- Binding="{Binding Description}"
- Width="Auto" />
- <DataGridTextColumn Header="Value"
- Binding="{Binding Value}"
- Width="Auto" />
- </DataGrid.Columns>
-
- </DataGrid>
-
-
-
- </Grid>
-
- </TabItem>
-
- <TabItem
- Name="TabGCode"
- ToolTip.Tip="GCode"
- IsVisible="False"
- IsEnabled="{Binding HaveGCode}">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-code"/>
- <!--<TextBlock
+ <uc:ButtonWithIcon
+ Name="PropertiesSaveButton"
+ IsEnabled="{Binding SlicerFile.CreatedThumbnailsCount}"
+ ToolTip.Tip="Save properties to a file or clipboard"
+ Icon="fas fa-save"
+ Spacing="3"
+ Text="⮟"
+ Command="{Binding OpenContextMenu}"
+ CommandParameter="PropertiesSave">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu Name="PropertiesSaveContextMenu" PlacementMode="Bottom">
+ <MenuItem
+ Command="{Binding OnClickPropertiesSaveFile}"
+ Header="To File"
+ i:MenuItem.Icon="far fa-save"/>
+
+ <MenuItem
+ Command="{Binding OnClickPropertiesSaveClipboard}"
+ Header="To Clipboard"
+ i:MenuItem.Icon="far fa-clipboard"/>
+
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+ </StackPanel>
+
+ <DataGrid IsVisible="{Binding SlicerProperties.Count}"
+ Name="PropertiesGrid"
+ Grid.Row="4"
+ CanUserReorderColumns="True"
+ CanUserResizeColumns="True"
+ CanUserSortColumns="True"
+ GridLinesVisibility="Horizontal"
+ IsReadOnly="True"
+ SelectionMode="Extended"
+ ClipboardCopyMode="IncludeHeader"
+ Items="{Binding SlicerProperties}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="Name"
+ Binding="{Binding Name}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Value"
+ Binding="{Binding Value}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Group"
+ Binding="{Binding Group}"
+ Width="Auto" />
+ </DataGrid.Columns>
+
+ </DataGrid>
+
+ <GridSplitter Grid.Row="5" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext"/>
+
+ <TextBlock Grid.Row="5"
+ Text="Layer data"
+ ToolTip.Tip="Shows the properties for the current selected layer"
+ FontWeight="Bold"
+ TextAlignment="Center"/>
+
+ <!-- Layer data -->
+
+ <DataGrid Grid.Row="6"
+ IsVisible="{Binding IsFileLoaded}"
+ Name="CurrentLayerGrid"
+ CanUserReorderColumns="False"
+ CanUserResizeColumns="False"
+ CanUserSortColumns="False"
+ GridLinesVisibility="Horizontal"
+ IsReadOnly="True"
+ ClipboardCopyMode="IncludeHeader"
+ Items="{Binding CurrentLayerProperties}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="Name"
+ Binding="{Binding Description}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Value"
+ Binding="{Binding Value}"
+ Width="Auto" />
+ </DataGrid.Columns>
+
+ </DataGrid>
+
+
+
+ </Grid>
+
+ </TabItem>
+
+ <TabItem
+ Name="TabGCode"
+ ToolTip.Tip="GCode"
+ IsVisible="False"
+ IsEnabled="{Binding HaveGCode}">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-code"/>
+ <!--<TextBlock
IsVisible="{Binding $parent[TabItem].IsSelected}"
VerticalAlignment="Center"
Margin="5,0,0,0">Gcode</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid RowDefinitions="Auto,*">
- <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="5">
- <TextBlock
- Text="{Binding GCodeLines, StringFormat=Lines: \{0\}}"
- VerticalAlignment="Center"/>
-
- <TextBlock Text="|" VerticalAlignment="Center"/>
-
- <TextBlock Text="{Binding #GCodeText.Text.Length, StringFormat=Chars: \{0\}}"
- VerticalAlignment="Center"/>
- </StackPanel>
-
- <StackPanel Grid.Row="0"
- Orientation="Horizontal"
- Spacing="2"
- HorizontalAlignment="Right"
- VerticalAlignment="Center">
-
- <ToggleButton
- IsChecked="{Binding SlicerFile.SuppressRebuildGCode}"
- ToolTip.Tip="Enable this to directly edit and use custom gcode.
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid RowDefinitions="Auto,*">
+ <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="5">
+ <TextBlock
+ Text="{Binding GCodeLines, StringFormat=Lines: \{0\}}"
+ VerticalAlignment="Center"/>
+
+ <TextBlock Text="|" VerticalAlignment="Center"/>
+
+ <TextBlock Text="{Binding #GCodeText.Text.Length, StringFormat=Chars: \{0\}}"
+ VerticalAlignment="Center"/>
+ </StackPanel>
+
+ <StackPanel Grid.Row="0"
+ Orientation="Horizontal"
+ Spacing="2"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center">
+
+ <ToggleButton
+ IsChecked="{Binding SlicerFile.SuppressRebuildGCode}"
+ ToolTip.Tip="Enable this to directly edit and use custom gcode.
&#x0a;While this is active, UVtools won't update/generate the gcode, meaning any future change won't be replicated to gcode, unless you press the 'Refresh' button.
&#x0a;To save the file with your custom gcode this setting must remain active while saving the file or else it will be re-generated.
&#x0a;Use with caution and only if you know what you are doing!"
- i:Attached.Icon="far fa-edit"/>
-
- <Button
- ToolTip.Tip="Rebuild GCode with current settings"
- i:Attached.Icon="fas fa-sync-alt"
- Command="{Binding OnClickRebuildGcode}"/>
-
- <uc:ButtonWithIcon Name="GcodeSaveButton"
- ToolTip.Tip="Save gcode to a file or clipboard"
- Icon="fas fa-save"
- Spacing="3"
- Text="⮟"
- Command="{Binding OpenContextMenu}"
- CommandParameter="GcodeSave">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu Name="GcodeSaveContextMenu" PlacementMode="Bottom">
- <MenuItem
- Command="{Binding OnClickGCodeSaveFile}"
- Header="To File"
- i:MenuItem.Icon="far fa-save"/>
-
- <MenuItem
- Command="{Binding OnClickGCodeSaveClipboard}"
- Header="To Clipboard"
- i:MenuItem.Icon="far fa-clipboard"/>
-
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
- </StackPanel>
-
- <TextBox
- Name="GCodeText"
- Grid.Row="1"
- IsReadOnly="{Binding !SlicerFile.SuppressRebuildGCode}"
- AcceptsReturn="True"
- Text="{Binding SlicerFile.GCodeStr}" />
-
- </Grid>
-
- </TabItem>
-
- <!--
+ i:Attached.Icon="far fa-edit"/>
+
+ <Button
+ ToolTip.Tip="Rebuild GCode with current settings"
+ i:Attached.Icon="fas fa-sync-alt"
+ Command="{Binding OnClickRebuildGcode}"/>
+
+ <uc:ButtonWithIcon Name="GcodeSaveButton"
+ ToolTip.Tip="Save gcode to a file or clipboard"
+ Icon="fas fa-save"
+ Spacing="3"
+ Text="⮟"
+ Command="{Binding OpenContextMenu}"
+ CommandParameter="GcodeSave">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu Name="GcodeSaveContextMenu" PlacementMode="Bottom">
+ <MenuItem
+ Command="{Binding OnClickGCodeSaveFile}"
+ Header="To File"
+ i:MenuItem.Icon="far fa-save"/>
+
+ <MenuItem
+ Command="{Binding OnClickGCodeSaveClipboard}"
+ Header="To Clipboard"
+ i:MenuItem.Icon="far fa-clipboard"/>
+
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+ </StackPanel>
+
+ <TextBox
+ Name="GCodeText"
+ Grid.Row="1"
+ IsReadOnly="{Binding !SlicerFile.SuppressRebuildGCode}"
+ AcceptsReturn="True"
+ Text="{Binding SlicerFile.GCodeStr}" />
+
+ </Grid>
+
+ </TabItem>
+
+ <!--
Issues Tab
-->
- <TabItem
- Name="TabIssues"
- ToolTip.Tip="Issues"
- IsEnabled="{Binding IsFileLoaded}" >
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-radiation-alt"/>
- <!--<TextBlock Margin="5,0,0,0">Issues</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid
- RowDefinitions="Auto,*">
- <StackPanel
- IsEnabled="{Binding IsFileLoaded}"
- Grid.Row="0"
- Orientation="Horizontal"
- Spacing="2"
- VerticalAlignment="Center">
- <RepeatButton VerticalAlignment="Stretch"
- HotKey="Ctrl + Shift + Down"
- ToolTip.Tip="Go to the previous issue [Ctrl + Shift + Down]"
- IsEnabled="{Binding IssueCanGoPrevious}"
- Command="{Binding IssueGoPrevious}"
- Interval="100"
- i:Attached.Icon="fas fa-caret-left"/>
-
- <TextBlock VerticalAlignment="Center">
- <TextBlock.Text>
- <MultiBinding StringFormat="{}{0}/{1}">
- <Binding Path="IssueSelectedIndexStr"/>
- <Binding Path="SlicerFile.IssueManager.Count"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
-
- <RepeatButton VerticalAlignment="Stretch"
- HotKey="Ctrl + Shift + Up"
- ToolTip.Tip="Go to the next issue [Ctrl + Shift + Up]"
- IsEnabled="{Binding IssueCanGoNext}"
- Command="{Binding IssueGoNext}"
- Interval="100"
- i:Attached.Icon="fas fa-caret-right"/>
-
- <Button VerticalAlignment="Stretch"
- ToolTip.Tip="Hides and ignores the selected issues, they won't be re-detected.
+ <TabItem
+ Name="TabIssues"
+ ToolTip.Tip="Issues"
+ IsEnabled="{Binding IsFileLoaded}" >
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-radiation-alt"/>
+ <!--<TextBlock Margin="5,0,0,0">Issues</TextBlock>!-->
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid
+ RowDefinitions="Auto,*">
+ <StackPanel
+ IsEnabled="{Binding IsFileLoaded}"
+ Grid.Row="0"
+ Orientation="Horizontal"
+ Spacing="2"
+ VerticalAlignment="Center">
+ <RepeatButton VerticalAlignment="Stretch"
+ HotKey="Ctrl + Shift + Down"
+ ToolTip.Tip="Go to the previous issue [Ctrl + Shift + Down]"
+ IsEnabled="{Binding IssueCanGoPrevious}"
+ Command="{Binding IssueGoPrevious}"
+ Interval="100"
+ i:Attached.Icon="fas fa-caret-left"/>
+
+ <TextBlock VerticalAlignment="Center">
+ <TextBlock.Text>
+ <MultiBinding StringFormat="{}{0}/{1}">
+ <Binding Path="IssueSelectedIndexStr"/>
+ <Binding Path="SlicerFile.IssueManager.Count"/>
+ </MultiBinding>
+ </TextBlock.Text>
+ </TextBlock>
+
+ <RepeatButton VerticalAlignment="Stretch"
+ HotKey="Ctrl + Shift + Up"
+ ToolTip.Tip="Go to the next issue [Ctrl + Shift + Up]"
+ IsEnabled="{Binding IssueCanGoNext}"
+ Command="{Binding IssueGoNext}"
+ Interval="100"
+ i:Attached.Icon="fas fa-caret-right"/>
+
+ <Button VerticalAlignment="Stretch"
+ ToolTip.Tip="Hides and ignores the selected issues, they won't be re-detected.
&#x0a;ALT + Click to re-enable the ignored issues."
- 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-eye-slash"
+ Command="{Binding OnClickIssueIgnore}"/>
- <Button VerticalAlignment="Stretch"
- ToolTip.Tip="Remove the selected issue(s) when possible.
+ <Button VerticalAlignment="Stretch"
+ ToolTip.Tip="Remove the selected issue(s) when possible.
&#x0a;Islands: All pixels are removed (turn black).
&#x0a;ResinTrap: All areas are filled with white pixels.
&#x0a;SuctionCup: Drills a vertical vent hole.
&#x0a;EmptyLayers: Layers are removed."
- IsEnabled="{Binding #IssuesGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
- i:Attached.Icon="fas fa-trash-alt"
- Command="{Binding OnClickIssueRemove}"/>
-
- </StackPanel>
-
- <StackPanel
- Grid.Row="0"
- Orientation="Horizontal"
- Spacing="2"
- HorizontalAlignment="Right"
- VerticalAlignment="Center">
-
- <Button
- IsEnabled="{Binding IsFileLoaded}"
- ToolTip.Tip="Attempt to repair issues"
- VerticalAlignment="Stretch"
- i:Attached.Icon="fas fa-toolbox"
- Command="{Binding OnClickRepairIssues}"/>
-
- <uc:ButtonWithIcon VerticalAlignment="Stretch"
- ToolTip.Tip="Compute Issues.
+ IsEnabled="{Binding #IssuesGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
+ i:Attached.Icon="fas fa-trash-alt"
+ Command="{Binding OnClickIssueRemove}"/>
+
+ </StackPanel>
+
+ <StackPanel
+ Grid.Row="0"
+ Orientation="Horizontal"
+ Spacing="2"
+ HorizontalAlignment="Right"
+ VerticalAlignment="Center">
+
+ <Button
+ IsEnabled="{Binding IsFileLoaded}"
+ ToolTip.Tip="Attempt to repair issues"
+ VerticalAlignment="Stretch"
+ i:Attached.Icon="fas fa-toolbox"
+ Command="{Binding OnClickRepairIssues}"/>
+
+ <uc:ButtonWithIcon VerticalAlignment="Stretch"
+ ToolTip.Tip="Compute Issues.
&#x0a;Right click to access settings."
- Icon="fas fa-sync-alt"
- Spacing="5"
- Text="Detect ⮟"
- Command="{Binding OnClickDetectIssues}">
-
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputeIslands}"
- Content="Islands"/>
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputeOverhangs}"
- Content="Overhangs"/>
- <StackPanel Orientation="Horizontal">
- <CheckBox
- VerticalAlignment="Center"
- IsChecked="{Binding Settings.Issues.ComputeResinTraps}"
- Content="Resin traps"/>
-
- <NumericUpDown
- VerticalAlignment="Center"
- Margin="10,0,0,0"
- ToolTip.Tip="Starting layer index for resin trap detection which will also be considered a drain layer.
+ Icon="fas fa-sync-alt"
+ Spacing="5"
+ Text="Detect ⮟"
+ Command="{Binding OnClickDetectIssues}">
+
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <CheckBox
+ IsChecked="{Binding Settings.Issues.ComputeIslands}"
+ Content="Islands"/>
+ <CheckBox
+ IsChecked="{Binding Settings.Issues.ComputeOverhangs}"
+ Content="Overhangs"/>
+ <StackPanel Orientation="Horizontal">
+ <CheckBox
+ VerticalAlignment="Center"
+ IsChecked="{Binding Settings.Issues.ComputeResinTraps}"
+ Content="Resin traps"/>
+
+ <NumericUpDown
+ VerticalAlignment="Center"
+ Margin="10,0,0,0"
+ ToolTip.Tip="Starting layer index for resin trap detection which will also be considered a drain layer.
&#x0a;Use this setting to bypass complicated rafts by select the model first real layer."
- Minimum="0"
- Maximum="{Binding SlicerFile.LastLayerIndex}"
- Increment="1"
- Width="110"
- Value="{Binding ResinTrapDetectionStartLayer}"/>
-
- <Button
- VerticalAlignment="Center"
- Margin="2,0,0,0"
- ToolTip.Tip="Set to the first normal layer"
- Content="N"
- Command="{Binding SetResinTrapDetectionStartLayer}"
- CommandParameter="N"/>
- <Button
- VerticalAlignment="Center"
- Margin="2,0,0,0"
- ToolTip.Tip="Set to the current layer"
- Content="C"
- Command="{Binding SetResinTrapDetectionStartLayer}"
- CommandParameter="C"/>
- </StackPanel>
-
- <CheckBox
- VerticalAlignment="Center"
- IsEnabled="{Binding Settings.Issues.ComputeResinTraps}"
- IsChecked="{Binding Settings.Issues.ComputeSuctionCups}"
- Content="Suction cups"/>
-
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputeTouchingBounds}"
- Content="Touching bounds"/>
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputePrintHeight}"
- Content="Print height"/>
- <CheckBox
- IsChecked="{Binding Settings.Issues.ComputeEmptyLayers}"
- Content="Empty layers"/>
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
- </StackPanel>
-
- <DataGrid
- Name="IssuesGrid"
- Grid.Row="1"
- CanUserReorderColumns="True"
- CanUserResizeColumns="True"
- CanUserSortColumns="True"
- GridLinesVisibility="Horizontal"
- SelectionMode="Extended"
- SelectedIndex="{Binding IssueSelectedIndex, Mode=TwoWay}"
- IsReadOnly="True"
- ClipboardCopyMode="None"
- Items="{Binding IssuesGridItems}">
- <DataGrid.Columns>
-
- <DataGridTextColumn Header="Type"
- Binding="{Binding Type}"
- Width="Auto" />
- <DataGridTextColumn Header="Layer(s)"
- Binding="{Binding LayerInfoStr}"
- Width="Auto" />
- <DataGridTextColumn Header="Area"
- Binding="{Binding Area, StringFormat={}{0:F0}}"
- Width="Auto" />
- </DataGrid.Columns>
-
- </DataGrid>
-
-
- </Grid>
-
-
- </TabItem>
-
- <!--
+ Minimum="0"
+ Maximum="{Binding SlicerFile.LastLayerIndex}"
+ Increment="1"
+ Width="110"
+ Value="{Binding ResinTrapDetectionStartLayer}"/>
+
+ <Button
+ VerticalAlignment="Center"
+ Margin="2,0,0,0"
+ ToolTip.Tip="Set to the first normal layer"
+ Content="N"
+ Command="{Binding SetResinTrapDetectionStartLayer}"
+ CommandParameter="N"/>
+ <Button
+ VerticalAlignment="Center"
+ Margin="2,0,0,0"
+ ToolTip.Tip="Set to the current layer"
+ Content="C"
+ Command="{Binding SetResinTrapDetectionStartLayer}"
+ CommandParameter="C"/>
+ </StackPanel>
+
+ <CheckBox
+ VerticalAlignment="Center"
+ IsEnabled="{Binding Settings.Issues.ComputeResinTraps}"
+ IsChecked="{Binding Settings.Issues.ComputeSuctionCups}"
+ Content="Suction cups"/>
+
+ <CheckBox
+ IsChecked="{Binding Settings.Issues.ComputeTouchingBounds}"
+ Content="Touching bounds"/>
+ <CheckBox
+ IsChecked="{Binding Settings.Issues.ComputePrintHeight}"
+ Content="Print height"/>
+ <CheckBox
+ IsChecked="{Binding Settings.Issues.ComputeEmptyLayers}"
+ Content="Empty layers"/>
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+ </StackPanel>
+
+ <DataGrid
+ Name="IssuesGrid"
+ Grid.Row="1"
+ CanUserReorderColumns="True"
+ CanUserResizeColumns="True"
+ CanUserSortColumns="True"
+ GridLinesVisibility="Horizontal"
+ SelectionMode="Extended"
+ SelectedIndex="{Binding IssueSelectedIndex, Mode=TwoWay}"
+ IsReadOnly="True"
+ ClipboardCopyMode="None"
+ Items="{Binding IssuesGridItems}">
+ <DataGrid.Columns>
+
+ <DataGridTextColumn Header="Type"
+ Binding="{Binding Type}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Layer(s)"
+ Binding="{Binding LayerInfoStr}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Area"
+ Binding="{Binding Area, StringFormat={}{0:F0}}"
+ Width="Auto" />
+ </DataGrid.Columns>
+
+ </DataGrid>
+
+
+ </Grid>
+
+
+ </TabItem>
+
+ <!--
Suggestions Tab
-->
- <TabItem
- Name="TabSuggestions"
- ToolTip.Tip="Suggestions, automations and analyzer"
- IsVisible="{Binding Suggestions.Length}"
- IsEnabled="{Binding IsFileLoaded}" >
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-shield-virus"/>
- <!--<TextBlock Margin="5,0,0,0">Suggestions</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid ColumnDefinitions="*">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="2*" MinHeight="200" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="*" MinHeight="200" />
- </Grid.RowDefinitions>
-
- <Grid Grid.Row="0" RowDefinitions="Auto" ColumnDefinitions="Auto,2,Auto,*">
- <uc:ButtonWithIcon Grid.Column="0"
- Text="Unselect all"
- Spacing="5"
- Icon="far fa-square"
- Command="{Binding #SuggestionsAvailableListBox.UnselectAll}"/>
-
- <uc:ButtonWithIcon Grid.Column="2"
- Text="Select all"
- Spacing="5"
- Icon="far fa-check-square"
- Command="{Binding #SuggestionsAvailableListBox.SelectAll}"/>
-
- <StackPanel Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right" Spacing="2">
- <uc:ButtonWithIcon IsEnabled="{Binding #SuggestionsAvailableListBox.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
- Icon="fas fa-check"
- Spacing="5"
- Text="Apply"
- Command="{Binding ApplySuggestionsClicked}"/>
-
- <Button VerticalAlignment="Stretch"
- ToolTip.Tip="Configure suggestions"
- Command="{Binding ConfigureSuggestionsClicked}"
- i:Attached.Icon="fas fa-cog"/>
- </StackPanel>
-
- </Grid>
-
- <ListBox
- Grid.Row="1"
- Name="SuggestionsAvailableListBox"
- SelectionMode="Multiple,Toggle"
- Items="{Binding SuggestionsAvailable}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Message}"
- TextWrapping="Wrap"
- ToolTip.Tip="{Binding ToolTip}">
- <!--<TextBlock.IsVisible>
+ <TabItem
+ Name="TabSuggestions"
+ ToolTip.Tip="Suggestions, automations and analyzer"
+ IsVisible="{Binding Suggestions.Length}"
+ IsEnabled="{Binding IsFileLoaded}" >
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-shield-virus"/>
+ <!--<TextBlock Margin="5,0,0,0">Suggestions</TextBlock>!-->
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid ColumnDefinitions="*">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="2*" MinHeight="200" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" MinHeight="200" />
+ </Grid.RowDefinitions>
+
+ <Grid Grid.Row="0" RowDefinitions="Auto" ColumnDefinitions="Auto,2,Auto,*">
+ <uc:ButtonWithIcon Grid.Column="0"
+ Text="Unselect all"
+ Spacing="5"
+ Icon="far fa-square"
+ Command="{Binding #SuggestionsAvailableListBox.UnselectAll}"/>
+
+ <uc:ButtonWithIcon Grid.Column="2"
+ Text="Select all"
+ Spacing="5"
+ Icon="far fa-check-square"
+ Command="{Binding #SuggestionsAvailableListBox.SelectAll}"/>
+
+ <StackPanel Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right" Spacing="2">
+ <uc:ButtonWithIcon IsEnabled="{Binding #SuggestionsAvailableListBox.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
+ Icon="fas fa-check"
+ Spacing="5"
+ Text="Apply"
+ Command="{Binding ApplySuggestionsClicked}"/>
+
+ <Button VerticalAlignment="Stretch"
+ ToolTip.Tip="Configure suggestions"
+ Command="{Binding ConfigureSuggestionsClicked}"
+ i:Attached.Icon="fas fa-cog"/>
+ </StackPanel>
+
+ </Grid>
+
+ <ListBox
+ Grid.Row="1"
+ Name="SuggestionsAvailableListBox"
+ SelectionMode="Multiple,Toggle"
+ Items="{Binding SuggestionsAvailable}">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Message}"
+ TextWrapping="Wrap"
+ ToolTip.Tip="{Binding ToolTip}">
+ <!--<TextBlock.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="Enabled"/>
<Binding Path="!IsApplied"/>
</MultiBinding>
</TextBlock.IsVisible>
!-->
- <TextBlock.ContextMenu>
- <ContextMenu>
- <MenuItem
- Command="{Binding $parent[uc:WindowEx].DataContext.ApplySuggestionClicked}"
- CommandParameter="{Binding .}"
- Header="Apply"
- IsVisible="{Binding !IsInformativeOnly}"
- i:MenuItem.Icon="fas fa-check"/>
- <MenuItem
- Command="{Binding $parent[uc:WindowEx].DataContext.OpenWebsite}"
- CommandParameter="{Binding InformationUrl}"
- Header="More information (Web)"
- IsVisible="{Binding InformationUrl, Converter={x:Static ObjectConverters.IsNotNull}}"
- i:MenuItem.Icon="fas fa-info-circle"/>
- <MenuItem
- Command="{Binding $parent[uc:WindowEx].DataContext.ConfigureSuggestionClicked}"
- CommandParameter="{Binding .}"
- Header="Configure"
- i:MenuItem.Icon="fas fa-cog"/>
- </ContextMenu>
- </TextBlock.ContextMenu>
- </TextBlock>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
-
- <GridSplitter Grid.Row="2" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"/>
-
- <TextBlock Grid.Row="2" Text="Applied suggestions:" HorizontalAlignment="Center" FontWeight="Bold"/>
-
- <ListBox
- Grid.Row="3"
- SelectionMode="AlwaysSelected"
- Items="{Binding SuggestionsApplied}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Message}"
- TextWrapping="Wrap"
- ToolTip.Tip="{Binding ToolTip}">
- <!--<TextBlock.IsVisible>
+ <TextBlock.ContextMenu>
+ <ContextMenu>
+ <MenuItem
+ Command="{Binding $parent[uc:WindowEx].DataContext.ApplySuggestionClicked}"
+ CommandParameter="{Binding .}"
+ Header="Apply"
+ IsVisible="{Binding !IsInformativeOnly}"
+ i:MenuItem.Icon="fas fa-check"/>
+ <MenuItem
+ Command="{Binding $parent[uc:WindowEx].DataContext.OpenWebsite}"
+ CommandParameter="{Binding InformationUrl}"
+ Header="More information (Web)"
+ IsVisible="{Binding InformationUrl, Converter={x:Static ObjectConverters.IsNotNull}}"
+ i:MenuItem.Icon="fas fa-info-circle"/>
+ <MenuItem
+ Command="{Binding $parent[uc:WindowEx].DataContext.ConfigureSuggestionClicked}"
+ CommandParameter="{Binding .}"
+ Header="Configure"
+ i:MenuItem.Icon="fas fa-cog"/>
+ </ContextMenu>
+ </TextBlock.ContextMenu>
+ </TextBlock>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+
+ <GridSplitter Grid.Row="2" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"/>
+
+ <TextBlock Grid.Row="2" Text="Applied suggestions:" HorizontalAlignment="Center" FontWeight="Bold"/>
+
+ <ListBox
+ Grid.Row="3"
+ SelectionMode="AlwaysSelected"
+ Items="{Binding SuggestionsApplied}">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Message}"
+ TextWrapping="Wrap"
+ ToolTip.Tip="{Binding ToolTip}">
+ <!--<TextBlock.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="Enabled"/>
<Binding Path="IsApplied"/>
</MultiBinding>
</TextBlock.IsVisible>
!-->
- <TextBlock.ContextMenu>
- <ContextMenu>
- <MenuItem
- Command="{Binding $parent[uc:WindowEx].DataContext.OpenWebsite}"
- CommandParameter="{Binding InformationUrl}"
- Header="More information (Web)"
- IsVisible="{Binding InformationUrl, Converter={x:Static ObjectConverters.IsNotNull}}"
- i:MenuItem.Icon="fas fa-info-circle"/>
- <MenuItem
- Command="{Binding $parent[uc:WindowEx].DataContext.ConfigureSuggestionClicked}"
- CommandParameter="{Binding .}"
- Header="Configure"
- i:MenuItem.Icon="fas fa-cog"/>
- </ContextMenu>
- </TextBlock.ContextMenu>
- </TextBlock>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
-
- </TabItem>
-
- <!-- Pixel Editor !-->
- <TabItem
- Name="TabPixelEditor"
- ToolTip.Tip="Pixel editor"
- IsVisible="{Binding IsPixelEditorActive}"
- IsEnabled="{Binding IsPixelEditorActive}">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-drafting-compass"/>
- <!--<TextBlock Margin="5,0,0,0">Pixel editor</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid RowDefinitions="Auto,20,Auto,*">
- <TabControl
- Padding="10,0"
- SelectedIndex="{Binding SelectedPixelOperationTabIndex}">
- <!-- Drawing !-->
- <TabControl.Styles>
- <Style Selector="TabItem">
- <Setter Property="FontSize" Value="24"/>
- </Style>
- </TabControl.Styles>
- <TabItem ToolTip.Tip="Drawing">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="fas fa-paint-brush"/>
- <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Drawing" />
- </StackPanel>
- </TabItem.Header>
-
- <StackPanel Spacing="10">
- <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
- <TextBlock Padding="10" Text="Shift+Left click to add white pixels
+ <TextBlock.ContextMenu>
+ <ContextMenu>
+ <MenuItem
+ Command="{Binding $parent[uc:WindowEx].DataContext.OpenWebsite}"
+ CommandParameter="{Binding InformationUrl}"
+ Header="More information (Web)"
+ IsVisible="{Binding InformationUrl, Converter={x:Static ObjectConverters.IsNotNull}}"
+ i:MenuItem.Icon="fas fa-info-circle"/>
+ <MenuItem
+ Command="{Binding $parent[uc:WindowEx].DataContext.ConfigureSuggestionClicked}"
+ CommandParameter="{Binding .}"
+ Header="Configure"
+ i:MenuItem.Icon="fas fa-cog"/>
+ </ContextMenu>
+ </TextBlock.ContextMenu>
+ </TextBlock>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+
+ </TabItem>
+
+ <!-- Pixel Editor !-->
+ <TabItem
+ Name="TabPixelEditor"
+ ToolTip.Tip="Pixel editor"
+ IsVisible="{Binding IsPixelEditorActive}"
+ IsEnabled="{Binding IsPixelEditorActive}">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-drafting-compass"/>
+ <!--<TextBlock Margin="5,0,0,0">Pixel editor</TextBlock>!-->
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid RowDefinitions="Auto,20,Auto,*">
+ <TabControl
+ Padding="10,0"
+ SelectedIndex="{Binding SelectedPixelOperationTabIndex}">
+ <!-- Drawing !-->
+ <TabControl.Styles>
+ <Style Selector="TabItem">
+ <Setter Property="FontSize" Value="24"/>
+ </Style>
+ </TabControl.Styles>
+ <TabItem ToolTip.Tip="Drawing">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="fas fa-paint-brush"/>
+ <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Drawing" />
+ </StackPanel>
+ </TabItem.Header>
+
+ <StackPanel Spacing="10">
+ <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
+ <TextBlock Padding="10" Text="Shift+Left click to add white pixels
&#x0a;Shift+Right click to remove pixels"/>
- </Border>
-
- <Grid
- RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
- ColumnDefinitions="Auto,10,130,5,40">
-
- <TextBlock
- Grid.Row="0"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Line type:" />
- <ComboBox
- Grid.Row="0"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Width="180"
- Items="{Binding DrawingPixelDrawing.LineTypes}"
- SelectedItem="{Binding DrawingPixelDrawing.LineType}"/>
-
- <TextBlock
- Grid.Row="2"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Brush shape:" />
- <ComboBox
- Grid.Row="2"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Width="180"
- Items="{Binding DrawingPixelDrawing.BrushShapeTypes}"
- SelectedItem="{Binding DrawingPixelDrawing.BrushShape}"/>
-
- <TextBlock Grid.Row="4" Grid.Column="0"
- VerticalAlignment="Center"
- Text="Rotation angle:" />
- <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_deg"
- FormatString="F2"
- Minimum="-360"
- Maximum="360"
- Value="{Binding DrawingPixelDrawing.RotationAngle}"/>
-
- <TextBlock Grid.Row="6" Grid.Column="0"
- VerticalAlignment="Center"
- Text="Brush diameter:" />
- <NumericUpDown Grid.Row="6" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_px"
- Minimum="1"
- Maximum="4000"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.BrushSize}"/>
-
- <TextBlock Grid.Row="8" Grid.Column="0"
- VerticalAlignment="Center"
- Text="Thickness:" />
- <NumericUpDown Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_px"
- Minimum="-1"
- Maximum="255"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.Thickness}"/>
-
- <TextBlock Grid.Row="10" Grid.Column="0"
- VerticalAlignment="Center"
- Text="Remove pixel brightness:" />
- <NumericUpDown Grid.Row="10" Grid.Column="2"
- Minimum="0"
- Maximum="255"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.RemovePixelBrightness}"/>
- <TextBlock
- Grid.Row="10"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelDrawing.RemovePixelBrightnessPercent, StringFormat=\{0:0\}%}" />
-
- <TextBlock
- Grid.Row="12"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Add pixel brightness:" />
- <NumericUpDown
- Grid.Row="12"
- Grid.Column="2"
- Minimum="1"
- Maximum="255"
+ </Border>
+
+ <Grid
+ RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,130,5,40">
+
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Line type:" />
+ <ComboBox
+ Grid.Row="0"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Width="180"
+ Items="{Binding DrawingPixelDrawing.LineTypes}"
+ SelectedItem="{Binding DrawingPixelDrawing.LineType}"/>
+
+ <TextBlock
+ Grid.Row="2"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Brush shape:" />
+ <ComboBox
+ Grid.Row="2"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Width="180"
+ Items="{Binding DrawingPixelDrawing.BrushShapeTypes}"
+ SelectedItem="{Binding DrawingPixelDrawing.BrushShape}"/>
+
+ <TextBlock Grid.Row="4" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Rotation angle:" />
+ <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_deg"
+ FormatString="F2"
+ Minimum="-360"
+ Maximum="360"
+ Value="{Binding DrawingPixelDrawing.RotationAngle}"/>
+
+ <TextBlock Grid.Row="6" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Brush diameter:" />
+ <NumericUpDown Grid.Row="6" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="1"
+ Maximum="4000"
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.BrushSize}"/>
+
+ <TextBlock Grid.Row="8" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Thickness:" />
+ <NumericUpDown Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="-1"
+ Maximum="255"
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.Thickness}"/>
+
+ <TextBlock Grid.Row="10" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Remove pixel brightness:" />
+ <NumericUpDown Grid.Row="10" Grid.Column="2"
+ Minimum="0"
+ Maximum="255"
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.RemovePixelBrightness}"/>
+ <TextBlock
+ Grid.Row="10"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelDrawing.RemovePixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+
+ <TextBlock
+ Grid.Row="12"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Add pixel brightness:" />
+ <NumericUpDown
+ Grid.Row="12"
+ Grid.Column="2"
+ Minimum="1"
+ Maximum="255"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.PixelBrightness}"/>
- <TextBlock
- Grid.Row="12"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelDrawing.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
-
- <TextBlock
- Grid.Row="14"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth below:" />
- <NumericUpDown Grid.Row="14" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.LayersBelow}"/>
-
-
- <TextBlock
- Grid.Row="16"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth above:" />
- <NumericUpDown Grid.Row="16" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- HorizontalAlignment="Stretch"
- Value="{Binding DrawingPixelDrawing.LayersAbove}"/>
-
- </Grid>
-
- </StackPanel>
-
- </TabItem>
-
- <!-- Text !-->
- <TabItem ToolTip.Tip="Text">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="fas fa-font"/>
- <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Text" />
- </StackPanel>
- </TabItem.Header>
-
- <StackPanel Spacing="10">
- <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
- <TextBlock Padding="10" Text="Shift+Left click to add text
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.PixelBrightness}"/>
+ <TextBlock
+ Grid.Row="12"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelDrawing.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+
+ <TextBlock
+ Grid.Row="14"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth below:" />
+ <NumericUpDown Grid.Row="14" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.LayersBelow}"/>
+
+
+ <TextBlock
+ Grid.Row="16"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth above:" />
+ <NumericUpDown Grid.Row="16" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ HorizontalAlignment="Stretch"
+ Value="{Binding DrawingPixelDrawing.LayersAbove}"/>
+
+ </Grid>
+
+ </StackPanel>
+
+ </TabItem>
+
+ <!-- Text !-->
+ <TabItem ToolTip.Tip="Text">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="fas fa-font"/>
+ <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Text" />
+ </StackPanel>
+ </TabItem.Header>
+
+ <StackPanel Spacing="10">
+ <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
+ <TextBlock Padding="10" Text="Shift+Left click to add text
&#x0a;Shift+Right click to remove text"/>
- </Border>
-
- <Grid
- RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
- ColumnDefinitions="Auto,10,130,5,40">
-
- <TextBlock
- Grid.Row="0"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Line type:" />
- <ComboBox
- Grid.Row="0"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Width="180"
- Items="{Binding DrawingPixelText.LineTypes}"
- SelectedItem="{Binding DrawingPixelText.LineType}"/>
-
- <TextBlock
- Grid.Row="2"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Font face:" />
- <ComboBox
- Grid.Row="2"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Width="180"
- Items="{Binding DrawingPixelText.FontFaces}"
- SelectedItem="{Binding DrawingPixelText.Font}"/>
-
- <TextBlock
- Grid.Row="4"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Font scale:" />
- <NumericUpDown
- Grid.Row="4"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Minimum="0.1"
- Maximum="255"
- Increment="0.1"
+ </Border>
+
+ <Grid
+ RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,130,5,40">
+
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Line type:" />
+ <ComboBox
+ Grid.Row="0"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Width="180"
+ Items="{Binding DrawingPixelText.LineTypes}"
+ SelectedItem="{Binding DrawingPixelText.LineType}"/>
+
+ <TextBlock
+ Grid.Row="2"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Font face:" />
+ <ComboBox
+ Grid.Row="2"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Width="180"
+ Items="{Binding DrawingPixelText.FontFaces}"
+ SelectedItem="{Binding DrawingPixelText.Font}"/>
+
+ <TextBlock
+ Grid.Row="4"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Font scale:" />
+ <NumericUpDown
+ Grid.Row="4"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Minimum="0.1"
+ Maximum="255"
+ Increment="0.1"
- Value="{Binding DrawingPixelText.FontScale}"/>
-
-
- <TextBlock
- Grid.Row="6"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Thickness:" />
- <NumericUpDown Grid.Row="6" Grid.Column="2"
- Classes="ValueLabel ValueLabel_px"
- Grid.ColumnSpan="3"
- Minimum="1"
- Maximum="255"
- Value="{Binding DrawingPixelText.Thickness}"/>
-
- <TextBlock
- Grid.Row="8"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Text:" />
- <TextBox
- Grid.Row="8"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- AcceptsReturn="True"
- Height="90"
- Text="{Binding DrawingPixelText.Text}"/>
-
- <TextBlock
- Grid.Row="10"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Line alignment:" />
- <ComboBox
- Grid.Row="10"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Width="180"
- Items="{Binding DrawingPixelText.LineAlignment, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
- SelectedItem="{Binding DrawingPixelText.LineAlignment, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
-
- <CheckBox
- Grid.Row="12"
- Grid.Column="2"
- Grid.ColumnSpan="3"
- Content="Flip text Vertically"
- IsChecked="{Binding DrawingPixelText.Mirror}"/>
-
- <TextBlock
- Grid.Row="14"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Rotation angle:" />
- <NumericUpDown Grid.Row="14" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_deg"
- FormatString="F2"
- Minimum="-360"
- Maximum="360"
- Value="{Binding DrawingPixelText.Angle}"/>
-
- <TextBlock
- Grid.Row="16"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Remove pixel brightness:" />
- <NumericUpDown
- Grid.Row="16"
- Grid.Column="2"
- Minimum="0"
- Maximum="255"
+ Value="{Binding DrawingPixelText.FontScale}"/>
+
+
+ <TextBlock
+ Grid.Row="6"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Thickness:" />
+ <NumericUpDown Grid.Row="6" Grid.Column="2"
+ Classes="ValueLabel ValueLabel_px"
+ Grid.ColumnSpan="3"
+ Minimum="1"
+ Maximum="255"
+ Value="{Binding DrawingPixelText.Thickness}"/>
+
+ <TextBlock
+ Grid.Row="8"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Text:" />
+ <TextBox
+ Grid.Row="8"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ AcceptsReturn="True"
+ Height="90"
+ Text="{Binding DrawingPixelText.Text}"/>
+
+ <TextBlock
+ Grid.Row="10"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Line alignment:" />
+ <ComboBox
+ Grid.Row="10"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Width="180"
+ Items="{Binding DrawingPixelText.LineAlignment, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
+ SelectedItem="{Binding DrawingPixelText.LineAlignment, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
+
+ <CheckBox
+ Grid.Row="12"
+ Grid.Column="2"
+ Grid.ColumnSpan="3"
+ Content="Flip text Vertically"
+ IsChecked="{Binding DrawingPixelText.Mirror}"/>
+
+ <TextBlock
+ Grid.Row="14"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Rotation angle:" />
+ <NumericUpDown Grid.Row="14" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_deg"
+ FormatString="F2"
+ Minimum="-360"
+ Maximum="360"
+ Value="{Binding DrawingPixelText.Angle}"/>
+
+ <TextBlock
+ Grid.Row="16"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Remove pixel brightness:" />
+ <NumericUpDown
+ Grid.Row="16"
+ Grid.Column="2"
+ Minimum="0"
+ Maximum="255"
- Value="{Binding DrawingPixelText.RemovePixelBrightness}"/>
- <TextBlock
- Grid.Row="16"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelText.RemovePixelBrightnessPercent, StringFormat=\{0:0\}%}" />
-
- <TextBlock
- Grid.Row="18"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Add pixel brightness:" />
- <NumericUpDown
- Grid.Row="18"
- Grid.Column="2"
- Minimum="1"
- Maximum="255"
+ Value="{Binding DrawingPixelText.RemovePixelBrightness}"/>
+ <TextBlock
+ Grid.Row="16"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelText.RemovePixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+
+ <TextBlock
+ Grid.Row="18"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Add pixel brightness:" />
+ <NumericUpDown
+ Grid.Row="18"
+ Grid.Column="2"
+ Minimum="1"
+ Maximum="255"
- Value="{Binding DrawingPixelText.PixelBrightness}"/>
- <TextBlock
- Grid.Row="18"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelText.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
-
-
- <TextBlock
- Grid.Row="20"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth below:" />
- <NumericUpDown Grid.Row="20" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- Value="{Binding DrawingPixelText.LayersBelow}"/>
-
-
- <TextBlock
- Grid.Row="22"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth above:" />
- <NumericUpDown Grid.Row="22" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- Value="{Binding DrawingPixelText.LayersAbove}"/>
-
- </Grid>
-
- </StackPanel>
-
- </TabItem>
-
- <!-- Eraser !-->
- <TabItem ToolTip.Tip="Eraser">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="fas fa-eraser"/>
- <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Eraser" />
- </StackPanel>
- </TabItem.Header>
-
- <StackPanel Spacing="10">
- <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
- <TextBlock Padding="10" Text="Shift+click over a white pixel to remove the linked area.
+ Value="{Binding DrawingPixelText.PixelBrightness}"/>
+ <TextBlock
+ Grid.Row="18"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelText.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+
+
+ <TextBlock
+ Grid.Row="20"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth below:" />
+ <NumericUpDown Grid.Row="20" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ Value="{Binding DrawingPixelText.LayersBelow}"/>
+
+
+ <TextBlock
+ Grid.Row="22"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth above:" />
+ <NumericUpDown Grid.Row="22" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ Value="{Binding DrawingPixelText.LayersAbove}"/>
+
+ </Grid>
+
+ </StackPanel>
+
+ </TabItem>
+
+ <!-- Eraser !-->
+ <TabItem ToolTip.Tip="Eraser">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="fas fa-eraser"/>
+ <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Eraser" />
+ </StackPanel>
+ </TabItem.Header>
+
+ <StackPanel Spacing="10">
+ <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
+ <TextBlock Padding="10" Text="Shift+click over a white pixel to remove the linked area.
&#x0a;(Fill linked area with black)"/>
- </Border>
-
- <Grid
- RowDefinitions="Auto,10,Auto,10,Auto"
- ColumnDefinitions="Auto,10,*,10,40">
-
- <TextBlock
- Grid.Row="0"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Pixel brightness:" />
- <NumericUpDown Grid.Row="0" Grid.Column="2"
- Classes="ValueLabel ValueLabel_sun"
- Minimum="0"
- Maximum="255"
+ </Border>
+
+ <Grid
+ RowDefinitions="Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,*,10,40">
+
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Pixel brightness:" />
+ <NumericUpDown Grid.Row="0" Grid.Column="2"
+ Classes="ValueLabel ValueLabel_sun"
+ Minimum="0"
+ Maximum="255"
- Value="{Binding DrawingPixelEraser.PixelBrightness}"/>
- <TextBlock
- Grid.Row="0"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelEraser.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
-
- <TextBlock
- Grid.Row="2"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth below:" />
- <NumericUpDown Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- Value="{Binding DrawingPixelEraser.LayersBelow}"/>
-
- <TextBlock
- Grid.Row="4"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Layers depth above:" />
- <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_layers"
- Minimum="0"
- Value="{Binding DrawingPixelEraser.LayersAbove}"/>
-
-
- </Grid>
-
- </StackPanel>
-
- </TabItem>
-
- <!-- Supports !-->
- <TabItem
- ToolTip.Tip="Supports"
+ Value="{Binding DrawingPixelEraser.PixelBrightness}"/>
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelEraser.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+
+ <TextBlock
+ Grid.Row="2"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth below:" />
+ <NumericUpDown Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ Value="{Binding DrawingPixelEraser.LayersBelow}"/>
+
+ <TextBlock
+ Grid.Row="4"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Layers depth above:" />
+ <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_layers"
+ Minimum="0"
+ Value="{Binding DrawingPixelEraser.LayersAbove}"/>
+
+
+ </Grid>
+
+ </StackPanel>
+
+ </TabItem>
+
+ <!-- Supports !-->
+ <TabItem
+ ToolTip.Tip="Supports"
>
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="fas fa-code-branch"/>
- <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Supports" />
- </StackPanel>
- </TabItem.Header>
-
- <StackPanel Spacing="10" >
- <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
- <TextBlock Padding="10" Text="Shift+click under a island to add primitive support.
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="fas fa-code-branch"/>
+ <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Supports" />
+ </StackPanel>
+ </TabItem.Header>
+
+ <StackPanel Spacing="10" >
+ <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
+ <TextBlock Padding="10" Text="Shift+click under a island to add primitive support.
&#x0a;Note: this operation can't be previewed."/>
- </Border>
- <Grid
- RowDefinitions="Auto,10,Auto,10,Auto,10,Auto"
- ColumnDefinitions="Auto,10,*,5,35">
- <TextBlock
- Grid.Row="0"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Tip diameter:" />
- <NumericUpDown Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_px"
- Minimum="1"
- Maximum="255"
- Value="{Binding DrawingPixelSupport.TipDiameter}"/>
-
- <TextBlock
- Grid.Row="2"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Pillar diameter:" />
- <NumericUpDown Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_px"
- Minimum="1"
- Maximum="255"
- Value="{Binding DrawingPixelSupport.PillarDiameter}"/>
-
- <TextBlock
- Grid.Row="4"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Base diameter:" />
- <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
- Classes="ValueLabel ValueLabel_px"
- Minimum="1"
- Maximum="255"
- Value="{Binding DrawingPixelSupport.BaseDiameter}"/>
-
- <TextBlock
- Grid.Row="6"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Pixel brightness:" />
- <NumericUpDown Grid.Row="6" Grid.Column="2"
- Classes="ValueLabel ValueLabel_sun"
- Minimum="0"
- Maximum="255"
+ </Border>
+ <Grid
+ RowDefinitions="Auto,10,Auto,10,Auto,10,Auto"
+ ColumnDefinitions="Auto,10,*,5,35">
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Tip diameter:" />
+ <NumericUpDown Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="1"
+ Maximum="255"
+ Value="{Binding DrawingPixelSupport.TipDiameter}"/>
+
+ <TextBlock
+ Grid.Row="2"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Pillar diameter:" />
+ <NumericUpDown Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="1"
+ Maximum="255"
+ Value="{Binding DrawingPixelSupport.PillarDiameter}"/>
+
+ <TextBlock
+ Grid.Row="4"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Base diameter:" />
+ <NumericUpDown Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="1"
+ Maximum="255"
+ Value="{Binding DrawingPixelSupport.BaseDiameter}"/>
+
+ <TextBlock
+ Grid.Row="6"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Pixel brightness:" />
+ <NumericUpDown Grid.Row="6" Grid.Column="2"
+ Classes="ValueLabel ValueLabel_sun"
+ Minimum="0"
+ Maximum="255"
- Value="{Binding DrawingPixelSupport.PixelBrightness}"/>
- <TextBlock
- Grid.Row="6"
- Grid.Column="4"
- VerticalAlignment="Center"
- Text="{Binding DrawingPixelSupport.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
+ Value="{Binding DrawingPixelSupport.PixelBrightness}"/>
+ <TextBlock
+ Grid.Row="6"
+ Grid.Column="4"
+ VerticalAlignment="Center"
+ Text="{Binding DrawingPixelSupport.PixelBrightnessPercent, StringFormat=\{0:0\}%}" />
- </Grid>
- </StackPanel>
+ </Grid>
+ </StackPanel>
- </TabItem>
+ </TabItem>
- <!-- Drain holes !-->
- <TabItem
- ToolTip.Tip="Drain holes"
+ <!-- Drain holes !-->
+ <TabItem
+ ToolTip.Tip="Drain holes"
>
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="fas fa-ring"/>
- <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Drain holes" />
- </StackPanel>
- </TabItem.Header>
-
- <StackPanel Spacing="10">
- <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
- <TextBlock Padding="10" Text="Shift+click to add a vertical drain hole.
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="fas fa-ring"/>
+ <TextBlock IsVisible="{Binding $parent[TabItem].IsSelected}" Text="Drain holes" />
+ </StackPanel>
+ </TabItem.Header>
+
+ <StackPanel Spacing="10">
+ <Border Background="{DynamicResource LightBackground}" BorderThickness="1" BorderBrush="Black">
+ <TextBlock Padding="10" Text="Shift+click to add a vertical drain hole.
&#x0a;Note: this operation can't be previewed."/>
- </Border>
- <Grid
- RowDefinitions="Auto"
- ColumnDefinitions="Auto,10,*">
- <TextBlock
- Grid.Row="0"
- Grid.Column="0"
- VerticalAlignment="Center"
- Text="Hole diameter:" />
- <NumericUpDown Grid.Row="0" Grid.Column="2"
- Classes="ValueLabel ValueLabel_px"
- Minimum="20"
- Maximum="255"
- Value="{Binding DrawingPixelDrainHole.Diameter}"/>
- </Grid>
- </StackPanel>
-
- </TabItem>
-
- </TabControl>
-
- <!-- Toolbar !-->
- <StackPanel
- Grid.Row="2"
- Orientation="Horizontal" Spacing="1">
- <uc:ButtonWithIcon IsEnabled="{Binding #DrawingsGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
- Icon="fas fa-trash-alt"
- Spacing="5"
- Text="Remove"
- Command="{Binding OnClickDrawingRemove}"/>
-
- <uc:ButtonWithIcon IsEnabled="{Binding Drawings.Count}"
- Icon="fas fa-times"
- Spacing="5"
- Text="Clear"
- Command="{Binding OnClickDrawingClear}"/>
- </StackPanel>
-
- <StackPanel
- Grid.Row="2"
- HorizontalAlignment="Right"
- Orientation="Horizontal"
- Spacing="10" >
-
- <uc:ButtonWithIcon IsEnabled="{Binding Drawings.Count}"
- Icon="fas fa-check"
- Spacing="5"
- Text="{Binding Drawings.Count, StringFormat=Apply \{0\} operations}"
- Command="{Binding DrawModifications}"
- CommandParameter="false"/>
- </StackPanel>
-
- <DataGrid
- Name="DrawingsGrid"
- Grid.Row="3"
- CanUserReorderColumns="True"
- CanUserResizeColumns="True"
- CanUserSortColumns="True"
- GridLinesVisibility="Horizontal"
- SelectionMode="Extended"
- IsReadOnly="True"
- ClipboardCopyMode="IncludeHeader"
- Items="{Binding Drawings}">
- <DataGrid.Columns>
- <DataGridTextColumn Header="#"
- Binding="{Binding Index}"
- Width="Auto" />
- <DataGridTextColumn Header="Operation"
- Binding="{Binding OperationType}"
- Width="Auto" />
- <DataGridTextColumn Header="Layer"
- Binding="{Binding LayerIndex}"
- Width="Auto" />
- <DataGridTextColumn Header="Position (X, Y)"
- Binding="{Binding Location}"
- Width="Auto" />
- </DataGrid.Columns>
-
- </DataGrid>
-
- </Grid>
-
- </TabItem>
-
-
- <TabItem
- Name="TabClipboard"
- IsEnabled="{Binding IsFileLoaded}"
- ToolTip.Tip="Clipboard">
- <TabItem.Header>
- <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
- <i:Icon Value="fas fa-clipboard-list"/>
- <!--<TextBlock Margin="5,0,0,0">Clipboard</TextBlock>!-->
- </StackPanel>
- </TabItem.Header>
-
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*" MinHeight="140"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*" MinHeight="180"/>
- </Grid.RowDefinitions>
- <StackPanel Orientation="Horizontal" Spacing="2">
-
- <Button IsEnabled="{Binding Clipboard.CanUndo}"
- Command="{Binding ClipboardUndo}"
- HotKey="Ctrl + Z"
- ToolTip.Tip="Undo [Ctrl + Z]
+ </Border>
+ <Grid
+ RowDefinitions="Auto"
+ ColumnDefinitions="Auto,10,*">
+ <TextBlock
+ Grid.Row="0"
+ Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="Hole diameter:" />
+ <NumericUpDown Grid.Row="0" Grid.Column="2"
+ Classes="ValueLabel ValueLabel_px"
+ Minimum="20"
+ Maximum="255"
+ Value="{Binding DrawingPixelDrainHole.Diameter}"/>
+ </Grid>
+ </StackPanel>
+
+ </TabItem>
+
+ </TabControl>
+
+ <!-- Toolbar !-->
+ <StackPanel
+ Grid.Row="2"
+ Orientation="Horizontal" Spacing="1">
+ <uc:ButtonWithIcon IsEnabled="{Binding #DrawingsGrid.SelectedItem, Converter={x:Static ObjectConverters.IsNotNull}}"
+ Icon="fas fa-trash-alt"
+ Spacing="5"
+ Text="Remove"
+ Command="{Binding OnClickDrawingRemove}"/>
+
+ <uc:ButtonWithIcon IsEnabled="{Binding Drawings.Count}"
+ Icon="fas fa-times"
+ Spacing="5"
+ Text="Clear"
+ Command="{Binding OnClickDrawingClear}"/>
+ </StackPanel>
+
+ <StackPanel
+ Grid.Row="2"
+ HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Spacing="10" >
+
+ <uc:ButtonWithIcon IsEnabled="{Binding Drawings.Count}"
+ Icon="fas fa-check"
+ Spacing="5"
+ Text="{Binding Drawings.Count, StringFormat=Apply \{0\} operations}"
+ Command="{Binding DrawModifications}"
+ CommandParameter="false"/>
+ </StackPanel>
+
+ <DataGrid
+ Name="DrawingsGrid"
+ Grid.Row="3"
+ CanUserReorderColumns="True"
+ CanUserResizeColumns="True"
+ CanUserSortColumns="True"
+ GridLinesVisibility="Horizontal"
+ SelectionMode="Extended"
+ IsReadOnly="True"
+ ClipboardCopyMode="IncludeHeader"
+ Items="{Binding Drawings}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="#"
+ Binding="{Binding Index}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Operation"
+ Binding="{Binding OperationType}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Layer"
+ Binding="{Binding LayerIndex}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Position (X, Y)"
+ Binding="{Binding Location}"
+ Width="Auto" />
+ </DataGrid.Columns>
+
+ </DataGrid>
+
+ </Grid>
+
+ </TabItem>
+
+
+ <TabItem
+ Name="TabClipboard"
+ IsEnabled="{Binding IsFileLoaded}"
+ ToolTip.Tip="Clipboard">
+ <TabItem.Header>
+ <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
+ <i:Icon Value="fas fa-clipboard-list"/>
+ <!--<TextBlock Margin="5,0,0,0">Clipboard</TextBlock>!-->
+ </StackPanel>
+ </TabItem.Header>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*" MinHeight="140"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="*" MinHeight="180"/>
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Horizontal" Spacing="2">
+
+ <Button IsEnabled="{Binding Clipboard.CanUndo}"
+ Command="{Binding ClipboardUndo}"
+ HotKey="Ctrl + Z"
+ ToolTip.Tip="Undo [Ctrl + Z]
&#x0a;Shift + Click to Undo and edit last operation [Ctrl + Shift + Z]"
- i:Attached.Icon="fas fa-undo-alt"/>
-
- <TextBlock VerticalAlignment="Center">
- <TextBlock.Text>
- <MultiBinding StringFormat="{}{0}/{1}">
- <Binding Path="Clipboard.CurrentIndexCountStr"/>
- <Binding Path="Clipboard.Items.Count"/>
- </MultiBinding>
- </TextBlock.Text>
- </TextBlock>
-
- <Button
- IsEnabled="{Binding Clipboard.CanRedo}"
- Command="{Binding ClipboardRedo}"
- HotKey="Ctrl + Y"
- ToolTip.Tip="Redo [Ctrl + Y]"
- i:Attached.Icon="fas fa-redo-alt"/>
-
- </StackPanel>
-
- <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="2" HorizontalAlignment="Right">
- <Button
- IsEnabled="{Binding Clipboard.Items.Count}"
- Command="{Binding ClipboardClear}"
- ToolTip.Tip="Clear all clips"
- i:Attached.Icon="fas fa-times"/>
- </StackPanel>
-
- <ListBox
- Grid.Row="1"
- Name="ClipboardList"
- SelectionMode="Single"
- AutoScrollToSelectedItem="True"
- SelectedIndex="{Binding Clipboard.CurrentIndex}"
- Items="{Binding Clipboard.Items}" />
-
- <GridSplitter Grid.Row="2" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"/>
-
- <Grid Grid.Row="3" RowDefinitions="Auto,*" ColumnDefinitions="*">
- <Grid Grid.Row="0"
- RowDefinitions="Auto"
- ColumnDefinitions="Auto,*,Auto">
- <TextBlock Grid.Row="0" Grid.Column="0"
- VerticalAlignment="Center"
- Text="{Binding Logs.Count, StringFormat=Operations: {0}}"/>
-
- <TextBlock Grid.Row="0" Grid.Column="1"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- FontWeight="Bold" Text="Logs"/>
-
- <StackPanel Grid.Row="0" Grid.Column="2" Orientation="Horizontal"
- Spacing="5"
- HorizontalAlignment="Right">
- <CheckBox VerticalAlignment="Center"
- ToolTip.Tip="Shows extra information useful to debug problems."
- IsChecked="{Binding IsVerbose}"
- Content="Verbose"/>
-
- <Button VerticalAlignment="Center"
- Command="{Binding Logs.Clear}"
- ToolTip.Tip="Clear all logs"
- i:Attached.Icon="fas fa-times"/>
- </StackPanel>
+ i:Attached.Icon="fas fa-undo-alt"/>
+
+ <TextBlock VerticalAlignment="Center">
+ <TextBlock.Text>
+ <MultiBinding StringFormat="{}{0}/{1}">
+ <Binding Path="Clipboard.CurrentIndexCountStr"/>
+ <Binding Path="Clipboard.Items.Count"/>
+ </MultiBinding>
+ </TextBlock.Text>
+ </TextBlock>
+
+ <Button
+ IsEnabled="{Binding Clipboard.CanRedo}"
+ Command="{Binding ClipboardRedo}"
+ HotKey="Ctrl + Y"
+ ToolTip.Tip="Redo [Ctrl + Y]"
+ i:Attached.Icon="fas fa-redo-alt"/>
+
+ </StackPanel>
+
+ <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="2" HorizontalAlignment="Right">
+ <Button
+ IsEnabled="{Binding Clipboard.Items.Count}"
+ Command="{Binding ClipboardClear}"
+ ToolTip.Tip="Clear all clips"
+ i:Attached.Icon="fas fa-times"/>
+ </StackPanel>
+
+ <ListBox
+ Grid.Row="1"
+ Name="ClipboardList"
+ SelectionMode="Single"
+ AutoScrollToSelectedItem="True"
+ SelectedIndex="{Binding Clipboard.CurrentIndex}"
+ Items="{Binding Clipboard.Items}" />
+
+ <GridSplitter Grid.Row="2" ResizeBehavior="PreviousAndNext" ResizeDirection="Rows"/>
+
+ <Grid Grid.Row="3" RowDefinitions="Auto,*" ColumnDefinitions="*">
+ <Grid Grid.Row="0"
+ RowDefinitions="Auto"
+ ColumnDefinitions="Auto,*,Auto">
+ <TextBlock Grid.Row="0" Grid.Column="0"
+ VerticalAlignment="Center"
+ Text="{Binding Logs.Count, StringFormat=Operations: {0}}"/>
+
+ <TextBlock Grid.Row="0" Grid.Column="1"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ FontWeight="Bold" Text="Logs"/>
+
+ <StackPanel Grid.Row="0" Grid.Column="2" Orientation="Horizontal"
+ Spacing="5"
+ HorizontalAlignment="Right">
+ <CheckBox VerticalAlignment="Center"
+ ToolTip.Tip="Shows extra information useful to debug problems."
+ IsChecked="{Binding IsVerbose}"
+ Content="Verbose"/>
+
+ <Button VerticalAlignment="Center"
+ Command="{Binding Logs.Clear}"
+ ToolTip.Tip="Clear all logs"
+ i:Attached.Icon="fas fa-times"/>
+ </StackPanel>
+
+ </Grid>
+
+ <DataGrid Grid.Row="1" Items="{Binding Logs}"
+ VerticalAlignment="Stretch"
+ CanUserReorderColumns="True"
+ CanUserResizeColumns="True"
+ CanUserSortColumns="True"
+ GridLinesVisibility="All"
+ IsReadOnly="True"
+ ClipboardCopyMode="IncludeHeader"
+ SelectionMode="Extended">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="#"
+ Binding="{Binding Index}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Started"
+ Binding="{Binding StartTime}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Time(s)"
+ Binding="{Binding ElapsedTime}"
+ Width="Auto" />
+ <DataGridTextColumn Header="Description"
+ Binding="{Binding Description}"
+ Width="Auto" />
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+
+ </Grid>
+
+
+ </TabItem>
+
+ </TabControl>
+
+ <Grid
+ IsEnabled="{Binding IsFileLoaded}"
+ DockPanel.Dock="Right"
+ ColumnDefinitions="160"
+ RowDefinitions="Auto,Auto,*,Auto,Auto,Auto,Auto,Auto" Margin="5">
+ <TextBlock
+ Text="{Binding MaximumLayerString}"
+ Name="Layer.Navigation.Up"
+ Margin="0,0,0,10"
+ HorizontalAlignment="Center"
+ TextAlignment="Center"
+ Grid.Row="0"/>
+ <RepeatButton
+ Grid.Row="1"
+ ToolTip.Tip="Navigate to up layer [Ctrl + Up]"
+ HotKey="Ctrl + Up"
+ Interval="100"
+ HorizontalAlignment="Stretch"
+ IsEnabled="{Binding CanGoUp}"
+ Command="{Binding GoNextLayer}"
+ i:Attached.Icon="fas fa-angle-up"/>
+
+ <Grid
+ Name="LayerNavigationSliderGrid"
+ Grid.Row="2" ColumnDefinitions="*,20,40">
+ <Panel
+ Grid.Column="0"
+ Name="LayerNavigationTooltipPanel"
+ Margin="{Binding LayerNavigationTooltipMargin}"
+ HorizontalAlignment="Stretch">
+ <Border
+ Name="Layer.Navigation.Tooltip.Border"
+ Classes="LayerNavigationToolTip"
+ VerticalAlignment="Top">
+ <TextBlock Padding="2" Text="{Binding ActualLayerTooltip}"/>
+ </Border>
+ </Panel>
+
+ <!--<Image
+ Grid.Column="1"
+ Name="Layer.Navigation.Issues" Width="16"></Image>!-->
+ <Canvas
+ Grid.Column="1"
+ Margin="0,15"
+ Classes="IssuesTrackerCanvas"
+ Name="Layer.Navigation.IssuesCanvas" Width="20"/>
+
+ <Slider
+ Grid.Column="2"
+ Name="Layer.Navigation.Slider"
+ Minimum="0"
+ Maximum="{Binding SliderMaximumValue}"
+ Value="{Binding ActualLayerSlider}"
+ TickFrequency="1"
+ TickPlacement="Outside"
+ SmallChange="1"
+ LargeChange="10"
+ IsSnapToTickEnabled="True"
+ Margin="0,5"
+ HorizontalAlignment="Right"
+ Orientation="Vertical"/>
</Grid>
- <DataGrid Grid.Row="1" Items="{Binding Logs}"
- VerticalAlignment="Stretch"
- CanUserReorderColumns="True"
- CanUserResizeColumns="True"
- CanUserSortColumns="True"
- GridLinesVisibility="All"
- IsReadOnly="True"
- ClipboardCopyMode="IncludeHeader"
- SelectionMode="Extended">
- <DataGrid.Columns>
- <DataGridTextColumn Header="#"
- Binding="{Binding Index}"
- Width="Auto" />
- <DataGridTextColumn Header="Started"
- Binding="{Binding StartTime}"
- Width="Auto" />
- <DataGridTextColumn Header="Time(s)"
- Binding="{Binding ElapsedTime}"
- Width="Auto" />
- <DataGridTextColumn Header="Description"
- Binding="{Binding Description}"
- Width="Auto" />
- </DataGrid.Columns>
- </DataGrid>
- </Grid>
-
- </Grid>
-
-
- </TabItem>
-
- </TabControl>
-
- <Grid
- IsEnabled="{Binding IsFileLoaded}"
- DockPanel.Dock="Right"
- ColumnDefinitions="160"
- RowDefinitions="Auto,Auto,*,Auto,Auto,Auto,Auto,Auto" Margin="5">
- <TextBlock
- Text="{Binding MaximumLayerString}"
- Name="Layer.Navigation.Up"
- Margin="0,0,0,10"
- HorizontalAlignment="Center"
- TextAlignment="Center"
- Grid.Row="0"/>
- <RepeatButton
- Grid.Row="1"
- ToolTip.Tip="Navigate to up layer [Ctrl + Up]"
- HotKey="Ctrl + Up"
- Interval="100"
- HorizontalAlignment="Stretch"
- IsEnabled="{Binding CanGoUp}"
- Command="{Binding GoNextLayer}"
- i:Attached.Icon="fas fa-angle-up"/>
-
- <Grid
- Name="LayerNavigationSliderGrid"
- Grid.Row="2" ColumnDefinitions="*,20,40">
- <Panel
- Grid.Column="0"
- Name="LayerNavigationTooltipPanel"
- Margin="{Binding LayerNavigationTooltipMargin}"
- HorizontalAlignment="Stretch">
- <Border
- Name="Layer.Navigation.Tooltip.Border"
- Classes="LayerNavigationToolTip"
- VerticalAlignment="Top">
- <TextBlock Padding="2" Text="{Binding ActualLayerTooltip}"/>
- </Border>
- </Panel>
-
- <!--<Image
- Grid.Column="1"
- Name="Layer.Navigation.Issues" Width="16"></Image>!-->
+ <RepeatButton
+ Grid.Row="3"
+ ToolTip.Tip="Navigate to down layer [Ctrl + Down]"
+ HotKey="Ctrl + Down"
+ Interval="100"
+ HorizontalAlignment="Stretch"
+ IsEnabled="{Binding CanGoDown}"
+ Command="{Binding GoPreviousLayer}"
+ i:Attached.Icon="fas fa-angle-down"/>
+
+ <NumericUpDown Grid.Row="4"
+ Margin="0,5"
+ Minimum="0"
+ Maximum="{Binding SliderMaximumValue}"
+ Value="{Binding ActualLayer}" />
+
+ <Grid Grid.Row="5" RowDefinitions="*" ColumnDefinitions="30,*,30">
+ <Button Grid.Column="0"
+ ToolTip.Tip="Navigate to first layer [Ctrl + Left]"
+ HotKey="Ctrl + Left"
+ IsEnabled="{Binding CanGoDown}"
+ Command="{Binding GoFirstLayer}"
+ i:Attached.Icon="fas fa-angle-double-down"/>
+
+ <TextBlock
+ Grid.Column="1"
+ Text="{Binding MinimumLayerString}"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Center"
+ TextAlignment="Center"/>
+
+ <Button
+ Grid.Column="2"
+ ToolTip.Tip="Navigate to last layer [Ctrl + Right]"
+ HotKey="Ctrl + Right"
+ IsEnabled="{Binding CanGoUp}"
+ Command="{Binding GoLastLayer}"
+ i:Attached.Icon="fas fa-angle-double-up"/>
+ </Grid>
- <Canvas
- Grid.Column="1"
- Margin="0,15"
- Classes="IssuesTrackerCanvas"
- Name="Layer.Navigation.IssuesCanvas" Width="20"/>
-
- <Slider
- Grid.Column="2"
- Name="Layer.Navigation.Slider"
- Minimum="0"
- Maximum="{Binding SliderMaximumValue}"
- Value="{Binding ActualLayerSlider}"
- TickFrequency="1"
- TickPlacement="Outside"
- SmallChange="1"
- LargeChange="10"
- IsSnapToTickEnabled="True"
- Margin="0,5"
- HorizontalAlignment="Right"
- Orientation="Vertical"/>
- </Grid>
-
- <RepeatButton
- Grid.Row="3"
- ToolTip.Tip="Navigate to down layer [Ctrl + Down]"
- HotKey="Ctrl + Down"
- Interval="100"
- HorizontalAlignment="Stretch"
- IsEnabled="{Binding CanGoDown}"
- Command="{Binding GoPreviousLayer}"
- i:Attached.Icon="fas fa-angle-down"/>
-
- <NumericUpDown Grid.Row="4"
- Margin="0,5"
- Minimum="0"
- Maximum="{Binding SliderMaximumValue}"
- Value="{Binding ActualLayer}" />
-
- <Grid Grid.Row="5" RowDefinitions="*" ColumnDefinitions="30,*,30">
- <Button Grid.Column="0"
- ToolTip.Tip="Navigate to first layer [Ctrl + Left]"
- HotKey="Ctrl + Left"
- IsEnabled="{Binding CanGoDown}"
- Command="{Binding GoFirstLayer}"
- i:Attached.Icon="fas fa-angle-double-down"/>
-
- <TextBlock
- Grid.Column="1"
- Text="{Binding MinimumLayerString}"
- VerticalAlignment="Center"
- HorizontalAlignment="Center"
- TextAlignment="Center"/>
-
- <Button
- Grid.Column="2"
- ToolTip.Tip="Navigate to last layer [Ctrl + Right]"
- HotKey="Ctrl + Right"
- IsEnabled="{Binding CanGoUp}"
- Command="{Binding GoLastLayer}"
- i:Attached.Icon="fas fa-angle-double-up"/>
- </Grid>
-
- <StackPanel Grid.Row="6"
- Margin="0,1,0,0"
- HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Orientation="Horizontal" Spacing="1">
- <Button
- ToolTip.Tip="Navigate to the smallest bottom layer in mass"
- Command="{Binding GoMassLayer}"
- CommandParameter="SB"
- Content="SB"/>
-
- <Button
- ToolTip.Tip="Navigate to the largest bottom layer in mass"
- Command="{Binding GoMassLayer}"
- CommandParameter="LB"
- Content="LB"/>
-
- <Button
- ToolTip.Tip="Navigate to the smallest normal layer in mass"
- Command="{Binding GoMassLayer}"
- CommandParameter="SN"
- Content="SN"/>
-
- <Button
- ToolTip.Tip="Navigate to the largest normal layer in mass"
- Command="{Binding GoMassLayer}"
- CommandParameter="LN"
- Content="LN"/>
- </StackPanel>
-
- </Grid>
-
-
- <!--<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
+ <StackPanel Grid.Row="6"
+ Margin="0,1,0,0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center"
+ Orientation="Horizontal" Spacing="1">
+ <Button
+ ToolTip.Tip="Navigate to the smallest bottom layer in mass"
+ Command="{Binding GoMassLayer}"
+ CommandParameter="SB"
+ Content="SB"/>
+
+ <Button
+ ToolTip.Tip="Navigate to the largest bottom layer in mass"
+ Command="{Binding GoMassLayer}"
+ CommandParameter="LB"
+ Content="LB"/>
+
+ <Button
+ ToolTip.Tip="Navigate to the smallest normal layer in mass"
+ Command="{Binding GoMassLayer}"
+ CommandParameter="SN"
+ Content="SN"/>
+
+ <Button
+ ToolTip.Tip="Navigate to the largest normal layer in mass"
+ Command="{Binding GoMassLayer}"
+ CommandParameter="LN"
+ Content="LN"/>
+ </StackPanel>
+
+ </Grid>
+
+
+ <!--<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Button Name="zoomtofit">Zoom to fit</Button>
<Button Name="center">Center image</Button>
</StackPanel>-->
- <Grid
- IsEnabled="{Binding IsFileLoaded}"
- ColumnDefinitions="*" RowDefinitions="Auto,*,Auto" Margin="5">
- <Grid Grid.Row="0" Grid.Column="0"
- IsEnabled="{Binding IsFileLoaded}"
- ColumnDefinitions="*,Auto" RowDefinitions="Auto" Margin="5">
- <WrapPanel HorizontalAlignment="Left" Grid.Row="0" Orientation="Horizontal">
- <uc:ToggleButtonWithIcon
- IsChecked="{Binding ShowLayerImageRotated}"
- HotKey="Ctrl + R"
- VerticalAlignment="Stretch"
- ToolTip.Tip="Auto rotate layer preview image at 90º (This can slow down the layer preview) [CTRL+R]"
- Margin="0,0,1,0"
- Text="Rotate ⮟"
- Spacing="5"
- Icon="fas fa-sync-alt">
- <uc:ToggleButtonWithIcon.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <RadioButton
- GroupName="ShowLayerImageRotateDirection"
- IsChecked="{Binding ShowLayerImageRotateCWDirection}"
- Content="90º Clockwise (CW)"/>
- <RadioButton
- GroupName="ShowLayerImageRotateDirection"
- IsChecked="{Binding ShowLayerImageRotateCCWDirection}"
- Content="90º Counter-clockwise (CCW)"/>
- </ContextMenu>
- </uc:ToggleButtonWithIcon.ContextMenu>
- </uc:ToggleButtonWithIcon>
-
-
- <uc:ToggleButtonWithIcon
- IsChecked="{Binding ShowLayerImageFlipped}"
- HotKey="Ctrl + F"
- VerticalAlignment="Stretch"
- ToolTip.Tip="Auto flip layer preview image (This can slow down the layer preview) [CTRL+F]"
- Margin="0,0,1,0"
- Text="Flip ⮟"
- Spacing="5"
- Icon="mdi-flip-horizontal">
- <uc:ToggleButtonWithIcon.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <CheckBox
- IsChecked="{Binding ShowLayerImageFlippedHorizontally}"
- Content="Horizontally"/>
- <CheckBox
- IsChecked="{Binding ShowLayerImageFlippedVertically}"
- Content="Vertically"/>
- </ContextMenu>
- </uc:ToggleButtonWithIcon.ContextMenu>
- </uc:ToggleButtonWithIcon>
-
-
- <uc:ToggleButtonWithIcon
- IsChecked="{Binding ShowLayerImageDifference}"
- ToolTip.Tip="Show layer differences where darker pixels were also present on previous layer and the white pixels the difference between previous and current layer."
- VerticalAlignment="Stretch"
- Margin="0,0,1,0"
- Text="Difference ⮟"
- Spacing="5"
- Icon="fas fa-layer-group">
- <uc:ToggleButtonWithIcon.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <CheckBox
- Content="Show layer similarity instead of difference"
- ToolTip.Tip="If enabled, it will recolor the current layer pixels in common with the previous and next layer"
- IsChecked="{Binding Settings.LayerPreview.LayerDifferenceHighlightSimilarityInstead}"/>
- </ContextMenu>
- </uc:ToggleButtonWithIcon.ContextMenu>
- </uc:ToggleButtonWithIcon>
-
- <uc:ToggleButtonWithIcon
- IsChecked="{Binding ShowLayerImageIssues}"
- ToolTip.Tip="Highlight Issues on current layer. Valid only if Issues are calculated."
- VerticalAlignment="Stretch"
- Margin="0,0,1,0"
- Text="Issues ⮟"
- Spacing="5"
- Icon="fas fa-radiation-alt">
- <Button.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <CheckBox
- ToolTip.Tip="Show crosshairs for selected issues on the current layer"
- IsChecked="{Binding ShowLayerImageCrosshairs}">
- <StackPanel Orientation="Horizontal">
- <i:Icon Value="fas fa-crosshairs"/>
- <TextBlock Margin="5,0,5,0" Text="Crosshairs"/>
- </StackPanel>
- </CheckBox>
-
- </ContextMenu>
- </Button.ContextMenu>
- </uc:ToggleButtonWithIcon>
-
-
- <uc:ButtonWithIcon Name="LayerPreviewOutlineButton"
- ToolTip.Tip="Click to access the various outlines."
- Command="{Binding OpenContextMenu}"
- CommandParameter="LayerPreviewOutline"
- VerticalAlignment="Stretch"
- Margin="1,0,0,0"
- Text="Outline ⮟"
- Spacing="5"
- Icon="fas fa-vector-square">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu Name="LayerPreviewOutlineContextMenu" PlacementMode="Bottom">
- <CheckBox
- IsChecked="{Binding ShowLayerOutlinePrintVolumeBoundary}"
- Content="Print volume boundary"/>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineLayerBoundary}"
- Content="Layer boundary"/>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineContourBoundary}"
- Content="Blob boundary"/>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineHollowAreas}"
- Content="Hollow areas"/>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineCentroids}"
- Content="Centroids"/>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineEdgeDetection}"
- Content="Edge detection">
- <CheckBox.IsEnabled>
- <MultiBinding Converter="{x:Static BoolConverters.And}">
- <Binding Path="!ShowLayerOutlineDistanceDetection"/>
- <Binding Path="!ShowLayerOutlineSkeletonize"/>
- </MultiBinding>
- </CheckBox.IsEnabled>
- </CheckBox>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineDistanceDetection}"
- ToolTip.Tip="Calculates the distance to the closest zero pixel for each pixel"
- Content="Distance detection">
- <CheckBox.IsEnabled>
- <MultiBinding Converter="{x:Static BoolConverters.And}">
- <Binding Path="!ShowLayerOutlineEdgeDetection"/>
- <Binding Path="!ShowLayerOutlineSkeletonize"/>
- </MultiBinding>
- </CheckBox.IsEnabled>
- </CheckBox>
- <CheckBox
- IsChecked="{Binding ShowLayerOutlineSkeletonize}"
- Content="Skeletonize">
- <CheckBox.IsEnabled>
- <MultiBinding Converter="{x:Static BoolConverters.And}">
- <Binding Path="!ShowLayerOutlineEdgeDetection"/>
- <Binding Path="!ShowLayerOutlineDistanceDetection"/>
- </MultiBinding>
- </CheckBox.IsEnabled>
- </CheckBox>
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
-
- <uc:ToggleButtonWithIcon HorizontalAlignment="Right"
- IsChecked="{Binding IsPixelEditorActive}"
- ToolTip.Tip="Edit layer image: Draw pixels, add supports and/or drain holes."
- VerticalAlignment="Stretch"
- Margin="0,0,0,0"
- Text="Pixel editor"
- Spacing="5"
- Icon="fas fa-drafting-compass"/>
-
- </WrapPanel>
-
-
- <StackPanel HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
- <uc:ButtonWithIcon Name="LayerActionsButton"
- Command="{Binding OpenContextMenu}"
- VerticalAlignment="Stretch"
- VerticalContentAlignment="Center"
- CommandParameter="LayerActions"
- Text="Actions ⮟"
- Spacing="5"
- Icon="mdi-layers-edit">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu Name="LayerActionsContextMenu" PlacementMode="Bottom" Items="{Binding LayerActionsMenu}"/>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
- <Button
- Command="{Binding ShowLayer}"
- HotKey="F5"
- ToolTip.Tip="Refresh current layer [F5]"
- VerticalAlignment="Stretch"
- Margin="1,0,0,0"
- i:Attached.Icon="fas fa-sync-alt"/>
-
- <uc:ButtonWithIcon
- Command="{Binding SaveCurrentLayerImage}"
- ToolTip.Tip="Save layer image to a file"
- VerticalAlignment="Stretch"
- VerticalContentAlignment="Center"
- Margin="1,0,0,0"
- Text="⮟"
- Spacing="3"
- Icon="fas fa-save">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu PlacementMode="Bottom">
- <MenuItem
- Command="{Binding SaveCurrentROIImage}"
- Header="Save the selected region (ROI)"
- i:MenuItem.Icon="far fa-object-group"/>
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
-
- </StackPanel>
- </Grid>
-
- <Border
- Grid.Row="1"
- BorderBrush="{DynamicResource LightBackground}"
- BorderThickness="5">
- <uvtava:AdvancedImageBox
- ShowGrid="{Binding Settings.LayerPreview.ShowBackgroudGrid}"
- GridCellSize="15"
- GridColor="{DynamicResource AdvancedImageBoxGridColor}"
- GridColorAlternate="{DynamicResource AdvancedImageBoxGridAlternateColor}"
- Name="LayerImage"/>
- </Border>
-
-
- <Canvas Grid.Row="1" Margin="20"
- IsVisible="{Binding IsTooltipOverlayVisible}">
- <Border BorderThickness="1"
- BorderBrush="Black"
- Background="{Binding Settings.LayerPreview.TooltipOverlayBackgroundBrush}"
- Padding="10"
- CornerRadius="5">
- <TextBlock Text="{Binding TooltipOverlayText}" Foreground="Black" />
- </Border>
- </Canvas>
-
-
-
- <Grid
- IsEnabled="{Binding IsFileLoaded}"
- Grid.Row="2"
- ColumnDefinitions="4*,2*" RowDefinitions="Auto" Margin="5">
- <WrapPanel Orientation="Horizontal">
- <StackPanel
- ToolTip.Tip="Number of pixels to cure on this layer image and the percentage of them against total lcd pixels and the total cured millimeters."
- VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
- <i:Icon Value="mdi-google-downasaur"/>
- <TextBlock Text="{Binding LayerPixelCountStr}"/>
- </StackPanel>
-
- <uc:ButtonWithIcon
- ToolTip.Tip="Object volume bounds for current layer, position and size in pixels and millimeters.
+ <Grid IsEnabled="{Binding IsFileLoaded}"
+ ColumnDefinitions="*" RowDefinitions="Auto,*,Auto" Margin="5">
+ <Grid Grid.Row="0" Grid.Column="0"
+ IsEnabled="{Binding IsFileLoaded}"
+ ColumnDefinitions="*,Auto" RowDefinitions="Auto" Margin="0,5,0,5">
+ <WrapPanel Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Orientation="Horizontal">
+ <uc:ToggleButtonWithIcon
+ IsChecked="{Binding ShowLayerImageRotated}"
+ HotKey="Ctrl + R"
+ VerticalAlignment="Stretch"
+ ToolTip.Tip="Auto rotate layer preview image at 90º (This can slow down the layer preview) [CTRL+R]"
+ Margin="0,0,1,0"
+ Text="Rotate ⮟"
+ Spacing="5"
+ Icon="fas fa-sync-alt">
+ <uc:ToggleButtonWithIcon.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <RadioButton
+ GroupName="ShowLayerImageRotateDirection"
+ IsChecked="{Binding ShowLayerImageRotateCWDirection}"
+ Content="90º Clockwise (CW)"/>
+ <RadioButton
+ GroupName="ShowLayerImageRotateDirection"
+ IsChecked="{Binding ShowLayerImageRotateCCWDirection}"
+ Content="90º Counter-clockwise (CCW)"/>
+ </ContextMenu>
+ </uc:ToggleButtonWithIcon.ContextMenu>
+ </uc:ToggleButtonWithIcon>
+
+
+ <uc:ToggleButtonWithIcon
+ IsChecked="{Binding ShowLayerImageFlipped}"
+ HotKey="Ctrl + F"
+ VerticalAlignment="Stretch"
+ ToolTip.Tip="Auto flip layer preview image (This can slow down the layer preview) [CTRL+F]"
+ Margin="0,0,1,0"
+ Text="Flip ⮟"
+ Spacing="5"
+ Icon="mdi-flip-horizontal">
+ <uc:ToggleButtonWithIcon.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <CheckBox
+ IsChecked="{Binding ShowLayerImageFlippedHorizontally}"
+ Content="Horizontally"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerImageFlippedVertically}"
+ Content="Vertically"/>
+ </ContextMenu>
+ </uc:ToggleButtonWithIcon.ContextMenu>
+ </uc:ToggleButtonWithIcon>
+
+
+ <uc:ToggleButtonWithIcon
+ IsChecked="{Binding ShowLayerImageDifference}"
+ ToolTip.Tip="Show layer differences where darker pixels were also present on previous layer and the white pixels the difference between previous and current layer."
+ VerticalAlignment="Stretch"
+ Margin="0,0,1,0"
+ Text="Difference ⮟"
+ Spacing="5"
+ Icon="fas fa-layer-group">
+ <uc:ToggleButtonWithIcon.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <CheckBox
+ Content="Show layer similarity instead of difference"
+ ToolTip.Tip="If enabled, it will recolor the current layer pixels in common with the previous and next layer"
+ IsChecked="{Binding Settings.LayerPreview.LayerDifferenceHighlightSimilarityInstead}"/>
+ </ContextMenu>
+ </uc:ToggleButtonWithIcon.ContextMenu>
+ </uc:ToggleButtonWithIcon>
+
+ <uc:ToggleButtonWithIcon
+ IsChecked="{Binding ShowLayerImageIssues}"
+ ToolTip.Tip="Highlight Issues on current layer. Valid only if Issues are calculated."
+ VerticalAlignment="Stretch"
+ Margin="0,0,1,0"
+ Text="Issues ⮟"
+ Spacing="5"
+ Icon="fas fa-radiation-alt">
+ <Button.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <CheckBox
+ ToolTip.Tip="Show crosshairs for selected issues on the current layer"
+ IsChecked="{Binding ShowLayerImageCrosshairs}">
+ <StackPanel Orientation="Horizontal">
+ <i:Icon Value="fas fa-crosshairs"/>
+ <TextBlock Margin="5,0,5,0" Text="Crosshairs"/>
+ </StackPanel>
+ </CheckBox>
+
+ </ContextMenu>
+ </Button.ContextMenu>
+ </uc:ToggleButtonWithIcon>
+
+
+ <uc:ButtonWithIcon Name="LayerPreviewOutlineButton"
+ ToolTip.Tip="Click to access the various outlines."
+ Command="{Binding OpenContextMenu}"
+ CommandParameter="LayerPreviewOutline"
+ VerticalAlignment="Stretch"
+ Margin="1,0,0,0"
+ Text="Outline ⮟"
+ Spacing="5"
+ Icon="fas fa-vector-square">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu Name="LayerPreviewOutlineContextMenu" PlacementMode="Bottom">
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlinePrintVolumeBoundary}"
+ Content="Print volume boundary"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineLayerBoundary}"
+ Content="Layer boundary"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineContourBoundary}"
+ Content="Blob boundary"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineHollowAreas}"
+ Content="Hollow areas"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineCentroids}"
+ Content="Centroids"/>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineEdgeDetection}"
+ Content="Edge detection">
+ <CheckBox.IsEnabled>
+ <MultiBinding Converter="{x:Static BoolConverters.And}">
+ <Binding Path="!ShowLayerOutlineDistanceDetection"/>
+ <Binding Path="!ShowLayerOutlineSkeletonize"/>
+ </MultiBinding>
+ </CheckBox.IsEnabled>
+ </CheckBox>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineDistanceDetection}"
+ ToolTip.Tip="Calculates the distance to the closest zero pixel for each pixel"
+ Content="Distance detection">
+ <CheckBox.IsEnabled>
+ <MultiBinding Converter="{x:Static BoolConverters.And}">
+ <Binding Path="!ShowLayerOutlineEdgeDetection"/>
+ <Binding Path="!ShowLayerOutlineSkeletonize"/>
+ </MultiBinding>
+ </CheckBox.IsEnabled>
+ </CheckBox>
+ <CheckBox
+ IsChecked="{Binding ShowLayerOutlineSkeletonize}"
+ Content="Skeletonize">
+ <CheckBox.IsEnabled>
+ <MultiBinding Converter="{x:Static BoolConverters.And}">
+ <Binding Path="!ShowLayerOutlineEdgeDetection"/>
+ <Binding Path="!ShowLayerOutlineDistanceDetection"/>
+ </MultiBinding>
+ </CheckBox.IsEnabled>
+ </CheckBox>
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+
+ <uc:ToggleButtonWithIcon HorizontalAlignment="Right"
+ IsChecked="{Binding IsPixelEditorActive}"
+ ToolTip.Tip="Edit layer image: Draw pixels, add supports and/or drain holes."
+ VerticalAlignment="Stretch"
+ Margin="0,0,0,0"
+ Text="Pixel editor"
+ Spacing="5"
+ Icon="fas fa-drafting-compass"/>
+ </WrapPanel>
+
+
+ <StackPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
+ <uc:ButtonWithIcon Name="LayerActionsButton"
+ Command="{Binding OpenContextMenu}"
+ VerticalAlignment="Stretch"
+ VerticalContentAlignment="Center"
+ CommandParameter="LayerActions"
+ Text="Actions ⮟"
+ Spacing="5"
+ Icon="mdi-layers-edit">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu Name="LayerActionsContextMenu" PlacementMode="Bottom" Items="{Binding LayerActionsMenu}"/>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+ <Button
+ Command="{Binding ShowLayer}"
+ HotKey="F5"
+ ToolTip.Tip="Refresh current layer [F5]"
+ VerticalAlignment="Stretch"
+ Margin="1,0,0,0"
+ i:Attached.Icon="fas fa-sync-alt"/>
+
+ <uc:ButtonWithIcon
+ Command="{Binding SaveCurrentLayerImage}"
+ ToolTip.Tip="Save layer image to a file"
+ VerticalAlignment="Stretch"
+ VerticalContentAlignment="Center"
+ Margin="1,0,0,0"
+ Text="⮟"
+ Spacing="3"
+ Icon="fas fa-save">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu PlacementMode="Bottom">
+ <MenuItem
+ Command="{Binding SaveCurrentROIImage}"
+ Header="Save the selected region (ROI)"
+ i:MenuItem.Icon="far fa-object-group"/>
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+
+ </StackPanel>
+ </Grid>
+
+ <Border
+ Grid.Row="1"
+ BorderBrush="{DynamicResource LightBackground}"
+ BorderThickness="5">
+ <uvtava:AdvancedImageBox
+ ShowGrid="{Binding Settings.LayerPreview.ShowBackgroudGrid}"
+ GridCellSize="15"
+ GridColor="{DynamicResource AdvancedImageBoxGridColor}"
+ GridColorAlternate="{DynamicResource AdvancedImageBoxGridAlternateColor}"
+ Name="LayerImage"/>
+ </Border>
+
+
+ <Canvas Grid.Row="1" Margin="20"
+ IsVisible="{Binding IsTooltipOverlayVisible}">
+ <Border BorderThickness="1"
+ BorderBrush="Black"
+ Background="{Binding Settings.LayerPreview.TooltipOverlayBackgroundBrush}"
+ Padding="10"
+ CornerRadius="5">
+ <TextBlock Text="{Binding TooltipOverlayText}" Foreground="Black" />
+ </Border>
+ </Canvas>
+
+
+
+ <Grid
+ IsEnabled="{Binding IsFileLoaded}"
+ Grid.Row="2"
+ ColumnDefinitions="4*,2*" RowDefinitions="Auto" Margin="5">
+ <WrapPanel Orientation="Horizontal">
+ <StackPanel
+ ToolTip.Tip="Number of pixels to cure on this layer image and the percentage of them against total lcd pixels and the total cured millimeters."
+ VerticalAlignment="Center" Orientation="Horizontal" Spacing="5">
+ <i:Icon Value="mdi-google-downasaur"/>
+ <TextBlock Text="{Binding LayerPixelCountStr}"/>
+ </StackPanel>
+
+ <uc:ButtonWithIcon
+ ToolTip.Tip="Object volume bounds for current layer, position and size in pixels and millimeters.
&#x0a;Click: go to region"
- Command="{Binding ZoomToFitPrintVolume}"
- Margin="5,0,0,0"
- Text="{Binding LayerBoundsStr}"
- Spacing="5"
- Icon="fas fa-expand"/>
-
- <uc:ButtonWithIcon
- IsEnabled="{Binding IsFileLoaded}"
- Margin="2,0,0,0"
- Command="{Binding OnROIClick}"
- ToolTip.Tip="Region of interest selection over layer.
+ Command="{Binding ZoomToFitPrintVolume}"
+ Margin="5,0,0,0"
+ Text="{Binding LayerBoundsStr}"
+ Spacing="5"
+ Icon="fas fa-expand"/>
+
+ <uc:ButtonWithIcon
+ IsEnabled="{Binding IsFileLoaded}"
+ Margin="2,0,0,0"
+ Command="{Binding OnROIClick}"
+ ToolTip.Tip="Region of interest selection over layer.
&#x0a;(NS): Not selected
&#x0a;Click: go to region
&#x0a;ESC: Clear ROI &amp; Masks | ESC + Shift: Clear ROI"
- Text="{Binding LayerROIStr}"
- Spacing="5"
- Icon="far fa-object-group">
- <uc:ButtonWithIcon.ContextMenu>
- <ContextMenu Name="ROIContextMenu" PlacementMode="Top">
- <MenuItem
- Command="{Binding SelectLayerPositiveAreasMask}"
- Header="Mask: Select layer positive areas"/>
- <MenuItem
- Command="{Binding SelectLayerHollowAreasMask}"
- Header="Mask: Select layer hollow areas"/>
- <Separator/>
- <MenuItem
- Command="{Binding SelectModelVolumeRoi}"
- Header="ROI: Select model volume"/>
- <MenuItem
- Command="{Binding SelectLayerVolumeRoi}"
- Header="ROI: Select layer volume"/>
- <Separator/>
- <MenuItem
- Command="{Binding ClearMask}"
- Header="Clear Mask"/>
- <MenuItem
- Command="{Binding ClearROI}"
- Header="Clear ROI"/>
- </ContextMenu>
- </uc:ButtonWithIcon.ContextMenu>
- </uc:ButtonWithIcon>
-
- </WrapPanel>
-
- <WrapPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
- <uc:ButtonWithIcon
- IsEnabled="{Binding LayerPixelPicker.IsSet}"
- Command="{Binding OnLayerPixelPickerClicked}"
- ToolTip.Tip="Pixel picker:
+ Text="{Binding LayerROIStr}"
+ Spacing="5"
+ Icon="far fa-object-group">
+ <uc:ButtonWithIcon.ContextMenu>
+ <ContextMenu Name="ROIContextMenu" PlacementMode="Top">
+ <MenuItem
+ Command="{Binding SelectLayerPositiveAreasMask}"
+ Header="Mask: Select layer positive areas"/>
+ <MenuItem
+ Command="{Binding SelectLayerHollowAreasMask}"
+ Header="Mask: Select layer hollow areas"/>
+ <Separator/>
+ <MenuItem
+ Command="{Binding SelectModelVolumeRoi}"
+ Header="ROI: Select model volume"/>
+ <MenuItem
+ Command="{Binding SelectLayerVolumeRoi}"
+ Header="ROI: Select layer volume"/>
+ <Separator/>
+ <MenuItem
+ Command="{Binding ClearMask}"
+ Header="Clear Mask"/>
+ <MenuItem
+ Command="{Binding ClearROI}"
+ Header="Clear ROI"/>
+ </ContextMenu>
+ </uc:ButtonWithIcon.ContextMenu>
+ </uc:ButtonWithIcon>
+
+ </WrapPanel>
+
+ <WrapPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
+ <uc:ButtonWithIcon
+ IsEnabled="{Binding LayerPixelPicker.IsSet}"
+ Command="{Binding OnLayerPixelPickerClicked}"
+ ToolTip.Tip="Pixel picker:
&#x0a;Use CONTROL and over a pixel to get his position and brightness.
&#x0a;Click: Center at position"
- Text="{Binding LayerPixelPicker}"
- Spacing="5"
- Icon="fas fa-map-marker-alt"/>
+ Text="{Binding LayerPixelPicker}"
+ Spacing="5"
+ Icon="fas fa-map-marker-alt"/>
- <uc:ButtonWithIcon
- ToolTip.Tip="Layer image zoom level, use mouse scroll to zoom in/out into image.
+ <uc:ButtonWithIcon
+ ToolTip.Tip="Layer image zoom level, use mouse scroll to zoom in/out into image.
&#x0a;Click to set zoom to 100%
&#x0a;Shift+Click to set zoom to defined value
&#x0a;Ctrl + 0 OR double right click to scale to fit"
- Margin="2,0,0,0"
- Command="{Binding ZoomToNormal}"
- Text="{Binding LayerZoomStr}"
- Spacing="5"
- Icon="fas fa-search-plus"/>
-
- <uc:ButtonWithIcon
- ToolTip.Tip="Layer Resolution and display size.
+ Margin="2,0,0,0"
+ Command="{Binding ZoomToNormal}"
+ Text="{Binding LayerZoomStr}"
+ Spacing="5"
+ Icon="fas fa-search-plus"/>
+
+ <uc:ButtonWithIcon
+ ToolTip.Tip="Layer Resolution and display size.
&#x0a;Click: Zoom to fit"
- Command="{Binding ZoomToFitSimple}"
- Margin="2,0,0,0"
- Text="{Binding LayerResolutionStr}"
- Spacing="5"
- Icon="fas fa-expand"/>
+ Command="{Binding ZoomToFitSimple}"
+ Margin="2,0,0,0"
+ Text="{Binding LayerResolutionStr}"
+ Spacing="5"
+ Icon="fas fa-expand"/>
- <TextBlock
- ToolTip.Tip="Layer preview computation time."
- Margin="5,0,0,0"
- VerticalAlignment="Center" Text="{Binding ShowLayerRenderMs, StringFormat=\{0\}ms}"/>
- </WrapPanel>
- </Grid>
- </Grid>
+ <TextBlock
+ ToolTip.Tip="Layer preview computation time."
+ Margin="5,0,0,0"
+ VerticalAlignment="Center" Text="{Binding ShowLayerRenderMs, StringFormat=\{0\}ms}"/>
+ </WrapPanel>
+ </Grid>
+ </Grid>
- </DockPanel>
- <Grid Grid.Row="0" Grid.Column="0"
+ </DockPanel>
+ <Grid Grid.Row="0" Grid.Column="0"
RowDefinitions="*,Auto,*" ColumnDefinitions="*,Auto,*"
IsEnabled="{Binding IsProgressVisible}"
IsVisible="{Binding IsProgressVisible}">
- <Border Grid.Row="1" Grid.Column="1" MinWidth="450"
+ <Border Grid.Row="1" Grid.Column="1" MinWidth="450"
Classes="ProgressLoading"
BorderThickness="5"
CornerRadius="5">
- <Grid RowDefinitions="Auto,Auto,Auto,Auto"
+ <Grid RowDefinitions="Auto,Auto,Auto,Auto"
ColumnDefinitions="*">
- <TextBlock
+ <TextBlock
Grid.Row="0"
Margin="10" Text="{Binding Progress.Title}"/>
- <TextBlock
+ <TextBlock
Grid.Row="1"
Margin="10,0,10,10" Text="{Binding Progress.ElapsedTimeStr, StringFormat=Elapsed Time: \{0\}}"/>
- <TextBlock
+ <TextBlock
Grid.Row="2"
Margin="10,0,10,10" Text="{Binding Progress.Description}" HorizontalAlignment="Center"/>
- <Grid
+ <Grid
Grid.Row="3"
RowDefinitions="30" ColumnDefinitions="*,100">
- <ProgressBar
+ <ProgressBar
Grid.Column="0"
Minimum="0"
Maximum="100"
VerticalAlignment="Stretch"
IsIndeterminate="{Binding Progress.IsIndeterminate}"
Value="{Binding Progress.ProgressPercent}" ShowProgressText="True"/>
- <Button
+ <Button
IsEnabled="{Binding Progress.CanCancel}"
Command="{Binding ProgressOnClickCancel}"
Grid.Column="1"
@@ -2122,9 +2120,9 @@
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
Content="Cancel"/>
- </Grid>
- </Grid>
- </Border>
- </Grid>
- </Grid>
+ </Grid>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
</uc:WindowEx>
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 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
- <Version>3.2.0</Version>
+ <Version>3.2.1</Version>
<Platforms>AnyCPU;x64</Platforms>
<PackageIcon>UVtools.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
@@ -44,9 +44,9 @@
<PackageReference Include="Avalonia.Desktop" Version="0.10.13" />
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.13" />
<PackageReference Include="MessageBox.Avalonia" Version="2.0.0" />
- <PackageReference Include="Projektanker.Icons.Avalonia" Version="4.2.1" />
- <PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="4.2.1" />
- <PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="4.2.1" />
+ <PackageReference Include="Projektanker.Icons.Avalonia" Version="4.3.0" />
+ <PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" Version="4.3.0" />
+ <PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="4.3.0" />
<PackageReference Include="ThemeEditor.Controls.ColorPicker" Version="0.10.12" />
</ItemGroup>
<ItemGroup>
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"