- **Command line arguments:**
   - (Add) Convert files: UVtools.exe -c \<inputfile\> \<outputfile1/ext1\> [outputfile2/ext2]
   - (Add) Extract files: UVtools.exe -e \<inputfile\> [output_folder]
   - https://github.com/sn4k3/UVtools#command-line-arguments
- **File formats:**
   - (Add) Implement TSMC (Two Stage Motor Control) for the supported formats
   - (Add) Implement 'Bottom retract speed' for the supported formats
   - (Add) LGS: Support for lgs120 and lg4k (#218)
   - (Add) CTB: Special/virtual file extensions .v2.ctb, .v3.ctb, .v4.ctb to force a convertion to the set version (2 to 4). The .ctb is Version 3 by default when creating/converting files
   - (Improvement) Better performance for file formats that decode images in sequential pixels groups
- **GCode:**
  - (Improvement) Better parsing of the movements / lifts
  - (Improvement) Better handling of lifts performed after cure the layer
  - (Improvement) More fail-safe checks and sanitize of gcode while parsing
- (Improvement) CTBv3: Enable per layer settings if disabled when fast save without reencode
- (Upgrade) .NET from 5.0.8 to 5.0.9
- (Fix) PrusaSlicer printer: Longer Orange 4k with correct resolution and display size
- (Fix) Odd error when changing properties too fast in multi-thread
This commit is contained in:
Tiago Conceição
2021-08-12 23:19:47 +01:00
parent b8e05db113
commit 80a9adbcd0
39 changed files with 1965 additions and 376 deletions
+93 -76
View File
@@ -7,6 +7,7 @@
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
@@ -390,12 +391,12 @@ namespace UVtools.Core.GCode
AppendMoveG1(z, feedRate);
}
public void AppendLiftMoveGx(float upZ, float upFeedRate, float downZ, float downFeedRate, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
public void AppendLiftMoveGx(float upZ, float upFeedRate, float upZ2, float upFeedRate2, float downZ, float downFeedRate, float downZ2, float downFeedRate2, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
{
if (_layerMoveCommand == GCodeMoveCommands.G0)
AppendLiftMoveG0(upZ, upFeedRate, downZ, downFeedRate, waitAfterLift, waitAfterRetract, layer);
AppendLiftMoveG0(upZ, upFeedRate, upZ2, upFeedRate2, downZ, downFeedRate, downZ2, downFeedRate2, waitAfterLift, waitAfterRetract, layer);
else
AppendLiftMoveG1(upZ, upFeedRate, downZ, downFeedRate, waitAfterLift, waitAfterRetract, layer);
AppendLiftMoveG1(upZ, upFeedRate, upZ2, upFeedRate2, downZ, downFeedRate, downZ2, downFeedRate2, waitAfterLift, waitAfterRetract, layer);
}
@@ -405,14 +406,15 @@ namespace UVtools.Core.GCode
AppendLine(CommandMoveG0, z, feedRate);
}
public void AppendLiftMoveG0(float upZ, float upFeedRate, float downZ, float downFeedRate, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
public void AppendLiftMoveG0(float upZ, float upFeedRate, float upZ2 = 0, float upFeedRate2 = 0, float downZ = 0, float downFeedRate = 0, float downZ2 = 0, float downFeedRate2 = 0, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
{
if (upZ == 0 || upFeedRate <= 0) return;
AppendLineOverrideComment(CommandMoveG0, "Z Lift", upZ, upFeedRate); // Z Lift
if ((upZ == 0 || upFeedRate <= 0) && (upZ2 == 0 || upFeedRate2 <= 0)) return;
if(upZ > 0 && upFeedRate > 0) AppendLineOverrideComment(CommandMoveG0, "Z Lift", upZ, upFeedRate); // Z Lift
if(upZ2 > 0 && upFeedRate2 > 0) AppendLineOverrideComment(CommandMoveG0, "Z Lift (2)", upZ2, upFeedRate2); // Z Lift2
if (_syncMovementsWithDelay && layer is not null)
{
// Finish this
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.LiftHeight, layer.LiftSpeed, 0.75f);
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer, 0.75f);
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
@@ -422,13 +424,17 @@ namespace UVtools.Core.GCode
AppendWaitG4(waitAfterLift, "Wait after lift");
}
if (downZ != 0 && downFeedRate > 0)
if ((downZ != 0 && downFeedRate > 0) || (downZ2 != 0 && downFeedRate2 > 0))
{
AppendLineOverrideComment(CommandMoveG0, "Retract to layer height", downZ, downFeedRate);
if(downZ2 != 0 && downFeedRate2 > 0)
AppendLineOverrideComment(CommandMoveG0, "Retract (2)", downZ2, downFeedRate2);
if (downZ != 0 && downFeedRate > 0)
AppendLineOverrideComment(CommandMoveG0, "Retract to layer height", downZ, downFeedRate);
if (_syncMovementsWithDelay && layer is not null)
{
// Finish this
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.LiftHeight, layer.RetractSpeed, 0.75f);
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.RetractHeight, layer.RetractSpeed, layer.RetractHeight2, layer.RetractSpeed2, 0.75f);
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
@@ -446,19 +452,17 @@ namespace UVtools.Core.GCode
AppendLine(CommandMoveG1, z, feedRate);
}
public void AppendLiftMoveG1(float upZ, float upFeedRate, float downZ, float downFeedRate, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
public void AppendLiftMoveG1(float upZ, float upFeedRate, float upZ2 = 0, float upFeedRate2 = 0, float downZ = 0, float downFeedRate = 0, float downZ2 = 0, float downFeedRate2 = 0, float waitAfterLift = 0, float waitAfterRetract = 0, Layer layer = null)
{
if (upZ == 0 || upFeedRate <= 0) return;
AppendLineOverrideComment(CommandMoveG1, "Lift Z", upZ, upFeedRate); // Z Lift
if ((upZ == 0 || upFeedRate <= 0) && (upZ2 == 0 || upFeedRate2 <= 0)) return;
if (upZ > 0 && upFeedRate > 0) AppendLineOverrideComment(CommandMoveG1, "Z Lift", upZ, upFeedRate); // Z Lift
if (upZ2 > 0 && upFeedRate2 > 0) AppendLineOverrideComment(CommandMoveG1, "Z Lift (2)", upZ2, upFeedRate2); // Z Lift2
if (_syncMovementsWithDelay && layer is not null)
{
// Finish this
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.LiftHeight, layer.LiftSpeed, 0.75f);
if (seconds > layer.WaitTimeAfterLift) // Fix if wait time already include this
{
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer, 0.75f);
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
if (waitAfterLift > 0)
@@ -466,18 +470,19 @@ namespace UVtools.Core.GCode
AppendWaitG4(waitAfterLift, "Wait after lift");
}
if (downZ != 0 && downFeedRate > 0)
if ((downZ != 0 && downFeedRate > 0) || (downZ2 != 0 && downFeedRate2 > 0))
{
AppendLineOverrideComment(CommandMoveG1, "Retract to layer height", downZ, downFeedRate);
if (downZ2 != 0 && downFeedRate2 > 0)
AppendLineOverrideComment(CommandMoveG1, "Retract (2)", downZ2, downFeedRate2);
if (downZ != 0 && downFeedRate > 0)
AppendLineOverrideComment(CommandMoveG1, "Retract to layer height", downZ, downFeedRate);
if (_syncMovementsWithDelay && layer is not null)
{
// Finish this
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.LiftHeight, layer.RetractSpeed, 0.75f);
if (seconds > layer.WaitTimeBeforeCure) // Fix if wait time already include this
{
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
var seconds = OperationCalculator.LightOffDelayC.CalculateSecondsLiftOnly(layer.RetractHeight, layer.RetractSpeed, layer.RetractHeight2, layer.RetractSpeed2, 0.75f);
var time = ConvertFromSeconds(seconds);
AppendWaitG4($"0{time}", "Sync movement");
}
}
@@ -569,7 +574,7 @@ namespace UVtools.Core.GCode
float lastZPosition = 0;
// Defaults for: Absolute, mm/m and s
// Defaults for: Absolute, mm/min and s
for (uint layerIndex = 0; layerIndex < slicerFile.LayerCount; layerIndex++)
{
var layer = slicerFile[layerIndex];
@@ -578,23 +583,64 @@ namespace UVtools.Core.GCode
float exposureTime = ConvertFromSeconds(layer.ExposureTime);
float waitAfterCure = ConvertFromSeconds(layer.WaitTimeAfterCure);
float liftHeight = layer.LiftHeight;
float liftZPos = Layer.RoundHeight(liftHeight + layer.PositionZ);
float liftZPosAbs = liftZPos;
//float liftZPos = Layer.RoundHeight(liftHeight + layer.PositionZ);
//float liftZPosAbs = liftZPos;
float liftSpeed = ConvertFromMillimetersPerMinute(layer.LiftSpeed);
float liftHeight2 = layer.LiftHeight2;
float liftSpeed2 = ConvertFromMillimetersPerMinute(layer.LiftSpeed2);
float waitAfterLift = ConvertFromSeconds(layer.WaitTimeAfterLift);
float retractPos = layer.PositionZ;
float retractHeight = layer.RetractHeight;
float retractSpeed = ConvertFromMillimetersPerMinute(layer.RetractSpeed);
float retractHeight2 = layer.RetractHeight2;
float retractSpeed2 = ConvertFromMillimetersPerMinute(layer.RetractSpeed2);
float liftHeightTotal = layer.LiftHeightTotal;
ushort pwmValue = layer.LightPWM;
if (_maxLedPower != byte.MaxValue)
{
pwmValue = (ushort)(_maxLedPower * pwmValue / byte.MaxValue);
}
float liftPos = 0;
float liftPos2 = 0;
float retractPos = 0;
float retractPos2 = 0;
switch (GCodePositioningType)
{
case GCodePositioningTypes.Absolute:
var absLiftPos = Layer.RoundHeight(liftHeight + layer.PositionZ);
var absLiftPos2 = Layer.RoundHeight(absLiftPos + liftHeight2);
var absRetractPos2 = Layer.RoundHeight(absLiftPos2 - retractHeight2);
if (liftHeight > 0) liftPos = absLiftPos;
if (liftHeight2 > 0) liftPos2 = absLiftPos2;
if (retractHeight2 > 0) retractPos2 = absRetractPos2;
if (retractHeight > 0) retractPos = layer.PositionZ;
if (retractPos > 0 && retractPos > retractPos2) retractPos2 = 0; // Fail-safe
break;
case GCodePositioningTypes.Partial:
liftZPos = liftHeight;
retractPos = Layer.RoundHeight(layer.PositionZ - lastZPosition - liftHeight);
var partialLiftPos = Layer.RoundHeight(layer.PositionZ - lastZPosition + liftHeight);
var partialLiftPosTotal = Layer.RoundHeight(partialLiftPos + liftHeight2);
var partialRetractPosTotal = Layer.RoundHeight(partialLiftPos + liftHeight2);
if (liftHeight > 0)
{
liftPos = partialLiftPos;
if (liftHeight2 > 0) liftPos2 = liftHeight2;
}
else
{
if (liftHeight2 > 0) liftPos2 = Layer.RoundHeight(partialLiftPos + liftHeight2);
}
if (retractHeight2 > 0) retractPos2 = -retractHeight2;
if (retractHeight > 0) retractPos = -retractHeight;
// Assert
if (Layer.RoundHeight(Math.Abs(retractPos + retractPos2)) != liftHeightTotal) // Fail-safe
{
retractPos2 = 0;
retractPos = -liftHeightTotal;
}
break;
}
@@ -605,9 +651,9 @@ namespace UVtools.Core.GCode
AppendShowImageM6054(GetShowImageString(layerIndex));
//}
if (liftHeight > 0 && liftZPosAbs > layer.PositionZ)
if (liftHeightTotal > 0 && Layer.RoundHeight(liftHeightTotal + layer.PositionZ) > layer.PositionZ)
{
AppendLiftMoveGx(liftZPos, liftSpeed, retractPos, retractSpeed, waitAfterLift, 0, layer);
AppendLiftMoveGx(liftPos, liftSpeed, liftPos2, liftSpeed2, retractPos, retractSpeed, retractPos2, retractSpeed2, waitAfterLift, 0, layer);
}
else if (lastZPosition < layer.PositionZ) // Ensure Z is on correct position
{
@@ -759,10 +805,7 @@ namespace UVtools.Core.GCode
}
// Propagate values before switch to the new layer
layerBlock.PositionZ ??= positionZ;
layerBlock.SetLayer();
layerBlock.Init();
layerBlock.SetLayer(true);
layerBlock.LayerIndex = layerIndex;
continue;
@@ -782,12 +825,16 @@ namespace UVtools.Core.GCode
RegexOptions.IgnoreCase);
match = moveG0Regex.Success && moveG0Regex.Groups.Count >= 2 ? moveG0Regex : moveG1Regex;
if (match.Success && match.Groups.Count >= 4 && !layerBlock.RetractSpeed.HasValue)
if (match.Success && match.Groups.Count >= 4 && !layerBlock.RetractSpeed2.HasValue && layerBlock.LightOffCount < 2)
{
float pos = float.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
float speed = ConvertToMillimetersPerMinute(float.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture));
if (!layerBlock.PositionZ.HasValue) // Lift or pos, set here for now
layerBlock.Movements.Add(new(pos, speed));
layerBlock.AssignMovements(positionType);
/*if (!layerBlock.PositionZ.HasValue) // Lift or pos, set here for now
{
switch (positionType)
{
@@ -817,7 +864,7 @@ namespace UVtools.Core.GCode
layerBlock.LiftHeight = layerBlock.PositionZ - positionZ;
layerBlock.PositionZ = positionZ = Layer.RoundHeight(layerBlock.PositionZ.Value + pos);
break;
}
}*/
continue;
}
@@ -897,7 +944,7 @@ namespace UVtools.Core.GCode
if (pwm == 0 && layerBlock.LightPWM.HasValue)
{
layerBlock.IsAfterLightOff = true;
layerBlock.LightOffCount++;
}
else if (!layerBlock.IsAfterLightOff)
{
@@ -910,7 +957,6 @@ namespace UVtools.Core.GCode
}
// Propagate values of left over layer
layerBlock.PositionZ ??= positionZ;
layerBlock.SetLayer();
@@ -1016,36 +1062,7 @@ namespace UVtools.Core.GCode
if (rebuildGlobalTable)
{
slicerFile.SuppressRebuildPropertiesWork(() =>
{
var bottomLayer = slicerFile.FirstLayer;
if (bottomLayer is not null)
{
if (bottomLayer.LightOffDelay > 0) slicerFile.BottomLightOffDelay = bottomLayer.LightOffDelay;
if (bottomLayer.WaitTimeBeforeCure > 0) slicerFile.BottomWaitTimeBeforeCure = bottomLayer.WaitTimeBeforeCure;
if (bottomLayer.ExposureTime > 0) slicerFile.BottomExposureTime = bottomLayer.ExposureTime;
if (bottomLayer.WaitTimeAfterCure > 0) slicerFile.BottomWaitTimeAfterCure = bottomLayer.WaitTimeAfterCure;
if (bottomLayer.LiftHeight > 0) slicerFile.BottomLiftHeight = bottomLayer.LiftHeight;
if (bottomLayer.LiftSpeed > 0) slicerFile.BottomLiftSpeed = bottomLayer.LiftSpeed;
if (bottomLayer.WaitTimeAfterLift > 0) slicerFile.BottomWaitTimeAfterLift = bottomLayer.WaitTimeAfterLift;
if (bottomLayer.RetractSpeed > 0) slicerFile.RetractSpeed = bottomLayer.RetractSpeed;
if (bottomLayer.LightPWM > 0) slicerFile.BottomLightPWM = bottomLayer.LightPWM;
}
var normalLayer = slicerFile.LastLayer;
if (normalLayer is not null)
{
if (normalLayer.LightOffDelay > 0) slicerFile.LightOffDelay = normalLayer.LightOffDelay;
if (normalLayer.WaitTimeBeforeCure > 0) slicerFile.WaitTimeBeforeCure = normalLayer.WaitTimeBeforeCure;
if (normalLayer.ExposureTime > 0) slicerFile.ExposureTime = normalLayer.ExposureTime;
if (normalLayer.WaitTimeAfterCure > 0) slicerFile.WaitTimeAfterCure = normalLayer.WaitTimeAfterCure;
if (normalLayer.LiftHeight > 0) slicerFile.LiftHeight = normalLayer.LiftHeight;
if (normalLayer.LiftSpeed > 0) slicerFile.LiftSpeed = normalLayer.LiftSpeed;
if (normalLayer.WaitTimeAfterLift > 0) slicerFile.WaitTimeAfterLift = normalLayer.WaitTimeAfterLift;
if (normalLayer.RetractSpeed > 0) slicerFile.RetractSpeed = normalLayer.RetractSpeed;
if (normalLayer.LightPWM > 0) slicerFile.LightPWM = normalLayer.LightPWM;
}
});
slicerFile.UpdateGlobalPropertiesFromLayers();
}
}
+156 -8
View File
@@ -7,6 +7,7 @@
*/
using System;
using System.Collections.Generic;
using UVtools.Core.FileFormats;
using UVtools.Core.Operations;
@@ -14,13 +15,18 @@ namespace UVtools.Core.GCode
{
public class GCodeLayer
{
private float? _positionZ;
private float? _waitTimeBeforeCure;
private float? _exposureTime;
private float? _waitTimeAfterCure;
private float? _liftHeight;
private float? _liftSpeed;
private float? _liftHeight2;
private float? _liftSpeed2;
private float? _waitTimeAfterLift;
private float? _retractSpeed;
private float? _retractHeight2;
private float? _retractSpeed2;
public enum GCodeLastParsedLine : byte
{
@@ -30,8 +36,16 @@ namespace UVtools.Core.GCode
public bool IsValid => LayerIndex.HasValue;
public FileFormat SlicerFile { get; }
public List<(float Pos, float Speed)> Movements = new();
public uint? LayerIndex { get; set; }
public float? PositionZ { get; set; }
public float? PositionZ
{
get => _positionZ;
set => _positionZ = value;
}
public float PreviousPositionZ { get; set; }
public float? WaitTimeBeforeCure
{
@@ -54,7 +68,7 @@ namespace UVtools.Core.GCode
public float? LiftHeight
{
get => _liftHeight;
set => _liftHeight = value is null ? null : (float)Math.Round(value.Value, 2);
set => _liftHeight = value is null ? null : Layer.RoundHeight(value.Value);
}
public float? LiftSpeed
@@ -63,6 +77,20 @@ namespace UVtools.Core.GCode
set => _liftSpeed = value is null ? null : (float)Math.Round(value.Value, 2);
}
public float LiftHeightTotal => Layer.RoundHeight((LiftHeight ?? 0) + (LiftHeight2 ?? 0));
public float? LiftHeight2
{
get => _liftHeight2;
set => _liftHeight2 = value is null ? null : Layer.RoundHeight(value.Value);
}
public float? LiftSpeed2
{
get => _liftSpeed2;
set => _liftSpeed2 = value is null ? null : (float)Math.Round(value.Value, 2);
}
public float? WaitTimeAfterLift
{
get => _waitTimeAfterLift;
@@ -75,11 +103,25 @@ namespace UVtools.Core.GCode
set => _retractSpeed = value is null ? null : (float)Math.Round(value.Value, 2);
}
public float? RetractHeight2
{
get => _retractHeight2;
set => _retractHeight2 = value is null ? null : Layer.RoundHeight(value.Value);
}
public float? RetractSpeed2
{
get => _retractSpeed2;
set => _retractSpeed2 = value is null ? null : (float)Math.Round(value.Value, 2);
}
public byte? LightPWM { get; set; }
public bool IsExposing => LightPWM.HasValue && !IsAfterLightOff;
public bool IsExposed => LightPWM.HasValue && IsAfterLightOff;
public bool IsAfterLightOff { get; set; }
public byte LightOffCount { get; set; }
public bool IsAfterLightOff => LightOffCount > 0;
public GCodeLayer(FileFormat slicerFile)
{
@@ -88,6 +130,9 @@ namespace UVtools.Core.GCode
public void Init()
{
PreviousPositionZ = PositionZ ?? 0;
Movements.Clear();
LayerIndex = null;
PositionZ = null;
WaitTimeBeforeCure = null;
@@ -95,39 +140,142 @@ namespace UVtools.Core.GCode
WaitTimeAfterCure = null;
LiftHeight = null;
LiftSpeed = null;
LiftHeight2 = null;
LiftSpeed2 = null;
WaitTimeAfterLift = null;
RetractSpeed = null;
RetractHeight2 = null;
RetractSpeed2 = null;
LightPWM = null;
IsAfterLightOff = false;
LightOffCount = 0;
}
public void AssignMovements(GCodeBuilder.GCodePositioningTypes positionType)
{
if (Movements.Count == 0) return;
var currentZ = PreviousPositionZ;
PositionZ = null;
LiftHeight = null;
LiftSpeed = null;
LiftHeight2 = null;
LiftSpeed2 = null;
RetractSpeed = null;
RetractHeight2 = null;
RetractSpeed2 = null;
for (int i = 0; i < Movements.Count; i++)
{
var (pos, speed) = Movements[i];
float heightRaw;
switch (positionType)
{
case GCodeBuilder.GCodePositioningTypes.Absolute:
heightRaw = Layer.RoundHeight(pos - currentZ);
currentZ = pos;
break;
case GCodeBuilder.GCodePositioningTypes.Partial:
heightRaw = pos;
currentZ = Layer.RoundHeight(currentZ + pos);
break;
default:
throw new ArgumentOutOfRangeException(nameof(positionType));
}
// Fail-safe check
if (currentZ < PreviousPositionZ)
throw new NotSupportedException("GCode parsing error: Attempting to crash the print on the LCD with negative position.\n" +
"Do not attempt to print this file!");
// Is position Z
if (i == Movements.Count - 1)
{
PositionZ = currentZ;
if (LiftHeight.HasValue) RetractSpeed = speed; // A lift exists, set to retract speed of this move
continue;
}
if (heightRaw == 0) continue;
var height = Math.Abs(heightRaw);
if (heightRaw > 0) // Is a lift
{
if (!LiftHeight.HasValue)
{
LiftHeight = height;
LiftSpeed = speed;
continue;
}
LiftHeight2 ??= 0;
LiftHeight2 += height;
LiftSpeed2 = speed;
continue;
}
if(!LiftHeight.HasValue) continue; // Fail-safe: Retract without a lift? Skip
// Is a extra retract (2)
RetractHeight2 ??= 0;
RetractHeight2 += height;
RetractSpeed2 = speed;
}
if (Movements.Count == 1) // Only 1 move, this is the PositionZ only
{
LiftSpeed = Movements[0].Speed;
return;
}
// Sanitize
if (PositionZ.HasValue && LiftHeight.HasValue && !IsExposed) // Lift before exposure order, need to remove layer height as offset
{
var liftHeight = Layer.RoundHeight(LiftHeight.Value - (PositionZ.Value - PreviousPositionZ));
if(liftHeight <= 0) return; // Something not right or not the correct moment, skip
LiftHeight = liftHeight;
}
if (LiftHeight.HasValue && RetractHeight2.HasValue) // Sanitize RetractHeight2 value
{
RetractHeight2 = Math.Clamp(RetractHeight2.Value, 0, LiftHeightTotal);
}
}
/// <summary>
/// Set gathered data to the layer
/// </summary>
public void SetLayer()
public void SetLayer(bool reinit = false)
{
if (!IsValid) return;
uint layerIndex = LayerIndex.Value;
var layer = SlicerFile[layerIndex];
if(PositionZ.HasValue) layer.PositionZ = PositionZ.Value;
if (!PositionZ.HasValue) PositionZ = PreviousPositionZ;
layer.PositionZ = PositionZ.Value;
layer.WaitTimeBeforeCure = WaitTimeBeforeCure ?? 0;
layer.ExposureTime = ExposureTime ?? SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomExposureTime, SlicerFile.ExposureTime);
layer.WaitTimeAfterCure = WaitTimeAfterCure ?? 0;
layer.LiftHeight = LiftHeight ?? 0;
layer.LiftSpeed = LiftSpeed ?? SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomLiftSpeed, SlicerFile.LiftSpeed);
layer.LiftHeight2 = LiftHeight2 ?? 0;
layer.LiftSpeed2 = LiftSpeed2 ?? SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomLiftSpeed2, SlicerFile.LiftSpeed2);
layer.WaitTimeAfterLift = WaitTimeAfterLift ?? 0;
layer.RetractSpeed = RetractSpeed ?? SlicerFile.RetractSpeed;
layer.RetractSpeed = RetractSpeed ?? SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomRetractSpeed, SlicerFile.RetractSpeed);
layer.RetractHeight2 = RetractHeight2 ?? 0;
layer.RetractSpeed2 = RetractSpeed2 ?? SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomRetractSpeed2, SlicerFile.RetractSpeed2);
layer.LightPWM = LightPWM ?? 0;//SlicerFile.GetInitialLayerValueOrNormal(layerIndex, SlicerFile.BottomLightPWM, SlicerFile.LightPWM);
if (SlicerFile.GCode.SyncMovementsWithDelay) // Dirty fix of the value
{
var syncTime = OperationCalculator.LightOffDelayC.CalculateSeconds(layer.LiftHeight, layer.LiftSpeed, layer.RetractSpeed, 1.5f);
var syncTime = OperationCalculator.LightOffDelayC.CalculateSeconds(layer, 1.5f);
if (syncTime < layer.WaitTimeBeforeCure)
{
layer.WaitTimeBeforeCure = (float) Math.Round(layer.WaitTimeBeforeCure - syncTime, 2);
}
}
if(reinit) Init();
}
}
}