using ColorMine.ColorSpaces; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Windows.Media; using Tango.BL.Dispensing; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.ColorConversion; using Tango.Core.DI; using Tango.Core.Threading; using Tango.PMR.ColorLab; using Tango.PPC.Common; using Tango.PPC.Common.Connection; using Tango.Settings; using Tango.SharedUI; namespace Tango.PPC.Jobs.Models { public class BrushStopModel : ViewModel { public enum PositionStatus { First = 1, FirstColor = 2, Middle = 3, SecondColor = 4, Last = 5 } private ActionTimer _volumeConversionTimer; private IColorConverter _converter; public const double MAX_INK_UPTAKE = 400; public event EventHandler ColorCatalogsItemChanged; public event EventHandler LiquidVolumesOutOfRangeChanged; public event EventHandler ColorChanged; [TangoInject] public IMachineProvider MachineProvider { get; set; } #region Property public String Guid { get; set; } [JsonIgnore] public bool PreventPropertyUpdate { get; set; } protected Int32 _red; /// /// Gets or sets the BrushStopModel red. /// public Int32 Red { get { return _red; } set { if (_red != value) { _red = value; RaisePropertyChangedAuto(); OnRGBChanged(); } } } protected Int32 _green; /// /// Gets or sets the BrushStopModel green. /// public Int32 Green { get { return _green; } set { if (_green != value) { _green = value; RaisePropertyChangedAuto(); OnRGBChanged(); } } } protected Int32 _blue; /// /// Gets or sets the BrushStopModel blue. /// public Int32 Blue { get { return _blue; } set { if (_blue != value) { _blue = value; RaisePropertyChangedAuto(); OnRGBChanged(); } } } protected Double _l; /// /// Gets or sets the BrushStopModel l. /// public Double L { get { return _l; } set { if (_l != value) { _l = value; RaisePropertyChangedAuto(); OnLABChanged(); } } } protected Double _a; /// /// Gets or sets the BrushStopModel a. /// public Double A { get { return _a; } set { if (_a != value) { _a = value; RaisePropertyChangedAuto(); OnLABChanged(); } } } protected Double _b; /// /// Gets or sets the BrushStopModel b. /// public Double B { get { return _b; } set { if (_b != value) { _b = value; RaisePropertyChangedAuto(); OnLABChanged(); } } } //HSB??? private double _hue; public double Hue { get { return _hue; } set { if (_hue != value) { _hue = value; OnHSBChanged(); RaisePropertyChangedAuto(); } } } private double _saturation; public double Saturation { get { return _saturation; } set { if (_saturation != value) { _saturation = value; OnHSBChanged(); RaisePropertyChangedAuto(); } } } private double _brightness; public double Brightness { get { return _brightness; } set { if (_brightness != value) { _brightness = value; OnHSBChanged(); RaisePropertyChangedAuto(); } } } private double _bestMatchL; public double BestMatchL { get { return _bestMatchL; } set { if (_bestMatchL != value) { _bestMatchL = value; RaisePropertyChangedAuto(); } } } private double _bestMatchA; public double BestMatchA { get { return _bestMatchA; } set { if (_bestMatchA != value) { _bestMatchA = value; RaisePropertyChangedAuto(); } } } private double _bestMatchB; public double BestMatchB { get { return _bestMatchB; } set { if (_bestMatchB != value) { _bestMatchB = value; RaisePropertyChangedAuto(); } } } public int BestMatchRed { get; set; } public int BestMatchGreen { get; set; } public int BestMatchBlue { get; set; } protected Double _offsetpercent; /// /// Gets or sets the brushstopbase offset percent. /// public Double OffsetPercent { get { return _offsetpercent; } set { if (_offsetpercent != value) { _offsetpercent = value; RaisePropertyChangedAuto(); OnOffsetPercentChanged(); } } } public double OffsetMeters { get { if (SegmentModel != null) { var a = SegmentModel.Length * (OffsetPercent / 100d); return a; } else { return 0; } } set { if (SegmentModel != null) { OffsetPercent = (value / SegmentModel.Length) * 100d; RaisePropertyChangedAuto(); } } } protected Int32 _stopindex; /// /// Gets or sets the brushstopbase stop index. /// public Int32 StopIndex { get { return _stopindex; } set { if (_stopindex != value) { _stopindex = value; RaisePropertyChangedAuto(); OnStopIndexChanged(); } } } private PositionStatus _position; public PositionStatus Position { get { return _position; } set { _position = value; RaisePropertyChangedAuto(); } } protected ColorSpaces _colorspace; public virtual ColorSpaces ColorSpace { get { return _colorspace; } set { if (_colorspace != value) { _colorspace = value; } RaisePropertyChangedAuto(); } } protected ColorCatalogsItem _colorcatalogsitem; [JsonIgnore] public virtual ColorCatalogsItem ColorCatalogsItem { get { return _colorcatalogsitem; } set { if (_colorcatalogsitem != value) { _colorcatalogsitem = value; OnColorCatalogsItemChanged(); RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(ColorCatalog)); } } } public string ColorCatalogsItemGuid { get { return ColorCatalogsItem == null ? "" : ColorCatalogsItem.Guid; } } /// /// Gets or sets the color catalog. /// /// /// The color catalog. /// [JsonIgnore] public virtual ColorCatalog ColorCatalog { get { if (ColorCatalogsItem != null && ColorCatalogsItem.ColorCatalogsGroup != null) { return ColorCatalogsItem.ColorCatalogsGroup.ColorCatalog; } return null; } } private System.Windows.Media.Color _color; [JsonIgnore] public System.Windows.Media.Color Color { get { return _color; } set { if (_color != value) { _color = value; RaisePropertyChangedAuto(); ColorChanged?.Invoke(this, new EventArgs()); } } } private System.Windows.Media.Color _bestMatchColor; [JsonIgnore] public System.Windows.Media.Color BestMatchColor { get { return _bestMatchColor; } set { _bestMatchColor = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(BestMatchA)); RaisePropertyChanged(nameof(BestMatchB)); RaisePropertyChanged(nameof(BestMatchL)); RaisePropertyChanged(nameof(ShownBestMatchColor)); } } [JsonIgnore] public System.Windows.Media.Color ShownBestMatchColor { get { if (IsOutOfGamut) return _bestMatchColor; return System.Windows.Media.Colors.Transparent; } } [JsonIgnore] public SolidColorBrush ColorBrush { get { if (Color == null) { InitColor(); } return new SolidColorBrush(Color); } } private SegmentModel _segmentmodel; [JsonIgnore] public SegmentModel SegmentModel { get { return _segmentmodel; } set { _segmentmodel = value; } } private bool _outOfGamutChecked; /// /// Gets or sets a value indicating whether out of gamut has been checked. /// [JsonIgnore] public bool OutOfGamutChecked { get { return _outOfGamutChecked; } set { _outOfGamutChecked = value; RaisePropertyChangedAuto(); } } private bool _isOutOfGamut; /// /// Gets or sets a value indicating whether this instance is out of gamut. /// public bool IsOutOfGamut { get { return _isOutOfGamut && ColorSpace != ColorSpaces.Volume && ColorSpace != ColorSpaces.Catalog; } set { if (_isOutOfGamut != value) { _isOutOfGamut = value; RaisePropertyChangedAuto(); } } } [JsonIgnore] protected bool RequiredMaxLiquidTest { get; set; } [JsonIgnore] public bool IsLiquidVolumesOutOfRange { get { if (RequiredMaxLiquidTest && (ColorSpace == ColorSpaces.Volume || ColorSpace == ColorSpaces.CMYK)) { var sum = LiquidVolumes.GetMaxNanoliterPerCM(); var maxLiq = GetTotalMaximumLiquidNlPerCMLimit(); LiquidVolumesOutOfRange = sum > GetTotalMaximumLiquidNlPerCMLimit(); return LiquidVolumesOutOfRange; } else return false; } } private bool _liquidVolumesOutOfRange; [JsonIgnore] public bool LiquidVolumesOutOfRange { get { return _liquidVolumesOutOfRange; } set { if (_liquidVolumesOutOfRange != value) { _liquidVolumesOutOfRange = value; LiquidVolumesOutOfRangeChanged?.Invoke(this, new EventArgs()); } } } [JsonIgnore] public bool IsLiquidVolumeBelowMinLimit { get { if (ColorSpace == ColorSpaces.Volume || ColorSpace == ColorSpaces.CMYK) { foreach (var liquidVolume in LiquidVolumes) { var min = liquidVolume.GetMinLimit(); if (liquidVolume.Volume > 0 && liquidVolume.Volume < min) { LiquidVolumeBelowMinLimit = true; LiquidVolumeBelowMinLimitmessage = $"{liquidVolume.IdsPack.LiquidType.Name} should be > {min.ToString("N3")}"; return LiquidVolumeBelowMinLimit; } } LiquidVolumeBelowMinLimit = false; LiquidVolumeBelowMinLimitmessage = ""; return false; } else return false; } } private string _liquidVolumeBelowMinLimitmessage; [JsonIgnore] public string LiquidVolumeBelowMinLimitmessage { get { return _liquidVolumeBelowMinLimitmessage; } set { _liquidVolumeBelowMinLimitmessage = value; RaisePropertyChangedAuto(); } } private bool _liquidVolumeBelowMinLimit; [JsonIgnore] public bool LiquidVolumeBelowMinLimit { get { return _liquidVolumeBelowMinLimit; } set { if (_liquidVolumeBelowMinLimit != value) { _liquidVolumeBelowMinLimit = value; LiquidVolumesOutOfRangeChanged?.Invoke(this, new EventArgs()); } } } [JsonIgnore] public ColorSpaces LastChangedColorSpace { get; set; } //Fine Tuning [JsonIgnore] public Double LBeforeChange { get; set; } [JsonIgnore] public Double ABeforeChange { get; set; } [JsonIgnore] public Double BBeforeChange { get; set; } [JsonIgnore] public BrushStop BrushStop { get; set; } public bool FineTuningChanged { get; set; } private LiquidVolumesCollection _liquidVolums; public LiquidVolumesCollection LiquidVolumes { get { return _liquidVolums; } set { _liquidVolums = value; RaisePropertyChangedAuto(); } } #endregion #region constructors public BrushStopModel(BrushStop stop) { Guid = System.Guid.NewGuid().ToString(); TangoIOC.Default.Inject(this); BrushStop = stop; LiquidVolumes = new LiquidVolumesCollection(); } public BrushStopModel(SegmentModel segmentModel, BrushStop stop) : this(stop) { SegmentModel = segmentModel; InitLiquidVolumes(); InitDefaultValues(); Color = Colors.White; var settings = SettingsManager.Default.GetOrCreate(); ColorSpace = settings.DefaultTabColorSpace == null ? ColorSpaces.Volume : (ColorSpaces)settings.DefaultTabColorSpace; if (ColorSpace == ColorSpaces.CMYK) ColorSpace = ColorSpaces.Volume; LastChangedColorSpace = ColorSpace; ColorCatalogsItem = null; PreventPropertyUpdate = false; LiquidVolumesOutOfRange = false; RequiredMaxLiquidTest = false; } public BrushStopModel(BrushStop brushStop, SegmentModel segmentModel, int version) : this(brushStop) { SegmentModel = segmentModel; BrushStop = brushStop; InitLiquidVolumes(); InitDefaultValues(); Guid = brushStop.Guid; OffsetPercent = brushStop.OffsetPercent; Color = brushStop.Color; BestMatchColor = brushStop.Color; ColorSpace = brushStop.ColorSpace.Space; LastChangedColorSpace = ColorSpace; if (ColorSpace == ColorSpaces.CMYK) ColorSpace = ColorSpaces.Volume; _colorcatalogsitem = brushStop.ColorCatalogsItem; _stopindex = brushStop.StopIndex; PreventPropertyUpdate = true; LiquidVolumes.SetVolumesFromBrushStop(brushStop); Red = brushStop.Red; Green = brushStop.Green; Blue = brushStop.Blue; L = brushStop.L; A = brushStop.A; B = brushStop.B; BestMatchL = brushStop.L; BestMatchA = brushStop.A; BestMatchB = brushStop.B; PreventPropertyUpdate = false; LiquidVolumesOutOfRange = false; } public void InitLiquidVolumes() { LiquidVolumes.Clear(); var supportedIdsPacks = SegmentModel.Job.Machine.Configuration.GetSupportedIdsPacks(SegmentModel.Job.Rml).Where(x => x.LiquidType.HasPigment && x.LiquidType.AvailableForStandardUser).OrderBy(x => x.LiquidType.PreferredIndex).ToList(); foreach (var idsPack in supportedIdsPacks) { var liquidVolume = new LiquidVolumeModel(this, idsPack); liquidVolume.VolumeChanged += (x, e) => OnVolumeChanged(); LiquidVolumes.Add(liquidVolume); } if (BrushStop != null) { LiquidVolumes.SetVolumesFromBrushStopSilent(BrushStop); } } private void InitDefaultValues() { _hue = 0; _saturation = 0; _brightness = 100; _l = 100; _a = 0; _b = 0; _bestMatchL = 100; _bestMatchA = _bestMatchB = 0; _red = _green = _blue = 255; LiquidVolumes.ResetVolumeSilent(); StopIndex = 1; Position = PositionStatus.FirstColor; IsOutOfGamut = false; _volumeConversionTimer = new ActionTimer(TimeSpan.FromMilliseconds(50)); _converter = new DefaultColorConverter(); _bestMatchColor = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue); } #endregion #region Methods /// /// Initializes the color. /// public void InitColor() { if (ColorSpace == ColorSpaces.Catalog && ColorCatalogsItem != null) { Color = Color.FromRgb((byte)ColorCatalogsItem.Red, (byte)ColorCatalogsItem.Green, (byte)ColorCatalogsItem.Blue); } else { Color = Color.FromRgb((byte)_red, (byte)_green, (byte)_blue); } } /// /// Sets the new color from MyColors. /// public void SetNewColor(BrushStopModel newBrushStop) { ColorSpace = newBrushStop.ColorSpace; PreventPropertyUpdate = true; Red = newBrushStop.Red; Green = newBrushStop.Green; Blue = newBrushStop.Blue; L = newBrushStop.L; A = newBrushStop.A; B = newBrushStop.B; BestMatchL = newBrushStop.BestMatchL; BestMatchA = newBrushStop.BestMatchA; BestMatchB = newBrushStop.BestMatchB; LiquidVolumes.SetVolumesFromBrushStop(newBrushStop); ColorCatalogsItem = newBrushStop.ColorCatalogsItem; PreventPropertyUpdate = false; Color = newBrushStop.Color; BestMatchColor = newBrushStop.BestMatchColor; } /// /// Creates the brush stop. /// public BrushStop CreateBrushStop(ColorSpaces colorSpace) { List list = SegmentModel.Job.ColorSpacesList; BrushStop s = new BrushStop(); s.ColorSpace = list.FirstOrDefault(x => x.Space == colorSpace); Configuration configuration = SegmentModel.Job.Machine.Configuration; Rml rml = SegmentModel.Job.Rml; s.SetLiquidVolumes(configuration, rml, rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault()); if (s.ColorSpace.Space == ColorSpaces.Volume) { foreach (var liquidVolume in LiquidVolumes) { s.SetVolume(liquidVolume.IdsPack.PackIndex, liquidVolume.Volume); } } else if (s.ColorSpace.Space == ColorSpaces.LAB) { s.ColorSpace.Space = BL.Enumerations.ColorSpaces.LAB; s.L = this.L; s.A = this.A; s.B = this.B; } else if (s.ColorSpace.Space == ColorSpaces.RGB) { s.ColorSpace.Space = BL.Enumerations.ColorSpaces.RGB; s.Red = this.Red; s.Green = this.Green; s.Blue = this.Blue; } //else if (s.ColorSpace.Space == ColorSpaces.HSB) //{ // s.ColorSpace.Space = BL.Enumerations.ColorSpaces.RGB; // s.Red = this.Red; // s.Green = this.Green; // s.Blue = this.Blue; //} return s; } public BrushStop CreateBrushStopForFineTuning(ColorSpaces colorSpace, double cyan, double yellow, double magenta, double black) { List list = SegmentModel.Job.ColorSpacesList; BrushStop s = new BrushStop(); s.ColorSpace = list.FirstOrDefault(x => x.Space == colorSpace); Configuration configuration = SegmentModel.Job.Machine.Configuration; Rml rml = SegmentModel.Job.Rml; s.SetLiquidVolumes(configuration, rml, rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault()); s.ColorSpace.Space = BL.Enumerations.ColorSpaces.LAB; s.L = this.L; s.A = this.A; s.B = this.B; s.Cyan = cyan; s.Yellow = yellow; s.Magenta = magenta; s.Black = black; return s; } public BrushStopModel Clone() { var cloned = new BrushStopModel(SegmentModel, BrushStop); cloned.StopIndex = StopIndex; cloned.PreventPropertyUpdate = true; cloned.Red = Red; cloned.Green = Green; cloned.Blue = Blue; cloned.L = L; cloned.A = A; cloned.B = B; cloned.BestMatchL = BestMatchL; cloned.BestMatchA = BestMatchA; cloned.BestMatchB = BestMatchB; cloned.LiquidVolumes.SetVolumesFromBrushStop(this); cloned.Hue = Hue; cloned.Saturation = Saturation; cloned.Brightness = Brightness; cloned.Color = Color; cloned.BrushStop = BrushStop; cloned.ColorCatalogsItem = ColorCatalogsItem; cloned.ColorSpace = ColorSpace; cloned.BestMatchColor = BestMatchColor; cloned.OffsetMeters = OffsetMeters; cloned.OffsetPercent = OffsetPercent; cloned.Position = Position; cloned.IsOutOfGamut = IsOutOfGamut; cloned.OutOfGamutChecked = OutOfGamutChecked; cloned.LiquidVolumesOutOfRange = LiquidVolumesOutOfRange; //this.MapPropertiesTo(cloned, MappingFlags.NoReferenceTypes); cloned.PreventPropertyUpdate = false; cloned.RequiredMaxLiquidTest = false; cloned.LastChangedColorSpace = ColorSpace; return cloned; } public static Color GetRelativeRGB(Color first, Color second, double firstOffset, double secondOffset, double offset) { var color = new Color(); var range = (secondOffset - firstOffset); var realoffset = offset - firstOffset; color.ScA = (float)(realoffset * (second.ScA - first.ScA) / range + first.ScA); color.ScR = (float)(realoffset * (second.ScR - first.ScR) / range + first.ScR); color.ScG = (float)(realoffset * (second.ScG - first.ScG) / range + first.ScG); color.ScB = (float)(realoffset * (second.ScB - first.ScB) / range + first.ScB); return color; } public void SetMyColor(FavoriteColor favoriteColor) { Color = favoriteColor.Color; BestMatchColor = favoriteColor.Color; ColorSpace = favoriteColor.ColorSpace; // _colorcatalogsitem = favoriteColor.ColorCatalogsItem; PreventPropertyUpdate = true; //LiquidVolumes.ResetVolume(); foreach (var liquidVolume in LiquidVolumes.Where(x => x.IdsPack.LiquidType.AvailableForStandardUser)) { liquidVolume.Volume = favoriteColor.GetVolume(liquidVolume.IdsPack.LiquidType.Type); } RaisePropertyChanged(nameof(LiquidVolumes)); //LiquidVolumes.GetLiquidVolume(LiquidTypes.Cyan).Volume = favoriteColor.Cyan; //LiquidVolumes.GetLiquidVolume(LiquidTypes.Magenta).Volume = favoriteColor.Magenta; //LiquidVolumes.GetLiquidVolume(LiquidTypes.Yellow).Volume = favoriteColor.Yellow; //LiquidVolumes.GetLiquidVolume(LiquidTypes.Black).Volume = favoriteColor.Black; Red = favoriteColor.Red; Green = favoriteColor.Green; Blue = favoriteColor.Blue; L = favoriteColor.L; A = favoriteColor.A; B = favoriteColor.B; BestMatchL = favoriteColor.L; BestMatchA = favoriteColor.A; BestMatchB = favoriteColor.B; PreventPropertyUpdate = false; LiquidVolumesOutOfRange = false; } /// /// Creates the brush stop. /// public BrushStop CreateBrushStop() { List list = SegmentModel.Job.ColorSpacesList; BrushStop s = new BrushStop(); if (ColorSpace == ColorSpaces.CMYK) ColorSpace = ColorSpaces.Volume; s.ColorSpace = list.FirstOrDefault(x => x.Space == ColorSpace); Configuration configuration = SegmentModel.Job.Machine.Configuration; Rml rml = SegmentModel.Job.Rml; s.Segment = BrushStop.Segment; s.SetLiquidVolumes(configuration, rml, rml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault()); s.OffsetPercent = OffsetPercent; s.StopIndex = StopIndex; s.IsOutOfGamut = IsOutOfGamut; s.ColorCatalog = ColorCatalog; s.ColorCatalogsItem = ColorCatalogsItem; LiquidVolumes.SetVolumesOnBrushStop(s); s.L = this.L; s.A = this.A; s.B = this.B; s.Red = this.Red; s.Green = this.Green; s.Blue = this.Blue; return s; } //Fine Tuning public void UndoColorChanges() { if (ColorSpace == ColorSpaces.LAB) { PreventPropertyUpdate = true; L = LBeforeChange; A = ABeforeChange; PreventPropertyUpdate = false; B = BBeforeChange; } else if (ColorSpace == ColorSpaces.Volume) { PreventPropertyUpdate = true; LiquidVolumes.Undo(); PreventPropertyUpdate = false; } } //Fine Tuning public void SaveColorBeforeChanges() { if (ColorSpace == ColorSpaces.LAB) { LBeforeChange = L; ABeforeChange = A; BBeforeChange = B; } else if (ColorSpace == ColorSpaces.Volume) { LiquidVolumes.SaveState(); } } #endregion #region changes private void OnVolumeChanged() { if (PreventPropertyUpdate) return; ColorSpace = ColorSpaces.Volume; RequiredMaxLiquidTest = true; RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); LastChangedColorSpace = ColorSpace; OnBrushStopFieldValueChanged(); } private void OnRGBChanged() { if (PreventPropertyUpdate) return; ColorSpace = ColorSpaces.RGB; InitColor(); LastChangedColorSpace = ColorSpace; OnBrushStopFieldValueChanged(); } private void OnHSBChanged() { if (PreventPropertyUpdate) return; // ColorSpace = ColorSpaces.HSB; Rgb rgb = GetRGBColor(); _red = (int)rgb.R; _green = (int)rgb.G; _blue = (int)rgb.B; InitColor(); LastChangedColorSpace = ColorSpace; OnBrushStopFieldValueChanged(); } private void OnLABChanged() { if (PreventPropertyUpdate) return; ColorSpace = ColorSpaces.LAB; Rgb rgb = GetRGBColor(); _red = (int)rgb.R; _green = (int)rgb.G; _blue = (int)rgb.B; InitColor(); OnBrushStopFieldValueChanged(); LastChangedColorSpace = ColorSpace; } private void OnColorCatalogsItemChanged() { if (PreventPropertyUpdate) return; ColorSpace = ColorSpaces.Catalog; if (_colorcatalogsitem != null) { _red = (int)_colorcatalogsitem.Red; _green = (int)_colorcatalogsitem.Green; _blue = (int)_colorcatalogsitem.Blue; InitColor(); LastChangedColorSpace = ColorSpace; BestMatchColor = Color; } if (ColorCatalogsItemChanged != null) { ColorCatalogsItemChanged.Invoke(this, new EventArgs()); } } private void OnOffsetPercentChanged() { //lenth? } private void OnStopIndexChanged() { //throw new NotImplementedException(); } public Rgb GetRGBColor() { if (ColorSpace == ColorSpaces.LAB) { Lab lab = new Lab(L, A, B); Rgb rgb = new Rgb(lab.ToRgb()); return rgb; } //if (ColorSpace == ColorSpaces.HSB) //{ // Hsb hsb = new Hsb(Hue, Saturation / 100, Brightness / 100); // Rgb rgb = new Rgb(hsb.ToRgb()); // return rgb; //} if (ColorSpace == ColorSpaces.Catalog && ColorCatalogsItem != null) { return new Rgb(ColorCatalogsItem.Red, ColorCatalogsItem.Green, ColorCatalogsItem.Blue); } return new Rgb(Red, Green, Blue); } public void ConvertColorToHSB() { //if (ColorSpace != ColorSpaces.HSB) //{ // if ( LastChangedColorSpace != ColorSpaces.HSB) // { // Hsb hsb = null; // if (LastChangedColorSpace == ColorSpaces.Volume) // { // BrushStop stop = CreateBrushStop(ColorSpaces.Volume); // try // { // IsBusy = true; // var output = _converter.Convert(stop, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false); // _red = output.SingleCoordinates.Red; // _green = output.SingleCoordinates.Green; // _blue = output.SingleCoordinates.Blue; // IsOutOfGamut = false;//output.OutOfGamut; // Rgb rgb = new Rgb(Red, Green, Blue); // hsb = new Hsb(rgb.To()); // } // catch (Exception ex) // { // LogManager.Log(ex, "An error occurred while trying to get volume => RGB from conversion engine."); // } // finally // { // IsBusy = false; // } // } // else if (LastChangedColorSpace == ColorSpaces.LAB) // { // Lab lab = new Lab(L, A, B); // hsb = new Hsb(lab.To()); // } // else if (LastChangedColorSpace == ColorSpaces.RGB) // { // Rgb rgb = new Rgb(Red, Green, Blue); // hsb = new Hsb(rgb.To()); // } // else if (LastChangedColorSpace == ColorSpaces.Catalog && ColorCatalogsItem != null) // { // Rgb rgb = new Rgb(ColorCatalogsItem.Red, ColorCatalogsItem.Green, ColorCatalogsItem.Blue); // hsb = new Hsb(rgb.To()); // } // if (hsb != null) // { // _hue = hsb.H; // _saturation = hsb.S * 100; ; // _brightness = hsb.B * 100; ; // RaisePropertyChanged(nameof(Hue)); // RaisePropertyChanged(nameof(Saturation)); // RaisePropertyChanged(nameof(Brightness)); // } // } // ColorSpace = ColorSpaces.HSB; // RequiredMaxLiquidTest = false; // RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); //} } public void ConvertColorToRGB() { if (ColorSpace != ColorSpaces.RGB) { if (LastChangedColorSpace != ColorSpaces.RGB) { if (LastChangedColorSpace == ColorSpaces.Catalog && ColorCatalogsItem != null) { _red = ColorCatalogsItem.Red; _green = ColorCatalogsItem.Green; _blue = ColorCatalogsItem.Blue; } else if (LastChangedColorSpace == ColorSpaces.Volume) { BrushStop stop = CreateBrushStop(ColorSpaces.Volume); try { IsBusy = true; var output = _converter.Convert(stop, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false); _red = output.SingleCoordinates.Red; _green = output.SingleCoordinates.Green; _blue = output.SingleCoordinates.Blue; IsOutOfGamut = false;//output.OutOfGamut; if (IsLiquidVolumesOutOfRange) { BestMatchColor = Color.FromRgb((byte)output.SingleCoordinates.Red, (byte)output.SingleCoordinates.Green, (byte)output.SingleCoordinates.Blue); InitColor(); } } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to get volume => RGB from conversion engine."); } finally { IsBusy = false; } } else { Rgb rgb = GetRGBColor(); _red = (int)rgb.R; _green = (int)rgb.G; _blue = (int)rgb.B; ColorSpace = ColorSpaces.RGB; ConvertColor(); } } ColorSpace = ColorSpaces.RGB; RaisePropertyChanged(nameof(Red)); RaisePropertyChanged(nameof(Green)); RaisePropertyChanged(nameof(Blue)); RequiredMaxLiquidTest = false; RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); } } public void ConvertColorToLAB() { if (ColorSpace != ColorSpaces.LAB) { if (LastChangedColorSpace != ColorSpaces.LAB) { Lab lab = null; if (LastChangedColorSpace == ColorSpaces.Catalog && ColorCatalogsItem != null) { _l = ColorCatalogsItem.L; _a = ColorCatalogsItem.A; _b = ColorCatalogsItem.B; BestMatchL = _l; BestMatchA = _a; BestMatchB = _b; } else if (LastChangedColorSpace == ColorSpaces.Volume) { BrushStop stop = CreateBrushStop(ColorSpaces.Volume); try { IsBusy = true; var output = _converter.Convert(stop, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false); _l = output.SingleCoordinates.L; _a = output.SingleCoordinates.A; _b = output.SingleCoordinates.B; BestMatchL = _l; BestMatchA = _a; BestMatchB = _b; IsOutOfGamut = false;//output.OutOfGamut; if (IsLiquidVolumesOutOfRange) { _red = output.SingleCoordinates.Red; _green = output.SingleCoordinates.Green; _blue = output.SingleCoordinates.Blue; BestMatchColor = Color.FromRgb((byte)_red, (byte)_green, (byte)_blue); InitColor(); } } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to convert volume to LAB."); } finally { IsBusy = false; } } //else if (LastChangedColorSpace == ColorSpaces.HSB) //{ // Hsb hsb = new Hsb(Hue, Saturation / 100, Brightness / 100); // lab = new Lab(hsb.To()); //} else if (LastChangedColorSpace == ColorSpaces.RGB) { Rgb rgb = new Rgb(Red, Green, Blue); lab = new Lab(rgb.To()); } if (lab != null) { _l = lab.L; _a = lab.A; _b = lab.B; BestMatchL = _l; BestMatchA = _a; BestMatchB = _b; ColorSpace = ColorSpaces.LAB; ConvertColor(); } } ColorSpace = ColorSpaces.LAB; RaisePropertyChanged(nameof(L)); RaisePropertyChanged(nameof(A)); RaisePropertyChanged(nameof(B)); RequiredMaxLiquidTest = false; RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); } } public void ConvertColorToVolume() { RequiredMaxLiquidTest = true; if (ColorSpace != ColorSpaces.Volume) { if (LastChangedColorSpace != ColorSpaces.Volume) { if (LastChangedColorSpace == ColorSpaces.Catalog) { if (ColorCatalogsItem != null) { LiquidVolumes.ResetVolumeSilent(); foreach (var liquidVolume in LiquidVolumes.Where(x => x.IdsPack.LiquidType.AvailableForStandardUser)) { liquidVolume.SetVolumeSilent(ColorCatalogsItem.GetLiquidVolumeByName(liquidVolume.IdsPack.LiquidType.DisplayName)); } LiquidVolumes.RaiseVolume(); IsOutOfGamut = false; // RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); // RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); } ColorSpace = ColorSpaces.Volume; RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); return; } ColorSpaces colorSpace = LastChangedColorSpace; //if (colorSpace == ColorSpaces.HSB) //{ // colorSpace = ColorSpaces.RGB; //} //else if (colorSpace == ColorSpaces.CMYK) { colorSpace = ColorSpaces.Volume; } BrushStop stop = CreateBrushStop(colorSpace); try { IsBusy = true; var output = _converter.Convert(stop, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false); foreach (var outputLiquid in output.SingleCoordinates.OutputLiquids) { LiquidVolumes.GetLiquidVolume(outputLiquid.LiquidType)?.SetVolumeSilent(outputLiquid.Volume); } IsOutOfGamut = false; //if ( LastChangedColorSpace != ColorSpaces.RGB) //{ // _red = output.SingleCoordinates.Red; // _green = output.SingleCoordinates.Green; // _blue = output.SingleCoordinates.Blue; // InitColor(); // BestMatchColor = Color.FromRgb((byte)output.SingleCoordinates.Red, (byte)output.SingleCoordinates.Green, (byte)output.SingleCoordinates.Blue); //} LiquidVolumes.RaiseVolume(); RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to get volume => RGB from conversion engine." + ex); //convertedString = Regex.Replace(ex,@"\xEF\xBF\xBD"," "); } finally { ColorSpace = ColorSpaces.Volume; IsBusy = false; } } ColorSpace = ColorSpaces.Volume; RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); RaisePropertyChanged(nameof(IsLiquidVolumeBelowMinLimit)); } } public void ConvertColorToCatalogs(List catalogs) { if (ColorSpace != ColorSpaces.Catalog) { if (LastChangedColorSpace != ColorSpaces.Catalog) { if (BestMatchColor == null) BestMatchColor = Color; var closestItem = catalogs.SelectMany(x => x.AllItemsOrdered).GetClosestItem(BestMatchColor); _colorcatalogsitem = closestItem; if (ColorCatalogsItemChanged != null) { ColorCatalogsItemChanged.Invoke(this, new EventArgs()); } RaisePropertyChangedAuto(nameof(ColorCatalogsItem)); } ColorSpace = ColorSpaces.Catalog; RaisePropertyChanged(nameof(ColorCatalog)); } } public void FineTuningConverter(double cyan, double yellow, double magenta, double black) { RequiredMaxLiquidTest = true; ColorSpaces colorSpace = ColorSpaces.LAB; BrushStop stop = CreateBrushStopForFineTuning(colorSpace, cyan, yellow, magenta, black); try { IsBusy = true; var output = _converter.Convert(stop, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false, ConversionType.FineTuning); var b = output.SingleCoordinates.OutputLiquids.FirstOrDefault(x => x.LiquidType == PMR.ColorLab.LiquidType.Black); if (b != null) { if (b.Volume > 0 && b.Volume < 0.5)//bug 7959 0.001 < K% < 0.5 ==> reset the K to 0. { b.Volume = 0; } } foreach (var outputLiquid in output.SingleCoordinates.OutputLiquids) { LiquidVolumes.GetLiquidVolume(outputLiquid.LiquidType)?.SetVolumeSilent(outputLiquid.Volume); } IsOutOfGamut = output.OutOfGamut; if (IsOutOfGamut) { BrushStop stopLAB = CreateBrushStop(ColorSpaces.Volume); IsBusy = true; var outputLAB = _converter.Convert(stopLAB, SegmentModel.Job.Machine.Configuration, SegmentModel.Job.Rml, false, false, false); _l = output.SingleCoordinates.L; _a = output.SingleCoordinates.A; _b = output.SingleCoordinates.B; } BestMatchRed = output.SingleCoordinates.Red; BestMatchGreen = output.SingleCoordinates.Green; BestMatchBlue = output.SingleCoordinates.Blue; } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to get volume => RGB from conversion engine." + ex); } finally { IsBusy = false; } } public void RaiseOffsetChanged() { RaisePropertyChanged(nameof(OffsetPercent)); RaisePropertyChanged(nameof(OffsetMeters)); } public void RaiseColorCatalogsItemChanged() { RaisePropertyChanged(nameof(ColorCatalogsItem)); } public void UpdateColorOnAccept() { if (ColorSpace == ColorSpaces.Catalog) { if (_colorcatalogsitem != null) { _red = (int)_colorcatalogsitem.Red; _green = (int)_colorcatalogsitem.Green; _blue = (int)_colorcatalogsitem.Blue; InitColor(); BestMatchColor = Color; } } InitColorsFromBestmatch(); } public void UpdateColorFromFineTuningDlg() { Rgb rgb = GetRGBColor(); _red = (int)rgb.R; _green = (int)rgb.G; _blue = (int)rgb.B; InitColor(); } #endregion #region color converters public void InitColorsFromBestmatch() { if (BestMatchColor == null || BestMatchColor == Color) return; _red = BestMatchColor.R; _green = BestMatchColor.G; _blue = BestMatchColor.B; if (ColorSpace == BL.Enumerations.ColorSpaces.LAB) { _l = _bestMatchL; _a = _bestMatchA; _b = _bestMatchB; } IsOutOfGamut = false; InitColor(); } private double GetTotalMaximumLiquidNlPerCMLimit() { try { var tables = SegmentModel.Job.Rml.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); if (tables.Count > 0) { return tables.Max(x => x.MaxInkUptake); } else { return MAX_INK_UPTAKE; } } catch { return MAX_INK_UPTAKE; } } private double GetMinLimitLiquid(LiquidTypes type) { try { var tables = SegmentModel.Job.Rml.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); LiquidTypesRml liquidType = SegmentModel.Job.Rml.LiquidTypesRmls.FirstOrDefault(x => x.LiquidType.Type == type); if (tables.Count > 0 && liquidType != null && liquidType.MaxNlPerCm != 0) { var vmax = Math.Max(SegmentModel.Job.Rml.VMax / 10d, 0); if (type == LiquidTypes.Black) { vmax = Math.Max(SegmentModel.Job.Rml.VMax, 0); } return (vmax * tables[0].MinInkUptake) / liquidType.MaxNlPerCm; } else { return 0; } } catch { return 0; } } public double GetColorNLPerCm(double color, LiquidTypes type) { StandardColorDispensingCalc calc = new StandardColorDispensingCalc(); Rml rml = SegmentModel.Job.Rml; LiquidTypesRml liquidType = rml.LiquidTypesRmls.FirstOrDefault(x => x.LiquidType.Type == type); if (liquidType != null) { double maxNlPerCm = liquidType.MaxNlPerCm; return calc.CalculateNanoliterPerCentimeter(color, maxNlPerCm); } return 0.0; } public void OnBrushStopFieldValueChanged() { IsBusy = true; _volumeConversionTimer.ResetReplace(() => { if (ColorSpace == BL.Enumerations.ColorSpaces.Volume) { //RaisePropertyChanged(nameof(IsLiquidVolumesOutOfRange)); if (IsLiquidVolumesOutOfRange || IsLiquidVolumeBelowMinLimit) { IsBusy = false; return; } } ConvertColor(); }); } public void ConvertColor() { try { ColorSpaces colorSpace = ColorSpace; BrushStop stop = CreateBrushStop(colorSpace); Configuration configuration = SegmentModel.Job.Machine.Configuration; Rml rml = SegmentModel.Job.Rml; bool bChangedVersion = false; if (stop.BrushColorSpace == BL.Enumerations.ColorSpaces.Volume && rml.ColorConversionVersion == 6) { rml.ColorConversionVersion = 5; bChangedVersion = true; } var output = _converter.Convert(stop, configuration, rml, false, false, false); if (bChangedVersion) { rml.ColorConversionVersion = 6; } //output.SingleCoordinates.OutputLiquids.SingleOrDefault(x => x.LiquidType == PMR.ColorLab.LiquidType.Cyan).Volume; if (stop.BrushColorSpace == BL.Enumerations.ColorSpaces.Volume) { IsOutOfGamut = false; _red = output.SingleCoordinates.Red; _green = output.SingleCoordinates.Green; _blue = output.SingleCoordinates.Blue; InitColor(); BestMatchColor = Color.FromRgb((byte)output.SingleCoordinates.Red, (byte)output.SingleCoordinates.Green, (byte)output.SingleCoordinates.Blue); } else if (stop.BrushColorSpace == BL.Enumerations.ColorSpaces.LAB) { IsOutOfGamut = _converter.IsOutOfGamut(stop, configuration, rml); if (IsOutOfGamut) { BestMatchL = (double)output.SingleCoordinates.L; BestMatchA = (double)output.SingleCoordinates.A; BestMatchB = (double)output.SingleCoordinates.B; Lab lab = new Lab(output.SingleCoordinates.L, output.SingleCoordinates.A, output.SingleCoordinates.B); Rgb rgb = new Rgb(lab.ToRgb()); BestMatchColor = Color.FromRgb((byte)(int)rgb.R, (byte)(int)rgb.G, (byte)(int)rgb.B); } else { BestMatchL = L; BestMatchA = A; BestMatchB = B; Lab lab1 = new Lab(L, A, B); Rgb rgb1 = new Rgb(lab1.ToRgb()); BestMatchColor = Color.FromRgb((byte)(int)rgb1.R, (byte)(int)rgb1.G, (byte)(int)rgb1.B); } } else if (stop.BrushColorSpace == BL.Enumerations.ColorSpaces.RGB) { IsOutOfGamut = _converter.IsOutOfGamut(stop, configuration, rml); if (IsOutOfGamut) { BestMatchColor = Color.FromRgb((byte)output.SingleCoordinates.Red, (byte)output.SingleCoordinates.Green, (byte)output.SingleCoordinates.Blue); } else { BestMatchColor = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue); } if (IsOutOfGamut != output.OutOfGamut) { } } //else if (stop.BrushColorSpace == BL.Enumerations.ColorSpaces.HSB) //{ // IsOutOfGamut = _converter.IsOutOfGamut(stop, configuration, rml); // BestMatchColor = Color.FromRgb((byte)output.SingleCoordinates.Red, (byte)output.SingleCoordinates.Green, (byte)output.SingleCoordinates.Blue); //} } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to get volume => RGB from conversion engine." + ex); BestMatchColor = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue); } finally { IsBusy = false; } } public void IsOutputOfGamut(ColorSpaces colorSpace) { try { BrushStop stop = CreateBrushStop(colorSpace); Configuration configuration = SegmentModel.Job.Machine.Configuration; Rml rml = SegmentModel.Job.Rml; IsOutOfGamut = _converter.IsOutOfGamut(stop, configuration, rml); } catch (Exception ex) { LogManager.Log(ex, "An error occurred while trying to test IsOutputOfGammut from conversion engine." + ex); BestMatchColor = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue); } finally { IsBusy = false; } } #endregion } }