| | |
| | | using Bro.Common.Helper; |
| | | using Bro.Common.Interface; |
| | | using Bro.Common.Model; |
| | | using HalconDotNet; |
| | | using Newtonsoft.Json; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | |
| | | using System.Drawing.Design; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace Bro.M071.Process |
| | | { |
| | | public class KeyLocation : IComplexDisplay |
| | | { |
| | | [Category("键名配置")] |
| | | [Description("单键键名")] |
| | | [TypeConverter(typeof(KeyNameDictConverter))] |
| | | public string Key { get; set; } |
| | | |
| | | [Category("位置配置")] |
| | | [Description("单键在键盘平面图上的位置显示")] |
| | | public Rectangle KeyRect { get; set; } = new Rectangle(); |
| | | |
| | | [Category("位置配置")] |
| | | [Description("单键之后间隙位置")] |
| | | public Rectangle IntervalRect { get; set; } = new Rectangle(); |
| | | |
| | | public string GetDisplayText() |
| | | { |
| | | return $"{Key}:{KeyRect.X},{KeyRect.Y},{KeyRect.Width},{KeyRect.Height}"; |
| | | } |
| | | } |
| | | |
| | | |
| | | public class KeyAlgorithem : IComplexDisplay |
| | | { |
| | | [Browsable(false)] |
| | |
| | | { |
| | | return $"{Name} -- {AlgorithemPath}"; |
| | | } |
| | | } |
| | | |
| | | public class MeasureType : Spec |
| | | { |
| | | [Category("检测类型")] |
| | | [Description("检测类型")] |
| | | [DisplayName("检测类型")] |
| | | public override string Code { get; set; } |
| | | |
| | | [Category("检测算法")] |
| | | [Description("检测算法路径")] |
| | | [Editor(typeof(FileDialogEditor), typeof(UITypeEditor))] |
| | | public string AlgorithemPath { get; set; } |
| | | } |
| | | |
| | | public class KeyResult : IComplexDisplay |
| | |
| | | { |
| | | public string GetDisplayText() |
| | | { |
| | | return Name + " " + string.Join(" ", Destination.Select(u => u.GetDisplayText())) + " " + CameraOp.GetDisplayText(); |
| | | return (IsEnabled ? "" : "禁用 ") + Name + " " + MotionOp.GetDisplayText() + " " + CameraOp.GetDisplayText(); |
| | | } |
| | | |
| | | public List<string> GetHalconToolPathList() |
| | |
| | | [Description("拍照点名称")] |
| | | public string Name { get; set; } |
| | | |
| | | [Category("设备配置")] |
| | | [Description("运动设备")] |
| | | [TypeConverter(typeof(DeviceSelectorConverter<IMotion>))] |
| | | public string MotionDevice { get; set; } |
| | | [Category("启用设置")] |
| | | [Description("true:启用 false:禁用")] |
| | | public bool IsEnabled { get; set; } = true; |
| | | |
| | | [Category("运动点位")] |
| | | [Description("运动点位")] |
| | | //[Category("设备配置")] |
| | | //[Description("运动设备")] |
| | | //[TypeConverter(typeof(DeviceSelectorConverter<IMotion>))] |
| | | //public string MotionDevice { get; set; } |
| | | |
| | | //[Category("运动点位")] |
| | | //[Description("运动点位")] |
| | | //[TypeConverter(typeof(ComplexObjectConvert))] |
| | | //[Editor(typeof(ComplexCollectionEditor<AxisInfo>), typeof(UITypeEditor))] |
| | | //public List<AxisInfo> Destination { get; set; } = new List<AxisInfo>(); |
| | | |
| | | [Category("运动机构配置")] |
| | | [Description("运动机构配置")] |
| | | [TypeConverter(typeof(ComplexObjectConvert))] |
| | | [Editor(typeof(ComplexCollectionEditor<AxisInfo>), typeof(UITypeEditor))] |
| | | public List<AxisInfo> Destination { get; set; } = new List<AxisInfo>(); |
| | | [Editor(typeof(IOperationConfigByDeviceEditor), typeof(UITypeEditor))] |
| | | public DeviceOpBind MotionOp { get; set; } = new DeviceOpBind(); |
| | | |
| | | [Category("相机和操作配置")] |
| | | [Description("相机和操作配置")] |
| | |
| | | |
| | | public class KeyUnit : IComplexDisplay, IHalconToolPath |
| | | { |
| | | #region 配置 |
| | | private string key = ""; |
| | | [Category("键名配置")] |
| | | [Description("单键检测键名")] |
| | |
| | | get => key; |
| | | set |
| | | { |
| | | AlignName = key = value; |
| | | AliasName = key = value; |
| | | } |
| | | } |
| | | |
| | | [Category("键名配置")] |
| | | [Description("别名")] |
| | | public string AlignName { get; set; } |
| | | public string AliasName { get; set; } |
| | | |
| | | [Category("启用设置")] |
| | | [Description("true:启用 false:禁用")] |
| | | public bool IsEnabled { get; set; } = true; |
| | | |
| | | [Category("图像来源")] |
| | | [Description("拍照点位")] |
| | | [TypeConverter(typeof(SnapshotPointConverter))] |
| | | public string SnapshotPoint { get; set; } |
| | | public string SnapshotPointId { get; set; } |
| | | |
| | | [Category("图像来源")] |
| | | [Description("拍照点位获取的图片索引")] |
| | | public int ImageIndex { get; set; } = 0; |
| | | [Description("拍照点位获取的图片序号,从1开始")] |
| | | public int ImageSeq { get; set; } = 1; |
| | | |
| | | [Category("算法配置")] |
| | | [Description("单键检测配置算法类型")] |
| | | [TypeConverter(typeof(KeyAlgorithemConverter))] |
| | | public string KeyAlgorithem { get; set; } |
| | | public string KeyAlgorithemId { get; set; } |
| | | |
| | | [Category("算法配置")] |
| | | [Description("单键检测配置结果类型")] |
| | | [TypeConverter(typeof(KeyResultConverter))] |
| | | public string KeyResult { get; set; } |
| | | public string KeyResultId { get; set; } |
| | | #endregion |
| | | |
| | | #region 检测相关字段 |
| | | public Dictionary<string, double> KeyValues = null; |
| | | //public SnapshotPoint SnapshotPoint = null; |
| | | public string KeyAlgorithemPath = ""; |
| | | public List<string> KeyResultList = null; |
| | | #endregion |
| | | |
| | | public string GetDisplayText() |
| | | { |
| | | return $"{AlignName}"; |
| | | string snapShot = "未指定"; |
| | | |
| | | using (var scope = GlobalVar.Container.BeginLifetimeScope()) |
| | | { |
| | | var config = scope.Resolve<IProcessConfig>(); |
| | | if (config != null) |
| | | { |
| | | var snapshotPoint = (config as M071Config).SnapshotPointCollection.FirstOrDefault(u => u.Id == SnapshotPointId); |
| | | if (snapshotPoint != null) |
| | | { |
| | | snapShot = snapshotPoint.Name; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return $"{AliasName}-{snapShot}-{ImageSeq}"; |
| | | } |
| | | |
| | | public List<string> GetHalconToolPathList() |
| | | { |
| | | return null; |
| | | using (var scope = GlobalVar.Container.BeginLifetimeScope()) |
| | | { |
| | | IProcessConfig iConfig = scope.Resolve<IProcessConfig>(); |
| | | |
| | | if (iConfig is M071Config config) |
| | | { |
| | | var algo = config.KeyAlgorithemCollection.FirstOrDefault(u => u.Id == KeyAlgorithemId); |
| | | if (algo != null) |
| | | { |
| | | return new List<string>() { algo.AlgorithemPath }; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return new List<string>(); |
| | | } |
| | | } |
| | | |
| | | public class MeasurementUint : IComplexDisplay |
| | | public class ProductionMeasurement : INotifyPropertyChanged, IDisposable |
| | | { |
| | | public string Barcode; |
| | | public string PResult; |
| | | |
| | | public List<MeasurementUnit> Measurements = new List<MeasurementUnit>(); |
| | | |
| | | public List<IShapeElement> ElementList = new List<IShapeElement>(); |
| | | |
| | | public DateTime? StartTime = null; |
| | | |
| | | public DateTime? EndTime = null; |
| | | |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public void Dispose() |
| | | { |
| | | Measurements?.ForEach(m => m?.Dispose()); |
| | | Measurements = null; |
| | | ElementList = null; |
| | | Barcode = null; |
| | | GC.Collect(); |
| | | } |
| | | |
| | | public void InitialMeasurementsPropertyChanged() |
| | | { |
| | | Measurements.ForEach(m => m.PropertyChanged += M_PropertyChanged); |
| | | } |
| | | |
| | | private object pChangedLock = new object(); |
| | | private void M_PropertyChanged(object sender, PropertyChangedEventArgs e) |
| | | { |
| | | lock (pChangedLock) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Measurements")); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public class MeasurementUnit : IComplexDisplay, INotifyPropertyChanged, IDisposable |
| | | { |
| | | public string Id = Guid.NewGuid().ToString(); |
| | | |
| | | #region 配置 |
| | | [Category("名称")] |
| | | [Description("名称")] |
| | | public string Name { get; set; } = ""; |
| | | |
| | | [Category("启用设置")] |
| | | [Description("true:启用 false:禁用")] |
| | | public bool IsEnabled { get; set; } = true; |
| | | |
| | | [Category("算法配置")] |
| | | [Description("检测和标准类型")] |
| | |
| | | [TypeConverter(typeof(ComplexObjectConvert))] |
| | | [Editor(typeof(ComplexCollectionEditor<KeyUnitBind>), typeof(UITypeEditor))] |
| | | public List<KeyUnitBind> KeyUnitCollection { get; set; } = new List<KeyUnitBind>(); |
| | | #endregion |
| | | |
| | | #region 显示 |
| | | [Browsable(false)] |
| | | public RectangleF DisplayLocation { get; set; } = new RectangleF(); |
| | | public Rectangle DisplayLocation { get; set; } = new Rectangle(10, 10, 100, 100); |
| | | #endregion |
| | | |
| | | #region 检测结果 |
| | | [Browsable(false)] |
| | | public MeasureType Spec { get; set; } = null; |
| | | #endregion |
| | | |
| | | public bool IsUpdated = false; |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | public void Dispose() |
| | | { |
| | | KeyUnitCollection?.ForEach(k => k?.Dispose()); |
| | | KeyUnitCollection = null; |
| | | } |
| | | |
| | | public string GetDisplayText() |
| | | { |
| | | if (string.IsNullOrWhiteSpace(Name)) |
| | | { |
| | | return string.Join("-", KeyUnitCollection.Select(u => u.GetDisplayText())) + "-" + MeasureType.ToString(); |
| | | return (IsEnabled ? "" : "禁用 ") + string.Join("-", KeyUnitCollection.Select(u => u.GetDisplayText())) + "-" + MeasureType?.ToString(); |
| | | } |
| | | else |
| | | { |
| | | return Name; |
| | | return (IsEnabled ? "" : "禁用 ") + Name; |
| | | } |
| | | } |
| | | |
| | | public void InitialKeyUnitMeasureChanged() |
| | | { |
| | | KeyUnitCollection.ForEach(k => k.PropertyChanged += K_PropertyChanged); |
| | | } |
| | | |
| | | private void K_PropertyChanged(object sender, PropertyChangedEventArgs e) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("KeyUnitCollection")); |
| | | } |
| | | |
| | | public MeasurementUnit Copy() |
| | | { |
| | | MeasurementUnit mUnit = new MeasurementUnit(); |
| | | |
| | | mUnit.Id = this.Id; |
| | | mUnit.Name = this.Name; |
| | | if (string.IsNullOrWhiteSpace(mUnit.Name)) |
| | | { |
| | | mUnit.Name = string.Join("-", KeyUnitCollection.Select(u => u.GetDisplayText())); |
| | | } |
| | | |
| | | mUnit.IsEnabled = this.IsEnabled; |
| | | mUnit.MeasureType = this.MeasureType; |
| | | |
| | | mUnit.DisplayLocation = new Rectangle(this.DisplayLocation.Location, this.DisplayLocation.Size); |
| | | |
| | | if (this.Spec == null) |
| | | { |
| | | mUnit.Spec = null; |
| | | } |
| | | else |
| | | { |
| | | mUnit.Spec = new MeasureType(); |
| | | mUnit.Spec.Code = this.Spec.Code; |
| | | mUnit.Spec.AlgorithemPath = this.Spec.AlgorithemPath; |
| | | mUnit.Spec.StandardValue = this.Spec.StandardValue; |
| | | mUnit.Spec.Tolrenance_Positive = this.Spec.Tolrenance_Positive; |
| | | mUnit.Spec.Tolrenance_Negative = this.Spec.Tolrenance_Negative; |
| | | } |
| | | |
| | | this.KeyUnitCollection.ForEach(k => |
| | | { |
| | | mUnit.KeyUnitCollection.Add(k.Copy()); |
| | | }); |
| | | |
| | | return mUnit; |
| | | } |
| | | } |
| | | |
| | | public class KeyUnitBind : IComplexDisplay |
| | | public class KeyUnitBind : IComplexDisplay, INotifyPropertyChanged, IDisposable |
| | | { |
| | | [Category("单键配置")] |
| | | [Description("单键配置")] |
| | |
| | | [Category("单键配置")] |
| | | [Description("单键结果配置")] |
| | | [TypeConverter(typeof(KeyUnitResultConverter))] |
| | | public string KeyResult { get; set; } = ""; |
| | | public string KeyResultId { get; set; } = ""; |
| | | |
| | | |
| | | public List<HImage> KeyImages = new List<HImage>(); |
| | | |
| | | public volatile int ImageSaveStatus = 0; |
| | | //[Browsable(false)] |
| | | //public NoticedDictionary<string, double?> MeasureValueDict { get; set; } = new NoticedDictionary<string, double?>(); |
| | | |
| | | [Browsable(false)] |
| | | public Dictionary<string, double?> MeasureValueDict { get; set; } = new Dictionary<string, double?>(); |
| | | |
| | | public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | //public void InitialMeasureValueDictPropertyChanged() |
| | | //{ |
| | | // MeasureValueDict.PropertyChanged += MeasureValueDict_PropertyChanged; |
| | | //} |
| | | |
| | | //private void MeasureValueDict_PropertyChanged(object sender, PropertyChangedEventArgs e) |
| | | //{ |
| | | // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MeasureValueDict")); |
| | | //} |
| | | |
| | | public bool? IsDone = null; |
| | | |
| | | public string GetDisplayText() |
| | | { |
| | | string msg = Key; |
| | | |
| | | msg += string.IsNullOrWhiteSpace(KeyResult) ? "" : $"-{KeyResult}"; |
| | | msg += string.IsNullOrWhiteSpace(KeyResultId) ? "" : $"-{KeyResultId}"; |
| | | |
| | | return msg; |
| | | } |
| | | |
| | | public void Dispose() |
| | | { |
| | | while (ImageSaveStatus != 0) |
| | | { |
| | | Thread.Sleep(10); |
| | | } |
| | | |
| | | KeyImages?.ForEach(i => |
| | | { |
| | | i?.Dispose(); |
| | | i = null; |
| | | }); |
| | | KeyImages = null; |
| | | MeasureValueDict = null; |
| | | } |
| | | |
| | | object valueDictLock = new object(); |
| | | public void FillKeyValues(Dictionary<string, double> valuePairs) |
| | | { |
| | | lock (valueDictLock) |
| | | { |
| | | if (valuePairs == null || valuePairs.Count == 0) |
| | | { |
| | | IsDone = false; |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsDone")); |
| | | return; |
| | | } |
| | | |
| | | foreach (KeyValuePair<string, double> pair in valuePairs) |
| | | { |
| | | if (MeasureValueDict.ContainsKey(pair.Key)) |
| | | { |
| | | MeasureValueDict[pair.Key] = pair.Value; |
| | | } |
| | | } |
| | | |
| | | if (MeasureValueDict.Values.All(u => u != null)) |
| | | { |
| | | IsDone = true; |
| | | } |
| | | |
| | | if (IsDone != null) |
| | | { |
| | | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsDone")); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public KeyUnitBind Copy() |
| | | { |
| | | KeyUnitBind clone = new KeyUnitBind(); |
| | | clone.Key = this.Key; |
| | | clone.KeyResultId = this.KeyResultId; |
| | | |
| | | this.MeasureValueDict.Keys.ToList().ForEach(k => |
| | | { |
| | | clone.MeasureValueDict[k] = null; |
| | | }); |
| | | |
| | | return clone; |
| | | } |
| | | } |
| | | |
| | | //public class NoticedDictionary<T1, T2> : Dictionary<T1, T2>, INotifyPropertyChanged |
| | | //{ |
| | | // public event PropertyChangedEventHandler PropertyChanged; |
| | | |
| | | // public new T2 this[T1 index] |
| | | // { |
| | | // get => base[index]; |
| | | // set |
| | | // { |
| | | // base[index] = value; |
| | | // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Index")); |
| | | // } |
| | | // } |
| | | //} |
| | | } |