diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-07-12 04:01:02 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-07-12 04:01:02 +0300 |
commit | c289954753cb790836709fcdb5979606d1bc0c7e (patch) | |
tree | fea6c90f03a0c8b6e08eefe4ad8f515a48f043bc | |
parent | 683a6f4fb4ba0942cb141245c7eff8afb7e43cea (diff) |
v2.14.3v2.14.3
- (Add) Exposure time finder: Base layers print modes, a option to speed up the print process and merge all base layers in the same height
- (Add) GCode tab: Allow to temporarily edit and use custom gcode
- (Change) Zcode: Omit M18 at end of the gcode to prevent carrier goes up and crash to the limit at a end of a print
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CHANGELOG.md | 12 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/FileFormat.cs | 30 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/ZCodeFile.cs | 4 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationCalibrateExposureFinder.cs | 166 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 2 | ||||
-rw-r--r-- | UVtools.ScriptSample/ScriptCustomGCode.cs | 20 | ||||
-rw-r--r-- | UVtools.WPF/Assets/Icons/pencil-alt-16x16.png | bin | 0 -> 177 bytes | |||
-rw-r--r-- | UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml | 38 | ||||
-rw-r--r-- | UVtools.WPF/MainWindow.GCode.cs | 7 | ||||
-rw-r--r-- | UVtools.WPF/MainWindow.axaml | 16 | ||||
-rw-r--r-- | UVtools.WPF/UVtools.WPF.csproj | 2 | ||||
-rw-r--r-- | build/CreateRelease.WPF.ps1 | 6 |
13 files changed, 223 insertions, 81 deletions
@@ -359,3 +359,4 @@ UVtools.Platforms/arch-x64/libcvextern.so build/nuget_api.key build/*.key + diff --git a/CHANGELOG.md b/CHANGELOG.md index 69d5756..f6e184c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog -## 11/06/2021 - v2.14.2 +## 12/07/2021 - v2.14.3 + +- (Add) Exposure time finder: Base layers print modes, a option to speed up the print process and merge all base layers in the same height +- (Add) GCode tab: Allow to temporarily edit and use custom gcode +- (Change) Zcode: Omit M18 at end of the gcode to prevent carrier goes up and crash to the limit at a end of a print + +## 11/07/2021 - v2.14.2 - **Exposure time finder:** - (Add) [ME] Option: 'Use different settings for layers with same Z positioning' @@ -17,7 +23,7 @@ - (Add) UVtools version to error logs - (Fix) ZCode: Some test files come with layer height of 0mm on a property, in that case lookup layer height on the second property as fallback -## 07/06/2021 - v2.14.1 +## 07/07/2021 - v2.14.1 - (Upgrade) EmguCV from 4.5.1 to 4.5.2 - **File formats:** @@ -32,7 +38,7 @@ - (Fix) UVJ: Error when using a null or empty layer array on manifest `config.json` file (#232) - (Fix) GCode parser: When only a G4/wait command is present on a layer it was setting the global exposure time and discard the this value per layer -## 03/06/2021 - v2.14.0 +## 03/07/2021 - v2.14.0 - **File Formats:** - (Add) SL1S: Prusa SL1S Speed diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 3b271b8..53ac4c2 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -353,6 +353,7 @@ namespace UVtools.Core.FileFormats private string _materialName; private float _materialGrams; private float _materialCost; + private bool _suppressRebuildGCode; #endregion @@ -527,6 +528,11 @@ namespace UVtools.Core.FileFormats public Layer FirstLayer => _layerManager?.FirstLayer; /// <summary> + /// Gets the first layer normal layer + /// </summary> + public Layer FirstNormalLayer => _layerManager?.Layers.FirstOrDefault(layer => layer.IsNormalLayer); + + /// <summary> /// Gets the last layer /// </summary> public Layer LastLayer => _layerManager?.LastLayer; @@ -1204,7 +1210,20 @@ namespace UVtools.Core.FileFormats /// <summary> /// Gets the GCode, returns null if not supported /// </summary> - public string GCodeStr => GCode?.ToString(); + public string GCodeStr + { + get => GCode?.ToString(); + set + { + GCode.Clear(); + if (!string.IsNullOrWhiteSpace(value)) + { + GCode.Append(value); + } + RaisePropertyChanged(); + + } + } /// <summary> /// Gets if this file format supports gcode @@ -1219,7 +1238,11 @@ namespace UVtools.Core.FileFormats /// <summary> /// Disable or enable the gcode auto rebuild when needed, set this to false to manually write your own gcode /// </summary> - public bool SuppressRebuildGCode { get; set; } + public bool SuppressRebuildGCode + { + get => _suppressRebuildGCode; + set => RaiseAndSetIfChanged(ref _suppressRebuildGCode, value); + } /// <summary> /// Get all configuration objects with properties and values @@ -2029,8 +2052,9 @@ namespace UVtools.Core.FileFormats /// </summary> public virtual void RebuildGCode() { - if (!SupportsGCode || SuppressRebuildGCode) return; + if (!SupportsGCode || _suppressRebuildGCode) return; GCode.RebuildGCode(this); + RaisePropertyChanged(nameof(GCodeStr)); } /// <summary> diff --git a/UVtools.Core/FileFormats/ZCodeFile.cs b/UVtools.Core/FileFormats/ZCodeFile.cs index 417ecc1..b02e816 100644 --- a/UVtools.Core/FileFormats/ZCodeFile.cs +++ b/UVtools.Core/FileFormats/ZCodeFile.cs @@ -16,7 +16,6 @@ using System.Text; using System.Xml.Serialization; using Emgu.CV; using Emgu.CV.CvEnum; -using Emgu.CV.Util; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.OpenSsl; @@ -435,7 +434,8 @@ namespace UVtools.Core.FileFormats GCodeTimeUnit = GCodeBuilder.GCodeTimeUnits.Milliseconds, GCodeShowImageType = GCodeBuilder.GCodeShowImageTypes.FilenameNonZeroPNG, MaxLEDPower = MaxLEDPower, - CommandClearImage = {Enabled = false} + CommandClearImage = {Enabled = false}, + CommandMotorsOffM18 = {Enabled = false}, }; } #endregion diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs index 72ba3d7..f24a6fe 100644 --- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs +++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Drawing; using System.Linq; using System.Text; @@ -28,6 +29,57 @@ namespace UVtools.Core.Operations [Serializable] public sealed class OperationCalibrateExposureFinder : Operation { + #region Enums + public enum CalibrateExposureFinderShapes : byte + { + Square, + Circle + } + public static Array ShapesItems => Enum.GetValues(typeof(CalibrateExposureFinderShapes)); + + public enum CalibrateExposureFinderMeasures : byte + { + Pixels, + Millimeters, + } + + public static Array MeasuresItems => Enum.GetValues(typeof(CalibrateExposureFinderMeasures)); + + public enum CalibrateExposureFinderMultipleBrightnessExcludeFrom : byte + { + None, + Bottom, + BottomAndBase + } + public static Array MultipleBrightnessExcludeFromItems => Enum.GetValues(typeof(CalibrateExposureFinderMultipleBrightnessExcludeFrom)); + + public enum CalibrateExposureFinderExposureGenTypes : byte + { + Linear, + Multiplier + } + + public static Array ExposureGenTypeItems => Enum.GetValues(typeof(CalibrateExposureFinderExposureGenTypes)); + + public enum CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes : byte + { + [Description("Iterative exposure: Print each base layer at it own exposure time")] + Iterative, + + [Description("Lowest exposure: Base layers will print at the lowest defined exposure time")] + UseLowest, + + [Description("Middle exposure: Base layers will print at the middle defined exposure time")] + UseMiddle, + + [Description("Highest exposure: Base layers will print at the highest defined exposure time")] + UseHighest, + + [Description("Custom exposure: Base layers will print at a custom defined exposure time")] + Custom + } + #endregion + #region Subclasses public sealed class BullsEyeCircle @@ -80,7 +132,7 @@ namespace UVtools.Core.Operations private bool _holesEnabled = false; private CalibrateExposureFinderShapes _holeShape = CalibrateExposureFinderShapes.Square; - private Measures _unitOfMeasure = Measures.Pixels; + private CalibrateExposureFinderMeasures _unitOfMeasure = CalibrateExposureFinderMeasures.Pixels; private string _holeDiametersPx = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11"; private string _holeDiametersMm = "0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2"; @@ -110,13 +162,15 @@ namespace UVtools.Core.Operations private decimal _multipleLayerHeightMaximum = 0.1m; private decimal _multipleLayerHeightStep = 0.01m; + private CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes _multipleExposuresBaseLayersPrintMode; + private decimal _multipleExposuresBaseLayersCustomExposure; private bool _differentSettingsForSamePositionedLayers; private bool _samePositionedLayersLiftHeightEnabled = true; private decimal _samePositionedLayersLiftHeight; private bool _samePositionedLayersLightOffDelayEnabled = true; private decimal _samePositionedLayersLightOffDelay; private bool _multipleExposures; - private ExposureGenTypes _exposureGenType = ExposureGenTypes.Linear; + private CalibrateExposureFinderExposureGenTypes _exposureGenType = CalibrateExposureFinderExposureGenTypes.Linear; private bool _exposureGenIgnoreBaseExposure; private decimal _exposureGenBottomStep = 0; private decimal _exposureGenNormalStep = 0.2m; @@ -139,6 +193,7 @@ namespace UVtools.Core.Operations private byte _bullsEyeFenceThickness = 10; private sbyte _bullsEyeFenceOffset; private bool _patternModelGlueBottomLayers = true; + #endregion #region Overrides @@ -466,7 +521,7 @@ namespace UVtools.Core.Operations set => RaiseAndSetIfChanged(ref _holeShape, value); } - public Measures UnitOfMeasure + public CalibrateExposureFinderMeasures UnitOfMeasure { get => _unitOfMeasure; set @@ -476,7 +531,7 @@ namespace UVtools.Core.Operations } } - public bool IsUnitOfMeasureMm => _unitOfMeasure == Measures.Millimeters; + public bool IsUnitOfMeasureMm => _unitOfMeasure == CalibrateExposureFinderMeasures.Millimeters; public string HoleDiametersMm { @@ -504,7 +559,7 @@ namespace UVtools.Core.Operations List<int> holes = new(); - if (_unitOfMeasure == Measures.Millimeters) + if (_unitOfMeasure == CalibrateExposureFinderMeasures.Millimeters) { var split = _holeDiametersMm.Split(',', StringSplitOptions.TrimEntries); foreach (var mmStr in split) @@ -602,7 +657,7 @@ namespace UVtools.Core.Operations List<int> bars = new(); - if (_unitOfMeasure == Measures.Millimeters) + if (_unitOfMeasure == CalibrateExposureFinderMeasures.Millimeters) { var split = _barThicknessesMm.Split(',', StringSplitOptions.TrimEntries); foreach (var mmStr in split) @@ -805,6 +860,24 @@ namespace UVtools.Core.Operations } } + public CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes MultipleExposuresBaseLayersPrintMode + { + get => _multipleExposuresBaseLayersPrintMode; + set + { + if(!RaiseAndSetIfChanged(ref _multipleExposuresBaseLayersPrintMode, value)) return; + RaisePropertyChanged(nameof(IsMultipleExposuresBaseLayersPrintModeCustom)); + } + } + + public bool IsMultipleExposuresBaseLayersPrintModeCustom => _multipleExposuresBaseLayersPrintMode == CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.Custom; + + public decimal MultipleExposuresBaseLayersCustomExposure + { + get => _multipleExposuresBaseLayersCustomExposure; + set => RaiseAndSetIfChanged(ref _multipleExposuresBaseLayersCustomExposure, value); + } + public bool DifferentSettingsForSamePositionedLayers { get => _differentSettingsForSamePositionedLayers; @@ -841,7 +914,7 @@ namespace UVtools.Core.Operations set => RaiseAndSetIfChanged(ref _multipleExposures, value); } - public ExposureGenTypes ExposureGenType + public CalibrateExposureFinderExposureGenTypes ExposureGenType { get => _exposureGenType; set => RaiseAndSetIfChanged(ref _exposureGenType, value); @@ -963,7 +1036,7 @@ namespace UVtools.Core.Operations List<BullsEyeCircle> bulleyes = new(); - if (_unitOfMeasure == Measures.Millimeters) + if (_unitOfMeasure == CalibrateExposureFinderMeasures.Millimeters) { var splitGroup = _bullsEyeConfigurationMm.Split(',', StringSplitOptions.TrimEntries); foreach (var group in splitGroup) @@ -1082,7 +1155,7 @@ namespace UVtools.Core.Operations if(_bottomLayers <= 0) _bottomLayers = SlicerFile.BottomLayerCount; if(_bottomExposure <= 0) _bottomExposure = (decimal)SlicerFile.BottomExposureTime; if(_normalExposure <= 0) _normalExposure = (decimal)SlicerFile.ExposureTime; - + if (_exposureGenManualBottom == 0) _exposureGenManualBottom = (decimal) SlicerFile.BottomExposureTime; if (_exposureGenManualNormal == 0) @@ -1090,6 +1163,8 @@ namespace UVtools.Core.Operations if (_multipleBrightnessGenExposureTime == 0) _multipleBrightnessGenExposureTime = (decimal)SlicerFile.ExposureTime; + if (_multipleExposuresBaseLayersCustomExposure <= 0) _multipleExposuresBaseLayersCustomExposure = (decimal)SlicerFile.ExposureTime; + if (!SlicerFile.HaveLayerParameterModifier(FileFormat.PrintParameterModifier.ExposureSeconds)) { _multipleLayerHeight = false; @@ -1107,45 +1182,11 @@ namespace UVtools.Core.Operations #endregion - #region Enums - - public enum CalibrateExposureFinderShapes : byte - { - Square, - Circle - } - public static Array ShapesItems => Enum.GetValues(typeof(CalibrateExposureFinderShapes)); - - public enum Measures : byte - { - Pixels, - Millimeters, - } - - public static Array MeasuresItems => Enum.GetValues(typeof(Measures)); - - public enum CalibrateExposureFinderMultipleBrightnessExcludeFrom : byte - { - None, - Bottom, - BottomAndBase - } - public static Array MultipleBrightnessExcludeFromItems => Enum.GetValues(typeof(CalibrateExposureFinderMultipleBrightnessExcludeFrom)); - - public enum ExposureGenTypes : byte - { - Linear, - Multiplier - } - - public static Array ExposureGenTypeItems => Enum.GetValues(typeof(ExposureGenTypes)); - #endregion - #region Equality - + private bool Equals(OperationCalibrateExposureFinder other) { - return _displayWidth == other._displayWidth && _displayHeight == other._displayHeight && _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _staircaseThickness == other._staircaseThickness && _holesEnabled == other._holesEnabled && _holeShape == other._holeShape && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barsEnabled == other._barsEnabled && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barFenceThickness == other._barFenceThickness && _barFenceOffset == other._barFenceOffset && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textEnabled == other._textEnabled && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _multipleBrightnessGenExposureTime == other._multipleBrightnessGenExposureTime && _multipleBrightnessGenEmulatedAALevel == other._multipleBrightnessGenEmulatedAALevel && _multipleBrightnessGenExposureFractions == other._multipleBrightnessGenExposureFractions && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _differentSettingsForSamePositionedLayers == other._differentSettingsForSamePositionedLayers && _samePositionedLayersLiftHeightEnabled == other._samePositionedLayersLiftHeightEnabled && _samePositionedLayersLiftHeight == other._samePositionedLayersLiftHeight && _samePositionedLayersLightOffDelayEnabled == other._samePositionedLayersLightOffDelayEnabled && _samePositionedLayersLightOffDelay == other._samePositionedLayersLightOffDelay && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && _exposureGenManualLayerHeight == other._exposureGenManualLayerHeight && _exposureGenManualBottom == other._exposureGenManualBottom && _exposureGenManualNormal == other._exposureGenManualNormal && Equals(_exposureTable, other._exposureTable) && _bullsEyeEnabled == other._bullsEyeEnabled && _bullsEyeConfigurationPx == other._bullsEyeConfigurationPx && _bullsEyeConfigurationMm == other._bullsEyeConfigurationMm && _bullsEyeInvertQuadrants == other._bullsEyeInvertQuadrants && _counterTrianglesEnabled == other._counterTrianglesEnabled && _counterTrianglesTipOffset == other._counterTrianglesTipOffset && _counterTrianglesFence == other._counterTrianglesFence && _patternModel == other._patternModel && _bullsEyeFenceThickness == other._bullsEyeFenceThickness && _bullsEyeFenceOffset == other._bullsEyeFenceOffset && _patternModelGlueBottomLayers == other._patternModelGlueBottomLayers; + return _displayWidth == other._displayWidth && _displayHeight == other._displayHeight && _layerHeight == other._layerHeight && _bottomLayers == other._bottomLayers && _bottomExposure == other._bottomExposure && _normalExposure == other._normalExposure && _topBottomMargin == other._topBottomMargin && _leftRightMargin == other._leftRightMargin && _chamferLayers == other._chamferLayers && _erodeBottomIterations == other._erodeBottomIterations && _partMargin == other._partMargin && _enableAntiAliasing == other._enableAntiAliasing && _mirrorOutput == other._mirrorOutput && _baseHeight == other._baseHeight && _featuresHeight == other._featuresHeight && _featuresMargin == other._featuresMargin && _staircaseThickness == other._staircaseThickness && _holesEnabled == other._holesEnabled && _holeShape == other._holeShape && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barsEnabled == other._barsEnabled && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barFenceThickness == other._barFenceThickness && _barFenceOffset == other._barFenceOffset && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textEnabled == other._textEnabled && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _multipleBrightnessGenExposureTime == other._multipleBrightnessGenExposureTime && _multipleBrightnessGenEmulatedAALevel == other._multipleBrightnessGenEmulatedAALevel && _multipleBrightnessGenExposureFractions == other._multipleBrightnessGenExposureFractions && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposuresBaseLayersPrintMode == other._multipleExposuresBaseLayersPrintMode && _multipleExposuresBaseLayersCustomExposure == other._multipleExposuresBaseLayersCustomExposure && _differentSettingsForSamePositionedLayers == other._differentSettingsForSamePositionedLayers && _samePositionedLayersLiftHeightEnabled == other._samePositionedLayersLiftHeightEnabled && _samePositionedLayersLiftHeight == other._samePositionedLayersLiftHeight && _samePositionedLayersLightOffDelayEnabled == other._samePositionedLayersLightOffDelayEnabled && _samePositionedLayersLightOffDelay == other._samePositionedLayersLightOffDelay && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && _exposureGenManualLayerHeight == other._exposureGenManualLayerHeight && _exposureGenManualBottom == other._exposureGenManualBottom && _exposureGenManualNormal == other._exposureGenManualNormal && Equals(_exposureTable, other._exposureTable) && _bullsEyeEnabled == other._bullsEyeEnabled && _bullsEyeConfigurationPx == other._bullsEyeConfigurationPx && _bullsEyeConfigurationMm == other._bullsEyeConfigurationMm && _bullsEyeInvertQuadrants == other._bullsEyeInvertQuadrants && _counterTrianglesEnabled == other._counterTrianglesEnabled && _counterTrianglesTipOffset == other._counterTrianglesTipOffset && _counterTrianglesFence == other._counterTrianglesFence && _patternModel == other._patternModel && _bullsEyeFenceThickness == other._bullsEyeFenceThickness && _bullsEyeFenceOffset == other._bullsEyeFenceOffset && _patternModelGlueBottomLayers == other._patternModelGlueBottomLayers; } public override bool Equals(object obj) @@ -1200,6 +1241,8 @@ namespace UVtools.Core.Operations hashCode.Add(_multipleLayerHeight); hashCode.Add(_multipleLayerHeightMaximum); hashCode.Add(_multipleLayerHeightStep); + hashCode.Add((int) _multipleExposuresBaseLayersPrintMode); + hashCode.Add(_multipleExposuresBaseLayersCustomExposure); hashCode.Add(_differentSettingsForSamePositionedLayers); hashCode.Add(_samePositionedLayersLiftHeightEnabled); hashCode.Add(_samePositionedLayersLiftHeight); @@ -1282,11 +1325,11 @@ namespace UVtools.Core.Operations switch (_exposureGenType) { - case ExposureGenTypes.Linear: + case CalibrateExposureFinderExposureGenTypes.Linear: bottomExposureTime = _bottomExposure + _exposureGenBottomStep * testN; exposureTime = _normalExposure + _exposureGenNormalStep * testN; break; - case ExposureGenTypes.Multiplier: + case CalibrateExposureFinderExposureGenTypes.Multiplier: bottomExposureTime = _bottomExposure + _bottomExposure * layerHeight * _exposureGenBottomStep * testN; exposureTime = _normalExposure + _normalExposure * layerHeight * _exposureGenNormalStep * testN; break; @@ -1986,7 +2029,10 @@ namespace UVtools.Core.Operations lastExposureItem is not null && lastcurrentHeight == currentHeight && lastExposureItem.LayerHeight == layerHeight && - (isBottomLayer && lastExposureItem.BottomExposure == bottomExposure || !isBottomLayer && lastExposureItem.Exposure == normalExposure); + ( + (isBottomLayer && lastExposureItem.BottomExposure == bottomExposure || !isBottomLayer && lastExposureItem.Exposure == normalExposure) || + (!isBottomLayer && isBaseLayer && _multipleExposuresBaseLayersPrintMode != CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.Iterative) + ); using var mat = reUseLastLayer ? newLayers[^1].LayerMat : EmguExtensions.InitMat(SlicerFile.Resolution); @@ -2098,7 +2144,29 @@ namespace UVtools.Core.Operations if (reUseLastLayer) { - newLayers[^1].LayerMat = mat; + var layer = newLayers[^1]; + layer.LayerMat = mat; + + if (!isBottomLayer && isBaseLayer) + { + switch (_multipleExposuresBaseLayersPrintMode) + { + case CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.UseLowest: + layer.ExposureTime = (float)_exposureTable[0].Exposure; + break; + case CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.UseMiddle: + layer.ExposureTime = (float)_exposureTable[(int)Math.Ceiling((_exposureTable.Count - 1) / 2.0)].Exposure; + break; + case CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.UseHighest: + layer.ExposureTime = (float)_exposureTable[^1].Exposure; + break; + case CalibrateExposureFinderMultipleExposuresBaseLayersPrintModes.Custom: + layer.ExposureTime = (float)_multipleExposuresBaseLayersCustomExposure; + break; + default: + throw new ArgumentOutOfRangeException($"Unhandled type for {_multipleExposuresBaseLayersCustomExposure}"); + } + } } else { diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 0f89f35..30fcd60 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -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>2.14.2</Version> + <Version>2.14.3</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> diff --git a/UVtools.ScriptSample/ScriptCustomGCode.cs b/UVtools.ScriptSample/ScriptCustomGCode.cs index c5e7565..5d33cb3 100644 --- a/UVtools.ScriptSample/ScriptCustomGCode.cs +++ b/UVtools.ScriptSample/ScriptCustomGCode.cs @@ -74,7 +74,7 @@ namespace UVtools.ScriptSample }*/ // 0.01 test - gcode.AppendComment("0.01 layer height simulated print test"); + /*gcode.AppendComment("0.01 layer height simulated print test"); pos = 1; layerHeight = 0.01f; @@ -86,7 +86,7 @@ namespace UVtools.ScriptSample pos = Layer.RoundHeight(pos + layerHeight); var liftPos = Layer.RoundHeight(pos + liftHeight); gcode.AppendLiftMoveG0(liftPos, feedrate, pos, feedrate, lightoff); - } + }*/ // 0.001 test /*gcode.AppendComment("0.001 layer height simulated print test"); @@ -121,22 +121,18 @@ namespace UVtools.ScriptSample } */ - /*gcode.AppendMoveG0(2, gcode.ConvertFromMillimetersPerMinute(150)); - gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(2.5f, gcode.ConvertFromMillimetersPerMinute(160)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(150), 1, gcode.ConvertFromMillimetersPerMinute(150)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(3f, gcode.ConvertFromMillimetersPerMinute(170)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(180), 1.5f, gcode.ConvertFromMillimetersPerMinute(180)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(3.5f, gcode.ConvertFromMillimetersPerMinute(180)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(195), 2, gcode.ConvertFromMillimetersPerMinute(195)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(4.0f, gcode.ConvertFromMillimetersPerMinute(190)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(200), 2.5f, gcode.ConvertFromMillimetersPerMinute(200)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(4.5f, gcode.ConvertFromMillimetersPerMinute(195)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(250), 3f, gcode.ConvertFromMillimetersPerMinute(250)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(5f, gcode.ConvertFromMillimetersPerMinute(199)); + gcode.AppendLiftMoveG0(20, gcode.ConvertFromMillimetersPerMinute(300), 3.5f, gcode.ConvertFromMillimetersPerMinute(300)); gcode.AppendWaitG4(lightoff); - gcode.AppendMoveG0(5.5f, gcode.ConvertFromMillimetersPerMinute(205)); - gcode.AppendWaitG4(lightoff);*/ gcode.AppendMoveG0(100, feedrate); //gcode.AppendTurnMotors(false); diff --git a/UVtools.WPF/Assets/Icons/pencil-alt-16x16.png b/UVtools.WPF/Assets/Icons/pencil-alt-16x16.png Binary files differnew file mode 100644 index 0000000..a6002a8 --- /dev/null +++ b/UVtools.WPF/Assets/Icons/pencil-alt-16x16.png diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml index f15720a..2ffeb4b 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml +++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml @@ -1096,8 +1096,44 @@ </DataGrid> + <Grid RowDefinitions="Auto" ColumnDefinitions="Auto,10,*" Margin="0,10,0,0"> + <TextBlock Grid.Row="0" Grid.Column="0" + ToolTip.Tip="Print mode for non-bottom base layers. +
A option other than 'Iterative' will speed up the print process and merge all base layers in the same height. +
The referred exposures come from the generated table." + Text="Base layers print mode:" + VerticalAlignment="Center"/> + + <ComboBox Grid.Row="0" Grid.Column="2" + HorizontalAlignment="Stretch" + VerticalAlignment="Center" + Items="{Binding Operation.MultipleExposuresBaseLayersPrintMode, Converter={StaticResource EnumToCollectionConverter}, Mode=OneTime}" + SelectedItem="{Binding Operation.MultipleExposuresBaseLayersPrintMode, Converter={StaticResource FromValueDescriptionToEnumConverter}}"/> + </Grid> + + <Grid RowDefinitions="Auto" ColumnDefinitions="Auto,10,Auto,5,Auto"> + <TextBlock Grid.Row="0" Grid.Column="0" + Text="Base layers exposure: " + ToolTip.Tip="Use this custom exposure time for base layers" + IsEnabled="{Binding Operation.IsMultipleExposuresBaseLayersPrintModeCustom}" + VerticalAlignment="Center"/> + + <NumericUpDown Grid.Row="0" Grid.Column="2" + Increment="0.5" + Minimum="0.1" + Maximum="1000" + FormatString="F2" + IsEnabled="{Binding Operation.IsMultipleExposuresBaseLayersPrintModeCustom}" + Value="{Binding Operation.MultipleExposuresBaseLayersCustomExposure}"/> + + <TextBlock Grid.Row="0" Grid.Column="4" + Text="s (For 'custom' mode only)" + IsEnabled="{Binding Operation.IsMultipleExposuresBaseLayersPrintModeCustom}" + VerticalAlignment="Center"/> + </Grid> + - <StackPanel Orientation="Vertical" Spacing="10" + <StackPanel Orientation="Vertical" Margin="0,10,0,0" Spacing="10" IsEnabled="{Binding Operation.MultipleExposures}" IsVisible="{Binding SlicerFile.SupportPerLayerSettings}"> diff --git a/UVtools.WPF/MainWindow.GCode.cs b/UVtools.WPF/MainWindow.GCode.cs index 3ab6c65..58b8f33 100644 --- a/UVtools.WPF/MainWindow.GCode.cs +++ b/UVtools.WPF/MainWindow.GCode.cs @@ -19,15 +19,16 @@ namespace UVtools.WPF { public bool HaveGCode => IsFileLoaded && SlicerFile.SupportsGCode; - public string GCodeStr => SlicerFile?.GCodeStr; public uint GCodeLines => !HaveGCode ? 0 : SlicerFile.GCode.LineCount; public void OnClickRebuildGcode() { if (!HaveGCode) return; + var temp = SlicerFile.SuppressRebuildGCode; + SlicerFile.SuppressRebuildGCode = false; SlicerFile.RebuildGCode(); + SlicerFile.SuppressRebuildGCode = temp; RaisePropertyChanged(nameof(GCodeLines)); - RaisePropertyChanged(nameof(GCodeStr)); CanSave = true; } @@ -69,7 +70,7 @@ namespace UVtools.WPF public void OnClickGCodeSaveClipboard() { if (!HaveGCode) return; - Application.Current.Clipboard.SetTextAsync(GCodeStr); + Application.Current.Clipboard.SetTextAsync(SlicerFile.GCodeStr); } } } diff --git a/UVtools.WPF/MainWindow.axaml b/UVtools.WPF/MainWindow.axaml index 9e0efbc..3507618 100644 --- a/UVtools.WPF/MainWindow.axaml +++ b/UVtools.WPF/MainWindow.axaml @@ -586,7 +586,16 @@ HorizontalAlignment="Right" VerticalAlignment="Center"> - <Button + <ToggleButton + IsChecked="{Binding SlicerFile.SuppressRebuildGCode}" + ToolTip.Tip="Enable this to directly edit and use custom gcode. +
While this is active, UVtools won't update/generate the gcode, meaning any future change won't be replicated to gcode, unless you press the 'Refresh' button. +
To save the file with your custom gcode this setting must remain active while saving the file or else it will be re-generated. +
Use with caution and only if you know what you are doing!"> + <Image Source="/Assets/Icons/pencil-alt-16x16.png"/> + </ToggleButton> + + <Button ToolTip.Tip="Rebuild GCode with current settings" Command="{Binding OnClickRebuildGcode}"> <Image Source="/Assets/Icons/refresh-16x16.png"/> @@ -627,8 +636,9 @@ <TextBox Name="GCodeText" Grid.Row="1" - IsReadOnly="True" - Text="{Binding GCodeStr}" /> + IsReadOnly="{Binding !SlicerFile.SuppressRebuildGCode}" + AcceptsReturn="True" + Text="{Binding SlicerFile.GCodeStr}" /> </Grid> </TabItem> diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 37b9bfc..917c2f0 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ <PackageLicenseFile>LICENSE</PackageLicenseFile> <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <RepositoryType>Git</RepositoryType> - <Version>2.14.2</Version> + <Version>2.14.3</Version> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> diff --git a/build/CreateRelease.WPF.ps1 b/build/CreateRelease.WPF.ps1 index 422a593..f3d3827 100644 --- a/build/CreateRelease.WPF.ps1 +++ b/build/CreateRelease.WPF.ps1 @@ -32,10 +32,10 @@ Set-Location $PSScriptRoot\.. #################################### ### Configuration ### #################################### -#$enableMSI = $true +$enableMSI = $true #$buildOnly = 'linux-x64' -$buildOnly = 'win-x64' -#$enableNugetPublish = $true +#$buildOnly = 'win-x64' +$enableNugetPublish = $true # Profilling $stopWatch = New-Object -TypeName System.Diagnostics.Stopwatch $deployStopWatch = New-Object -TypeName System.Diagnostics.Stopwatch |