mirror of
https://github.com/riegera2412/UVtools.git
synced 2026-07-08 17:42:31 +02:00
2c7ad09dc0
- (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)
227 lines
9.4 KiB
C#
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
|
|
} |