diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-02-26 00:01:10 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-02-26 00:01:10 +0300 |
commit | 286cfcb48e0cc49a16f500473d1a289612a96d63 (patch) | |
tree | 0b89f85055d7eae54bd67651a37d984fdcf258ec | |
parent | 4ec98cfab14f4e2c8cd1ba246c85e75ea67d1934 (diff) |
v2.5.1v2.5.1
* (Add) Calibration - Exposure time finder: Option to "Do not perform the lifting sequence for layers with same Z positioning"
The lift height will be set to 0 for sequential layers that share same z position.
Some printers may not support this and always require a lift after each layer.
* (Fix) Hide MaterialMilliliters from layer data if unable to calculate the value (NaN)
* (Fix) CWS: A missing line break wasn't lifting printer on finish
* (Fix) Layers: Allow to set LiftHeight and LightOffDelay to 0 per layer
-rw-r--r-- | CHANGELOG.md | 9 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/CWSFile.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/FileFormat.cs | 26 | ||||
-rw-r--r-- | UVtools.Core/FileFormats/IFileFormat.cs | 510 | ||||
-rw-r--r-- | UVtools.Core/Layer/Layer.cs | 4 | ||||
-rw-r--r-- | UVtools.Core/Layer/LayerManager.cs | 13 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationCalibrateExposureFinder.cs | 16 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 2 | ||||
-rw-r--r-- | UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml | 16 | ||||
-rw-r--r-- | UVtools.WPF/MainWindow.Information.cs | 6 | ||||
-rw-r--r-- | UVtools.WPF/UVtools.WPF.csproj | 2 |
11 files changed, 73 insertions, 533 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 38ceaba..4ec8639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 25/02/2021 - v2.5.1 + +* (Add) Calibration - Exposure time finder: Option to "Do not perform the lifting sequence for layers with same Z positioning" + The lift height will be set to 0 for sequential layers that share same z position. + Some printers may not support this and always require a lift after each layer. +* (Fix) Hide MaterialMilliliters from layer data if unable to calculate the value (NaN) +* (Fix) CWS: A missing line break wasn't lifting printer on finish +* (Fix) Layers: Allow to set LiftHeight and LightOffDelay to 0 per layer + ## 21/02/2021 - v2.5.0 * (Add) Help - Material manager (F10): Allow to manage material stock and costs with statistic over time diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs index a4beaa3..db9204d 100644 --- a/UVtools.Core/FileFormats/CWSFile.cs +++ b/UVtools.Core/FileFormats/CWSFile.cs @@ -183,7 +183,7 @@ namespace UVtools.Core.FileFormats "<Slice> Blank{0}" + "M106 S0{0}{0}"; - public const string GCodeEnd = "M106 S0{0} ; UV off" + + public const string GCodeEnd = "M106 S0 ;UV off{0}" + "G1 Z{1}{0}" + "{0}M18 ;Disable Motors{0}" + ";<Completed>{0}"; diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 66ff0f4..f4c5a1d 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -85,20 +85,20 @@ namespace UVtools.Core.FileFormats { #region Instances - public static PrintParameterModifier BottomLayerCount { get; } = new PrintParameterModifier("Bottom layer count", null, "layers",0, ushort.MaxValue, 0); - public static PrintParameterModifier BottomExposureSeconds { get; } = new PrintParameterModifier("Bottom exposure time", null, "s", 0.1M, 1000, 2); - public static PrintParameterModifier ExposureSeconds { get; } = new PrintParameterModifier("Exposure time", null, "s", 0.1M, 1000, 2); + public static PrintParameterModifier BottomLayerCount { get; } = new ("Bottom layer count", null, "layers",0, ushort.MaxValue, 0); + public static PrintParameterModifier BottomExposureSeconds { get; } = new ("Bottom exposure time", null, "s", 0.1M, 1000, 2); + public static PrintParameterModifier ExposureSeconds { get; } = new ("Exposure time", null, "s", 0.1M, 1000, 2); - public static PrintParameterModifier BottomLightOffDelay { get; } = new PrintParameterModifier("Bottom light-off seconds", null, "s"); - public static PrintParameterModifier LightOffDelay { get; } = new PrintParameterModifier("Light-off seconds", null, "s"); - public static PrintParameterModifier BottomLiftHeight { get; } = new PrintParameterModifier("Bottom lift height", @"Modify 'Bottom lift height' millimeters between bottom layers", "mm", 1); - public static PrintParameterModifier LiftHeight { get; } = new PrintParameterModifier("Lift height", @"Modify 'Lift height' millimeters between layers", "mm", 1); - public static PrintParameterModifier BottomLiftSpeed { get; } = new PrintParameterModifier("Bottom lift Speed", @"Modify 'Bottom lift Speed' mm/min between bottom layers", "mm/min", 10); - public static PrintParameterModifier LiftSpeed { get; } = new PrintParameterModifier("Lift speed", @"Modify 'Lift speed' mm/min between layers", "mm/min", 10, 5000, 2); - public static PrintParameterModifier RetractSpeed { get; } = new PrintParameterModifier("Retract speed", @"Modify 'Retract speed' mm/min between layer", "mm/min", 10, 5000, 2); - - public static PrintParameterModifier BottomLightPWM { get; } = new PrintParameterModifier("Bottom light PWM", @"Modify 'Bottom light PWM' value", null, 1, byte.MaxValue, 0); - public static PrintParameterModifier LightPWM { get; } = new PrintParameterModifier("Light PWM", @"Modify 'Light PWM' value", null, 1, byte.MaxValue, 0); + public static PrintParameterModifier BottomLightOffDelay { get; } = new ("Bottom light-off seconds", null, "s"); + public static PrintParameterModifier LightOffDelay { get; } = new ("Light-off seconds", null, "s"); + public static PrintParameterModifier BottomLiftHeight { get; } = new ("Bottom lift height", @"Modify 'Bottom lift height' millimeters between bottom layers", "mm", 1); + public static PrintParameterModifier LiftHeight { get; } = new ("Lift height", @"Modify 'Lift height' millimeters between layers", "mm"); + public static PrintParameterModifier BottomLiftSpeed { get; } = new ("Bottom lift Speed", @"Modify 'Bottom lift Speed' mm/min between bottom layers", "mm/min", 10); + public static PrintParameterModifier LiftSpeed { get; } = new ("Lift speed", @"Modify 'Lift speed' mm/min between layers", "mm/min", 10, 5000, 2); + public static PrintParameterModifier RetractSpeed { get; } = new ("Retract speed", @"Modify 'Retract speed' mm/min between layer", "mm/min", 10, 5000, 2); + + public static PrintParameterModifier BottomLightPWM { get; } = new ("Bottom light PWM", @"Modify 'Bottom light PWM' value", null, 1, byte.MaxValue, 0); + public static PrintParameterModifier LightPWM { get; } = new ("Light PWM", @"Modify 'Light PWM' value", null, 1, byte.MaxValue, 0); public static PrintParameterModifier[] Parameters = { BottomLayerCount, diff --git a/UVtools.Core/FileFormats/IFileFormat.cs b/UVtools.Core/FileFormats/IFileFormat.cs deleted file mode 100644 index e96bb0a..0000000 --- a/UVtools.Core/FileFormats/IFileFormat.cs +++ /dev/null @@ -1,510 +0,0 @@ -/* - * 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.Drawing; -using System.Text; -using Emgu.CV; -using UVtools.Core.Operations; - -namespace UVtools.Core.FileFormats -{ - /// <summary> - /// Slicer file format representation interface - /// </summary> - public interface IFileFormat - { - #region Properties - /// <summary> - /// Gets the file format type - /// </summary> - FileFormat.FileFormatType FileType { get; } - - /// <summary> - /// Gets the valid file extensions for this <see cref="FileFormat"/> - /// </summary> - FileExtension[] FileExtensions { get; } - - /// <summary> - /// Gets the available <see cref="FileFormat.PrintParameterModifier"/> - /// </summary> - FileFormat.PrintParameterModifier[] PrintParameterModifiers { get; } - - /// <summary> - /// Gets the available <see cref="FileFormat.PrintParameterModifier"/> per layer - /// </summary> - FileFormat.PrintParameterModifier[] PrintParameterPerLayerModifiers { get; } - - /// <summary> - /// Gets the file filter for open and save dialogs - /// </summary> - string FileFilter { get; } - - /// <summary> - /// Gets all valid file extensions in "*.extension1;*.extension2" format - /// </summary> - - string FileFilterExtensionsOnly { get; } - - /// <summary> - /// Gets or sets if change a global property should rebuild every layer data based on them - /// </summary> - bool SuppressRebuildProperties { get; set; } - - /// <summary> - /// Gets the input file path loaded into this <see cref="FileFormat"/> - /// </summary> - string FileFullPath { get; set; } - - /// <summary> - /// Gets the thumbnails count present in this file format - /// </summary> - byte ThumbnailsCount { get; } - - /// <summary> - /// Gets the number of created thumbnails - /// </summary> - byte CreatedThumbnailsCount { get; } - - /// <summary> - /// Gets the original thumbnail sizes - /// </summary> - System.Drawing.Size[] ThumbnailsOriginalSize { get; } - - /// <summary> - /// Gets the thumbnails for this <see cref="FileFormat"/> - /// </summary> - Mat[] Thumbnails { get; set; } - - /// <summary> - /// Gets the cached layers into compressed bytes - /// </summary> - LayerManager LayerManager { get; set; } - - Size Resolution { get; set; } - - /// <summary> - /// Gets the image width resolution - /// </summary> - uint ResolutionX { get; set; } - - /// <summary> - /// Gets the image height resolution - /// </summary> - uint ResolutionY { get; set; } - - /// <summary> - /// Gets the size of display in millimeters - /// </summary> - SizeF Display { get; set; } - - /// <summary> - /// Gets or sets the display width in millimeters - /// </summary> - float DisplayWidth { get; set; } - - /// <summary> - /// Gets or sets the display height in millimeters - /// </summary> - float DisplayHeight { get; set; } - - /// <summary> - /// Gets or sets if images need to be mirrored on lcd to print on the correct orientation - /// </summary> - bool MirrorDisplay { get; set; } - - /// <summary> - /// Gets or sets the maximum printer build Z volume - /// </summary> - float MaxPrintHeight { get; set; } - - /// <summary> - /// Gets or sets the pixels per mm on X direction - /// </summary> - float Xppmm { get; set; } - - /// <summary> - /// Gets or sets the pixels per mm on Y direction - /// </summary> - float Yppmm { get; set; } - - /// <summary> - /// Gets or sets the pixels per mm - /// </summary> - SizeF Ppmm { get; set; } - - /// <summary> - /// Gets the printer XY pixel resolution - /// </summary> - decimal XYResolution { get; } - - /// <summary> - /// Gets the printer XY pixel resolution in microns - /// </summary> - decimal XYResolutionUm { get; } - - bool HaveAntiAliasing { get; } - - /// <summary> - /// Gets or sets the AntiAliasing level - /// </summary> - byte AntiAliasing { get; set; } - - /// <summary> - /// Gets Layer Height in mm - /// </summary> - float LayerHeight { get; set; } - - /// <summary> - /// Gets or sets the print height in mm - /// </summary> - float PrintHeight { get; set; } - - /// <summary> - /// Gets the last layer index - /// </summary> - uint LastLayerIndex { get; } - - #region Universal Properties - - /// <summary> - /// Gets if this format support per layer override settings - /// </summary> - bool SupportPerLayerSettings { get; } - - /// <summary> - /// Gets the number of layers present in this file - /// </summary> - uint LayerCount { get; set; } - - /// <summary> - /// Gets or sets the number of initial layer count - /// </summary> - ushort BottomLayerCount { get; set; } - - /// <summary> - /// Gets the number of normal layer count - /// </summary> - uint NormalLayerCount { get; } - - /// <summary> - /// Gets or sets the initial exposure time for <see cref="BottomLayerCount"/> in seconds - /// </summary> - float BottomExposureTime { get; set; } - - /// <summary> - /// Gets or sets the normal layer exposure time in seconds - /// </summary> - float ExposureTime { get; set; } - - /// <summary> - /// Gets or sets the bottom layer off time in seconds - /// </summary> - float BottomLightOffDelay { get; set; } - - /// <summary> - /// Gets or sets the layer off time in seconds - /// </summary> - float LightOffDelay { get; set; } - - /// <summary> - /// Gets or sets the bottom lift height in mm - /// </summary> - float BottomLiftHeight { get; set; } - - /// <summary> - /// Gets or sets the lift height in mm - /// </summary> - float LiftHeight { get; set; } - - /// <summary> - /// Gets or sets the bottom lift speed in mm/min - /// </summary> - float BottomLiftSpeed { get; set; } - - /// <summary> - /// Gets or sets the speed in mm/min - /// </summary> - float LiftSpeed { get; set; } - - /// <summary> - /// Gets the speed in mm/min for the retracts - /// </summary> - float RetractSpeed { get; set; } - - /// <summary> - /// Gets or sets the bottom pwm value from 0 to 255 - /// </summary> - byte BottomLightPWM { get; set; } - - /// <summary> - /// Gets or sets the pwm value from 0 to 255 - /// </summary> - byte LightPWM { get; set; } - #endregion - - /// <summary> - /// Gets the estimate print time in seconds - /// </summary> - float PrintTime { get; set; } - - /// <summary> - /// Gets the estimate print time in seconds, if print doesn't support it it will be calculated - /// </summary> - float PrintTimeOrComputed { get; } - - /// <summary> - /// Gets the calculated estimate print time in seconds - /// </summary> - float PrintTimeComputed { get; } - - /// <summary> - /// Gets the estimate print time in hours - /// </summary> - float PrintTimeHours { get; } - - /// <summary> - /// Gets the estimate print time in hours and minutes formatted - /// </summary> - string PrintTimeString { get; } - - /// <summary> - /// Gets the estimate used material in ml - /// </summary> - float MaterialMilliliters { get; set; } - - /// <summary> - /// Gets the estimate material in grams - /// </summary> - float MaterialGrams { get; set; } - - /// <summary> - /// Gets the estimate material cost - /// </summary> - float MaterialCost { get; set; } - - /// <summary> - /// Gets the material name - /// </summary> - string MaterialName { get; set; } - - /// <summary> - /// Gets the machine name - /// </summary> - string MachineName { get; set; } - - /// <summary> - /// Gets the GCode, returns null if not supported - /// </summary> - StringBuilder GCode { get; set; } - string GCodeStr { get; } - - /// <summary> - /// Gets if this file have available gcode - /// </summary> - bool HaveGCode { get; } - - /// <summary> - /// Get all configuration objects with properties and values - /// </summary> - object[] Configs { get; } - - /// <summary> - /// Gets if this file is valid to read - /// </summary> - bool IsValid { get; } - - #endregion - - #region Methods - /// <summary> - /// Clears all definitions and properties, it also dispose valid candidates - /// </summary> - void Clear(); - - /// <summary> - /// Validate if a file is a valid <see cref="FileFormat"/> - /// </summary> - /// <param name="fileFullPath">Full file path</param> - void FileValidation(string fileFullPath); - - /// <summary> - /// Checks if a extension is valid under the <see cref="FileFormat"/> - /// </summary> - /// <param name="extension">Extension to check</param> - /// <param name="isFilePath">True if <see cref="extension"/> is a full file path, otherwise false for extension only</param> - /// <returns>True if valid, otherwise false</returns> - bool IsExtensionValid(string extension, bool isFilePath = false); - - /// <summary> - /// Gets all valid file extensions in a specified format - /// </summary> - - string GetFileExtensions(string prepend = ".", string separator = ", "); - - /// <summary> - /// Gets a thumbnail by it height or lower - /// </summary> - /// <param name="maxHeight">Max height allowed</param> - /// <returns></returns> - Mat GetThumbnail(uint maxHeight = 400); - - /// <summary> - /// Gets a thumbnail by the largest or smallest - /// </summary> - /// <param name="largest">True to get the largest, otherwise false</param> - /// <returns></returns> - Mat GetThumbnail(bool largest); - - /// <summary> - /// Sets thumbnails from a list of thumbnails and clone them - /// </summary> - /// <param name="images"></param> - void SetThumbnails(Mat[] images); - - /// <summary> - /// Sets all thumbnails the same image - /// </summary> - /// <param name="images">Image to set</param> - void SetThumbnails(Mat images); - - /// <summary> - /// Sets a thumbnail from a disk file - /// </summary> - /// <param name="index">Thumbnail index</param> - /// <param name="filePath"></param> - void SetThumbnail(int index, string filePath); - - /// <summary> - /// Encode to an output file - /// </summary> - /// <param name="fileFullPath">Output file</param> - /// <param name="progress"></param> - void Encode(string fileFullPath, OperationProgress progress = null); - void AfterEncode(); - - /* - /// <summary> - /// Begin encode to an output file - /// </summary> - /// <param name="fileFullPath">Output file</param> - //void BeginEncode(string fileFullPath); - - /// <summary> - /// Insert a layer image to be encoded - /// </summary> - /// <param name="image"></param> - /// <param name="layerIndex"></param> - //void InsertLayerImageEncode(Image<L8> image, uint layerIndex); - - /// <summary> - /// Finish the encoding procedure - /// </summary> - //void EndEncode();*/ - - /// <summary> - /// Decode a slicer file - /// </summary> - /// <param name="fileFullPath"></param> - /// <param name="progress"></param> - void Decode(string fileFullPath, OperationProgress progress = null); - - /// <summary> - /// Extract contents to a folder - /// </summary> - /// <param name="path">Path to folder where content will be extracted</param> - /// <param name="genericConfigExtract"></param> - /// <param name="genericLayersExtract"></param> - /// <param name="progress"></param> - void Extract(string path, bool genericConfigExtract = true, bool genericLayersExtract = true, - OperationProgress progress = null); - - /// <summary> - /// Get height in mm from layer height - /// </summary> - /// <param name="layerIndex"></param> - /// <param name="realHeight"></param> - /// <returns>The height in mm</returns> - float GetHeightFromLayer(uint layerIndex, bool realHeight = true); - - /// <summary> - /// Gets the value for initial layer or normal layers based on layer index - /// </summary> - /// <typeparam name="T">Type of value</typeparam> - /// <param name="layerIndex">Layer index</param> - /// <param name="initialLayerValue">Initial value</param> - /// <param name="normalLayerValue">Normal value</param> - /// <returns></returns> - T GetInitialLayerValueOrNormal<T>(uint layerIndex, T initialLayerValue, T normalLayerValue); - - void RefreshPrintParametersModifiersValues(); - void RefreshPrintParametersPerLayerModifiersValues(uint layerIndex); - - /// <summary> - /// Gets the value attributed to <see cref="FileFormat.PrintParameterModifier"/> - /// </summary> - /// <param name="modifier">Modifier to use</param> - /// <returns>A value</returns> - object GetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier); - - /// <summary> - /// Sets a property value attributed to <see cref="modifier"/> - /// </summary> - /// <param name="modifier">Modifier to use</param> - /// <param name="value">Value to set</param> - /// <returns>True if set, otherwise false = <see cref="modifier"/> not found</returns> - bool SetValueFromPrintParameterModifier(FileFormat.PrintParameterModifier modifier, decimal value); - - byte SetValuesFromPrintParametersModifiers(); - - void EditPrintParameters(OperationEditParameters operation); - - /// <summary> - /// Rebuilds GCode based on current settings - /// </summary> - void RebuildGCode(); - - /// <summary> - /// Saves current configuration on input file - /// </summary> - /// <param name="progress"></param> - void Save(OperationProgress progress = null); - - /// <summary> - /// Saves current configuration on a copy - /// </summary> - /// <param name="filePath">File path to save copy as, use null to overwrite active file (Same as <see cref="Save"/>)</param> - /// <param name="progress"></param> - void SaveAs(string filePath = null, OperationProgress progress = null); - - /// <summary> - /// Converts this file type to another file type - /// </summary> - /// <param name="to">Target file format</param> - /// <param name="fileFullPath">Output path file</param> - /// <param name="progress"></param> - /// <returns>The converted file if successful, otherwise null</returns> - FileFormat Convert(Type to, string fileFullPath, OperationProgress progress = null); - - /// <summary> - /// Converts this file type to another file type - /// </summary> - /// <param name="to">Target file format</param> - /// <param name="fileFullPath">Output path file</param> - /// <param name="progress"></param> - /// <returns>TThe converted file if successful, otherwise null</returns> - FileFormat Convert(FileFormat to, string fileFullPath, OperationProgress progress = null); - - /// <summary> - /// Validate AntiAlias Level - /// </summary> - byte ValidateAntiAliasingLevel(); - - #endregion - } -} diff --git a/UVtools.Core/Layer/Layer.cs b/UVtools.Core/Layer/Layer.cs index 9ea9b9b..286aaf7 100644 --- a/UVtools.Core/Layer/Layer.cs +++ b/UVtools.Core/Layer/Layer.cs @@ -138,7 +138,7 @@ namespace UVtools.Core get => _lightOffDelay; set { - if (value <= 0) value = SlicerFile.GetInitialLayerValueOrNormal(Index, SlicerFile.BottomLightOffDelay, SlicerFile.LightOffDelay); + if (value < 0) value = SlicerFile.GetInitialLayerValueOrNormal(Index, SlicerFile.BottomLightOffDelay, SlicerFile.LightOffDelay); RaiseAndSetIfChanged(ref _lightOffDelay, value); } } @@ -151,7 +151,7 @@ namespace UVtools.Core get => _liftHeight; set { - if (value <= 0) value = SlicerFile.GetInitialLayerValueOrNormal(Index, SlicerFile.BottomLiftHeight, SlicerFile.LiftHeight); + if (value < 0) value = SlicerFile.GetInitialLayerValueOrNormal(Index, SlicerFile.BottomLiftHeight, SlicerFile.LiftHeight); RaiseAndSetIfChanged(ref _liftHeight, value); } } diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index ae9a023..49469f7 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -289,6 +289,19 @@ namespace UVtools.Core SlicerFile?.RebuildGCode(); } + /// <summary> + /// Set LiftHeight to 0 if previous and current have same PositionZ + /// </summary> + public void SetNoLiftForSamePositionedLayers() + { + for (int layerIndex = 1; layerIndex < Count; layerIndex++) + { + if (this[layerIndex - 1].PositionZ != this[layerIndex].PositionZ) continue; + this[layerIndex].LiftHeight = 0; + } + SlicerFile?.RebuildGCode(); + } + public Rectangle GetBoundingRectangle(OperationProgress progress = null) { progress ??= new OperationProgress(OperationProgress.StatusOptimizingBounds, Count-1); diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs index 9fd4d25..ec2634f 100644 --- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs +++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs @@ -76,6 +76,7 @@ namespace UVtools.Core.Operations private decimal _multipleLayerHeightMaximum = 0.1m; private decimal _multipleLayerHeightStep = 0.01m; + private bool _dontLiftSamePositionedLayers; private bool _multipleExposures; private ExposureGenTypes _exposureGenType = ExposureGenTypes.Linear; private bool _exposureGenIgnoreBaseExposure; @@ -592,6 +593,12 @@ namespace UVtools.Core.Operations } } + public bool DontLiftSamePositionedLayers + { + get => _dontLiftSamePositionedLayers; + set => RaiseAndSetIfChanged(ref _dontLiftSamePositionedLayers, value); + } + public bool MultipleExposures { get => _multipleExposures; @@ -750,7 +757,7 @@ namespace UVtools.Core.Operations private bool Equals(OperationCalibrateExposureFinder other) { - return _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 && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape; + return _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 && _unitOfMeasure == other._unitOfMeasure && _holeDiametersPx == other._holeDiametersPx && _holeDiametersMm == other._holeDiametersMm && _barSpacing == other._barSpacing && _barLength == other._barLength && _barVerticalSplitter == other._barVerticalSplitter && _barThicknessesPx == other._barThicknessesPx && _barThicknessesMm == other._barThicknessesMm && _textFont == other._textFont && _textScale.Equals(other._textScale) && _textThickness == other._textThickness && _text == other._text && _multipleBrightness == other._multipleBrightness && _multipleBrightnessExcludeFrom == other._multipleBrightnessExcludeFrom && _multipleBrightnessValues == other._multipleBrightnessValues && _dontLiftSamePositionedLayers == other._dontLiftSamePositionedLayers && _multipleLayerHeight == other._multipleLayerHeight && _multipleLayerHeightMaximum == other._multipleLayerHeightMaximum && _multipleLayerHeightStep == other._multipleLayerHeightStep && _multipleExposures == other._multipleExposures && _exposureGenType == other._exposureGenType && _exposureGenIgnoreBaseExposure == other._exposureGenIgnoreBaseExposure && _exposureGenBottomStep == other._exposureGenBottomStep && _exposureGenNormalStep == other._exposureGenNormalStep && _exposureGenTests == other._exposureGenTests && Equals(_exposureTable, other._exposureTable) && _holeShape == other._holeShape; } public override bool Equals(object obj) @@ -793,6 +800,7 @@ namespace UVtools.Core.Operations hashCode.Add(_multipleLayerHeight); hashCode.Add(_multipleLayerHeightMaximum); hashCode.Add(_multipleLayerHeightStep); + hashCode.Add(_dontLiftSamePositionedLayers); hashCode.Add(_multipleExposures); hashCode.Add((int) _exposureGenType); hashCode.Add(_exposureGenIgnoreBaseExposure); @@ -1288,6 +1296,12 @@ namespace UVtools.Core.Operations SlicerFile.ExposureTime = (float)NormalExposure; SlicerFile.BottomLayerCount = BottomLayers; SlicerFile.LayerManager.Layers = newLayers.ToArray(); + + if (_dontLiftSamePositionedLayers) + { + SlicerFile.LayerManager.SetNoLiftForSamePositionedLayers(); + } + SlicerFile.SuppressRebuildProperties = false; if (_mirrorOutput) diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 9c4fcf6..a64a938 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.5.0</Version> + <Version>2.5.1</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> diff --git a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml index 507a922..51daff9 100644 --- a/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml +++ b/UVtools.WPF/Controls/Calibrators/CalibrateExposureFinderControl.axaml @@ -431,12 +431,13 @@ <TextBlock Text="Only printers able to do Anti-Aliasing and enabled on file can support this, make sure your is supported or else it can print a full white or full black model. 
Also take into consideration some printers/formats have fixed usable AA levels and all in between will be threshold, study this first. 
If your printer is able to do 'Multiple exposures times per layer', please use that method instead of this (More accurate and AA threshold free)."/> - - <CheckBox + <CheckBox Content="Enable - For advanced users only!" IsChecked="{Binding Operation.MultipleBrightness}"/> - <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto" + + + <Grid RowDefinitions="Auto,10,Auto,10,Auto,10,Auto" ColumnDefinitions="Auto,10,200,5,Auto,20,Auto,10,Auto,5,Auto,5,Auto" IsEnabled="{Binding Operation.MultipleBrightness}"> @@ -613,10 +614,19 @@ <TextBlock Text="Only few printers support this, make sure your is supported or else it will print a malformed model. 
After this, do not apply any modification which reconstruct the z positions of the layers."/> + <StackPanel Orientation="Horizontal" Spacing="20"> <CheckBox Content="Enable - For advanced users only!" IsChecked="{Binding Operation.MultipleExposures}"/> + <CheckBox + ToolTip.Tip="The lift height will be set to 0 for sequential layers that share same z position. +
Some printers may not support this and always require a lift after each layer." + Content="Do not perform the lifting sequence for layers with same Z positioning" + IsEnabled="{Binding Operation.MultipleExposures}" + IsChecked="{Binding Operation.DontLiftSamePositionedLayers}"/> + </StackPanel> + <TextBlock Text="Automatic exposure generation:" IsEnabled="{Binding Operation.MultipleExposures}" FontWeight="Bold"/> diff --git a/UVtools.WPF/MainWindow.Information.cs b/UVtools.WPF/MainWindow.Information.cs index e2faf3f..58c4d3c 100644 --- a/UVtools.WPF/MainWindow.Information.cs +++ b/UVtools.WPF/MainWindow.Information.cs @@ -361,8 +361,12 @@ namespace UVtools.WPF if (SlicerFile.PrintParameterPerLayerModifiers.Contains(FileFormat.PrintParameterModifier.LightPWM)) CurrentLayerProperties.Add(new StringTag(nameof(layer.LightPWM), layer.LightPWM.ToString())); } + var materialMillilitersPercent = layer.MaterialMillilitersPercent; + if (!float.IsNaN(materialMillilitersPercent)) + { + CurrentLayerProperties.Add(new StringTag(nameof(layer.MaterialMilliliters), $"{layer.MaterialMilliliters}ml ({materialMillilitersPercent:F2}%)")); + } - CurrentLayerProperties.Add(new StringTag(nameof(layer.MaterialMilliliters), $"{layer.MaterialMilliliters}ml ({layer.MaterialMillilitersPercent:F2}%)")); } #endregion } diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 2a353c6..66f8739 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.5.0</Version> + <Version>2.5.1</Version> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |