From c49c45d6e42402376ec1069d081c6eb289e62380 Mon Sep 17 00:00:00 2001 From: "xhm\\HP" <1173131411@qq.com> Date: Sun, 16 Mar 2025 13:11:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=95=8C=E9=9D=A2=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DH.Commons.Devies/Base/VisionEngineBase.cs | 186 +++ DH.Commons.Devies/DH.Commons.Devies.csproj | 15 +- DH.Commons/DH.Commons.csproj | 16 +- .../DetectionConfig.cs | 234 +++- DH.Commons/Enums/SolidMotionCardEnum.cs | 2 +- DH.Commons/GlobalVar.cs | 2 +- DH.Commons/Helper/EnumHelper.cs | 771 ++++++++++++ DH.Commons/Helper/HDevEngineTool.cs | 2 +- DH.Commons/Helper/OpenCVEngineTool.cs | 2 +- DH.Commons/Helper/UIHelper.cs | 123 ++ DH.Commons/Interface/IShapeElement.cs | 39 + DH.Devices.Vision/DH.Devices.Vision.csproj | 42 +- DH.Devices.Vision/GlobalSuppressions.cs | 10 + DH.Devices.Vision/SimboDetection.cs | 13 +- .../SimboInstanceSegmentation.cs | 9 + DH.Devices.Vision/SimboObjectDetection.cs | 9 + DH.Devices.Vision/SimboVisionDriver.cs | 657 ++++++++++- DH.Devices.Vision/SimboVisionMLBase.cs | 42 +- DH.Devices.Vision/SimboVisionModel.cs | 6 + DH.UI.Model.Winform/Canvas.Designer.cs | 599 ++++++++++ DH.UI.Model.Winform/Canvas.cs | 629 ++++++++++ DH.UI.Model.Winform/Canvas.resx | 120 ++ DH.UI.Model.Winform/CanvasImage.Designer.cs | 33 + DH.UI.Model.Winform/CanvasImage.cs | 943 +++++++++++++++ DH.UI.Model.Winform/CanvasImage.resx | 120 ++ DH.UI.Model.Winform/Ctrl/GridCtrl.Designer.cs | 109 ++ DH.UI.Model.Winform/Ctrl/GridCtrl.cs | 74 ++ DH.UI.Model.Winform/Ctrl/GridCtrl.resx | 120 ++ DH.UI.Model.Winform/Ctrl/GridCtrlHost.cs | 12 + .../Ctrl/IOIndicatorCtrl.Designer.cs | 78 ++ DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.cs | 126 ++ DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.resx | 120 ++ .../DH.UI.Model.Winform.csproj | 48 + DH.UI.Model.Winform/Element/CommonHelper.cs | 199 ++++ DH.UI.Model.Winform/Element/ElementBase.cs | 980 ++++++++++++++++ .../Element/MLResultDisplay.cs | 325 ++++++ DH.UI.Model.Winform/GridCtrl.Designer.cs | 109 ++ DH.UI.Model.Winform/GridCtrl.cs | 74 ++ DH.UI.Model.Winform/GridCtrl.resx | 120 ++ DH.UI.Model.Winform/GridCtrlHost.cs | 12 + .../IOIndicatorCtrl.Designer.cs | 78 ++ DH.UI.Model.Winform/IOIndicatorCtrl.cs | 126 ++ DH.UI.Model.Winform/IOIndicatorCtrl.resx | 120 ++ DHSoftware.sln | 35 +- DHSoftware/DHSoftware.csproj | 2 + DHSoftware/MainWindow.Designer.cs | 23 +- DHSoftware/MainWindow.cs | 1030 +++++------------ DHSoftware/MainWindow.resx | 4 +- .../Views/CtrlVisionDisplay.Designer.cs | 196 ++++ DHSoftware/Views/CtrlVisionDisplay.cs | 172 +++ DHSoftware/Views/CtrlVisionDisplay.resx | 123 ++ .../Views/CtrlVisionRunBase.Designer.cs | 174 +++ DHSoftware/Views/CtrlVisionRunBase.cs | 249 ++++ DHSoftware/Views/CtrlVisionRunBase.resx | 120 ++ DHSoftware/Views/DefectRowEdit.Designer.cs | 177 +-- DHSoftware/Views/DefectRowEdit.cs | 5 +- .../Views/DetectConfigControl.Designer.cs | 351 +++--- DHSoftware/Views/DetectConfigControl.cs | 170 +-- DHSoftware/Views/SettingWindow.cs | 1 + DHSoftware/Views/UserConfigFrm.cs | 5 +- DHSoftware/Views/UserDetetion.cs | 5 +- DHSoftware/productModel.cs | 3 +- 62 files changed, 9095 insertions(+), 1204 deletions(-) create mode 100644 DH.Commons.Devies/Base/VisionEngineBase.cs rename {DH.Devices.Vision => DH.Commons}/DetectionConfig.cs (67%) create mode 100644 DH.Commons/Helper/EnumHelper.cs create mode 100644 DH.Commons/Helper/UIHelper.cs create mode 100644 DH.Commons/Interface/IShapeElement.cs create mode 100644 DH.Devices.Vision/GlobalSuppressions.cs create mode 100644 DH.UI.Model.Winform/Canvas.Designer.cs create mode 100644 DH.UI.Model.Winform/Canvas.cs create mode 100644 DH.UI.Model.Winform/Canvas.resx create mode 100644 DH.UI.Model.Winform/CanvasImage.Designer.cs create mode 100644 DH.UI.Model.Winform/CanvasImage.cs create mode 100644 DH.UI.Model.Winform/CanvasImage.resx create mode 100644 DH.UI.Model.Winform/Ctrl/GridCtrl.Designer.cs create mode 100644 DH.UI.Model.Winform/Ctrl/GridCtrl.cs create mode 100644 DH.UI.Model.Winform/Ctrl/GridCtrl.resx create mode 100644 DH.UI.Model.Winform/Ctrl/GridCtrlHost.cs create mode 100644 DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.Designer.cs create mode 100644 DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.cs create mode 100644 DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.resx create mode 100644 DH.UI.Model.Winform/DH.UI.Model.Winform.csproj create mode 100644 DH.UI.Model.Winform/Element/CommonHelper.cs create mode 100644 DH.UI.Model.Winform/Element/ElementBase.cs create mode 100644 DH.UI.Model.Winform/Element/MLResultDisplay.cs create mode 100644 DH.UI.Model.Winform/GridCtrl.Designer.cs create mode 100644 DH.UI.Model.Winform/GridCtrl.cs create mode 100644 DH.UI.Model.Winform/GridCtrl.resx create mode 100644 DH.UI.Model.Winform/GridCtrlHost.cs create mode 100644 DH.UI.Model.Winform/IOIndicatorCtrl.Designer.cs create mode 100644 DH.UI.Model.Winform/IOIndicatorCtrl.cs create mode 100644 DH.UI.Model.Winform/IOIndicatorCtrl.resx create mode 100644 DHSoftware/Views/CtrlVisionDisplay.Designer.cs create mode 100644 DHSoftware/Views/CtrlVisionDisplay.cs create mode 100644 DHSoftware/Views/CtrlVisionDisplay.resx create mode 100644 DHSoftware/Views/CtrlVisionRunBase.Designer.cs create mode 100644 DHSoftware/Views/CtrlVisionRunBase.cs create mode 100644 DHSoftware/Views/CtrlVisionRunBase.resx diff --git a/DH.Commons.Devies/Base/VisionEngineBase.cs b/DH.Commons.Devies/Base/VisionEngineBase.cs new file mode 100644 index 0000000..28f5718 --- /dev/null +++ b/DH.Commons.Devies/Base/VisionEngineBase.cs @@ -0,0 +1,186 @@ +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; +using DH.Commons.Enums; +using HalconDotNet; +using OpenCvSharp; + + + +namespace DH.Devices.Devices +{ + /// + /// 视觉处理引擎:1.传统视觉 2.深度学习 + /// CV深度学习 四大领域 + /// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗; + /// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体; + /// Object Detection 目标检测:寻找图像中的物体并进行定位; + /// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体; + /// + public abstract class VisionEngineBase + { + public List DetectionConfigs = new List(); + #region event + public event Action> OnCropParamsOutput; + public event Action> OnDetectionDone; + public event Action OnDetectionWarningStop;//有无检测 需要报警停机 + #endregion + //public VisionEngineInitialConfigBase IConfig + //{ + // get => InitialConfig as VisionEngineInitialConfigBase; + //} + // public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper(); + public string BatchNO { get; set; } + + public HTuple hv_ModelID; + + public abstract DetectStationResult RunInference(Mat originImgSet, string detectionId = null); + + //public abstract void SaveDetectResultAsync(DetectStationResult detectResult); + + + + public virtual void DetectionDone(string detectionId, Bitmap image, List detectionResults) + { + OnDetectionDone?.Invoke(detectionId, image, detectionResults); + } + + public virtual void DetectionWarningStop(string detectionDes) + { + OnDetectionWarningStop?.Invoke(detectionDes); + } + + public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat) + { + if (saveMap != null) + { + //ImageSaveSet imageSaveSet = new ImageSaveSet() + //{ + // FullName = fullname, + // SaveImage = saveMap.CopyBitmap(), + // ImageFormat = imageFormat.DeepSerializeClone() + //}; + + //ImageSaveHelper.ImageSaveAsync(imageSaveSet); + } + } + } + public class CamModuleXY + { + [Category("图片行")] + [DisplayName("行")] + [Description("行")] + // [TypeConverter(typeof(DeviceIdSelectorConverter))] + //[TypeConverter(typeof(CollectionCountConvert))] + public int PicRows { get; set; } = 1; + + [Category("图片列")] + [DisplayName("列")] + [Description("列")] + // [TypeConverter(typeof(DeviceIdSelectorConverter))] + //[TypeConverter(typeof(CollectionCountConvert))] + public int PicCols { get; set; } = 1; + + public string GetDisplayText() + { + return "行:" + PicRows.ToString() + "列:" + PicCols.ToString(); + } + } + + //public class RelatedCamera + //{ + + // [Category("关联相机")] + // [DisplayName("关联相机")] + // [Description("关联相机描述")] + // //[TypeConverter(typeof(DeviceIdSelectorConverter))] + // //[TypeConverter(typeof(CollectionCountConvert))] + // public string CameraSourceId { get; set; } = ""; + + + // //public string GetDisplayText() + // //{ + // // using (var scope = GlobalVar.Container.BeginLifetimeScope()) + // // { + // // List deviceList = scope.Resolve>(); + // // IDevice CameraDevice = deviceList.FirstOrDefault(dev => dev.Id.Equals(CameraSourceId)); + + // // if (CameraDevice != null && CameraDevice is CameraBase) + // // { + // // return CameraDevice.Name; + // // } + + // // } + // // return CameraSourceId; + // //} + //} + public class VisionEngineInitialConfigBase //: InitialConfigBase + { + [Category("深度学习检测配置")] + [DisplayName("检测配置集合")] + [Description("检测配置集合")] + //[TypeConverter(typeof(CollectionCountConvert))] + //[Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + public List DetectionConfigs { get; set; } = new List(); + + [Category("深度学习检测配置")] + [DisplayName("标签分类")] + [Description("标签分类,A_NG,B_TBD...")] + // [TypeConverter(typeof(CollectionCountConvert))] + // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + public List RecongnitionLabelCategoryList { get; set; } = new List(); + + [Category("深度学习检测配置")] + [DisplayName("检测标签定义集合")] + [Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")] + // [TypeConverter(typeof(CollectionCountConvert))] + // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + public List RecongnitionLabelList { get; set; } = new List(); + + [Category("深度学习检测配置")] + [DisplayName("标签置信度")] + [Description("标签置信度,过滤小于改置信度的标签,大于该设置的标签才能识别")] + public float Score { get; set; } = 0.5f; + + [Category("深度学习检测配置")] + [DisplayName("CPU线程数量")] + [Description("用于深度学习的CPU线程数量,不要设置太大,会单独占用线程,影响其他程序运行")] + public int CPUNums { get; set; } = 1; + + //[Category("深度学习检测配置")] + //[DisplayName("检测项GPU指定")] + //[Description("将检测项指定到GPU")] + // [TypeConverter(typeof(CollectionCountConvert))] + // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] + // public List DetectionGPUList { get; set; } = new List(); + + // [Category("数据保存配置")] + //[DisplayName("是否保存检测明细CSV")] + //[Description("是否保存 检测明细CSV")] + //public override bool IsEnableCSV { get; set; } = true; + + //[Category("数据保存配置")] + //[DisplayName("是否保存检测图片")] + //[Description("是否保存 检测图片,总开关")] + //public bool IsSaveImage { get; set; } = true; + + //[Category("数据保存配置")] + //[Description("检测图片 保存文件夹")] + //[DisplayName("检测图片保存文件夹")] + //[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))] + //public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\X017\\Images"; + + //[Category("数据保存配置")] + //[Description("检测明细CSV文件夹")] + //[DisplayName("检测明细CSV文件夹")] + //[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))] + //public string CSVDataPath { get; set; } = "D:\\PROJECTS\\X017\\Images"; + + } +} + + + + + diff --git a/DH.Commons.Devies/DH.Commons.Devies.csproj b/DH.Commons.Devies/DH.Commons.Devies.csproj index 37c8091..7f403cc 100644 --- a/DH.Commons.Devies/DH.Commons.Devies.csproj +++ b/DH.Commons.Devies/DH.Commons.Devies.csproj @@ -1,11 +1,14 @@ - + - net8.0 + net8.0-windows enable enable - AnyCPU;X64 - True + ..\ + output + true + true + AnyCPU;x64 @@ -19,6 +22,10 @@ + + + + ..\x64\Debug\halcondotnet.dll diff --git a/DH.Commons/DH.Commons.csproj b/DH.Commons/DH.Commons.csproj index 1920bc2..fc78210 100644 --- a/DH.Commons/DH.Commons.csproj +++ b/DH.Commons/DH.Commons.csproj @@ -1,17 +1,19 @@ - + - net8.0 + net8.0-windows enable enable - AnyCPU;X64 - True + ..\ + output + true + true + AnyCPU;x64 - - - + + diff --git a/DH.Devices.Vision/DetectionConfig.cs b/DH.Commons/DetectionConfig.cs similarity index 67% rename from DH.Devices.Vision/DetectionConfig.cs rename to DH.Commons/DetectionConfig.cs index 90afdb6..e62cd14 100644 --- a/DH.Devices.Vision/DetectionConfig.cs +++ b/DH.Commons/DetectionConfig.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using System.Text; using System.Drawing.Design; -namespace DH.Devices.Vision +namespace DH.Commons.Enums { public enum MLModelType { @@ -25,7 +25,9 @@ namespace DH.Devices.Vision } public class ModelLabel { +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelId { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 [Category("模型标签")] @@ -37,7 +39,9 @@ namespace DH.Devices.Vision [Category("模型标签")] [DisplayName("模型标签")] [Description("模型识别的标签名称")] +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelName { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 @@ -57,7 +61,9 @@ namespace DH.Devices.Vision public class MLRequest { public int ImageChannels = 3; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public Mat mImage; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public int ResizeWidth; public int ResizeHeight; @@ -68,11 +74,17 @@ namespace DH.Devices.Vision //public int ImageResizeCount; public bool IsCLDetection; public int ProCount; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string in_node_name; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string out_node_name; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string in_lable_path; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public int ResizeImageSize; public int segmentWidth; @@ -81,7 +93,9 @@ namespace DH.Devices.Vision // public List OkClassTxtList; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List LabelNames; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 @@ -113,16 +127,22 @@ namespace DH.Devices.Vision /// public class DetectionResultDetail { +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelBGR { get; set; }//识别到对象的标签BGR +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public int LabelNo { get; set; } // 识别到对象的标签索引 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelName { get; set; }//识别到对象的标签名称 +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public double Score { get; set; }//识别目标结果的可能性、得分 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelDisplay { get; set; }//识别到对象的 显示信息 +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public double Area { get; set; }//识别目标的区域面积 @@ -141,8 +161,12 @@ namespace DH.Devices.Vision public class MLResult { public bool IsSuccess = false; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string ResultMessage; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public Bitmap ResultMap; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List ResultDetails = new List(); } public class MLInit @@ -164,7 +188,11 @@ namespace DH.Devices.Vision public bool IsGPU; public int GPUId; public float Score_thre; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre) +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 { ModelFile = modelFile; IsGPU = isGPU; @@ -186,20 +214,27 @@ namespace DH.Devices.Vision } public class DetectStationResult { +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string Pid { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string TempPid { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 /// /// 检测工位名称 /// +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string DetectName { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 /// /// 深度学习 检测结果 /// public List DetectDetails = new List(); + public List DetectionResultShapes = new List(); /// @@ -237,7 +272,9 @@ namespace DH.Devices.Vision public int StationDetectElapsed { get; set; } public static string NormalizeAndClean(string input) { +#pragma warning disable CS8603 // 可能返回 null 引用。 if (input == null) return null; +#pragma warning restore CS8603 // 可能返回 null 引用。 // Step 1: 标准化字符编码为 Form C (规范组合) string normalizedString = input.Normalize(NormalizationForm.FormC); @@ -274,6 +311,184 @@ namespace DH.Devices.Vision CameraSourceId = cameraSourceId; } + } + public class CustomizedPoint : INotifyPropertyChanged, IComparable + { + private double x = 0; + [Category("坐标设置")] + [Description("X坐标")] + public double X + { + get => x; + set + { + if (value != x) + { + x = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("X")); + } + } + } + + private double y = 0; + [Category("坐标设置")] + [Description("Y坐标")] + public double Y + { + get => y; + set + { + if (value != y) + { + y = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Y")); + } + } + } + + public CustomizedPoint() { } + + public CustomizedPoint(double x, double y) + { + X = x; + Y = y; + } + + //public CustomizedPoint(Point p) + //{ + // X = p.X; + // Y = p.Y; + //} + + public CustomizedPoint(PointF p) + { + X = p.X; + Y = p.Y; + } + + public CustomizedPoint(CustomizedPoint p) + { + X = p.X; + Y = p.Y; + } + + /// + /// 根据PLC的读取数值获取点位坐标 + /// + /// 0:X低位 1:X高位 2:Y低位 3:Y高位 + //public CustomizedPoint(List plcValues) + //{ + // if (plcValues == null || plcValues.Count != 4) + // return; + + // var list = plcValues.ParseUnsignShortListToInt(); + + // X = list[0]; + // Y = list[1]; + //} + + public event PropertyChangedEventHandler PropertyChanged; + + public static List GetPoints(List Xs, List Ys) + { + List points = new List(); + for (int i = 0; i < Xs.Count && i < Ys.Count; i++) + { + points.Add(new CustomizedPoint(Xs[i], Ys[i])); + } + + return points; + } + + public static double GetDistance(CustomizedPoint p1, CustomizedPoint p2) + { + return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2)); + } + + public override string ToString() + { + return GetDisplayText(); + } + + public virtual string GetDisplayText() + { + return string.Format("X:{0};Y:{1}", X, Y); + } + + public virtual string GetCSVHead() + { + return "X,Y"; + } + + public virtual string GetCSVData() + { + return X.ToString("f3") + ";" + Y.ToString("f3"); + } + + //public static double GetCustomizedPointDistance(CustomizedPoint startPoint, CustomizedPoint endPoint) + //{ + // return Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2)); + //} + + public CustomizedPoint OffsetClone(CustomizedPoint point) + { + return new CustomizedPoint(X + point.X, Y + point.Y); + } + + public void Offset(CustomizedPoint point) + { + X += point.X; + Y += point.Y; + } + + public int CompareTo(CustomizedPoint other) + { + return (X == other.X && Y == other.Y) ? 0 : 1; + } + + public override int GetHashCode() + { + //return (int)(X * 10 + Y); + return (new Tuple(X, Y)).GetHashCode(); + } + + public static CustomizedPoint operator -(CustomizedPoint p1, CustomizedPoint p2) + { + return new CustomizedPoint(p1.X - p2.X, p1.Y - p2.Y); + } + + public static CustomizedPoint operator +(CustomizedPoint p1, CustomizedPoint p2) + { + return new CustomizedPoint(p1.X + p2.X, p1.Y + p2.Y); + } + } + public class PreTreatParam + { + + /// + /// 参数名称 + /// + /// + [Category("预处理参数")] + [DisplayName("参数名称")] + [Description("参数名称")] +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 + public string Name { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 + + + /// + /// 参数值 + /// + /// + [Category("预处理参数")] + [DisplayName("参数值")] + [Description("参数值")] +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 + public string Value { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 + + } public class DetectionConfig { @@ -403,9 +618,14 @@ namespace DH.Devices.Vision //[Category("深度学习配置")] //[DisplayName("检测配置标签")] //[Description("检测配置标签关联")] - - //public List DetectConfigLabelList { get; set; } = new List(); + //public List DetectConfigLabelList { get; set; } = new List(); + [Category("显示配置")] + [DisplayName("显示位置")] + [Description("检测信息显示位置。左上角为(1,1),向右向下为正方向")] + // [TypeConverter(typeof(ComplexObjectConvert))] + // [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] + public CustomizedPoint ShowLocation { get; set; } = new CustomizedPoint(); public DetectionConfig() { @@ -413,7 +633,7 @@ namespace DH.Devices.Vision } public DetectionConfig(string name, MLModelType modelType, string modelPath, bool isEnableGPU,string sCameraSourceId) - { + { ModelPath = modelPath ?? string.Empty; Name = name; ModelType = modelType; @@ -463,7 +683,9 @@ namespace DH.Devices.Vision [DisplayName("检测项标签")] [Description("检测标签Id")] //[TypeConverter(typeof(DetectionLabelConverter))] +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string LabelId { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 [Browsable(false)] //public string LabelName { get => GetLabelName(); } @@ -562,11 +784,13 @@ namespace DH.Devices.Vision [DisplayName("检测标签")] [Description("检测标签信息")] //[TypeConverter(typeof(DetectionLabelConverter))] + public string LabelId { get; set; } - // [Browsable(false)] + public string LabelName { get; set; } + [Category("过滤器基础信息")] [DisplayName("是否启用过滤器")] [Description("是否启用过滤器")] diff --git a/DH.Commons/Enums/SolidMotionCardEnum.cs b/DH.Commons/Enums/SolidMotionCardEnum.cs index c2387bc..6f424c1 100644 --- a/DH.Commons/Enums/SolidMotionCardEnum.cs +++ b/DH.Commons/Enums/SolidMotionCardEnum.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace XKRS.Common.Model.SolidMotionCard +namespace DH.Commons.Enums { diff --git a/DH.Commons/GlobalVar.cs b/DH.Commons/GlobalVar.cs index ce615fc..8cd5751 100644 --- a/DH.Commons/GlobalVar.cs +++ b/DH.Commons/GlobalVar.cs @@ -1,6 +1,6 @@  -namespace XKRS.Common.Model +namespace DH.Commons.Enums { public static class GlobalVar { diff --git a/DH.Commons/Helper/EnumHelper.cs b/DH.Commons/Helper/EnumHelper.cs new file mode 100644 index 0000000..32cc533 --- /dev/null +++ b/DH.Commons/Helper/EnumHelper.cs @@ -0,0 +1,771 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; + +namespace DH.Commons.Enums +{ + public static class EnumHelper + { + /// + /// 根据枚举的代码名称获取枚举列表信息 + /// + /// + /// + public static List GetEnumListByName(string enumName, string assemblyName = "Common.Model.Helper.EnumHelper+") + { + List list = new List(); + + string fullName = assemblyName + enumName; + + Type t = typeof(EnumHelper).Assembly.GetType(fullName); + + t.GetEnumNames().ToList().ForEach(e => + { + int value = Convert.ToInt32(Enum.Parse(t, e)); + string desc = ((Enum)Enum.Parse(t, e)).GetEnumDescription(); + var item = new { Value = value, Desc = desc, Code = e }; + list.Add(item); + }); + + return list; + } + + /// + /// 获取枚举的列表信息,一般供下拉列表使用 + /// + /// 枚举类型 + /// Desc:中文描述 Value:整形值 Code:枚举值 + public static List GetEnumListByType(Type enumType) + { + List list = new List(); + + enumType.GetEnumNames().ToList().ForEach(e => + { + int value = Convert.ToInt32(Enum.Parse(enumType, e)); + string desc = ((Enum)Enum.Parse(enumType, e)).GetEnumDescription(); + var item = new { Value = value, Desc = desc, Code = e }; + list.Add(item); + }); + + return list; + } + + /// + /// 获取具体某一枚举的中文描述 + /// + /// + /// + public static string GetEnumDescription(this Enum enumObj) + { + Type t = enumObj.GetType(); + FieldInfo f = t.GetField(enumObj.ToString()); + if (f == null) + { + return enumObj.ToString(); + } + DescriptionAttribute attr = f.GetCustomAttribute(); + if (attr != null) + { + return attr.Description; + } + else + { + return enumObj.ToString(); + } + } + + //public static System.Windows.Media.Color GetEnumSelectedMediaColor(this Enum enumObj) + //{ + // Type t = enumObj.GetType(); + // FieldInfo f = t.GetField(enumObj.ToString()); + + // ColorSelectAttribute attr = f.GetCustomAttribute(); + // if (attr != null) + // { + // var prop = typeof(System.Windows.Media.Colors).GetProperties().FirstOrDefault(p => p.Name == attr.SelectedColor); + // if (prop != null) + // { + // return (System.Windows.Media.Color)prop.GetValue(null); + // } + // } + // return System.Windows.Media.Colors.Transparent; + //} + + //public static System.Drawing.Color GetEnumSelectedColor(this Enum enumObj) + //{ + // Type t = enumObj.GetType(); + // FieldInfo f = t.GetField(enumObj.ToString()); + + // ColorSelectAttribute attr = f.GetCustomAttribute(); + // if (attr != null) + // { + // return System.Drawing.Color.FromName(attr.SelectedColor); + // } + // else + // { + // return System.Drawing.Color.Transparent; + // } + //} + + //public static System.Drawing.Color GetEnumSelectedFontColor(this Enum enumObj) + //{ + // Type t = enumObj.GetType(); + // FieldInfo f = t.GetField(enumObj.ToString()); + + // var attr = f.GetCustomAttribute(); + // if (attr != null) + // { + // return System.Drawing.Color.FromName(attr.SelectedColor); + // } + // else + // { + // return System.Drawing.Color.Transparent; + // } + //} + + //public static string GetEnumSelectedColorString(this Enum enumObj) + //{ + // Type t = enumObj.GetType(); + // FieldInfo f = t.GetField(enumObj.ToString()); + + // ColorSelectAttribute attr = f.GetCustomAttribute(); + // if (attr != null) + // { + // return attr.SelectedColor; + // } + // else + // { + // return "Transparent"; + // } + //} + + + /// + /// 当枚举牵涉到状态变换,检查现状态是否满足待转换的状态的前置状态要求 + /// + /// + /// + /// + //public static bool CheckPreStateValid(this Enum stateToBe, int currentState) + //{ + // Type t = stateToBe.GetType(); + // FieldInfo f = t.GetField(stateToBe.ToString()); + + // PreStateAttribute attr = f.GetCustomAttribute(); + // if (attr == null) + // { + // return true; + // } + // else + // { + // return attr.CheckPreStateValid(currentState); + // } + //} + + /// + /// 设备状态定义 + /// 未初始化和异常状态无前置状态要求 + /// 初始化操作前置状态必须是未初始化、关闭状态和异常状态 + /// 打开前置必须是初始化和暂停 + /// 关闭前置必须是打开和暂停和异常 + /// 暂停前置必须是打开 + /// + //public enum DeviceState + //{ + // TBD = -1, + + // [ColorSelect("Gray")] + // [FontColorSelect("Black")] + // [Description("未初始化")] + // DSUninit = 1, + + // [ColorSelect("Gold")] + // [FontColorSelect("White")] + // [PreState(1 + 2 + 4 + 8 + 32)] + // [Description("初始化")] + // DSInit = 2, + + // [ColorSelect("Lime")] + // [FontColorSelect("Black")] + // [PreState(2 + 4 + 16)] + // [Description("运行中")] + // DSOpen = 4, + + // [ColorSelect("Gray")] + // [FontColorSelect("White")] + // [PreState(1 + 4 + 8 + 16 + 32)] + // [Description("关闭")] + // DSClose = 8, + + // [ColorSelect("Gold")] + // [FontColorSelect("White")] + // [PreState(4 + 16)] + // [Description("暂停")] + // DSPause = 16, + + // [ColorSelect("Red")] + // [FontColorSelect("White")] + // [Description("异常")] + // DSExcept = 32 + //} + + ///// + ///// 工序状态 + ///// + //public enum RunState + //{ + // [ColorSelect("Gold")] + // [Description("空闲")] + // Idle = 1, + // [ColorSelect("Lime")] + // [Description("运行中")] + // Running = 2, + // [ColorSelect("Gray")] + // [Description("停止")] + // Stop = 3, + // [ColorSelect("Red")] + // [Description("宕机")] + // Down = 99, + //} + + [Flags] + public enum DeviceAttributeType + { + [Description("设备驱动")] + Device = 1, + + [Description("初始配置")] + InitialConfig = 2, + [Description("操作配置")] + OperationConfig = 4, + [Description("设备配置")] + DeviceConfig = 8, + [Description("输入配置")] + InputConfig = 16, + + [Description("初始配置控件")] + InitialConfigCtrl = 32, + [Description("操作配置控件")] + OperationConfigCtrl = 64, + [Description("设备配置控件")] + DeviceConfigCtrl = 128, + [Description("输入配置控件")] + InputConfigCtrl = 256, + + [Description("运行控件")] + RunCtrl = 512, + + [Description("操作配置面板")] + OperationConfigPanel = 1024, + } + + public enum EnableState + { + [Description("启用")] + Enabled = 0, + [Description("禁用")] + Disabled = 1, + } + + public enum EnableStateFilter + { + [Description("全部")] + All = -1, + [Description("启用")] + Enabled = 0, + [Description("禁用")] + Disabled = 1, + } + + public enum OutputResult + { + [Description("OK")] + OK = 1, + [Description("NG")] + NG = 2, + } + + /// + /// PLC项目的值的类型 + /// + public enum PLCItemType + { + [Description("布尔类型")] + Bool = 0, + [Description("整型")] + Integer = 1, + [Description("字符串型")] + String = 2, + } + + /// + /// 对PLC项目的操作类型 + /// + public enum PLCOpType + { + [Description("读取")] + Read = 1, + [Description("写入")] + Write = 2, + [Description("监控")] + Monitor = 4, + + /// + /// 报警监控 1+8 + /// + [Description("报警监控")] + WarningMonitor = 9, + + /// + /// CT监控 1+16 + /// + [Description("CT监控")] + CTMonitor = 17, + } + + /// + /// 相机运行模式 + /// + public enum CameraOpMode + { + [Description("单次拍照")] + SingleSnapShot = 1, + [Description("连续模式")] + ContinuousMode = 2, + } + + /// + /// 日志类型 + /// + public enum LogType + { + [Description("警告信息")] + Exception_Warning = 1, + [Description("错误信息")] + Exception_Error = 2, + [Description("致命信息")] + Exception_Fatal = 3, + + [Description("设备信息")] + Info_Device = 11, + [Description("工序信息")] + Info_Process = 12, + [Description("操作信息")] + Info_Operation = 13, + + [Description("用户操作信息")] + User_Operation = 21, + + [Description("测量结果")] + MeasureResult = 31, + } + + //public enum CameraDriverType + //{ + // Halcon, + // //HalconPlugIn, + // Hik, + //} + + //public enum ImageType + //{ + // Bmp, + // Png, + // Jpeg, + //} + + //public enum ReplyValue + //{ + // OK = 1, + // NG = -1, + // IGNORE = -999, + //} + + public enum PriorityDirection + { + X, + Y, + } + + public enum ElementState + { + New = 1, + MouseHover = 2, + MouseInSide = 3, + Selected = 4, + Moving = 5, + Editing = 6, + + Normal = 11, + + Measuring = 21, + MeasureDoneOK = 22, + MeasureDoneNG = 23, + + CanStretchLeft = 41, + CanStretchRight = 42, + CanStretchTop = 43, + CanStretchBottom = 44, + + CanStretchLeftUpperCorner = 45, + CanStretchLeftLowerCorner = 46, + CanStretchRightUpperCorner = 47, + CanStretchRightLowerCorner = 48, + + StretchingLeft = 31, + StretchingRight = 32, + StretchingTop = 33, + StretchingBottom = 34, + + StretchingLeftUpperCorner = 35, + StretchingLeftLowerCorner = 36, + StretchingRightUpperCorner = 37, + StretchingRightLowerCorner = 38, + } + + public enum MouseState + { + Normal = 1, + HoverElement = 2, + InSideElement = 3, + + MoveElement = 4, + + StretchingLeft = 11, + StretchingRight = 12, + StretchingTop = 13, + StretchingBottom = 14, + + StretchingLeftUpperCorner = 15, + StretchingLeftLowerCorner = 16, + StretchingRightUpperCorner = 17, + StretchingRightLowerCorner = 18, + + New = 21, + Editing = 22, + //SelectedElement = 23, + + MovingAll = 31, + + SelectionZone = 41, + SelectionZoneDoing = 42, + } + + public enum RunMode + { + [Description("正常运行模式")] + NormalMode = 1, + [Description("调试模式")] + DebugMode = 0, + [Description("模拟模式")] + DemoMode = 2, + } + + public enum MoveType + { + [Description("绝对运动")] + AbsoluteMove = 1, + [Description("机器人坐标系相对运动")] + RobotRelativeMove = 2, + [Description("相对某个基准点位的相对运动")] + BasedPointRelativeMove = 3, + [Description("回原点")] + Origin = 4, + [Description("左侧姿势")] + LeftPose = 6, + [Description("右侧姿势")] + RightPose = 5, + [Description("前侧姿势")] + FrontPose = 7, + [Description("相机坐标系相对运动")] + CameraRelativeMove = 12, + } + + /// + /// 马达/运动板卡运行模式 + /// + public enum MotionMode + { + /// + /// 普通点位运动 + /// + [Description("普通点位运动")] + P2P = 1, + + /// + /// 找正限位运动 + /// + [Description("找正限位运动")] + FindPositive = 4, + + /// + /// 离开正限位 + /// + [Description("离开正限位")] + LeavePositive = 5, + + /// + /// 找负限位运动 + /// + [Description("找负限位运动")] + FindNegative = 6, + + /// + /// 离开负限位 + /// + [Description("离开负限位")] + LeaveNegative = 7, + + /// + /// 找原点运动 + /// + [Description("回原点运动")] + GoHome = 8, + + /// + /// Jog模式 + /// + [Description("Jog模式")] + Jog = 9, + + ///// + ///// 读数头找原点方式 + ///// + //[Description("找原点inde")] + //FindOriIndex = 10, + + ///// + ///// 插补模式 + ///// + //[Description("插补模式")] + //Coordinate = 11 + } + + /// + /// IO预定义类型 主要针对输出 + /// + public enum IOPrestatement + { + [Description("自定义")] + Customized = 0, + + [Description("指示灯-黄")] + Light_Yellow = 1, + [Description("指示灯-绿")] + Light_Green = 2, + [Description("指示灯-红")] + Light_Red = 3, + [Description("蜂鸣器")] + Beep = 4, + [Description("照明灯")] + Light = 5, + + [Description("急停")] + EmergencyStop = 99, + } + + ///// + ///// GTS运动板卡控制返回控制码 + ///// + //public enum GTSRetCode + //{ + // [Description("指令执行成功")] + // GRCRunOK = 0, // 指令执行成功 + // [Description("指令执行错误")] + // GRCRunErr = 1, // 指令执行错误 + // [Description("icense不支持")] + // GRCNotSupport = 2, // icense不支持 + // [Description("指令参数错误")] + // GRCInvalidParam = 7, // 指令参数错误 + // [Description("主机和运动控制器通讯失败")] + // GRCCommErr = -1, // 主机和运动控制器通讯失败 + // [Description("打开控制器失败")] + // GRCOpenErr = -6, // 打开控制器失败 + // [Description("运动控制器没有响应")] + // GRCNotAck = -7 // 运动控制器没有响应 + //} + + /// + /// 运动板卡 IO 类型(IN OUT) + /// + public enum IOType + { + [Description("INPUT")] + INPUT = 0, + [Description("OUTPUT")] + OUTPUT = 1 + } + + public enum IOValue + { + [Description("关闭")] + FALSE = 0, + [Description("开启")] + TRUE = 1, + [Description("反转")] + REVERSE = 2, + } + + /// + /// PubSubCenter事件中心的消息类型 + /// + public enum PubSubCenterMessageType + { + /// + /// 运行界面更新产品下拉 + /// + [Description("更新产品下拉")] + UpdateProductionCodes, + + /// + /// 流程是否关闭 + /// + [Description("流程是否打开")] + IsProcessOpened, + + /// + /// 清除数据 + /// + [Description("清除数据")] + ClearData, + /// + /// 更新批次信息 + /// + [Description("更新批次信息")] + UpdateBatchNO, + /// + /// 请求批次信息 + /// + [Description("更新批次信息")] + RequestBatchNO, + + /// + /// 模型检测异常 + /// + [Description("模型检测异常")] + MLDetectException, + } + public enum SizeEnum + { + [Description("圆形测量")] + Circle = 1, + [Description("直线测量")] + Line = 2, + [Description("线线测量")] + LineLine = 3, + [Description("线圆测量")] + LineCircle = 4, + [Description("高度测量")] + Height = 5, + } + + public enum MachineState + { + Unknown = 0, + Ready = 1, + Running = 2, + Alarm = 3, + Pause = 4, + Resetting = 5, + Closing = 6, + ClearProduct = 7, + Warning = 8, + } + + public enum ResultState + { + [Description("NA")] + NA = -5, + [Description("尺寸NG")] + SizeNG = -4, + [Description("检测NG")] + DetectNG = -3, + + //[Description("检测不足TBD")] + // ShortageTBD = -2, + [Description("检测结果TBD")] + ResultTBD = -1, + [Description("OK")] + OK = 1, + // [Description("NG")] + // NG = 2, + //统计结果 + [Description("A类NG")] + A_NG = 25, + [Description("B类NG")] + B_NG = 26, + [Description("C类NG")] + C_NG = 27, + } + public enum HikCameraType + { + [Description("HikCamera-Gige")] + Gige = 0, + [Description("HikCamera-USB")] + USB = 1 + } + + /// + /// 光源操作 + /// + public enum LightOperation + { + [Description("打开")] + Open = 1, + [Description("关闭")] + Close = 2, + [Description("写入")] + Write = 3, + [Description("读取")] + Read = 4, + [Description("频闪")] + Flash = 5, + } + + /// + /// 监听反馈数据值 + /// + public enum ReturnValue + { + OKVALUE = 1, + NGVALUE = -1, + EXCEPTIONVALUE = -2, + UNAUTHORIZATION = -10, + IGNORE = -999, + } + + //public enum LogLevel + //{ + // [Description("详细")] + // [ColorSelect("White")] + // [FontColorSelect("Green")] + // Detail = 2, + // [Description("信息")] + // [ColorSelect("White")] + // [FontColorSelect("Dark")] + // Information = 3, + // [Description("辅助")] + // [ColorSelect("White")] + // [FontColorSelect("Blue")] + // Assist = 4, + // [Description("动作")] + // [ColorSelect("DarkGreen")] + // [FontColorSelect("Yellow")] + // Action = 5, + // [Description("错误")] + // [ColorSelect("Orange")] + // [FontColorSelect("White")] + // Error = 6, + // [Description("警报")] + // [ColorSelect("Brown")] + // [FontColorSelect("White")] + // Warning = 7, + // [Description("异常")] + // [ColorSelect("Red")] + // [FontColorSelect("White")] + // Exception = 8, + //} + } +} diff --git a/DH.Commons/Helper/HDevEngineTool.cs b/DH.Commons/Helper/HDevEngineTool.cs index bd6f51e..bfe77f2 100644 --- a/DH.Commons/Helper/HDevEngineTool.cs +++ b/DH.Commons/Helper/HDevEngineTool.cs @@ -5,7 +5,7 @@ using System.Drawing.Imaging; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; -namespace XKRS.Common.Model +namespace DH.Commons.Enums { public class HDevEngineTool : IDisposable { diff --git a/DH.Commons/Helper/OpenCVEngineTool.cs b/DH.Commons/Helper/OpenCVEngineTool.cs index 86e5aff..5226ecf 100644 --- a/DH.Commons/Helper/OpenCVEngineTool.cs +++ b/DH.Commons/Helper/OpenCVEngineTool.cs @@ -9,7 +9,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; -namespace XKRS.Common.Model +namespace DH.Commons.Enums { public class OpenCVEngineTool : IDisposable { diff --git a/DH.Commons/Helper/UIHelper.cs b/DH.Commons/Helper/UIHelper.cs new file mode 100644 index 0000000..2ab9f8d --- /dev/null +++ b/DH.Commons/Helper/UIHelper.cs @@ -0,0 +1,123 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DH.Commons.Enums +{ + public static class UIHelper + { + public static void SetCombo(ComboBox cbo, object dataSource, string display, string value) + { + cbo.DataSource = dataSource; + cbo.DisplayMember = display; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ValueMember = value; + } + } + + public static void SetCombo(ToolStripComboBox cbo, object dataSource, string display, string value) + { + cbo.ComboBox.DataSource = dataSource; + cbo.ComboBox.DisplayMember = display; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ComboBox.ValueMember = value; + } + } + + public static void SetCombo(DataGridViewComboBoxColumn cbo, object dataSource, string display, string value) + { + cbo.DataSource = dataSource; + cbo.DisplayMember = display; + if (!string.IsNullOrWhiteSpace(value)) + { + cbo.ValueMember = value; + } + } + } + + #region DataGridView设置列头为复选框 + public class DataGridViewCheckboxHeaderEventArgs : EventArgs + { + private bool checkedState = false; + + public bool CheckedState + { + get { return checkedState; } + set { checkedState = value; } + } + } + + public delegate void DataGridViewCheckboxHeaderEventHander(object sender, DataGridViewCheckboxHeaderEventArgs e); + public class DataGridViewCheckboxHeaderCell : DataGridViewColumnHeaderCell + { + Point checkBoxLocation; + Size checkBoxSize; + bool _checked = false; + Point _cellLocation = new Point(); + System.Windows.Forms.VisualStyles.CheckBoxState _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal; + + public event DataGridViewCheckboxHeaderEventHander OnCheckBoxClicked; + +        //绘制列头checkbox +        protected override void Paint(System.Drawing.Graphics graphics, + System.Drawing.Rectangle clipBounds, + System.Drawing.Rectangle cellBounds, + int rowIndex, + DataGridViewElementStates dataGridViewElementState, + object value, + object formattedValue, + string errorText, + DataGridViewCellStyle cellStyle, + DataGridViewAdvancedBorderStyle advancedBorderStyle, + DataGridViewPaintParts paintParts) + { + base.Paint(graphics, clipBounds, cellBounds, rowIndex, + dataGridViewElementState, value, + formattedValue, errorText, cellStyle, + advancedBorderStyle, paintParts); + + Point p = new Point(); + Size s = CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal); + p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2) - 1;   //列头checkbox的X坐标 +            p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (s.Height / 2);     //列头checkbox的Y坐标 +            _cellLocation = cellBounds.Location; + checkBoxLocation = p; + checkBoxSize = s; + if (_checked) + _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal; + else + _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal; + + CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState); + } + +        /// +        /// 点击列头checkbox单击事件 +        /// +        protected override void OnMouseClick(DataGridViewCellMouseEventArgs e) + { + Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y); + if (p.X >= checkBoxLocation.X && p.X <= checkBoxLocation.X + checkBoxSize.Width + && p.Y >= checkBoxLocation.Y && p.Y <= checkBoxLocation.Y + checkBoxSize.Height) + { + _checked = !_checked; + +                //获取列头checkbox的选择状态 +                DataGridViewCheckboxHeaderEventArgs ex = new DataGridViewCheckboxHeaderEventArgs(); + ex.CheckedState = _checked; + + object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。因为列头checkbox是绘制出来的,无法获得它的实例 + +                if (OnCheckBoxClicked != null) + { + OnCheckBoxClicked(sender, ex);//触发单击事件 +                    DataGridView.InvalidateCell(this); + } + } + base.OnMouseClick(e); + } + } + #endregion +} diff --git a/DH.Commons/Interface/IShapeElement.cs b/DH.Commons/Interface/IShapeElement.cs new file mode 100644 index 0000000..3d39fa1 --- /dev/null +++ b/DH.Commons/Interface/IShapeElement.cs @@ -0,0 +1,39 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using static DH.Commons.Enums.EnumHelper; + + +namespace DH.Commons.Enums +{ + public interface IShapeElement : INotifyPropertyChanged, ICloneable + { + string ID { get; set; } + + int Index { get; set; } + int GroupIndex { get; set; } + + string Name { get; set; } + + void OnMouseDown(PointF point); + void OnMouseUp(PointF point); + void OnMouseMove(PointF point); + void OnMouseDoubleClick(PointF point); + bool IsIntersect(RectangleF rect); + + bool IsEnabled { get; set; } + void Draw(Graphics g); + + void Translate(float x, float y); + + /// + /// WPF中标识该对象是否已经加入渲染,需要显示 + /// + bool IsShowing { get; set; } + + void Initial(); + bool IsCreatedDone(); + + ElementState State { get; set; } + } +} diff --git a/DH.Devices.Vision/DH.Devices.Vision.csproj b/DH.Devices.Vision/DH.Devices.Vision.csproj index 6ca65e5..5c3baff 100644 --- a/DH.Devices.Vision/DH.Devices.Vision.csproj +++ b/DH.Devices.Vision/DH.Devices.Vision.csproj @@ -1,15 +1,15 @@ - + - - net8.0-windows - enable - enable - ..\ - output - true - true - AnyCPU;x64 - + + net8.0-windows + enable + enable + ..\ + output + true + true + AnyCPU;x64 + @@ -22,4 +22,24 @@ + + + + + + + + + + + + + + + + + ..\x64\Debug\halcondotnet.dll + + + diff --git a/DH.Devices.Vision/GlobalSuppressions.cs b/DH.Devices.Vision/GlobalSuppressions.cs new file mode 100644 index 0000000..8b2c949 --- /dev/null +++ b/DH.Devices.Vision/GlobalSuppressions.cs @@ -0,0 +1,10 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")] +[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboInstanceSegmentation.Load(DH.Devices.Vision.MLInit)~System.Boolean")] +[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboObjectDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")] diff --git a/DH.Devices.Vision/SimboDetection.cs b/DH.Devices.Vision/SimboDetection.cs index d579cf8..7ef52ac 100644 --- a/DH.Devices.Vision/SimboDetection.cs +++ b/DH.Devices.Vision/SimboDetection.cs @@ -1,4 +1,4 @@ -#define USE_MULTI_THREAD +//#define USE_MULTI_THREAD using OpenCvSharp; using OpenCvSharp.Extensions; @@ -13,6 +13,7 @@ using System.Threading.Tasks; using System.Security.Cryptography.Xml; using System.Runtime.InteropServices; using Newtonsoft.Json; +using DH.Commons.Enums; @@ -103,14 +104,18 @@ namespace DH.Devices.Vision // json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}"; // Console.WriteLine("检测结果JSON:" + json); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 HYoloResult detResult = JsonConvert.DeserializeObject(json); +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 if (detResult == null) { return; } int iNum = detResult.HYolo.Count; +#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值 int IokNum = 0; +#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值 for (int ix = 0; ix < iNum; ix++) { var det = detResult.HYolo[ix]; @@ -140,6 +145,7 @@ namespace DH.Devices.Vision Mat originMat = new Mat(); Mat detectMat = new Mat(); +#pragma warning disable CS0168 // 声明了变量,但从未使用过 try { if (req.mImage == null) @@ -228,15 +234,20 @@ namespace DH.Devices.Vision { originMat?.Dispose(); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 originMat = null; +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 //maskMat?.Dispose(); // maskMat = null; detectMat?.Dispose(); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 detectMat = null; +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 // maskWeighted?.Dispose(); // maskWeighted = null; // GC.Collect(); } +#pragma warning restore CS0168 // 声明了变量,但从未使用过 } diff --git a/DH.Devices.Vision/SimboInstanceSegmentation.cs b/DH.Devices.Vision/SimboInstanceSegmentation.cs index f0a751d..7f7936c 100644 --- a/DH.Devices.Vision/SimboInstanceSegmentation.cs +++ b/DH.Devices.Vision/SimboInstanceSegmentation.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using System.Runtime.InteropServices; using Newtonsoft.Json; +using DH.Commons.Enums; namespace DH.Devices.Vision @@ -126,14 +127,18 @@ namespace DH.Devices.Vision // json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}"; // Console.WriteLine("检测结果JSON:" + json); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 SegResult detResult = JsonConvert.DeserializeObject(json); +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 if (detResult == null) { return; } int iNum = detResult.SegmentResult.Count; +#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值 int IokNum = 0; +#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值 for (int ix = 0; ix < iNum; ix++) { var det = detResult.SegmentResult[ix]; @@ -166,6 +171,7 @@ namespace DH.Devices.Vision Mat originMat = new Mat(); Mat detectMat = new Mat(); +#pragma warning disable CS0168 // 声明了变量,但从未使用过 try { if (req.mImage == null) @@ -253,11 +259,14 @@ namespace DH.Devices.Vision { originMat?.Dispose(); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 originMat = null; +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 // GC.Collect(); } +#pragma warning restore CS0168 // 声明了变量,但从未使用过 } } diff --git a/DH.Devices.Vision/SimboObjectDetection.cs b/DH.Devices.Vision/SimboObjectDetection.cs index 6e60836..3ad0d60 100644 --- a/DH.Devices.Vision/SimboObjectDetection.cs +++ b/DH.Devices.Vision/SimboObjectDetection.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using System.Runtime.InteropServices; using Newtonsoft.Json; using System.Xml; +using DH.Commons.Enums; namespace DH.Devices.Vision @@ -135,7 +136,9 @@ namespace DH.Devices.Vision // json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}"; // Console.WriteLine("检测结果JSON:" + json); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 SegResult detResult = JsonConvert.DeserializeObject(json); +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 if (detResult == null) { return; @@ -173,6 +176,7 @@ namespace DH.Devices.Vision MLResult mlResult = new MLResult(); Mat originMat=new Mat() ; Mat detectMat= new Mat(); +#pragma warning disable CS0168 // 声明了变量,但从未使用过 try { if (req.mImage == null) @@ -263,19 +267,24 @@ namespace DH.Devices.Vision if (detectMat != null) { detectMat.Dispose(); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 detectMat = null; +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 } if (originMat != null) { originMat.Dispose(); +#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 originMat = null; +#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。 } // GC.Collect(); } +#pragma warning restore CS0168 // 声明了变量,但从未使用过 } diff --git a/DH.Devices.Vision/SimboVisionDriver.cs b/DH.Devices.Vision/SimboVisionDriver.cs index 378cecf..7d22468 100644 --- a/DH.Devices.Vision/SimboVisionDriver.cs +++ b/DH.Devices.Vision/SimboVisionDriver.cs @@ -1,4 +1,9 @@ -using OpenCvSharp; +using DH.Commons.Enums; +using DH.Devices.Devices; +using DH.UI.Model.Winform; +using HalconDotNet; +using OpenCvSharp; +using OpenCvSharp.Extensions; using System; using System.Collections.Generic; using System.Diagnostics; @@ -6,13 +11,659 @@ using System.Linq; using System.Runtime.ExceptionServices; using System.Text; using System.Threading.Tasks; +using System.Windows.Forms; using System.Xml.Linq; +using XKRS.UI.Model.Winform; +using static DH.Commons.Enums.EnumHelper; +using ResultState = DH.Commons.Enums.ResultState; + namespace DH.Devices.Vision { - public class SimboVisionDriver + public class SimboVisionDriver : VisionEngineBase { - + public Dictionary HalconToolDict = new Dictionary(); + + public List SimboStationMLEngineList = new List(); + + public void Init() + { + //InitialQueue(); + InitialHalconTools(); + InitialSimboMLEnginesAsync(); + + // ImageSaveHelper.OnImageSaveExceptionRaised -= ImageSaveHelper_OnImageSaveExceptionRaised; + // ImageSaveHelper.OnImageSaveExceptionRaised += ImageSaveHelper_OnImageSaveExceptionRaised; + // base.Init(); + } + + //private void ImageSaveHelper_OnImageSaveExceptionRaised(DateTime dt, string msg) + //{ + // LogAsync(new LogMsg(dt, LogLevel.Error, msg)); + //} + public override DetectStationResult RunInference(Mat originImgSet, string detectionId = null) + { + DetectStationResult detectResult = new DetectStationResult(); + DetectionConfig detectConfig = null; + //找到对应的配置 + if (!string.IsNullOrWhiteSpace(detectionId)) + { + detectConfig = DetectionConfigs.FirstOrDefault(u => u.Id == detectionId); + } + else + { + //detectConfig = DetectionConfigs.FirstOrDefault(u => u.CameraSourceId == camera.CameraName); + } + + if (detectConfig == null) + { + + //未能获得检测配置 + return detectResult; + } + #region 1.预处理 + + using (Mat PreTMat = originImgSet.Clone()) + { + PreTreated(detectConfig, detectResult, PreTMat); + } + + + + #endregion + if (detectResult.IsPreTreatNG) + { + detectResult.ResultState = ResultState.DetectNG; + detectResult.IsPreTreatDone = true; + detectResult.IsMLDetectDone = false; + return detectResult; + + } + + + + if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath) && detectConfig.IsEnabled) + { + + + SimboStationMLEngineSet mlSet = null; + mlSet = SimboStationMLEngineList.FirstOrDefault(t => t.DetectionId == detectConfig.Id); + if (mlSet == null) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:{detectConfig.Name}未能获取对应配置的模型检测工具"); + detectResult.IsMLDetectDone = false; + + //HandleDetectDone(detectResult, detectConfig); + return detectResult; + } + + #region 2.深度学习推理 + //LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行"); + + if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath)) + { + Stopwatch mlWatch = new Stopwatch(); + var req = new MLRequest(); + //之前的检测图片都是相机存储成HImage + + + req.ResizeWidth = (int)detectConfig.ModelWidth; + req.ResizeHeight = (int)detectConfig.ModelHeight; + // req.LabelNames = detectConfig.GetLabelNames(); + // req.Score = IIConfig.Score; + req.mImage = originImgSet.Clone(); + + req.in_lable_path = detectConfig.in_lable_path; + + req.confThreshold = detectConfig.ModelconfThreshold; + req.iouThreshold = 0.3f; + req.segmentWidth = 320; + req.out_node_name = "output0"; + switch (detectConfig.ModelType) + { + case MLModelType.ImageClassification: + break; + case MLModelType.ObjectDetection: + + break; + case MLModelType.SemanticSegmentation: + break; + case MLModelType.InstanceSegmentation: + break; + case MLModelType.ObjectGPUDetection: + + break; + default: + break; + } + + // LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN"); + mlWatch.Start(); + //20230802改成多线程推理 RunInferenceFixed + + var result = mlSet.StationMLEngine.RunInference(req); + // var result = mlSet.StationMLEngine.RunInferenceFixed(req); + mlWatch.Stop(); + // LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference END"); + + + + + + + // var req = new MLRequest(); + + //req.mImage = inferenceImage; + + //req.ResizeWidth = detectConfig.ModelWidth; + //req.ResizeHeight = detectConfig.ModelHeight; + //req.confThreshold = detectConfig.ModelconfThreshold; + //req.iouThreshold = 0.3f; + //req.out_node_name = "output0"; + //req.in_lable_path = detectConfig.in_lable_path; + + //Stopwatch sw = Stopwatch.StartNew(); + //var result = Dectection[detectionId].RunInference(req); + //sw.Stop(); + //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); + + //this.BeginInvoke(new MethodInvoker(delegate () + //{ + // // pictureBox1.Image?.Dispose(); // 释放旧图像 + // // pictureBox1.Image = result.ResultMap; + // richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess}相机名字{camera.CameraName} 耗时 {mlWatch.ElapsedMilliseconds}ms\n"); + //})); + //req.mImage?.Dispose(); + + + + + if (result == null || (result != null && !result.IsSuccess)) + { + detectResult.IsMLDetectDone = false; + } + if (result != null && result.IsSuccess) + { + detectResult.DetectDetails = result.ResultDetails; + if (detectResult.DetectDetails != null) + { + } + else + { + detectResult.IsMLDetectDone = false; + } + } + } + #endregion + + + + #region 3.后处理 + #endregion + //根据那些得分大于阈值的推理结果,判断产品是否成功 + #region 4.最终过滤(逻辑过滤) + detectResult.DetectDetails?.ForEach(d => + { + + + //当前检测项的 过滤条件 + //var conditionList = detectConfig.DetectionFilterList + // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) + // .GroupBy(u => u.ResultState) + // .OrderBy(u => u.Key) + // .ToList(); + //当前检测项的 过滤条件 + var conditionList = detectConfig.DetectionFilterList + .Where(u => u.IsEnabled && u.LabelName == d.LabelName) + .GroupBy(u => u.ResultState) + .OrderBy(u => u.Key) + .ToList(); + + if (conditionList.Count == 0) + { + + d.FinalResult = d.LabelName.ToLower() == "ok" + ? ResultState.OK + : ResultState.DetectNG; + } + else + { + d.FinalResult = detectConfig.IsMixModel + ? ResultState.A_NG + : ResultState.OK; + + + } + + + foreach (IGrouping group in conditionList) + { + //bool b = group.ToList().Any(f => + //{ + // return f.FilterOperation(d); + //}); + + + //if (b) + //{ + // d.FinalResult = group.Key; + // break; + //} + + if (group.Any(f => f.FilterOperation(d))) + { + d.FinalResult = group.Key; + break; + } + //else + //{ + // d.FinalResult = d.InferenceResult = ResultState.OK; + //} + } + }); + #endregion + #region 5.统计缺陷过滤结果或预处理直接NG + //if (detectResult.DetectDetails?.Count > 0) + //{ + // detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult; + // detectResult.ResultLabel = detectResult.ResultLabel; + // detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 + + + //} + detectResult.ResultState = detectResult.DetectDetails? + .GroupBy(u => u.FinalResult) + .OrderBy(u => u.Key) + .FirstOrDefault()?.Key ?? ResultState.OK; + detectResult.ResultLabel = detectResult.ResultLabel; + detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 + #endregion + + + + + + DisplayDetectionResult(detectResult, originImgSet.Clone(), detectionId); + + + + + } + return detectResult; + + } + /// + /// 初始化深度学习工具 + /// + private bool InitialSimboMLEnginesAsync() + { + //深度学习 模型加载 + var resultOK = MLLoadModel(); + return resultOK; + } + /// + /// 深度学习 模型加载 + /// + /// + private bool MLLoadModel() + { + bool resultOK = false; + try + { + // SimboStationMLEngineList = new List(); + // _cameraRelatedDetectionDict = IConfig.DetectionConfigs.Select(t => t.ModelPath).Distinct().ToList(); + DetectionConfigs.ForEach(dc => + //_cameraRelatedDetectionDict.ForEach(dc => + { + + if (dc.IsEnabled && !string.IsNullOrWhiteSpace(dc.ModelPath)) + { + if (dc.IsEnableGPU) + { + //if (IIConfig.IsLockGPU) + //{ + //foreach (var validGPU in ValidGPUList2) + //{ + // if (validGPU.DetectionIds.Contains(dc.Id)) + // { + var engine = SingleMLLoadModel(dc, true, 0); + SimboStationMLEngineList.Add(engine); + // } + //} + //} + //else + //{ + // foreach (var validGPU in ValidGPUList) + // { + // //var validGPU = ValidGPUList.FirstOrDefault(u => u.DetectionIds.Contains(dc.Id)); + // if (validGPU.DetectionId == dc.Id) + // { + // var engine = SingleMLLoadModel(dc, true, validGPU.GPUNo); + // SimboStationMLEngineList.Add(engine); + // } + // } + //} + + } + else + { + //for (int i = 0; i < IConfig.CPUNums; i++) + for (int i = 0; i < 1; i++) + { + //var engine = SingleMLLoadModel(dc, false, i); + var engine = SingleMLLoadModel(dc, false, i); + SimboStationMLEngineList.Add(engine); + } + } + } + }); + resultOK = true; + } + catch (Exception ex) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:模型并发加载异常:{ex.GetExceptionMessage()}"); + resultOK = false; + } + + return resultOK; + } + /// + /// 单个模型加载 + /// + /// + /// + /// + private SimboStationMLEngineSet SingleMLLoadModel(DetectionConfig dc, bool isGPU, int coreInx) + { + SimboStationMLEngineSet mLEngineSet = new SimboStationMLEngineSet(); + try + { + mLEngineSet.IsUseGPU = isGPU; + if (isGPU) + { + mLEngineSet.GPUNo = coreInx; + } + else + { + mLEngineSet.CPUNo = coreInx; + } + mLEngineSet.DetectionId = dc.Id; + mLEngineSet.DetectionName = dc.Name; + + if (!string.IsNullOrWhiteSpace(dc.ModelPath)) + { + // 根据算法类型创建不同的实例 + switch (dc.ModelType) + { + case MLModelType.ImageClassification: + break; + case MLModelType.ObjectDetection: + mLEngineSet.StationMLEngine = new SimboObjectDetection(); + break; + case MLModelType.SemanticSegmentation: + + break; + case MLModelType.InstanceSegmentation: + mLEngineSet.StationMLEngine = new SimboInstanceSegmentation(); + break; + case MLModelType.ObjectGPUDetection: + mLEngineSet.StationMLEngine = new SimboDetection(); + break; + default: + break; + } + MLInit mLInit; + string inferenceDevice = "CPU"; + if (dc.IsEnableGPU) + { + inferenceDevice = "GPU"; + mLInit = new MLInit(dc.ModelPath, isGPU, coreInx, dc.ModelconfThreshold); + } + else + { + mLInit = new MLInit(dc.ModelPath, "images", inferenceDevice, (int)dc.ModelWidth, (int)dc.ModelHeight); + + } + + bool isSuccess = mLEngineSet.StationMLEngine.Load(mLInit); + if (!isSuccess) + { + // throw new ProcessException("异常:模型加载异常", null); + } + //LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}"); + } + } + catch (Exception ex) + { + //throw new ProcessException($"异常:是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}"); + } + return mLEngineSet; + } + private void InitialHalconTools() + { + HOperatorSet.SetSystem("parallelize_operators", "true"); + HOperatorSet.SetSystem("reentrant", "true"); + HOperatorSet.SetSystem("global_mem_cache", "exclusive"); + + HalconToolDict = new Dictionary(); + + DetectionConfigs.ForEach(c => + { + if (!c.IsEnabled) + return; + + if (c.HalconAlgorithemPath_Pre != null) + LoadHalconTool(c.HalconAlgorithemPath_Pre); + + }); + } + + private void LoadHalconTool(string path) + { + if (!HalconToolDict.ContainsKey(path)) + { + + + string algorithemPath = path; + + if (string.IsNullOrWhiteSpace(algorithemPath)) + return; + + string directoryPath = Path.GetDirectoryName(algorithemPath); + string fileName = Path.GetFileNameWithoutExtension(algorithemPath); + + HDevEngineTool tool = new HDevEngineTool(directoryPath); + tool.LoadProcedure(fileName); + + HalconToolDict[path] = tool; + } + } + + /// + /// 预处理 + /// + /// + /// + public void PreTreated(DetectionConfig detectConfig, DetectStationResult detectResult, Mat MhImage) + { + try + { + // detectResult.VisionImageSet.DetectionOriginImage = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); + //detectResult.VisionImageSet.PreTreatedBitmap = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); + //detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.PreTreatedBitmap?.CopyBitmap(); + if (!string.IsNullOrWhiteSpace(detectConfig.HalconAlgorithemPath_Pre)) + { + HObject obj = OpenCVHelper.MatToHImage(MhImage); + HImage hImage = HalconHelper.ConvertHObjectToHImage(obj); + string toolKey = detectConfig.HalconAlgorithemPath_Pre; + if (!HalconToolDict.ContainsKey(toolKey)) + { + // LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}未获取预处理算法"); + return; + } + //Mean_Thre Deviation_Thre Mean_standard Deviation_standard + var tool = HalconToolDict[toolKey]; + + ////tool.InputTupleDic["Mean_Thre"] = 123; + for (int i = 0; i < detectConfig.PreTreatParams.Count; i++) + { + var param = detectConfig.PreTreatParams[i]; + tool.InputTupleDic[param.Name] = double.Parse(param.Value); + } + + // tool.InputTupleDic["fCricularity"] = 200; + + tool.InputImageDic["INPUT_Image"] = hImage; + + + if (!tool.RunProcedure(out string errorMsg, out _)) + { + // detectResult.PreTreatedFlag = false; + + detectResult.IsPreTreatDone = false; + + + return; + } + + var preTreatRet = tool.GetResultTuple("OUTPUT_Flag").I; + + //var fRCricularity = tool.GetResultTuple("fRCricularity"); + + + // detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = preTreatRet == 1; + //detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true; + // detectResult.VisionImageSet.PreTreatedTime = DateTime.Now; + + for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++) + { + var param = detectConfig.OUTPreTreatParams[i]; + tool.InputTupleDic[param.Name] = double.Parse(param.Value); + } + + + + + // 2023/10/16 新增预处理结果反馈,如果预处理结果为NG,直接返回 + if (preTreatRet != 0) + { + detectResult.ResultState = ResultState.DetectNG; + + detectResult.IsPreTreatNG = true; + + + + // if (detectResult.VisionImageSet.PreTreatedFlag) + { + //detectResult.VisionImageSet.MLImage = tool.GetResultObject("OUTPUT_PreTreatedImage"); + //DetectionResultImage + // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); + + } + + } + else + { + // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); + + } + } + } + catch (Exception ex) + { + + } + finally + { + //detectResult.VisionImageSet.HImage?.Dispose(); + //detectResult.VisionImageSet.HImage = null; + // MhImage?.Dispose(); + //MhImage = null; + } + + } + + /// + /// 显示检测结果 + /// + /// + private void DisplayDetectionResult(DetectStationResult detectResult,Mat result,string DetectionId) + { + //结果显示上传 + Task.Run(() => + { + try + { + + + string displayTxt = detectResult.ResultState.ToString() + "\r\n"; + if (detectResult.DetectDetails != null && detectResult.DetectDetails?.Count > 0) + { + detectResult.DetectDetails.ForEach(d => + { + displayTxt += + $"{d.LabelName} score:{d.Score.ToString("f2")} area:{d.Area.ToString("f2")}\r\n"; + }); + } + + //if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0) + //{ + // detectResult.realSpecs.ForEach(d => + // { + // displayTxt += + // $"{d.Code} :{d.ActualValue} \r\n"; + // }); + //} + Bitmap resultMask=result.ToBitmap(); + //if (detectResult.VisionImageSet.DetectionResultImage == null && detectResult.VisionImageSet.SizeResultImage == null) + //{ + // return; + //} + //else if (detectResult.VisionImageSet.DetectionResultImage == null && detectResult.VisionImageSet.SizeResultImage != null) + //{ + // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.SizeResultImage.CopyBitmap(); + // resultMask = detectResult.VisionImageSet.DetectionResultImage.CopyBitmap(); + //} + //else if (detectResult.VisionImageSet.DetectionResultImage != null && detectResult.VisionImageSet.SizeResultImage != null) + //{ + // Mat img1 = ConvertBitmapToMat(detectResult.VisionImageSet.SizeResultImage.CopyBitmap()); // 第一张图片,已经带框 + // Mat img2 = ConvertBitmapToMat(detectResult.VisionImageSet.DetectionResultImage.CopyBitmap()); // 第二张图片,已经带框 + + // // 合成两张图像:可以选择叠加或拼接 + // Mat resultImg = new Mat(); + // Cv2.AddWeighted(img1, 0.5, img2, 0.5, 0, resultImg); // 使用加权平均法合成图像 + + // resultMask = resultImg.ToBitmap(); + //} + //else + //{ + // resultMask = detectResult.VisionImageSet.DetectionResultImage.CopyBitmap(); + //} + + List detectionResultShapes = + new List(detectResult.DetectionResultShapes); + + DetectResultDisplay resultDisplay = new DetectResultDisplay(detectResult, resultMask, displayTxt); + detectionResultShapes.Add(resultDisplay); + List detectionResultShapesClone = new List(detectionResultShapes); + + DetectionDone(DetectionId, resultMask, detectionResultShapes); + + //SaveDetectResultImageAsync(detectResult); + // SaveDetectResultCSVAsync(detectResult); + } + catch (Exception ex) + { + // LogAsync(DateTime.Now, LogLevel.Exception, + // $"{Name}显示{detectResult.DetectName}检测结果异常,{ex.GetExceptionMessage()}"); + } + finally + { + + + } + }); + } } } diff --git a/DH.Devices.Vision/SimboVisionMLBase.cs b/DH.Devices.Vision/SimboVisionMLBase.cs index 485093e..9d8482a 100644 --- a/DH.Devices.Vision/SimboVisionMLBase.cs +++ b/DH.Devices.Vision/SimboVisionMLBase.cs @@ -1,4 +1,5 @@  +using DH.Commons.Enums; using OpenCvSharp; using System; using System.Collections.Generic; @@ -28,7 +29,7 @@ namespace DH.Devices.Vision MLGPUEngine.FreePredictor(Model); } catch (Exception e) { } - // MLEngine.FreePredictor(Model); + // MLEngine.FreePredictor(Model); } public void Dispose2() { @@ -41,7 +42,7 @@ namespace DH.Devices.Vision } public SimboVisionMLBase() { - // ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道 + ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道 // ColorLut = new Mat(1, 256, MatType.CV_8UC3, ColorMap); } } @@ -55,16 +56,22 @@ namespace DH.Devices.Vision // "rect": [421, 823, 6, 8] // }] //} +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List HYolo; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public class Result { public double fScore; public int classId; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string classname; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 //public double area; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List rect; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 } @@ -72,45 +79,28 @@ namespace DH.Devices.Vision } public class SegResult { +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List SegmentResult; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public class Result { public double fScore; public int classId; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string classname; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public double area; +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public List rect; +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 } } - public class PreTreatParam - { - - /// - /// 参数名称 - /// - /// - [Category("预处理参数")] - [DisplayName("参数名称")] - [Description("参数名称")] - public string Name { get; set; } - - - /// - /// 参数值 - /// - /// - [Category("预处理参数")] - [DisplayName("参数值")] - [Description("参数值")] - public string Value { get; set; } - - - } + public static class MLGPUEngine { diff --git a/DH.Devices.Vision/SimboVisionModel.cs b/DH.Devices.Vision/SimboVisionModel.cs index b07f3e6..9427f3e 100644 --- a/DH.Devices.Vision/SimboVisionModel.cs +++ b/DH.Devices.Vision/SimboVisionModel.cs @@ -22,14 +22,20 @@ namespace DH.Devices.Vision /// /// 检测配置ID /// +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string DetectionId { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public string DetectionName { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 /// /// 深度学习模型 /// +#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 public SimboVisionMLBase StationMLEngine { get; set; } +#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 } } diff --git a/DH.UI.Model.Winform/Canvas.Designer.cs b/DH.UI.Model.Winform/Canvas.Designer.cs new file mode 100644 index 0000000..d5d2379 --- /dev/null +++ b/DH.UI.Model.Winform/Canvas.Designer.cs @@ -0,0 +1,599 @@ +namespace DH.UI.Model.Winform +{ + partial class Canvas + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Canvas)); + this.ctmsElements = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tsmiResort = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiInitialState = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiClearStandardValue = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiClearActualValue = new System.Windows.Forms.ToolStripMenuItem(); + this.ctmsKeepElements = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tsmiUnselectElements = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiKeepSelected = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiKeepUnselected = new System.Windows.Forms.ToolStripMenuItem(); + this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel(); + this.scMain = new System.Windows.Forms.SplitContainer(); + this.tsROIs = new System.Windows.Forms.ToolStrip(); + this.tsTool = new System.Windows.Forms.ToolStrip(); + this.tsBtnLoadImage = new System.Windows.Forms.ToolStripButton(); + this.tsBtnSaveImage = new System.Windows.Forms.ToolStripButton(); + this.tsBtnSaveImageWithElements = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.tsBtnMapSize = new System.Windows.Forms.ToolStripButton(); + this.tsBtnScreenSize = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.tsBtnModeNormal = new System.Windows.Forms.ToolStripButton(); + this.tsBtnModeSelection = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.chkShowChecked = new System.Windows.Forms.CheckBox(); + this.dgElements = new System.Windows.Forms.DataGridView(); + this.colEnableState = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colIndex = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.propGridElement = new System.Windows.Forms.PropertyGrid(); + this.miniToolStrip = new System.Windows.Forms.ToolStrip(); + this.stsStatus = new System.Windows.Forms.StatusStrip(); + this.tsslLocation = new System.Windows.Forms.ToolStripStatusLabel(); + this.tsslMouseState = new System.Windows.Forms.ToolStripStatusLabel(); + this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ctmsElements.SuspendLayout(); + this.ctmsKeepElements.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.scMain)).BeginInit(); + this.scMain.Panel1.SuspendLayout(); + this.scMain.Panel2.SuspendLayout(); + this.scMain.SuspendLayout(); + this.tsTool.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dgElements)).BeginInit(); + this.stsStatus.SuspendLayout(); + this.SuspendLayout(); + // + // ctmsElements + // + this.ctmsElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiResort, + this.tsmiInitialState, + this.tsmiClearStandardValue, + this.tsmiClearActualValue}); + this.ctmsElements.Name = "ctmsElements"; + this.ctmsElements.Size = new System.Drawing.Size(137, 92); + // + // tsmiResort + // + this.tsmiResort.Name = "tsmiResort"; + this.tsmiResort.Size = new System.Drawing.Size(136, 22); + this.tsmiResort.Text = "重新排序"; + this.tsmiResort.Click += new System.EventHandler(this.tsmiResort_Click); + // + // tsmiInitialState + // + this.tsmiInitialState.Name = "tsmiInitialState"; + this.tsmiInitialState.Size = new System.Drawing.Size(136, 22); + this.tsmiInitialState.Text = "初始化"; + this.tsmiInitialState.Click += new System.EventHandler(this.tsmiInitialState_Click); + // + // tsmiClearStandardValue + // + this.tsmiClearStandardValue.Name = "tsmiClearStandardValue"; + this.tsmiClearStandardValue.Size = new System.Drawing.Size(136, 22); + this.tsmiClearStandardValue.Text = "清空标准值"; + this.tsmiClearStandardValue.Click += new System.EventHandler(this.tsmiClearStandardValue_Click); + // + // tsmiClearActualValue + // + this.tsmiClearActualValue.Name = "tsmiClearActualValue"; + this.tsmiClearActualValue.Size = new System.Drawing.Size(136, 22); + this.tsmiClearActualValue.Text = "清空测量值"; + this.tsmiClearActualValue.Click += new System.EventHandler(this.tsmiClearActualValue_Click); + // + // ctmsKeepElements + // + this.ctmsKeepElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiUnselectElements, + this.tsmiKeepSelected, + this.tsmiKeepUnselected}); + this.ctmsKeepElements.Name = "ctmsKeepElements"; + this.ctmsKeepElements.Size = new System.Drawing.Size(173, 70); + // + // tsmiUnselectElements + // + this.tsmiUnselectElements.Name = "tsmiUnselectElements"; + this.tsmiUnselectElements.Size = new System.Drawing.Size(172, 22); + this.tsmiUnselectElements.Text = "取消全部基元选择"; + this.tsmiUnselectElements.Click += new System.EventHandler(this.tsmiUnselectElements_Click); + // + // tsmiKeepSelected + // + this.tsmiKeepSelected.Name = "tsmiKeepSelected"; + this.tsmiKeepSelected.Size = new System.Drawing.Size(172, 22); + this.tsmiKeepSelected.Text = "保留选中的基元"; + this.tsmiKeepSelected.Click += new System.EventHandler(this.tsmiKeepSelected_Click); + // + // tsmiKeepUnselected + // + this.tsmiKeepUnselected.Name = "tsmiKeepUnselected"; + this.tsmiKeepUnselected.Size = new System.Drawing.Size(172, 22); + this.tsmiKeepUnselected.Text = "保留未选中的基元"; + this.tsmiKeepUnselected.Click += new System.EventHandler(this.tsmiKeepUnselected_Click); + // + // BottomToolStripPanel + // + this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.BottomToolStripPanel.Name = "BottomToolStripPanel"; + this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // TopToolStripPanel + // + this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.TopToolStripPanel.Name = "TopToolStripPanel"; + this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // RightToolStripPanel + // + this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.RightToolStripPanel.Name = "RightToolStripPanel"; + this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // LeftToolStripPanel + // + this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.LeftToolStripPanel.Name = "LeftToolStripPanel"; + this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // ContentPanel + // + this.ContentPanel.Size = new System.Drawing.Size(610, 417); + // + // scMain + // + this.scMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.scMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.scMain.Location = new System.Drawing.Point(0, 0); + this.scMain.Name = "scMain"; + // + // scMain.Panel1 + // + this.scMain.Panel1.Controls.Add(this.tsROIs); + this.scMain.Panel1.Controls.Add(this.tsTool); + // + // scMain.Panel2 + // + this.scMain.Panel2.Controls.Add(this.splitContainer1); + this.scMain.Size = new System.Drawing.Size(635, 467); + this.scMain.SplitterDistance = 399; + this.scMain.TabIndex = 4; + // + // tsROIs + // + this.tsROIs.Location = new System.Drawing.Point(29, 0); + this.tsROIs.Name = "tsROIs"; + this.tsROIs.Size = new System.Drawing.Size(370, 25); + this.tsROIs.TabIndex = 2; + this.tsROIs.Text = "toolStrip1"; + this.tsROIs.Visible = false; + // + // tsTool + // + this.tsTool.Dock = System.Windows.Forms.DockStyle.Left; + this.tsTool.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.tsTool.ImageScalingSize = new System.Drawing.Size(24, 24); + this.tsTool.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsBtnLoadImage, + this.tsBtnSaveImage, + this.tsBtnSaveImageWithElements, + this.toolStripSeparator4, + this.tsBtnMapSize, + this.tsBtnScreenSize, + this.toolStripSeparator1, + this.tsBtnModeNormal, + this.tsBtnModeSelection, + this.toolStripSeparator2}); + this.tsTool.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow; + this.tsTool.Location = new System.Drawing.Point(0, 0); + this.tsTool.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.tsTool.Name = "tsTool"; + this.tsTool.Size = new System.Drawing.Size(29, 467); + this.tsTool.TabIndex = 1; + this.tsTool.Text = "toolStrip1"; + // + // tsBtnLoadImage + // + this.tsBtnLoadImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnLoadImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnLoadImage.Image"))); + this.tsBtnLoadImage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnLoadImage.Name = "tsBtnLoadImage"; + this.tsBtnLoadImage.Size = new System.Drawing.Size(26, 28); + this.tsBtnLoadImage.Text = "LoadImage"; + this.tsBtnLoadImage.ToolTipText = "Load Image"; + this.tsBtnLoadImage.Click += new System.EventHandler(this.tsBtnLoadImage_Click); + // + // tsBtnSaveImage + // + this.tsBtnSaveImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnSaveImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImage.Image"))); + this.tsBtnSaveImage.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnSaveImage.Name = "tsBtnSaveImage"; + this.tsBtnSaveImage.Size = new System.Drawing.Size(26, 28); + this.tsBtnSaveImage.Text = "SaveImage"; + this.tsBtnSaveImage.Click += new System.EventHandler(this.tsBtnSaveImage_Click); + // + // tsBtnSaveImageWithElements + // + this.tsBtnSaveImageWithElements.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnSaveImageWithElements.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImageWithElements.Image"))); + this.tsBtnSaveImageWithElements.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnSaveImageWithElements.Name = "tsBtnSaveImageWithElements"; + this.tsBtnSaveImageWithElements.Size = new System.Drawing.Size(26, 28); + this.tsBtnSaveImageWithElements.Text = "SaveImageWithElements"; + this.tsBtnSaveImageWithElements.Click += new System.EventHandler(this.tsBtnSaveImageWithElements_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(26, 6); + // + // tsBtnMapSize + // + this.tsBtnMapSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnMapSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnMapSize.Image"))); + this.tsBtnMapSize.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnMapSize.Name = "tsBtnMapSize"; + this.tsBtnMapSize.Size = new System.Drawing.Size(26, 28); + this.tsBtnMapSize.Text = "Original"; + this.tsBtnMapSize.ToolTipText = "Map Size"; + this.tsBtnMapSize.Click += new System.EventHandler(this.tsBtnMapSize_Click); + // + // tsBtnScreenSize + // + this.tsBtnScreenSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnScreenSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnScreenSize.Image"))); + this.tsBtnScreenSize.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnScreenSize.Name = "tsBtnScreenSize"; + this.tsBtnScreenSize.Size = new System.Drawing.Size(26, 28); + this.tsBtnScreenSize.Text = "toolStripButton2"; + this.tsBtnScreenSize.ToolTipText = "Screen Size"; + this.tsBtnScreenSize.Click += new System.EventHandler(this.tsBtnScreenSize_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(26, 6); + // + // tsBtnModeNormal + // + this.tsBtnModeNormal.CheckOnClick = true; + this.tsBtnModeNormal.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnModeNormal.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeNormal.Image"))); + this.tsBtnModeNormal.ImageTransparentColor = System.Drawing.SystemColors.Control; + this.tsBtnModeNormal.Name = "tsBtnModeNormal"; + this.tsBtnModeNormal.Size = new System.Drawing.Size(26, 28); + this.tsBtnModeNormal.Text = "Normal Mode"; + this.tsBtnModeNormal.ToolTipText = "Normal Mode"; + this.tsBtnModeNormal.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged); + // + // tsBtnModeSelection + // + this.tsBtnModeSelection.CheckOnClick = true; + this.tsBtnModeSelection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsBtnModeSelection.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeSelection.Image"))); + this.tsBtnModeSelection.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsBtnModeSelection.Name = "tsBtnModeSelection"; + this.tsBtnModeSelection.Size = new System.Drawing.Size(26, 28); + this.tsBtnModeSelection.Text = "Selection Mode"; + this.tsBtnModeSelection.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(26, 6); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.chkShowChecked); + this.splitContainer1.Panel1.Controls.Add(this.dgElements); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.propGridElement); + this.splitContainer1.Size = new System.Drawing.Size(232, 467); + this.splitContainer1.SplitterDistance = 215; + this.splitContainer1.TabIndex = 2; + // + // chkShowChecked + // + this.chkShowChecked.AutoSize = true; + this.chkShowChecked.Location = new System.Drawing.Point(14, 8); + this.chkShowChecked.Name = "chkShowChecked"; + this.chkShowChecked.Size = new System.Drawing.Size(110, 17); + this.chkShowChecked.TabIndex = 1; + this.chkShowChecked.Text = "仅显示选中项目"; + this.chkShowChecked.UseVisualStyleBackColor = true; + this.chkShowChecked.CheckedChanged += new System.EventHandler(this.chkShowChecked_CheckedChanged); + // + // dgElements + // + this.dgElements.AllowUserToAddRows = false; + this.dgElements.AllowUserToDeleteRows = false; + this.dgElements.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dgElements.BackgroundColor = System.Drawing.SystemColors.GradientInactiveCaption; + this.dgElements.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgElements.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colEnableState, + this.colId, + this.colIndex, + this.colName}); + this.dgElements.Location = new System.Drawing.Point(0, 30); + this.dgElements.MultiSelect = false; + this.dgElements.Name = "dgElements"; + this.dgElements.RowTemplate.Height = 23; + this.dgElements.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dgElements.Size = new System.Drawing.Size(232, 185); + this.dgElements.TabIndex = 0; + this.dgElements.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgElements_CellMouseDoubleClick); + this.dgElements.SelectionChanged += new System.EventHandler(this.dgElements_SelectionChanged); + // + // colEnableState + // + this.colEnableState.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colEnableState.DataPropertyName = "IsEnabled"; + this.colEnableState.FillWeight = 41.95804F; + this.colEnableState.HeaderText = ""; + this.colEnableState.MinimumWidth = 30; + this.colEnableState.Name = "colEnableState"; + this.colEnableState.Resizable = System.Windows.Forms.DataGridViewTriState.True; + // + // colId + // + this.colId.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colId.DataPropertyName = "ID"; + this.colId.HeaderText = "ID"; + this.colId.MinimumWidth = 30; + this.colId.Name = "colId"; + this.colId.ReadOnly = true; + this.colId.Visible = false; + // + // colIndex + // + this.colIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells; + this.colIndex.DataPropertyName = "Index"; + this.colIndex.HeaderText = "序号"; + this.colIndex.MinimumWidth = 40; + this.colIndex.Name = "colIndex"; + this.colIndex.ReadOnly = true; + this.colIndex.Width = 56; + // + // colName + // + this.colName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.colName.DataPropertyName = "Name"; + this.colName.FillWeight = 158.042F; + this.colName.HeaderText = "名称"; + this.colName.MinimumWidth = 60; + this.colName.Name = "colName"; + this.colName.ReadOnly = true; + // + // propGridElement + // + this.propGridElement.Dock = System.Windows.Forms.DockStyle.Fill; + this.propGridElement.LargeButtons = true; + this.propGridElement.LineColor = System.Drawing.SystemColors.ControlDark; + this.propGridElement.Location = new System.Drawing.Point(0, 0); + this.propGridElement.Margin = new System.Windows.Forms.Padding(3, 3, 3, 50); + this.propGridElement.Name = "propGridElement"; + this.propGridElement.Size = new System.Drawing.Size(232, 248); + this.propGridElement.TabIndex = 0; + this.propGridElement.ToolbarVisible = false; + this.propGridElement.SelectedObjectsChanged += new System.EventHandler(this.propGridElement_SelectedObjectsChanged); + // + // miniToolStrip + // + this.miniToolStrip.AccessibleName = "新项选择"; + this.miniToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonDropDown; + this.miniToolStrip.AutoSize = false; + this.miniToolStrip.CanOverflow = false; + this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None; + this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.miniToolStrip.ImageScalingSize = new System.Drawing.Size(24, 24); + this.miniToolStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow; + this.miniToolStrip.Location = new System.Drawing.Point(0, 235); + this.miniToolStrip.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.miniToolStrip.Name = "miniToolStrip"; + this.miniToolStrip.Size = new System.Drawing.Size(29, 237); + this.miniToolStrip.TabIndex = 1; + // + // stsStatus + // + this.stsStatus.BackColor = System.Drawing.Color.Transparent; + this.stsStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsslLocation, + this.tsslMouseState}); + this.stsStatus.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow; + this.stsStatus.Location = new System.Drawing.Point(0, 445); + this.stsStatus.Name = "stsStatus"; + this.stsStatus.Size = new System.Drawing.Size(635, 22); + this.stsStatus.TabIndex = 0; + this.stsStatus.Text = "statusStrip1"; + // + // tsslLocation + // + this.tsslLocation.Name = "tsslLocation"; + this.tsslLocation.Size = new System.Drawing.Size(24, 17); + this.tsslLocation.Text = " "; + // + // tsslMouseState + // + this.tsslMouseState.Name = "tsslMouseState"; + this.tsslMouseState.Size = new System.Drawing.Size(52, 17); + this.tsslMouseState.Text = " "; + // + // dataGridViewCheckBoxColumn1 + // + this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewCheckBoxColumn1.DataPropertyName = "IsEnabled"; + this.dataGridViewCheckBoxColumn1.FillWeight = 41.95804F; + this.dataGridViewCheckBoxColumn1.HeaderText = ""; + this.dataGridViewCheckBoxColumn1.MinimumWidth = 30; + this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1"; + this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True; + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.dataGridViewTextBoxColumn1.DataPropertyName = "Id"; + this.dataGridViewTextBoxColumn1.HeaderText = "ID"; + this.dataGridViewTextBoxColumn1.MinimumWidth = 30; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + this.dataGridViewTextBoxColumn1.Visible = false; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader; + this.dataGridViewTextBoxColumn2.DataPropertyName = "Index"; + this.dataGridViewTextBoxColumn2.HeaderText = "序号"; + this.dataGridViewTextBoxColumn2.MinimumWidth = 40; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader; + this.dataGridViewTextBoxColumn3.DataPropertyName = "Name"; + this.dataGridViewTextBoxColumn3.FillWeight = 158.042F; + this.dataGridViewTextBoxColumn3.HeaderText = "名称"; + this.dataGridViewTextBoxColumn3.MinimumWidth = 80; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + // + // Canvas + // + this.Controls.Add(this.stsStatus); + this.Controls.Add(this.scMain); + this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134))); + this.Name = "Canvas"; + this.Size = new System.Drawing.Size(635, 467); + this.ctmsElements.ResumeLayout(false); + this.ctmsKeepElements.ResumeLayout(false); + this.scMain.Panel1.ResumeLayout(false); + this.scMain.Panel1.PerformLayout(); + this.scMain.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.scMain)).EndInit(); + this.scMain.ResumeLayout(false); + this.tsTool.ResumeLayout(false); + this.tsTool.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.dgElements)).EndInit(); + this.stsStatus.ResumeLayout(false); + this.stsStatus.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.ContextMenuStrip ctmsElements; + private System.Windows.Forms.ToolStripMenuItem tsmiResort; + private System.Windows.Forms.ToolStripMenuItem tsmiInitialState; + private System.Windows.Forms.ToolStripMenuItem tsmiClearStandardValue; + private System.Windows.Forms.ToolStripMenuItem tsmiClearActualValue; + private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1; + private System.Windows.Forms.ContextMenuStrip ctmsKeepElements; + private System.Windows.Forms.ToolStripMenuItem tsmiKeepSelected; + private System.Windows.Forms.ToolStripMenuItem tsmiKeepUnselected; + private System.Windows.Forms.ToolStripMenuItem tsmiUnselectElements; + private System.Windows.Forms.ToolStripPanel BottomToolStripPanel; + private System.Windows.Forms.ToolStripPanel TopToolStripPanel; + private System.Windows.Forms.ToolStripPanel RightToolStripPanel; + private System.Windows.Forms.ToolStripPanel LeftToolStripPanel; + private System.Windows.Forms.ToolStripContentPanel ContentPanel; + private System.Windows.Forms.SplitContainer scMain; + private System.Windows.Forms.StatusStrip stsStatus; + private System.Windows.Forms.ToolStripStatusLabel tsslLocation; + private System.Windows.Forms.ToolStripStatusLabel tsslMouseState; + private System.Windows.Forms.ToolStrip tsTool; + private System.Windows.Forms.ToolStripButton tsBtnLoadImage; + private System.Windows.Forms.ToolStripButton tsBtnSaveImage; + private System.Windows.Forms.ToolStripButton tsBtnSaveImageWithElements; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripButton tsBtnMapSize; + private System.Windows.Forms.ToolStripButton tsBtnScreenSize; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton tsBtnModeNormal; + private System.Windows.Forms.ToolStripButton tsBtnModeSelection; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.CheckBox chkShowChecked; + private System.Windows.Forms.DataGridView dgElements; + private System.Windows.Forms.DataGridViewCheckBoxColumn colEnableState; + private System.Windows.Forms.DataGridViewTextBoxColumn colId; + private System.Windows.Forms.DataGridViewTextBoxColumn colIndex; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.PropertyGrid propGridElement; + private System.Windows.Forms.ToolStrip miniToolStrip; + private System.Windows.Forms.ToolStrip tsROIs; + } +} diff --git a/DH.UI.Model.Winform/Canvas.cs b/DH.UI.Model.Winform/Canvas.cs new file mode 100644 index 0000000..8c95fd2 --- /dev/null +++ b/DH.UI.Model.Winform/Canvas.cs @@ -0,0 +1,629 @@ + +using DH.Commons.Enums; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using static DH.Commons.Enums.EnumHelper; + + + +namespace DH.UI.Model.Winform +{ + public partial class Canvas : UserControl + { + readonly CanvasImage cvImage = new CanvasImage(); + + #region Grid + readonly GridCtrl gridCtrl = new GridCtrl(); + + private void GridValueChanged(int gridValue) + { + cvImage.GridValue = gridValue; + } + + private void ShowGridChanged(bool isShowGrid) + { + cvImage.ShowGrid = isShowGrid; + } + + private void GridColorChanged(Color obj) + { + cvImage.Pen_Grid.Color = obj; + } + #endregion + + public Canvas() + { + InitializeComponent(); + DoubleBuffered = true; + SetStyle(ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw | + ControlStyles.AllPaintingInWmPaint, true); + + cvImage.Dock = DockStyle.Fill; + scMain.Panel1.Controls.Add(cvImage); + + dgElements.AutoGenerateColumns = false; + + var checkHead = new DataGridViewCheckboxHeaderCell(); + checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked; + dgElements.Columns[0].HeaderCell = checkHead; + dgElements.Columns[0].HeaderCell.Value = string.Empty; + + Elements.CollectionChanged += Elements_CollectionChanged; + + cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated; + cvImage.OnMouseStateChanged += OnMouseStateChanged; + + gridCtrl.IsShowGridChanged = ShowGridChanged; + gridCtrl.GridValueChanged = GridValueChanged; + gridCtrl.GridColorChanged = GridColorChanged; + gridCtrl.Padding = new Padding(0, 5, 0, 5); + tsTool.Items.Add(new GridCtrlHost(gridCtrl)); + tsTool.Invalidate(); + + _eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1); + + //tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false; + } + + private void OnMouseStateChanged(MouseState ms) + { + if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing) + { + if (this.IsHandleCreated) + { + this.Invoke(new Action(() => + { + tsBtnModeSelection.Checked = false; + tsBtnModeNormal.Checked = true; + })); + } + } + } + + #region 底部状态栏 + public bool IsShowStatusBar + { + get => stsStatus.Visible; + set => stsStatus.Visible = value; + } + + private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc) + { + //await Task.Run(() => tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}"); + this.Invoke(new Action(() => + { + tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X.ToString("f2")},Y:{imagePoint.Y.ToString("f2")} 颜色:{colorDesc}"; + })); + } + + //private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc) + //{ + // if (InvokeRequired) + // { + // Invoke(new Action(MouseLocationUpdated), screenPoint, imagePoint); + // } + // else + // { + // tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}"; + // } + //} + #endregion + + #region 属性 + #region CanvasImage相关 + //private MouseState mouseState = MouseState.Normal; + //public MouseState MouseState + //{ + // get + // { + // return mouseState; + // } + // set + // { + // if (mouseState != value) + // { + // mouseState = value; + + // tsslMouseState.Text = mouseState.ToString(); + + // if (mouseState >= MouseState.SelectionZone) + // { + // tsBtnModeSelection.Checked = true; + // } + // else + // { + // tsBtnModeNormal.Checked = true; + // } + // } + // } + //} + + public string ImageFilePath { get; set; } + + public Bitmap MAP + { + get => cvImage.MAP; + set => cvImage.MAP = value; + } + public Matrix Matrix + { + get => cvImage.Matrix; + set => cvImage.Matrix = value; + } + public MouseState MouseState + { + get => cvImage.MouseState; + set => cvImage.MouseState = value; + } + public ObservableCollection Elements + { + get => cvImage.Elements; + } + #endregion + + private bool isShowElementList = false; + public bool IsShowElementList + { + get => isShowElementList; + set + { + //if (isShowElementList != value) + { + isShowElementList = value; + scMain.Panel2Collapsed = !value; + } + } + } + + private bool isShowROITool = false; + public bool IsShowROITool + { + get => isShowROITool; + set + { + tsROIs.Visible = isShowROITool = value; + } + } + #endregion + + #region 图片操作 + /// + /// 载入图片 + /// + /// + public void LoadImage(Bitmap map) + { + cvImage.LoadImage(map); + OnImageChanged?.Invoke(); + } + public void Clear() + { + cvImage.Clear(); + } + + /// + /// 设置图片为原始尺寸 + /// + public void SetMapSize() + { + cvImage.SetMapSize(); + } + + /// + /// 设置图片为适配尺寸 + /// + public void SetScreenSize() + { + cvImage.SetScreenSize(); + } + #endregion + + #region 基元列表 + private void chkShowChecked_CheckedChanged(object sender, EventArgs e) + { + dgElements.DataSource = null; + + if (Elements != null && Elements.Count > 0) + { + if (chkShowChecked.Checked) + { + dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList(); + } + else + { + dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList(); + } + } + } + + private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e) + { + //foreach (IShapeElement ele in Elements) + //{ + // ele.IsEnabled = e.CheckedState; + //} + for (int i = 0; i < Elements.Count; i++) + { + Elements[i].IsEnabled = e.CheckedState; + } + OnElementChanged(null); + } + + private void dgElements_SelectionChanged(object sender, EventArgs e) + { + if (dgElements.SelectedRows.Count > 0) + { + var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString()); + propGridElement.SelectedObject = ele; + } + } + + private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + if (dgElements.SelectedRows.Count > 0) + { + var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString()); + + for (int i = 0; i < Elements.Count; i++) + { + Elements[i].State = ElementState.Normal; + } + + ele.State = ElementState.Selected; + + SetDeviceByElement?.Invoke(ele); + + Invalidate(); + } + } + + System.Threading.Timer _eleCollectionChangedTimer = null; + + private void OnElementCollectionChangedBufferTimer(object state) + { + OnElementChanged(null); + for (int i = 0; i < Elements.Count; i++) + { + Elements[i].PropertyChanged -= Ele_PropertyChanged; + Elements[i].PropertyChanged += Ele_PropertyChanged; + } + //foreach (IShapeElement ele in Elements) + //{ + // ele.PropertyChanged -= Ele_PropertyChanged; + // ele.PropertyChanged += Ele_PropertyChanged; + //} + } + + private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + //_eleCollectionChangedTimer?.Change(200, -1); + OnElementChanged(null); + for (int i = 0; i < Elements.Count; i++) + { + Elements[i].PropertyChanged -= Ele_PropertyChanged; + Elements[i].PropertyChanged += Ele_PropertyChanged; + } + } + + private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "IsEnabled") + { + OnElementChanged(sender as IShapeElement); + } + else + { + Invoke(new Action(() => + { + cvImage.Invalidate(); + })); + } + } + + private void OnElementChanged(IShapeElement ele) + { + if (ele != null) + OnElementChangedHandle?.Invoke(ele); + + if (InvokeRequired) + { + Invoke(new Action(() => OnElementChanged(ele))); + } + else + { + if (isShowElementList) + { + dgElements.DataSource = null; + if (Elements != null && Elements.Count > 0) + { + if (chkShowChecked.Checked) + { + dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList(); + } + else + { + dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList(); + } + } + Invalidate(); + } + } + } + + private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e) + { + propGridElement.ExpandAllGridItems(); + } + + #region 基元列表右键菜单 + private void tsmiResort_Click(object sender, EventArgs e) + { + //Elements.Sort(); + } + + private void tsmiClearActualValue_Click(object sender, EventArgs e) + { + //foreach (IShapeElement ele in Elements) + //{ + // if (ele.IsEnabled) + // { + // ele.SetActualValue(0.0); + // } + //} + } + + private void tsmiInitialState_Click(object sender, EventArgs e) + { + //foreach (IShapeElement ele in Elements) + //{ + // if (ele.IsEnabled) + // { + // ele.State = ElementState.Normal; + // ele.InitialMeasureResult(); + // } + //} + } + + private void tsmiClearStandardValue_Click(object sender, EventArgs e) + { + //foreach (IShapeElement ele in Elements) + //{ + // if (ele.IsEnabled) + // { + // ele.SetStandardValue(0.0); + // } + //} + } + #endregion + #endregion + + #region 图像区域右键菜单 + private void tsmiKeepUnselected_Click(object sender, EventArgs e) + { + KeepElements(false); + } + + private void tsmiKeepSelected_Click(object sender, EventArgs e) + { + KeepElements(true); + } + + private void KeepElements(bool isKeepSelected) + { + for (int i = 0; i < Elements.Count; i++) + { + var ele = Elements[i]; + if (ele.IsEnabled) + { + if (ele.State == ElementState.Selected) + { + ele.IsEnabled = isKeepSelected; + } + else + { + ele.IsEnabled = !isKeepSelected; + } + } + } + } + + private void tsmiUnselectElements_Click(object sender, EventArgs e) + { + //if (MouseState == MouseState.SelectedElement) + //{ + // MouseState = MouseState.Normal; + + // //Elements.ForEach(ele => + // foreach (IShapeElement ele in Elements) + // { + // ele.State = ElementState.Normal; + // } + // //); + //} + } + #endregion + + #region 基元的设备属性 运动设置和相机设置 + public Action SetElementDevicePara; + + public Action SetDeviceByElement; + #endregion + + #region 一般操作工具条 + public bool IsShowToolBar + { + get => tsTool.Visible; + set => tsTool.Visible = value; + } + + private void tsBtnLoadImage_Click(object sender, EventArgs e) + { + Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage)); + InvokeThread.SetApartmentState(ApartmentState.STA); + InvokeThread.Start(); + InvokeThread.Join(); + } + + private void OpenLoadImage() + { + ImageFilePath = ""; + OpenFileDialog ofd = new OpenFileDialog(); + if (ofd.ShowDialog() == DialogResult.OK) + { + ImageFilePath = ofd.FileName; + LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath)); + } + } + + private void tsBtnSaveImage_Click(object sender, EventArgs e) + { + if (MAP == null) + return; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp"; + if (sfd.ShowDialog() == DialogResult.OK) + { + string filePath = sfd.FileName; + if (filePath.EndsWith("bmp")) + { + MAP.Save(filePath, ImageFormat.Bmp); + } + else + { + MAP.Save(filePath, ImageFormat.Jpeg); + } + MessageBox.Show("图片保存成功!"); + } + } + + private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e) + { + if (MAP == null) + return; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp"; + if (sfd.ShowDialog() == DialogResult.OK) + { + string filePath = sfd.FileName; + + Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb); + //Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat); + //Bitmap bmp = new Bitmap(MAP.Width, MAP.Height); + using (Graphics g = Graphics.FromImage(bmp)) + { + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + g.DrawImage(MAP, 0, 0); + + for (int i = 0; i < Elements.Count; i++) + { + var ele = Elements[i]; + if (ele.IsEnabled) + ele.Draw(g); + } + } + + if (filePath.EndsWith("bmp")) + { + bmp.Save(filePath, ImageFormat.Bmp); + } + else + { + bmp.Save(filePath, ImageFormat.Jpeg); + } + MessageBox.Show("带基元图片保存成功!"); + } + } + + private void tsBtnMapSize_Click(object sender, EventArgs e) + { + SetMapSize(); + } + + private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e) + { + var btn = sender as ToolStripButton; + if (btn.Checked) + { + btn.BackColor = SystemColors.ActiveCaption; + + foreach (ToolStripItem c in tsTool.Items) + { + if (c is ToolStripButton) + { + if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name) + { + var temp = c as ToolStripButton; + temp.Checked = false; + temp.BackColor = SystemColors.Control; + } + } + } + + switch (btn.Name) + { + case "tsBtnModeNormal": + MouseState = MouseState.Normal; + break; + case "tsBtnModeSelection": + MouseState = MouseState.SelectionZone; + break; + } + } + } + + private void tsBtnScreenSize_Click(object sender, EventArgs e) + { + SetScreenSize(); + } + #endregion + + #region 基元工具条 + //private void LoadElementTools() + //{ + // var eleDict = ElementFactory.GetAllElementsInfo(); + + // foreach (KeyValuePair pair in eleDict) + // { + + // } + //} + + public void SetNewROIType(IShapeElement element) + { + cvImage.DrawTemplate = element; + } + #endregion + + #region 事件 + public event Action OnElementChangedHandle; + public event Action OnImageChanged; + #endregion + + #region 工具栏显示/隐藏右键菜单 + private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e) + { + //IsShowToolBar = tsmiShowToolBar.Checked; + } + + private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e) + { + //IsShowStatusBar = tsmiShowStatusBar.Checked; + } + #endregion + } +} diff --git a/DH.UI.Model.Winform/Canvas.resx b/DH.UI.Model.Winform/Canvas.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/DH.UI.Model.Winform/Canvas.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/CanvasImage.Designer.cs b/DH.UI.Model.Winform/CanvasImage.Designer.cs new file mode 100644 index 0000000..1e2b61f --- /dev/null +++ b/DH.UI.Model.Winform/CanvasImage.Designer.cs @@ -0,0 +1,33 @@ +namespace DH.UI.Model.Winform +{ + partial class CanvasImage + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // CanvasImage + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.Name = "CanvasImage"; + this.Size = new System.Drawing.Size(575, 472); + this.ResumeLayout(false); + + } + + #endregion + } +} diff --git a/DH.UI.Model.Winform/CanvasImage.cs b/DH.UI.Model.Winform/CanvasImage.cs new file mode 100644 index 0000000..e25b9a7 --- /dev/null +++ b/DH.UI.Model.Winform/CanvasImage.cs @@ -0,0 +1,943 @@ + +using DH.Commons.Enums; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Linq; +using System.Threading; +using System.Windows.Forms; + +using static DH.Commons.Enums.EnumHelper; + + +namespace DH.UI.Model.Winform +{ + public partial class CanvasImage : UserControl + { + public CanvasImage() + { + InitializeComponent(); + + DoubleBuffered = true; + SetStyle(ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw | + ControlStyles.AllPaintingInWmPaint, true); + + MouseWheel += Canvas_MouseWheel; + KeyDown += OnCanvasKeyDown; + KeyPress += OnCanvasKeyPressed; + MouseDoubleClick += Canvas_MouseDoubleClick; + MouseDown += Canvas_MouseDown; + MouseMove += Canvas_MouseMove; + MouseUp += Canvas_MouseUp; + + // EventRouter.ChangeElementsMouseState -= OnElementChangeMouseState; + // EventRouter.ChangeElementsMouseState += OnElementChangeMouseState; + + //Elements.CollectionChanged += Elements_CollectionChanged; + } + + private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + //this.Invoke(new Action(() => + //{ + // this.Invalidate(); + //})); + } + + #region Event + public Action OnMouseStateChanged; + public Action DrawTemplateChanged = null; + public Action OnMouseLocationUpdated; + #endregion + + private MouseState mouseState = MouseState.Normal; + public MouseState MouseState + { + get + { + return mouseState; + } + set + { + if (mouseState != value) + { + mouseState = value; + + // OnMouseStateChanged?.BeginInvoke(value, null, null); + Task.Run(() => OnMouseStateChanged.Invoke(value)); + } + } + } + + #region 属性和字段 + + //private Bitmap map = new Bitmap(10, 10); + //public Bitmap MAP + //{ + // get + // { + // _mapLoadHandler.WaitOne(); + // return map; + // } + // set + // { + // map = value; + // } + //} + + public Bitmap MAP { get; set; } = new Bitmap(10, 10); + + public Matrix Matrix { get; set; } = new Matrix(); + public ObservableCollection Elements { get; set; } = new ObservableCollection(); + + RectangleF _selectionRect = new RectangleF(); + #endregion + + #region 重绘 + protected override void OnPaint(PaintEventArgs e) + { + try + { + //lock (_mapLoadLock) + //{ } + + Rectangle rect = ClientRectangle; + Graphics originG = e.Graphics; + BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current; + BufferedGraphics myBuffer = currentContext.Allocate(originG, rect); + Graphics g = myBuffer.Graphics; + g.SmoothingMode = SmoothingMode.HighSpeed; + g.PixelOffsetMode = PixelOffsetMode.HighSpeed; + g.InterpolationMode = InterpolationMode.NearestNeighbor; + g.Clear(BackColor); + + g.MultiplyTransform(Matrix); + + if (MAP != null) + { + try + { + g.DrawImage(MAP, 0, 0, MAP.Width, MAP.Height); + } + catch (Exception ex) + { + } + } + else + { + g.Clear(BackColor); + } + + DrawTemplate?.Draw(g); + foreach (IShapeElement ele in Elements) + { + if (ele.IsEnabled && ele.IsShowing) + { + ele.Draw(g); + } + } + + #region Grid + if (MAP != null) + { + if (ShowGrid) + { + int baseX = MAP.Width / 2; + int baseY = MAP.Height / 2; + + Point[] xPoint = new Point[] { new Point(0, baseY), new Point(MAP.Width, baseY) }; + Point[] yPoint = new Point[] { new Point(baseX, 0), new Point(baseX, MAP.Height) }; + + g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), xPoint[0], xPoint[1]); + g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), yPoint[0], yPoint[1]); + + if (GridValue > 0) + { + int stepX = MAP.Width / 2 / (GridValue * MAP.Width / 2 / _minGridStep / 10); + int stepY = MAP.Height / 2 / (GridValue * MAP.Height / 2 / _minGridStep / 10); + + //int stepX = _minGridStep + (10 - GridValue) * (MAP.Width / 2 - _minGridStep) / 10; + //int stepY = _minGridStep + (10 - GridValue) * (MAP.Height / 2 - _minGridStep) / 10; + + int yPositive = baseY; + do + { + xPoint = new Point[] { new Point(0, yPositive), new Point(MAP.Width, yPositive) }; + g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]); + yPositive -= stepY; + } while (yPositive > 0); + + int yNegative = baseY; + do + { + xPoint = new Point[] { new Point(0, yNegative), new Point(MAP.Width, yNegative) }; + g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]); + yNegative += stepY; + } while (yNegative < MAP.Height); + + int xPositive = baseX; + do + { + yPoint = new Point[] { new Point(xPositive, 0), new Point(xPositive, MAP.Height) }; + g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]); + xPositive -= stepX; + } while (xPositive > 0); + + int xNegative = baseX; + do + { + yPoint = new Point[] { new Point(xNegative, 0), new Point(xNegative, MAP.Height) }; + g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]); + xNegative += stepX; + } while (xNegative < MAP.Width); + } + } + } + #endregion + + if (MouseState == MouseState.SelectionZoneDoing) + { + g.DrawRectangle(Pens.AliceBlue, _selectionRect.X, _selectionRect.Y, _selectionRect.Width, _selectionRect.Height); + g.FillRectangle(new SolidBrush(Color.FromArgb(40, 0, 0, 255)), _selectionRect); + } + + myBuffer.Render(originG); + g.Dispose(); + myBuffer.Dispose();//释放资源 + } + catch (Exception) + { + } + } + + private void halfTransparent() + { + } + #endregion + + #region 绘制类型 + private IShapeElement drawTemplate = null; + public IShapeElement DrawTemplate + { + get + { + return drawTemplate; + } + set + { + if (drawTemplate != value) + { + + drawTemplate = value; + + //DrawTemplateChanged?.BeginInvoke(value, null, null); + Task.Run(() => DrawTemplateChanged.Invoke(value)); + + if (value == null) + { + MouseState = MouseState.Normal; + return; + } + + MouseState = MouseState.New; + + var existed = Elements.FirstOrDefault(e => e.ID == value.ID); + if (existed != null) + { + Elements.Remove(existed); + } + + //if (DrawTemplate != null) + //{ + // DrawTemplate.OnDrawDone += OnElementDrawDone; + //} + } + } + } + + string currentElementId = ""; + string CurrentElementId + { + get + { + return currentElementId; + } + set + { + if (currentElementId != value) + { + currentElementId = value; + } + } + } + + private void OnElementDrawDone(IShapeElement ele) + { + //int maxIndex = 1; + //if (Elements.Count > 0) + //{ + // maxIndex = Elements.Max(u => u.Index) + 1; + //} + //ele.Index = maxIndex; + //ele.Name = maxIndex.ToString(); + + //#region 获取基元的设备属性,目前包括运动坐标和相机参数 + //SetElementDevicePara?.Invoke(ele); + //#endregion + + //Elements.Add(ele); + //DrawTemplate = DrawTemplate?.Clone() as IShapeElement; + } + #endregion + + #region 状态变换 + private void OnElementChangeMouseState(IShapeElement ele, ElementState preState, ElementState curState) + { + if (curState != ElementState.Normal) + { + switch (curState) + { + case ElementState.New: + MouseState = MouseState.New; + break; + case ElementState.Selected: + CurrentElementId = ele.ID; + Cursor = Cursors.Default; + break; + case ElementState.Moving: + MouseState = MouseState.MoveElement; + Cursor = Cursors.NoMove2D; + break; + case ElementState.Editing: + MouseState = MouseState.Editing; + Cursor = Cursors.Hand; + break; + case ElementState.MouseInSide: + MouseState = MouseState.InSideElement; + break; + case ElementState.MouseHover: + MouseState = MouseState.HoverElement; + break; + case ElementState.CanStretchLeft: + Cursor = Cursors.SizeWE; + break; + case ElementState.StretchingLeft: + MouseState = MouseState.StretchingLeft; + Cursor = Cursors.SizeWE; + break; + case ElementState.CanStretchBottom: + Cursor = Cursors.SizeNS; + break; + case ElementState.StretchingBottom: + MouseState = MouseState.StretchingBottom; + Cursor = Cursors.SizeNS; + break; + case ElementState.CanStretchRight: + Cursor = Cursors.SizeWE; + break; + case ElementState.StretchingRight: + MouseState = MouseState.StretchingRight; + Cursor = Cursors.SizeWE; + break; + case ElementState.CanStretchTop: + Cursor = Cursors.SizeNS; + break; + case ElementState.StretchingTop: + MouseState = MouseState.StretchingTop; + Cursor = Cursors.SizeNS; + break; + + case ElementState.CanStretchLeftLowerCorner: + Cursor = Cursors.SizeNESW; + break; + case ElementState.StretchingLeftLowerCorner: + MouseState = MouseState.StretchingLeftLowerCorner; + Cursor = Cursors.SizeNESW; + break; + case ElementState.CanStretchLeftUpperCorner: + Cursor = Cursors.SizeNWSE; + break; + case ElementState.StretchingLeftUpperCorner: + MouseState = MouseState.StretchingLeftUpperCorner; + Cursor = Cursors.SizeNWSE; + break; + case ElementState.CanStretchRightLowerCorner: + Cursor = Cursors.SizeNWSE; + break; + case ElementState.StretchingRightLowerCorner: + MouseState = MouseState.StretchingRightLowerCorner; + Cursor = Cursors.SizeNWSE; + break; + case ElementState.CanStretchRightUpperCorner: + Cursor = Cursors.SizeNESW; + break; + case ElementState.StretchingRightUpperCorner: + MouseState = MouseState.StretchingRightUpperCorner; + Cursor = Cursors.SizeNESW; + break; + default: + //MouseState = MouseState.Normal; + break; + } + } + else + { + if (Elements.All(e => e.State == ElementState.Normal)) + { + CurrentElementId = null; + + if (preState == ElementState.Selected) + { + DrawTemplate = null; + } + else if (DrawTemplate != null) + { + MouseState = MouseState.New; + return; + } + + //MouseState = MouseState.Normal; + } + } + + this.Invalidate(); + } + #endregion + + #region 鼠标动作 + private void Canvas_MouseWheel(object sender, MouseEventArgs e) + { + PointF prePoint = ToMapPoint(e.Location); + + //先缩放 + if (e.Delta > 0) + { + Matrix.Scale((float)1.1, (float)1.1); + } + else + { + Matrix.Scale((float)0.9, (float)0.9); + } + + PointF afterPoint = ToMapPoint(e.Location); + + //后平移 + Matrix.Translate(afterPoint.X - prePoint.X, afterPoint.Y - prePoint.Y); + + Invalidate(); + } + + PointF startPoint, currentPoint; + bool _isMouseBtnPressing = false; + + private void Canvas_MouseDown(object sender, MouseEventArgs e) + { + PointF p = ToMapPoint(e.Location); + + if (e.Button == MouseButtons.Left) + { + _isMouseBtnPressing = true; + + switch (MouseState) + { + case MouseState.Normal: + startPoint = e.Location; + break; + case MouseState.StretchingLeft: + break; + case MouseState.StretchingRight: + break; + case MouseState.StretchingTop: + break; + case MouseState.StretchingBottom: + break; + case MouseState.MoveElement: + break; + case MouseState.HoverElement: + case MouseState.InSideElement: + case MouseState.New: + DrawTemplate?.OnMouseDown(p); + break; + case MouseState.Editing: + break; + case MouseState.SelectionZone: + MouseState = MouseState.SelectionZoneDoing; + startPoint = p; + break; + } + + foreach (IShapeElement ele in Elements) + { + ele.OnMouseDown(p); + } + } + else if (e.Button == MouseButtons.Right) + { + if (DrawTemplate != null && DrawTemplate.State == ElementState.New && DrawTemplate.IsCreatedDone()) + { + IShapeElement ele = DrawTemplate.Clone() as IShapeElement; + ele.State = ElementState.Normal; + Elements.Add(ele); + + // (DrawTemplate as ElementBase).Initial(); + } + } + } + + private void Canvas_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) + return; + + _isMouseBtnPressing = false; + switch (MouseState) + { + case MouseState.Normal: + break; + case MouseState.HoverElement: + break; + case MouseState.InSideElement: + break; + case MouseState.StretchingLeft: + break; + case MouseState.StretchingRight: + break; + case MouseState.StretchingTop: + break; + case MouseState.StretchingBottom: + break; + case MouseState.MoveElement: + //MouseState = MouseState.SelectedElement; + break; + case MouseState.New: + break; + case MouseState.Editing: + break; + case MouseState.MovingAll: + MouseState = MouseState.Normal; + break; + case MouseState.SelectionZone: + break; + case MouseState.SelectionZoneDoing: + MouseState = MouseState.SelectionZone; + + foreach (IShapeElement ele in Elements) + { + ele.State = ElementState.Normal; + if (ele.IsIntersect(_selectionRect)) + { + ele.State = ElementState.Selected; + } + } + + break; + } + + Cursor = Cursors.Default; + + if (MouseState != MouseState.SelectionZone) + { + PointF p = ToMapPoint(e.Location); + DrawTemplate?.OnMouseUp(p); + foreach (IShapeElement ele in Elements) + { + ele.OnMouseUp(p); + } + } + } + + private void Canvas_MouseMove(object sender, MouseEventArgs e) + { + PointF p = ToMapPoint(e.Location); + + switch (MouseState) + { + case MouseState.Normal: + { + if (_isMouseBtnPressing) + { + currentPoint = e.Location; + PointF p1 = ToMapPoint(startPoint); + PointF p2 = ToMapPoint(currentPoint); + Matrix.Translate(p2.X - p1.X, p2.Y - p1.Y); + startPoint = e.Location; + } + } + break; + case MouseState.StretchingLeft: + break; + case MouseState.StretchingRight: + break; + case MouseState.StretchingTop: + break; + case MouseState.StretchingBottom: + break; + case MouseState.MoveElement: + break; + case MouseState.HoverElement: + case MouseState.InSideElement: + case MouseState.New: + DrawTemplate?.OnMouseMove(p); + break; + case MouseState.Editing: + break; + case MouseState.MovingAll: + break; + case MouseState.SelectionZoneDoing: + { + currentPoint = p; + + float[] x2 = new float[2] { startPoint.X, currentPoint.X }; + float[] y2 = new float[2] { startPoint.Y, currentPoint.Y }; + + float xMin = x2.Min(); + float xMax = x2.Max(); + float yMin = y2.Min(); + float yMax = y2.Max(); + + _selectionRect = new RectangleF(xMin, yMin, xMax - xMin, yMax - yMin); + } + break; + } + + PointF mapPoint = ToMapPoint(e.Location); + Color color = Color.Transparent; + if (MAP != null && mapPoint.X > 0 && mapPoint.X < MAP.Width && mapPoint.Y > 0 && mapPoint.Y < MAP.Height) + { + color = MAP.GetPixel((int)mapPoint.X, (int)mapPoint.Y); + } + + // OnMouseLocationUpdated?.BeginInvoke(e.Location, mapPoint, color.Name, null, null); + Task.Run(() => OnMouseLocationUpdated?.Invoke(e.Location, mapPoint, color.Name)); + + if (MouseState != MouseState.SelectionZoneDoing) + { + Elements.ToList().ForEach(ele => ele?.OnMouseMove(p)); + } + + Invalidate(); + } + + private void Canvas_MouseDoubleClick(object sender, MouseEventArgs e) + { + PointF p = ToMapPoint(e.Location); + + if (e.Button == MouseButtons.Left) + { + switch (MouseState) + { + //case MouseState.SelectedElement: + case MouseState.HoverElement: + case MouseState.InSideElement: + case MouseState.MoveElement: + case MouseState.Normal: + //Elements.ForEach(ele => + foreach (IShapeElement ele in Elements) + { + ele.OnMouseDoubleClick(p); + } + //); + break; + default: + break; + } + } + else + { + //if (MouseState == MouseState.SelectedElement) + { + MouseState = MouseState.Normal; + + //Elements.ForEach(ele => + foreach (IShapeElement ele in Elements) + { + ele.State = ElementState.Normal; + } + //); + } + } + } + #endregion + + #region 图片操作 + bool _firstLoad = true; + object _mapLoadLock = new object(); + ManualResetEvent _mapLoadHandler = new ManualResetEvent(true); + ManualResetEvent _mapUsingHandler = new ManualResetEvent(false); + + /// + /// 载入图片 + /// + /// + public void LoadImage(Bitmap bitmap) + { + if (bitmap == null) + return; + + ////lock (_mapLoadLock) + ////_mapUsingHandler.WaitOne(); + //_mapLoadHandler.Reset(); + //{ + // map?.Dispose(); + // map = null; + // map = bitmap; + //} + //_mapLoadHandler.Set(); + + MAP = bitmap; + + if (_firstLoad) + { + SetScreenSize(); + _firstLoad = false; + } + Invalidate(); + } + + public void Clear() + { + MAP = null; + Elements.Clear(); + + Invalidate(); + } + + /// + /// 设置图片为原始尺寸 + /// + public void SetMapSize() + { + Matrix = new Matrix(); + Invalidate(); + } + + /// + /// 设置图片为适配尺寸 + /// + public void SetScreenSize() + { + try + { + if (MAP == null) + return; + + Matrix = new Matrix(); + + //先缩放 + List ratios = new List() { MAP.Width / (float)Width, MAP.Height / (float)Height }; + float ratio = 1 / ratios.Max(); + Matrix.Scale(ratio, ratio); + + //再平移 + //将plMain的中心转换为图片坐标 + PointF screenCenter = new PointF(Width / 2.0f, Height / 2.0f); + PointF mapPoint = ToMapPoint(screenCenter); + + //目标坐标减去当前坐标 + Matrix.Translate(-MAP.Width / 2.0f + mapPoint.X, -MAP.Height / 2.0f + mapPoint.Y); + + Invalidate(); + } + catch (Exception ex) + { + //Trace.TraceError(ex.GetExceptionMessage()); + } + } + #endregion + + #region 私有方法 + //private void DisplayMouseLocation(Point location) + //{ + // string screenPoint = string.Format("屏幕坐标X:{0};Y:{1}", location.X, location.Y); + + // Point mapPoint = ToMapPoint(location); + // string mapPointStr = string.Format("图片坐标X:{0};Y:{1}", mapPoint.X, mapPoint.Y); + + // tsslLocation.Text = screenPoint + " " + mapPointStr; + //} + + private PointF ToMapPoint(PointF p) + { + PointF[] ps = new PointF[] { p }; + Matrix invertMatrix = Matrix.Clone(); + invertMatrix.Invert(); + invertMatrix.TransformPoints(ps); + + return ps[0]; + } + + private Point ToScreenPoint(Point p) + { + Point[] ps = new Point[] { p }; + Matrix.TransformPoints(ps); + + return ps[0]; + } + + #endregion + + #region 按键操作 + public void OnCanvasKeyPressed(object sender, KeyPressEventArgs e) + { + //if (e.KeyChar == 27) //Esc + //{ + // //if (MouseState == MouseState.SelectedElement) + // { + // MouseState = MouseState.Normal; + + // //Elements.ForEach(ele => + // foreach (IShapeElement ele in Elements) + // { + // ele.State = ElementState.Normal; + // } + // //); + // } + //} + + //Invalidate(); + } + + public void OnCanvasKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Delete) //delete键 + { + Elements.Remove(Elements.FirstOrDefault(u => u.ID == CurrentElementId)); + } + + if (e.KeyData == Keys.Escape) //Esc + { + if (DrawTemplate != null /*&& (DrawTemplate as ElementBase).CreatePoints.Count > 0*/) + { + DrawTemplate.Initial(); + } + else + { + DrawTemplate = null; + + if (MouseState != MouseState.Normal) + { + MouseState = MouseState.Normal; + } + else + { + Elements.ToList().ForEach(u => u.State = ElementState.Normal); + } + } + } + + //if (e.KeyData == Keys.Up) + //{ + // Elements.ToList().ForEach(u => + // { + // if (u.State == ElementState.Selected) + // { + // u.Translate(0, -1); + // } + // }); + //} + + //if (e.KeyData == Keys.Down) + //{ + // Elements.ToList().ForEach(u => + // { + // if (u.State == ElementState.Selected) + // { + // u.Translate(0, 1); + // } + // }); + //} + + //if (e.KeyData == Keys.Left) + //{ + // Elements.ToList().ForEach(u => + // { + // if (u.State == ElementState.Selected) + // { + // u.Translate(-1, 0); + // } + // }); + //} + + //if (e.KeyData == Keys.Right) + //{ + // Elements.ToList().ForEach(u => + // { + // if (u.State == ElementState.Selected) + // { + // u.Translate(1, 0); + // } + // }); + //} + + Invalidate(); + } + #endregion + + #region 基元的设备属性 运动设置和相机设置 + public Action SetElementDevicePara; + + public Action SetDeviceByElement; + #endregion + + #region Grid + private bool showGrid = false; + public bool ShowGrid + { + get => showGrid; + set + { + showGrid = value; + Invalidate(); + } + } + + private int gridValue = 0; + public int GridValue + { + get => gridValue; + set + { + gridValue = value; + Invalidate(); + } + } + + private Pen penGrid = new Pen(Color.FromArgb(120, Color.Red), 1.0f); + public Pen Pen_Grid + { + get => penGrid; + set + { + penGrid = value; + Invalidate(); + } + } + + readonly int _minGridStep = 10; + #endregion + + #region Dispose + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + MAP?.Dispose(); + Matrix?.Dispose(); + penGrid?.Dispose(); + + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + #endregion + } +} diff --git a/DH.UI.Model.Winform/CanvasImage.resx b/DH.UI.Model.Winform/CanvasImage.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/DH.UI.Model.Winform/CanvasImage.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/Ctrl/GridCtrl.Designer.cs b/DH.UI.Model.Winform/Ctrl/GridCtrl.Designer.cs new file mode 100644 index 0000000..1b26268 --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/GridCtrl.Designer.cs @@ -0,0 +1,109 @@ +namespace DH.UI.Model.Winform +{ + partial class GridCtrl + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.chkShowGrid = new System.Windows.Forms.CheckBox(); + this.tbGridValue = new System.Windows.Forms.TrackBar(); + this.panel1 = new System.Windows.Forms.Panel(); + this.colorDialog1 = new System.Windows.Forms.ColorDialog(); + this.btnColor = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // chkShowGrid + // + this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button; + //this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid; + this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top; + this.chkShowGrid.Location = new System.Drawing.Point(0, 0); + this.chkShowGrid.Name = "chkShowGrid"; + this.chkShowGrid.Size = new System.Drawing.Size(32, 30); + this.chkShowGrid.TabIndex = 0; + this.chkShowGrid.UseVisualStyleBackColor = true; + this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged); + // + // tbGridValue + // + this.tbGridValue.AutoSize = false; + this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom; + this.tbGridValue.Location = new System.Drawing.Point(0, 21); + this.tbGridValue.Name = "tbGridValue"; + this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical; + this.tbGridValue.Size = new System.Drawing.Size(32, 121); + this.tbGridValue.TabIndex = 1; + this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both; + this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Controls.Add(this.chkShowGrid); + this.panel1.Controls.Add(this.tbGridValue); + this.panel1.Location = new System.Drawing.Point(1, 1); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(32, 142); + this.panel1.TabIndex = 2; + // + // btnColor + // + this.btnColor.BackColor = System.Drawing.Color.Red; + this.btnColor.Location = new System.Drawing.Point(4, 150); + this.btnColor.Name = "btnColor"; + this.btnColor.Size = new System.Drawing.Size(25, 23); + this.btnColor.TabIndex = 3; + this.btnColor.Text = " "; + this.btnColor.UseVisualStyleBackColor = false; + this.btnColor.Click += new System.EventHandler(this.btnColor_Click); + // + // GridCtrl + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; + this.Controls.Add(this.btnColor); + this.Controls.Add(this.panel1); + this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134))); + this.Name = "GridCtrl"; + this.Size = new System.Drawing.Size(32, 192); + ((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit(); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkShowGrid; + private System.Windows.Forms.TrackBar tbGridValue; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ColorDialog colorDialog1; + private System.Windows.Forms.Button btnColor; + } +} diff --git a/DH.UI.Model.Winform/Ctrl/GridCtrl.cs b/DH.UI.Model.Winform/Ctrl/GridCtrl.cs new file mode 100644 index 0000000..0eec2c4 --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/GridCtrl.cs @@ -0,0 +1,74 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DH.UI.Model.Winform +{ + public partial class GridCtrl : UserControl + { + public Action IsShowGridChanged { get; set; } + + public Action GridValueChanged { get; set; } + + public Action GridColorChanged { get; set; } + + public GridCtrl() + { + InitializeComponent(); + + IsChecked = chkShowGrid.Checked; + GridValue = tbGridValue.Value; + } + + bool isChecked = false; + bool IsChecked + { + get => isChecked; + set + { + if (isChecked != value) + { + // IsShowGridChanged?.BeginInvoke(value, null, null); + Task.Run(() => IsShowGridChanged.Invoke(value)); + } + + isChecked = value; + } + } + + int gridValue = 0; + int GridValue + { + get => gridValue; + set + { + if (gridValue != value) + { + // GridValueChanged?.BeginInvoke(value, null, null); + Task.Run(() => GridValueChanged.Invoke(value)); + } + + gridValue = value; + } + } + private void chkShowGrid_CheckedChanged(object sender, EventArgs e) + { + IsChecked = chkShowGrid.Checked; + } + + private void tbGridValue_ValueChanged(object sender, EventArgs e) + { + GridValue = tbGridValue.Value; + } + + private void btnColor_Click(object sender, EventArgs e) + { + if (colorDialog1.ShowDialog() == DialogResult.OK) + { + btnColor.BackColor = colorDialog1.Color; + // GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null); + Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor)); + } + } + } +} diff --git a/DH.UI.Model.Winform/Ctrl/GridCtrl.resx b/DH.UI.Model.Winform/Ctrl/GridCtrl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/GridCtrl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/Ctrl/GridCtrlHost.cs b/DH.UI.Model.Winform/Ctrl/GridCtrlHost.cs new file mode 100644 index 0000000..c999dff --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/GridCtrlHost.cs @@ -0,0 +1,12 @@ +using System.Windows.Forms; + +namespace DH.UI.Model.Winform +{ + public class GridCtrlHost : ToolStripControlHost + { + public GridCtrlHost(GridCtrl grid) : base(grid) + { + //Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134); + } + } +} diff --git a/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.Designer.cs b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.Designer.cs new file mode 100644 index 0000000..f082d76 --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.Designer.cs @@ -0,0 +1,78 @@ +namespace DH.UI.Model.Winform +{ + partial class IOIndicatorCtrl + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + plStatus = new Panel(); + lblDesc = new Label(); + SuspendLayout(); + // + // plStatus + // + plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + plStatus.Location = new Point(0, 0); + plStatus.Margin = new Padding(4); + plStatus.Name = "plStatus"; + plStatus.Size = new Size(28, 34); + plStatus.TabIndex = 0; + plStatus.Paint += plStatus_Paint; + plStatus.DoubleClick += plStatus_DoubleClick; + // + // lblDesc + // + lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + lblDesc.AutoSize = true; + lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World); + lblDesc.Location = new Point(36, 11); + lblDesc.Margin = new Padding(4, 0, 4, 0); + lblDesc.Name = "lblDesc"; + lblDesc.Size = new Size(31, 13); + lblDesc.TabIndex = 1; + lblDesc.Text = "XXXX"; + lblDesc.TextAlign = ContentAlignment.MiddleLeft; + lblDesc.DoubleClick += lblDesc_DoubleClick; + // + // IOIndicatorCtrl + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(lblDesc); + Controls.Add(plStatus); + Margin = new Padding(4); + Name = "IOIndicatorCtrl"; + Size = new Size(138, 34); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Panel plStatus; + private Label lblDesc; + } +} diff --git a/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.cs b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.cs new file mode 100644 index 0000000..7821132 --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.cs @@ -0,0 +1,126 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace DH.UI.Model.Winform +{ + public partial class IOIndicatorCtrl : UserControl + { + public IOIndicatorCtrl() + { + InitializeComponent(); + } + + private bool isON = false; + + public bool IsOn + { + get => isON; + set + { + bool? temp = isON; + isON = value; + + if (temp != isON) + { + RefreshStatus(); + } + } + } + + private void RefreshStatus() + { + if (InvokeRequired) + { + Invoke(new Action(() => RefreshStatus())); + } + else + { + plStatus.Invalidate(); + } + } + + private string desc = ""; + public string Desc + { + get => desc; + set + { + desc = value; + + DisplayDesc(); + } + } + + public int Index { get; set; } + + private void DisplayDesc() + { + if (InvokeRequired) + { + Invoke(new Action(() => DisplayDesc())); + } + else + { + lblDesc.Text = Desc; + } + } + + readonly PointF[] regionBlink = new PointF[] + { + new PointF(5,10), + new PointF(10,13), + new PointF(12,7), + new PointF(10,5) + }; + + public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0) + { + InitializeComponent(); + + IsOn = _isOn; + Desc = _desc; + Index = index; + } + + /// + /// 更新绘制图标 + /// + /// + /// + private void plStatus_Paint(object sender, PaintEventArgs e) + { + Panel pl = sender as Panel; + + Graphics g = e.Graphics; + + g.Clear(SystemColors.Control); + + + if (IsOn) + { + g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle); + } + else + { + g.FillEllipse(Brushes.Gray, pl.ClientRectangle); + } + + g.FillPolygon(Brushes.White, regionBlink); + + } + + public event Action OnIODoubleClick; + + + private void lblDesc_DoubleClick(object sender, EventArgs e) + { + OnIODoubleClick?.Invoke(Name, IsOn, Index); + } + + private void plStatus_DoubleClick(object sender, EventArgs e) + { + OnIODoubleClick?.Invoke(Name, IsOn, Index); + } + } +} diff --git a/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.resx b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.resx new file mode 100644 index 0000000..a395bff --- /dev/null +++ b/DH.UI.Model.Winform/Ctrl/IOIndicatorCtrl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/DH.UI.Model.Winform.csproj b/DH.UI.Model.Winform/DH.UI.Model.Winform.csproj new file mode 100644 index 0000000..f2d0ff7 --- /dev/null +++ b/DH.UI.Model.Winform/DH.UI.Model.Winform.csproj @@ -0,0 +1,48 @@ + + + + net8.0-windows + enable + enable + ..\ + output + true + AnyCPU;x64 + + + + + + + + + + + + + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + + + + + + Settings.Designer.cs + SettingsSingleFileGenerator + + + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/Element/CommonHelper.cs b/DH.UI.Model.Winform/Element/CommonHelper.cs new file mode 100644 index 0000000..7f50ccd --- /dev/null +++ b/DH.UI.Model.Winform/Element/CommonHelper.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using static DH.Commons.Enums.EnumHelper; + + +namespace DH.UI.Model.Winform +{ + //public static class AOIEnumHelper + //{ + // public enum ElementState + // { + // New = 1, + // MouseHover = 2, + // MouseInSide = 3, + // Selected = 4, + // Moving = 5, + + // Normal = 11, + + // Measuring = 21, + // MeasureDoneOK = 22, + // MeasureDoneNG = 23, + // } + + // public enum MouseState + // { + // Normal = 1, + // HoverElement = 2, + // InSideElement = 3, + + // StretchingLeft = 11, + // StretchingRight = 12, + // StretchingUp = 13, + // StretchingDown = 14, + // MoveElement = 15, + + // New = 21, + // Editing = 22, + // SelectedElement = 23, + + // MovingAll = 31, + + // SelectionZone = 41, + // SelectionZoneDoing = 42, + // } + + // public enum RunMode + // { + // [Description("设置模式")] + // SetMode = 0, + // [Description("运行模式")] + // RunMode = 1, + // } + //} + + public static class EventRouter + { + /// + /// ElementBase 基元 + /// 1st MouseState 初始状态 + /// 2nd MouseState 变化状态 + /// + public static event Action ChangeElementsMouseState; + + public static void TriggerElementsMouseStateChanged(ElementBase ele, ElementState preState, ElementState curState) + { + ChangeElementsMouseState?.Invoke(ele, preState, curState); + } + } + + public class NoticedPoints : List + { + public Action OnItemChanged; + + public NoticedPoints() { } + + public NoticedPoints(List points) + { + AddRange(points); + } + + public new PointF this[int index] + { + get + { + if (index >= 0 && index < Count) + { + return base[index]; + } + else + { + return new Point(); + } + + } + set + { + if (base[index] != value) + { + base[index] = value; + OnItemChanged?.Invoke(); + } + } + } + + public new void Add(PointF item) + { + lock (this) + { + base.Add(item); + OnItemChanged?.Invoke(); + } + } + + public new void AddRange(IEnumerable collection) + { + lock (this) + { + base.AddRange(collection); + OnItemChanged?.Invoke(); + } + } + + public new void Clear() + { + lock (this) + { + base.Clear(); + OnItemChanged?.Invoke(); + } + } + + public new void Insert(int index, PointF item) + { + lock (this) + { + base.Insert(index, item); + OnItemChanged?.Invoke(); + } + } + + public new void InsertRange(int index, IEnumerable collection) + { + lock (this) + { + base.InsertRange(index, collection); + OnItemChanged?.Invoke(); + } + } + + public new bool Remove(PointF item) + { + lock (this) + { + bool flag = base.Remove(item); + + if (flag) + { + OnItemChanged?.Invoke(); + } + + return flag; + } + } + + public new int RemoveAll(Predicate match) + { + lock (this) + { + int i = base.RemoveAll(match); + if (i > 0) + { + OnItemChanged?.Invoke(); + } + + return i; + } + } + + public new void RemoveAt(int index) + { + lock (this) + { + base.RemoveAt(index); + OnItemChanged?.Invoke(); + } + } + + public new void RemoveRange(int index, int count) + { + lock (this) + { + base.RemoveRange(index, count); + OnItemChanged?.Invoke(); + } + } + } +} diff --git a/DH.UI.Model.Winform/Element/ElementBase.cs b/DH.UI.Model.Winform/Element/ElementBase.cs new file mode 100644 index 0000000..0b529b4 --- /dev/null +++ b/DH.UI.Model.Winform/Element/ElementBase.cs @@ -0,0 +1,980 @@ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using System.Windows.Forms; + +using System.Text.Json.Serialization; +using DH.Commons.Enums; +using static DH.Commons.Enums.EnumHelper; + + +namespace DH.UI.Model.Winform +{ + [Serializable] + public abstract class ElementBase : IShapeElement, IEventHandle, ICloneable, IComparable, IDisposable + { + #region 常量 + protected int _mouseIntersectDistance = 4; + #endregion + + #region 标识符 + /// + /// ID,采用GUID + /// + [ReadOnly(true)] + [Category("\t通用标识")] + [Description("GUID")] + public virtual string ID { get; set; } = Guid.NewGuid().ToString().ToUpper(); + + /// + /// 序号 + /// + [Category("\t通用标识")] + [Description("序号")] + public virtual int Index { get; set; } = 0; + + [Browsable(false)] + public virtual int GroupIndex { get; set; } = 0; + + private string name = ""; + /// + /// 名称 + /// + [Category("\t通用标识")] + [Description("名称")] + public virtual string Name + { + get + { + if (string.IsNullOrWhiteSpace(name)) + { + return GetDisplayText(); + } + else + { + return name; + } + } + set => name = value; + } + #endregion + + #region 启用状态 + private bool isEnabled = true; + + //[Browsable(false)] + public virtual bool IsEnabled + { + get + { + return isEnabled; + } + set + { + //if (isEnabled != value) + //{ + // isEnabled = value; + + // PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs("IsEnabled"), null, null); + //} + + Set(ref isEnabled, value); + } + } + + [Browsable(false)] + public virtual bool IsShowing { get; set; } = true; + + private bool showList = true; + [Browsable(false)] + public virtual bool ShowList + { + get => showList; + set => Set(ref showList, value); + } + #endregion + + #region 字段 + [JsonIgnore] + protected PointF _startPoint, _currentPoint; + #endregion + + #region 绘图特性 + [Browsable(false)] + public NoticedPoints CreatePoints { get; set; } = new NoticedPoints(); + + public virtual bool IsCreatedDone() + { + return CreatePoints.Count >= 2; + } + + //protected Region Region { get; set; } + + #region 画笔相关 + #region 绘图画笔 + [JsonIgnore] + [Browsable(false)] + protected Pen Pen { get; set; } = new Pen(Color.Red, 1); + + protected virtual void SetNewStatePen() + { + Pen = new Pen(Color.Red, 3); + } + + protected virtual void SetNormalPen() + { + Pen = new Pen(Color.Red, 1); + } + + protected virtual void SetHoverPen() + { + Pen = new Pen(Color.BlueViolet, 3); + } + + protected virtual void SetInSidePen() + { + Pen = new Pen(Color.YellowGreen, 3); + } + + protected virtual void SetSelectedPen() + { + Pen = new Pen(Color.Pink, 3); + } + + protected virtual void SetMeasureDoneOKPen() + { + Pen = new Pen(Color.Green, 2); + } + + protected virtual void SetMeasureDoneNGPen() + { + Pen = new Pen(Color.Red, 2); + } + + protected virtual void SetMeasuringPen() + { + Pen = new Pen(Color.Yellow, 3); + } + #endregion + + #region 文字画笔 + //[JsonIgnore] + //protected Pen PenText = new Pen(Color.Black, 1); + //[JsonIgnore] + //protected Pen PenTextOK = new Pen(Color.Green, 1.5f); + //[JsonIgnore] + //protected Pen PenTextNG = new Pen(Color.Red, 2); + + ///// + ///// 字体大小 + ///// + //[Category("显示属性")] + //[Description("字体大小")] + ////[Browsable(false)] + //public virtual float FontSize { get; set; } = 15; + /// + /// 字体大小 + /// + [Category("显示属性")] + [Description("字体设置")] + [Browsable(false)] + public virtual Font Font { get; set; } = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World); + + /// + /// 字体和基元的距离 + /// + [Category("显示属性")] + [Description("字体和基元的距离")] + [Browsable(false)] + public virtual int FontDistance { get; set; } = 15; + + [Category("显示属性")] + [Description("显示字符说明")] + [Browsable(false)] + public virtual bool IsShowRemark { get; set; } = true; + + #endregion + #endregion + + //public Graphics Graphics { get; set; } + public abstract void Draw(Graphics g); + protected abstract void DrawResult(Graphics g); + #endregion + + #region 状态 + private ElementState state = ElementState.New; + [JsonIgnore] + [Browsable(false)] + public ElementState State + { + get + { + return state; + } + set + { + if (state != value) + { + ElementState preState = state; + Set(ref state, value); + EventRouter.TriggerElementsMouseStateChanged(this, preState, state); + switch (state) + { + case ElementState.MouseHover: + SetHoverPen(); + break; + case ElementState.MouseInSide: + SetInSidePen(); + break; + case ElementState.Selected: + SetSelectedPen(); + break; + case ElementState.Normal: + SetNormalPen(); + break; + case ElementState.Measuring: + SetMeasuringPen(); + break; + case ElementState.MeasureDoneOK: + SetMeasureDoneOKPen(); + break; + case ElementState.MeasureDoneNG: + SetMeasureDoneNGPen(); + break; + case ElementState.New: + SetNewStatePen(); + break; + } + } + } + } + + /// + /// 是否是运行模式 + /// + [Browsable(false)] + public RunMode RunMode { get; set; } = RunMode.NormalMode; + #endregion + + #region 复制 + public abstract object Clone(); + + public virtual void Initial() + { + State = ElementState.New; + CreatePoints = new NoticedPoints(); + } + #endregion + + #region IMouseEvent + public virtual void OnMouseDoubleClick(PointF p) + { + if (State == ElementState.MeasureDoneNG || State == ElementState.MeasureDoneOK) + return; + + //if (State == ElementState.MouseInSide) + //{ + // State = ElementState.Selected; + //} + //else if (State == ElementState.Selected || State == ElementState.Moving) + //{ + // if (IsMouseInSide(p)) + // { + // State = ElementState.MouseInSide; + // } + //} + if (IsMouseInSide(p)) + { + State = ElementState.Selected; + } + } + + public abstract void OnKeyDown(object sender, KeyEventArgs e); + + public abstract void OnKeyUp(object sender, KeyEventArgs e); + + public virtual void OnMouseDown(PointF p) + { + //switch (State) + //{ + // case ElementState.New: + // OnMouseDownWhenNew(p); + // break; + // case ElementState.MouseHover: + // break; + // case ElementState.MouseInSide: + // State = ElementState.Selected; + // break; + // case ElementState.Selected: + // _startPoint = p; + // State = ElementState.Moving; + // break; + // case ElementState.Normal: + // break; + //} + if (State == ElementState.New) + { + OnMouseDownWhenNew(p); + } + else if (IsMouseCanMoveElement(p) && State == ElementState.Selected) + { + State = ElementState.Moving; + } + else if (IsMouseCanStretchBottom(p) && State == ElementState.CanStretchBottom) + { + State = ElementState.StretchingBottom; + } + else if (IsMouseCanStretchTop(p) && State == ElementState.CanStretchTop) + { + State = ElementState.StretchingTop; + } + else if (IsMouseCanStretchLeft(p) && State == ElementState.CanStretchLeft) + { + State = ElementState.StretchingLeft; + } + else if (IsMouseCanStretchRight(p) && State == ElementState.CanStretchRight) + { + State = ElementState.StretchingRight; + } + else if (IsMouseCanStretchLeftLowerCorner(p) && State == ElementState.CanStretchLeftLowerCorner) + { + State = ElementState.StretchingLeftLowerCorner; + } + else if (IsMouseCanStretchLeftUpperCorner(p) && State == ElementState.CanStretchLeftUpperCorner) + { + State = ElementState.StretchingLeftUpperCorner; + } + else if (IsMouseCanStretchRightLowerCorner(p) && State == ElementState.CanStretchRightLowerCorner) + { + State = ElementState.StretchingRightLowerCorner; + } + else if (IsMouseCanStretchRightUpperCorner(p) && State == ElementState.CanStretchRightUpperCorner) + { + State = ElementState.StretchingRightUpperCorner; + } + } + + public virtual void OnMouseMove(PointF p) + { + switch (State) + { + case ElementState.New: + OnMouseMoveWhenNew(p); + break; + case ElementState.Selected: + { + if (IsMouseCanStretchLeft(p)) + { + State = ElementState.CanStretchLeft; + } + else if (IsMouseCanStretchRight(p)) + { + State = ElementState.CanStretchRight; + } + else if (IsMouseCanStretchTop(p)) + { + State = ElementState.CanStretchTop; + } + else if (IsMouseCanStretchBottom(p)) + { + State = ElementState.CanStretchBottom; + } + else if (IsMouseCanStretchLeftLowerCorner(p)) + { + State = ElementState.CanStretchLeftLowerCorner; + } + else if (IsMouseCanStretchLeftUpperCorner(p)) + { + State = ElementState.CanStretchLeftUpperCorner; + } + else if (IsMouseCanStretchRightLowerCorner(p)) + { + State = ElementState.CanStretchRightLowerCorner; + } + else if (IsMouseCanStretchRightUpperCorner(p)) + { + State = ElementState.CanStretchRightUpperCorner; + } + + break; + } + case ElementState.Moving: + _currentPoint = p; + //Translate(_currentPoint.X - _startPoint.X, _currentPoint.Y - _startPoint.Y); + //_startPoint = _currentPoint; + Relocate(p); + break; + case ElementState.MouseHover: + case ElementState.MouseInSide: + case ElementState.Normal: + //if (IsMouseInSide(p)) + //{ + // State = ElementState.MouseInSide; + //} + //else if (IsMouseHover(p)) + //{ + // State = ElementState.MouseHover; + //} + //else + //{ + // State = ElementState.Normal; + //} + break; + case ElementState.CanStretchBottom: + if (!IsMouseCanStretchBottom(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchTop: + if (!IsMouseCanStretchTop(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchLeft: + if (!IsMouseCanStretchLeft(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchRight: + if (!IsMouseCanStretchRight(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchLeftUpperCorner: + if (!IsMouseCanStretchLeftUpperCorner(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchLeftLowerCorner: + if (!IsMouseCanStretchLeftLowerCorner(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchRightLowerCorner: + if (!IsMouseCanStretchRightLowerCorner(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.CanStretchRightUpperCorner: + if (!IsMouseCanStretchRightUpperCorner(p)) + { + State = ElementState.Selected; + } + break; + case ElementState.StretchingTop: + StretchTop(p); + break; + case ElementState.StretchingBottom: + StretchBottom(p); + break; + case ElementState.StretchingLeft: + StretchLeft(p); + break; + case ElementState.StretchingRight: + StretchRight(p); + break; + case ElementState.StretchingLeftLowerCorner: + StretchLeftLowerCorner(p); + break; + case ElementState.StretchingLeftUpperCorner: + StretchLeftUpperCorner(p); + break; + case ElementState.StretchingRightLowerCorner: + StretchRightLowerCorner(p); + break; + case ElementState.StretchingRightUpperCorner: + StretchRightUpperCorner(p); + break; + } + } + + public virtual void OnMouseUp(PointF p) + { + switch (State) + { + case ElementState.New: + OnMouseUpWhenNew(p); + break; + case ElementState.Moving: + State = ElementState.Selected; + break; + case ElementState.Selected: + if (!IsMouseInSide(p)) + { + State = ElementState.Normal; + } + break; + case ElementState.StretchingBottom: + State = ElementState.CanStretchBottom; + break; + case ElementState.StretchingLeft: + State = ElementState.CanStretchLeft; + break; + case ElementState.StretchingRight: + State = ElementState.CanStretchRight; + break; + case ElementState.StretchingTop: + State = ElementState.CanStretchTop; + break; + case ElementState.StretchingLeftLowerCorner: + State = ElementState.CanStretchLeftLowerCorner; + break; + case ElementState.StretchingLeftUpperCorner: + State = ElementState.CanStretchLeftUpperCorner; + break; + case ElementState.StretchingRightUpperCorner: + State = ElementState.CanStretchRightUpperCorner; + break; + case ElementState.StretchingRightLowerCorner: + State = ElementState.CanStretchRightLowerCorner; + break; + default: + State = ElementState.Normal; + break; + } + + AfterTranformOp(); + } + + public virtual void AfterTranformOp() + { + } + + #region 当基元状态为新建或可编辑时的鼠标操作动作 + /// + /// 当状态为New时的鼠标按下操作 + /// + /// + public abstract void OnMouseDownWhenNew(PointF p); + + public abstract void OnMouseMoveWhenNew(PointF p); + + public abstract void OnMouseUpWhenNew(PointF p); + #endregion + + #endregion + + #region 委托事件 + [JsonIgnore] + public Action OnDrawDone; + [JsonIgnore] + public Action OnMeasureDone; + [JsonIgnore] + public Action OnElementEnableChanged; + #endregion + + #region 几何特性 + /// + /// 基类基础的Rectangle 用于计算MouseHover和Inside等 + /// + [Browsable(false)] + public Rectangle BaseRectangle { get; set; } + EnumHelper.ElementState IShapeElement.State { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public abstract bool IsMouseHover(PointF p); + + public abstract bool IsMouseInSide(PointF p); + + public abstract bool IsIntersect(RectangleF rect); + #region Move & Stretch & Move Anchor + public virtual bool IsMouseCanMoveElement(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchLeft(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchRight(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchTop(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchBottom(PointF p) + { + return false; + } + + public virtual void StretchLeft(PointF p) + { + } + + public virtual void StretchRight(PointF p) + { + } + + public virtual void StretchTop(PointF p) + { + } + + public virtual void StretchBottom(PointF p) + { + } + + public virtual bool IsMouseCanStretchLeftUpperCorner(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchRightUpperCorner(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchLeftLowerCorner(PointF p) + { + return false; + } + + public virtual bool IsMouseCanStretchRightLowerCorner(PointF p) + { + return false; + } + + public virtual void StretchLeftUpperCorner(PointF p) + { + } + + public virtual void StretchRightUpperCorner(PointF p) + { + } + + public virtual void StretchLeftLowerCorner(PointF p) + { + } + + public virtual void StretchRightLowerCorner(PointF p) + { + } + + public virtual bool IsMouseCanMoveAnchor(PointF p) + { + return false; + } + #endregion + + #endregion + + #region 变形操作 + public abstract void Translate(float x, float y); + + public virtual void Relocate(PointF point) { } + + //public abstract void RotateAt(int x, int y, float degree); + #endregion + + #region 运动 + //[Browsable(false)] + //public PlanPoint MovePoint { get; set; } + #endregion + + #region 相机 + //[Browsable(false)] + //public CameraOperationConfigBase CameraOpConfig { get; set; } + #endregion + + #region 光源 + #endregion + + #region 算法 + /// + /// 算法 + /// + /// 计算参数 + public virtual void Calculate(Bitmap image) { } + + public virtual void Calculate(IntPtr imagePtr, int ptrSize, int imageWidth, int imageHeight) { } + + public virtual void Calculate(string imagePath) { } + #endregion + + #region 图片保存 + //[Description("图片保存方式")] + //public ImageSaveMode ImageSaveMode { get; set; } = ImageSaveMode.NoSave; + + //public virtual void SaveImage(Bitmap image) + //{ + // if (string.IsNullOrWhiteSpace(AOIMeasure.GlobalVar.ImageSaveDirectory) || ImageSaveMode == ImageSaveMode.NoSave) + // { + // return; + // } + + // DirectoryInfo dir = new DirectoryInfo(GlobalVar.ImageSaveDirectory); + // if (!dir.Exists) + // { + // dir.Create(); + // } + + // string imgPath = Path.Combine(AOIMeasure.GlobalVar.ImageSaveDirectory, Name + "_" + DateTime.Now.ToString("MMdd_HHmmss") + ".bmp"); + // switch (ImageSaveMode) + // { + // case ImageSaveMode.SaveImage: + // image.Save(imgPath); + // break; + // case ImageSaveMode.SaveImageWithElement: + // Bitmap bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb); + // using (Graphics g = Graphics.FromImage(bmp)) + // { + // g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + // g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + // g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + // g.DrawImage(image, 0, 0, image.Width, image.Height); + + // Draw(g); + // } + + // bmp.Save(imgPath); + // break; + // } + //} + + //public virtual void SaveImage(IntPtr imagePtr, int ptrSize) + //{ + // Bitmap map = null; + // unsafe + // { + // byte* pArray = (byte*)imagePtr; + // byte[] array = new byte[ptrSize]; + // Marshal.Copy(imagePtr, array, 0, ptrSize); + // using (MemoryStream ms = new MemoryStream(array)) + // { + // map = (Bitmap)Image.FromStream(ms); + // } + // } + + // SaveImage(map); + //} + + //public virtual void SaveImage(string imagePath) + //{ + // using (Bitmap map = Image.FromFile(imagePath) as Bitmap) + // { + // SaveImage(map); + // } + //} + #endregion + + #region 值设置 + public virtual void InitialMeasureResult() + { + //PropertyInfo[] prop = this.GetType().GetProperties(); + //Array.ForEach(prop, p => + //{ + // if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite) + // { + // MeasureSpec spec = p.GetValue(this) as MeasureSpec; + // spec.Result = MeasureResult.NotYet; + // p.SetValue(this, spec); + // } + //}); + } + + public virtual void SetActualValue(double v) + { + //PropertyInfo[] prop = this.GetType().GetProperties(); + //Array.ForEach(prop, p => + // { + // if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite) + // { + // MeasureSpec spec = p.GetValue(this) as MeasureSpec; + // spec.ActualValue = (float)v; + // p.SetValue(this, spec); + // } + // }); + } + + public virtual void SetStandardValue(double v) + { + //PropertyInfo[] prop = this.GetType().GetProperties(); + //Array.ForEach(prop, p => + //{ + // if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite) + // { + // MeasureSpec spec = p.GetValue(this) as MeasureSpec; + // spec.StandardValue = (float)v; + // p.SetValue(this, spec); + // } + //}); + } + #endregion + + #region IPropertyChanged + public event PropertyChangedEventHandler PropertyChanged; + + public virtual void Set(ref T field, T newValue, [CallerMemberName] string propName = null) + { + if (!field.Equals(newValue)) + { + field = newValue; + //PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null); + RaisePropertyChanged(propName); + } + } + + public virtual void RaisePropertyChanged(string propName = "") + { + //PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null); + + //Task.Run(() => + //{ + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + //}); + } + #endregion + + public override string ToString() + { + return GetDisplayText(); + } + + public abstract string GetDisplayText(); + + #region IComparable + public virtual int CompareTo(ElementBase other) + { + //throw new NotImplementedException(); + return Index - other.Index; + } + #endregion + + #region IDisposable Support + private bool disposedValue = false; // 要检测冗余调用 + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // 释放托管状态(托管对象)。 + Pen?.Dispose(); + } + + // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。 + // TODO: 将大型字段设置为 null。 + + disposedValue = true; + } + } + + // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。 + // ~ElementBase() + // { + // // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 + // Dispose(false); + // } + + // 添加此代码以正确实现可处置模式。 + public void Dispose() + { + // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 + Dispose(true); + // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。 + // GC.SuppressFinalize(this); + } + #endregion + } + + [Serializable] + public abstract class DisplayElementBase : ElementBase + { + //public override object Clone() + //{ + // throw new NotImplementedException(); + //} + + //public override void Draw(Graphics g) + //{ + // throw new NotImplementedException(); + //} + + //public override string GetDisplayText() + //{ + // throw new NotImplementedException(); + //} + + //public override bool IsIntersect(Rectangle rect) + //{ + // throw new NotImplementedException(); + //} + + public override bool IsMouseHover(PointF p) + { + return false; + } + + //public override bool IsMouseInSide(Point p) + //{ + // throw new NotImplementedException(); + //} + + public override void OnKeyDown(object sender, KeyEventArgs e) + { + } + + public override void OnKeyUp(object sender, KeyEventArgs e) + { + } + + public override void OnMouseDownWhenNew(PointF p) + { + } + + public override void OnMouseMoveWhenNew(PointF p) + { + } + + public override void OnMouseUpWhenNew(PointF p) + { + } + + public override void Translate(float x, float y) + { + } + + protected override void DrawResult(Graphics g) + { + } + } + + public interface IEventHandle + { + void OnMouseMove(PointF p); + + void OnMouseDown(PointF p); + + void OnMouseUp(PointF p); + + void OnMouseDoubleClick(PointF p); + + void OnKeyDown(object sender, KeyEventArgs e); + + void OnKeyUp(object sender, KeyEventArgs e); + } + + public class ElementIndexCompare : IComparer + { + public int Compare(ElementBase x, ElementBase y) + { + return x.Index - y.Index; + } + } +} diff --git a/DH.UI.Model.Winform/Element/MLResultDisplay.cs b/DH.UI.Model.Winform/Element/MLResultDisplay.cs new file mode 100644 index 0000000..61dab98 --- /dev/null +++ b/DH.UI.Model.Winform/Element/MLResultDisplay.cs @@ -0,0 +1,325 @@ + +using DH.Commons.Enums; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + + +namespace DH.UI.Model.Winform +{ + public class DetectResultDisplay : ElementBase + { + //深度学习 显示结果 + private List mlResultList = null; + public List MLResultList + { + get => mlResultList; + set + { + if (mlResultList != value) + { + mlResultList = value; + } + } + } + + //测量结果 + //private List specResultList = null; + //public List SpecResultList + //{ + // get => specResultList; + // set + // { + // if (specResultList != value) + // { + // specResultList = value; + + // string specDisplay = ""; + // if (specResultList != null && specResultList.Count > 0) + // { + // specResultList.ForEach(s => + // { + // specDisplay += $"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}\r\n"; + // }); + // } + + // if (!string.IsNullOrWhiteSpace(specDisplay)) + // { + // DisplayTxt += specDisplay; + // } + // } + // } + //} + + ResultState ResultState = ResultState.DetectNG; + + string DisplayTxt = ""; + Bitmap ResultImage = null; + PointF StartPoint = new PointF(); + Brush FontBrush = new SolidBrush(Color.Green); + Pen DetectResultRectPen = new Pen(new SolidBrush(Color.Green)); + Font DetectResultFont = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World); + + public int ImageWidth { get; set; } + public int ImageHeight { get; set; } + public DetectResultDisplay() { } + + //public DetectResultDisplay(NetResult result, List specs, ResultState resultState, int imageWidth) + //{ + // ImageWidth = imageWidth; + + // ResultState = resultState; + + // displayTxt = resultState.ToString() + "\r\n"; + // if (resultState != ResultState.OK) + // { + // fontBrush = new SolidBrush(Color.Red); + // } + + // NetResult = result; + // SpecList = specs; + + // Font = new Font(new FontFamily("Tahoma"), 35 * ImageWidth / 1400, GraphicsUnit.World); + // startPoint = new PointF(150 * ImageWidth / 1400, 150 * ImageWidth / 1400); + //} + + public DetectResultDisplay(DetectStationResult detectResult, Bitmap resultImage, string displayTxt) + { + ImageWidth = resultImage.Width; + ImageHeight = resultImage.Height; + var longSide = ImageWidth > ImageHeight ? ImageWidth : ImageHeight; + + MLResultList = detectResult.DetectDetails; + // SpecResultList = detectResult.Specs; + ResultState = detectResult.ResultState; + ResultImage = resultImage; + DisplayTxt = displayTxt; + if (ResultState != ResultState.OK) + { + FontBrush = new SolidBrush(Color.Red); + DetectResultRectPen = new Pen(new SolidBrush(Color.Red)); + } + Font = new Font(new FontFamily("Tahoma"), 35 * longSide / 1400, GraphicsUnit.World); + DetectResultFont = new Font(new FontFamily("Tahoma"), 25 * longSide / 1400, GraphicsUnit.World); + StartPoint = new PointF(100 * ImageWidth / 1400, 100 * ImageHeight / 1400); + } + + public override object Clone() + { + return null; + } + + + public override void Draw(Graphics g) + { + //画检测结果图 + if (ResultImage != null && ResultState != ResultState.OK) + { + g.DrawImage(ResultImage, new Point(0, 0)); + } + //画文字 + if (!string.IsNullOrWhiteSpace(DisplayTxt)) + { + g.DrawString(DisplayTxt, Font, FontBrush, StartPoint); + } + //画外接矩形+label 深度学习 + if (MLResultList != null && MLResultList.Count > 0) + { + MLResultList.ForEach(d => + { + g.DrawRectangle(DetectResultRectPen, d.Rect); + + string locationTxt = $"{d.LabelDisplay}"; + var locationX = d.Rect.X; + var locationY = d.Rect.Y <= 20 ? d.Rect.Y + 20 : d.Rect.Y - 20; + g.DrawString(locationTxt, DetectResultFont, FontBrush, locationX, locationY); + }); + } + //画spec信息 + + //if (DetectResult != null && DetectResult.NetResult?.DetectDetails?.Count > 0) + //{ + // DetectResult.NetResult?.DetectDetails.ForEach(d => + // { + // g.DrawRectangle(defectRectPen, d.Rect); + + // string locationTxt = $"{d.Rect.X},{d.Rect.Y}"; + // g.DrawString(locationTxt, defectFont, fontBrush, d.Rect.X, d.Rect.Y - 5); + // }); + //} + + //float fontHeight = g.MeasureString(displayTxt, Font).Height; + //startPoint.Y += fontHeight * 1.2f; + + //var defects = DetectResult.NetResult?.DetectDetails; + //if (defects != null && defects.Count > 0) + //{ + // defects.ForEach(d => + // { + // g.DrawString($"{d.ClassName} X:{d.Rect.X.ToString("f2")} Y:{d.Rect.Y.ToString("f2")} S:{d.Area}", Font, d.FinalResult == EnumHelper.ResultState.OK ? fontBrushOK : fontBrushNG, startPoint); + + // startPoint.Y += fontHeight; + // }); + //} + + //DetectResult.Specs.ForEach(s => + //{ + // g.DrawString($"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}", Font, s.MeasureResult ?? false == true ? fontBrushOK : fontBrushNG, startPoint); + + // startPoint.Y += fontHeight; + //}); + } + + public override string GetDisplayText() + { + return ""; + } + + public override bool IsIntersect(RectangleF rect) + { + return false; + } + + public override bool IsMouseHover(PointF p) + { + return false; + } + + public override bool IsMouseInSide(PointF p) + { + return false; + } + + public override void OnKeyDown(object sender, KeyEventArgs e) + { + } + + public override void OnKeyUp(object sender, KeyEventArgs e) + { + } + + protected override void DrawResult(Graphics g) + { + } + + public override void OnMouseDownWhenNew(PointF p) + { + } + + public override void OnMouseMoveWhenNew(PointF p) + { + } + + public override void OnMouseUpWhenNew(PointF p) + { + } + + public override void Translate(float x, float y) + { + } + } + + public class RectResultDisplay : ElementBase + { + ResultState ResultState = ResultState.DetectNG; + public string DisplayTxt = ""; + Color FillColor = Color.Lime; + int FontSize = 15; + RectangleF Rect = new RectangleF(); + bool IsFilled = false; + + public RectResultDisplay() { } + + public RectResultDisplay(ResultState _resultState, RectangleF _rect, string _displayTxt, Color _fillColor, bool _isFilled, int _fontSize) + { + ResultState = _resultState; + Rect = _rect; + DisplayTxt = _displayTxt; + FillColor = _fillColor; + IsFilled = _isFilled; + FontSize = _fontSize; + } + + public override object Clone() + { + RectResultDisplay rect = new RectResultDisplay(); + + rect.ResultState = ResultState; + rect.Rect = Rect; + rect.DisplayTxt = DisplayTxt; + rect.FillColor = FillColor; + rect.FontSize = FontSize; + rect.IsFilled = IsFilled; + + return rect; + } + + public override void Draw(Graphics g) + { + g.DrawRectangle(new Pen(FillColor, 1), Rect.X, Rect.Y, Rect.Width, Rect.Height); + + if (IsFilled) + { + g.FillRectangle(new SolidBrush(Color.FromArgb(20, FillColor)), Rect); + } + + Font font = new Font("Tahoma", FontSize); + var txtSize = g.MeasureString(DisplayTxt, font); + + g.DrawString(DisplayTxt, font, new SolidBrush(FillColor), (float)(Rect.X + Rect.Width / 2.0 - txtSize.Width / 2.0), Rect.Y + Rect.Height + 5); + } + + public override string GetDisplayText() + { + return $"{ResultState} {DisplayTxt} ({Rect.X},{Rect.Y},{Rect.Width},{Rect.Height})"; + } + + public override bool IsIntersect(RectangleF rect) + { + return rect.IntersectsWith(Rect); + } + + public override bool IsMouseHover(PointF p) + { + return false; + } + + public override bool IsMouseInSide(PointF p) + { + return Rect.Contains(p); + } + + public override void OnKeyDown(object sender, KeyEventArgs e) + { + } + + public override void OnKeyUp(object sender, KeyEventArgs e) + { + } + + public override void OnMouseDownWhenNew(PointF p) + { + } + + public override void OnMouseMoveWhenNew(PointF p) + { + } + + public override void OnMouseUpWhenNew(PointF p) + { + } + + public override void Translate(float x, float y) + { + Rect.Offset(new PointF(x, y)); + } + + protected override void DrawResult(Graphics g) + { + } + } +} diff --git a/DH.UI.Model.Winform/GridCtrl.Designer.cs b/DH.UI.Model.Winform/GridCtrl.Designer.cs new file mode 100644 index 0000000..bfc50ad --- /dev/null +++ b/DH.UI.Model.Winform/GridCtrl.Designer.cs @@ -0,0 +1,109 @@ +namespace XKRS.UI.Model.Winform +{ + partial class GridCtrl + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.chkShowGrid = new System.Windows.Forms.CheckBox(); + this.tbGridValue = new System.Windows.Forms.TrackBar(); + this.panel1 = new System.Windows.Forms.Panel(); + this.colorDialog1 = new System.Windows.Forms.ColorDialog(); + this.btnColor = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // chkShowGrid + // + this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button; + // this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid; + this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top; + this.chkShowGrid.Location = new System.Drawing.Point(0, 0); + this.chkShowGrid.Name = "chkShowGrid"; + this.chkShowGrid.Size = new System.Drawing.Size(32, 30); + this.chkShowGrid.TabIndex = 0; + this.chkShowGrid.UseVisualStyleBackColor = true; + this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged); + // + // tbGridValue + // + this.tbGridValue.AutoSize = false; + this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom; + this.tbGridValue.Location = new System.Drawing.Point(0, 21); + this.tbGridValue.Name = "tbGridValue"; + this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical; + this.tbGridValue.Size = new System.Drawing.Size(32, 121); + this.tbGridValue.TabIndex = 1; + this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both; + this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Controls.Add(this.chkShowGrid); + this.panel1.Controls.Add(this.tbGridValue); + this.panel1.Location = new System.Drawing.Point(1, 1); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(32, 142); + this.panel1.TabIndex = 2; + // + // btnColor + // + this.btnColor.BackColor = System.Drawing.Color.Red; + this.btnColor.Location = new System.Drawing.Point(4, 150); + this.btnColor.Name = "btnColor"; + this.btnColor.Size = new System.Drawing.Size(25, 23); + this.btnColor.TabIndex = 3; + this.btnColor.Text = " "; + this.btnColor.UseVisualStyleBackColor = false; + this.btnColor.Click += new System.EventHandler(this.btnColor_Click); + // + // GridCtrl + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; + this.Controls.Add(this.btnColor); + this.Controls.Add(this.panel1); + this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134))); + this.Name = "GridCtrl"; + this.Size = new System.Drawing.Size(32, 192); + ((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit(); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkShowGrid; + private System.Windows.Forms.TrackBar tbGridValue; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ColorDialog colorDialog1; + private System.Windows.Forms.Button btnColor; + } +} diff --git a/DH.UI.Model.Winform/GridCtrl.cs b/DH.UI.Model.Winform/GridCtrl.cs new file mode 100644 index 0000000..dace442 --- /dev/null +++ b/DH.UI.Model.Winform/GridCtrl.cs @@ -0,0 +1,74 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace XKRS.UI.Model.Winform +{ + public partial class GridCtrl : UserControl + { + public Action IsShowGridChanged { get; set; } + + public Action GridValueChanged { get; set; } + + public Action GridColorChanged { get; set; } + + public GridCtrl() + { + InitializeComponent(); + + IsChecked = chkShowGrid.Checked; + GridValue = tbGridValue.Value; + } + + bool isChecked = false; + bool IsChecked + { + get => isChecked; + set + { + if (isChecked != value) + { + // IsShowGridChanged?.BeginInvoke(value, null, null); + Task.Run(() => IsShowGridChanged.Invoke(value)); + } + + isChecked = value; + } + } + + int gridValue = 0; + int GridValue + { + get => gridValue; + set + { + if (gridValue != value) + { + // GridValueChanged?.BeginInvoke(value, null, null); + Task.Run(() => GridValueChanged.Invoke(value)); + } + + gridValue = value; + } + } + private void chkShowGrid_CheckedChanged(object sender, EventArgs e) + { + IsChecked = chkShowGrid.Checked; + } + + private void tbGridValue_ValueChanged(object sender, EventArgs e) + { + GridValue = tbGridValue.Value; + } + + private void btnColor_Click(object sender, EventArgs e) + { + if (colorDialog1.ShowDialog() == DialogResult.OK) + { + btnColor.BackColor = colorDialog1.Color; + // GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null); + Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor)); + } + } + } +} diff --git a/DH.UI.Model.Winform/GridCtrl.resx b/DH.UI.Model.Winform/GridCtrl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/DH.UI.Model.Winform/GridCtrl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DH.UI.Model.Winform/GridCtrlHost.cs b/DH.UI.Model.Winform/GridCtrlHost.cs new file mode 100644 index 0000000..2f7f79e --- /dev/null +++ b/DH.UI.Model.Winform/GridCtrlHost.cs @@ -0,0 +1,12 @@ +using System.Windows.Forms; + +namespace XKRS.UI.Model.Winform +{ + public class GridCtrlHost : ToolStripControlHost + { + public GridCtrlHost(GridCtrl grid) : base(grid) + { + //Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134); + } + } +} diff --git a/DH.UI.Model.Winform/IOIndicatorCtrl.Designer.cs b/DH.UI.Model.Winform/IOIndicatorCtrl.Designer.cs new file mode 100644 index 0000000..6d83432 --- /dev/null +++ b/DH.UI.Model.Winform/IOIndicatorCtrl.Designer.cs @@ -0,0 +1,78 @@ +namespace XKRS.UI.Model.Winform +{ + partial class IOIndicatorCtrl + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + plStatus = new Panel(); + lblDesc = new Label(); + SuspendLayout(); + // + // plStatus + // + plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + plStatus.Location = new Point(0, 0); + plStatus.Margin = new Padding(4); + plStatus.Name = "plStatus"; + plStatus.Size = new Size(28, 34); + plStatus.TabIndex = 0; + plStatus.Paint += plStatus_Paint; + plStatus.DoubleClick += plStatus_DoubleClick; + // + // lblDesc + // + lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + lblDesc.AutoSize = true; + lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World); + lblDesc.Location = new Point(36, 11); + lblDesc.Margin = new Padding(4, 0, 4, 0); + lblDesc.Name = "lblDesc"; + lblDesc.Size = new Size(31, 13); + lblDesc.TabIndex = 1; + lblDesc.Text = "XXXX"; + lblDesc.TextAlign = ContentAlignment.MiddleLeft; + lblDesc.DoubleClick += lblDesc_DoubleClick; + // + // IOIndicatorCtrl + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(lblDesc); + Controls.Add(plStatus); + Margin = new Padding(4); + Name = "IOIndicatorCtrl"; + Size = new Size(138, 34); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Panel plStatus; + private Label lblDesc; + } +} diff --git a/DH.UI.Model.Winform/IOIndicatorCtrl.cs b/DH.UI.Model.Winform/IOIndicatorCtrl.cs new file mode 100644 index 0000000..bc40ed4 --- /dev/null +++ b/DH.UI.Model.Winform/IOIndicatorCtrl.cs @@ -0,0 +1,126 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace XKRS.UI.Model.Winform +{ + public partial class IOIndicatorCtrl : UserControl + { + public IOIndicatorCtrl() + { + InitializeComponent(); + } + + private bool isON = false; + + public bool IsOn + { + get => isON; + set + { + bool? temp = isON; + isON = value; + + if (temp != isON) + { + RefreshStatus(); + } + } + } + + private void RefreshStatus() + { + if (InvokeRequired) + { + Invoke(new Action(() => RefreshStatus())); + } + else + { + plStatus.Invalidate(); + } + } + + private string desc = ""; + public string Desc + { + get => desc; + set + { + desc = value; + + DisplayDesc(); + } + } + + public int Index { get; set; } + + private void DisplayDesc() + { + if (InvokeRequired) + { + Invoke(new Action(() => DisplayDesc())); + } + else + { + lblDesc.Text = Desc; + } + } + + readonly PointF[] regionBlink = new PointF[] + { + new PointF(5,10), + new PointF(10,13), + new PointF(12,7), + new PointF(10,5) + }; + + public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0) + { + InitializeComponent(); + + IsOn = _isOn; + Desc = _desc; + Index = index; + } + + /// + /// 更新绘制图标 + /// + /// + /// + private void plStatus_Paint(object sender, PaintEventArgs e) + { + Panel pl = sender as Panel; + + Graphics g = e.Graphics; + + g.Clear(SystemColors.Control); + + + if (IsOn) + { + g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle); + } + else + { + g.FillEllipse(Brushes.Gray, pl.ClientRectangle); + } + + g.FillPolygon(Brushes.White, regionBlink); + + } + + public event Action OnIODoubleClick; + + + private void lblDesc_DoubleClick(object sender, EventArgs e) + { + OnIODoubleClick?.Invoke(Name, IsOn, Index); + } + + private void plStatus_DoubleClick(object sender, EventArgs e) + { + OnIODoubleClick?.Invoke(Name, IsOn, Index); + } + } +} diff --git a/DH.UI.Model.Winform/IOIndicatorCtrl.resx b/DH.UI.Model.Winform/IOIndicatorCtrl.resx new file mode 100644 index 0000000..a395bff --- /dev/null +++ b/DH.UI.Model.Winform/IOIndicatorCtrl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DHSoftware.sln b/DHSoftware.sln index 54646c2..a4155f0 100644 --- a/DHSoftware.sln +++ b/DHSoftware.sln @@ -17,8 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commons", "Commons", "{0AB4 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Commons", "DH.Commons\DH.Commons.csproj", "{027373EC-C5CB-4161-8D43-AB6009371FDE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Vision", "DH.Devices.Vision\DH.Devices.Vision.csproj", "{97B55FCF-54A3-449E-8437-735E65C35291}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Camera", "DH.Devices.Camera\DH.Devices.Camera.csproj", "{1378A932-1C25-40EF-BA31-A3463B23F4E5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.PLC", "DH.Devices.PLC\DH.Devices.PLC.csproj", "{458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}" @@ -29,6 +27,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Motion", "DH.Dev EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Commons.Devies", "DH.Commons.Devies\DH.Commons.Devies.csproj", "{A33108B6-2740-4D28-AD22-B280372980BE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.UI.Model.Winform", "DH.UI.Model.Winform\DH.UI.Model.Winform.csproj", "{12CB9041-B1B1-41AE-B308-AABDACAA580E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Vision", "DH.Devices.Vision\DH.Devices.Vision.csproj", "{5AD3A29E-149A-4C37-9548-7638A36C8175}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,14 +57,6 @@ Global {027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|Any CPU.Build.0 = Release|Any CPU {027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|x64.ActiveCfg = Release|x64 {027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|x64.Build.0 = Release|x64 - {97B55FCF-54A3-449E-8437-735E65C35291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97B55FCF-54A3-449E-8437-735E65C35291}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97B55FCF-54A3-449E-8437-735E65C35291}.Debug|x64.ActiveCfg = Debug|x64 - {97B55FCF-54A3-449E-8437-735E65C35291}.Debug|x64.Build.0 = Debug|x64 - {97B55FCF-54A3-449E-8437-735E65C35291}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97B55FCF-54A3-449E-8437-735E65C35291}.Release|Any CPU.Build.0 = Release|Any CPU - {97B55FCF-54A3-449E-8437-735E65C35291}.Release|x64.ActiveCfg = Release|x64 - {97B55FCF-54A3-449E-8437-735E65C35291}.Release|x64.Build.0 = Release|x64 {1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|x64.ActiveCfg = Debug|x64 @@ -93,6 +89,22 @@ Global {A33108B6-2740-4D28-AD22-B280372980BE}.Release|Any CPU.Build.0 = Release|Any CPU {A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.ActiveCfg = Release|X64 {A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.Build.0 = Release|X64 + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|x64.ActiveCfg = Debug|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|x64.Build.0 = Debug|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|Any CPU.Build.0 = Release|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|x64.ActiveCfg = Release|Any CPU + {12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|x64.Build.0 = Release|Any CPU + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|x64.ActiveCfg = Debug|x64 + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|x64.Build.0 = Debug|x64 + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|Any CPU.Build.0 = Release|Any CPU + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.ActiveCfg = Release|x64 + {5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -102,12 +114,13 @@ Global {1591B03B-0015-42FC-B784-0D9F740E2A23} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0} {F77AF94C-280D-44C5-B7C0-FC86AA9EC504} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0} {027373EC-C5CB-4161-8D43-AB6009371FDE} = {0AB4BB9A-A861-4F80-B549-CD331490942B} - {97B55FCF-54A3-449E-8437-735E65C35291} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504} {1378A932-1C25-40EF-BA31-A3463B23F4E5} = {1591B03B-0015-42FC-B784-0D9F740E2A23} {458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D} = {2560C5A5-0CA2-48AD-B606-6C55BEFD8109} {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0} {144E3775-0BD7-4528-9FB0-A0F4ADC74313} = {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} {A33108B6-2740-4D28-AD22-B280372980BE} = {0AB4BB9A-A861-4F80-B549-CD331490942B} + {12CB9041-B1B1-41AE-B308-AABDACAA580E} = {3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C} + {5AD3A29E-149A-4C37-9548-7638A36C8175} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6FC1A8DF-636E-434C-981E-10F20FAD723B} diff --git a/DHSoftware/DHSoftware.csproj b/DHSoftware/DHSoftware.csproj index ebca883..730d9ee 100644 --- a/DHSoftware/DHSoftware.csproj +++ b/DHSoftware/DHSoftware.csproj @@ -21,6 +21,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/DHSoftware/MainWindow.Designer.cs b/DHSoftware/MainWindow.Designer.cs index b2b9275..b6f3a2e 100644 --- a/DHSoftware/MainWindow.Designer.cs +++ b/DHSoftware/MainWindow.Designer.cs @@ -50,7 +50,7 @@ splitContainer1 = new SplitContainer(); splitContainer2 = new SplitContainer(); tabImgDisplay = new AntdUI.Tabs(); - tabPage1 = new AntdUI.TabPage(); + tabMain = new AntdUI.TabPage(); tabsStas = new AntdUI.Tabs(); tabPage3 = new AntdUI.TabPage(); richTextBox1 = new RichTextBox(); @@ -124,6 +124,7 @@ buttonSZ.Radius = 0; buttonSZ.Size = new Size(50, 40); buttonSZ.TabIndex = 0; + buttonSZ.Visible = false; buttonSZ.WaveSize = 0; // // pageHeader1 @@ -142,7 +143,7 @@ // label1 // label1.AutoSize = true; - label1.Location = new Point(709, 10); + label1.Location = new Point(979, 10); label1.Name = "label1"; label1.Size = new Size(64, 21); label1.TabIndex = 1; @@ -240,23 +241,23 @@ // // tabImgDisplay // - tabImgDisplay.Controls.Add(tabPage1); + tabImgDisplay.Controls.Add(tabMain); tabImgDisplay.Dock = DockStyle.Fill; tabImgDisplay.Location = new Point(0, 0); tabImgDisplay.Name = "tabImgDisplay"; - tabImgDisplay.Pages.Add(tabPage1); + tabImgDisplay.Pages.Add(tabMain); tabImgDisplay.Size = new Size(580, 320); tabImgDisplay.Style = styleCard1; tabImgDisplay.TabIndex = 1; tabImgDisplay.Text = "tabs1"; // - // tabPage1 + // tabMain // - tabPage1.Location = new Point(3, 28); - tabPage1.Name = "tabPage1"; - tabPage1.Size = new Size(574, 289); - tabPage1.TabIndex = 0; - tabPage1.Text = "检测"; + tabMain.Location = new Point(3, 28); + tabMain.Name = "tabMain"; + tabMain.Size = new Size(574, 289); + tabMain.TabIndex = 0; + tabMain.Text = "检测"; // // tabsStas // @@ -452,7 +453,7 @@ private SplitContainer splitContainer1; private SplitContainer splitContainer2; private AntdUI.Tabs tabImgDisplay; - private AntdUI.TabPage tabPage1; + private AntdUI.TabPage tabMain; private AntdUI.Tabs tabsStas; private AntdUI.TabPage tabPage3; private RichTextBox richTextBox1; diff --git a/DHSoftware/MainWindow.cs b/DHSoftware/MainWindow.cs index e42539b..92a919d 100644 --- a/DHSoftware/MainWindow.cs +++ b/DHSoftware/MainWindow.cs @@ -26,7 +26,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using XKRS.Common.Model; +using XKRS.UI.Device.Winform; using static AntdUI.Math3D; using Camera = DHSoftware.Models.Camera; @@ -60,8 +60,7 @@ namespace DHSoftware //绑定事件 BindEventHandler(); UserConfigFrm userControlFrm = new UserConfigFrm(); - // tabImgDisplay.Pages.Clear(); - // tabPage2.Controls.Clear(); + userControlFrm.Window = this; userControlFrm.Dock = DockStyle.Fill; tabPage2.Controls.Add(userControlFrm); @@ -278,6 +277,7 @@ namespace DHSoftware public volatile int ProductNum_Total = 0; public volatile int ProductNum_OK = 0; private readonly object _cameraSummaryLock = new object(); + public SimboVisionDriver? _visionEngine = null; List DetectionConfigs = new List(); List SimboStationMLEngineList = new List(); Dictionary HalconToolDict = new Dictionary(); @@ -286,6 +286,8 @@ namespace DHSoftware private void HandleStartButton() { CurrentMachine = true; + + //_visionEngine.Start(); //[Category("深度学习检测配置")] //[DisplayName("检测标签定义集合")] //[Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")] @@ -349,6 +351,8 @@ namespace DHSoftware det1.ModelHeight = 640; det1.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam1.txt"; det1.IsEnabled = true; + det1.ShowLocation.X = 1; + det1.ShowLocation.Y = 1; det2.CameraCollects = CameraCollects2; det2.ModelconfThreshold = Conf; @@ -356,6 +360,8 @@ namespace DHSoftware det2.ModelHeight = 640; det2.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam2.txt"; det2.IsEnabled = true; + det2.ShowLocation.X = 2; + det2.ShowLocation.Y = 1; det3.CameraCollects = CameraCollects3; det3.ModelconfThreshold = Conf; @@ -363,6 +369,8 @@ namespace DHSoftware det3.ModelHeight = 640; det3.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam3.txt"; det3.IsEnabled = true; + det3.ShowLocation.X = 3; + det3.ShowLocation.Y = 1; det4.CameraCollects = CameraCollects4; det4.ModelconfThreshold = Conf; @@ -370,6 +378,8 @@ namespace DHSoftware det4.ModelHeight = 640; det4.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam4.txt"; det4.IsEnabled = true; + det4.ShowLocation.X = 4; + det4.ShowLocation.Y = 1; @@ -379,6 +389,8 @@ namespace DHSoftware det5.ModelHeight = 640; det5.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam5.txt"; det5.IsEnabled = true; + det5.ShowLocation.X = 1; + det5.ShowLocation.Y = 2; det6.CameraCollects = CameraCollects6; det6.ModelconfThreshold = Conf; @@ -386,6 +398,8 @@ namespace DHSoftware det6.ModelHeight = 640; det6.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam6.txt"; det6.IsEnabled = true; + det6.ShowLocation.X = 2; + det6.ShowLocation.Y = 2; det7.CameraCollects = CameraCollects7; det7.ModelconfThreshold = Conf; @@ -393,6 +407,8 @@ namespace DHSoftware det7.ModelHeight = 640; det7.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam7.txt"; det7.IsEnabled = true; + det7.ShowLocation.X = 3; + det7.ShowLocation.Y = 2; det8.CameraCollects = CameraCollects8; det8.ModelconfThreshold = Conf; @@ -400,6 +416,8 @@ namespace DHSoftware det8.ModelHeight = 640; det8.in_lable_path = "D:\\PROJECTS\\X015\\Vision\\Cam8.txt"; det8.IsEnabled = true; + det8.ShowLocation.X = 4; + det8.ShowLocation.Y = 2; DetectionConfigs.Add(det1); DetectionConfigs.Add(det2); @@ -452,7 +470,7 @@ namespace DHSoftware cam.CameraName = $"Cam{i}"; Cameras.Add(cam); cam.CameraConnect(); - // cam.OnHImageOutput += OnCameraHImageOutput; + cam.OnHImageOutput += OnCameraHImageOutput; } @@ -485,20 +503,25 @@ namespace DHSoftware + _visionEngine = new SimboVisionDriver(); + _visionEngine.DetectionConfigs = DetectionConfigs; + _visionEngine.Init(); + CtrlVisionRunBase ctrlVisionRun = new CtrlVisionRunBase(_visionEngine); + tabImgDisplay.Controls.Add(ctrlVisionRun); //Add the code for the "启动" button click here - //初始化Halcon工具 - InitialHalconTools(); + ////初始化Halcon工具 + //InitialHalconTools(); - //深度学习模型加载 - bool resultOK = InitialSimboMLEnginesAsync(); - if (resultOK) - { - //初始化失败 - // return; - } + ////深度学习模型加载 + //bool resultOK = InitialSimboMLEnginesAsync(); + //if (resultOK) + //{ + // //初始化失败 + // // return; + //} //位置比较卡 sLDMotion.AxisSettings = new List(); @@ -658,788 +681,261 @@ namespace DHSoftware }); } /// - /// 初始化深度学习工具 - /// - private bool InitialSimboMLEnginesAsync() - { - //深度学习 模型加载 - var resultOK = MLLoadModel(); - return resultOK; - } - /// - /// 深度学习 模型加载 - /// - /// - private bool MLLoadModel() - { - bool resultOK = false; - try - { - SimboStationMLEngineList = new List(); - // _cameraRelatedDetectionDict = IConfig.DetectionConfigs.Select(t => t.ModelPath).Distinct().ToList(); - DetectionConfigs.ForEach(dc => - //_cameraRelatedDetectionDict.ForEach(dc => - { - - if (dc.IsEnabled && !string.IsNullOrWhiteSpace(dc.ModelPath)) - { - if (dc.IsEnableGPU) - { - //if (IIConfig.IsLockGPU) - //{ - //foreach (var validGPU in ValidGPUList2) - //{ - // if (validGPU.DetectionIds.Contains(dc.Id)) - // { - var engine = SingleMLLoadModel(dc, true, 0); - SimboStationMLEngineList.Add(engine); - // } - //} - //} - //else - //{ - // foreach (var validGPU in ValidGPUList) - // { - // //var validGPU = ValidGPUList.FirstOrDefault(u => u.DetectionIds.Contains(dc.Id)); - // if (validGPU.DetectionId == dc.Id) - // { - // var engine = SingleMLLoadModel(dc, true, validGPU.GPUNo); - // SimboStationMLEngineList.Add(engine); - // } - // } - //} - - } - else - { - //for (int i = 0; i < IConfig.CPUNums; i++) - for (int i = 0; i < 1; i++) - { - //var engine = SingleMLLoadModel(dc, false, i); - var engine = SingleMLLoadModel(dc, false, i); - SimboStationMLEngineList.Add(engine); - } - } - } - }); - resultOK = true; - } - catch (Exception ex) - { - // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:模型并发加载异常:{ex.GetExceptionMessage()}"); - resultOK = false; - } - - return resultOK; - } - /// - /// 单个模型加载 - /// - /// - /// - /// - private SimboStationMLEngineSet SingleMLLoadModel(DetectionConfig dc, bool isGPU, int coreInx) - { - SimboStationMLEngineSet mLEngineSet = new SimboStationMLEngineSet(); - try - { - mLEngineSet.IsUseGPU = isGPU; - if (isGPU) - { - mLEngineSet.GPUNo = coreInx; - } - else - { - mLEngineSet.CPUNo = coreInx; - } - mLEngineSet.DetectionId = dc.Id; - mLEngineSet.DetectionName = dc.Name; - - if (!string.IsNullOrWhiteSpace(dc.ModelPath)) - { - // 根据算法类型创建不同的实例 - switch (dc.ModelType) - { - case MLModelType.ImageClassification: - break; - case MLModelType.ObjectDetection: - mLEngineSet.StationMLEngine = new SimboObjectDetection(); - break; - case MLModelType.SemanticSegmentation: - - break; - case MLModelType.InstanceSegmentation: - mLEngineSet.StationMLEngine = new SimboInstanceSegmentation(); - break; - case MLModelType.ObjectGPUDetection: - mLEngineSet.StationMLEngine = new SimboDetection(); - break; - default: - break; - } - MLInit mLInit; - string inferenceDevice = "CPU"; - if (dc.IsEnableGPU) - { - inferenceDevice = "GPU"; - mLInit = new MLInit(dc.ModelPath, isGPU, coreInx, dc.ModelconfThreshold); - } - else - { - mLInit = new MLInit(dc.ModelPath, "images", inferenceDevice, (int)dc.ModelWidth, (int)dc.ModelHeight); - - } - - bool isSuccess = mLEngineSet.StationMLEngine.Load(mLInit); - if (!isSuccess) - { - // throw new ProcessException("异常:模型加载异常", null); - } - //LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}"); - } - } - catch (Exception ex) - { - //throw new ProcessException($"异常:是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}"); - } - return mLEngineSet; - } - private void InitialHalconTools() - { - HOperatorSet.SetSystem("parallelize_operators", "true"); - HOperatorSet.SetSystem("reentrant", "true"); - HOperatorSet.SetSystem("global_mem_cache", "exclusive"); - - HalconToolDict = new Dictionary(); - - DetectionConfigs.ForEach(c => - { - if (!c.IsEnabled) - return; - - if (c.HalconAlgorithemPath_Pre != null) - LoadHalconTool(c.HalconAlgorithemPath_Pre); - - }); - } - - private void LoadHalconTool(string path) - { - if (!HalconToolDict.ContainsKey(path)) - { - - - string algorithemPath = path; - - if (string.IsNullOrWhiteSpace(algorithemPath)) - return; - - string directoryPath = Path.GetDirectoryName(algorithemPath); - string fileName = Path.GetFileNameWithoutExtension(algorithemPath); - - HDevEngineTool tool = new HDevEngineTool(directoryPath); - tool.LoadProcedure(fileName); - - HalconToolDict[path] = tool; - } - } - - /// - /// 预处理 - /// - /// - /// - public void PreTreated(DetectionConfig detectConfig, DetectStationResult detectResult, Mat MhImage) - { - try - { - // detectResult.VisionImageSet.DetectionOriginImage = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); - //detectResult.VisionImageSet.PreTreatedBitmap = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap(); - //detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.PreTreatedBitmap?.CopyBitmap(); - if (!string.IsNullOrWhiteSpace(detectConfig.HalconAlgorithemPath_Pre)) - { - HObject obj = OpenCVHelper.MatToHImage(MhImage); - HImage hImage = HalconHelper.ConvertHObjectToHImage(obj); - string toolKey = detectConfig.HalconAlgorithemPath_Pre; - if (!HalconToolDict.ContainsKey(toolKey)) - { - // LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}未获取预处理算法"); - return; - } - //Mean_Thre Deviation_Thre Mean_standard Deviation_standard - var tool = HalconToolDict[toolKey]; - - ////tool.InputTupleDic["Mean_Thre"] = 123; - for (int i = 0; i < detectConfig.PreTreatParams.Count; i++) - { - var param = detectConfig.PreTreatParams[i]; - tool.InputTupleDic[param.Name] = double.Parse(param.Value); - } - - // tool.InputTupleDic["fCricularity"] = 200; - - tool.InputImageDic["INPUT_Image"] = hImage; - - - if (!tool.RunProcedure(out string errorMsg, out _)) - { - // detectResult.PreTreatedFlag = false; - - detectResult.IsPreTreatDone = false; - - - return; - } - - var preTreatRet = tool.GetResultTuple("OUTPUT_Flag").I; - - //var fRCricularity = tool.GetResultTuple("fRCricularity"); - - - // detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = preTreatRet == 1; - //detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true; - // detectResult.VisionImageSet.PreTreatedTime = DateTime.Now; - - for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++) - { - var param = detectConfig.OUTPreTreatParams[i]; - tool.InputTupleDic[param.Name] = double.Parse(param.Value); - } - - - - - // 2023/10/16 新增预处理结果反馈,如果预处理结果为NG,直接返回 - if (preTreatRet != 0) - { - detectResult.ResultState = ResultState.DetectNG; - - detectResult.IsPreTreatNG = true; - - - - // if (detectResult.VisionImageSet.PreTreatedFlag) - { - //detectResult.VisionImageSet.MLImage = tool.GetResultObject("OUTPUT_PreTreatedImage"); - //DetectionResultImage - // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); - - } - - } - else - { - // detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap(); - - } - } - } - catch (Exception ex) - { - - } - finally - { - //detectResult.VisionImageSet.HImage?.Dispose(); - //detectResult.VisionImageSet.HImage = null; - // MhImage?.Dispose(); - //MhImage = null; - } - - } - /// /// 相机回调 /// /// /// /// - //private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) - //{ - - // //if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase)) - // //{ - // // Console.WriteLine(); - // //} - // //if (camera.CameraName.Equals("cam2", StringComparison.OrdinalIgnoreCase)) - // //{ - // // Console.WriteLine(); - // //} - - // // 获取该相机的拍照计数 - // uint productNumber = (uint)camera.SnapshotCount; - - // Task.Run(async () => - // { - // using (Mat localImageSet = imageSet.Clone()) // 复制 Mat 避免并发问题 - // { - // // imageSet?.Dispose(); - // // 拍照计数与物件编号一致,查找对应的产品 - // ProductData product = null; - // //内外壁模组多个相机的处理方法 - // //计算队列的方法不变 - // int index = PieceNumberToIndex(productNumber); - // // 找到产品存放在哪个队列里 - // ConcurrentDictionary tmpDic = _productLists[index]; - - // try - // { - // int retryTimes = 100; - // while (product == null && retryTimes > 0) - // { - // if (tmpDic.ContainsKey(productNumber)) - // { - // product = tmpDic[productNumber]; - // } - // else - // { - // // Thread.Sleep(20); - // await Task.Delay(20); - // } - // retryTimes--; - // } - // // 如果产品为空,则销毁图片,提示错误 - // if (null == product) - // { - // List pnList = tmpDic.Keys.ToList(); - - // string pnStr = ""; - // if (pnList != null && pnList.Count > 0) - // { - // pnStr = string.Join(",", pnList); - // } - - // //LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}"); - // localImageSet.Dispose(); - // this.BeginInvoke(new MethodInvoker(delegate () - // { - - // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - - // richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName); - - // // 设置回原来的滚动位置 - // richTextBox1.SelectionStart = richTextBox1.TextLength; - // richTextBox1.ScrollToCaret(); - // })); - // //重新生成实例 销毁之前的实例 - - // using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) - // { - // sw.WriteLine(productNumber + "提前推出" + camera.CameraName); - // } - // return; - // } - - // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}"); - - // if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName)) - // { - - // localImageSet.Dispose(); - // this.BeginInvoke(new MethodInvoker(delegate () - // { - - // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - - // richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName); - - // // 设置回原来的滚动位置 - // richTextBox1.SelectionStart = richTextBox1.TextLength; - // richTextBox1.ScrollToCaret(); - // })); - // //重新生成实例 销毁之前的实例 - - // using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) - // { - // sw.WriteLine(productNumber + "提前推出" + camera.CameraName); - // } - // // LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理1"); - - // return; - // } - - - // double totalTime = 0.0; - // List resultStates = new List(); - // List? detectionDict = _cameraRelatedDetectionDict[camera.CameraName]; - - - // for (int i = 0; i < detectionDict.Count; i++) - // { - // string detectionId = detectionDict[i]; - - // DetectionConfig detectConfig = null; - // //找到对应的配置 - // if (!string.IsNullOrWhiteSpace(detectionId)) - // { - // detectConfig = DetectionConfigs.FirstOrDefault(u => u.Id == detectionId); - // } - // else - // { - // detectConfig = DetectionConfigs.FirstOrDefault(u => u.CameraSourceId == camera.CameraName); - // } + private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet) + { + + //if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase)) + //{ + // Console.WriteLine(); + //} + //if (camera.CameraName.Equals("cam2", StringComparison.OrdinalIgnoreCase)) + //{ + // Console.WriteLine(); + //} + + // 获取该相机的拍照计数 + uint productNumber = (uint)camera.SnapshotCount; + + Task.Run(async () => + { + using (Mat localImageSet = imageSet.Clone()) // 复制 Mat 避免并发问题 + { + // imageSet?.Dispose(); + // 拍照计数与物件编号一致,查找对应的产品 + ProductData product = null; + //内外壁模组多个相机的处理方法 + //计算队列的方法不变 + int index = PieceNumberToIndex(productNumber); + // 找到产品存放在哪个队列里 + ConcurrentDictionary tmpDic = _productLists[index]; + + try + { + int retryTimes = 100; + while (product == null && retryTimes > 0) + { + if (tmpDic.ContainsKey(productNumber)) + { + product = tmpDic[productNumber]; + } + else + { + // Thread.Sleep(20); + await Task.Delay(20); + } + retryTimes--; + } + // 如果产品为空,则销毁图片,提示错误 + if (null == product) + { + List pnList = tmpDic.Keys.ToList(); + + string pnStr = ""; + if (pnList != null && pnList.Count > 0) + { + pnStr = string.Join(",", pnList); + } + + //LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}"); + localImageSet.Dispose(); + this.BeginInvoke(new MethodInvoker(delegate () + { + + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; + + richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName); + + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + //重新生成实例 销毁之前的实例 - // if (detectConfig == null) - // { + using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) + { + sw.WriteLine(productNumber + "提前推出" + camera.CameraName); + } + return; + } - // //未能获得检测配置 - // return; - // } + // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}"); - // // 1. 预处理 - // using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 - // { - // DetectStationResult detectResult = new DetectStationResult(); - // #region 1.预处理 + if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName)) + { - // using (Mat PreTMat = inferenceImage.Clone()) - // { - // PreTreated(detectConfig, detectResult, PreTMat); - // } + localImageSet.Dispose(); + this.BeginInvoke(new MethodInvoker(delegate () + { + + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; + + richTextBox1.AppendText(productNumber + "提前推出" + camera.CameraName); + + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + //重新生成实例 销毁之前的实例 + + using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) + { + sw.WriteLine(productNumber + "提前推出" + camera.CameraName); + } + // LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.Name} 找到产品{productNumber},但是没有推理1"); + + return; + } + + + double totalTime = 0.0; + List resultStates = new List(); + List? detectionDict = _cameraRelatedDetectionDict[camera.CameraName]; + + + for (int i = 0; i < detectionDict.Count; i++) + { + string detectionId = detectionDict[i]; + + + + + + // 1. 预处理 + using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本 + { + DetectStationResult temp1=_visionEngine.RunInference(inferenceImage, detectionId); + + resultStates.Add(temp1.ResultState); + + product.ResultCollection.Add(temp1); + + + } + + + } + + product.InferenceOne(); + + // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}"); + + if (!product.InferenceFinished()) + { + return; + } + ProductNum_Total++; + CalculateOEE(); + this.BeginInvoke(new MethodInvoker(delegate () + { + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - // #endregion - // if (detectResult.IsPreTreatNG) - // { - // detectResult.ResultState = ResultState.DetectNG; - // detectResult.IsPreTreatDone = true; - // detectResult.IsMLDetectDone = false; + richTextBox1.AppendText($"统计结果成功,{productNumber} 吹气!\n"); - // } + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + #region 6. 统计产品结果 + product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK) + ? ResultState.B_NG + : ResultState.OK; + product.ProductLabelCategory = product.ProductResult.GetEnumDescription(); + product.ProductLabel = product.ProductResult.GetEnumDescription(); + #endregion + #region 7.产品吹气 + #endregion - // if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath) && detectConfig.IsEnabled) - // { - // SimboStationMLEngineSet mlSet = null; - // mlSet = SimboStationMLEngineList.FirstOrDefault(t => t.DetectionId == detectConfig.Id); - // if (mlSet == null) - // { - // // LogAsync(DateTime.Now, LogLevel.Exception, $"异常:{detectConfig.Name}未能获取对应配置的模型检测工具"); - // detectResult.IsMLDetectDone = false; - // //HandleDetectDone(detectResult, detectConfig); - // return; - // } + // 出列 + ProductData temp = null; - // #region 2.深度学习推理 - // //LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行"); + int tryTimes = 10; + while (temp == null && tryTimes > 0) + { + if (tmpDic.TryRemove(productNumber, out temp)) + { + break; + } - // if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath)) - // { - // Stopwatch mlWatch = new Stopwatch(); - // var req = new MLRequest(); - // //之前的检测图片都是相机存储成HImage + tryTimes--; + Thread.Sleep(5); + } + if (temp == null) + { + string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," + + $"当前队列产品数量:{tmpDic.Count}"; + this.BeginInvoke(new MethodInvoker(delegate () + { + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - // req.ResizeWidth = (int)detectConfig.ModelWidth; - // req.ResizeHeight = (int)detectConfig.ModelHeight; - // // req.LabelNames = detectConfig.GetLabelNames(); - // // req.Score = IIConfig.Score; - // req.mImage = inferenceImage.Clone(); + richTextBox1.AppendText(logStr); - // req.in_lable_path = detectConfig.in_lable_path; + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + } + else + { + try + { + string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," + + $"产品结果:{temp.ProductResult.GetEnumDescription()}," + + $"当前队列产品数量:{tmpDic.Count}"; + this.BeginInvoke(new MethodInvoker(delegate () + { - // req.confThreshold = detectConfig.ModelconfThreshold; - // req.iouThreshold = 0.3f; - // req.segmentWidth = 320; - // req.out_node_name = "output0"; - // switch (detectConfig.ModelType) - // { - // case MLModelType.ImageClassification: - // break; - // case MLModelType.ObjectDetection: + int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - // break; - // case MLModelType.SemanticSegmentation: - // break; - // case MLModelType.InstanceSegmentation: - // break; - // case MLModelType.ObjectGPUDetection: - - // break; - // default: - // break; - // } + richTextBox1.AppendText(logStr); - // // LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN"); - // mlWatch.Start(); - // //20230802改成多线程推理 RunInferenceFixed - - // var result = mlSet.StationMLEngine.RunInference(req); - // // var result = mlSet.StationMLEngine.RunInferenceFixed(req); - // mlWatch.Stop(); - // // LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference END"); + // 设置回原来的滚动位置 + richTextBox1.SelectionStart = richTextBox1.TextLength; + richTextBox1.ScrollToCaret(); + })); + //重新生成实例 销毁之前的实例 + var saveData = temp.GetProductData(); + using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) + { + sw.WriteLine(logStr); + } - - - - - - // // var req = new MLRequest(); - - // //req.mImage = inferenceImage; - - // //req.ResizeWidth = detectConfig.ModelWidth; - // //req.ResizeHeight = detectConfig.ModelHeight; - // //req.confThreshold = detectConfig.ModelconfThreshold; - // //req.iouThreshold = 0.3f; - // //req.out_node_name = "output0"; - // //req.in_lable_path = detectConfig.in_lable_path; - - // //Stopwatch sw = Stopwatch.StartNew(); - // //var result = Dectection[detectionId].RunInference(req); - // //sw.Stop(); - // //LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms"); - - // this.BeginInvoke(new MethodInvoker(delegate () - // { - // // pictureBox1.Image?.Dispose(); // 释放旧图像 - // // pictureBox1.Image = result.ResultMap; - // richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess}相机名字{camera.CameraName} 耗时 {mlWatch.ElapsedMilliseconds}ms\n"); - // })); - // req.mImage?.Dispose(); - - - - - // if (result == null || (result != null && !result.IsSuccess)) - // { - // detectResult.IsMLDetectDone = false; - // } - // if (result != null && result.IsSuccess) - // { - // detectResult.DetectDetails = result.ResultDetails; - // if (detectResult.DetectDetails != null) - // { - // } - // else - // { - // detectResult.IsMLDetectDone = false; - // } - // } - // } - // #endregion - - - - // #region 3.后处理 - // #endregion - // //根据那些得分大于阈值的推理结果,判断产品是否成功 - // #region 4.最终过滤(逻辑过滤) - // detectResult.DetectDetails?.ForEach(d => - // { - - - // //当前检测项的 过滤条件 - // //var conditionList = detectConfig.DetectionFilterList - // // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) - // // .GroupBy(u => u.ResultState) - // // .OrderBy(u => u.Key) - // // .ToList(); - // //当前检测项的 过滤条件 - // var conditionList = detectConfig.DetectionFilterList - // .Where(u => u.IsEnabled && u.LabelName == d.LabelName) - // .GroupBy(u => u.ResultState) - // .OrderBy(u => u.Key) - // .ToList(); - - // if (conditionList.Count == 0) - // { - - // d.FinalResult = d.LabelName.ToLower() == "ok" - // ? ResultState.OK - // : ResultState.DetectNG; - // } - // else - // { - // d.FinalResult = detectConfig.IsMixModel - // ? ResultState.A_NG - // : ResultState.OK; - - - // } - - - // foreach (IGrouping group in conditionList) - // { - // //bool b = group.ToList().Any(f => - // //{ - // // return f.FilterOperation(d); - // //}); - - - // //if (b) - // //{ - // // d.FinalResult = group.Key; - // // break; - // //} - - // if (group.Any(f => f.FilterOperation(d))) - // { - // d.FinalResult = group.Key; - // break; - // } - // //else - // //{ - // // d.FinalResult = d.InferenceResult = ResultState.OK; - // //} - // } - // }); - // #endregion - // #region 5.统计缺陷过滤结果或预处理直接NG - // //if (detectResult.DetectDetails?.Count > 0) - // //{ - // // detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult; - // // detectResult.ResultLabel = detectResult.ResultLabel; - // // detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 - - - // //} - // detectResult.ResultState = detectResult.DetectDetails? - // .GroupBy(u => u.FinalResult) - // .OrderBy(u => u.Key) - // .FirstOrDefault()?.Key ?? ResultState.OK; - // detectResult.ResultLabel = detectResult.ResultLabel; - // detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级 - // #endregion - - // resultStates.Add(detectResult.ResultState); - - // product.ResultCollection.Add(detectResult); - - - - - - - // } - - - // } - - - // } - - // product.InferenceOne(); - - // // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}"); - - // if (!product.InferenceFinished()) - // { - - // return; - // } - // ProductNum_Total++; - // CalculateOEE(); - // this.BeginInvoke(new MethodInvoker(delegate () - // { - - // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - - // richTextBox1.AppendText($"统计结果成功,{productNumber} 吹气!\n"); - - // // 设置回原来的滚动位置 - // richTextBox1.SelectionStart = richTextBox1.TextLength; - // richTextBox1.ScrollToCaret(); - // })); - // #region 6. 统计产品结果 - // product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK) - // ? ResultState.B_NG - // : ResultState.OK; - // product.ProductLabelCategory = product.ProductResult.GetEnumDescription(); - // product.ProductLabel = product.ProductResult.GetEnumDescription(); - // #endregion - // #region 7.产品吹气 - - // #endregion - - - - - - // // 出列 - // ProductData temp = null; - - // int tryTimes = 10; - // while (temp == null && tryTimes > 0) - // { - // if (tmpDic.TryRemove(productNumber, out temp)) - // { - // break; - // } - - // tryTimes--; - // Thread.Sleep(5); - // } - // if (temp == null) - // { - // string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," + - // $"当前队列产品数量:{tmpDic.Count}"; - // this.BeginInvoke(new MethodInvoker(delegate () - // { - - // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - - // richTextBox1.AppendText(logStr); - - // // 设置回原来的滚动位置 - // richTextBox1.SelectionStart = richTextBox1.TextLength; - // richTextBox1.ScrollToCaret(); - // })); - // } - // else - // { - // try - // { - // string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," + - // $"产品结果:{temp.ProductResult.GetEnumDescription()}," + - // $"当前队列产品数量:{tmpDic.Count}"; - // this.BeginInvoke(new MethodInvoker(delegate () - // { - - // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y; - - // richTextBox1.AppendText(logStr); - - // // 设置回原来的滚动位置 - // richTextBox1.SelectionStart = richTextBox1.TextLength; - // richTextBox1.ScrollToCaret(); - // })); - // //重新生成实例 销毁之前的实例 - // var saveData = temp.GetProductData(); - // using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8)) - // { - // sw.WriteLine(logStr); - // } - - // } - // catch (Exception) { } - // finally - // { - // // temp.Dispose(); - // temp = null; - // } - // } - - // // UpdateCT((float)(dtNow - _ctTime).TotalSeconds); - // //_ctTime = dtNow; - // // }); - - - // } - // catch (Exception ex) - // { - // //LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}"); - // product?.Dispose(); - // } - // } - - // }); - //} + } + catch (Exception) { } + finally + { + // temp.Dispose(); + temp = null; + } + } + + // UpdateCT((float)(dtNow - _ctTime).TotalSeconds); + //_ctTime = dtNow; + // }); + + + } + catch (Exception ex) + { + //LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}"); + product?.Dispose(); + } + } + + }); + } public void SetResult() diff --git a/DHSoftware/MainWindow.resx b/DHSoftware/MainWindow.resx index 3511979..1e30dff 100644 --- a/DHSoftware/MainWindow.resx +++ b/DHSoftware/MainWindow.resx @@ -1,7 +1,7 @@  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 44, 19 + + \ No newline at end of file diff --git a/DHSoftware/Views/CtrlVisionRunBase.Designer.cs b/DHSoftware/Views/CtrlVisionRunBase.Designer.cs new file mode 100644 index 0000000..409aba4 --- /dev/null +++ b/DHSoftware/Views/CtrlVisionRunBase.Designer.cs @@ -0,0 +1,174 @@ + +namespace XKRS.UI.Device.Winform +{ + partial class CtrlVisionRunBase + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.tableDisplay = new System.Windows.Forms.TableLayoutPanel(); + this.tlpOpConfig = new System.Windows.Forms.TableLayoutPanel(); + this.propOpConfig = new System.Windows.Forms.PropertyGrid(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.btnExecuteOpConfig = new System.Windows.Forms.Button(); + this.btnBatchRun = new System.Windows.Forms.Button(); + this.splitCMain = new System.Windows.Forms.SplitContainer(); + this.tlpOpConfig.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitCMain)).BeginInit(); + this.splitCMain.Panel1.SuspendLayout(); + this.splitCMain.Panel2.SuspendLayout(); + this.splitCMain.SuspendLayout(); + this.SuspendLayout(); + // + // tableDisplay + // + this.tableDisplay.ColumnCount = 2; + this.tableDisplay.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableDisplay.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableDisplay.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableDisplay.Location = new System.Drawing.Point(0, 0); + this.tableDisplay.Name = "tableDisplay"; + this.tableDisplay.RowCount = 2; + this.tableDisplay.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableDisplay.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableDisplay.Size = new System.Drawing.Size(769, 251); + this.tableDisplay.TabIndex = 0; + // + // tlpOpConfig + // + this.tlpOpConfig.ColumnCount = 1; + this.tlpOpConfig.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tlpOpConfig.Controls.Add(this.propOpConfig, 0, 1); + this.tlpOpConfig.Controls.Add(this.flowLayoutPanel1, 0, 0); + this.tlpOpConfig.Dock = System.Windows.Forms.DockStyle.Fill; + this.tlpOpConfig.Location = new System.Drawing.Point(0, 0); + this.tlpOpConfig.Name = "tlpOpConfig"; + this.tlpOpConfig.RowCount = 2; + this.tlpOpConfig.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F)); + this.tlpOpConfig.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tlpOpConfig.Size = new System.Drawing.Size(769, 247); + this.tlpOpConfig.TabIndex = 0; + // + // propOpConfig + // + this.propOpConfig.Dock = System.Windows.Forms.DockStyle.Fill; + this.propOpConfig.Location = new System.Drawing.Point(3, 38); + this.propOpConfig.Name = "propOpConfig"; + this.propOpConfig.Size = new System.Drawing.Size(763, 206); + this.propOpConfig.TabIndex = 1; + this.propOpConfig.ToolbarVisible = false; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Controls.Add(this.btnExecuteOpConfig); + this.flowLayoutPanel1.Controls.Add(this.btnBatchRun); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(769, 35); + this.flowLayoutPanel1.TabIndex = 2; + // + // btnExecuteOpConfig + // + this.btnExecuteOpConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnExecuteOpConfig.BackColor = System.Drawing.SystemColors.GradientActiveCaption; + this.btnExecuteOpConfig.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnExecuteOpConfig.Font = new System.Drawing.Font("微软雅黑", 12F); + this.btnExecuteOpConfig.Location = new System.Drawing.Point(598, 3); + this.btnExecuteOpConfig.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3); + this.btnExecuteOpConfig.MinimumSize = new System.Drawing.Size(1, 1); + this.btnExecuteOpConfig.Name = "btnExecuteOpConfig"; + this.btnExecuteOpConfig.Size = new System.Drawing.Size(166, 30); + this.btnExecuteOpConfig.TabIndex = 0; + this.btnExecuteOpConfig.Text = "执行当前配置操作"; + this.btnExecuteOpConfig.UseVisualStyleBackColor = false; + // this.btnExecuteOpConfig.Click += new System.EventHandler(this.btnExecuteOpConfig_Click); + // + // btnBatchRun + // + this.btnBatchRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnBatchRun.BackColor = System.Drawing.SystemColors.Info; + this.btnBatchRun.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnBatchRun.Font = new System.Drawing.Font("微软雅黑", 12F); + this.btnBatchRun.Location = new System.Drawing.Point(488, 3); + this.btnBatchRun.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3); + this.btnBatchRun.MinimumSize = new System.Drawing.Size(1, 1); + this.btnBatchRun.Name = "btnBatchRun"; + this.btnBatchRun.Size = new System.Drawing.Size(100, 30); + this.btnBatchRun.TabIndex = 0; + this.btnBatchRun.Text = "批量检测"; + this.btnBatchRun.UseVisualStyleBackColor = false; + // this.btnBatchRun.Click += new System.EventHandler(this.btnBatchRun_Click); + // + // splitCMain + // + this.splitCMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitCMain.Location = new System.Drawing.Point(0, 0); + this.splitCMain.Name = "splitCMain"; + this.splitCMain.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitCMain.Panel1 + // + this.splitCMain.Panel1.Controls.Add(this.tableDisplay); + // + // splitCMain.Panel2 + // + this.splitCMain.Panel2.Controls.Add(this.tlpOpConfig); + this.splitCMain.Size = new System.Drawing.Size(769, 502); + this.splitCMain.SplitterDistance = 251; + this.splitCMain.TabIndex = 2; + // + // CtrlVisionRunBase + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.splitCMain); + this.Name = "CtrlVisionRunBase"; + this.Size = new System.Drawing.Size(769, 502); + this.tlpOpConfig.ResumeLayout(false); + this.flowLayoutPanel1.ResumeLayout(false); + this.splitCMain.Panel1.ResumeLayout(false); + this.splitCMain.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitCMain)).EndInit(); + this.splitCMain.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableDisplay; + private System.Windows.Forms.TableLayoutPanel tlpOpConfig; + private System.Windows.Forms.Button btnExecuteOpConfig; + private System.Windows.Forms.PropertyGrid propOpConfig; + private System.Windows.Forms.SplitContainer splitCMain; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button btnBatchRun; + } +} diff --git a/DHSoftware/Views/CtrlVisionRunBase.cs b/DHSoftware/Views/CtrlVisionRunBase.cs new file mode 100644 index 0000000..f762271 --- /dev/null +++ b/DHSoftware/Views/CtrlVisionRunBase.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +using System.IO; +using DH.Commons.Enums; +using DH.Devices.Devices; + + +namespace XKRS.UI.Device.Winform +{ + public partial class CtrlVisionRunBase : UserControl + { + + private DateTime LastDisplayTime = DateTime.MinValue; + + + //public CtrlVisionRunBase() + //{ + // InitializeComponent(); + //} + + //private object OnUpdateBatchNO(ISubscriber arg1, object arg2, object arg3) + //{ + // //获取BatchNO + // if (arg2 is string batchNo) + // { + // ML.BatchNO = string.IsNullOrEmpty(batchNo) ? "OFFline_" + DateTime.Now.ToString("yyyyMMdd") : batchNo; + // } + // return null; + //} + + public CtrlVisionRunBase(VisionEngineBase device) + { + InitializeComponent(); + + Device = device; + InitialLayout(); + + this.Load += (s, e) => + { + ML.OnDetectionDone -= ML_OnDetectionDone; + ML.OnDetectionDone += ML_OnDetectionDone; + }; + + // PubSubCenter.GetInstance().RemoveSubscribers(PubSubCenterMessageType.UpdateBatchNO.ToString()); + // PubSubCenter.GetInstance().Subscribe(PubSubCenterMessageType.UpdateBatchNO.ToString(), OnUpdateBatchNO); + } + + + + + private async void ML_OnDetectionDone(string detectionId, Bitmap image, List detectionResults) + { + + await Task.Run(() => + { + if (!this.IsHandleCreated) + return; + + this.Invoke(new Action(() => + { + if (this.IsDisposed) + return; + var display = displayList.FirstOrDefault(u => u.DetectionId == detectionId); + if (display != null) + { + display.RefreshDetectionResult(image, detectionResults); + } + })); + }); + } + + public VisionEngineBase Device { get; set; } + + protected VisionEngineBase ML + { + get => Device as VisionEngineBase; + } + + //VisionEngineInitialConfigBase IConfig => ML?.InitialConfig as VisionEngineInitialConfigBase; + + //VisionEngineOperationConfigBase OpConfig = new VisionEngineOperationConfigBase(); + + //private void btnExecuteOpConfig_Click(object sender, EventArgs e) + //{ + // try + // { + // PubSubCenter.GetInstance().Publish(PubSubCenterMessageType.RequestBatchNO.ToString(), null, null); + // var msg = ML.RunWrap(OpConfig); + + // if (msg.Result != 1) + // { + // MessageBox.Show(msg.Message); + // } + // } + // catch (Exception ex) + // { + // MessageBox.Show(ex.GetExceptionMessage()); + // } + //} + + #region Layout + int rows = 1; + int cols = 1; + + public int Rows + { + get => rows; + set + { + if (value <= 1) + { + rows = 1; + } + else + { + rows = value; + } + } + } + + public int Cols + { + get => cols; + set + { + if (value <= 1) + { + cols = 1; + } + else + { + cols = value; + } + } + } + + List displayList = null; + + private void InitialLayout() + { + if (ML.DetectionConfigs.Count == 0) + { + return; + } + + var locations = ML.DetectionConfigs.Select(u => u.ShowLocation).ToList(); + + if (locations.Count > 0) + { + Rows = (int)locations.Max(u => u.Y); + Cols = (int)locations.Max(u => u.X); + } + + + tableDisplay.ColumnCount = Cols; + tableDisplay.RowCount = Rows; + + tableDisplay.ColumnStyles.Clear(); + for (int i = 0; i < Cols; i++) + { + ColumnStyle colStyle = new ColumnStyle(); + colStyle.SizeType = SizeType.Percent; + colStyle.Width = 1.0f / (float)Cols; + + tableDisplay.ColumnStyles.Add(colStyle); + } + + tableDisplay.RowStyles.Clear(); + for (int i = 0; i < Rows; i++) + { + RowStyle rowStyle = new RowStyle(); + rowStyle.SizeType = SizeType.Percent; + rowStyle.Height = 1.0f / (float)Rows; + + tableDisplay.RowStyles.Add(rowStyle); + } + + tableDisplay.Controls.Clear(); + displayList = new List(); + + ML.DetectionConfigs.ForEach(d => + { + //if (!d.IsShowInUI) + // return; + + CtrlVisionDisplay display = new CtrlVisionDisplay(); + display.DetectionId = d.Id; + display.DetectionName = d.Name; + display.RowIndex = (int)d.ShowLocation.Y - 1; + display.ColIndex = (int)d.ShowLocation.X - 1; + //display.RowIndex = (int)count%row; + //display.ColIndex = (int)count / row; + + display.Dock = DockStyle.Fill; + + display.OnShowOpConfigMenuStateChanged -= Display_OnShowOpConfigMenuStateChanged; + display.OnShowOpConfigMenuStateChanged += Display_OnShowOpConfigMenuStateChanged; + + displayList.Add(display); + tableDisplay.Controls.Add(display); + tableDisplay.SetCellPosition(display, new TableLayoutPanelCellPosition(display.ColIndex, display.RowIndex)); + }); + + splitCMain.Panel2Collapsed = true; + + // propOpConfig.SelectedObject = OpConfig; + } + + private void Display_OnShowOpConfigMenuStateChanged(bool isVisible) + { + IsShowOpConfig = isVisible; + } + + public bool IsShowOpConfig + { + get => !splitCMain.Panel2Collapsed; + set + { + if (splitCMain.Panel2Collapsed == value) + { + splitCMain.Panel2Collapsed = !value; + + displayList.ForEach(d => d.IsShowOpConfig = value); + } + } + } + #endregion + + //private void btnBatchRun_Click(object sender, EventArgs e) + //{ + // FrmMLBatchRun frmMLBatchRun = new FrmMLBatchRun(Device); + + // frmMLBatchRun.MdiParent = (this.Parent as DeviceRunFrmBase).MdiParent; + // frmMLBatchRun.DockPanel = (this.Parent as DeviceRunFrmBase).DockPanel; + // frmMLBatchRun.DockState = DockState.Document; + // frmMLBatchRun.Text = $"{Device.Name}_批量检测"; + + // frmMLBatchRun.Show(); + //} + } +} diff --git a/DHSoftware/Views/CtrlVisionRunBase.resx b/DHSoftware/Views/CtrlVisionRunBase.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/DHSoftware/Views/CtrlVisionRunBase.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DHSoftware/Views/DefectRowEdit.Designer.cs b/DHSoftware/Views/DefectRowEdit.Designer.cs index e422d73..70f3f22 100644 --- a/DHSoftware/Views/DefectRowEdit.Designer.cs +++ b/DHSoftware/Views/DefectRowEdit.Designer.cs @@ -29,6 +29,13 @@ private void InitializeComponent() { panel1 = new AntdUI.Panel(); + select_Result = new AntdUI.Select(); + label5 = new AntdUI.Label(); + input_maxArea = new AntdUI.InputNumber(); + label3 = new AntdUI.Label(); + input_minArea = new AntdUI.InputNumber(); + label4 = new AntdUI.Label(); + input_maxScore = new AntdUI.InputNumber(); label2 = new AntdUI.Label(); input_minScore = new AntdUI.InputNumber(); label1 = new AntdUI.Label(); @@ -38,13 +45,6 @@ stackPanel1 = new AntdUI.StackPanel(); button_cancel = new AntdUI.Button(); button_ok = new AntdUI.Button(); - input_maxScore = new AntdUI.InputNumber(); - input_maxArea = new AntdUI.InputNumber(); - label3 = new AntdUI.Label(); - input_minArea = new AntdUI.InputNumber(); - label4 = new AntdUI.Label(); - label5 = new AntdUI.Label(); - select_Result = new AntdUI.Select(); panel1.SuspendLayout(); stackPanel1.SuspendLayout(); SuspendLayout(); @@ -74,6 +74,87 @@ panel1.TabIndex = 0; panel1.Text = "panel1"; // + // select_Result + // + select_Result.Dock = DockStyle.Top; + select_Result.Location = new Point(18, 408); + select_Result.Name = "select_Result"; + select_Result.Size = new Size(464, 41); + select_Result.TabIndex = 27; + select_Result.Text = "select1"; + // + // label5 + // + label5.Dock = DockStyle.Top; + label5.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + label5.Location = new Point(18, 384); + label5.Name = "label5"; + label5.Size = new Size(464, 24); + label5.TabIndex = 25; + label5.Text = "标签结果"; + // + // input_maxArea + // + input_maxArea.Dock = DockStyle.Top; + input_maxArea.Font = new Font("Microsoft YaHei UI", 9F); + input_maxArea.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + input_maxArea.Location = new Point(18, 346); + input_maxArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 }); + input_maxArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); + input_maxArea.Name = "input_maxArea"; + input_maxArea.Radius = 3; + input_maxArea.Size = new Size(464, 38); + input_maxArea.TabIndex = 24; + input_maxArea.Text = "0"; + // + // label3 + // + label3.Dock = DockStyle.Top; + label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + label3.Location = new Point(18, 322); + label3.Name = "label3"; + label3.Size = new Size(464, 24); + label3.TabIndex = 23; + label3.Text = "最大面积"; + // + // input_minArea + // + input_minArea.Dock = DockStyle.Top; + input_minArea.Font = new Font("Microsoft YaHei UI", 9F); + input_minArea.Increment = new decimal(new int[] { 10, 0, 0, 0 }); + input_minArea.Location = new Point(18, 284); + input_minArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 }); + input_minArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); + input_minArea.Name = "input_minArea"; + input_minArea.Radius = 3; + input_minArea.Size = new Size(464, 38); + input_minArea.TabIndex = 22; + input_minArea.Text = "0"; + // + // label4 + // + label4.Dock = DockStyle.Top; + label4.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + label4.Location = new Point(18, 260); + label4.Name = "label4"; + label4.Size = new Size(464, 24); + label4.TabIndex = 21; + label4.Text = "最小面积"; + // + // input_maxScore + // + input_maxScore.Dock = DockStyle.Top; + input_maxScore.Font = new Font("Microsoft YaHei UI", 9F); + input_maxScore.Increment = new decimal(new int[] { 1, 0, 0, 65536 }); + input_maxScore.Location = new Point(18, 222); + input_maxScore.Maximum = new decimal(new int[] { 1, 0, 0, 0 }); + input_maxScore.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); + input_maxScore.Name = "input_maxScore"; + input_maxScore.Radius = 3; + input_maxScore.Size = new Size(464, 38); + input_maxScore.TabIndex = 20; + input_maxScore.Text = "0"; + // // label2 // label2.Dock = DockStyle.Top; @@ -96,7 +177,7 @@ input_minScore.Radius = 3; input_minScore.Size = new Size(464, 38); input_minScore.TabIndex = 18; - input_minScore.Text = "0.3"; + input_minScore.Text = "0"; // // label1 // @@ -169,86 +250,6 @@ button_ok.Text = "Submit"; button_ok.Type = AntdUI.TTypeMini.Primary; // - // input_maxScore - // - input_maxScore.Dock = DockStyle.Top; - input_maxScore.Font = new Font("Microsoft YaHei UI", 9F); - input_maxScore.Increment = new decimal(new int[] { 1, 0, 0, 65536 }); - input_maxScore.Location = new Point(18, 222); - input_maxScore.Maximum = new decimal(new int[] { 1, 0, 0, 0 }); - input_maxScore.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); - input_maxScore.Name = "input_maxScore"; - input_maxScore.Radius = 3; - input_maxScore.Size = new Size(464, 38); - input_maxScore.TabIndex = 20; - input_maxScore.Text = "0"; - // - // input_maxArea - // - input_maxArea.Dock = DockStyle.Top; - input_maxArea.Font = new Font("Microsoft YaHei UI", 9F); - input_maxArea.Increment = new decimal(new int[] { 10, 0, 0, 0 }); - input_maxArea.Location = new Point(18, 346); - input_maxArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 }); - input_maxArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); - input_maxArea.Name = "input_maxArea"; - input_maxArea.Radius = 3; - input_maxArea.Size = new Size(464, 38); - input_maxArea.TabIndex = 24; - input_maxArea.Text = "0"; - // - // label3 - // - label3.Dock = DockStyle.Top; - label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); - label3.Location = new Point(18, 322); - label3.Name = "label3"; - label3.Size = new Size(464, 24); - label3.TabIndex = 23; - label3.Text = "最大面积"; - // - // input_minArea - // - input_minArea.Dock = DockStyle.Top; - input_minArea.Font = new Font("Microsoft YaHei UI", 9F); - input_minArea.Increment = new decimal(new int[] { 10, 0, 0, 0 }); - input_minArea.Location = new Point(18, 284); - input_minArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 }); - input_minArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 }); - input_minArea.Name = "input_minArea"; - input_minArea.Radius = 3; - input_minArea.Size = new Size(464, 38); - input_minArea.TabIndex = 22; - input_minArea.Text = "0"; - // - // label4 - // - label4.Dock = DockStyle.Top; - label4.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); - label4.Location = new Point(18, 260); - label4.Name = "label4"; - label4.Size = new Size(464, 24); - label4.TabIndex = 21; - label4.Text = "最小面积"; - // - // label5 - // - label5.Dock = DockStyle.Top; - label5.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); - label5.Location = new Point(18, 384); - label5.Name = "label5"; - label5.Size = new Size(464, 24); - label5.TabIndex = 25; - label5.Text = "标签结果"; - // - // select_Result - // - select_Result.Location = new Point(21, 414); - select_Result.Name = "select_Result"; - select_Result.Size = new Size(458, 41); - select_Result.TabIndex = 27; - select_Result.Text = "select1"; - // // DefectRowEdit // Controls.Add(panel1); diff --git a/DHSoftware/Views/DefectRowEdit.cs b/DHSoftware/Views/DefectRowEdit.cs index 72b885d..b83f6a7 100644 --- a/DHSoftware/Views/DefectRowEdit.cs +++ b/DHSoftware/Views/DefectRowEdit.cs @@ -42,7 +42,7 @@ namespace AntdUIDemo.Views.Table if (String.IsNullOrEmpty(input_name.Text)) { input_name.Status = AntdUI.TType.Error; - AntdUI.Message.warn(window, "姓名不能为空!", autoClose: 3); + AntdUI.Message.warn(window, "标签不能为空!", autoClose: 3); return; } user.LabelDescription = input_name.Text; @@ -57,6 +57,9 @@ namespace AntdUIDemo.Views.Table input_name.Text = user.LabelDescription; // input_addr.Text = user.Address; input_minScore.Value =(decimal) user.ScoreMinValue; + input_maxScore.Value =(decimal) user.ScoreMaxValue; + input_minArea.Value =(decimal) user.ScoreMaxValue; + input_maxScore.Value =(decimal) user.ScoreMaxValue; } } } diff --git a/DHSoftware/Views/DetectConfigControl.Designer.cs b/DHSoftware/Views/DetectConfigControl.Designer.cs index bcccd74..b0fbaff 100644 --- a/DHSoftware/Views/DetectConfigControl.Designer.cs +++ b/DHSoftware/Views/DetectConfigControl.Designer.cs @@ -29,90 +29,211 @@ private void InitializeComponent() { panel1 = new Panel(); + panel3 = new Panel(); + label6 = new AntdUI.Label(); + cbxDetectType = new AntdUI.Select(); + label1 = new AntdUI.Label(); + tbDetectName = new AntdUI.Input(); + btnPreOpen = new AntdUI.Button(); + tbModelpath = new AntdUI.Input(); button3 = new AntdUI.Button(); + switchEnable = new AntdUI.Switch(); + label8 = new AntdUI.Label(); + label10 = new AntdUI.Label(); + sthPic = new AntdUI.Switch(); + sthSaveNGPic = new AntdUI.Switch(); + label7 = new AntdUI.Label(); + label9 = new AntdUI.Label(); + swSaveOKPic = new AntdUI.Switch(); panel2 = new Panel(); - label2 = new Label(); + label2 = new AntdUI.Label(); buttonDEL = new AntdUI.Button(); table_base = new AntdUI.Table(); buttonADD = new AntdUI.Button(); - label10 = new AntdUI.Label(); - sthSaveNGPic = new AntdUI.Switch(); - label9 = new AntdUI.Label(); - swSaveOKPic = new AntdUI.Switch(); - label7 = new AntdUI.Label(); - sthPic = new AntdUI.Switch(); - label8 = new AntdUI.Label(); - switchEnable = new AntdUI.Switch(); - tbDetectName = new TextBox(); - label6 = new AntdUI.Label(); - cbxDetectType = new ComboBox(); - label5 = new AntdUI.Label(); - btnPreOpen = new AntdUI.Button(); - tbModelpath = new TextBox(); - label1 = new AntdUI.Label(); panel1.SuspendLayout(); + panel3.SuspendLayout(); panel2.SuspendLayout(); SuspendLayout(); // // panel1 // panel1.BorderStyle = BorderStyle.FixedSingle; - panel1.Controls.Add(button3); + panel1.Controls.Add(panel3); panel1.Controls.Add(panel2); - panel1.Controls.Add(label10); - panel1.Controls.Add(sthSaveNGPic); - panel1.Controls.Add(label9); - panel1.Controls.Add(swSaveOKPic); - panel1.Controls.Add(label7); - panel1.Controls.Add(sthPic); - panel1.Controls.Add(label8); - panel1.Controls.Add(switchEnable); - panel1.Controls.Add(tbDetectName); - panel1.Controls.Add(label6); - panel1.Controls.Add(cbxDetectType); - panel1.Controls.Add(label5); - panel1.Controls.Add(btnPreOpen); - panel1.Controls.Add(tbModelpath); - panel1.Controls.Add(label1); panel1.Dock = DockStyle.Fill; panel1.Location = new Point(0, 0); panel1.Name = "panel1"; - panel1.Size = new Size(683, 445); + panel1.Size = new Size(600, 445); panel1.TabIndex = 0; // + // panel3 + // + panel3.Controls.Add(label6); + panel3.Controls.Add(cbxDetectType); + panel3.Controls.Add(label1); + panel3.Controls.Add(tbDetectName); + panel3.Controls.Add(btnPreOpen); + panel3.Controls.Add(tbModelpath); + panel3.Controls.Add(button3); + panel3.Controls.Add(switchEnable); + panel3.Controls.Add(label8); + panel3.Controls.Add(label10); + panel3.Controls.Add(sthPic); + panel3.Controls.Add(sthSaveNGPic); + panel3.Controls.Add(label7); + panel3.Controls.Add(label9); + panel3.Controls.Add(swSaveOKPic); + panel3.Dock = DockStyle.Fill; + panel3.Location = new Point(0, 0); + panel3.Name = "panel3"; + panel3.Size = new Size(598, 206); + panel3.TabIndex = 41; + // + // label6 + // + label6.Location = new Point(3, 15); + label6.Name = "label6"; + label6.Size = new Size(58, 23); + label6.TabIndex = 25; + label6.Text = "检测名称"; + // + // cbxDetectType + // + cbxDetectType.Anchor = AnchorStyles.Top | AnchorStyles.Right; + cbxDetectType.Location = new Point(341, 7); + cbxDetectType.Name = "cbxDetectType"; + cbxDetectType.Size = new Size(226, 31); + cbxDetectType.TabIndex = 40; + // + // label1 + // + label1.Location = new Point(3, 44); + label1.Name = "label1"; + label1.Size = new Size(73, 23); + label1.TabIndex = 9; + label1.Text = "模型路径"; + // + // tbDetectName + // + tbDetectName.Location = new Point(82, 7); + tbDetectName.Name = "tbDetectName"; + tbDetectName.Size = new Size(249, 31); + tbDetectName.TabIndex = 39; + // + // btnPreOpen + // + btnPreOpen.Anchor = AnchorStyles.Top | AnchorStyles.Right; + btnPreOpen.Location = new Point(507, 36); + btnPreOpen.MinimumSize = new Size(20, 0); + btnPreOpen.Name = "btnPreOpen"; + btnPreOpen.Size = new Size(60, 31); + btnPreOpen.TabIndex = 22; + btnPreOpen.Text = "..."; + // + // tbModelpath + // + tbModelpath.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + tbModelpath.Location = new Point(82, 36); + tbModelpath.Name = "tbModelpath"; + tbModelpath.Size = new Size(415, 31); + tbModelpath.TabIndex = 38; + // // button3 // - button3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - button3.Location = new Point(538, 70); + button3.Anchor = AnchorStyles.Top | AnchorStyles.Right; + button3.Location = new Point(385, 73); button3.Name = "button3"; - button3.Size = new Size(115, 34); + button3.Size = new Size(182, 34); button3.TabIndex = 37; button3.Text = "查看文件夹"; // + // switchEnable + // + switchEnable.Location = new Point(82, 84); + switchEnable.Name = "switchEnable"; + switchEnable.Size = new Size(60, 23); + switchEnable.TabIndex = 27; + switchEnable.Text = "switch1"; + // + // label8 + // + label8.Location = new Point(3, 84); + label8.Name = "label8"; + label8.Size = new Size(58, 23); + label8.TabIndex = 28; + label8.Text = "模型启用"; + // + // label10 + // + label10.Location = new Point(176, 113); + label10.Name = "label10"; + label10.Size = new Size(73, 23); + label10.TabIndex = 34; + label10.Text = "保存NG原图"; + // + // sthPic + // + sthPic.Location = new Point(263, 84); + sthPic.Name = "sthPic"; + sthPic.Size = new Size(60, 23); + sthPic.TabIndex = 29; + sthPic.Text = "switch2"; + // + // sthSaveNGPic + // + sthSaveNGPic.Location = new Point(263, 113); + sthSaveNGPic.Name = "sthSaveNGPic"; + sthSaveNGPic.Size = new Size(60, 23); + sthSaveNGPic.TabIndex = 33; + sthSaveNGPic.Text = "switch4"; + // + // label7 + // + label7.Location = new Point(184, 84); + label7.Name = "label7"; + label7.Size = new Size(58, 23); + label7.TabIndex = 30; + label7.Text = "数据保存"; + // + // label9 + // + label9.Location = new Point(3, 113); + label9.Name = "label9"; + label9.Size = new Size(73, 23); + label9.TabIndex = 32; + label9.Text = "保存OK原图"; + // + // swSaveOKPic + // + swSaveOKPic.Location = new Point(82, 113); + swSaveOKPic.Name = "swSaveOKPic"; + swSaveOKPic.Size = new Size(60, 23); + swSaveOKPic.TabIndex = 31; + swSaveOKPic.Text = "switch3"; + // // panel2 // - panel2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; panel2.Controls.Add(label2); panel2.Controls.Add(buttonDEL); panel2.Controls.Add(table_base); panel2.Controls.Add(buttonADD); - panel2.Location = new Point(17, 141); + panel2.Dock = DockStyle.Bottom; + panel2.Location = new Point(0, 206); panel2.Name = "panel2"; - panel2.Size = new Size(639, 286); + panel2.Size = new Size(598, 237); panel2.TabIndex = 35; // // label2 // - label2.AutoSize = true; - label2.Location = new Point(3, 5); + label2.Location = new Point(3, 3); label2.Name = "label2"; - label2.Size = new Size(56, 17); - label2.TabIndex = 25; + label2.Size = new Size(58, 23); + label2.TabIndex = 29; label2.Text = "模型参数"; // // buttonDEL // - buttonDEL.Location = new Point(93, 25); + buttonDEL.Location = new Point(93, 28); buttonDEL.Name = "buttonDEL"; buttonDEL.Size = new Size(84, 34); buttonDEL.TabIndex = 24; @@ -121,152 +242,30 @@ // table_base // table_base.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - table_base.Location = new Point(3, 65); + table_base.Location = new Point(0, 68); table_base.Name = "table_base"; - table_base.Size = new Size(633, 218); + table_base.Size = new Size(598, 169); table_base.TabIndex = 22; table_base.Text = "table1"; // // buttonADD // - buttonADD.Location = new Point(3, 25); + buttonADD.Location = new Point(3, 28); buttonADD.Name = "buttonADD"; buttonADD.Size = new Size(84, 34); buttonADD.TabIndex = 23; buttonADD.Text = "新增"; // - // label10 - // - label10.Location = new Point(171, 99); - label10.Name = "label10"; - label10.Size = new Size(73, 23); - label10.TabIndex = 34; - label10.Text = "保存NG原图"; - // - // sthSaveNGPic - // - sthSaveNGPic.Location = new Point(258, 99); - sthSaveNGPic.Name = "sthSaveNGPic"; - sthSaveNGPic.Size = new Size(57, 23); - sthSaveNGPic.TabIndex = 33; - sthSaveNGPic.Text = "switch4"; - // - // label9 - // - label9.Location = new Point(17, 99); - label9.Name = "label9"; - label9.Size = new Size(73, 23); - label9.TabIndex = 32; - label9.Text = "保存OK原图"; - // - // swSaveOKPic - // - swSaveOKPic.Location = new Point(96, 99); - swSaveOKPic.Name = "swSaveOKPic"; - swSaveOKPic.Size = new Size(57, 23); - swSaveOKPic.TabIndex = 31; - swSaveOKPic.Text = "switch3"; - // - // label7 - // - label7.Location = new Point(179, 70); - label7.Name = "label7"; - label7.Size = new Size(58, 23); - label7.TabIndex = 30; - label7.Text = "数据保存"; - // - // sthPic - // - sthPic.Location = new Point(258, 70); - sthPic.Name = "sthPic"; - sthPic.Size = new Size(57, 23); - sthPic.TabIndex = 29; - sthPic.Text = "switch2"; - // - // label8 - // - label8.Location = new Point(17, 70); - label8.Name = "label8"; - label8.Size = new Size(58, 23); - label8.TabIndex = 28; - label8.Text = "模型启用"; - // - // switchEnable - // - switchEnable.Location = new Point(96, 70); - switchEnable.Name = "switchEnable"; - switchEnable.Size = new Size(57, 23); - switchEnable.TabIndex = 27; - switchEnable.Text = "switch1"; - // - // tbDetectName - // - tbDetectName.Location = new Point(96, 12); - tbDetectName.Name = "tbDetectName"; - tbDetectName.Size = new Size(211, 23); - tbDetectName.TabIndex = 26; - // - // label6 - // - label6.Location = new Point(17, 12); - label6.Name = "label6"; - label6.Size = new Size(58, 23); - label6.TabIndex = 25; - label6.Text = "检测名称"; - // - // cbxDetectType - // - cbxDetectType.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - cbxDetectType.DropDownStyle = ComboBoxStyle.DropDownList; - cbxDetectType.FormattingEnabled = true; - cbxDetectType.Location = new Point(402, 10); - cbxDetectType.Name = "cbxDetectType"; - cbxDetectType.Size = new Size(254, 25); - cbxDetectType.TabIndex = 24; - // - // label5 - // - label5.Location = new Point(333, 12); - label5.Name = "label5"; - label5.Size = new Size(73, 23); - label5.TabIndex = 23; - label5.Text = "目标类型"; - // - // btnPreOpen - // - btnPreOpen.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - btnPreOpen.Location = new Point(613, 41); - btnPreOpen.Name = "btnPreOpen"; - btnPreOpen.Size = new Size(43, 23); - btnPreOpen.TabIndex = 22; - btnPreOpen.Text = "..."; - // - // tbModelpath - // - tbModelpath.Location = new Point(96, 41); - tbModelpath.Name = "tbModelpath"; - tbModelpath.Size = new Size(511, 23); - tbModelpath.TabIndex = 17; - // - // label1 - // - label1.Location = new Point(17, 41); - label1.Name = "label1"; - label1.Size = new Size(73, 23); - label1.TabIndex = 9; - label1.Text = "模型路径"; - // // DetectConfigControl // AutoScaleDimensions = new SizeF(7F, 17F); AutoScaleMode = AutoScaleMode.Font; Controls.Add(panel1); Name = "DetectConfigControl"; - Size = new Size(683, 445); + Size = new Size(600, 445); panel1.ResumeLayout(false); - panel1.PerformLayout(); + panel3.ResumeLayout(false); panel2.ResumeLayout(false); - panel2.PerformLayout(); ResumeLayout(false); } @@ -274,11 +273,7 @@ private Panel panel1; private AntdUI.Label label1; - private TextBox tbModelpath; - private TextBox tbDetectName; private AntdUI.Label label6; - private ComboBox cbxDetectType; - private AntdUI.Label label5; private AntdUI.Button btnPreOpen; private AntdUI.Label label7; private AntdUI.Switch sthPic; @@ -289,10 +284,14 @@ private AntdUI.Label label9; private AntdUI.Switch swSaveOKPic; private Panel panel2; - private Label label2; private AntdUI.Button buttonDEL; private AntdUI.Table table_base; private AntdUI.Button buttonADD; private AntdUI.Button button3; + private AntdUI.Input tbDetectName; + private AntdUI.Input tbModelpath; + private AntdUI.Label label2; + private AntdUI.Select cbxDetectType; + private Panel panel3; } } diff --git a/DHSoftware/Views/DetectConfigControl.cs b/DHSoftware/Views/DetectConfigControl.cs index 09828ae..4d6f27f 100644 --- a/DHSoftware/Views/DetectConfigControl.cs +++ b/DHSoftware/Views/DetectConfigControl.cs @@ -1,5 +1,6 @@ using AntdUI; using AntdUIDemo.Views.Table; +using DH.Commons.Enums; using DH.Devices.Vision; using DHSoftware.Models; using System; @@ -148,12 +149,12 @@ namespace DHSoftware.Views }, new ColumnSwitch("IsEnable", "是否启用", ColumnAlign.Center){ //支持点击回调 - Call= (value,record, i_row, i_col) =>{ - //执行耗时操作 - Thread.Sleep(1000); - // AntdUI.Message.info(window, value.ToString(),autoClose:1); - return value; - } + //Call= (value,record, i_row, i_col) =>{ + // //执行耗时操作 + // Thread.Sleep(10); + // // AntdUI.Message.info(window, value.ToString(),autoClose:1); + // return value; + //} }, new Column("ScoreMinValue", "最小得分",ColumnAlign.Center), new Column("ScoreMaxValue", "最大得分",ColumnAlign.Center), @@ -222,7 +223,12 @@ namespace DHSoftware.Views { DefectRow useradd = new DefectRow() { - LabelDescription="xinquexian" + LabelDescription="xinquexian", + IsEnable=true, + ScoreMinValue=0.3, + ScoreMaxValue=1, + AreaMinValue=1, + AreaMaxValue=999999999, }; var form = new DefectRowEdit(_window, useradd) { Size = new Size(700, 500) }; @@ -361,87 +367,87 @@ namespace DHSoftware.Views //表格内部按钮事件 private void Table_base_CellButtonClick(object sender, TableButtonEventArgs e) { - //var buttontext = e.Btn.Text; + var buttontext = e.Btn.Text; - //if (e.Record is User user) - //{ - // curUser = user; - // switch (buttontext) - // { - // //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据 - // case "编辑": - // var form = new UserEdit(window, user) { Size = new Size(500, 300) }; - // AntdUI.Drawer.open(new AntdUI.Drawer.Config(window, form) - // { - // OnLoad = () => - // { - // AntdUI.Message.info(window, "进入编辑", autoClose: 1); - // }, - // OnClose = () => - // { - // AntdUI.Message.info(window, "结束编辑", autoClose: 1); - // } - // }); - // break; - // case "删除": - // var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn); - // if (result == DialogResult.OK) - // antList.Remove(user); - // break; - // case "AntdUI": - // //超链接内容 - // AntdUI.Message.info(window, user.CellLinks.FirstOrDefault().Id, autoClose: 1); - // break; - // case "查看图片": - // //使用clone可以防止table中的image被修改 - // Preview.open(new Preview.Config(window, (Image)curUser.CellImages[0].Image.Clone())); - // break; - // } - //} + if (e.Record is DefectRow user) + { + curUser = user; + switch (buttontext) + { + //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据 + case "编辑": + var form = new DefectRowEdit(_window, user) { Size = new Size(500, 300) }; + AntdUI.Drawer.open(new AntdUI.Drawer.Config(_window, form) + { + OnLoad = () => + { + AntdUI.Message.info(_window, "进入编辑", autoClose: 1); + }, + OnClose = () => + { + AntdUI.Message.info(_window, "结束编辑", autoClose: 1); + } + }); + break; + case "删除": + var result = Modal.open(_window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn); + if (result == DialogResult.OK) + antList.Remove(user); + break; + case "AntdUI": + //超链接内容 + // AntdUI.Message.info(_window, user.CellLinks.FirstOrDefault().Id, autoClose: 1); + break; + case "查看图片": + //使用clone可以防止table中的image被修改 + // Preview.open(new Preview.Config(window, (Image)curUser.CellImages[0].Image.Clone())); + break; + } + } } private void ButtonDEL_Click(object sender, EventArgs e) { - //if (antList.Count == 0 || !antList.Any(x => x.Selected)) - //{ - // bool isSubSelected = false; - // // 判断子元素是否勾选 - // for (int i = 0; i < antList.Count; i++) - // { - // if (antList[i].Users != null && antList[i].Users.Any(x => x.Selected)) - // { - // isSubSelected = true; - // break; - // } - // } - // if (!isSubSelected) - // { - // AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3); - // return; - // } - //} + if (antList.Count == 0 || !antList.Any(x => x.Selected)) + { + bool isSubSelected = false; + //// 判断子元素是否勾选 + //for (int i = 0; i < antList.Count; i++) + //{ + // if (antList[i].Users != null && antList[i].Users.Any(x => x.Selected)) + // { + // isSubSelected = true; + // break; + // } + //} + if (!isSubSelected) + { + AntdUI.Message.warn(_window, "请选择要删除的行!", autoClose: 3); + return; + } + } - //var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn); - //if (result == DialogResult.OK) - //{ - // // 使用反转for循环删除主列表中选中的项 - // for (int i = antList.Count - 1; i >= 0; i--) - // { - // // 删除选中的主列表项 - // if (antList[i].Selected) - // { - // antList.RemoveAt(i); - // } - // else - // { - // // 删除子列表中选中的项 - // antList[i].Users = antList[i].Users?.Where(user => !user.Selected).ToArray(); - // } - // } - // // 提示删除完成 - // // AntdUI.Message.success(this.w, "删除成功!", autoClose: 3); - // MessageBox.Show("删除成功!"); - //} + var result = Modal.open(_window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn); + if (result == DialogResult.OK) + { + // 使用反转for循环删除主列表中选中的项 + for (int i = antList.Count - 1; i >= 0; i--) + { + // 删除选中的主列表项 + if (antList[i].Selected) + { + antList.RemoveAt(i); + } + else + { + // 删除子列表中选中的项 + // antList[i].Users = antList[i].Users?.Where(user => !user.Selected).ToArray(); + } + } + // 提示删除完成 + // AntdUI.Message.success(this.w, "删除成功!", autoClose: 3); + MessageBox.Show("删除成功!"); + } } diff --git a/DHSoftware/Views/SettingWindow.cs b/DHSoftware/Views/SettingWindow.cs index d754de3..0837eb9 100644 --- a/DHSoftware/Views/SettingWindow.cs +++ b/DHSoftware/Views/SettingWindow.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using AntdUI; +using DH.Commons.Enums; using DH.Devices.Devices; using DH.Devices.Vision; diff --git a/DHSoftware/Views/UserConfigFrm.cs b/DHSoftware/Views/UserConfigFrm.cs index 26ee30b..ba477d5 100644 --- a/DHSoftware/Views/UserConfigFrm.cs +++ b/DHSoftware/Views/UserConfigFrm.cs @@ -1,5 +1,6 @@ using AntdUI; using AntdUIDemo.Models; +using DH.Commons.Enums; using DH.Devices.Devices; using DH.Devices.Vision; using System; @@ -198,8 +199,8 @@ namespace DHSoftware.Views int width = tabs.Width; int height = tabs.Height; // 创建新 TabPage - UserDetetion control = new UserDetetion(width, height); - control._windows = Window; + UserDetetion control = new UserDetetion(Window,width, height); + // control._windows = Window; switch (name) { case "工位1": diff --git a/DHSoftware/Views/UserDetetion.cs b/DHSoftware/Views/UserDetetion.cs index 2a70177..4b6c3a2 100644 --- a/DHSoftware/Views/UserDetetion.cs +++ b/DHSoftware/Views/UserDetetion.cs @@ -17,9 +17,10 @@ namespace DHSoftware.Views private StackPanel panel, panel2, panel3, panel4; public Window _windows; //根据检测配置 将对应的相机配置、中处理预处理、尺寸测量 - public UserDetetion(int parentWidth, int parentHeight) + public UserDetetion(Window windows,int parentWidth, int parentHeight) { InitializeComponent(); + _windows = windows; AntdUI.CollapseItem group1 = new CollapseItem(); group1.Height = parentHeight / 4; group1.Text = "相机配置"; @@ -214,7 +215,7 @@ namespace DHSoftware.Views // 遍历 panel 的 Controls,找到最后一个 CameraConfigControl 并移除 for (int i = panel3.Controls.Count - 1; i >= 0; i--) { - if (panel3.Controls[i] is CameraConfigControl) + if (panel3.Controls[i] is DetectConfigControl) { panel3.Controls.RemoveAt(i); break; // 只删除一个 diff --git a/DHSoftware/productModel.cs b/DHSoftware/productModel.cs index 4fc7d20..cae60b3 100644 --- a/DHSoftware/productModel.cs +++ b/DHSoftware/productModel.cs @@ -1,4 +1,5 @@ -using DH.Devices.Vision; +using DH.Commons.Enums; +using DH.Devices.Vision; using System; using System.Collections.Generic; using System.Linq;