using Newtonsoft.Json;
using Colourful;
using Colourful.Conversion;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.BL.FineTuning;
using Tango.Core;
using Tango.Core.Commands;
using Tango.Core.DI;
using Tango.Core.Helpers;
using Tango.Documents;
using Tango.Explorer;
using Tango.Integration.Operation;
using Tango.PDF;
using Tango.PPC.Common;
using Tango.PPC.Common.Application;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.Navigation;
using Tango.PPC.Common.Notifications;
using Tango.PPC.Common.Notifications.NotificationItems;
using Tango.PPC.Common.Printing;
using Tango.PPC.Common.Storage;
using Tango.PPC.Jobs.ColorCorrectionTool;
using Tango.PPC.Jobs.FineTuning;
using Tango.PPC.Jobs.Models;
using Tango.PPC.Jobs.Reports;
using Tango.PPC.Storage;
using Tango.PPC.Storage.Models;
using Tango.Settings;
using Tango.SharedUI;
using ColorMine.ColorSpaces;
namespace Tango.PPC.Jobs.Dialogs
{
public class VectorFineTuningDialogVM : DialogViewVM
{
private JobHandler _handler;
private String _sessionID;
#region Properties
private RunningJobStatus _runningJobStatus;
///
/// Gets or sets the running job status.
///
public RunningJobStatus RunningJobStatus
{
get { return _runningJobStatus; }
set { _runningJobStatus = value; RaisePropertyChangedAuto(); }
}
///
/// Gets or sets the machine provider.
///
[TangoInject]
public IMachineProvider MachineProvider { get; set; }
///
/// Gets or sets the notification provider.
///
[TangoInject]
public INotificationProvider NotificationProvider { get; set; }
///
/// Gets or sets the printing manager.
///
[TangoInject]
public IPrintingManager PrintingManager { get; set; }
[TangoInject]
public INavigationManager NavigationManager { get; set; }
///
/// Gets or sets the storage provider.
///
[TangoInject]
public IStorageProvider StorageProvider { get; set; }
[TangoInject]
public IPPCApplicationManager ApplicationManager { get; set; }
public BrushStopModel BrushStopModel { get; set; }
public ColorSpaces OpenFromColorSpace { get; set; }
private bool _isOutOfGamut;
///
/// Gets or sets a value indicating whether this instance is out of gamut.
///
public bool IsOutOfGamut
{
get { return _isOutOfGamut; }
set
{
if (_isOutOfGamut != value)
{
_isOutOfGamut = value;
RaisePropertyChangedAuto();
}
}
}
//private System.Windows.Media.Color _targetcolor;
//public System.Windows.Media.Color TargetColor
//{
// get { return _targetcolor; }
// set
// {
// _targetcolor = value;
// RaisePropertyChanged(nameof(ColorBrush));
// }
//}
public SolidColorBrush ColorBrush
{
get
{
Lab lab = new Lab(TargetL, TargetA, TargetB);
Rgb rgb = new Rgb(lab.ToRgb());
return new SolidColorBrush() { Color = Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B) };
//return new SolidColorBrush(TargetColor);
}
}
protected Double _targetL;
public Double TargetL
{
get
{
return _targetL;
}
set
{
if (_targetL != value)
{
_targetL = value;
RaisePropertyChangedAuto();
}
}
}
protected Double _targetA;
///
/// Gets or sets the BrushStopModel a.
///
public Double TargetA
{
get
{
return _targetA;
}
set
{
if (_targetA != value)
{
_targetA = value;
RaisePropertyChangedAuto();
OnLABChanged();
}
}
}
protected Double _targetB;
///
/// Gets or sets the BrushStopModel b.
///
public Double TargetB
{
get
{
return _targetB;
}
set
{
if (_targetB != value)
{
_targetB = value;
RaisePropertyChangedAuto();
OnLABChanged();
}
}
}
protected Double? _measuredL;
///
/// Gets or sets the Measured l.
///
public Double? MeasuredL
{
get
{
return _measuredL;
}
set
{
if (_measuredL != value)
{
_measuredL = value;
RaisePropertyChangedAuto();
if (ActiveLogModel != null)
ActiveLogModel.L = _measuredL;
OnLABChanged();
}
}
}
protected Double? _measuredA;
///
/// Gets or sets the Measured a.
///
public Double? MeasuredA
{
get
{
return _measuredA;
}
set
{
if (_measuredA != value)
{
_measuredA = value;
RaisePropertyChangedAuto();
if (ActiveLogModel != null)
ActiveLogModel.A = _measuredA;
OnLABChanged();
}
}
}
protected Double? _measuredB;
///
/// Gets or sets the Measured b.
///
public Double? MeasuredB
{
get
{
return _measuredB;
}
set
{
if (_measuredB != value)
{
_measuredB = value;
RaisePropertyChangedAuto();
if (ActiveLogModel != null)
ActiveLogModel.B = _measuredB;
OnLABChanged();
}
}
}
protected Double? _dL;
///
/// Gets or sets the delta L
///
public Double? DL
{
get { return _dL; }
set
{
if (_dL != value)
{
_dL = value;
if (ActiveLogModel != null)
ActiveLogModel.dL = _dL == null? 0: (double)_dL;
RaisePropertyChangedAuto();
}
}
}
///
/// Gets the measured h for show text in deltaH.
///
public double? MeasuredH
{
get {
if(IsValidLAB())
{
var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
LabColor labColor = new LabColor((double)MeasuredL, (double)MeasuredA, (double)MeasuredB);
var LCH_input = converter.ToLChab(labColor);
return LCH_input.h;
}
return null;
}
}
private bool _IsTargetVisible;
public bool IsTargetVisible
{
get { return _IsTargetVisible; }
set {
if (_IsTargetVisible != value)
{
_IsTargetVisible = value;
RaisePropertyChangedAuto();
}
}
}
protected Double? _dC;
///
/// Gets or sets the delta C
///
public Double? DC
{
get { return _dC; }
set
{
if (_dC != value)
{
_dC = value;
if (ActiveLogModel != null)
ActiveLogModel.dC = _dC == null ? 0 : (double)_dC;
RaisePropertyChangedAuto();
}
}
}
protected Double? _dH;
///
/// Gets or sets the delta Hue
///
public Double? DH
{
get { return _dH; }
set
{
if (_dH != value)
{
_dH = value;
if (ActiveLogModel != null)
ActiveLogModel.dH = _dH == null ? 0 : (double)_dH;
RaisePropertyChangedAuto();
RaisePropertyChanged(nameof(MeasuredH));
}
}
}
protected Double? _deltaE;
///
/// Gets or sets the delta Hue
///
public Double? DeltaE
{
get { return _deltaE; }
set
{
if (_deltaE != value)
{
_deltaE = value;
RaisePropertyChangedAuto();
}
}
}
private bool _CorrectOnlyHue;
public bool CorrectOnlyHue
{
get { return _CorrectOnlyHue; }
set
{
if(_CorrectOnlyHue != value)
{
_CorrectOnlyHue = value;
if (ActiveLogModel != null)
ActiveLogModel.CorrectOnlyHue = _CorrectOnlyHue;
VectorCorrection();
RaisePropertyChangedAuto();
}
}
}
protected Double _cyan;
///
/// Gets or sets the cyan.
///
public Double Cyan
{
get
{
return _cyan;
}
set
{
if (_cyan != value)
{
_cyan = value;
RaisePropertyChangedAuto();
}
}
}
protected Double _magenta;
///
/// Gets or sets the magenta.
///
public Double Magenta
{
get
{
return _magenta;
}
set
{
if (_magenta != value)
{
_magenta = value;
RaisePropertyChangedAuto();
}
}
}
protected Double _yellow;
///
/// Gets or sets the yellow.
///
public Double Yellow
{
get
{
return _yellow;
}
set
{
if (_yellow != value)
{
_yellow = value;
RaisePropertyChangedAuto();
}
}
}
protected Double _black;
///
/// Gets or sets the black.
///
public Double Black
{
get
{
return _black;
}
set
{
if (_black != value)
{
_black = value;
RaisePropertyChangedAuto();
}
}
}
public int TrialNumber
{
get
{
if (ActiveLogModel == null)
return 1;
return ActiveLogModel.TrialNumber + 1;
}
}
public TestColor TestColor { get; set; }
private SynchronizedObservableCollection _trialsLogItems;
public SynchronizedObservableCollection TrialsLogitems
{
get { return _trialsLogItems; }
set
{
_trialsLogItems = value;
RaisePropertyChangedAuto();
}
}
private TrialsLogModel _activeLogModel;
public TrialsLogModel ActiveLogModel
{
get { return _activeLogModel; }
set
{
_activeLogModel = value;
RaisePropertyChangedAuto();
}
}
private TrialsLogModel _selectedLog;
public TrialsLogModel SelectedLog
{
get { return _selectedLog; }
set
{
_selectedLog = value;
RaisePropertyChangedAuto();
OKCommand.RaiseCanExecuteChanged();
}
}
private bool _isExpanderOpened;
public bool IsExpanderOpened
{
get { return _isExpanderOpened; }
set
{
_isExpanderOpened = value;
RaisePropertyChangedAuto();
}
}
private bool _isJobRunning;
public bool IsJobRunning
{
get { return _isJobRunning; }
set
{
_isJobRunning = value;
RaisePropertyChangedAuto();
Application.Current.Dispatcher.Invoke(() =>
{
OKCommand.RaiseCanExecuteChanged();
RaisePropertyChanged(nameof(IsDisableInputLAB));
});
}
}
private bool _isJobFailed;
public bool IsJobFailed
{
get { return _isJobFailed; }
set { _isJobFailed = value; RaisePropertyChangedAuto(); }
}
private String _jobFailedReason;
public String JobFailedReason
{
get { return _jobFailedReason; }
set { _jobFailedReason = value; RaisePropertyChangedAuto(); }
}
private bool IsPrepareToStartJob { get; set; }
public bool IsDisableInputLAB
{
get
{
return IsJobRunning == true || (TrialsLogitems != null && TrialsLogitems.Count > 10);
}
}
private bool _isManualFineTuning;
///
/// Gets or sets a value indicating whether this instance is vector fine tuning.
///
///
/// true if this instance is Automatic tab selected; otherwise, manual .
///
public bool IsManualFineTuning
{
get { return _isManualFineTuning; }
set {
if(_isManualFineTuning != value)
{
_isManualFineTuning = value;
if(_isManualFineTuning )
{
_selectedTabIndex = 1;
RaisePropertyChanged(nameof(SelectedTabIndex));
}
else
{
_selectedTabIndex = 0;
RaisePropertyChanged(nameof(SelectedTabIndex));
}
if(ActiveLogModel != null)
{
ActiveLogModel.IsManualCorrection = IsManualFineTuning;
}
RaisePropertyChangedAuto();
}
}
}
private bool _isOnlyManual;
///
/// Gets or sets a value indicating whether this instance is only manual. Opened from CMYK tab.
///
public bool IsOnlyManual
{
get { return _isOnlyManual; }
set {
_isOnlyManual = value;
RaisePropertyChangedAuto();
}
}
private int _selectedTabIndex;
///
/// Gets or sets the index of the selected category.
///
public int SelectedTabIndex
{
get { return _selectedTabIndex; }
set
{
if (_selectedTabIndex != value)
{
_selectedTabIndex = value;
RaisePropertyChangedAuto();
IsManualFineTuning = (value == 1);
InvalidateRelayCommands();
}
}
}
public VisualOffsetModel VisualCorrectionModel { get; set; }
private double _lightnessOffset;
public double LightnessOffset
{
get { return _lightnessOffset; }
set {
if(_lightnessOffset != value)
{
_lightnessOffset = value;
if (ActiveLogModel != null)
ActiveLogModel.LightnessOffset = _lightnessOffset;
OnLightnessOffsetChanged();
RaisePropertyChangedAuto();
}
}
}
private double _chromaOffset;
public double ChromaOffset
{
get { return _chromaOffset; }
set
{
if (_chromaOffset != value)
{
_chromaOffset = value;
if (ActiveLogModel != null)
ActiveLogModel.ChromaOffset = _chromaOffset;
OnChromaOffsetChanged();
RaisePropertyChangedAuto();
}
}
}
private double _hueOffset;
public double HueOffset
{
get { return _hueOffset; }
set
{
if (_hueOffset != value)
{
_hueOffset = value;
if (ActiveLogModel != null)
ActiveLogModel.HueOffset = _hueOffset;
OnHueOffsetChanged();
RaisePropertyChangedAuto();
}
}
}
private int _fineTuningTrialLengthMeters;
public int FineTuningTrialLengthMeters
{
get { return _fineTuningTrialLengthMeters; }
set
{
_fineTuningTrialLengthMeters = value;
RaisePropertyChangedAuto();
OnUpdateSettingineTuningTrialLengthMeters();
}
}
#endregion
#region Commands
public RelayCommand TestCommand { get; set; }
public RelayCommand ByPassTestCommand { get; set; }
public RelayCommand StopCommand { get; set; }
public RelayCommand ClearTrialsCommand { get; set; }
public RelayCommand ExportTrialsCommand { get; set; }
public RelayCommand DeleteTrialCommand { get; set; }
///
/// Gets or sets the pressed command.
/// { }); ;
IsExpanderOpened = true;
IsTargetVisible = false;
TangoIOC.Default.Inject(this);
_CorrectOnlyHue = true;
IsManualFineTuning = false;
IsOnlyManual = false;
VisualCorrectionModel = new VisualOffsetModel();
var settings = SettingsManager.Default.GetOrCreate();
FineTuningTrialLengthMeters = settings.FineTuningTrialLengthMeters;
}
///
/// Initializes at open the dialog.
///
public void Init(BrushStopModel brushstop, ColorSpaces colorspace)// double l, double a, double b)//, System.Windows.Media.Color targetColor)
{
CorrectOnlyHue = false;
LightnessOffset = 0.0;
ChromaOffset = 0.0;
HueOffset = 0.0;
DC = null;
DL = null;
DH = null;
DeltaE = null;
MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted;
MachineProvider.MachineOperator.PrintingEnded += MachineOperator_PrintingEnded;
MachineProvider.MachineOperator.PrintingCompleted += MachineOperator_PrintingCompleted;
MachineProvider.MachineOperator.JobRunsLogger.JobRunAvailable += JobRunsLogger_JobRunAvailable;
BrushStopModel = brushstop.Clone();
BrushStopModel.Guid = brushstop.Guid;
IsOutOfGamut = brushstop.IsOutOfGamut;
OpenFromColorSpace = colorspace;
if (OpenFromColorSpace == ColorSpaces.Catalog && brushstop.ColorCatalogsItem != null)
{
TargetL = BrushStopModel.ColorCatalogsItem.L;
TargetA = BrushStopModel.ColorCatalogsItem.A;
TargetB = BrushStopModel.ColorCatalogsItem.B;
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.LiquidVolumes.ResetVolume();
foreach (var liquidVolume in BrushStopModel.LiquidVolumes.Where(x => x.IdsPack.LiquidType.AvailableForStandardUser))
{
liquidVolume.Volume = brushstop.ColorCatalogsItem.GetLiquidVolumeByName(liquidVolume.IdsPack.LiquidType.DisplayName);
}
BrushStopModel.PreventPropertyUpdate = false;
IsOnlyManual = false;
}
else if(OpenFromColorSpace == ColorSpaces.Volume)
{
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = 0;
BrushStopModel.A = 0;
BrushStopModel.B = 0;
BrushStopModel.PreventPropertyUpdate = false;
BrushStopModel.ConvertColorToLAB();
TargetL = BrushStopModel.L;
TargetB = BrushStopModel.B;
TargetA = BrushStopModel.A;
IsOnlyManual = true;
}
else
{
TargetL = brushstop.L;
TargetB = brushstop.B;
TargetA = brushstop.A;
BrushStopModel.ConvertColorToVolume();
var blackVolume = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Black);
if (blackVolume.Volume > 0 && blackVolume.Volume < 0.5)
{
BrushStopModel.PreventPropertyUpdate = true;
blackVolume.Volume = 0;
BrushStopModel.PreventPropertyUpdate = false;
}
BrushStopModel.ColorSpace = ColorSpaces.LAB;
IsOnlyManual = false;
}
_sessionID = BrushStopModel.Guid + $"{TargetL}{TargetA}{TargetB}";
Cyan = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Cyan).Volume;
Magenta = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Magenta).Volume;
Yellow = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Yellow).Volume;
Black = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Black).Volume;
MeasuredL = MeasuredB = MeasuredA = null;
TestColor = null;
TestColor = TrialsLogEngine.Default.GetByBrushStopGuid(BrushStopModel.Guid);
if (TestColor == null )
{
ActiveLogModel = new TrialsLogModel(0, Cyan, Magenta, Yellow, Black);
ActiveLogModel.SuggestionL = TargetL;
ActiveLogModel.SuggestionA = TargetA;
ActiveLogModel.SuggestionB = TargetB;
TrialsLogitems = new SynchronizedObservableCollection();
TrialsLogitems.Add(ActiveLogModel);
InitManualCorrection();
//TEST
//for(int i = 1; i < 10; i++)
//{
// var model = new TrialsLogModel(i , Cyan, Magenta, Yellow, Black);
// TrialsLogitems.Insert(0, model);
//}
}
else
{
TrialsLogitems = new SynchronizedObservableCollection(TestColor.TrialslogList.OrderByDescending(x => x.TrialNumber));
int maxTrialsNumber = TrialsLogitems.Max(x => x.TrialNumber);
ActiveLogModel = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == maxTrialsNumber);
if (ActiveLogModel == null)
{
ActiveLogModel = new TrialsLogModel(0, Cyan, Magenta, Yellow, Black);
ActiveLogModel.SuggestionL = TargetL;
ActiveLogModel.SuggestionA = TargetA;
ActiveLogModel.SuggestionB = TargetB;
TrialsLogitems.Add(ActiveLogModel);
}
if (ActiveLogModel.IsTested == false)
{
MeasuredL = ActiveLogModel.L;
MeasuredA = ActiveLogModel.A;
MeasuredB = ActiveLogModel.B;
}
ActiveLogModel.IsActiveTrial = true;
ActiveLogModel.IsSelectionEnable = true;
var minValue = TrialsLogitems.Min(x => (double?)x.DeltaE);
if(minValue != null && minValue < 2)
{
TrialsLogitems.Where(x=> (double?)x.DeltaE == minValue).ToList().ForEach(i => i.IsBest = true);
}
UpdateManualCorrection();
LightnessOffset = ActiveLogModel.LightnessOffset;
ChromaOffset = ActiveLogModel.ChromaOffset;
HueOffset = ActiveLogModel.HueOffset;
}
OKCommand.RaiseCanExecuteChanged();
TestCommand.RaiseCanExecuteChanged();
ByPassTestCommand.RaiseCanExecuteChanged();
IsVisible = true;
RaisePropertyChanged(nameof(TrialsLogitems));
RaisePropertyChanged(nameof(IsDisableInputLAB));
RaisePropertyChanged(nameof(TrialNumber));
RaisePropertyChanged(nameof(ColorBrush));
if(IsOnlyManual)
SelectedTabIndex = 1;
else
SelectedTabIndex = 0;
}
public void InitManualCorrection()
{
if (ActiveLogModel == null)
return;
double l = MeasuredL == null ? TargetL : (double)MeasuredL;
double a = MeasuredA == null ? TargetA : (double)MeasuredA;
double b = MeasuredB == null ? TargetB : (double)MeasuredB;
LabColor labColor = new LabColor(l, a, b);
var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
var last_LCH = converter.ToLChab(labColor);
VisualCorrectionModel.InitLAB(l, a, b, last_LCH.C, last_LCH.h);
}
public void UpdateManualCorrection()
{
if(ActiveLogModel == null)
return;
double l = MeasuredL == null ? ActiveLogModel.SuggestionL: (double) MeasuredL;
double a = MeasuredA == null ? ActiveLogModel.SuggestionA : (double)MeasuredA;
double b = MeasuredB == null ? ActiveLogModel.SuggestionB : (double)MeasuredB;
VisualCorrectionModel.UpdateSourceLAB(l, a, b );
VisualCorrectionModel.UpdateManualColors();
}
#region Methods
protected override bool CanOK()
{
return (SelectedLog != null && IsJobRunning == false);
}
private async void ExportTrialsLog(object obj)
{
if (!StorageProvider.IsConnected)
{
await NotificationProvider.ShowError("No storage device connected.");
return;
}
//var result = await NavigationManager.
// NavigateForResult(
// new StorageNavigationRequest()
// {
// Intent = StorageNavigationIntent.SaveFile,
// DefaultFileName = "Color_Correction_Report",
// Filter = ExplorerFileDefinition.PDFFile.Extension,
// Title = "Save Color Correction Report",
// });
// if (result != null)
{
DateTime reportDateTime = DateTime.UtcNow.ToLocalTime();
ColorCorrectionRepotVM vm = new ColorCorrectionRepotVM()
{
JobName = BrushStopModel.SegmentModel.Job.Name,
TargetColor = String.Format($"L*{TargetL:0.##} a*{TargetA:0.##} b*{TargetB:0.##}"),
};
foreach (var item in TrialsLogitems)
{
vm.ReportItems.Add(new ColorCorrectionReportLogItem()
{
TrialsNumber = item.TrialNumber,
Date = item.Date,
CMYK = item.CMYK,
MeasuredLAB = item.LAB,
DeltaE = item.DeltaE,
IsBest = item.IsBest
});
}
try
{
PdfWpfWriter writer = new PdfWpfWriter();
writer.AddElement(new ColorCorrectionReport() { DataContext = vm });
string path = StorageProvider.Drive.Name + "\\Color Correction Report_" + reportDateTime.ToString(@"MM_dd_y_HH_mm") + ExplorerFileDefinition.PDFFile.Extension;
if (File.Exists(path))
{
path = StorageProvider.Drive.Name + "\\Color Correction Report_" + reportDateTime.ToString(@"MM_dd_y_HH_mm") + "_1" + ExplorerFileDefinition.PDFFile.Extension;
}
writer.Save(path);
await NotificationProvider.ShowSuccess("Color Correction Report saved successfully.");
LogManager.Log($"Color Correction Report saved successfully to file {path}.");
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error saving color correction report to file.");
await NotificationProvider.ShowError($"An error occurred while trying to save the color correction report.\n{ex.Message}");
}
}
}
private async void ClearTrialsLog(object obj)
{
if (TrialsLogitems.Count > 1)
{
if (false == await NotificationProvider.ShowQuestion("“All the trials will be cleared."))
{
return;
}
ActiveLogModel = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == 0);
ActiveLogModel.L = ActiveLogModel.A = ActiveLogModel.B = null;
ActiveLogModel.SuggestionL = TargetL;
ActiveLogModel.SuggestionA = TargetA;
ActiveLogModel.SuggestionB = TargetB;
ActiveLogModel.NewSuggestionL = ActiveLogModel.NewSuggestionA = ActiveLogModel.NewSuggestionB = 0;
ActiveLogModel.DeltaE = null;
ActiveLogModel.IsTested = false;
TrialsLogitems.Clear();
if (TestColor != null)
{
TrialsLogEngine.Default.Delete(TestColor);
}
TrialsLogitems.Add(ActiveLogModel);
RaisePropertyChanged(nameof(TrialsLogitems));
RaisePropertyChanged(nameof(IsDisableInputLAB));
RaisePropertyChanged(nameof(TrialNumber));
VectorCorrection();
ClearFoNextTrial();
InvalidateRelayCommands();
}
}
private void DeleteTrialLog(object obj)
{
if (SelectedLog != null)
{
if (SelectedLog.TrialNumber != 0)
{
bool isLastItem = (TrialsLogitems.Count - 1) == SelectedLog.TrialNumber;
TrialsLogitems.Remove(SelectedLog);
int trialNumber = 0;
foreach (var trial in TrialsLogitems.OrderBy(x => x.TrialNumber))
{
trial.TrialNumber = trialNumber;
trialNumber++;
}
var max = TrialsLogitems.Max(x => x.TrialNumber);
ActiveLogModel = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == max);
if (isLastItem)
{
ActiveLogModel.IsTested = false;
_measuredL = ActiveLogModel.L;
_measuredB = ActiveLogModel.B;
_measuredA = ActiveLogModel.A;
RaisePropertyChanged(nameof(MeasuredL));
RaisePropertyChanged(nameof(MeasuredA));
RaisePropertyChanged(nameof(MeasuredB));
}
if (TestColor != null)
{
TestColor.TrialslogList.Clear();
TestColor.TrialslogList.AddRange(TrialsLogitems);
TrialsLogEngine.Default.UpdateTest(TestColor);
}
RaisePropertyChanged(nameof(IsDisableInputLAB));
SelectedLog = null;
var minDelataE = TrialsLogitems.Min(x => x.DeltaE);
if (minDelataE != null && minDelataE < 2)
TrialsLogitems.ToList().ForEach(x => x.IsBest = (x.DeltaE == minDelataE));
RaisePropertyChanged(nameof(TrialNumber));
}
else if (TrialsLogitems.Count == 1)
{
ActiveLogModel.L = ActiveLogModel.A = ActiveLogModel.B = null;
ActiveLogModel.NewSuggestionL = ActiveLogModel.NewSuggestionA = ActiveLogModel.NewSuggestionB = 0;
ActiveLogModel.DeltaE = null;
ActiveLogModel.IsTested = false;
if (TestColor != null)
{
TrialsLogEngine.Default.Delete(TestColor);
}
SelectedLog = null;
_measuredL = null;
_measuredB = null;
_measuredA = null;
IsTargetVisible = false;
RaisePropertyChanged(nameof(MeasuredL));
RaisePropertyChanged(nameof(MeasuredA));
RaisePropertyChanged(nameof(MeasuredB));
RaisePropertyChanged(nameof(TrialsLogitems));
RaisePropertyChanged(nameof(IsDisableInputLAB));
}
VectorCorrection();
UpdateManualCorrection();
LightnessOffset = ActiveLogModel.LightnessOffset;
ChromaOffset = ActiveLogModel.ChromaOffset;
HueOffset = ActiveLogModel.HueOffset;
InvalidateRelayCommands();
}
}
protected override async void Accept()
{
if (IsBusy)
return;
IsBusy = true;
OnClose();
if (SelectedLog.TrialNumber == 0)
{
IsBusy = false;
base.Accept();
return;
}
//var prevtrial = TrialsLogitems.FirstOrDefault( x=> x.TrialNumber == (SelectedLog.TrialNumber -1));
if(SelectedLog != null && SelectedLog.DeltaE != null && SelectedLog.DeltaE >=2)//by Hagai
{
if (false == await NotificationProvider.ShowQuestion("Please note that the color you have chosen is not the closest one."))
{
IsBusy = false;
return;
}
}
// SaveTest(GetExcelDataItems(SelectedLog, true));
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Cyan).Volume = SelectedLog.C;
BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Magenta).Volume = SelectedLog.M;
BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Yellow).Volume = SelectedLog.Y;
BrushStopModel.PreventPropertyUpdate = false;
BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Black).Volume = SelectedLog.K;
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = SelectedLog.SuggestionL;
BrushStopModel.A = SelectedLog.SuggestionA;
BrushStopModel.B = SelectedLog.SuggestionB;
BrushStopModel.PreventPropertyUpdate = false;
if (TestColor != null)
{
TrialsLogEngine.Default.Delete(TestColor);
}
try
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
var selectedRun = await db.JobRuns.FirstOrDefaultAsync(x => x.Guid == SelectedLog.JobRunGuid);
if (selectedRun != null)
{
VectorFineTuningRunModel model = JsonConvert.DeserializeObject(selectedRun.FineTuningString);
model.Approved = true;
selectedRun.FineTuningString = JsonConvert.SerializeObject(model);
await db.SaveChangesAsync();
}
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error updating the selected job run fine tuning db entry.");
}
IsBusy = false;
base.Accept();
}
protected override void Cancel()
{
OnClose();
if (TestColor != null )// update test
{
if (TrialsLogitems.Count == 1 && (MeasuredL == null || MeasuredA == null || MeasuredB == null))
{
TrialsLogEngine.Default.Delete(TestColor);
}
else if (TrialsLogitems.Count > 0)
{
TestColor.L = TargetL;
TestColor.A = TargetA;
TestColor.B = TargetB;
TestColor.OpenedFromCatalog = OpenFromColorSpace == ColorSpaces.Catalog;
TestColor.OpenedFromCMYK = OpenFromColorSpace == ColorSpaces.Volume;
TestColor.BrushStopGuid = BrushStopModel.Guid;
TestColor.TrialslogList.Clear();
TestColor.TrialslogList.AddRange(TrialsLogitems);
TrialsLogEngine.Default.UpdateTest(TestColor);
//if(ActiveLogModel != null && !ActiveLogModel.IsTested)
//{
// SaveTest(GetExcelDataItems(ActiveLogModel, false));
//}
}
}
else if(TrialsLogitems.Count > 0
&& (TrialsLogitems.Count > 1
|| (MeasuredL != null && MeasuredA != null && MeasuredB != null)
|| ( IsManualFineTuning && (LightnessOffset != 0 || HueOffset != 0 || ChromaOffset != 0))))
{
TestColor = new TestColor();
TestColor.BrushStopGuid = BrushStopModel.Guid;
TestColor.L = TargetL;
TestColor.A = TargetA;
TestColor.B = TargetB;
TestColor.OpenedFromCatalog = OpenFromColorSpace == ColorSpaces.Catalog;
TestColor.OpenedFromCMYK = OpenFromColorSpace == ColorSpaces.Volume;
TestColor.TrialslogList.AddRange(TrialsLogitems);
TrialsLogEngine.Default.AddTest(TestColor);
//if (ActiveLogModel != null && !ActiveLogModel.IsTested
// && (MeasuredL != null && MeasuredA != null && MeasuredB != null)
//|| (IsManualFineTuning && (LightnessOffset != 0 || HueOffset != 0 || ChromaOffset != 0)))
//{
// SaveTest(GetExcelDataItems(ActiveLogModel, false));
//}
}
base.Cancel();
}
private void OnClose()
{
MachineProvider.MachineOperator.PrintingStarted -= MachineOperator_PrintingStarted;
MachineProvider.MachineOperator.PrintingEnded -= MachineOperator_PrintingEnded;
MachineProvider.MachineOperator.PrintingCompleted -= MachineOperator_PrintingCompleted;
MachineProvider.MachineOperator.JobRunsLogger.JobRunAvailable -= JobRunsLogger_JobRunAvailable;
}
private bool IsValidLAB()
{
if (MeasuredL == null || MeasuredL < 0 || MeasuredL > 100
|| MeasuredA == null || MeasuredA < -128 || MeasuredA > 127
|| MeasuredB == null || MeasuredB < -128 || MeasuredB > 127)
return false;
return true;
}
public void ClearFoNextTrial()
{
if(IsOnlyManual)
SelectedTabIndex = 1;
CorrectOnlyHue = false;
_measuredL = null;
_measuredB = null;
_measuredA = null;
RaisePropertyChanged(nameof(MeasuredL));
RaisePropertyChanged(nameof(MeasuredA));
RaisePropertyChanged(nameof(MeasuredB));
IsTargetVisible = false;
if (ActiveLogModel != null)
{
VisualCorrectionModel.ClearAll(ActiveLogModel.SuggestionL, ActiveLogModel.SuggestionA, ActiveLogModel.SuggestionB);
}
else
{
VisualCorrectionModel.ClearAll(TargetL, TargetA, TargetB);
}
LightnessOffset = 0.0;
ChromaOffset = 0.0;
HueOffset = 0.0;
DC = null;
DL = null;
DH = null;
DeltaE = null;
VisualCorrectionModel.UpdateManualColors();
}
private void OnLABChanged()
{
if (ActiveLogModel == null)
return;
if (IsValidLAB())
{
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = (double)MeasuredL;
BrushStopModel.A = (double)MeasuredA;
BrushStopModel.B = (double)MeasuredB;
BrushStopModel.PreventPropertyUpdate = false;
//BrushStopModel.ConvertColor();
//if(BrushStopModel.IsOutOfGamut)
//{
// await NotificationProvider.ShowInfo("Color is out of gamut!");
//}
double dL, dC, dH;
//DeltaE = DeltaE_CMC(TargetL, TargetA, TargetB, (double)MeasuredL, (double)MeasuredA, (double)MeasuredB, out dL, out dC, out dH);
//DeltaE = DeltaE_CMC( (double)MeasuredL, (double)MeasuredA, (double)MeasuredB, TargetL, TargetA, TargetB, out dL, out dC, out dH);
DeltaE = DeltaE_CMC( TargetL, TargetA, TargetB, (double)MeasuredL, (double)MeasuredA, (double)MeasuredB, out dL, out dC, out dH);
DL = dL;
DC = (Double?)dC;
DH = (Double?)dH;
ActiveLogModel.DeltaE = DeltaE;
VectorCorrection();
UpdateManualCorrection();
OnLightnessOffsetChanged();
OnChromaOffsetChanged();
OnHueOffsetChanged();
IsTargetVisible = true;
// ValidationTests();
}
else if(DeltaE != null)
{
DL = DC = DH = DeltaE = null;
IsTargetVisible = false;
}
TestCommand.RaiseCanExecuteChanged();
ByPassTestCommand.RaiseCanExecuteChanged();
}
private void OnLightnessOffsetChanged()
{
if (ActiveLogModel == null )
return;
VisualCorrectionModel.LightnessOffset = LightnessOffset;
VisualCorrectionModel.ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
ActiveLogModel.VectorCorrectionL = VisualCorrectionModel.L;
ActiveLogModel.VectorCorrectionA = VisualCorrectionModel.A;
ActiveLogModel.VectorCorrectionB = VisualCorrectionModel.B;
VisualCorrectionModel.IsOutOfGamut = IsOutOfGammot();
TestCommand.RaiseCanExecuteChanged();
ByPassTestCommand.RaiseCanExecuteChanged();
}
private void OnChromaOffsetChanged()
{
if (ActiveLogModel == null )
return;
VisualCorrectionModel.ChromaOffset = ChromaOffset;
VisualCorrectionModel.ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
ActiveLogModel.VectorCorrectionL = VisualCorrectionModel.L;
ActiveLogModel.VectorCorrectionA = VisualCorrectionModel.A;
ActiveLogModel.VectorCorrectionB = VisualCorrectionModel.B;
VisualCorrectionModel.IsOutOfGamut = IsOutOfGammot();
TestCommand.RaiseCanExecuteChanged();
ByPassTestCommand.RaiseCanExecuteChanged();
}
private void OnHueOffsetChanged()
{
if (ActiveLogModel == null )
return;
VisualCorrectionModel.HueOffset = HueOffset;
VisualCorrectionModel.ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
ActiveLogModel.VectorCorrectionL = VisualCorrectionModel.L;
ActiveLogModel.VectorCorrectionA = VisualCorrectionModel.A;
ActiveLogModel.VectorCorrectionB = VisualCorrectionModel.B;
VisualCorrectionModel.IsOutOfGamut = IsOutOfGammot();
TestCommand.RaiseCanExecuteChanged();
ByPassTestCommand.RaiseCanExecuteChanged();
}
private bool IsOutOfGammot()
{
BrushStopModel.ColorSpace = ColorSpaces.LAB;
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = ActiveLogModel.VectorCorrectionL;
BrushStopModel.A = ActiveLogModel.VectorCorrectionA;
BrushStopModel.B = ActiveLogModel.VectorCorrectionB;
BrushStopModel.PreventPropertyUpdate = false;
BrushStopModel.IsOutputOfGamut(ColorSpaces.LAB);
return BrushStopModel.IsOutOfGamut;
}
private void OnUpdateSettingineTuningTrialLengthMeters()
{
if (FineTuningTrialLengthMeters != 0)
{
var settings = SettingsManager.Default.GetOrCreate();
settings.FineTuningTrialLengthMeters = FineTuningTrialLengthMeters;
settings.Save();
}
}
#endregion
#region Job
private void BypassTest()
{
BrushStopModel.PreventPropertyUpdate = true;
CalculateSuggestionLAB(ActiveLogModel);
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = ActiveLogModel.NewSuggestionL;
BrushStopModel.A = ActiveLogModel.NewSuggestionA;
BrushStopModel.B = ActiveLogModel.NewSuggestionB;
BrushStopModel.PreventPropertyUpdate = false;
//calculate CMYK
if (OpenFromColorSpace == ColorSpaces.LAB || ((MeasuredL != null && MeasuredA != null && MeasuredB != null)
|| IsManualFineTuning && (LightnessOffset != 0.0 || ChromaOffset != 0.0 || HueOffset != 0.0)))
{
BrushStopModel.FineTuningConverter(ActiveLogModel.C, ActiveLogModel.M, ActiveLogModel.Y, ActiveLogModel.K);
if (BrushStopModel.IsOutOfGamut)
{
ActiveLogModel.NewSuggestionL = BrushStopModel.L;
ActiveLogModel.NewSuggestionA = BrushStopModel.A;
ActiveLogModel.NewSuggestionB = BrushStopModel.B;
}
}
BrushStopModel.ColorSpace = ColorSpaces.LAB;
UpdateOnEndJob();
InvalidateRelayCommands();
}
private async void StartJob()
{
if(IsJobRunning || IsPrepareToStartJob)
return;
if (ActiveLogModel.DeltaE != null && ActiveLogModel.DeltaE <= 0.5)
{
if (true == await NotificationProvider.ShowQuestion("Previous trial seems to be very close; no more trials are recommended"))
return;
}
IsPrepareToStartJob = true;
BrushStopModel.PreventPropertyUpdate = true;
CalculateSuggestionLAB(ActiveLogModel);
BrushStopModel.PreventPropertyUpdate = true;
BrushStopModel.L = ActiveLogModel.NewSuggestionL;
BrushStopModel.A = ActiveLogModel.NewSuggestionA;
BrushStopModel.B = ActiveLogModel.NewSuggestionB;
BrushStopModel.PreventPropertyUpdate = false;
//calculate CMYK
if ( OpenFromColorSpace == ColorSpaces.LAB || ((MeasuredL != null && MeasuredA != null && MeasuredB != null)
|| IsManualFineTuning && (LightnessOffset != 0.0 || ChromaOffset != 0.0 || HueOffset != 0.0)))
{
BrushStopModel.FineTuningConverter(ActiveLogModel.C, ActiveLogModel.M, ActiveLogModel.Y, ActiveLogModel.K);
if (BrushStopModel.IsOutOfGamut)
{
ActiveLogModel.NewSuggestionL = BrushStopModel.L;
ActiveLogModel.NewSuggestionA = BrushStopModel.A;
ActiveLogModel.NewSuggestionB = BrushStopModel.B;
}
BrushStopModel.ColorSpace = ColorSpaces.LAB;
}
// var settings = SettingsManager.Default.GetOrCreate();
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
Job job = new Job();
job.Guid = BrushStopModel.SegmentModel.Job.Guid;
job.ID = BrushStopModel.SegmentModel.Job.ID;
job.EnableLubrication = true;
job.Designation = JobDesignations.FineTuning;
job.Machine = await new MachineBuilder(db).Set(MachineProvider.Machine.Guid).WithConfiguration().WithSpools().WithCats().WithVersion().BuildAsync();
var trialNumber = ActiveLogModel.TrialNumber + 1;
job.Name = BrushStopModel.SegmentModel.Job.Name;
job.Rml = await new RmlBuilder(db).Set(BrushStopModel.SegmentModel.Job.Rml.Guid).WithActiveParametersGroup().WithCAT(MachineProvider.Machine.Guid).WithCCT().WithGbdAndLub().WithLiquidFactors().WithSpools().BuildAsync();
job.SpoolType = db.SpoolTypes.FirstOrDefault(x => x.Guid == BrushStopModel.SegmentModel.Job.SpoolGuid);// db.SpoolTypes.FirstOrDefault(x => x.Guid == settings.SpoolTypeGuid);
job.WindingMethod = db.WindingMethods.FirstOrDefault();
job.VectorFineTuningRunModel = CreateFineTuningRunModel();
Segment segment = new Segment();
segment.Name = "VFT Segment";
segment.Length = FineTuningTrialLengthMeters;//settings.FineTuningTrialLengthMeters;
segment.Job = job;
segment.JobGuid = job.Guid;
job.Segments.Add(segment);
BrushStop stop = new BrushStop();
stop.Segment = segment;
stop.ColorSpace = db.ColorSpaces.FirstOrDefault(x => x.Code == (int)ColorSpaces.Volume);
stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, job.Rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault());
stop.BestMatchR = BrushStopModel.BestMatchRed;
stop.BestMatchG = BrushStopModel.BestMatchGreen;
stop.BestMatchB = BrushStopModel.BestMatchBlue;
stop.L = BrushStopModel.L;
stop.A = BrushStopModel.A;
stop.B = BrushStopModel.B;
BrushStopModel.LiquidVolumes.SetVolumesOnBrushStop(stop);
segment.BrushStops.Add(stop);
try
{
await PrintingManager.Print(job, db);
}
catch (Exception ex)
{
LogManager.Log(ex, "Could not start the test job.");
await NotificationProvider.ShowError($"{ex.Message}.");
IsJobRunning = false;
IsPrepareToStartJob = false;
}
}
IsPrepareToStartJob = false;
}
private bool CanStartJob(object arg)
{
return (!IsJobRunning && ActiveLogModel != null
&& TrialsLogitems.Count <= 10
&& (ActiveLogModel.TrialNumber == 0 //asked by Hagai to job first trial without correction
|| ((!IsManualFineTuning && IsValidLAB())
|| (IsManualFineTuning && (LightnessOffset != 0.0 || ChromaOffset != 0.0 || HueOffset != 0.0))))
);
}
private void MachineOperator_PrintingStarted(object sender, PrintingEventArgs e)
{
if (IsVisible)
{
_handler = e.JobHandler;
e.JobHandler.StatusChanged += JobHandler_StatusChanged;
e.JobHandler.Stopped += JobHandler_Stopped;
e.JobHandler.Completed += JobHandler_Completed;
e.JobHandler.Failed += JobHandler_Failed;
InvokeUI(() =>
{
IsJobFailed = false;
IsJobRunning = true;
});
//e.JobHandler.CanCancelChanged += JobHandler_CanCancelChanged;
}
}
private void JobHandler_Failed(object sender, Exception e)
{
InvokeUI(() =>
{
IsJobFailed = true;
IsJobRunning = false;
});
JobFailedReason = e.FlattenMessage();
}
///
/// Handles the Stopped event of the JobHandler.
///
/// The source of the event.
/// The instance containing the event data.
private void JobHandler_Stopped(object sender, EventArgs e)
{
if (_handler != null)
{
_handler.StatusChanged -= JobHandler_StatusChanged;
_handler.Stopped -= JobHandler_Stopped;
_handler.Completed -= JobHandler_Completed;
//_handler.CanCancelChanged -= JobHandler_CanCancelChanged;
InvokeUI(() =>
{
IsJobRunning = false;
InvalidateRelayCommands();
});
}
}
///
/// Handles the JobHandler StatusChanged event.
///
/// The sender.
/// The e.
private void JobHandler_StatusChanged(object sender, RunningJobStatus e)
{
InvokeUI(() =>
{
RunningJobStatus = e;
});
}
private void MachineOperator_PrintingEnded(object sender, PrintingEventArgs e)
{
}
private void MachineOperator_PrintingCompleted(object sender, PrintingEventArgs e)
{
LogManager.Log($"'{e.Job.Name}' printing complete. Job designation is {e.Job.Designation}.");
// if (e.Job.Designation == BL.Enumerations.JobDesignations.FineTuning)
//{
// NotificationProvider.PushNotification(new MessageNotificationItem(String.Format("'{0}' fine tuning completed successfully", e.Job.Name), "Tap to approve or repeat.", MessageNotificationItem.MessageNotificationItemTypes.Success, () =>
// {
// }));
//}
//if (IsVisible)
//{
// IsJobRunning = false;
// Dispatcher.CurrentDispatcher.Invoke(() =>
// {
// ActiveLogModel.IsTested = true;
// ActiveLogModel.Date = DateTime.UtcNow;
// if (ActiveLogModel != null && ActiveLogModel.TrialNumber < 10)
// {
// ActiveLogModel = new TrialsLogModel(ActiveLogModel.TrialNumber + 1, Cyan, Magenta, Yellow, Black);
// _trialsLogItems.Add( ActiveLogModel);
// RaisePropertyChanged(nameof(TrialsLogitems));
// }
// _measuredL = null;
// _measuredA = null;
// _measuredB = null;
// RaisePropertyChanged(nameof(MeasuredL));
// RaisePropertyChanged(nameof(MeasuredA));
// RaisePropertyChanged(nameof(MeasuredB));
// });
//}
}
private void JobHandler_Completed(object sender, EventArgs e)
{
if (_handler != null)
{
if (IsVisible)
{
IsJobRunning = false;
}
InvokeUI(() =>
{
UpdateOnEndJob();
InvalidateRelayCommands();
});
_handler.StatusChanged -= JobHandler_StatusChanged;
_handler.Stopped -= JobHandler_Stopped;
_handler.Completed -= JobHandler_Completed;
}
}
private void StopTest()
{
if (_handler != null)
{
_handler.Cancel();
InvokeUI(() =>
{
IsJobRunning = false;
InvalidateRelayCommands();
});
}
}
private void UpdateOnEndJob()
{
ActiveLogModel.IsTested = true;
Cyan = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Cyan).Volume;
Magenta = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Magenta).Volume;
Yellow = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Yellow).Volume;
Black = BrushStopModel.LiquidVolumes.GetLiquidVolume(LiquidTypes.Black).Volume;
if (ActiveLogModel != null && TrialsLogitems.Count <= 10)
{
var suggestionL = ActiveLogModel.NewSuggestionL;
var suggestionA = ActiveLogModel.NewSuggestionA;
var suggestionB = ActiveLogModel.NewSuggestionB;
ActiveLogModel = new TrialsLogModel(ActiveLogModel.TrialNumber + 1, Cyan, Magenta, Yellow, Black);
ActiveLogModel.SuggestionL = suggestionL;
ActiveLogModel.SuggestionA = suggestionA;
ActiveLogModel.SuggestionB = suggestionB;
ActiveLogModel.VectorCorrectionL = suggestionL;
ActiveLogModel.VectorCorrectionA = suggestionA;
ActiveLogModel.VectorCorrectionB = suggestionB;
TrialsLogitems.Insert(0, ActiveLogModel);
var minDelataE = TrialsLogitems.Min(x => (double?)x.DeltaE);
if (minDelataE != null && minDelataE < 2)
TrialsLogitems.ToList().ForEach(x => x.IsBest = ((double?)x.DeltaE == minDelataE));
RaisePropertyChanged(nameof(TrialsLogitems));
RaisePropertyChanged(nameof(TrialNumber));
// UpdateManualCorrection();
ClearFoNextTrial();
}
RaisePropertyChanged(nameof(IsDisableInputLAB));
}
#endregion
#region Delta E
double DeltaE_CMC(double L1, double a1, double b1, double L2, double a2, double b2, out double dL, out double dC, out double dH)
{
double SL;
if (L1 < 16)
SL = 0.511;
else
SL = L1 * 0.040975 / (1 + 0.01765 * L1);
//chroma calculation
double C1 = Math.Sqrt(a1 * a1 + b1 * b1);
double C2 = Math.Sqrt(a2 * a2 + b2 * b2);
var deltaC = C1 - C2;
double SC = (0.0638 * C1 / (1 + 0.0131 * C1)) + 0.638;
double C1_P4 = Math.Pow(C1, 4);
double F = Math.Sqrt(C1_P4 / (C1_P4 + 1900));
double H1 = Math.Atan2(b1, a1) * (180 / Math.PI);
if (H1 < 0)
H1 = H1 + 360;
double T;
if ((H1 >= 164) & (H1 <= 345))
T = 0.56 + Math.Abs(0.2 * Math.Cos((H1 + 168) *Math.PI / 180));
else //if ((H1 > 345) | (H1 < 164))
T = 0.36 + Math.Abs(0.4 * Math.Cos((H1 + 35) *Math.PI / 180));
double SH = SC * (T * F + 1 - F);
var deltaL = L1 - L2;
//hue calculation
double delta_a = a1 - a2;
double delta_b = b1 - b2;
var deltaH = Math.Sqrt(Math.Max(delta_a * delta_a + delta_b * delta_b - deltaC * deltaC, 0.0));
double dECMC = Math.Sqrt(Math.Pow(deltaL / (2 * SL), 2) + Math.Pow(deltaC / SC, 2) + Math.Pow(deltaH / SH, 2));
dL = (deltaL / (2 * SL)) *(-1);
dC = (deltaC / SC)*(-1);
LabColor target_labColor = new LabColor(L1, a1, b1);
LabColor labColor = new LabColor(L2, a2, b2);
var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
var LCH_input = converter.ToLChab(labColor);
var LCH_target = converter.ToLChab(target_labColor);
if(LCH_target.h > LCH_input.h)
dH = (deltaH / SH) * (-1);
else
dH = (deltaH / SH);
return dECMC;
}
double DeltaE_regular(double L1, double a1, double b1, double L2, double a2, double b2)
{
return Math.Sqrt(Math.Pow(L1 - L2, 2) + Math.Pow(a1 - a2, 2) + Math.Pow(b1 - b2, 2));
}
private async void ValidationTests()
{
//if (ActiveLogModel.DeltaE <= 0.5)
//{
// await NotificationProvider.ShowInfo("Previous trial seems to be very close; no more trials are recommended");
// return ;
//}
if (TrialsLogitems.Count == 1 || ActiveLogModel.DeltaE == null)
return;
int currentTrialNumber = ActiveLogModel.TrialNumber;
if (TrialsLogitems.Count >= 3)
{
var item = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == currentTrialNumber - 2);
var item1 = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == currentTrialNumber - 1);
var item2 = ActiveLogModel;
if(item1 != null && item2 != null && item != null && item2.DeltaE != null && item1.DeltaE != null && item.DeltaE != null)
{//dEi+2- dEi+1>0.5 and dEi+1-dEi>0.5
if ( ( item2.DeltaE - item1.DeltaE) > 0.5 && (item1.DeltaE - item.DeltaE) > 0.5)
{
await NotificationProvider.ShowInfo("It seems that we can’t get you any closer");
return;
}
//Math.Abs
//| dEi+1- dEi | and |dEi+2 -dEi+1|<=0.1.
if (Math.Abs((double)item1.DeltaE - (double)item.DeltaE) <= 0.1 && Math.Abs((double)item2.DeltaE - (double)item1.DeltaE) <= 0.1)
{
await NotificationProvider.ShowInfo("It seems that we can’t get you any closer");
return;
}
}
}
if (TrialsLogitems.Count > 2)
{
var item = TrialsLogitems.FirstOrDefault(x => x.TrialNumber == currentTrialNumber - 1);
var item1 = ActiveLogModel;
if (item == null || item1 == null)
return;
if (Math.Abs((double)item1.C - (double)item.C) < 0.1
&& Math.Abs((double)item1.M - (double)item.M) < 0.1
&& Math.Abs((double)item1.Y - (double)item.Y) < 0.1
&& Math.Abs((double)item1.K - (double)item.K) < 0.1)
{
await NotificationProvider.ShowInfo("It seems that we can’t get you any closer");
return;
}
if( MeasuredL == null || MeasuredA == null || MeasuredB == null || item.L == null || item1.L == null || item.A == null || item1.B == null || item.A == null || item1.A == null)
return;
var deltaE_reg = DeltaE_regular(TargetL, TargetA, TargetB, (double)MeasuredL, (double)MeasuredA, (double)MeasuredB);
if ((Math.Abs((double)item1.L - (double)item.L) < 0.1 && Math.Abs((double)item1.A - (double)item.A) < 0.1 && Math.Abs((double)item1.B - (double)item.B) < 0.1)
|| deltaE_reg < 0.2)
{
await NotificationProvider.ShowInfo("It seems that we can’t get you any closer");
return;
}
}
return;
}
private bool CalculateSuggestionLAB(TrialsLogModel trial)
{
if ((MeasuredL != null && MeasuredA != null && MeasuredB != null)
|| IsManualFineTuning && (LightnessOffset != 0.0 || ChromaOffset != 0.0 || HueOffset != 0.0))
{
if(IsManualFineTuning)
{
LabColor labColor = new LabColor(trial.SuggestionL, trial.SuggestionA, trial.SuggestionB);
var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
var LCH = converter.ToLChab(labColor);
Lch lch = VisualCorrectionModel.Correction(LCH.L, LCH.C, LCH.h, LightnessOffset, ChromaOffset, HueOffset);
trial.NewSuggestionL = lch.L;
trial.NewSuggestionA = lch.C * Math.Cos(lch.H * (Math.PI / 180));
trial.NewSuggestionB = lch.C * Math.Sin(lch.H * (Math.PI / 180));
}
else if ( CorrectOnlyHue)
{
var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
LabColor labColorTarget = new LabColor(TargetL, TargetA, TargetB);
var LCH_target = converter.ToLChab(labColorTarget);
LabColor labColorSuggestion = new LabColor(ActiveLogModel.SuggestionL, ActiveLogModel.SuggestionA, ActiveLogModel.SuggestionB);
var LCH_suggestion = converter.ToLChab(labColorSuggestion);
LabColor labColorNew = new LabColor((double)trial.VectorCorrectionL, (double)trial.VectorCorrectionA, (double)trial.VectorCorrectionB);
var LCH_new = converter.ToLChab(labColorNew);
double L = LCH_suggestion.L;
double C = LCH_suggestion.C;
double H = LCH_suggestion.h + (LCH_target.h - LCH_new.h);
LabColor lab = converter.ToLab(new LChabColor(L, C, H));
trial.NewSuggestionL = lab.L;
trial.NewSuggestionA = lab.a;
trial.NewSuggestionB = lab.b;
LogManager.Log($" Fine Tuning. Suggestion (calculated) LAB L:'{trial.NewSuggestionL}'A:'{trial.NewSuggestionA}' B:'{trial.NewSuggestionB}'.");
return true;
}
else
{
var settings = SettingsManager.Default.GetOrCreate();
bool bNotChangeL = false;
if(settings.FineTuningMinLimitdL > 0)
{
var dL = Math.Abs((double)trial.VectorCorrectionL - trial.SuggestionL);
var dA = Math.Abs((double)trial.VectorCorrectionA - trial.SuggestionA);
var dB = Math.Abs((double)trial.VectorCorrectionB - trial.SuggestionB);
if(dL < settings.FineTuningMinLimitdL && (dL < dA || dL < dB))
{
bNotChangeL = true;
}
}
trial.NewSuggestionL = bNotChangeL ? trial.SuggestionL : LimitToRange((trial.SuggestionL + (TargetL - (double)trial.VectorCorrectionL)), 0, 100);
trial.NewSuggestionA = LimitToRange((trial.SuggestionA + (TargetA - (double)trial.VectorCorrectionA)), -128, 127);
trial.NewSuggestionB = LimitToRange((trial.SuggestionB + (TargetB - (double)trial.VectorCorrectionB)), -128, 127);
LogManager.Log($" Fine Tuning. Suggestion (calculated) LAB L:'{trial.NewSuggestionL}'A:'{trial.NewSuggestionA}' B:'{trial.NewSuggestionB}'.");
return true;
}
}
else
{
trial.NewSuggestionL = trial.SuggestionL;
trial.NewSuggestionA = trial.SuggestionA;
trial.NewSuggestionB = trial.SuggestionB;
}
return false;
}
public double LimitToRange(double value, double inclusiveMinimum, double inlusiveMaximum)
{
if (value >= inclusiveMinimum)
{
if (value <= inlusiveMaximum)
{
return value;
}
return inlusiveMaximum;
}
return inclusiveMinimum;
}
#endregion
#region JobRun Extensions
private VectorFineTuningRunModel CreateFineTuningRunModel()
{
VectorFineTuningRunModel model = new VectorFineTuningRunModel();
model.Type = IsManualFineTuning ? FineTuningTypes.ManualFineTuning : FineTuningTypes.FineTuning;
model.FineTuningSessionID = _sessionID;
model.FineTuningTrialNumber = ActiveLogModel.TrialNumber + 1;
model.JobName = BrushStopModel.SegmentModel.Job.Name;
model.FineTuningTargetL = TargetL;
model.FineTuningTargetA = TargetA;
model.FineTuningTargetB = TargetB;
model.FineTuningSuggestionL = BrushStopModel.L;
model.FineTuningSuggestionA = BrushStopModel.A;
model.FineTuningSuggestionB = BrushStopModel.B;
model.FineTuningMeasuredL = MeasuredL;
model.FineTuningMeasuredA = MeasuredA;
model.FineTuningMeasuredB = MeasuredB;
model.CorrectOnlyHue = CorrectOnlyHue;
model.Lightness = LightnessOffset;
model.Chroma = ChromaOffset;
model.Hue = HueOffset;
model.DeltaL = DL;
model.DeltaH = DH;
model.DeltaC = DC;
model.DeltaE = DeltaE;
return model;
}
private void JobRunsLogger_JobRunAvailable(object sender, Integration.JobRuns.JobRunAvailableEventArgs e)
{
ActiveLogModel.JobRunGuid = e.JobRun.Guid;
}
///
/// Vectors the correction.
///
protected void VectorCorrection()
{
if(ActiveLogModel == null)
return;
if ( !IsValidLAB())
{
ActiveLogModel.VectorCorrectionL = MeasuredL == null ? ActiveLogModel.SuggestionL : (double)MeasuredL;
ActiveLogModel.VectorCorrectionA = MeasuredA == null ? ActiveLogModel.SuggestionA : (double)MeasuredA;
ActiveLogModel.VectorCorrectionB = MeasuredB == null ? ActiveLogModel.SuggestionB : (double)MeasuredB;
return;
}
ActiveLogModel.VectorCorrectionL = (double)MeasuredL;
ActiveLogModel.VectorCorrectionA = (double)MeasuredA;
ActiveLogModel.VectorCorrectionB = (double)MeasuredB;
return;
}
#endregion
#region save in excel
protected List GetExcelDataItems(TrialsLogModel model, bool isAccepted)
{
String nameRML = BrushStopModel.SegmentModel.Job.Rml.DisplayName;
String jobName = BrushStopModel.SegmentModel.Job.Name;
String machine_SN = BrushStopModel.SegmentModel.Job.Machine.DeviceName;
List items = new List(){ new ExcelFTTestsData()
{
Date = model.Date.ToString(),
Job_Name = jobName,
FVT_ID = model.TrialNumber.ToString(),
Machine_SN = machine_SN,
RML = nameRML,
Target_L = TargetL.ToString("###.##"),
Target_A = TargetA.ToString("###.##"),
Target_B = TargetB.ToString("###.##"),
Suggested_L = model.SuggestionL.ToString("###.##"),
Suggested_A = model.SuggestionA.ToString("###.##"),
Suggested_B = model.SuggestionB.ToString("###.##"),
Suggested_C = model.C.ToString("0.##"),
Suggested_M = model.M.ToString("0.##"),
Suggested_Y = model.Y.ToString("0.##"),
Suggested_K = model.K.ToString("0.##"),
Result_L = model.NewSuggestionL.ToString("###.##"),
Result_A = model.NewSuggestionA.ToString("###.##"),
Result_B = model.NewSuggestionB.ToString("###.##"),
delta_L = model.dL.ToString("###.##"),
delta_C = model.dC.ToString("###.##"),
delta_H = model.dH.ToString("###.##"),
delta_E_CMC = model.DeltaEDisplay,
OOG = model.SuggestedColor,
Type = model.IsManualCorrection ? "Visual " + model.LightnessOffset.ToString("#.#") + "L+ " + model.ChromaOffset.ToString("#.#") + "C+ " + model.HueOffset.ToString("#.#") + "H" : model.CorrectOnlyHue ? "Vector H" : "Vector",
User_selected_option = isAccepted? "accepted" : "",//?????
User_finished_process = model.IsTested ? "tested" : "not tested"
} };
return items;
}
protected void SaveTest(List items)
{
if (items == null || items.Count == 0)
return;
Task.Factory.StartNew(() =>
{
ExcelWriter writer = null;
try
{
IsFree = false;
String dbFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Color Fine tuning");
Directory.CreateDirectory(dbFolder);
Stream stream = null;
String nameRML = BrushStopModel.SegmentModel.Job.Rml.DisplayName;
String jobName = BrushStopModel.SegmentModel.Job.Name;
String mashine_SN = BrushStopModel.SegmentModel.Job.Machine.DeviceName;
string fileName = String.Format($"{TargetL.ToString("##0")}_{TargetA.ToString("##0")}_{TargetB.ToString("##0")}_{nameRML}_{jobName}.xlsx");
string file = Path.Combine(dbFolder, fileName);
bool dispose = false;
if (File.Exists(file))
{
stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
dispose = true;
}
else
{
stream = EmbeddedResourceHelper.GetEmbeddedResourceStream("Tango.PPC.Jobs.FineTuning.FTVTemplate.xlsx");
}
if (stream == null)
return;
byte[] data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
File.WriteAllBytes(file, data);
if (dispose)
{
stream.Dispose();
}
writer = new ExcelWriter(file);
writer.WriteData(items, "Sheet1");
writer.Dispose();
writer = null;
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error exporting data.");
InvokeUI(async () =>
{
await NotificationProvider.ShowError($"An error occurred while trying to export the data. Make sure the excel file is closed and data is valid.\n{ex.FlattenMessage()}");
});
}
finally
{
IsFree = true;
if (writer != null)
writer.Dispose();
}
});
}
#endregion
}
}