Files
UVtools/UVtools.Core/Suggestions/SuggestionTransitionLayerCount.cs
Tiago Conceição 2c7ad09dc0 v3.13.1
- (Change) `Layer.IsBottomLayer` no longer calculate the value using the position of the layer, a new property `IsBottomLayerByHeight` is now used to get that result
- (Improvement) Tool - Double exposure: Increase the bottom layer count per cloned bottom layer
- (Improvement) Calibration - Exposure time finder: Set the absolute bottom layer count accordingly when also testing for bottom time
- (Improvement) Goo: Enforce Wait times or Light-off-delay flag based on property set
- (Fix) AnyCubic and Goo: `PerLayerSetting` flag was set inverted causing printer not to follow layer settings when it should and also the otherwise (#689)
- (Fix) Tool - Scripting: Prevent from reload UI multiple times when using profiles (#694)
2023-04-27 22:58:05 +01:00

227 lines
9.4 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.Text;
using UVtools.Core.FileFormats;
using UVtools.Core.Operations;
namespace UVtools.Core.Suggestions;
public sealed class SuggestionTransitionLayerCount : Suggestion
{
#region Members
private decimal _transitionStepTime = 2;
private ushort _minimumTransitionLayerCount = 3;
private ushort _maximumTransitionLayerCount = 10;
#endregion
#region Properties
public override bool IsAvailable
{
get
{
if (SlicerFile is null) return false;
return SlicerFile.CanUseLayerExposureTime && SlicerFile.LayerCount != 0;
}
}
public override bool IsApplied
{
get
{
if (SlicerFile is null) return false;
// Can't apply
if (SlicerFile.BottomLayerCount == 0
|| SlicerFile.BottomExposureTime <= 0
|| SlicerFile.ExposureTime <= 0
|| SlicerFile.BottomExposureTime < SlicerFile.ExposureTime
|| SlicerFile.BottomLayerCount + _minimumTransitionLayerCount > SlicerFile.LayerCount
|| SlicerFile.MaximumPossibleTransitionLayerCount < _minimumTransitionLayerCount) return true;
var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
? SlicerFile.TransitionLayerCount
: SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
if (actualTransitionLayerCount == suggestedTransitionLayerCount) return true;
return _applyWhen switch
{
SuggestionApplyWhen.OutsideLimits => actualTransitionLayerCount >= _minimumTransitionLayerCount &&
actualTransitionLayerCount <= _maximumTransitionLayerCount,
SuggestionApplyWhen.Different => actualTransitionLayerCount == suggestedTransitionLayerCount,
_ => throw new ArgumentOutOfRangeException()
};
}
}
public override string Title => "Transition layers";
public override string Description => "If you are printing flat on the build plate your model will print better when using a smooth transition exposure time instead of a harsh variation, resulting in reduced layer line effect and avoid possible problems due the large exposure difference.\n" +
"This is not so important when your model print raised under a raft/supports unaffected by the bottom exposure, in that case, it's fine to ignore this.";
public override string Message
{
get
{
var actualTransitionDecrementTime = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
? SlicerFile.GetTransitionStepTime()
: SlicerFile.ParseTransitionStepTimeFromLayers();
var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
? SlicerFile.TransitionLayerCount
: SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTimeFromLayers(suggestedTransitionLayerCount);
var bottomExposureTime = SlicerFile.LastBottomLayer?.ExposureTime ?? SlicerFile.BottomExposureTime;
var exposureTime = SlicerFile.ExposureTime;
var layerIndex = SlicerFile.TransitionLayerCount > 0
? SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount
: SlicerFile.BottomLayerCount;
if (SlicerFile.ContainsLayer(layerIndex))
{
exposureTime = SlicerFile[layerIndex].ExposureTime;
}
return IsApplied
? $"{GlobalAppliedMessage}: {bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s"
: $"{GlobalNotAppliedMessage} {bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s is out of the recommended {bottomExposureTime}s » {(suggestedTransitionDecrementTime <= 0 || suggestedTransitionLayerCount == 0 ? string.Empty : $"[-{suggestedTransitionDecrementTime}s/{suggestedTransitionLayerCount} layers] » ")}{exposureTime}s";
}
}
public override string ToolTip => $"The recommended transition time is ±{_transitionStepTime}s constrained over [{_minimumTransitionLayerCount} to {_maximumTransitionLayerCount}] layers.\n" +
$"Explanation: {Description}";
public override string? InformationUrl => "https://ameralabs.com/blog/9-settings-to-change-for-faster-resin-3d-printing";
public override string? ConfirmationMessage
{
get
{
var actualTransitionDecrementTime = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
? SlicerFile.GetTransitionStepTime()
: SlicerFile.ParseTransitionStepTimeFromLayers();
var actualTransitionLayerCount = SlicerFile.TransitionLayerType == FileFormat.TransitionLayerTypes.Firmware
? SlicerFile.TransitionLayerCount
: SlicerFile.ParseTransitionLayerCountFromLayers();
var suggestedTransitionLayerCount = TransitionLayerCount;
var suggestedTransitionDecrementTime = SlicerFile.GetTransitionStepTimeFromLayers(suggestedTransitionLayerCount);
var bottomExposureTime = SlicerFile.LastBottomLayer?.ExposureTime ?? SlicerFile.BottomExposureTime;
var exposureTime = SlicerFile.ExposureTime;
var layerIndex = SlicerFile.TransitionLayerCount > 0
? SlicerFile.BottomLayerCount + SlicerFile.TransitionLayerCount
: SlicerFile.BottomLayerCount;
if (SlicerFile.ContainsLayer(layerIndex))
{
exposureTime = SlicerFile[layerIndex].ExposureTime;
}
return $"{Title}: ({bottomExposureTime}s » {(actualTransitionDecrementTime <= 0 || actualTransitionLayerCount == 0 ? string.Empty : $"[-{actualTransitionDecrementTime}s/{actualTransitionLayerCount} layers] » ")}{exposureTime}s) » ({bottomExposureTime}s » {(suggestedTransitionDecrementTime <= 0 || suggestedTransitionLayerCount == 0 ? string.Empty : $"[-{suggestedTransitionDecrementTime}s/{suggestedTransitionLayerCount} layers] » ")}{exposureTime}s)";
}
}
public ushort TransitionLayerCount =>
(ushort)Math.Min(
Math.Clamp(
SlicerFile.GetTransitionLayerCountFromLayers((float)_transitionStepTime, false),
_minimumTransitionLayerCount,
_maximumTransitionLayerCount)
, SlicerFile.MaximumPossibleTransitionLayerCount);
public decimal TransitionStepTime
{
get => _transitionStepTime;
set => RaiseAndSetIfChanged(ref _transitionStepTime, Math.Max(0, Math.Round(value, 2)));
}
public ushort MinimumTransitionLayerCount
{
get => _minimumTransitionLayerCount;
set => RaiseAndSetIfChanged(ref _minimumTransitionLayerCount, value);
}
public ushort MaximumTransitionLayerCount
{
get => _maximumTransitionLayerCount;
set => RaiseAndSetIfChanged(ref _maximumTransitionLayerCount, value);
}
#endregion
#region Override
public override string? Validate()
{
var sb = new StringBuilder();
if (_transitionStepTime < 0)
{
sb.AppendLine("Decrement time (s) must be zero or a positive value");
}
/*if (_minimumTransitionTimeDecrement < 0)
{
sb.AppendLine("Minimum limit (s) can't be a negative value");
}
if (_maximumTransitionTimeDecrement < 0)
{
sb.AppendLine("Maximum limit (s) can't be a negative value");
}
if (_minimumTransitionTimeDecrement > _maximumTransitionTimeDecrement)
{
sb.AppendLine("Minimum limit (s) can't be higher than maximum limit (s)");
}*/
/*if (_minimumTransitionLayerCount == 0)
{
sb.AppendLine("Minimum limit (layers) must be a positive value");
}*/
if (_minimumTransitionLayerCount > _maximumTransitionLayerCount)
{
sb.AppendLine("Minimum limit (layers) can't be higher than maximum limit (layers)");
}
return sb.ToString();
}
#endregion
#region Constructor
public SuggestionTransitionLayerCount()
{
_applyWhen = SuggestionApplyWhen.Different;
}
#endregion
#region Methods
protected override bool ExecuteInternally(OperationProgress progress)
{
SlicerFile.TransitionLayerCount = TransitionLayerCount;
return true;
}
#endregion
}