mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-08 17:42:31 +02:00
WPF progress
This commit is contained in:
@@ -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"
|
||||
@@ -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 |
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 |
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace UVtools.WPF.Extensions
|
||||
WindowStartupLocation = location,
|
||||
CanResize = false
|
||||
});
|
||||
|
||||
|
||||
return await messageBoxStandardWindow.ShowDialog(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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]";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
@@ -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();
|
||||
}
|
||||
|
||||
@@ -199,6 +199,8 @@
|
||||
FontWeight="Bold"
|
||||
Text="{Binding Title}"/>
|
||||
|
||||
<!--<ScrollViewer Padding="15"
|
||||
Content="{Binding ContentControl}"/>!-->
|
||||
<Border Margin="15" Child="{Binding ContentControl}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user