mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-12 03:22:32 +02:00
v3.1.1
- (Add) Raft relief: Tabs type - Creates tabs around the raft to easily insert a tool under it and detach the raft from build plate - (Add) Linux AppImage binaries (You won't get them with auto-update, please download AppImage once before can use auto-update feature in the future) - (Change) Rename "layer compression method" to "layer compression codec", please redefine the codec setting if you changed before - (Improvement) Linux and macOS releases are now compiled, published and packed under Linux (WSL). Windows release still and must be published under windows.
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
name: Submit UVtools package to Windows Package Manager Community Repository
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
|
||||
winget:
|
||||
name: Publish winget package
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Submit package to Windows Package Manager Community Repository
|
||||
run: |
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json
|
||||
$installerUrl = $github.release.assets | Where-Object -Property name -match '.+win-x64.+\.msi' | Select -ExpandProperty browser_download_url -First 1
|
||||
if($null -eq $installerUrl){ exit 1 }
|
||||
$version = $github.release.tag_name.Replace('v', '')
|
||||
if($version.Length -lt 5){ exit 2 }
|
||||
.\wingetcreate.exe update PTRTECH.UVtools --version $version --urls $installerUrl --token ${{ secrets.WINGET_TOKEN }} --submit
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Winget and Nuget package publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
|
||||
winget:
|
||||
name: Winget - Pull request
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Submit package to Windows Package Manager Community Repository
|
||||
run: |
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
$installerUrl = $github.event.release.assets | Where-Object -Property name -match '.+win-x64.+\.msi' | Select -ExpandProperty browser_download_url -First 1
|
||||
if($null -eq $installerUrl){ exit 1 }
|
||||
$version = $github.event.release.tag_name.Replace('v', '')
|
||||
if($version.Length -lt 5){ exit 2 }
|
||||
.\wingetcreate.exe update PTRTECH.UVtools --version $version --urls $installerUrl --token ${WINGET_TOKEN} --submit
|
||||
env:
|
||||
WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }}
|
||||
|
||||
nuget:
|
||||
name: Nuget - Publish package
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Verify commit exists in origin/main
|
||||
run: |
|
||||
git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/*
|
||||
git branch --remote --contains | grep origin/main
|
||||
- name: Set VERSION variable from tag
|
||||
run: |
|
||||
echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
||||
echo "VERSION=${VERSION:1}" >> $GITHUB_ENV
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release
|
||||
- name: Pack
|
||||
run: dotnet pack UVtools.Core --configuration Release --no-build --output .
|
||||
- name: Push nuget.org
|
||||
run: dotnet nuget push UVtools.Core.${VERSION}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${NUGET_TOKEN}
|
||||
env:
|
||||
NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
||||
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 21/03/2022 - v3.1.1
|
||||
|
||||
- (Add) Raft relief: Tabs type - Creates tabs around the raft to easily insert a tool under it and detach the raft from build plate
|
||||
- (Add) Linux AppImage binaries (You won't get them with auto-update, please download AppImage once before can use auto-update feature in the future)
|
||||
- (Change) Rename "layer compression method" to "layer compression codec", please redefine the codec setting if you changed before
|
||||
- (Improvement) Linux and macOS releases are now compiled, published and packed under Linux (WSL). Windows release still and must be published under windows.
|
||||
|
||||
## 17/03/2022 - v3.1.0
|
||||
|
||||
- **Benchmark:**
|
||||
|
||||
@@ -71,7 +71,7 @@ public static class CoreSettings
|
||||
/// <summary>
|
||||
/// Gets or sets the default compression type for layers
|
||||
/// </summary>
|
||||
public static Layer.LayerCompressionMethod DefaultLayerCompressionMethod { get; set; } = Layer.LayerCompressionMethod.Png;
|
||||
public static Layer.LayerCompressionCodec DefaultLayerCompressionCodec { get; set; } = Layer.LayerCompressionCodec.Png;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default folder to save the settings
|
||||
|
||||
@@ -103,7 +103,7 @@ public static class ZipArchiveExtensions
|
||||
{
|
||||
//Gets the complete path for the destination file, including any
|
||||
//relative paths that were in the zip file
|
||||
var destFileName = Path.Combine(destinationPath, file.FullName);
|
||||
var destFileName = Path.GetFullPath(Path.Combine(destinationPath, file.FullName));
|
||||
var fullDestDirPath = Path.GetFullPath(destinationPath + Path.DirectorySeparatorChar);
|
||||
if (!destFileName.StartsWith(fullDestDirPath)) return; // Entry is outside the target dir
|
||||
|
||||
|
||||
@@ -4490,16 +4490,16 @@ public abstract class FileFormat : BindableBase, IDisposable, IEquatable<FileFor
|
||||
/// <summary>
|
||||
/// Changes the compression method of all layers to a new method
|
||||
/// </summary>
|
||||
/// <param name="to">The new method to change to</param>
|
||||
/// <param name="newCodec">The new method to change to</param>
|
||||
/// <param name="progress"></param>
|
||||
public void ChangeLayersCompressionMethod(Layer.LayerCompressionMethod to, OperationProgress? progress = null)
|
||||
public void ChangeLayersCompressionMethod(Layer.LayerCompressionCodec newCodec, OperationProgress? progress = null)
|
||||
{
|
||||
progress ??= new OperationProgress($"Changing layers compress method to {to}");
|
||||
progress ??= new OperationProgress($"Changing layers compression codec to {newCodec}");
|
||||
progress.Reset("Layers", LayerCount);
|
||||
|
||||
Parallel.ForEach(this, CoreSettings.GetParallelOptions(progress), layer =>
|
||||
{
|
||||
layer.CompressionMethod = to;
|
||||
layer.CompressionCodec = newCodec;
|
||||
progress.LockAndIncrement();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
{
|
||||
#region Enums
|
||||
|
||||
public enum LayerCompressionMethod : byte
|
||||
public enum LayerCompressionCodec : byte
|
||||
{
|
||||
[Description("PNG: Compression=High Speed=Slow (Use with low RAM)")]
|
||||
Png,
|
||||
@@ -56,7 +56,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
#region Members
|
||||
|
||||
public object Mutex = new();
|
||||
private LayerCompressionMethod _compressionMethod;
|
||||
private LayerCompressionCodec _compressionCodec;
|
||||
private byte[]? _compressedBytes;
|
||||
private uint _nonZeroPixelCount;
|
||||
private Rectangle _boundingRectangle = Rectangle.Empty;
|
||||
@@ -593,21 +593,21 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
/// <summary>
|
||||
/// Gets or sets the compression method used to cache the image
|
||||
/// </summary>
|
||||
public LayerCompressionMethod CompressionMethod
|
||||
public LayerCompressionCodec CompressionCodec
|
||||
{
|
||||
get => _compressionMethod;
|
||||
get => _compressionCodec;
|
||||
set
|
||||
{
|
||||
if (!HaveImage)
|
||||
{
|
||||
RaiseAndSetIfChanged(ref _compressionMethod, value);
|
||||
RaiseAndSetIfChanged(ref _compressionCodec, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle conversion
|
||||
if (_compressionMethod == value) return;
|
||||
if (_compressionCodec == value) return;
|
||||
using var mat = LayerMat;
|
||||
_compressionMethod = value;
|
||||
_compressionCodec = value;
|
||||
_compressedBytes = CompressMat(mat, value);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
@@ -634,7 +634,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
get
|
||||
{
|
||||
if (_compressedBytes is null) return null;
|
||||
if (_compressionMethod == LayerCompressionMethod.Png) return _compressedBytes;
|
||||
if (_compressionCodec == LayerCompressionCodec.Png) return _compressedBytes;
|
||||
|
||||
using var mat = LayerMat;
|
||||
return mat.GetPngByes();
|
||||
@@ -656,17 +656,17 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
if (!HaveImage) return null!;
|
||||
|
||||
Mat mat;
|
||||
switch (_compressionMethod)
|
||||
switch (_compressionCodec)
|
||||
{
|
||||
case LayerCompressionMethod.Png:
|
||||
case LayerCompressionCodec.Png:
|
||||
mat = new Mat();
|
||||
CvInvoke.Imdecode(_compressedBytes, ImreadModes.Grayscale, mat);
|
||||
break;
|
||||
case LayerCompressionMethod.Lz4:
|
||||
case LayerCompressionCodec.Lz4:
|
||||
mat = new Mat(SlicerFile.Resolution, DepthType.Cv8U, 1);
|
||||
LZ4Codec.Decode(_compressedBytes.AsSpan(), mat.GetDataByteSpan());
|
||||
break;
|
||||
case LayerCompressionMethod.GZip:
|
||||
case LayerCompressionCodec.GZip:
|
||||
{
|
||||
mat = new(SlicerFile.Resolution, DepthType.Cv8U, 1);
|
||||
var matSpan = mat.GetDataByteSpan();
|
||||
@@ -683,7 +683,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
|
||||
break;
|
||||
}
|
||||
case LayerCompressionMethod.Deflate:
|
||||
case LayerCompressionCodec.Deflate:
|
||||
{
|
||||
mat = new(SlicerFile.Resolution, DepthType.Cv8U, 1);
|
||||
var matSpan = mat.GetDataByteSpan();
|
||||
@@ -715,7 +715,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
{
|
||||
if (value is not null)
|
||||
{
|
||||
CompressedBytes = CompressMat(value, _compressionMethod);
|
||||
CompressedBytes = CompressMat(value, _compressionCodec);
|
||||
}
|
||||
|
||||
GetBoundingRectangle(value, true);
|
||||
@@ -815,10 +815,10 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
|
||||
#region Constructor
|
||||
|
||||
public Layer(uint index, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null)
|
||||
public Layer(uint index, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null)
|
||||
{
|
||||
compressionMethod ??= CoreSettings.DefaultLayerCompressionMethod;
|
||||
_compressionMethod = compressionMethod.Value;
|
||||
compressionMethod ??= CoreSettings.DefaultLayerCompressionCodec;
|
||||
_compressionCodec = compressionMethod.Value;
|
||||
|
||||
SlicerFile = slicerFile;
|
||||
_index = index;
|
||||
@@ -828,9 +828,9 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
ResetParameters();
|
||||
}
|
||||
|
||||
public Layer(uint index, byte[] pngBytes, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(index, slicerFile, compressionMethod)
|
||||
public Layer(uint index, byte[] pngBytes, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(index, slicerFile, compressionMethod)
|
||||
{
|
||||
if (_compressionMethod == LayerCompressionMethod.Png)
|
||||
if (_compressionCodec == LayerCompressionCodec.Png)
|
||||
{
|
||||
CompressedBytes = pngBytes;
|
||||
}
|
||||
@@ -844,25 +844,25 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
_isModified = false;
|
||||
}
|
||||
|
||||
public Layer(uint index, Mat layerMat, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(index, slicerFile, compressionMethod)
|
||||
public Layer(uint index, Mat layerMat, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(index, slicerFile, compressionMethod)
|
||||
{
|
||||
LayerMat = layerMat;
|
||||
_isModified = false;
|
||||
}
|
||||
|
||||
public Layer(uint index, Stream stream, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(index, stream.ToArray(), slicerFile, compressionMethod)
|
||||
public Layer(uint index, Stream stream, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(index, stream.ToArray(), slicerFile, compressionMethod)
|
||||
{ }
|
||||
|
||||
public Layer(FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(0, slicerFile, compressionMethod)
|
||||
public Layer(FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(0, slicerFile, compressionMethod)
|
||||
{ }
|
||||
|
||||
public Layer(byte[] pngBytes, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(0, pngBytes, slicerFile, compressionMethod)
|
||||
public Layer(byte[] pngBytes, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(0, pngBytes, slicerFile, compressionMethod)
|
||||
{ }
|
||||
|
||||
public Layer(Mat layerMat, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(0, layerMat, slicerFile, compressionMethod)
|
||||
public Layer(Mat layerMat, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(0, layerMat, slicerFile, compressionMethod)
|
||||
{ }
|
||||
|
||||
public Layer(Stream stream, FileFormat slicerFile, LayerCompressionMethod? compressionMethod = null) : this(0, stream, slicerFile, compressionMethod) { }
|
||||
public Layer(Stream stream, FileFormat slicerFile, LayerCompressionCodec? compressionMethod = null) : this(0, stream, slicerFile, compressionMethod) { }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1504,20 +1504,20 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
return clonedLayers;
|
||||
}
|
||||
|
||||
public static byte[] CompressMat(Mat mat, LayerCompressionMethod method)
|
||||
public static byte[] CompressMat(Mat mat, LayerCompressionCodec codec)
|
||||
{
|
||||
switch (method)
|
||||
switch (codec)
|
||||
{
|
||||
case LayerCompressionMethod.Png:
|
||||
case LayerCompressionCodec.Png:
|
||||
return mat.GetPngByes();
|
||||
case LayerCompressionMethod.Lz4:
|
||||
case LayerCompressionCodec.Lz4:
|
||||
{
|
||||
var span = mat.GetDataByteSpan();
|
||||
var target = new byte[LZ4Codec.MaximumOutputSize(span.Length)];
|
||||
var encodedLength = LZ4Codec.Encode(span, target.AsSpan());
|
||||
return target[..encodedLength];
|
||||
}
|
||||
case LayerCompressionMethod.GZip:
|
||||
case LayerCompressionCodec.GZip:
|
||||
{
|
||||
/*var matSpan = mat.GetDataByteSpan();
|
||||
var compressedBytes = new byte[matSpan.Length];
|
||||
@@ -1537,7 +1537,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
gZipStream.Write(mat.GetDataByteSpan());
|
||||
return compressedStream.ToArray();
|
||||
}
|
||||
case LayerCompressionMethod.Deflate:
|
||||
case LayerCompressionCodec.Deflate:
|
||||
{
|
||||
using var compressedStream = new MemoryStream();
|
||||
using var deflateStream = new DeflateStream(compressedStream, CompressionLevel.Fastest);
|
||||
@@ -1547,7 +1547,7 @@ public class Layer : BindableBase, IEquatable<Layer>, IEquatable<uint>
|
||||
/*case LayerCompressionMethod.None:
|
||||
return mat.GetBytes();*/
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(method));
|
||||
throw new ArgumentOutOfRangeException(nameof(codec));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,12 @@ using Emgu.CV;
|
||||
using Emgu.CV.CvEnum;
|
||||
using Emgu.CV.Structure;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Emgu.CV.Util;
|
||||
using UVtools.Core.EmguCV;
|
||||
using UVtools.Core.Extensions;
|
||||
using UVtools.Core.FileFormats;
|
||||
|
||||
@@ -23,9 +27,17 @@ public class OperationRaftRelief : Operation
|
||||
#region Enums
|
||||
public enum RaftReliefTypes : byte
|
||||
{
|
||||
[Description("Relief: Drill raft to relief pressure and remove some mass")]
|
||||
Relief,
|
||||
|
||||
[Description("Dimming: Darkens the raft to cure it less")]
|
||||
Dimming,
|
||||
Decimate
|
||||
|
||||
[Description("Decimate: Remove the raft and keep supports only on the plate")]
|
||||
Decimate,
|
||||
|
||||
[Description("Tabs: Creates tabs around the raft to easily insert a tool under it and detach the raft from build plate")]
|
||||
Tabs
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -38,6 +50,9 @@ public class OperationRaftRelief : Operation
|
||||
private byte _wallMargin = 40; // +/- 2mm
|
||||
private byte _holeDiameter = 80; // +/- 4mm
|
||||
private byte _holeSpacing = 40; // +/- 2mm
|
||||
private byte _tabBrightness = byte.MaxValue;
|
||||
private ushort _tabTriangleBase = 200;
|
||||
private ushort _tabTriangleHeight = 250;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -57,7 +72,20 @@ public class OperationRaftRelief : Operation
|
||||
|
||||
public override Enumerations.LayerRangeSelection StartLayerRangeSelection =>
|
||||
Enumerations.LayerRangeSelection.None;
|
||||
|
||||
|
||||
public override string? ValidateInternally()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
if (_reliefType == RaftReliefTypes.Tabs)
|
||||
{
|
||||
if(_tabTriangleHeight == 0) sb.AppendLine("The tab height can't be 0");
|
||||
if(_tabTriangleBase == 0) sb.AppendLine("The tab base can't be 0");
|
||||
if(_tabBrightness == 0) sb.AppendLine("The tab brightness can't be 0");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = $"[{_reliefType}] [Mask layer: {_maskLayerIndex}] [Ignore: {_ignoreFirstLayers}] [B: {_brightness}] [Dilate: {_dilateIterations}] [Wall margin: {_wallMargin}] [Hole diameter: {_holeDiameter}] [Hole spacing: {_holeSpacing}]";
|
||||
@@ -75,8 +103,6 @@ public class OperationRaftRelief : Operation
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
public static Array RaftReliefItems => Enum.GetValues(typeof(RaftReliefTypes));
|
||||
|
||||
public RaftReliefTypes ReliefType
|
||||
{
|
||||
get => _reliefType;
|
||||
@@ -86,12 +112,15 @@ public class OperationRaftRelief : Operation
|
||||
RaisePropertyChanged(nameof(IsRelief));
|
||||
RaisePropertyChanged(nameof(IsDimming));
|
||||
RaisePropertyChanged(nameof(IsDecimate));
|
||||
RaisePropertyChanged(nameof(IsTabs));
|
||||
RaisePropertyChanged(nameof(BrightnessPercent));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRelief => _reliefType == RaftReliefTypes.Relief;
|
||||
public bool IsDimming => _reliefType == RaftReliefTypes.Dimming;
|
||||
public bool IsDecimate => _reliefType == RaftReliefTypes.Decimate;
|
||||
public bool IsTabs => _reliefType == RaftReliefTypes.Tabs;
|
||||
|
||||
public uint MaskLayerIndex
|
||||
{
|
||||
@@ -115,7 +144,7 @@ public class OperationRaftRelief : Operation
|
||||
}
|
||||
}
|
||||
|
||||
public decimal BrightnessPercent => Math.Round(_brightness * 100 / 255M, 2);
|
||||
public decimal BrightnessPercent => Math.Round((_reliefType == RaftReliefTypes.Tabs ? _tabBrightness : _brightness) * 100 / 255M, 2);
|
||||
|
||||
public byte DilateIterations
|
||||
{
|
||||
@@ -140,13 +169,36 @@ public class OperationRaftRelief : Operation
|
||||
get => _holeSpacing;
|
||||
set => RaiseAndSetIfChanged(ref _holeSpacing, value);
|
||||
}
|
||||
|
||||
public byte TabBrightness
|
||||
{
|
||||
get => _tabBrightness;
|
||||
set => RaiseAndSetIfChanged(ref _tabBrightness, Math.Max((byte)1, value));
|
||||
}
|
||||
|
||||
public ushort TabTriangleBase
|
||||
{
|
||||
get => _tabTriangleBase;
|
||||
set => RaiseAndSetIfChanged(ref _tabTriangleBase, Math.Max((ushort)5, value));
|
||||
}
|
||||
|
||||
public ushort TabTriangleHeight
|
||||
{
|
||||
get => _tabTriangleHeight;
|
||||
set
|
||||
{
|
||||
if (!RaiseAndSetIfChanged(ref _tabTriangleHeight, Math.Max((ushort)5, value))) return;
|
||||
RaisePropertyChanged(nameof(BrightnessPercent));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equality
|
||||
|
||||
protected bool Equals(OperationRaftRelief other)
|
||||
{
|
||||
return _reliefType == other._reliefType && _maskLayerIndex == other._maskLayerIndex && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing;
|
||||
return _reliefType == other._reliefType && _maskLayerIndex == other._maskLayerIndex && _ignoreFirstLayers == other._ignoreFirstLayers && _brightness == other._brightness && _dilateIterations == other._dilateIterations && _wallMargin == other._wallMargin && _holeDiameter == other._holeDiameter && _holeSpacing == other._holeSpacing && _tabTriangleBase == other._tabTriangleBase && _tabTriangleHeight == other._tabTriangleHeight;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
@@ -159,7 +211,18 @@ public class OperationRaftRelief : Operation
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine((int) _reliefType, _maskLayerIndex, _ignoreFirstLayers, _brightness, _dilateIterations, _wallMargin, _holeDiameter, _holeSpacing);
|
||||
var hashCode = new HashCode();
|
||||
hashCode.Add((int) _reliefType);
|
||||
hashCode.Add(_maskLayerIndex);
|
||||
hashCode.Add(_ignoreFirstLayers);
|
||||
hashCode.Add(_brightness);
|
||||
hashCode.Add(_dilateIterations);
|
||||
hashCode.Add(_wallMargin);
|
||||
hashCode.Add(_holeDiameter);
|
||||
hashCode.Add(_holeSpacing);
|
||||
hashCode.Add(_tabTriangleBase);
|
||||
hashCode.Add(_tabTriangleHeight);
|
||||
return hashCode.ToHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -176,7 +239,6 @@ public class OperationRaftRelief : Operation
|
||||
var anchor = new Point(-1, -1);
|
||||
var kernel = EmguExtensions.Kernel3x3Rectangle;
|
||||
|
||||
|
||||
uint firstSupportLayerIndex = _maskLayerIndex;
|
||||
if (firstSupportLayerIndex <= 0)
|
||||
{
|
||||
@@ -185,13 +247,13 @@ public class OperationRaftRelief : Operation
|
||||
for (; firstSupportLayerIndex < layerCount; firstSupportLayerIndex++)
|
||||
{
|
||||
progress.ThrowIfCancellationRequested();
|
||||
progress++;
|
||||
supportsMat = GetRoiOrDefault(SlicerFile[firstSupportLayerIndex].LayerMat);
|
||||
var circles = CvInvoke.HoughCircles(supportsMat, HoughModes.Gradient, 1, 5, 80, 35, 5, 200);
|
||||
if (circles.Length >= minSupportsRequired) break;
|
||||
|
||||
supportsMat.Dispose();
|
||||
supportsMat = null;
|
||||
progress++;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -265,6 +327,109 @@ public class OperationRaftRelief : Operation
|
||||
case RaftReliefTypes.Decimate:
|
||||
supportsMat.CopyTo(target);
|
||||
break;
|
||||
case RaftReliefTypes.Tabs:
|
||||
{
|
||||
using var contours = mat.FindContours(RetrType.External);
|
||||
var span = mat.GetDataByteSpan();
|
||||
|
||||
var minX = 10;
|
||||
var maxX = mat.Size.Width - 10;
|
||||
var minY = 10;
|
||||
var maxY = mat.Size.Height - 10;
|
||||
|
||||
var triangleBaseRadius = _tabTriangleBase / 2;
|
||||
var triangleHeightRadius = _tabTriangleHeight / 2;
|
||||
|
||||
var directions = new[]
|
||||
{
|
||||
new Point(0, -1), // Up
|
||||
new Point(1, 0), // Right
|
||||
new Point(0, 1), // Down
|
||||
new Point(-1, 0), // Left
|
||||
};
|
||||
|
||||
var color = new MCvScalar(_tabBrightness);
|
||||
|
||||
for (var i = 0; i < contours.Size; i++)
|
||||
{
|
||||
using var contour = new EmguContour(contours[i]);
|
||||
if(contour.Centroid.IsAnyNegative() || contour.Area < 10000) continue;
|
||||
|
||||
for (var dir = 0; dir < directions.Length; dir++)
|
||||
{
|
||||
var direction = directions[dir];
|
||||
|
||||
var foundFirstWhite = false;
|
||||
var foundPoint = false;
|
||||
|
||||
var x = contour.Centroid.X;
|
||||
var y = contour.Centroid.Y;
|
||||
|
||||
while (!foundPoint
|
||||
&& x >= minX && x <= maxX && y >= minY && y <= maxY
|
||||
&& contour.Bounds.Contains(x, y))
|
||||
{
|
||||
var pixel = span[mat.GetPixelPos(x, y)];
|
||||
|
||||
if (pixel > 0)
|
||||
{
|
||||
if (!foundFirstWhite)
|
||||
{
|
||||
foundFirstWhite = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CvInvoke.PointPolygonTest(contours[i], new PointF(x, y), false) == 0) // Must be on edge
|
||||
{
|
||||
foundPoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
x += direction.X;
|
||||
y += direction.Y;
|
||||
}
|
||||
|
||||
if(!foundPoint) continue;
|
||||
|
||||
var polygon = new Point[3];
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0: // Up
|
||||
polygon[0] = new Point(Math.Max(10, x - triangleBaseRadius), y);
|
||||
polygon[1] = new Point(Math.Min(mat.Width - 10, x + triangleBaseRadius), y);
|
||||
polygon[2] = new Point(x, Math.Max(10, y - triangleHeightRadius));
|
||||
break;
|
||||
case 1: // Right
|
||||
polygon[0] = new Point(x, Math.Max(10, y - triangleBaseRadius));
|
||||
polygon[1] = new Point(x, Math.Min(mat.Width - 10, y + triangleBaseRadius));
|
||||
polygon[2] = new Point(Math.Min(mat.Width - 10, x + triangleHeightRadius), y);
|
||||
break;
|
||||
case 2: // Down
|
||||
polygon[0] = new Point(Math.Max(10, x - triangleBaseRadius), y);
|
||||
polygon[1] = new Point(Math.Min(mat.Width - 10, x + triangleBaseRadius), y);
|
||||
polygon[2] = new Point(x, Math.Min(mat.Height - 10, y + triangleHeightRadius));
|
||||
break;
|
||||
case 3: // Left
|
||||
polygon[0] = new Point(x, Math.Max(10, y - triangleBaseRadius));
|
||||
polygon[1] = new Point(x, Math.Min(mat.Width - 10, y + triangleBaseRadius));
|
||||
polygon[2] = new Point(Math.Max(10, x - triangleHeightRadius), y);
|
||||
break;
|
||||
}
|
||||
|
||||
CvInvoke.Ellipse(mat, new Point(x, y), new Size(triangleBaseRadius, (int)(triangleBaseRadius / 1.5)), 90 * dir, 0, 180, EmguExtensions.WhiteColor, -1, LineType.AntiAlias);
|
||||
using var vec = new VectorOfPoint(polygon);
|
||||
CvInvoke.FillPoly(mat, vec, color, LineType.AntiAlias);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(ReliefType));
|
||||
}
|
||||
|
||||
ApplyMask(original, target);
|
||||
|
||||
@@ -271,4 +271,25 @@ public static class SystemAware
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if is running under Linux and under AppImage format
|
||||
/// </summary>
|
||||
public static bool IsRunningLinuxAppImage(out string? path)
|
||||
{
|
||||
path = null;
|
||||
if (!OperatingSystem.IsLinux()) return false;
|
||||
path = Environment.GetEnvironmentVariable("APPIMAGE");
|
||||
return !string.IsNullOrWhiteSpace(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if is running under Linux and under AppImage format
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsRunningLinuxAppImage() => IsRunningLinuxAppImage(out _);
|
||||
|
||||
/// <summary>
|
||||
/// Gets if is running under MacOS and under app format
|
||||
/// </summary>
|
||||
public static bool IsRunningMacOSApp => OperatingSystem.IsMacOS() && AppContext.BaseDirectory.EndsWith(".app/Contents/MacOS");
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
|
||||
<Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description>
|
||||
<Version>3.1.0</Version>
|
||||
<Version>3.1.1</Version>
|
||||
<Copyright>Copyright © 2020 PTRTECH</Copyright>
|
||||
<PackageIcon>UVtools.png</PackageIcon>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<ComboBox Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
SelectedItem="{Binding Operation.ReliefType}"
|
||||
Items="{Binding Operation.RaftReliefItems}"/>
|
||||
Items="{Binding Operation.ReliefType, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
|
||||
SelectedItem="{Binding Operation.ReliefType, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
@@ -65,49 +65,99 @@ you must manually input the layer index of the last raft where it ends and suppo
|
||||
Classes="ValueLabel ValueLabel_sun"
|
||||
Minimum="0"
|
||||
Maximum="255"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"
|
||||
Value="{Binding Operation.Brightness}"/>
|
||||
<TextBlock
|
||||
Grid.Row="6" Grid.Column="4"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"
|
||||
Text="{Binding Operation.BrightnessPercent, StringFormat=\{0:F2\}%}" VerticalAlignment="Center"/>
|
||||
Value="{Binding Operation.Brightness}">
|
||||
<NumericUpDown.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}">
|
||||
<Binding Path="Operation.IsRelief"/>
|
||||
<Binding Path="Operation.IsDimming"/>
|
||||
</MultiBinding>
|
||||
</NumericUpDown.IsVisible>
|
||||
</NumericUpDown>
|
||||
|
||||
<NumericUpDown Grid.Row="6" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_sun"
|
||||
Minimum="0"
|
||||
Maximum="255"
|
||||
IsVisible="{Binding Operation.IsTabs}"
|
||||
Value="{Binding Operation.TabBrightness}"/>
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="4"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"
|
||||
Text="{Binding Operation.BrightnessPercent, StringFormat=\{0:F2\}%}" VerticalAlignment="Center"/>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8" Grid.Column="0"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"
|
||||
Text="Supports margin:" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Row="8" Grid.Column="0"
|
||||
Text="Supports margin:" VerticalAlignment="Center">
|
||||
<TextBlock.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}">
|
||||
<Binding Path="Operation.IsRelief"/>
|
||||
<Binding Path="Operation.IsDimming"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.IsVisible>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8" Grid.Column="0"
|
||||
IsVisible="{Binding Operation.IsDecimate}"
|
||||
ToolTip.Tip="Raft will be replaced by the present supports and then dilated by this value to thicken the supports and increase the adhesion.
|
||||
<TextBlock Grid.Row="8" Grid.Column="0"
|
||||
IsVisible="{Binding Operation.IsDecimate}"
|
||||
ToolTip.Tip="Raft will be replaced by the present supports and then dilated by this value to thicken the supports and increase the adhesion.
|
||||

Use large numbers with tiny supports for best adhesion."
|
||||
Text="Dilate supports by:" VerticalAlignment="Center"/>
|
||||
Text="Dilate supports by:" VerticalAlignment="Center"/>
|
||||
|
||||
<TextBlock Grid.Row="8" Grid.Column="0"
|
||||
IsVisible="{Binding Operation.IsTabs}"
|
||||
Text="Tab triangle base:" VerticalAlignment="Center"/>
|
||||
|
||||
<NumericUpDown Grid.Row="8" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_px"
|
||||
Minimum="0"
|
||||
Maximum="255"
|
||||
Value="{Binding Operation.DilateIterations}"/>
|
||||
Minimum="0"
|
||||
Maximum="255"
|
||||
IsVisible="{Binding !Operation.IsTabs}"
|
||||
Value="{Binding Operation.DilateIterations}"/>
|
||||
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="10" Grid.Column="0"
|
||||
Text="Wall margin:" VerticalAlignment="Center"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"
|
||||
/>
|
||||
<NumericUpDown Grid.Row="8" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_px"
|
||||
Minimum="5"
|
||||
Maximum="65535"
|
||||
IsVisible="{Binding Operation.IsTabs}"
|
||||
Value="{Binding Operation.TabTriangleBase}"/>
|
||||
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0"
|
||||
Text="Wall margin:" VerticalAlignment="Center">
|
||||
<TextBlock.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}">
|
||||
<Binding Path="Operation.IsRelief"/>
|
||||
<Binding Path="Operation.IsDimming"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.IsVisible>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0"
|
||||
IsVisible="{Binding Operation.IsTabs}"
|
||||
Text="Tab triangle height:" VerticalAlignment="Center"/>
|
||||
|
||||
<NumericUpDown Grid.Row="10" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_px"
|
||||
Minimum="1"
|
||||
Maximum="255"
|
||||
Value="{Binding Operation.WallMargin}"
|
||||
IsVisible="{Binding !Operation.IsDecimate}"/>
|
||||
Value="{Binding Operation.WallMargin}">
|
||||
<NumericUpDown.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}">
|
||||
<Binding Path="Operation.IsRelief"/>
|
||||
<Binding Path="Operation.IsDimming"/>
|
||||
</MultiBinding>
|
||||
</NumericUpDown.IsVisible>
|
||||
</NumericUpDown>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="12"
|
||||
<NumericUpDown Grid.Row="10" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_px"
|
||||
Minimum="5"
|
||||
Maximum="65535"
|
||||
IsVisible="{Binding Operation.IsTabs}"
|
||||
Value="{Binding Operation.TabTriangleHeight}"/>
|
||||
|
||||
|
||||
|
||||
<TextBlock Grid.Row="12" Grid.Column="0"
|
||||
Text="Hole diameter:" VerticalAlignment="Center"
|
||||
IsVisible="{Binding Operation.IsRelief}"/>
|
||||
|
||||
@@ -121,8 +171,7 @@ you must manually input the layer index of the last raft where it ends and suppo
|
||||
<TextBlock
|
||||
Grid.Row="14" Grid.Column="0"
|
||||
Text="Hole spacing:" VerticalAlignment="Center"
|
||||
IsVisible="{Binding Operation.IsRelief}"
|
||||
/>
|
||||
IsVisible="{Binding Operation.IsRelief}"/>
|
||||
|
||||
<NumericUpDown Grid.Row="14" Grid.Column="2"
|
||||
Classes="ValueLabel ValueLabel_px"
|
||||
|
||||
@@ -1163,7 +1163,7 @@ public partial class MainWindow : WindowEx
|
||||
public async void MenuFileSettingsClicked()
|
||||
{
|
||||
var oldTheme = Settings.General.Theme;
|
||||
var oldLayerCompressionMethod = Settings.General.LayerCompressionMethod;
|
||||
var oldLayerCompressionCodec = Settings.General.LayerCompressionCodec;
|
||||
var settingsWindow = new SettingsWindow();
|
||||
await settingsWindow.ShowDialog(this);
|
||||
if (settingsWindow.DialogResult == DialogResults.OK)
|
||||
@@ -1173,16 +1173,16 @@ public partial class MainWindow : WindowEx
|
||||
App.ApplyTheme();
|
||||
}
|
||||
|
||||
if (oldLayerCompressionMethod != Settings.General.LayerCompressionMethod)
|
||||
if (oldLayerCompressionCodec != Settings.General.LayerCompressionCodec)
|
||||
{
|
||||
IsGUIEnabled = false;
|
||||
ShowProgressWindow($"Changing layer compression method from {oldLayerCompressionMethod.ToString().ToUpper()} to {Settings.General.LayerCompressionMethod.ToString().ToUpper()}");
|
||||
ShowProgressWindow($"Changing layers compression codec from {oldLayerCompressionCodec.ToString().ToUpper()} to {Settings.General.LayerCompressionCodec.ToString().ToUpper()}");
|
||||
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
SlicerFile.ChangeLayersCompressionMethod(Settings.General.LayerCompressionMethod, Progress);
|
||||
SlicerFile.ChangeLayersCompressionMethod(Settings.General.LayerCompressionCodec, Progress);
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using Avalonia;
|
||||
using Projektanker.Icons.Avalonia;
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Threading;
|
||||
using UVtools.Core;
|
||||
@@ -43,7 +44,9 @@ public class AppVersionChecker : BindableBase
|
||||
var package = File.ReadAllText(file);
|
||||
if (!string.IsNullOrWhiteSpace(package) && (package.EndsWith("-x64") || package.EndsWith("-arm64")))
|
||||
{
|
||||
return $"{About.Software}_{package}_v{_version}.zip";
|
||||
return SystemAware.IsRunningLinuxAppImage()
|
||||
? $"{About.Software}_{package}_v{_version}.AppImage"
|
||||
: $"{About.Software}_{package}_v{_version}.zip";
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -58,20 +61,22 @@ public class AppVersionChecker : BindableBase
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return $"{About.Software}_linux-x64_v{_version}.zip";
|
||||
return SystemAware.IsRunningLinuxAppImage()
|
||||
? $"{About.Software}_linux-x64_v{_version}.AppImage"
|
||||
: $"{About.Software}_linux-x64_v{_version}.zip";
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
if (RuntimeInformation.ProcessArchitecture is Architecture.Arm or Architecture.Arm64) return $"{About.Software}_osx-arm64_v{_version}.zip";
|
||||
|
||||
return $"{About.Software}_osx-x64_v{_version}.zip";
|
||||
return RuntimeInformation.ProcessArchitecture is Architecture.Arm or Architecture.Arm64
|
||||
? $"{About.Software}_osx-arm64_v{_version}.zip"
|
||||
: $"{About.Software}_osx-x64_v{_version}.zip";
|
||||
}
|
||||
|
||||
return $"{About.Software}_universal-x86-x64_v{_version}.zip";
|
||||
}
|
||||
}
|
||||
|
||||
public string Runtime
|
||||
/*public string Runtime
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -90,7 +95,7 @@ public class AppVersionChecker : BindableBase
|
||||
|
||||
return "universal-x86-x64";
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public string Version
|
||||
{
|
||||
@@ -180,8 +185,9 @@ public class AppVersionChecker : BindableBase
|
||||
progress.ItemName = "Megabytes";
|
||||
try
|
||||
{
|
||||
var downloadFilename = Filename;
|
||||
var path = Path.GetTempPath();
|
||||
DownloadedFile = Path.Combine(path, Filename);
|
||||
DownloadedFile = Path.Combine(path, downloadFilename);
|
||||
Debug.WriteLine($"Downloading to: {DownloadedFile}");
|
||||
progress.ItemName = "Megabytes";
|
||||
|
||||
@@ -203,53 +209,70 @@ public class AppVersionChecker : BindableBase
|
||||
}
|
||||
else
|
||||
{
|
||||
string upgradeFolder = "UPDATED_VERSION";
|
||||
var targetDir = Path.Combine(App.ApplicationPath, upgradeFolder);
|
||||
await using (var stream = File.Open(DownloadedFile, FileMode.Open))
|
||||
// Linux AppImage
|
||||
if (downloadFilename.EndsWith(".AppImage") && SystemAware.IsRunningLinuxAppImage(out var appImagePath))
|
||||
{
|
||||
using ZipArchive zip = new(stream, ZipArchiveMode.Read);
|
||||
zip.ExtractToDirectory(targetDir, true);
|
||||
var directory = Path.GetDirectoryName(appImagePath);
|
||||
var oldFileName = Path.GetFileName(appImagePath);
|
||||
// Try to keep same filename logic if user renamed the file, like UVtools.AppImage would keep same same
|
||||
var newFilename = Regex.Replace(oldFileName, @"v\d.\d.\d", $"v{_version}");
|
||||
var newFullPath = Path.Combine(directory, newFilename);
|
||||
|
||||
if (File.Exists(appImagePath)) File.Delete(appImagePath);
|
||||
File.Move(DownloadedFile, newFullPath, true);
|
||||
SystemAware.StartProcess("chmod", $"a+x \"{newFullPath}\"");
|
||||
SystemAware.StartProcess(newFullPath);
|
||||
}
|
||||
|
||||
File.Delete(DownloadedFile);
|
||||
|
||||
string upgradeFileName = $"{About.Software}_upgrade.sh";
|
||||
var upgradeFile = Path.Combine(App.ApplicationPath, upgradeFileName);
|
||||
await using (var stream = File.CreateText(upgradeFile))
|
||||
else // others
|
||||
{
|
||||
await stream.WriteLineAsync("#!/bin/bash");
|
||||
await stream.WriteLineAsync($"echo {About.Software} v{App.Version} updater script");
|
||||
await stream.WriteLineAsync($"cd '{App.ApplicationPath}'");
|
||||
await stream.WriteLineAsync($"killall {About.Software}");
|
||||
await stream.WriteLineAsync("sleep 0.5");
|
||||
|
||||
|
||||
//stream.WriteLine($"[ -f {About.Software} ] && {App.AppExecutableQuoted} & || dotnet {About.Software}.dll &");
|
||||
if (OperatingSystem.IsMacOS() && App.ApplicationPath.EndsWith(".app/Contents/MacOS"))
|
||||
var upgradeFolder = "UPDATED_VERSION";
|
||||
var targetDir = Path.Combine(App.ApplicationPath, upgradeFolder);
|
||||
await using (var stream = File.Open(DownloadedFile, FileMode.Open))
|
||||
{
|
||||
await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* ../../../");
|
||||
await stream.WriteLineAsync($"open ../../../{About.Software}.app");
|
||||
}
|
||||
else
|
||||
{
|
||||
await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* .");
|
||||
await stream.WriteLineAsync($"if [ -f '{About.Software}' ]; then");
|
||||
await stream.WriteLineAsync($" ./{About.Software} &");
|
||||
await stream.WriteLineAsync("else");
|
||||
await stream.WriteLineAsync($" dotnet {About.Software}.dll &");
|
||||
await stream.WriteLineAsync("fi");
|
||||
using ZipArchive zip = new(stream, ZipArchiveMode.Read);
|
||||
zip.ExtractToDirectory(targetDir, true);
|
||||
}
|
||||
|
||||
await stream.WriteLineAsync($"rm -fr {upgradeFolder}");
|
||||
await stream.WriteLineAsync("sleep 0.5");
|
||||
await stream.WriteLineAsync($"rm -f {upgradeFileName}");
|
||||
//stream.WriteLine("exit");
|
||||
stream.Close();
|
||||
File.Delete(DownloadedFile);
|
||||
|
||||
var upgradeFileName = $"{About.Software}_upgrade.sh";
|
||||
var upgradeFile = Path.Combine(App.ApplicationPath, upgradeFileName);
|
||||
await using (var stream = File.CreateText(upgradeFile))
|
||||
{
|
||||
stream.NewLine = "\n";
|
||||
await stream.WriteLineAsync("#!/bin/bash");
|
||||
await stream.WriteLineAsync($"echo {About.Software} v{App.Version} updater script");
|
||||
await stream.WriteLineAsync($"cd '{App.ApplicationPath}'");
|
||||
await stream.WriteLineAsync($"killall {About.Software}");
|
||||
await stream.WriteLineAsync("sleep 0.5");
|
||||
|
||||
|
||||
//stream.WriteLine($"[ -f {About.Software} ] && {App.AppExecutableQuoted} & || dotnet {About.Software}.dll &");
|
||||
if (SystemAware.IsRunningMacOSApp)
|
||||
{
|
||||
await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* ../../../");
|
||||
await stream.WriteLineAsync($"open ../../../{About.Software}.app");
|
||||
}
|
||||
else
|
||||
{
|
||||
await stream.WriteLineAsync($"cp -fR {upgradeFolder}/* .");
|
||||
await stream.WriteLineAsync($"if [ -f '{About.Software}' ]; then");
|
||||
await stream.WriteLineAsync($" ./{About.Software} &");
|
||||
await stream.WriteLineAsync("else");
|
||||
await stream.WriteLineAsync($" dotnet {About.Software}.dll &");
|
||||
await stream.WriteLineAsync("fi");
|
||||
}
|
||||
|
||||
await stream.WriteLineAsync($"rm -fr {upgradeFolder}");
|
||||
await stream.WriteLineAsync("sleep 0.5");
|
||||
await stream.WriteLineAsync($"rm -f {upgradeFileName}");
|
||||
//stream.WriteLine("exit");
|
||||
}
|
||||
|
||||
SystemAware.StartProcess("bash", $"\"{upgradeFile}\"");
|
||||
//App.NewInstance(App.MainWindow.SlicerFile?.FileFullPath);
|
||||
}
|
||||
|
||||
SystemAware.StartProcess("bash", $"\"{upgradeFile}\"");
|
||||
|
||||
//App.NewInstance(App.MainWindow.SlicerFile?.FileFullPath);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<Version>3.1.0</Version>
|
||||
<Version>3.1.1</Version>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<PackageIcon>UVtools.png</PackageIcon>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
@@ -43,6 +43,7 @@
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.13" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.13" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.13" />
|
||||
<PackageReference Include="Emgu.CV.runtime.ubuntu.20.04-x64" Version="4.5.4.4788" />
|
||||
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.5.5.4823" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="2.0.0" />
|
||||
<PackageReference Include="Projektanker.Icons.Avalonia" Version="4.2.1" />
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class UserSettings : BindableBase
|
||||
private bool _loadDemoFileOnStartup = true;
|
||||
private bool _loadLastRecentFileOnStartup;
|
||||
private int _maxDegreeOfParallelism = -1;
|
||||
private Layer.LayerCompressionMethod _layerCompressionMethod = CoreSettings.DefaultLayerCompressionMethod;
|
||||
private Layer.LayerCompressionCodec _layerCompressionCodec = CoreSettings.DefaultLayerCompressionCodec;
|
||||
|
||||
private bool _windowsCanResize;
|
||||
private bool _windowsTakeIntoAccountScreenScaling = true;
|
||||
@@ -102,10 +102,10 @@ public sealed class UserSettings : BindableBase
|
||||
set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, Math.Min(value, Environment.ProcessorCount));
|
||||
}
|
||||
|
||||
public Layer.LayerCompressionMethod LayerCompressionMethod
|
||||
public Layer.LayerCompressionCodec LayerCompressionCodec
|
||||
{
|
||||
get => _layerCompressionMethod;
|
||||
set => RaiseAndSetIfChanged(ref _layerCompressionMethod, value);
|
||||
get => _layerCompressionCodec;
|
||||
set => RaiseAndSetIfChanged(ref _layerCompressionCodec, value);
|
||||
}
|
||||
|
||||
public bool WindowsCanResize
|
||||
@@ -1641,7 +1641,7 @@ public sealed class UserSettings : BindableBase
|
||||
}
|
||||
|
||||
CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism;
|
||||
CoreSettings.DefaultLayerCompressionMethod = _instance.General.LayerCompressionMethod;
|
||||
CoreSettings.DefaultLayerCompressionCodec = _instance.General.LayerCompressionCodec;
|
||||
|
||||
if (_instance.Network.RemotePrinters.Count == 0)
|
||||
{
|
||||
@@ -1864,7 +1864,7 @@ public sealed class UserSettings : BindableBase
|
||||
Instance.SavesCount++;
|
||||
_instance.ModifiedDateTime = DateTime.Now;
|
||||
CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism;
|
||||
CoreSettings.DefaultLayerCompressionMethod = _instance.General.LayerCompressionMethod;
|
||||
CoreSettings.DefaultLayerCompressionCodec = _instance.General.LayerCompressionCodec;
|
||||
try
|
||||
{
|
||||
XmlExtensions.SerializeToFile(_instance, FilePath, XmlExtensions.SettingsIndent);
|
||||
|
||||
@@ -526,7 +526,7 @@ public class BenchmarkWindow : WindowEx
|
||||
|
||||
public void TestPNGCompress(BenchmarkResolution resolution)
|
||||
{
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionMethod.Png);
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Png);
|
||||
}
|
||||
|
||||
public void TestPNGDecompress(BenchmarkResolution resolution)
|
||||
@@ -534,7 +534,7 @@ public class BenchmarkWindow : WindowEx
|
||||
|
||||
public void TestGZipCompress(BenchmarkResolution resolution)
|
||||
{
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionMethod.GZip);
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.GZip);
|
||||
}
|
||||
|
||||
public void TestGZipDecompress(BenchmarkResolution resolution)
|
||||
@@ -542,7 +542,7 @@ public class BenchmarkWindow : WindowEx
|
||||
|
||||
public void TestDeflateCompress(BenchmarkResolution resolution)
|
||||
{
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionMethod.Deflate);
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Deflate);
|
||||
}
|
||||
|
||||
public void TestDeflateDecompress(BenchmarkResolution resolution)
|
||||
@@ -550,7 +550,7 @@ public class BenchmarkWindow : WindowEx
|
||||
|
||||
public void TestLZ4Compress(BenchmarkResolution resolution)
|
||||
{
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionMethod.Lz4);
|
||||
Layer.CompressMat(Mats[resolution], Layer.LayerCompressionCodec.Lz4);
|
||||
}
|
||||
|
||||
public void TestLZ4Decompress(BenchmarkResolution resolution)
|
||||
|
||||
@@ -126,15 +126,15 @@
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip.Tip="Sets the compression method used to store layer image cache.
|
||||
ToolTip.Tip="Sets the compression codec used to store the layer image cache.
|
||||

The selected method will impact RAM usage and operations speed."
|
||||
Text="Layer compression:"/>
|
||||
Text="Layer compression codec:"/>
|
||||
|
||||
<ComboBox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="17"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Items="{Binding Settings.General.LayerCompressionMethod, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
|
||||
SelectedItem="{Binding Settings.General.LayerCompressionMethod, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
|
||||
Items="{Binding Settings.General.LayerCompressionCodec, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}"
|
||||
SelectedItem="{Binding Settings.General.LayerCompressionCodec, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ Set-Location $PSScriptRoot\..
|
||||
### Configuration ###
|
||||
####################################
|
||||
$enableMSI = $true
|
||||
$buildOnly = 'win-x64'
|
||||
#$buildOnly = 'win-x64'
|
||||
#$buildOnly = 'linux-x64'
|
||||
#$buildOnly = 'osx-x64'
|
||||
#$buildOnly = 'osx-arm64'
|
||||
|
||||
Reference in New Issue
Block a user