* (Add) Infill: CubicDynamicLink - Alternates centers with lateral links, consume same resin as center linked and make model/infill stronger.
* (Add) Update estimate print time when modify dependent parameters (#103)
* (Add) Tool - Calculator: Old and new print time estimation (#103)
* (Fix) Print time calculation was using normal layers with bottom layer off time
* (Fix) Calculate print time based on each layer setting instead of global settings
This commit is contained in:
Tiago Conceição
2020-11-26 03:02:16 +00:00
parent 00179581dd
commit 8059078528
15 changed files with 210 additions and 69 deletions
+9 -1
View File
@@ -1,11 +1,19 @@
# Changelog
## 26/11/2020 - v1.3.4
* (Add) Infill: CubicDynamicLink - Alternates centers with lateral links, consume same resin as center linked and make model/infill stronger.
* (Add) Update estimate print time when modify dependent parameters (#103)
* (Add) Tool - Calculator: Old and new print time estimation (#103)
* (Fix) Print time calculation was using normal layers with bottom layer off time
* (Fix) Calculate print time based on each layer setting instead of global settings
## 25/11/2020 - v1.3.3
* (Add) Improved island detection: Combines the island and overhang detections for a better more realistic detection and to discard false-positives. (Slower)
If enabled, and when a island is found, it will check for overhangs on that same island, if no overhang found then the island will be discarded and considered safe, otherwise it will flag as an island issue.
Note: Overhangs settings will be used to configure the detection. Enabling Overhangs is not required for this procedure to work.
Enabled by default,
Enabled by default.
* (Add) More information on the About box: Operative system and architecture, framework, processor count and screens
* (Fix) Overhangs: Include islands when detecting overhangs were not skip when found a island
* (Fix) Decode CWS from Wanhao Workshop fails on number of slices (#102)
+1 -1
View File
@@ -1215,7 +1215,7 @@ namespace UVtools.Core.FileFormats
set
{
HeaderSettings.PrintTime = (uint) value;
RaisePropertyChanged();
base.PrintTime = value;
}
}
+1 -5
View File
@@ -320,11 +320,7 @@ namespace UVtools.Core.FileFormats
public override float PrintTime
{
get => HeaderSettings.EstimatedPrintTime;
set
{
HeaderSettings.EstimatedPrintTime = value;
RaisePropertyChanged();
}
set => base.PrintTime = HeaderSettings.EstimatedPrintTime = value;
}
public override float UsedMaterial
+67 -7
View File
@@ -10,6 +10,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
@@ -29,6 +30,7 @@ namespace UVtools.Core.FileFormats
public abstract class FileFormat : BindableBase, IFileFormat, IDisposable, IEquatable<FileFormat>, IEnumerable<Layer>
{
public const string TemporaryFileAppend = ".tmp";
public const ushort ExtraPrintTime = 300;
#region Enums
/// <summary>
@@ -374,6 +376,7 @@ namespace UVtools.Core.FileFormats
private bool _haveModifiedLayers;
private LayerManager _layerManager;
private float _printTime;
/// <summary>
/// Gets or sets if modifications require a full encode to save
@@ -412,6 +415,38 @@ namespace UVtools.Core.FileFormats
public abstract float DisplayWidth { get; set; }
public abstract float DisplayHeight { get; set; }
public float Xppmm
{
get => DisplayWidth > 0 ? ResolutionX / DisplayWidth : 0;
set
{
RaisePropertyChanged(nameof(Xppmm));
RaisePropertyChanged(nameof(Ppmm));
}
}
public float Yppmm
{
get => DisplayHeight > 0 ? ResolutionY / DisplayHeight : 0;
set
{
RaisePropertyChanged(nameof(Yppmm));
RaisePropertyChanged(nameof(Ppmm));
}
}
public SizeF Ppmm
{
get => new SizeF(Xppmm, Yppmm);
set
{
Xppmm = value.Width;
Yppmm = value.Height;
}
}
public bool HaveAntiAliasing => AntiAliasing > 1;
public abstract byte AntiAliasing { get; }
@@ -443,17 +478,39 @@ namespace UVtools.Core.FileFormats
public virtual byte LightPWM { get; set; } = DefaultLightPWM;
public virtual float PrintTime { get; set; }
public virtual float PrintTime
{
get => _printTime;
set
{
_printTime = value;
RaisePropertyChanged();
RaisePropertyChanged(nameof(PrintTimeOrComputed));
RaisePropertyChanged(nameof(PrintTimeComputed));
RaisePropertyChanged(nameof(PrintTimeHours));
}
}
//(header.numberOfLayers - header.bottomLayers) * (double) header.exposureTimeSeconds + (double) header.bottomLayers * (double) header.exposureBottomTimeSeconds + (double) header.offTimeSeconds * (double) header.numberOfLayers);
public virtual float PrintTimeOrComputed
public float PrintTimeOrComputed => PrintTime > 0 ? PrintTime : PrintTimeComputed;
public float PrintTimeComputed
{
get
{
if (PrintTime > 0) return PrintTime;
return NormalLayerCount * ExposureTime +
NormalLayerCount * LayerOffTime +
BottomLayerCount * BottomExposureTime +
NormalLayerCount * BottomLayerOffTime;
float time = ExtraPrintTime;
foreach (var layer in this)
{
var layerOff = OperationCalculator.LightOffDelayC.CalculateSeconds(layer.LiftHeight, layer.LiftSpeed, layer.RetractSpeed);
time += layer.ExposureTime;
if (layerOff >= layer.LayerOffTime)
time += layerOff;
else
time += layer.LayerOffTime;
}
return (float) Math.Round(time, 2);
}
}
@@ -492,6 +549,7 @@ namespace UVtools.Core.FileFormats
if (this[LayerCount - 1] is null) return; // Not initialized
LayerManager.RebuildLayersProperties();
RebuildGCode();
PrintTime = PrintTimeComputed;
return;
}
if (
@@ -511,6 +569,8 @@ namespace UVtools.Core.FileFormats
{
LayerManager.RebuildLayersProperties(false);
RebuildGCode();
if(e.PropertyName != nameof(BottomLightPWM) && e.PropertyName != nameof(LightPWM))
PrintTime = PrintTimeComputed;
return;
}
}
+20
View File
@@ -118,6 +118,21 @@ namespace UVtools.Core.FileFormats
/// </summary>
float DisplayHeight { 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; }
bool HaveAntiAliasing { get; }
/// <summary>
@@ -228,6 +243,11 @@ namespace UVtools.Core.FileFormats
/// </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>
+1 -1
View File
@@ -909,7 +909,7 @@ namespace UVtools.Core.FileFormats
set
{
HeaderSettings.PrintTime = (uint) value;
RaisePropertyChanged();
base.PrintTime = value;
}
}
+1 -5
View File
@@ -410,11 +410,7 @@ namespace UVtools.Core.FileFormats
public override float PrintTime
{
get => OutputConfigSettings.PrintTime;
set
{
OutputConfigSettings.PrintTime = value;
RaisePropertyChanged();
}
set => base.PrintTime = OutputConfigSettings.PrintTime = value;
}
public override float UsedMaterial
+1 -1
View File
@@ -287,7 +287,7 @@ namespace UVtools.Core.FileFormats
set
{
ResinMetadataSettings.PrintTime = (uint) value;
RaisePropertyChanged();
base.PrintTime = value;
}
}
+62 -42
View File
@@ -936,6 +936,7 @@ namespace UVtools.Core
}
else*/ if (operation.InfillType == OperationInfill.InfillAlgorithm.Cubic ||
operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink ||
operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink ||
operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked)
{
using (var infillPattern = EmguExtensions.InitMat(new Size(operation.InfillSpacing, operation.InfillSpacing)))
@@ -944,8 +945,10 @@ namespace UVtools.Core
bool firstPattern = true;
uint accumulator = 0;
uint step = 0;
bool dynamicCenter = false;
while (accumulator < layerIndex)
{
dynamicCenter = !dynamicCenter;
firstPattern = true;
accumulator += operation.InfillSpacing;
@@ -978,65 +981,82 @@ namespace UVtools.Core
thickness, thickness),
infillColor, -1);
// Center cross
int margin = (int)(operation.InfillSpacing - accumulator + layerIndex) - thickness;
int marginInv = (int)(accumulator - layerIndex) - thickness;
if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicCenterLink ||
(operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink &&
dynamicCenter) ||
operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked)
{
// Center cross
int margin = (int) (operation.InfillSpacing - accumulator + layerIndex) - thickness;
int marginInv = (int) (accumulator - layerIndex) - thickness;
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, margin, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, marginInv, operation.InfillThickness, operation.InfillThickness),
new Rectangle(marginInv, marginInv, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, marginInv, operation.InfillThickness, operation.InfillThickness),
new Rectangle(margin, marginInv, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, margin, operation.InfillThickness, operation.InfillThickness),
new Rectangle(marginInv, margin, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked)
{
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, -thickness, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, -thickness, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(-thickness, margin, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(-thickness, marginInv, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(operation.InfillSpacing - thickness, margin, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(operation.InfillSpacing - thickness, marginInv, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, operation.InfillSpacing - thickness, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, operation.InfillSpacing - thickness, operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
}
}
if (operation.InfillType == OperationInfill.InfillAlgorithm.CubicInterlinked ||
(operation.InfillType == OperationInfill.InfillAlgorithm.CubicDynamicLink && !dynamicCenter))
{
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, -thickness, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, -thickness, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(-thickness, margin, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(-thickness, marginInv, operation.InfillThickness,
operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(operation.InfillSpacing - thickness, margin,
operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(operation.InfillSpacing - thickness, marginInv,
operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(margin, operation.InfillSpacing - thickness,
operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
CvInvoke.Rectangle(infillPattern,
new Rectangle(marginInv, operation.InfillSpacing - thickness,
operation.InfillThickness, operation.InfillThickness),
infillColor, -1);
}
}
else
{
+2 -1
View File
@@ -13,7 +13,7 @@ namespace UVtools.Core.Operations
[Serializable]
public sealed class OperationInfill : Operation
{
private InfillAlgorithm _infillType = InfillAlgorithm.CubicCenterLink;
private InfillAlgorithm _infillType = InfillAlgorithm.CubicDynamicLink;
private ushort _wallThickness = 64;
private ushort _infillThickness = 45;
private ushort _infillSpacing = 160;
@@ -42,6 +42,7 @@ namespace UVtools.Core.Operations
//Rhombus,
Cubic,
CubicCenterLink,
CubicDynamicLink,
CubicInterlinked,
}
#endregion
+1 -1
View File
@@ -10,7 +10,7 @@
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl>
<Description>MSLA/DLP, file analysis, repair, conversion and manipulation</Description>
<Version>1.3.3</Version>
<Version>1.3.4</Version>
<Copyright>Copyright © 2020 PTRTECH</Copyright>
<PackageIcon>UVtools.png</PackageIcon>
<Platforms>AnyCPU;x64</Platforms>
@@ -249,7 +249,7 @@
<Grid
Grid.Row="2"
RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
RowDefinitions="Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto,10,Auto"
ColumnDefinitions="Auto,10,100,5,Auto,30,Auto,10,100,5,Auto"
>
@@ -373,6 +373,22 @@
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding SlicerFile.LayerOffTime, StringFormat=Current value: \{0\}}"/>
<TextBlock
Grid.Row="14"
Grid.Column="0"
Grid.ColumnSpan="11"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding SlicerFile.PrintTimeHours, StringFormat=Old print time: \{0\}h}"/>
<TextBlock
Grid.Row="16"
Grid.Column="0"
Grid.ColumnSpan="11"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding LightOffDelayPrintTimeHours, StringFormat=New print time: \{0\}h}"/>
<!-- Bottom -->
@@ -1,4 +1,5 @@
using Avalonia.Markup.Xaml;
using System;
using Avalonia.Markup.Xaml;
using UVtools.Core.FileFormats;
using UVtools.Core.Operations;
@@ -6,10 +7,17 @@ namespace UVtools.WPF.Controls.Tools
{
public class ToolCalculatorControl : ToolControl
{
private decimal _lightOffDelayPrintTimeHours;
public OperationCalculator Operation => BaseOperation as OperationCalculator;
public FileFormat SlicerFile => App.SlicerFile;
public decimal LightOffDelayPrintTimeHours
{
get => _lightOffDelayPrintTimeHours;
set => RaiseAndSetIfChanged(ref _lightOffDelayPrintTimeHours, value);
}
public ToolCalculatorControl()
{
InitializeComponent();
@@ -21,6 +29,19 @@ namespace UVtools.WPF.Controls.Tools
(decimal)SlicerFile.LiftSpeed, (decimal)SlicerFile.BottomLiftSpeed,
(decimal)SlicerFile.RetractSpeed, (decimal)SlicerFile.RetractSpeed)
};
Operation.CalcLightOffDelay.PropertyChanged += (sender, e) =>
{
if (e.PropertyName != nameof(Operation.CalcLightOffDelay.LightOffDelay) &&
e.PropertyName != nameof(Operation.CalcLightOffDelay.BottomLightOffDelay)) return;
LightOffDelayPrintTimeHours = Math.Round(
(FileFormat.ExtraPrintTime +
SlicerFile.BottomLayerCount * (Operation.CalcLightOffDelay.BottomLightOffDelay + (decimal) SlicerFile.BottomExposureTime) +
SlicerFile.NormalLayerCount * (Operation.CalcLightOffDelay.LightOffDelay + (decimal)SlicerFile.ExposureTime))
/ 3600, 2);
};
_lightOffDelayPrintTimeHours = (decimal) SlicerFile.PrintTimeHours;
}
private void InitializeComponent()
@@ -45,6 +66,8 @@ namespace UVtools.WPF.Controls.Tools
SlicerFile.LayerOffTime = (float)Operation.CalcLightOffDelay.LightOffDelay;
}
LightOffDelayPrintTimeHours = (decimal)SlicerFile.PrintTimeHours;
App.MainWindow.CanSave = true;
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
+1 -1
View File
@@ -12,7 +12,7 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<Version>1.3.3</Version>
<Version>1.3.4</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">