WPF progress

This commit is contained in:
Tiago Conceição
2020-10-20 23:41:38 +01:00
parent d709cdda41
commit 661cb1cf99
30 changed files with 8239 additions and 895 deletions
+9
View File
@@ -0,0 +1,9 @@
cd $PSScriptRoot
$version = (Get-Command UVtools.GUI\bin\Release\UVtools.Core.dll).FileVersionInfo.FileVersion
Remove-Item "$PSScriptRoot\UVtools.GUI\bin\Release\Logs" -Recurse -ErrorAction Ignore
Add-Type -A System.IO.Compression.FileSystem
[IO.Compression.ZipFile]::CreateFromDirectory("$PSScriptRoot\UVtools.GUI\bin\Release", "$PSScriptRoot\UVtools.GUI\bin\UVtools_v$version.zip")
Copy-Item "$PSScriptRoot\UVtools.Installer\bin\Release\UVtools.msi" -Destination "$PSScriptRoot\UVtools.GUI\bin\UVtools_v$version.msi"
+9
View File
@@ -0,0 +1,9 @@
cd $PSScriptRoot
$version = (Get-Command UVtools.WPF\bin\Release\netcoreapp3.1\UVtools.dll).FileVersionInfo.FileVersion
echo "UVtools v$version"
Remove-Item "$PSScriptRoot\UVtools.WPF\bin\Release\netcoreapp3.1\Assets\usersettings.xml" -Recurse -ErrorAction Ignore
Add-Type -A System.IO.Compression.FileSystem
[IO.Compression.ZipFile]::CreateFromDirectory("$PSScriptRoot\UVtools.WPF\bin\Release\netcoreapp3.1", "$PSScriptRoot\UVtools.WPF\bin\UVtools_v$version.zip")
Copy-Item "$PSScriptRoot\UVtools.Installer\bin\Release\UVtools.msi" -Destination "$PSScriptRoot\UVtools.WPF\bin\UVtools_v$version.msi"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

+16 -1
View File
@@ -18,6 +18,9 @@ namespace UVtools.Core.Extensions
public static class EmguExtensions
{
public static readonly MCvScalar BlackByte = new MCvScalar(0);
public static readonly MCvScalar Black3Byte = new MCvScalar(0, 0, 0);
public static readonly MCvScalar Transparent4Byte = new MCvScalar(0, 0, 0, 0);
public static readonly MCvScalar Black4Byte = new MCvScalar(0, 0, 0, 255);
public static unsafe byte* GetBytePointer(this Mat mat)
{
@@ -216,7 +219,19 @@ namespace UVtools.Core.Extensions
public static Mat InitMat(Size size, DepthType depthType = DepthType.Cv8U, int channels = 1)
{
var mat = new Mat(size, depthType, channels);
mat.SetTo(BlackByte);
switch (channels)
{
case 1:
mat.SetTo(BlackByte);
break;
case 3:
mat.SetTo(Black3Byte);
break;
case 4:
mat.SetTo(Transparent4Byte);
break;
}
return mat;
}
+2 -10
View File
@@ -956,17 +956,10 @@ namespace UVtools.Core
}
}
bool isIsland = true;
if (points.Count == 0) continue; // Should never happen
if (points.Count == 92 && points[0].X == 876 && points[0].Y == 884)
{
}
var requiredSupportingPixels = Math.Max(1, points.Count * islandConfig.RequiredPixelsToSupportMultiplier);
if (pixelsSupportingIsland >= requiredSupportingPixels)
isIsland = false;
/*if (pixelsSupportingIsland >= islandConfig.RequiredPixelsToSupport)
isIsland = false; // Not a island, bounding is strong, i think...
else if (pixelsSupportingIsland > 0 &&
@@ -975,12 +968,11 @@ namespace UVtools.Core
isIsland = false; // Not a island, but maybe weak bounding...*/
if (isIsland)
if (pixelsSupportingIsland < requiredSupportingPixels)
{
result.Add(new LayerIssue(layer, LayerIssue.IssueType.Island,
points.ToArray(),
rect));
continue;
}
// Check for overhangs
+1 -2
View File
@@ -216,8 +216,7 @@
<setting name="LayerRepairRemoveEmptyLayers" serializeAs="String">
<value>True</value>
</setting>
<setting name="LayerRepairRemoveIslandsBelowEqualPixelsDefault"
serializeAs="String">
<setting name="LayerRepairRemoveIslandsBelowEqualPixelsDefault" serializeAs="String">
<value>5</value>
</setting>
<setting name="PartialUpdateIslandsOnEditing" serializeAs="String">
+2 -2
View File
@@ -112,7 +112,7 @@
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing.Common, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Drawing.Common.5.0.0-rc.1.20451.14\lib\net461\System.Drawing.Common.dll</HintPath>
<HintPath>..\packages\System.Drawing.Common.5.0.0-rc.2.20475.5\lib\net461\System.Drawing.Common.dll</HintPath>
</Reference>
<Reference Include="System.Drawing.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Drawing.Primitives.4.3.0\lib\net45\System.Drawing.Primitives.dll</HintPath>
@@ -143,7 +143,7 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0-rc.1.20451.14\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0-rc.2.20475.5\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Extensions, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath>
+2 -2
View File
@@ -6,7 +6,7 @@
<package id="Emgu.CV.runtime.windows" version="4.4.0.4099" targetFramework="net48" />
<package id="ObjectListView.Official" version="2.9.2-alpha2" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Drawing.Common" version="5.0.0-rc.1.20451.14" targetFramework="net48" />
<package id="System.Drawing.Common" version="5.0.0-rc.2.20475.5" targetFramework="net48" />
<package id="System.Drawing.Primitives" version="4.3.0" targetFramework="net48" />
<package id="System.IO" version="4.3.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.4" targetFramework="net48" />
@@ -14,7 +14,7 @@
<package id="System.Reflection.TypeExtensions" version="4.7.0" targetFramework="net48" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net48" />
<package id="System.Runtime" version="4.3.1" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0-rc.1.20451.14" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0-rc.2.20475.5" targetFramework="net48" />
<package id="System.Runtime.Extensions" version="4.3.1" targetFramework="net48" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net48" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net48" />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 109 KiB

+84 -20
View File
@@ -11,7 +11,6 @@ using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Threading;
using UVtools.Core.Extensions;
using UVtools.WPF.Extensions;
using Bitmap = Avalonia.Media.Imaging.Bitmap;
@@ -515,6 +514,31 @@ namespace UVtools.WPF.Controls
}
}
/// <summary>
/// Gets or sets an image to follow the mouse pointer
/// </summary>
public Bitmap TrackerImage
{
get => _trackerImage;
set
{
if (!RaiseAndSetIfChanged(ref _trackerImage, value)) return;
RaisePropertyChanged(nameof(HaveTrackerImage));
TriggerRender();
}
}
public bool HaveTrackerImage => !(_trackerImage is null);
/// <summary>
/// Gets or sets if the tracker image will be scaled to the current zoom
/// </summary>
public bool TrackerImageAutoZoom
{
get => _trackerImageAutoZoom;
set => RaiseAndSetIfChanged(ref _trackerImageAutoZoom, value);
}
public bool IsHorizontalBarVisible
{
get
@@ -545,6 +569,12 @@ namespace UVtools.WPF.Controls
set => SetAndRaise(ShowGridProperty, ref _showGrid, value);
}
public Point PointerPosition
{
get => _pointerPosition;
private set => RaiseAndSetIfChanged(ref _pointerPosition, value);
}
public bool IsPanning
{
get => _isPanning;
@@ -577,7 +607,7 @@ namespace UVtools.WPF.Controls
get
{
var viewport = GetImageViewPort();
return new Point((viewport.Width / 2), viewport.Height / 2);
return new Point(viewport.Width / 2, viewport.Height / 2);
}
}
@@ -736,6 +766,8 @@ namespace UVtools.WPF.Controls
private bool _isPanning;
private bool _isSelecting;
private Bitmap _image;
private Bitmap _trackerImage;
private bool _trackerImageAutoZoom = true;
private byte _gridCellSize;
private ISolidColorBrush _gridColor = Brushes.Gainsboro;
private ISolidColorBrush _gridColorAlternate = Brushes.White;
@@ -751,6 +783,8 @@ namespace UVtools.WPF.Controls
private Rect _selectionRegion = Rect.Empty;
private SelectionModes _selectionMode = SelectionModes.None;
private bool _canRender = true;
private Point _pointerPosition;
public AdvancedImageBox()
@@ -810,9 +844,11 @@ namespace UVtools.WPF.Controls
}
}
public void TriggerRender()
public void TriggerRender(bool renderOnlyCursorTracker = false)
{
if (!_canRender) return;
if (renderOnlyCursorTracker && _trackerImage is null) return;
InvalidateVisual();
}
@@ -1019,7 +1055,7 @@ namespace UVtools.WPF.Controls
_canRender = true;
Offset = new Vector(x, y);
Debug.WriteLine(
/*Debug.WriteLine(
$"X/Y: {x},{y} | \n" +
$"Offset: {Offset} | \n" +
$"ZoomFactor: {ZoomFactor} | \n" +
@@ -1027,7 +1063,7 @@ namespace UVtools.WPF.Controls
$"MAX: {HorizontalScrollBar.Maximum},{VerticalScrollBar.Maximum} \n" +
$"ViewPort: {Viewport.Width},{Viewport.Height} \n" +
$"Container: {HorizontalScrollBar.ViewportSize},{VerticalScrollBar.ViewportSize} \n" +
$"Relative: {relativeDisplayPoint}");
$"Relative: {relativeDisplayPoint}");*/
}
/// <summary>
@@ -1467,10 +1503,26 @@ namespace UVtools.WPF.Controls
if (Image is null) return;
// Draw iamge
context.DrawImage(Image,
context.DrawImage(_image,
GetSourceImageRegion(),
GetImageViewPort()
);
if (HaveTrackerImage && _pointerPosition.X >= 0 && _pointerPosition.Y >= 0)
{
var destSize = TrackerImageAutoZoom
? new Size(_trackerImage.Size.Width * ZoomFactor, _trackerImage.Size.Height * ZoomFactor)
: _image.Size;
var destPos = new Point(
_pointerPosition.X - destSize.Width / 2,
_pointerPosition.Y - destSize.Height / 2
);
context.DrawImage(_trackerImage,
new Rect(destPos, destSize)
);
}
//SkiaContext.SkCanvas.dr
// Draw pixel grid
var pixelSize = ZoomFactor;
@@ -1806,15 +1858,27 @@ namespace UVtools.WPF.Controls
IsSelecting = false;
}
protected override void OnPointerLeave(PointerEventArgs e)
{
base.OnPointerLeave(e);
PointerPosition = new Point(-1,-1);
TriggerRender(true);
e.Handled = true;
}
protected override void OnPointerMoved(PointerEventArgs e)
{
base.OnPointerMoved(e);
if (e.Handled) return;
if (!IsPanning && !IsSelecting) return;
var pointer = e.GetCurrentPoint(this);
var location = pointer.Position;
PointerPosition = pointer.Position;
if (!IsPanning && !IsSelecting)
{
TriggerRender(true);
return;
}
if (IsPanning)
{
@@ -1823,13 +1887,13 @@ namespace UVtools.WPF.Controls
if (!InvertMouse)
{
x = _startScrollPosition.X + (_startMousePosition.X - location.X);
y = _startScrollPosition.Y + (_startMousePosition.Y - location.Y);
x = _startScrollPosition.X + (_startMousePosition.X - _pointerPosition.X);
y = _startScrollPosition.Y + (_startMousePosition.Y - _pointerPosition.Y);
}
else
{
x = (_startScrollPosition.X - (_startMousePosition.X - location.X));
y = (_startScrollPosition.Y - (_startMousePosition.Y - location.Y));
x = (_startScrollPosition.X - (_startMousePosition.X - _pointerPosition.X));
y = (_startScrollPosition.Y - (_startMousePosition.Y - _pointerPosition.Y));
}
Offset = new Vector(x, y);
@@ -1843,26 +1907,26 @@ namespace UVtools.WPF.Controls
var imageOffset = GetImageViewPort().Position;
if (location.X < _startMousePosition.X)
if (_pointerPosition.X < _startMousePosition.X)
{
x = location.X;
w = _startMousePosition.X - location.X;
x = _pointerPosition.X;
w = _startMousePosition.X - _pointerPosition.X;
}
else
{
x = _startMousePosition.X;
w = location.X - _startMousePosition.X;
w = _pointerPosition.X - _startMousePosition.X;
}
if (location.Y < _startMousePosition.Y)
if (_pointerPosition.Y < _startMousePosition.Y)
{
y = location.Y;
h = _startMousePosition.Y - location.Y;
y = _pointerPosition.Y;
h = _startMousePosition.Y - _pointerPosition.Y;
}
else
{
y = _startMousePosition.Y;
h = location.Y - _startMousePosition.Y;
h = _pointerPosition.Y - _startMousePosition.Y;
}
x -= imageOffset.X - Offset.X;
@@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="800"
mc:Ignorable="d" d:DesignWidth="950" d:DesignHeight="500"
x:Class="UVtools.WPF.Controls.Tools.ToolPixelDimmingControl">
<StackPanel Spacing="10">
<StackPanel Spacing="10" Orientation="Horizontal">
@@ -31,8 +31,8 @@
</StackPanel>
<Grid
RowDefinitions="200"
ColumnDefinitions="400,10,400"
RowDefinitions="200,10,Auto"
ColumnDefinitions="450,10,450"
>
<TextBox
AcceptsReturn="True"
@@ -49,175 +49,185 @@
TextWrapping="NoWrap"
Text="{Binding AlternatePatternText}"
/>
</Grid>
<Border
<Border
Grid.Row="3"
BorderBrush="LightGray"
BorderThickness="1"
Margin="0,5"
Padding="5"
>
<StackPanel Spacing="10">
<TextBlock FontWeight="Bold" Text="Pixel dimming generator"/>
<StackPanel Spacing="10">
<TextBlock FontWeight="Bold" Text="Pixel dimming generator"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock
VerticalAlignment="Center"
Text="Brightness:"/>
<NumericUpDown
Minimum="0"
Maximum="254"
Width="80"
Value="{Binding DimGenBrightness}"
/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Chessboard"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Chessboard"
/>
<Button
Padding="10"
Content="Sparse"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Sparse"
/>
<Button
Padding="10"
Content="Crosses"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Crosses"
/>
<Button
Padding="10"
Content="Strips"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Strips"
/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Pyramid"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Pyramid"
/>
<Button
Padding="10"
Content="Rhombus"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Rhombus"
/>
<Button
Padding="10"
Content="Waves"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Waves"
/>
<Button
Padding="10"
Content="Slashes"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Slashes"
/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Hearts"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Hearts"
/>
<Button
Padding="10"
Content="Solid"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Solid"
/>
</StackPanel>
</StackPanel>
</Border>
<Border
Grid.Row="3"
Grid.Column="3"
BorderBrush="LightGray"
BorderThickness="1"
Padding="5"
>
<StackPanel Spacing="10">
<TextBlock FontWeight="Bold" Text="Infill generator"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock
VerticalAlignment="Center"
Text="Brightness:"/>
<NumericUpDown
Minimum="0"
Maximum="254"
Width="80"
Value="{Binding DimGenBrightness}"
TextWrapping="Wrap"
Text="Warning: This function can generate a large number of resin traps. (Use with caution)"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock
VerticalAlignment="Center"
Text="Thickness:"/>
<NumericUpDown
Minimum="5"
Maximum="10000"
Width="80"
Value="{Binding InfillGenThickness}"
/>
<TextBlock
VerticalAlignment="Center"
Text="px"/>
<TextBlock
Margin="20,0,0,0"
VerticalAlignment="Center"
Text="Spacing:"/>
<NumericUpDown
Minimum="5"
Maximum="10000"
Width="80"
Value="{Binding InfillGenSpacing}"
/>
<TextBlock
VerticalAlignment="Center"
Text="px"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Rectilinear"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Rectilinear"
/>
<Button
Padding="10"
Content="Square grid"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Square grid"
/>
<Button
Padding="10"
Content="Waves"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Waves"
/>
</StackPanel>
</StackPanel>
</Border>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Chessboard"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Chessboard"
/>
<Button
Padding="10"
Content="Sparse"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Sparse"
/>
<Button
Padding="10"
Content="Crosses"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Crosses"
/>
<Button
Padding="10"
Content="Strips"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Strips"
/>
<Button
Padding="10"
Content="Pyramid"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Pyramid"
/>
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Rhombus"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Rhombus"
/>
<Button
Padding="10"
Content="Waves"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Waves"
/>
<Button
Padding="10"
Content="Slashes"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Slashes"
/>
<Button
Padding="10"
Content="Hearts"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Hearts"
/>
<Button
Padding="10"
Content="Solid"
Width="100"
Command="{Binding GeneratePixelDimming}"
CommandParameter="Solid"
/>
</StackPanel>
</StackPanel>
</Border>
<Border
BorderBrush="LightGray"
BorderThickness="1"
Padding="5"
>
<StackPanel Spacing="10">
<TextBlock FontWeight="Bold" Text="Infill generator"/>
<TextBlock Text="Warning: This function can generate a large number of resin traps. (Use with caution)"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock
VerticalAlignment="Center"
Text="Thickness:"/>
<NumericUpDown
Minimum="5"
Maximum="10000"
Width="80"
Value="{Binding InfillGenThickness}"
/>
<TextBlock
VerticalAlignment="Center"
Text="px"/>
<TextBlock
Margin="20,0,0,0"
VerticalAlignment="Center"
Text="Spacing:"/>
<NumericUpDown
Minimum="5"
Maximum="10000"
Width="80"
Value="{Binding InfillGenSpacing}"
/>
<TextBlock
VerticalAlignment="Center"
Text="px"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button
Padding="10"
Content="Rectilinear"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Rectilinear"
/>
<Button
Padding="10"
Content="Square grid"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Square grid"
/>
<Button
Padding="10"
Content="Waves"
Width="100"
Command="{Binding GenerateInfill}"
CommandParameter="Waves"
/>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</UserControl>
+16 -3
View File
@@ -151,10 +151,23 @@ namespace UVtools.WPF.Extensions
break;
case 4:
var srcPixels4 = (uint*) (void*) mat.DataPointer;
for (uint i = 0; i < dataCount; i++)
if (mat.Depth == DepthType.Cv8U)
{
targetPixels[i] = srcPixels4[i];
var srcPixels4 = (byte*)(void*)mat.DataPointer;
uint pixel4 = 0;
for (uint i = 0; i < dataCount; i++)
{
targetPixels[i] = (uint)(srcPixels4[pixel4++] | srcPixels4[pixel4++] << 8 | srcPixels4[pixel4++] << 16 | srcPixels4[pixel4++] << 24);
}
}
else if (mat.Depth == DepthType.Cv32S)
{
var srcPixels4 = (uint*) (void*) mat.DataPointer;
for (uint i = 0; i < dataCount; i++)
{
targetPixels[i] = srcPixels4[i];
}
}
break;
@@ -21,10 +21,5 @@ namespace UVtools.WPF.Extensions
{
return new Point(point.X, point.Y);
}
public static bool IsEmpty(this Point point)
{
return point.X == 0 && point.Y == 0;
}
}
}
+1 -1
View File
@@ -32,7 +32,7 @@ namespace UVtools.WPF.Extensions
WindowStartupLocation = location,
CanResize = false
});
return await messageBoxStandardWindow.ShowDialog(window);
}
+7 -12
View File
@@ -24,7 +24,7 @@ namespace UVtools.WPF
private Array _layerHierarchyJagged;
private VectorOfVectorOfPoint _layerContours;
private Mat _layerHierarchy;
private SKCanvas _canvas;
//private SKCanvas _canvas;
private WriteableBitmap _bitmap;
public bool IsCached => !ReferenceEquals(_layer, null);
@@ -59,8 +59,8 @@ namespace UVtools.WPF
set
{
_bitmap = value;
_canvas?.Dispose();
_canvas = null;
//_canvas?.Dispose();
//_canvas = null;
}
}
@@ -68,17 +68,12 @@ namespace UVtools.WPF
{
get
{
if (_canvas is null)
using (var framebuffer = Bitmap.Lock())
{
using (var framebuffer = Bitmap.Lock())
{
var info = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height,
framebuffer.Format.ToSkColorType(), SKAlphaType.Premul);
return SKSurface.Create(info, framebuffer.Address, framebuffer.RowBytes).Canvas;
}
var info = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height,
framebuffer.Format.ToSkColorType(), SKAlphaType.Premul);
return SKSurface.Create(info, framebuffer.Address, framebuffer.RowBytes).Canvas;
}
return _canvas;
}
}
+15 -12
View File
@@ -215,14 +215,14 @@ namespace UVtools.WPF
if (Settings.PixelEditor.PartialUpdateIslandsOnEditing)
{
UpdateIslandsOverhangs(whiteListLayers);
await UpdateIslandsOverhangs(whiteListLayers);
}
ShowLayer(); // It will call latter so its a extra call
CanSave = true;
}
private async void UpdateIslandsOverhangs(List<uint> whiteListLayers)
private async Task UpdateIslandsOverhangs(List<uint> whiteListLayers)
{
if (whiteListLayers.Count == 0) return;
var islandConfig = GetIslandDetectionConfiguration();
@@ -238,16 +238,15 @@ namespace UVtools.WPF
IsGUIEnabled = false;
List<LayerIssue> toRemove = new List<LayerIssue>();
var issueList = Issues.ToList();
foreach (var layerIndex in islandConfig.WhiteListLayers)
{
foreach (var issue in Issues)
{
if (issue.LayerIndex != layerIndex && (issue.Type == LayerIssue.IssueType.Island || issue.Type == LayerIssue.IssueType.Overhang)) continue;
toRemove.Add(issue);
issueList.Remove(issue);
}
}
Issues.RemoveMany(toRemove);
var resultIssues = await Task.Factory.StartNew(() =>
{
@@ -278,11 +277,14 @@ namespace UVtools.WPF
IsGUIEnabled = true;
if (resultIssues is null || resultIssues.Count == 0) return;
Issues.AddRange(resultIssues);
Issues = new ObservableCollection<LayerIssue>(Issues.OrderBy(issue => issue.Type)
issueList.AddRange(resultIssues);
issueList = issueList.OrderBy(issue => issue.Type)
.ThenBy(issue => issue.LayerIndex)
.ThenBy(issue => issue.PixelsCount).ToList());
.ThenBy(issue => issue.PixelsCount).ToList();
Issues.Clear();
Issues.AddRange(issueList);
}
public int IssueSelectedIndex
@@ -429,9 +431,7 @@ namespace UVtools.WPF
});
IsGUIEnabled = true;
if (resultIssues is null)
{
UpdateLayerTrackerHighlightIssues();
@@ -440,6 +440,8 @@ namespace UVtools.WPF
Issues.AddRange(resultIssues);
UpdateLayerTrackerHighlightIssues();
ShowLayer();
RaisePropertyChanged(nameof(IssueSelectedIndexStr));
RaisePropertyChanged(nameof(IssueCanGoPrevious));
RaisePropertyChanged(nameof(IssueCanGoNext));
@@ -494,6 +496,7 @@ namespace UVtools.WPF
BinaryThreshold = Settings.Issues.IslandBinaryThreshold,
RequiredAreaToProcessCheck = Settings.Issues.IslandRequiredAreaToProcessCheck,
RequiredPixelBrightnessToProcessCheck = Settings.Issues.IslandRequiredPixelBrightnessToProcessCheck,
RequiredPixelsToSupportMultiplier = Settings.Issues.IslandRequiredPixelsToSupportMultiplier,
RequiredPixelsToSupport = Settings.Issues.IslandRequiredPixelsToSupport,
RequiredPixelBrightnessToSupport = Settings.Issues.IslandRequiredPixelBrightnessToSupport
};
+131 -39
View File
@@ -33,6 +33,7 @@ using UVtools.WPF.Structures;
using Color = UVtools.WPF.Structures.Color;
using Helpers = UVtools.WPF.Controls.Helpers;
using Point = System.Drawing.Point;
using Size = Avalonia.Size;
namespace UVtools.WPF
{
@@ -162,17 +163,15 @@ namespace UVtools.WPF
get => _showLayerImageRotated;
set
{
if (RaiseAndSetIfChanged(ref _showLayerImageRotated, value))
if (!RaiseAndSetIfChanged(ref _showLayerImageRotated, value)) return;
var rect = LayerImageBox.SelectionRegion;
if (!rect.IsEmpty)
{
var rect = LayerImageBox.SelectionRegion;
if (!rect.IsEmpty)
{
LayerImageBox.SelectionRegion = GetTransposedRectangle(rect.ToDotNet(), _showLayerImageRotated, true).ToAvalonia();
}
ZoomToFit();
ShowLayer();
LayerImageBox.SelectionRegion = GetTransposedRectangle(rect.ToDotNet(), _showLayerImageRotated, true).ToAvalonia();
}
ZoomToFit();
ShowLayer();
}
}
@@ -181,10 +180,8 @@ namespace UVtools.WPF
get => _showLayerImageDifference;
set
{
if (RaiseAndSetIfChanged(ref _showLayerImageDifference, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerImageDifference, value)) return;
ShowLayer();
}
}
@@ -205,10 +202,8 @@ namespace UVtools.WPF
get => _showLayerImageCrosshairs;
set
{
if (RaiseAndSetIfChanged(ref _showLayerImageCrosshairs, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerImageCrosshairs, value)) return;
ShowLayer();
}
}
@@ -217,10 +212,8 @@ namespace UVtools.WPF
get => _showLayerOutlinePrintVolumeBoundary;
set
{
if (RaiseAndSetIfChanged(ref _showLayerOutlinePrintVolumeBoundary, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerOutlinePrintVolumeBoundary, value)) return;
ShowLayer();
}
}
@@ -229,10 +222,8 @@ namespace UVtools.WPF
get => _showLayerOutlineLayerBoundary;
set
{
if (RaiseAndSetIfChanged(ref _showLayerOutlineLayerBoundary, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerOutlineLayerBoundary, value)) return;
ShowLayer();
}
}
@@ -241,10 +232,8 @@ namespace UVtools.WPF
get => _showLayerOutlineHollowAreas;
set
{
if (RaiseAndSetIfChanged(ref _showLayerOutlineHollowAreas, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerOutlineHollowAreas, value)) return;
ShowLayer();
}
}
@@ -253,10 +242,8 @@ namespace UVtools.WPF
get => _showLayerOutlineEdgeDetection;
set
{
if (RaiseAndSetIfChanged(ref _showLayerOutlineEdgeDetection, value))
{
ShowLayer();
}
if (!RaiseAndSetIfChanged(ref _showLayerOutlineEdgeDetection, value)) return;
ShowLayer();
}
}
@@ -268,7 +255,7 @@ namespace UVtools.WPF
if (!RaiseAndSetIfChanged(ref _isPixelEditorActive, value)) return;
if (_isPixelEditorActive)
{
TabSelectedIndex = 3;
SelectedTabItem = TabPixelEditor;
}
else
{
@@ -857,9 +844,9 @@ namespace UVtools.WPF
lineThickness);
}
public Point GetTransposedPoint(Point point, bool clockWise = true)
public Point GetTransposedPoint(Point point, bool clockWise = true, bool ignoreLayerRotation = false)
{
if (!_showLayerImageRotated) return point;
if (!_showLayerImageRotated && !ignoreLayerRotation) return point;
return clockWise
? new Point(point.Y, LayerCache.Image.Height - 1 - point.X)
: new Point(LayerCache.Image.Height - 1 - point.Y, point.X);
@@ -946,7 +933,7 @@ namespace UVtools.WPF
/// </summary>
/// <param name="point">Point holding X and Y coordinates</param>
/// <param name="zoomLevel">Zoom level to set, 0 to ignore or negative value to get current locked zoom level</param>
public void CenterLayerAt(System.Drawing.Point point, int zoomLevel = 0) => CenterLayerAt(point.X, point.Y, zoomLevel);
public void CenterLayerAt(Point point, int zoomLevel = 0) => CenterLayerAt(point.X, point.Y, zoomLevel);
/// <summary>
@@ -1060,7 +1047,7 @@ namespace UVtools.WPF
/// If there is an issue under the point location passed, that issue will be selected and
/// scrolled into view on the IssueList.
/// </summary>
private void SelectIssueAtPoint(System.Drawing.Point location)
private void SelectIssueAtPoint(Point location)
{
//location = GetTransposedPoint(location);
// If location clicked is within an issue, activate it.
@@ -1072,6 +1059,7 @@ namespace UVtools.WPF
if (!GetTransposedIssueBounds(issue).Contains(location)) continue;
IssueSelectedIndex = i;
SelectedTabItem = TabIssues;
break;
}
}
@@ -1276,7 +1264,7 @@ namespace UVtools.WPF
public void OnLayerPixelPickerClicked()
{
if (!LayerPixelPicker.IsSet) return;
LayerImageBox.CenterAt(LayerPixelPicker.Location);
CenterLayerAt(GetTransposedPoint(LayerPixelPicker.Location, false), -1);
}
public async void SaveCurrentLayerImage()
@@ -1293,5 +1281,109 @@ namespace UVtools.WPF
LayerCache.ImageBgr.Save(result);
}
const byte _pixelEditorCursorMinDiamater = 10;
public void UpdatePixelEditorCursor()
{
Mat cursor = null;
MCvScalar _pixelEditorCursorColor = new MCvScalar(
Settings.PixelEditor.CursorColor.B,
Settings.PixelEditor.CursorColor.G,
Settings.PixelEditor.CursorColor.R,
Settings.PixelEditor.CursorColor.A);
switch ((PixelOperation.PixelOperationType)SelectedPixelOperationTabIndex)
{
case PixelOperation.PixelOperationType.Drawing:
if (DrawingPixelDrawing.BrushSize > 1)
{
cursor = EmguExtensions.InitMat(new System.Drawing.Size(DrawingPixelDrawing.BrushSize, DrawingPixelDrawing.BrushSize), DepthType.Cv8U, 4);
switch (DrawingPixelDrawing.BrushShape)
{
case PixelDrawing.BrushShapeType.Rectangle:
CvInvoke.Rectangle(cursor,
new Rectangle(Point.Empty, new System.Drawing.Size(DrawingPixelDrawing.BrushSize, DrawingPixelDrawing.BrushSize)),
_pixelEditorCursorColor, DrawingPixelDrawing.Thickness, DrawingPixelDrawing.LineType);
_pixelEditorCursorColor.V3 = 255;
CvInvoke.Rectangle(cursor,
new Rectangle(Point.Empty, new System.Drawing.Size(DrawingPixelDrawing.BrushSize-1, DrawingPixelDrawing.BrushSize-1)),
_pixelEditorCursorColor, 1, DrawingPixelDrawing.LineType);
break;
case PixelDrawing.BrushShapeType.Circle:
var center = new Point(DrawingPixelDrawing.BrushSize / 2, DrawingPixelDrawing.BrushSize / 2);
CvInvoke.Circle(cursor,
center,
center.X,
_pixelEditorCursorColor,
DrawingPixelDrawing.Thickness, DrawingPixelDrawing.LineType
);
_pixelEditorCursorColor.V3 = 255;
CvInvoke.Circle(cursor,
center,
center.X,
_pixelEditorCursorColor,
1, DrawingPixelDrawing.LineType
);
break;
}
}
break;
case PixelOperation.PixelOperationType.Text:
break;
var text = DrawingPixelText.Text;
if (string.IsNullOrEmpty(text) || DrawingPixelText.FontScale < 0.2) return;
int baseLine = 0;
var size = CvInvoke.GetTextSize(text, DrawingPixelText.Font, DrawingPixelText.FontScale, DrawingPixelText.Thickness, ref baseLine);
cursor = EmguExtensions.InitMat(size, DepthType.Cv8U, 4);
CvInvoke.PutText(cursor, text, new Point(0, 0), DrawingPixelText.Font, DrawingPixelText.FontScale, _pixelEditorCursorColor, DrawingPixelText.Thickness, DrawingPixelText.LineType, DrawingPixelText.Mirror);
break;
case PixelOperation.PixelOperationType.Supports:
case PixelOperation.PixelOperationType.DrainHole:
var diameter = SelectedPixelOperationTabIndex == (byte)PixelOperation.PixelOperationType.Supports ?
DrawingPixelSupport.TipDiameter : DrawingPixelDrainHole.Diameter;
if (diameter >= _pixelEditorCursorMinDiamater)
{
cursor = EmguExtensions.InitMat(new System.Drawing.Size(diameter, diameter), DepthType.Cv8U, 4);
var center = new Point(diameter / 2, diameter / 2);
CvInvoke.Circle(cursor,
center,
center.X,
_pixelEditorCursorColor,
-1, LineType.AntiAlias
);
_pixelEditorCursorColor.V3 = 255;
CvInvoke.Circle(cursor,
center,
center.X,
_pixelEditorCursorColor,
1, LineType.AntiAlias
);
}
break;
}
if (!(cursor is null))
{
LayerImageBox.TrackerImage = cursor.ToBitmap();
//cursor.Save("D:\\Cursor.png");
//LayerImageBox.TrackerImage.Save("D:\\CursorAVA.png");
}
/*else if (tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.Text)
{
var text = tbPixelEditorTextText.Text;
if (string.IsNullOrEmpty(text) || nmPixelEditorTextFontScale.Value < 0.2m) return;
LineType lineType = (LineType)cbPixelEditorTextLineType.SelectedItem;
FontFace fontFace = (FontFace)cbPixelEditorTextFontFace.SelectedItem;
double scale = (double) nmPixelEditorTextFontScale.Value * pbLayer.Zoom / 100;
int thickness = (int) nmPixelEditorTextThickness.Value;
int baseLine = 0;
var size = CvInvoke.GetTextSize(text, fontFace, scale, thickness, ref baseLine);
mat = new Mat(size, DepthType.Cv8U, 4);
CvInvoke.PutText(mat, text, new Point(0,0), fontFace, scale, new MCvScalar(255,100,255, 255), thickness, lineType, cbPixelEditorTextMirror.Checked);
}*/
}
}
}
+10 -7
View File
@@ -314,7 +314,7 @@ namespace UVtools.WPF
}
else if (SelectedPixelOperationTabIndex == (byte)PixelOperation.PixelOperationType.Supports)
{
if (ActualLayer == 0) return;
if (_actualLayer == 0) return;
var operationSupport = new PixelSupport(ActualLayer, realLocation,
DrawingPixelSupport.TipDiameter, DrawingPixelSupport.PillarDiameter,
DrawingPixelSupport.BaseDiameter);
@@ -328,13 +328,13 @@ namespace UVtools.WPF
}
else if (SelectedPixelOperationTabIndex == (byte)PixelOperation.PixelOperationType.DrainHole)
{
if (ActualLayer == 0) return;
if (_actualLayer == 0) return;
var operationDrainHole = new PixelDrainHole(ActualLayer, realLocation, DrawingPixelDrainHole.Diameter);
//if (PixelHistory.Contains(operation)) return;
Drawings.Add(operationDrainHole);
CvInvoke.Circle(LayerCache.ImageBgr, operationDrainHole.Location, operationDrainHole.Diameter / 2,
CvInvoke.Circle(LayerCache.ImageBgr, location, operationDrainHole.Diameter / 2,
new MCvScalar(Settings.PixelEditor.DrainHoleColor.B, Settings.PixelEditor.DrainHoleColor.G, Settings.PixelEditor.DrainHoleColor.R), -1);
RefreshLayerImage();
}
@@ -348,9 +348,9 @@ namespace UVtools.WPF
{
if (Drawings.Count == 0)
{
if (exitEditor)
if (exitEditor && !ReferenceEquals(LastSelectedTabItem, TabPixelEditor))
{
TabSelectedIndex = LastTabSelectedIndex;
SelectedTabItem = LastSelectedTabItem;
}
return;
@@ -432,7 +432,7 @@ namespace UVtools.WPF
}
}
//UpdateIslandsOverhangs(whiteListLayers);
await UpdateIslandsOverhangs(whiteListLayers);
}
}
@@ -442,7 +442,10 @@ namespace UVtools.WPF
if (exitEditor || (Settings.PixelEditor.CloseEditorOnApply && result == ButtonResult.Yes))
{
IsPixelEditorActive = false;
TabSelectedIndex = LastTabSelectedIndex;
if (!ReferenceEquals(LastSelectedTabItem, TabPixelEditor))
{
SelectedTabItem = LastSelectedTabItem;
}
}
CanSave = true;
+12 -2
View File
@@ -246,8 +246,9 @@
Background="WhiteSmoke"
DockPanel.Dock="Left"
Width="400"
SelectedIndex="{Binding TabSelectedIndex}">
SelectedItem="{Binding SelectedTabItem}">
<TabItem
Name="TabInformation"
ToolTip.Tip="Information"
IsEnabled="{Binding IsFileLoaded}" >
<TabItem.Header>
@@ -415,6 +416,7 @@
</TabItem>
<TabItem
Name="TabGCode"
ToolTip.Tip="GCode"
IsEnabled="{Binding HaveGCode}">
<TabItem.Header>
@@ -499,6 +501,7 @@
Issues Tab
-->
<TabItem
Name="TabIssues"
ToolTip.Tip="Issues"
IsEnabled="{Binding IsFileLoaded}" >
<TabItem.Header>
@@ -517,6 +520,8 @@
Spacing="5"
VerticalAlignment="Center">
<RepeatButton
HotKey="Ctrl + Shift + Down"
ToolTip.Tip="Go to the previous issue [Ctrl + Shift + Down]"
IsEnabled="{Binding IssueCanGoPrevious}"
Command="{Binding IssueGoPrevious}"
Interval="100"
@@ -534,6 +539,8 @@
</TextBlock>
<RepeatButton
HotKey="Ctrl + Shift + Up"
ToolTip.Tip="Go to the next issue [Ctrl + Shift + Up]"
IsEnabled="{Binding IssueCanGoNext}"
Command="{Binding IssueGoNext}"
Interval="100"
@@ -644,6 +651,7 @@
<!-- Pixel Editor !-->
<TabItem
Name="TabPixelEditor"
ToolTip.Tip="Pixel editor"
IsEnabled="{Binding IsPixelEditorActive}">
<TabItem.Header>
@@ -1179,7 +1187,9 @@
</TabItem>
<TabItem ToolTip.Tip="Log">
<TabItem
Name="TabLog"
ToolTip.Tip="Log">
<TabItem.Header>
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
<Image Source="/Assets/Icons/book-32x32.png" Width="32"/>
+29 -22
View File
@@ -11,16 +11,12 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Threading;
using Emgu.CV;
using Emgu.CV.CvEnum;
@@ -238,13 +234,13 @@ namespace UVtools.WPF
private uint _savesCount;
private bool _canSave;
private MenuItem[] _menuFileConvertItems;
private int _tabSelectedIndex;
private int _lastTabSelectedIndex;
private PointerEventArgs _globalPointerEventArgs;
private PointerPoint _globalPointerPoint;
private KeyModifiers _globalModifiers;
private TabItem _selectedTabItem;
private TabItem _lastSelectedTab;
private TabItem _lastSelectedTabItem;
#endregion
@@ -287,19 +283,24 @@ namespace UVtools.WPF
set => RaisePropertyChanged();
}
public int TabSelectedIndex
public TabItem TabInformation { get; }
public TabItem TabGCode { get; }
public TabItem TabIssues { get; }
public TabItem TabPixelEditor { get; }
public TabItem TabLog { get; }
public TabItem SelectedTabItem
{
get => _tabSelectedIndex;
get => _selectedTabItem;
set
{
var lastTab = _tabSelectedIndex;
if (!RaiseAndSetIfChanged(ref _tabSelectedIndex, value)) return;
LastTabSelectedIndex = lastTab;
var lastTab = _selectedTabItem;
if (!RaiseAndSetIfChanged(ref _selectedTabItem, value)) return;
LastSelectedTabItem = lastTab;
if (_firstTimeOnIssues)
{
_firstTimeOnIssues = false;
if (_tabSelectedIndex == 2 && Settings.Issues.ComputeIssuesOnClickTab)
if (ReferenceEquals(_selectedTabItem, TabIssues) && Settings.Issues.ComputeIssuesOnClickTab)
{
OnClickDetectIssues();
}
@@ -307,10 +308,10 @@ namespace UVtools.WPF
}
}
public int LastTabSelectedIndex
public TabItem LastSelectedTabItem
{
get => _lastTabSelectedIndex;
set => RaiseAndSetIfChanged(ref _lastTabSelectedIndex, value);
get => _lastSelectedTabItem;
set => RaiseAndSetIfChanged(ref _lastSelectedTabItem, value);
}
#endregion
@@ -348,8 +349,12 @@ namespace UVtools.WPF
InitPixelEditor();
InitLayerPreview();
//IssuesGrid.SelectionChanged += IssuesGridOnSelectionChanged;
TabInformation = this.FindControl<TabItem>("TabInformation");
TabGCode = this.FindControl<TabItem>("TabGCode");
TabIssues = this.FindControl<TabItem>("TabIssues");
TabPixelEditor = this.FindControl<TabItem>("TabPixelEditor");
TabLog = this.FindControl<TabItem>("TabLog");
foreach (var menuItem in new[] { MenuTools, LayerActionsMenu })
@@ -459,6 +464,7 @@ namespace UVtools.WPF
if (e.Handled
|| !IsFileLoaded
|| LayerImageBox.IsPanning
|| !(LayerImageBox.TrackerImage is null)
|| LayerImageBox.Cursor == StaticControls.CrossCursor
|| LayerImageBox.Cursor == StaticControls.HandCursor
|| LayerImageBox.SelectionMode == AdvancedImageBox.SelectionModes.Rectangle
@@ -478,7 +484,7 @@ namespace UVtools.WPF
"» Click over a pixel to draw\n" +
"» Hold CTRL to clear pixels";
//UpdatePixelEditorCursor();
UpdatePixelEditorCursor();
}
else
{
@@ -518,6 +524,7 @@ namespace UVtools.WPF
(e.KeyModifiers & KeyModifiers.Shift) == 0 ||
(e.KeyModifiers & KeyModifiers.Control) == 0)
{
LayerImageBox.TrackerImage = null;
LayerImageBox.Cursor = StaticControls.ArrowCursor;
LayerImageBox.AutoPan = true;
LayerImageBox.SelectionMode = AdvancedImageBox.SelectionModes.None;
@@ -604,7 +611,7 @@ namespace UVtools.WPF
_issuesSliderCanvas.Children.Clear();
Drawings.Clear();
TabSelectedIndex = 0;
SelectedTabItem = TabInformation;
_firstTimeOnIssues = true;
IsPixelEditorActive = false;
CanSave = false;
@@ -678,7 +685,7 @@ namespace UVtools.WPF
Title = (SlicerFile is null
? $"{About.Software} Version: {AppSettings.Version}"
: $"{About.Software} File: {Path.GetFileName(SlicerFile.FileFullPath)} ({Math.Round(LastStopWatch.ElapsedMilliseconds / 1000m, 2)}s) Version: {AppSettings.Version}")
+ " [PREVIEW ALPHA RELEASE]";
;
#if DEBUG
Title += " [DEBUG]";
+1 -1
View File
@@ -18,7 +18,7 @@ namespace UVtools.WPF.Structures
public Point Location
{
get => _location;
private set => this.RaiseAndSetIfChanged(ref _location, value);
set => this.RaiseAndSetIfChanged(ref _location, value);
}
public byte Brightness
+3 -4
View File
@@ -24,12 +24,11 @@
<NoWarn>1701;1702;</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.999-cibuild0011389-beta" />
<PackageReference Include="Avalonia" Version="0.10.999-cibuild0011401-beta" />
<PackageReference Include="Avalonia.Angle.Windows.Natives" Version="2.1.0.2020091801" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.999-cibuild0011389-beta" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.999-cibuild0011389-beta" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.999-cibuild0011401-beta" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.999-cibuild0011401-beta" />
<PackageReference Include="Avalonia.ThemeManager" Version="0.10.0-preview3" />
<PackageReference Include="Dock.Avalonia" Version="0.10.0-preview5" />
<PackageReference Include="Emgu.CV.runtime.raspbian" Version="4.4.0.4099" />
<PackageReference Include="Emgu.CV.runtime.ubuntu" Version="4.4.0.4099" />
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.4.0.4099" />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 109 KiB

+26 -1
View File
@@ -554,6 +554,7 @@ namespace UVtools.WPF
private byte _islandRequiredAreaToProcessCheck = 1;
private byte _islandRequiredPixelBrightnessToProcessCheck = 1;
private byte _islandRequiredPixelsToSupport = 10;
private decimal _islandRequiredPixelsToSupportMultiplier = 0.25m;
private byte _islandRequiredPixelBrightnessToSupport = 150;
private bool _overhangIndependentFromIslands = true;
private byte _overhangErodeIterations = 49;
@@ -622,6 +623,12 @@ namespace UVtools.WPF
set => this.RaiseAndSetIfChanged(ref _islandRequiredAreaToProcessCheck, value);
}
public decimal IslandRequiredPixelsToSupportMultiplier
{
get => _islandRequiredPixelsToSupportMultiplier;
set => this.RaiseAndSetIfChanged(ref _islandRequiredPixelsToSupportMultiplier, value);
}
public byte IslandRequiredPixelsToSupport
{
get => _islandRequiredPixelsToSupport;
@@ -696,6 +703,7 @@ namespace UVtools.WPF
private Color _supportsHighlightColor = new Color(255, 0, 139, 139);
private Color _drainHoleColor = new Color(255, 142, 69, 133);
private Color _drainHoleHighlightColor = new Color(255, 159, 0, 197);
private Color _cursorColor = new Color(150, 52, 152, 219);
private bool _partialUpdateIslandsOnEditing = true;
private bool _closeEditorOnApply;
@@ -835,6 +843,23 @@ namespace UVtools.WPF
set => DrainHoleHighlightColor = new Color(value);
}
public Color CursorColor
{
get => _cursorColor;
set
{
this.RaiseAndSetIfChanged(ref _cursorColor, value);
this.RaisePropertyChanged(nameof(CursorBrush));
}
}
[XmlIgnore]
public SolidColorBrush CursorBrush
{
get => new SolidColorBrush(_cursorColor.ToAvalonia());
set => CursorColor = new Color(value);
}
public bool PartialUpdateIslandsOnEditing
{
get => _partialUpdateIslandsOnEditing;
@@ -861,7 +886,7 @@ namespace UVtools.WPF
private bool _repairIslands = true;
private bool _repairResinTraps = true;
private bool _removeEmptyLayers = true;
private byte _removeIslandsBelowEqualPixels = 10;
private byte _removeIslandsBelowEqualPixels = 5;
private ushort _removeIslandsRecursiveIterations = 4;
private byte _closingIterations = 2;
private byte _openingIterations = 0;
File diff suppressed because it is too large Load Diff
@@ -16,12 +16,19 @@ namespace UVtools.WPF.Windows
{
public class SettingsWindow : WindowEx
{
private double _scrollViewerMaxHeight;
public UserSettings SettingsBackup { get; }
public UserSettings Settings => UserSettings.Instance;
public string[] FileOpenDialogFilters { get; }
public string[] ZoomRanges { get; }
public double ScrollViewerMaxHeight
{
get => _scrollViewerMaxHeight;
set => RaiseAndSetIfChanged(ref _scrollViewerMaxHeight, value);
}
public SettingsWindow()
{
Title += $" [v{AppSettings.Version}]";
@@ -40,6 +47,10 @@ namespace UVtools.WPF.Windows
ZoomRanges = AppSettings.ZoomLevels.Skip(AppSettings.ZoomLevelSkipCount).Select(
s => Convert.ToString(s / 100, CultureInfo.InvariantCulture) + "x").ToArray();
//MaxHeight = Screens.Primary.WorkingArea.Height - 50;
ScrollViewerMaxHeight = Screens.Primary.WorkingArea.Height - 700;
DataContext = this;
InitializeComponent();
}
+2
View File
@@ -199,6 +199,8 @@
FontWeight="Bold"
Text="{Binding Title}"/>
<!--<ScrollViewer Padding="15"
Content="{Binding ContentControl}"/>!-->
<Border Margin="15" Child="{Binding ContentControl}"/>
</StackPanel>