Files
UVtools/UVtools.Core/Operations/OperationProgress.cs
T
Tiago Conceição 0ba61780b7 v2.4.0
* (Upgrade) EmguCV/OpenCV to v4.5.1
* (Upgrade) AvaloniaUI to 1.0
* (Improvement) GUI re-touched
* (Improvement) Make pixel editor tab to disappear when pixel editor is disabled
* (Improvement) Simplify the output filename from PrusaSlicer profiles
* (Improvement) All operations require a slicer file at constructor rather than on execute, this allow exposure the open file to the operation before run it
* (Improvement) Calibrations: Auto set "Mirror Output" if open file have MirrorDisplay set
* (Change) Tool - Redraw model/supports icon
* (Change) photon and cbddlp to use version 3 by default
* (Add) Tool - Dynamic layer height: Analyze and optimize the model with dynamic layer heights, larger angles will slice at lower layer height
        while more straight angles will slice larger layer height. (#131)
* (Add) Calibration - Exposure time finder: Generates test models with various strategies and increments to verify the best exposure time for a given layer height
* (Add) File load checks, trigger error when a file have critical errors and attempt to fix non-critical errors
  * Layers must have an valid image, otherwise trigger an error
  * Layers must have a incremental or equal position Z than it previous, otherwise trigger an error
  * If layer 0 starts at 0mm it will auto fix all layers, it will add Layer Height to the current z at every layer
* (Add) Tool - Edit print parameters: Allow set parameters to each x layers and skip n layers inside the given range.
        This allow the use of optimizations in a layer pattern, for example, to set 3s for a layer but 2.5s for the next.
* (Add) Layer height property to "Layer Data" table: Shows layer height for the slice
* (Fix) When automations applied and file is saved, it will not warn user about file overwrite for the first time save
* (Fix) Tool - Redraw model/supports: Disable apply button when no file selected
* (Fix) Tool - Infill: Lack of equality member to test if same infill profile already exists
* (Fix) Auto converted files from SL1 where clipping filename at first dot (.), now it only strips known extensions
* (Fix) SL1 encoded files wasn't generating the right information and lead to printer crash
* (Fix) PrusaSlicer printer "Anycubic Photon S" LiftSpeed was missing and contains a typo (#135)
* (Fix) PrusaSlicer profile manager wasnt marking missing profiles to be installed (#135)
* (Fix) PrusaSlicer folder search on linux to also look at %HOME%/.config/PrusaSlicer (#135, #136)
* (Fix) Operations were revised and some bug fixed, most about can't cancel the progress
* (Fix) Some typos on tooltips
* (Fix) Prevent PhotonS from enconding, it will trigger error now as this format is read-only
* **(Fix) Ctrl + Shift + Z to redo the last operation:**
  * The layer range is reseted instead of pull the used values
  * Tool - Arithmetic always disabled
  * Action - Layer import didn't generate info and always disabled
2021-02-06 22:09:55 +00:00

190 lines
6.0 KiB
C#

/*
* GNU AFFERO GENERAL PUBLIC LICENSE
* Version 3, 19 November 2007
* Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using System;
using System.Diagnostics;
using System.Threading;
using UVtools.Core.Extensions;
using UVtools.Core.Objects;
namespace UVtools.Core.Operations
{
public sealed class OperationProgress : BindableBase
{
public const string StatusDecodeThumbnails = "Decoded Thumbnails";
public const string StatusGatherLayers = "Gathered Layers";
public const string StatusDecodeLayers = "Decoded Layers";
public const string StatusEncodeLayers = "Encoded Layers";
public const string StatusWritingFile = "Writing File";
public const string StatusEncodeGcode = "Encoding GCode";
public const string StatusOptimizingBounds = "Gathering Bounds";
public const string StatusCalculatingBounds = "Calculating Bounds";
public const string StatusExtracting = "Extracting";
public const string StatusIslands = "Layers processed (Islands/Overhangs)";
public const string StatusResinTraps = "Layers processed (Resin traps)";
public const string StatusRepairLayers = "Repaired Layers";
public object Mutex = new object();
public CancellationTokenSource TokenSource { get; } = new CancellationTokenSource();
public CancellationToken Token => TokenSource.Token;
private bool _canCancel = true;
private string _title = "Operation";
private string _itemName = "Initializing";
private uint _processedItems;
private uint _itemCount;
public
OperationProgress()
{
}
public OperationProgress(string name, uint value = 0)
{
Reset(name, value);
}
public OperationProgress(bool canCancel)
{
_canCancel = canCancel;
}
public Stopwatch StopWatch { get; } = new ();
/// <summary>
/// Gets or sets if operation can be cancelled
/// </summary>
public bool CanCancel
{
get
{
if (!_canCancel) return _canCancel;
return !Token.IsCancellationRequested && Token.CanBeCanceled && _canCancel;
}
set => RaiseAndSetIfChanged(ref _canCancel, value);
}
/// <summary>
/// Gets or sets the item name for the operation
/// </summary>
public string Title
{
get => _title;
set => RaiseAndSetIfChanged(ref _title, value);
}
public string ElapsedTimeStr => $"{StopWatch.Elapsed.Minutes}m {StopWatch.Elapsed.Seconds}s";
//{StopWatch.Elapsed.Milliseconds} ms
/// <summary>
/// Gets or sets the item name for the operation
/// </summary>
public string ItemName
{
get => _itemName;
set => RaiseAndSetIfChanged(ref _itemName, value);
}
/// <summary>
/// Gets or sets the number of processed items
/// </summary>
public uint ProcessedItems
{
get => _processedItems;
set
{
//_processedItems = value;
RaiseAndSetIfChanged(ref _processedItems, value);
RaisePropertyChanged(nameof(ProgressPercent));
RaisePropertyChanged(nameof(Description));
}
}
/// <summary>
/// Gets or sets the total of item count on this operation
/// </summary>
public uint ItemCount
{
get => _itemCount;
set
{
RaiseAndSetIfChanged(ref _itemCount, value);
RaisePropertyChanged(nameof(IsIndeterminate));
RaisePropertyChanged(nameof(ProgressPercent));
RaisePropertyChanged(nameof(Description));
}
}
/// <summary>
/// Gets or sets an tag
/// </summary>
public object Tag { get; set; }
/// <summary>
/// Gets the remaining items to be processed
/// </summary>
public uint RemainingItems => _itemCount - _processedItems;
public int ProgressStep => (int)ProgressPercent;
public string Description => ToString();
public bool IsIndeterminate => _itemCount == 0;
/// <summary>
/// Gets the progress from 0 to 100%
/// </summary>
public double ProgressPercent => _itemCount == 0 ? 0 : Math.Round(_processedItems * 100.0 / _itemCount, 2).Clamp(0, 100);
public static OperationProgress operator +(OperationProgress progress, uint value)
{
progress.ProcessedItems += value;
return progress;
}
public static OperationProgress operator ++(OperationProgress progress)
{
progress.ProcessedItems++;
return progress;
}
public static OperationProgress operator --(OperationProgress progress)
{
progress.ProcessedItems--;
return progress;
}
public void Reset(string name = "", uint itemCount = 0, uint items = 0)
{
ItemName = name;
ItemCount = itemCount;
ProcessedItems = items;
}
public override string ToString()
{
return _itemCount == 0 ?
$"{_processedItems}/? {_itemName}" :
$"{_processedItems.ToString().PadLeft(_itemCount.ToString().Length, '0')}/{_itemCount} {_itemName} | {ProgressPercent:0.00}%";
}
public void TriggerRefresh()
{
RaisePropertyChanged(nameof(ElapsedTimeStr));
RaisePropertyChanged(nameof(CanCancel));
//OnPropertyChanged(nameof(ProgressPercent));
//OnPropertyChanged(nameof(Description));
}
}
}