From 774fe9d5d096aa2922f2219ddfeeb18c925530de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiago=20Concei=C3=A7=C3=A3o?= Date: Tue, 31 Aug 2021 17:06:46 +0100 Subject: [PATCH] v2.20.5 - (Add) Setting - Max degree of parallelism: Sets the maximum number of concurrent tasks/threads/operations enabled to run by parallel method calls. If your computer lags and freeze during operations you can reduce this number to reduce the workload and keep some cores available to other tasks as well. <= 0: Will utilize however many threads the underlying scheduler provides, mostly this is the processor count. 1: Single thread. (#279) --- CHANGELOG.md | 7 ++ UVtools.Core/CoreSettings.cs | 42 +++++++++ UVtools.Core/FileFormats/CTBEncryptedFile.cs | 4 +- UVtools.Core/FileFormats/CWSFile.cs | 4 +- UVtools.Core/FileFormats/CXDLPFile.cs | 12 +-- UVtools.Core/FileFormats/CXDLPv1File.cs | 8 +- UVtools.Core/FileFormats/ChituboxFile.cs | 4 +- UVtools.Core/FileFormats/FDGFile.cs | 4 +- UVtools.Core/FileFormats/FileFormat.cs | 2 +- .../FileFormats/FlashForgeSVGXFile.cs | 4 +- UVtools.Core/FileFormats/GR1File.cs | 8 +- UVtools.Core/FileFormats/LGSFile.cs | 4 +- UVtools.Core/FileFormats/MDLPFile.cs | 8 +- UVtools.Core/FileFormats/OSLAFile.cs | 4 +- UVtools.Core/FileFormats/PHZFile.cs | 4 +- UVtools.Core/FileFormats/PhotonSFile.cs | 4 +- .../FileFormats/PhotonWorkshopFile.cs | 4 +- UVtools.Core/Layer/LayerManager.cs | 24 +++-- UVtools.Core/Operations/OperationBlur.cs | 2 +- .../OperationCalibrateElephantFoot.cs | 2 +- .../OperationCalibrateExposureFinder.cs | 2 +- .../Operations/OperationCalibrateGrayscale.cs | 2 +- .../OperationCalibrateStressTower.cs | 12 +-- .../Operations/OperationCalibrateTolerance.cs | 12 +-- .../OperationCalibrateXYZAccuracy.cs | 2 +- .../Operations/OperationChangeResolution.cs | 2 +- .../Operations/OperationDynamicLayerHeight.cs | 2 +- UVtools.Core/Operations/OperationFlip.cs | 2 +- UVtools.Core/Operations/OperationInfill.cs | 2 +- .../Operations/OperationLayerArithmetic.cs | 2 +- .../Operations/OperationLayerExportGif.cs | 2 +- .../Operations/OperationLayerExportHeatMap.cs | 2 +- .../Operations/OperationLayerExportImage.cs | 2 +- .../OperationLayerExportSkeleton.cs | 2 +- .../Operations/OperationLayerImport.cs | 8 +- .../Operations/OperationLayerReHeight.cs | 2 +- .../OperationLightBleedCompensation.cs | 2 +- UVtools.Core/Operations/OperationMask.cs | 2 +- UVtools.Core/Operations/OperationMorph.cs | 4 +- UVtools.Core/Operations/OperationMove.cs | 2 +- UVtools.Core/Operations/OperationPattern.cs | 2 +- .../Operations/OperationPixelArithmetic.cs | 4 +- .../Operations/OperationPixelDimming.cs | 4 +- .../Operations/OperationRaftRelief.cs | 2 +- .../Operations/OperationRedrawModel.cs | 2 +- .../Operations/OperationRepairLayers.cs | 6 +- UVtools.Core/Operations/OperationResize.cs | 2 +- UVtools.Core/Operations/OperationRotate.cs | 2 +- UVtools.Core/Operations/OperationSolidify.cs | 2 +- UVtools.Core/Operations/OperationThreshold.cs | 2 +- UVtools.Core/UVtools.Core.csproj | 2 +- UVtools.ScriptSample/ScriptInsetSample.cs | 3 +- .../ScriptLightBleedCompensationSample.cs | 3 +- UVtools.WPF/MainWindow.Issues.cs | 2 +- UVtools.WPF/MainWindow.LayerPreview.cs | 2 +- UVtools.WPF/UVtools.WPF.csproj | 2 +- UVtools.WPF/UserSettings.cs | 46 ++++++---- UVtools.WPF/Windows/SettingsWindow.axaml | 87 +++++++++++++++++++ UVtools.WPF/Windows/SettingsWindow.axaml.cs | 33 ++++++- 59 files changed, 302 insertions(+), 129 deletions(-) create mode 100644 UVtools.Core/CoreSettings.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index bc150fa..4d34147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 31/08/2021 - v2.20.5 + +- (Add) Setting - Max degree of parallelism: Sets the maximum number of concurrent tasks/threads/operations enabled to run by parallel method calls. + If your computer lags and freeze during operations you can reduce this number to reduce the workload and keep some cores available to other tasks as well. + <= 0: Will utilize however many threads the underlying scheduler provides, mostly this is the processor count. + 1: Single thread. (#279) + ## 29/08/2021 - v2.20.4 - (Fix) On some tools, calibration tests and even files when recalculating the Z layer position for the whole set, it will use the bottom setting for all layers diff --git a/UVtools.Core/CoreSettings.cs b/UVtools.Core/CoreSettings.cs new file mode 100644 index 0000000..47f019c --- /dev/null +++ b/UVtools.Core/CoreSettings.cs @@ -0,0 +1,42 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; +using System.Threading.Tasks; + +namespace UVtools.Core +{ + public static class CoreSettings + { + #region Members + private static int _maxDegreeOfParallelism = -1; + + #endregion + + #region Properties + + /// + /// Gets or sets the maximum number of concurrent tasks enabled by this ParallelOptions instance. + /// Less or equal to 0 will set to auto number + /// 1 = Single thread + /// n = Multi threads + /// + public static int MaxDegreeOfParallelism + { + get => _maxDegreeOfParallelism; + set => _maxDegreeOfParallelism = value > 0 ? Math.Min(value, Environment.ProcessorCount) : -1; + } + + /// + /// Gets the ParallelOptions with set + /// + public static ParallelOptions ParallelOptions => new() {MaxDegreeOfParallelism = _maxDegreeOfParallelism}; + + #endregion + } +} diff --git a/UVtools.Core/FileFormats/CTBEncryptedFile.cs b/UVtools.Core/FileFormats/CTBEncryptedFile.cs index 667eea4..e37bf8c 100644 --- a/UVtools.Core/FileFormats/CTBEncryptedFile.cs +++ b/UVtools.Core/FileFormats/CTBEncryptedFile.cs @@ -1184,7 +1184,7 @@ namespace UVtools.Core.FileFormats } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -1333,7 +1333,7 @@ namespace UVtools.Core.FileFormats outputFile.Seek(outputFile.Position + layerTableSize, SeekOrigin.Begin); progress.Reset(OperationProgress.StatusEncodeLayers, LayerCount); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layerDef = new LayerDef(this, this[layerIndex]); diff --git a/UVtools.Core/FileFormats/CWSFile.cs b/UVtools.Core/FileFormats/CWSFile.cs index 2fed48b..3636aac 100644 --- a/UVtools.Core/FileFormats/CWSFile.cs +++ b/UVtools.Core/FileFormats/CWSFile.cs @@ -660,7 +660,7 @@ namespace UVtools.Core.FileFormats if (Printer == PrinterType.BeneMono) { - Parallel.For(0, LayerCount, + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, //new ParallelOptions { MaxDegreeOfParallelism = Printer == PrinterType.BeneMono ? 1 : 1 }, layerIndex => { @@ -862,7 +862,7 @@ namespace UVtools.Core.FileFormats if (Printer == PrinterType.BeneMono) { - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; diff --git a/UVtools.Core/FileFormats/CXDLPFile.cs b/UVtools.Core/FileFormats/CXDLPFile.cs index 91463c3..4a2fa6a 100644 --- a/UVtools.Core/FileFormats/CXDLPFile.cs +++ b/UVtools.Core/FileFormats/CXDLPFile.cs @@ -600,7 +600,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -647,7 +647,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -710,7 +710,7 @@ namespace UVtools.Core.FileFormats } - /*Parallel.For(0, LayerCount, + /*Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, //new ParallelOptions{MaxDegreeOfParallelism = 1}, layerIndex => { @@ -822,7 +822,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -862,7 +862,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) @@ -907,7 +907,7 @@ namespace UVtools.Core.FileFormats } progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = EmguExtensions.InitMat(Resolution); diff --git a/UVtools.Core/FileFormats/CXDLPv1File.cs b/UVtools.Core/FileFormats/CXDLPv1File.cs index 5ad49a1..ee83c9b 100644 --- a/UVtools.Core/FileFormats/CXDLPv1File.cs +++ b/UVtools.Core/FileFormats/CXDLPv1File.cs @@ -518,7 +518,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -558,7 +558,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -643,7 +643,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -678,7 +678,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) diff --git a/UVtools.Core/FileFormats/ChituboxFile.cs b/UVtools.Core/FileFormats/ChituboxFile.cs index ed1d571..6854d82 100644 --- a/UVtools.Core/FileFormats/ChituboxFile.cs +++ b/UVtools.Core/FileFormats/ChituboxFile.cs @@ -1874,7 +1874,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -2105,7 +2105,7 @@ namespace UVtools.Core.FileFormats } } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayerDefinitions[0, layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/FDGFile.cs b/UVtools.Core/FileFormats/FDGFile.cs index edeae11..1a8e456 100644 --- a/UVtools.Core/FileFormats/FDGFile.cs +++ b/UVtools.Core/FileFormats/FDGFile.cs @@ -961,7 +961,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1092,7 +1092,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/FileFormat.cs b/UVtools.Core/FileFormats/FileFormat.cs index 04a8a3d..6163492 100644 --- a/UVtools.Core/FileFormats/FileFormat.cs +++ b/UVtools.Core/FileFormats/FileFormat.cs @@ -2703,7 +2703,7 @@ namespace UVtools.Core.FileFormats if (LayerCount > 0) { - Parallel.ForEach(this, (layer) => + Parallel.ForEach(this, CoreSettings.ParallelOptions, layer => { if (progress.Token.IsCancellationRequested) return; var byteArr = layer.CompressedBytes; diff --git a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs index 6c0ebea..c153037 100644 --- a/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs +++ b/UVtools.Core/FileFormats/FlashForgeSVGXFile.cs @@ -505,7 +505,7 @@ namespace UVtools.Core.FileFormats SVGDocument.Groups = new List { new("background") }; var groups = new FlashForgeSVGXSvgGroup[LayerCount]; - Parallel.For(0, LayerCount, /*new ParallelOptions{MaxDegreeOfParallelism = 1},*/ layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -656,7 +656,7 @@ namespace UVtools.Core.FileFormats LayerManager.Init(SVGDocument.PrintParameters.LayerCount); progress.Reset(OperationProgress.StatusDecodeLayers, LayerCount); - Parallel.For(0, LayerCount, /*new ParallelOptions{MaxDegreeOfParallelism = 1},*/ layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/FileFormats/GR1File.cs b/UVtools.Core/FileFormats/GR1File.cs index 77f2cce..7ef5603 100644 --- a/UVtools.Core/FileFormats/GR1File.cs +++ b/UVtools.Core/FileFormats/GR1File.cs @@ -365,7 +365,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -399,7 +399,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -483,7 +483,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -515,7 +515,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = EmguExtensions.InitMat(Resolution); diff --git a/UVtools.Core/FileFormats/LGSFile.cs b/UVtools.Core/FileFormats/LGSFile.cs index e00e6cd..9551474 100644 --- a/UVtools.Core/FileFormats/LGSFile.cs +++ b/UVtools.Core/FileFormats/LGSFile.cs @@ -529,7 +529,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -607,7 +607,7 @@ namespace UVtools.Core.FileFormats layerData[layerIndex].Parent = this; } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = layerData[layerIndex].Decode()) diff --git a/UVtools.Core/FileFormats/MDLPFile.cs b/UVtools.Core/FileFormats/MDLPFile.cs index f62c05a..fa17498 100644 --- a/UVtools.Core/FileFormats/MDLPFile.cs +++ b/UVtools.Core/FileFormats/MDLPFile.cs @@ -324,7 +324,7 @@ namespace UVtools.Core.FileFormats var previews = new byte[ThumbnailsOriginalSize.Length][]; // Previews - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { if (progress.Token.IsCancellationRequested) return; var encodeLength = ThumbnailsOriginalSize[previewIndex].Area() * 2; @@ -358,7 +358,7 @@ namespace UVtools.Core.FileFormats { progress.Token.ThrowIfCancellationRequested(); - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = this[layerIndex]; @@ -440,7 +440,7 @@ namespace UVtools.Core.FileFormats inputFile.Seek(2, SeekOrigin.Current); } - Parallel.For(0, previews.Length, previewIndex => + Parallel.For(0, previews.Length, CoreSettings.ParallelOptions, previewIndex => { Thumbnails[previewIndex] = DecodeImage(DATATYPE_RGB565_BE, previews[previewIndex], ThumbnailsOriginalSize[previewIndex]); previews[previewIndex] = null; @@ -472,7 +472,7 @@ namespace UVtools.Core.FileFormats progress.Token.ThrowIfCancellationRequested(); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = EmguExtensions.InitMat(Resolution)) diff --git a/UVtools.Core/FileFormats/OSLAFile.cs b/UVtools.Core/FileFormats/OSLAFile.cs index 20e4834..2c4bad4 100644 --- a/UVtools.Core/FileFormats/OSLAFile.cs +++ b/UVtools.Core/FileFormats/OSLAFile.cs @@ -527,7 +527,7 @@ namespace UVtools.Core.FileFormats { var layerBytes = new byte[LayerCount][]; - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -687,7 +687,7 @@ namespace UVtools.Core.FileFormats layerBytes[layerIndex] = inputFile.ReadBytes(inputFile.ReadUIntLittleEndian()); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = DecodeImage(HeaderSettings.LayerDataType, layerBytes[layerIndex], Resolution)) diff --git a/UVtools.Core/FileFormats/PHZFile.cs b/UVtools.Core/FileFormats/PHZFile.cs index 94f34fb..be70c04 100644 --- a/UVtools.Core/FileFormats/PHZFile.cs +++ b/UVtools.Core/FileFormats/PHZFile.cs @@ -987,7 +987,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1115,7 +1115,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinitions[layerIndex].Decode((uint)layerIndex)) diff --git a/UVtools.Core/FileFormats/PhotonSFile.cs b/UVtools.Core/FileFormats/PhotonSFile.cs index f4492f8..292dcca 100644 --- a/UVtools.Core/FileFormats/PhotonSFile.cs +++ b/UVtools.Core/FileFormats/PhotonSFile.cs @@ -444,7 +444,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -518,7 +518,7 @@ namespace UVtools.Core.FileFormats } } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = layersDefinitions[layerIndex].Decode()) diff --git a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs index 7724596..a692b4c 100644 --- a/UVtools.Core/FileFormats/PhotonWorkshopFile.cs +++ b/UVtools.Core/FileFormats/PhotonWorkshopFile.cs @@ -1325,7 +1325,7 @@ namespace UVtools.Core.FileFormats foreach (var batch in BatchLayersIndexes()) { - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = this[layerIndex].LayerMat) @@ -1446,7 +1446,7 @@ namespace UVtools.Core.FileFormats }); } - Parallel.ForEach(batch, layerIndex => + Parallel.ForEach(batch, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = LayersDefinition[layerIndex].Decode()) diff --git a/UVtools.Core/Layer/LayerManager.cs b/UVtools.Core/Layer/LayerManager.cs index 34a2603..678c298 100644 --- a/UVtools.Core/Layer/LayerManager.cs +++ b/UVtools.Core/Layer/LayerManager.cs @@ -630,7 +630,7 @@ namespace UVtools.Core if (_boundingRectangle.IsEmpty) // Safe checking { progress.Reset(OperationProgress.StatusOptimizingBounds, LayerCount-1); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; @@ -775,7 +775,7 @@ namespace UVtools.Core Mat GetCachedMat(uint layerIndex) { if (cachedLayers[layerIndex] is not null) return cachedLayers[layerIndex]; - Parallel.For(layerIndex, Math.Min(layerIndex + cacheCount, LayerCount), i => + Parallel.For(layerIndex, Math.Min(layerIndex + cacheCount, LayerCount), CoreSettings.ParallelOptions, i => { if (this[i].IsEmpty) return; // empty layers cachedLayers[i] = this[i].LayerMat; @@ -825,7 +825,7 @@ namespace UVtools.Core GetCachedMat(rootLayerIndex); progress.Token.ThrowIfCancellationRequested(); uint layerAdvance = (uint) Math.Min(i + cacheCount, actionLayers.Count); - Parallel.For(i, layerAdvance, l => + Parallel.For(i, layerAdvance, CoreSettings.ParallelOptions, l => { var layerIndex = actionLayers[(int) l]; var layer = this[layerIndex]; @@ -1007,9 +1007,7 @@ namespace UVtools.Core progress.Reset(OperationProgress.StatusIslands, LayerCount); // Detect contours - Parallel.ForEach(this, - //new ParallelOptions{MaxDegreeOfParallelism = 1}, - layer => + Parallel.ForEach(this, CoreSettings.ParallelOptions, layer => { if (progress.Token.IsCancellationRequested) return; if (layer.IsEmpty) @@ -1422,8 +1420,8 @@ namespace UVtools.Core //foreach (var area in areas) //Parallel.ForEach(from t in areas where t.Type == LayerHollowArea.AreaType.Unknown select t, - // new ParallelOptions{MaxDegreeOfParallelism = 1}, area => - foreach(var area in areas) + // CoreSettings.ParallelOptions, area => + foreach (var area in areas) { //if (progress.Token.IsCancellationRequested) return; if (area.Type != LayerHollowArea.AreaType.Unknown) continue; // processed, ignore @@ -1437,7 +1435,7 @@ namespace UVtools.Core //List linkedAreas = new(); for (sbyte dir = 1; dir >= -1 && area.Type != LayerHollowArea.AreaType.Drain; dir -= 2) - //Parallel.ForEach(new sbyte[] {1, -1}, new ParallelOptions {MaxDegreeOfParallelism = 2}, dir => + //Parallel.ForEach(new sbyte[] {1, -1}, CoreSettings.ParallelOptions, dir => { Queue queue = new(); queue.Enqueue(area); @@ -1783,7 +1781,7 @@ namespace UVtools.Core } progress.Reset("Saving", (uint) modifiedLayers.Count); - Parallel.ForEach(modifiedLayers, (modifiedLayer, state) => + Parallel.ForEach(modifiedLayers, CoreSettings.ParallelOptions, modifiedLayer => { this[modifiedLayer.Key].LayerMat = modifiedLayer.Value; modifiedLayer.Value.Dispose(); @@ -1835,7 +1833,7 @@ namespace UVtools.Core Array.Resize(ref _layers, (int) newLayerCount); if (differenceLayerCount > 0 && initBlack) { - Parallel.For(oldLayerCount, newLayerCount, layerIndex => + Parallel.For(oldLayerCount, newLayerCount, CoreSettings.ParallelOptions, layerIndex => { this[layerIndex] = new Layer((uint)layerIndex, EmguExtensions.InitMat(SlicerFile.Resolution), this); }); @@ -1866,7 +1864,7 @@ namespace UVtools.Core // Allocate new layers if (initBlack) { - Parallel.For(insertAtLayerIndex, insertAtLayerIndex + layerCount, layerIndex => + Parallel.For(insertAtLayerIndex, insertAtLayerIndex + layerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint) layerIndex, EmguExtensions.InitMat(SlicerFile.Resolution), this); }); @@ -1917,7 +1915,7 @@ namespace UVtools.Core public Layer[] AllocateFromMat(Mat[] mats) { var layers = new Layer[mats.Length]; - Parallel.For(0L, mats.Length, i => + Parallel.For(0L, mats.Length, CoreSettings.ParallelOptions, i => { layers[i] = new Layer((uint)i, mats[i], this); }); diff --git a/UVtools.Core/Operations/OperationBlur.cs b/UVtools.Core/Operations/OperationBlur.cs index 9642812..7ec4de9 100644 --- a/UVtools.Core/Operations/OperationBlur.cs +++ b/UVtools.Core/Operations/OperationBlur.cs @@ -132,7 +132,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) diff --git a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs index 74da586..b400c6a 100644 --- a/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs +++ b/UVtools.Core/Operations/OperationCalibrateElephantFoot.cs @@ -661,7 +661,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } // Preview diff --git a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs index 11ed778..b69a64d 100644 --- a/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs +++ b/UVtools.Core/Operations/OperationCalibrateExposureFinder.cs @@ -1883,7 +1883,7 @@ namespace UVtools.Core.Operations var tableGrouped = table.GroupBy(pair => new {pair.Key.LayerHeight, pair.Key.BottomExposure, pair.Key.Exposure}).Distinct(); SlicerFile.BottomLayerCount = _bottomLayers; progress.ItemCount = (uint) (SlicerFile.LayerCount * table.Count); - Parallel.For(0, SlicerFile.LayerCount, layerIndex => + Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationCalibrateGrayscale.cs b/UVtools.Core/Operations/OperationCalibrateGrayscale.cs index 47308d3..308e7fe 100644 --- a/UVtools.Core/Operations/OperationCalibrateGrayscale.cs +++ b/UVtools.Core/Operations/OperationCalibrateGrayscale.cs @@ -449,7 +449,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; diff --git a/UVtools.Core/Operations/OperationCalibrateStressTower.cs b/UVtools.Core/Operations/OperationCalibrateStressTower.cs index 70df44d..9f8c8b6 100644 --- a/UVtools.Core/Operations/OperationCalibrateStressTower.cs +++ b/UVtools.Core/Operations/OperationCalibrateStressTower.cs @@ -333,19 +333,19 @@ namespace UVtools.Core.Operations var anchor = new Point(-1, -1); var kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), anchor);*/ - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { layers[layerIndex] = EmguExtensions.InitMat(SlicerFile.Resolution); }); - Parallel.For(0, baseLayers, layerIndex => + Parallel.For(0, baseLayers, CoreSettings.ParallelOptions, layerIndex => { int chamferOffset = (int) Math.Max(0, _chamferLayers - layerIndex); CvInvoke.Circle(layers[layerIndex], center, (int) baseRadius - chamferOffset, EmguExtensions.WhiteColor, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected); }); - Parallel.For(0, baseLayers+bodyLayers, layerIndex => + Parallel.For(0, baseLayers+bodyLayers, CoreSettings.ParallelOptions, layerIndex => { decimal angle = (layerIndex * _spiralAngleStepPerLayer) % 360m; for (byte spiral = 0; spiral < _spirals; spiral++) @@ -375,7 +375,7 @@ namespace UVtools.Core.Operations currrentlayer += bodyLayers; - Parallel.For(0, ceilLayers, i => + Parallel.For(0, ceilLayers, CoreSettings.ParallelOptions, i => { uint layerIndex = (uint)(currrentlayer + i); CvInvoke.Circle(layers[layerIndex], center, (int)baseRadius, EmguExtensions.WhiteColor, -1, _enableAntiAliasing ? LineType.AntiAlias : LineType.EightConnected); @@ -387,7 +387,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; @@ -418,7 +418,7 @@ namespace UVtools.Core.Operations var layers = GetLayers(); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint)layerIndex, layers[layerIndex], SlicerFile.LayerManager) {IsModified = true}; layers[layerIndex].Dispose(); diff --git a/UVtools.Core/Operations/OperationCalibrateTolerance.cs b/UVtools.Core/Operations/OperationCalibrateTolerance.cs index a6a8f50..a23bcb3 100644 --- a/UVtools.Core/Operations/OperationCalibrateTolerance.cs +++ b/UVtools.Core/Operations/OperationCalibrateTolerance.cs @@ -638,7 +638,7 @@ namespace UVtools.Core.Operations if (!addPart(step)) break; } - Parallel.For(0, layers.Length, layerIndex => + Parallel.For(0, layers.Length, CoreSettings.ParallelOptions, layerIndex => //for (var i = 0; i < layers.Length; i++) { layers[layerIndex] = layer.Clone(); @@ -646,7 +646,7 @@ namespace UVtools.Core.Operations if (_erodeBottomIterations > 0) { - Parallel.For(0, _bottomLayers, layerIndex => + Parallel.For(0, _bottomLayers, CoreSettings.ParallelOptions, layerIndex => { CvInvoke.Erode(layers[layerIndex], layers[layerIndex], kernel, anchor, _erodeBottomIterations, BorderType.Reflect101, default); }); @@ -654,7 +654,7 @@ namespace UVtools.Core.Operations if (_chamferLayers > 0) { - Parallel.For(0, _chamferLayers, layerIndexOffset => + Parallel.For(0, _chamferLayers, CoreSettings.ParallelOptions, layerIndexOffset => { var iteration = _chamferLayers - layerIndexOffset; CvInvoke.Erode(layers[layerIndexOffset], layers[layerIndexOffset], kernel, anchor, iteration, BorderType.Reflect101, default); @@ -676,7 +676,7 @@ namespace UVtools.Core.Operations }*/ } - Parallel.For(Math.Max(0u, LayerCount - 15), LayerCount, layerIndex => + Parallel.For(Math.Max(0u, LayerCount - 15), LayerCount, CoreSettings.ParallelOptions, layerIndex => { foreach (var keyValuePair in pointTextList) { @@ -688,7 +688,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; @@ -730,7 +730,7 @@ namespace UVtools.Core.Operations var layers = GetLayers(); - Parallel.For(0, LayerCount, layerIndex => + Parallel.For(0, LayerCount, CoreSettings.ParallelOptions, layerIndex => { newLayers[layerIndex] = new Layer((uint)layerIndex, layers[layerIndex], SlicerFile.LayerManager) {IsModified = true}; layers[layerIndex].Dispose(); diff --git a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs index 92c0564..62996e4 100644 --- a/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs +++ b/UVtools.Core/Operations/OperationCalibrateXYZAccuracy.cs @@ -721,7 +721,7 @@ namespace UVtools.Core.Operations { var flip = SlicerFile.DisplayMirror; if (flip == Enumerations.FlipDirection.None) flip = Enumerations.FlipDirection.Horizontally; - Parallel.ForEach(layers, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); + Parallel.ForEach(layers, CoreSettings.ParallelOptions, mat => CvInvoke.Flip(mat, mat, Enumerations.ToOpenCVFlipType(flip))); } return layers; diff --git a/UVtools.Core/Operations/OperationChangeResolution.cs b/UVtools.Core/Operations/OperationChangeResolution.cs index a43fdbe..505978b 100644 --- a/UVtools.Core/Operations/OperationChangeResolution.cs +++ b/UVtools.Core/Operations/OperationChangeResolution.cs @@ -162,7 +162,7 @@ namespace UVtools.Core.Operations progress.ItemCount = SlicerFile.LayerCount; var boundingRectangle = SlicerFile.BoundingRectangle; var newSize = new Size((int) NewResolutionX, (int) NewResolutionY); - Parallel.For(0, SlicerFile.LayerCount, layerIndex => + Parallel.For(0, SlicerFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs index e503ab6..321a815 100644 --- a/UVtools.Core/Operations/OperationDynamicLayerHeight.cs +++ b/UVtools.Core/Operations/OperationDynamicLayerHeight.cs @@ -588,7 +588,7 @@ namespace UVtools.Core.Operations matThresholdCache[layerIndex].Dispose(); matThresholdCache[layerIndex] = null; } - Parallel.For(fromLayerIndex, Math.Min(fromLayerIndex + CacheObjectCount, SlicerFile.LayerCount), layerIndex => + Parallel.For(fromLayerIndex, Math.Min(fromLayerIndex + CacheObjectCount, SlicerFile.LayerCount), CoreSettings.ParallelOptions, layerIndex => { if (matCache[layerIndex] is not null) return; // Already cached matCache[layerIndex] = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationFlip.cs b/UVtools.Core/Operations/OperationFlip.cs index 3510d3e..e9c2a43 100644 --- a/UVtools.Core/Operations/OperationFlip.cs +++ b/UVtools.Core/Operations/OperationFlip.cs @@ -100,7 +100,7 @@ namespace UVtools.Core.Operations #region Methods protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationInfill.cs b/UVtools.Core/Operations/OperationInfill.cs index 0793da7..b2ab150 100644 --- a/UVtools.Core/Operations/OperationInfill.cs +++ b/UVtools.Core/Operations/OperationInfill.cs @@ -135,7 +135,7 @@ namespace UVtools.Core.Operations mask = GetHoneycombMask(GetRoiSizeOrDefault()); } - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerArithmetic.cs b/UVtools.Core/Operations/OperationLayerArithmetic.cs index 721f8c9..e3a8411 100644 --- a/UVtools.Core/Operations/OperationLayerArithmetic.cs +++ b/UVtools.Core/Operations/OperationLayerArithmetic.cs @@ -288,7 +288,7 @@ namespace UVtools.Core.Operations } progress.Reset("Applied layers", (uint) SetLayers.Count); - Parallel.ForEach(SetLayers, layerIndex => + Parallel.ForEach(SetLayers, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; progress.LockAndIncrement(); diff --git a/UVtools.Core/Operations/OperationLayerExportGif.cs b/UVtools.Core/Operations/OperationLayerExportGif.cs index ae93843..c3d5f78 100644 --- a/UVtools.Core/Operations/OperationLayerExportGif.cs +++ b/UVtools.Core/Operations/OperationLayerExportGif.cs @@ -219,7 +219,7 @@ namespace UVtools.Core.Operations ROI = SlicerFile.BoundingRectangle; } - Parallel.For(0, TotalLayers, i => + Parallel.For(0, TotalLayers, CoreSettings.ParallelOptions, i => { if (progress.Token.IsCancellationRequested) return; uint layerIndex = (uint) (LayerIndexStart + i * (_skip + 1)); diff --git a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs index 3817514..9263f28 100644 --- a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs +++ b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs @@ -101,7 +101,7 @@ namespace UVtools.Core.Operations using var mask = GetMask(sumMat32); - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerExportImage.cs b/UVtools.Core/Operations/OperationLayerExportImage.cs index 5925b67..5748662 100644 --- a/UVtools.Core/Operations/OperationLayerExportImage.cs +++ b/UVtools.Core/Operations/OperationLayerExportImage.cs @@ -172,7 +172,7 @@ namespace UVtools.Core.Operations var slicedFileNameNoExt = SlicerFile.FilenameNoExt; - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerExportSkeleton.cs b/UVtools.Core/Operations/OperationLayerExportSkeleton.cs index 0fd56d0..9197c5f 100644 --- a/UVtools.Core/Operations/OperationLayerExportSkeleton.cs +++ b/UVtools.Core/Operations/OperationLayerExportSkeleton.cs @@ -86,7 +86,7 @@ namespace UVtools.Core.Operations using var mask = GetMask(skeletonSum); - Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs index c2997ee..6a05590 100644 --- a/UVtools.Core/Operations/OperationLayerImport.cs +++ b/UVtools.Core/Operations/OperationLayerImport.cs @@ -73,7 +73,7 @@ namespace UVtools.Core.Operations public override string ValidateInternally() { /*var result = new ConcurrentBag(); - Parallel.ForEach(Files, file => + Parallel.ForEach(Files, CoreSettings.ParallelOptions, file => { using (Mat mat = CvInvoke.Imread(file.TagString, ImreadModes.AnyColor)) { @@ -238,7 +238,7 @@ namespace UVtools.Core.Operations SL1File format = new(); format.LayerManager.Init((uint)keyImage.Count); - Parallel.ForEach(keyImage, pair => + Parallel.ForEach(keyImage, CoreSettings.ParallelOptions, pair => { if (progress.Token.IsCancellationRequested) return; using var mat = CvInvoke.Imread(pair.Value, ImreadModes.Grayscale); @@ -360,9 +360,7 @@ namespace UVtools.Core.Operations } progress.Reset(ProgressAction, fileFormat.LayerCount); - Parallel.For(0, fileFormat.LayerCount, - //new ParallelOptions{MaxDegreeOfParallelism = 1}, - i => + Parallel.For(0, fileFormat.LayerCount, CoreSettings.ParallelOptions, i => { if (progress.Token.IsCancellationRequested) return; uint layerIndex = (uint)(_startLayerIndex + i); diff --git a/UVtools.Core/Operations/OperationLayerReHeight.cs b/UVtools.Core/Operations/OperationLayerReHeight.cs index a7f8d30..44f153d 100644 --- a/UVtools.Core/Operations/OperationLayerReHeight.cs +++ b/UVtools.Core/Operations/OperationLayerReHeight.cs @@ -220,7 +220,7 @@ namespace UVtools.Core.Operations layerIndexes[i] = i * _selectedItem.Modifier; } - Parallel.ForEach(layerIndexes, layerIndex => + Parallel.ForEach(layerIndexes, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var oldLayer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationLightBleedCompensation.cs b/UVtools.Core/Operations/OperationLightBleedCompensation.cs index c3175af..dd86654 100644 --- a/UVtools.Core/Operations/OperationLightBleedCompensation.cs +++ b/UVtools.Core/Operations/OperationLightBleedCompensation.cs @@ -203,7 +203,7 @@ namespace UVtools.Core.Operations { var dimMats = GetDimMats(); if (dimMats.Length == 0) return false; - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.Core/Operations/OperationMask.cs b/UVtools.Core/Operations/OperationMask.cs index c310ae5..8b35a39 100644 --- a/UVtools.Core/Operations/OperationMask.cs +++ b/UVtools.Core/Operations/OperationMask.cs @@ -75,7 +75,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationMorph.cs b/UVtools.Core/Operations/OperationMorph.cs index 8c5f561..bdb29ad 100644 --- a/UVtools.Core/Operations/OperationMorph.cs +++ b/UVtools.Core/Operations/OperationMorph.cs @@ -155,9 +155,7 @@ namespace UVtools.Core.Operations out var maxIteration ); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, - //new ParallelOptions {MaxDegreeOfParallelism = 1}, - layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; int iterations = LayerManager.MutateGetIterationVar(isFade, (int)IterationsStart, (int)IterationsEnd, iterationSteps, maxIteration, LayerIndexStart, (uint)layerIndex); diff --git a/UVtools.Core/Operations/OperationMove.cs b/UVtools.Core/Operations/OperationMove.cs index deb3829..8b82d29 100644 --- a/UVtools.Core/Operations/OperationMove.cs +++ b/UVtools.Core/Operations/OperationMove.cs @@ -284,7 +284,7 @@ namespace UVtools.Core.Operations if (ROI.IsEmpty) ROI = SlicerFile.LayerManager.GetBoundingRectangle(progress); CalculateDstRoi(); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationPattern.cs b/UVtools.Core/Operations/OperationPattern.cs index 163980d..9e668b2 100644 --- a/UVtools.Core/Operations/OperationPattern.cs +++ b/UVtools.Core/Operations/OperationPattern.cs @@ -298,7 +298,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; diff --git a/UVtools.Core/Operations/OperationPixelArithmetic.cs b/UVtools.Core/Operations/OperationPixelArithmetic.cs index b6a1b9c..12fab9f 100644 --- a/UVtools.Core/Operations/OperationPixelArithmetic.cs +++ b/UVtools.Core/Operations/OperationPixelArithmetic.cs @@ -494,7 +494,7 @@ namespace UVtools.Core.Operations } - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) @@ -839,7 +839,7 @@ namespace UVtools.Core.Operations { var result = new string[mat.Height]; var span = mat.GetBytePointer(); - Parallel.For(0, mat.Height, y => + Parallel.For(0, mat.Height, CoreSettings.ParallelOptions, y => { result[y] = string.Empty; var pixelPos = mat.GetPixelPos(0, y); diff --git a/UVtools.Core/Operations/OperationPixelDimming.cs b/UVtools.Core/Operations/OperationPixelDimming.cs index 97df8bd..070e6ce 100644 --- a/UVtools.Core/Operations/OperationPixelDimming.cs +++ b/UVtools.Core/Operations/OperationPixelDimming.cs @@ -296,7 +296,7 @@ namespace UVtools.Core.Operations { var result = new string[mat.Height]; var span = mat.GetBytePointer(); - Parallel.For(0, mat.Height, y => + Parallel.For(0, mat.Height, CoreSettings.ParallelOptions, y => { result[y] = string.Empty; for (int x = 0; x < mat.Width; x++) @@ -649,7 +649,7 @@ namespace UVtools.Core.Operations CvInvoke.BitwiseNot(patternMask, patternMask); CvInvoke.BitwiseNot(alternatePatternMask, alternatePatternMask); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationRaftRelief.cs b/UVtools.Core/Operations/OperationRaftRelief.cs index 52401ee..d59d217 100644 --- a/UVtools.Core/Operations/OperationRaftRelief.cs +++ b/UVtools.Core/Operations/OperationRaftRelief.cs @@ -239,7 +239,7 @@ namespace UVtools.Core.Operations } progress.Reset(ProgressAction, firstSupportLayerIndex - _ignoreFirstLayers); - Parallel.For(_ignoreFirstLayers, firstSupportLayerIndex, layerIndex => + Parallel.For(_ignoreFirstLayers, firstSupportLayerIndex, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationRedrawModel.cs b/UVtools.Core/Operations/OperationRedrawModel.cs index abcc4be..cd23236 100644 --- a/UVtools.Core/Operations/OperationRedrawModel.cs +++ b/UVtools.Core/Operations/OperationRedrawModel.cs @@ -167,7 +167,7 @@ namespace UVtools.Core.Operations int startLayerIndex = (int)(SlicerFile.LayerCount - otherFile.LayerCount); if (startLayerIndex < 0) return false; - Parallel.For(0, otherFile.LayerCount, layerIndex => + Parallel.For(0, otherFile.LayerCount, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var fullMatLayerIndex = startLayerIndex + layerIndex; diff --git a/UVtools.Core/Operations/OperationRepairLayers.cs b/UVtools.Core/Operations/OperationRepairLayers.cs index cdafcc3..c554e26 100644 --- a/UVtools.Core/Operations/OperationRepairLayers.cs +++ b/UVtools.Core/Operations/OperationRepairLayers.cs @@ -179,7 +179,7 @@ namespace UVtools.Core.Operations if (!issuesGroup.Any()) break; // Nothing to process islandsToRecompute.Clear(); - Parallel.ForEach(issuesGroup, group => + Parallel.ForEach(issuesGroup, CoreSettings.ParallelOptions, group => { if (progress.Token.IsCancellationRequested) return; Layer layer = SlicerFile[group.Key]; @@ -234,7 +234,7 @@ namespace UVtools.Core.Operations progress.Reset("Attempt to attach islands below", (uint) islandsToProcess.Count); - Parallel.ForEach(issuesGroup, group => + Parallel.ForEach(issuesGroup, CoreSettings.ParallelOptions, group => { using var mat = SlicerFile[group.Key].LayerMat; var matSpan = mat.GetDataByteSpan(); @@ -319,7 +319,7 @@ namespace UVtools.Core.Operations progress.Reset(ProgressAction, LayerRangeCount); if (_repairIslands || _repairResinTraps) { - Parallel.For(LayerIndexStart, LayerIndexEnd, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var layer = SlicerFile[layerIndex]; diff --git a/UVtools.Core/Operations/OperationResize.cs b/UVtools.Core/Operations/OperationResize.cs index b3d6c50..394e4ac 100644 --- a/UVtools.Core/Operations/OperationResize.cs +++ b/UVtools.Core/Operations/OperationResize.cs @@ -156,7 +156,7 @@ namespace UVtools.Core.Operations decimal xSteps = Math.Abs(100 - _x) / (LayerIndexEnd - LayerIndexStart + 1); decimal ySteps = Math.Abs(100 - _y) / (LayerIndexEnd - LayerIndexStart + 1); - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; var newX = _x; diff --git a/UVtools.Core/Operations/OperationRotate.cs b/UVtools.Core/Operations/OperationRotate.cs index fe9e215..717762c 100644 --- a/UVtools.Core/Operations/OperationRotate.cs +++ b/UVtools.Core/Operations/OperationRotate.cs @@ -84,7 +84,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationSolidify.cs b/UVtools.Core/Operations/OperationSolidify.cs index b689799..f108953 100644 --- a/UVtools.Core/Operations/OperationSolidify.cs +++ b/UVtools.Core/Operations/OperationSolidify.cs @@ -86,7 +86,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using var mat = SlicerFile[layerIndex].LayerMat; diff --git a/UVtools.Core/Operations/OperationThreshold.cs b/UVtools.Core/Operations/OperationThreshold.cs index 4754f00..47faf36 100644 --- a/UVtools.Core/Operations/OperationThreshold.cs +++ b/UVtools.Core/Operations/OperationThreshold.cs @@ -81,7 +81,7 @@ namespace UVtools.Core.Operations protected override bool ExecuteInternally(OperationProgress progress) { - Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex => + Parallel.For(LayerIndexStart, LayerIndexEnd + 1, CoreSettings.ParallelOptions, layerIndex => { if (progress.Token.IsCancellationRequested) return; using (var mat = SlicerFile[layerIndex].LayerMat) diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index a8558b4..5de153d 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ https://github.com/sn4k3/UVtools https://github.com/sn4k3/UVtools MSLA/DLP, file analysis, calibration, repair, conversion and manipulation - 2.20.4 + 2.20.5 Copyright © 2020 PTRTECH UVtools.png AnyCPU;x64 diff --git a/UVtools.ScriptSample/ScriptInsetSample.cs b/UVtools.ScriptSample/ScriptInsetSample.cs index 015fe04..9b6de73 100644 --- a/UVtools.ScriptSample/ScriptInsetSample.cs +++ b/UVtools.ScriptSample/ScriptInsetSample.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using UVtools.Core.Scripting; using Emgu.CV; using Emgu.CV.CvEnum; +using UVtools.Core; namespace UVtools.ScriptSample { @@ -90,7 +91,7 @@ namespace UVtools.ScriptSample Progress.Reset("Inset layers", Operation.LayerRangeCount); // Sets the progress name and number of items to process // Loop user selected layers in parallel, this will put each core of CPU working here on parallel - Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, layerIndex => + Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (Progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs b/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs index b7fc518..d272108 100644 --- a/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs +++ b/UVtools.ScriptSample/ScriptLightBleedCompensationSample.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using UVtools.Core.Scripting; using Emgu.CV; using Emgu.CV.Structure; +using UVtools.Core; using UVtools.Core.Extensions; namespace UVtools.ScriptSample @@ -86,7 +87,7 @@ namespace UVtools.ScriptSample var brightnesses = Levels; // Loop user selected layers in parallel, this will put each core of CPU working here on parallel - Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, layerIndex => + Parallel.For(Operation.LayerIndexStart, Operation.LayerIndexEnd+1, CoreSettings.ParallelOptions, layerIndex => { if (Progress.Token.IsCancellationRequested) return; // Abort operation, user requested cancellation diff --git a/UVtools.WPF/MainWindow.Issues.cs b/UVtools.WPF/MainWindow.Issues.cs index 0e9def1..1308b0e 100644 --- a/UVtools.WPF/MainWindow.Issues.cs +++ b/UVtools.WPF/MainWindow.Issues.cs @@ -116,7 +116,7 @@ namespace UVtools.WPF bool result = false; try { - Parallel.ForEach(processIssues, layerIssues => + Parallel.ForEach(processIssues, CoreSettings.ParallelOptions, layerIssues => { if (Progress.Token.IsCancellationRequested) return; using (var image = SlicerFile[layerIssues.Key].LayerMat) diff --git a/UVtools.WPF/MainWindow.LayerPreview.cs b/UVtools.WPF/MainWindow.LayerPreview.cs index 5a047bd..4e94c57 100644 --- a/UVtools.WPF/MainWindow.LayerPreview.cs +++ b/UVtools.WPF/MainWindow.LayerPreview.cs @@ -796,7 +796,7 @@ namespace UVtools.WPF bool showSimilarityInstead = Settings.LayerPreview.LayerDifferenceHighlightSimilarityInstead; - Parallel.For(rect.Y, rect.Bottom, y => + Parallel.For(rect.Y, rect.Bottom, CoreSettings.ParallelOptions, y => { for (int x = rect.X; x < rect.Right; x++) { diff --git a/UVtools.WPF/UVtools.WPF.csproj b/UVtools.WPF/UVtools.WPF.csproj index 1b1922b..3f1d96f 100644 --- a/UVtools.WPF/UVtools.WPF.csproj +++ b/UVtools.WPF/UVtools.WPF.csproj @@ -12,7 +12,7 @@ LICENSE https://github.com/sn4k3/UVtools Git - 2.20.4 + 2.20.5 diff --git a/UVtools.WPF/UserSettings.cs b/UVtools.WPF/UserSettings.cs index 2ac29c6..b76150e 100644 --- a/UVtools.WPF/UserSettings.cs +++ b/UVtools.WPF/UserSettings.cs @@ -9,6 +9,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Threading.Tasks; using System.Xml.Serialization; using Avalonia.Media; using JetBrains.Annotations; @@ -22,7 +23,7 @@ namespace UVtools.WPF public sealed class UserSettings : BindableBase { #region Constants - public const ushort SETTINGS_VERSION = 4; + public const ushort SETTINGS_VERSION = 5; #endregion #region Sub classes @@ -34,6 +35,8 @@ namespace UVtools.WPF private bool _startMaximized = true; private bool _checkForUpdatesOnStartup = true; private bool _loadDemoFileOnStartup = true; + private int _maxDegreeOfParallelism = -1; + private bool _windowsCanResize; private bool _windowsTakeIntoAccountScreenScaling = true; private ushort _windowsHorizontalMargin = 100; @@ -48,7 +51,6 @@ namespace UVtools.WPF private bool _promptOverwriteFileSave = true; private string _fileSaveNamePrefix; private string _fileSaveNameSuffix = "_copy"; - private int _maxDegreeOfParallelism; public bool StartMaximized @@ -69,6 +71,15 @@ namespace UVtools.WPF set => RaiseAndSetIfChanged(ref _loadDemoFileOnStartup, value); } + /// + /// Gets or sets the maximum number of concurrent tasks enabled by a ParallelOptions instance. + /// + public int MaxDegreeOfParallelism + { + get => _maxDegreeOfParallelism; + set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, Math.Min(value, Environment.ProcessorCount)); + } + public bool WindowsCanResize { get => _windowsCanResize; @@ -154,19 +165,7 @@ namespace UVtools.WPF set => RaiseAndSetIfChanged(ref _fileSaveNameSuffix, value); } - /// - /// Gets or sets the maximum number of concurrent tasks enabled by a ParallelOptions instance. - /// - public int MaxDegreeOfParallelism - { - get => _maxDegreeOfParallelism; - set => RaiseAndSetIfChanged(ref _maxDegreeOfParallelism, value); - } - - public GeneralUserSettings() - { - MaxDegreeOfParallelism = Environment.ProcessorCount; - } + public GeneralUserSettings() { } public GeneralUserSettings Clone() { @@ -1417,16 +1416,26 @@ namespace UVtools.WPF using var myXmlReader = new StreamReader(FilePath); _instance = (UserSettings)serializer.Deserialize(myXmlReader); if (_instance.General.MaxDegreeOfParallelism <= 0) - _instance.General.MaxDegreeOfParallelism = Environment.ProcessorCount; + { + _instance.General.MaxDegreeOfParallelism = -1; + } + else + { + _instance.General.MaxDegreeOfParallelism = Math.Min(_instance.General.MaxDegreeOfParallelism, Environment.ProcessorCount); + } + if (_instance.SettingsVersion < SETTINGS_VERSION) { // Upgrade - + if (_instance.SettingsVersion <= 4) + { + _instance.General.MaxDegreeOfParallelism = -1; + } _instance.SettingsVersion = SETTINGS_VERSION; } - + CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; } catch (Exception e) { @@ -1443,6 +1452,7 @@ namespace UVtools.WPF { Instance.SavesCount++; _instance.ModifiedDateTime = DateTime.Now; + CoreSettings.MaxDegreeOfParallelism = _instance.General.MaxDegreeOfParallelism; var serializer = new XmlSerializer(_instance.GetType()); try { diff --git a/UVtools.WPF/Windows/SettingsWindow.axaml b/UVtools.WPF/Windows/SettingsWindow.axaml index e6e5e26..6389676 100644 --- a/UVtools.WPF/Windows/SettingsWindow.axaml +++ b/UVtools.WPF/Windows/SettingsWindow.axaml @@ -32,6 +32,93 @@ + + + + + + + + + + + + +