2026-01-26 18:56:53 +09:00

1171 lines
48 KiB
C#

using Aurora.Api;
using Aurora.Api.DataType;
using Hermes;
using Hermes.Functional;
using Matrox.MatroxImagingLibrary;
using MilCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Converters;
using VisionCalibrator;
using VisionCommon;
namespace MilUI {
/// <summary>
/// Interaction logic for CameraDisplay.xaml
/// </summary>
public partial class CameraDisplay : UserControl, IMilCameraDisplay, IUpdateRecipe, IDisposable {
private const double DEFAULT_IMAGE_WIDTH = 2500.0;
private const double DEFAULT_IMAGE_HEIGHT = 2500.0;
private MIL_ID DisplayId = MIL.M_NULL;
private MIL_ID ImageId = MIL.M_NULL;
private MIL_ID GraphicContext = MIL.M_NULL;
private MIL_ID StaticGraphicList = MIL.M_NULL;
private MIL_ID _trainRoiLabel = MIL.M_NULL;
private MIL_ID _trainOriginLabel = MIL.M_NULL;
private Dictionary<eRoiIdx, MIL_ID> _findRoiLabels = new Dictionary<eRoiIdx, MIL_ID>();
private Logger _Logger;
private CamConfig _CamConfig;
private CameraBase _CameraDev;
private FovInfo _FovInfo;
private FovRecipe _FovRecipe;
private PatternRecipe _PatternRecipe;
private Calibrator _Calibrator;
private ImageSize _ImageSize;
private eDisplayType _DisplayType;
private IDisposable _EventDisposable;
private Dictionary<eRoiIdx, PatternInfo> _PatternInfos = new Dictionary<eRoiIdx, PatternInfo>();
private GCHandle ThisPtr;
private MIL_DISP_HOOK_FUNCTION_PTR MouseLeftDownHookFuncPtr;
private MIL_DISP_HOOK_FUNCTION_PTR MouseLeftMoveHookFuncPtr;
private MIL_DISP_HOOK_FUNCTION_PTR MouseRightDownHookFuncPtr;
private MIL_DISP_HOOK_FUNCTION_PTR MouseWheelHookFuncPtr;
private MIL_GRA_HOOK_FUNCTION_PTR GraphicSelectionModifiedHookFuncPtr;
private GridGuideLine _gridGuideLine;
private MilGraphics _patternResultGraphics;
private MilGraphics _patternTrackingGraphics;
private MilGraphics _trainGraphics;
private MilGraphics _findGraphics;
private Dictionary<eRoiIdx, MilGraphics> _findLabelNumGraphicsDic = new Dictionary<eRoiIdx, MilGraphics>();
private DisplayMode _displayMode;
private eDisplayMode _curDisplayMode = eDisplayMode.None;
#region TrainRoi & FindRoi Changed Event
private GCHandle _TrainRoiChangedDataHandle;
private Dictionary<eRoiIdx, GCHandle> _FindRoiChangedDataHandles = new Dictionary<eRoiIdx, GCHandle>();
private MIL_GRA_HOOK_FUNCTION_PTR _OnTrainRoiChangedFuncPtr;
private Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR> _OnFindRoiChangedFuncPtrs = new Dictionary<eRoiIdx, MIL_GRA_HOOK_FUNCTION_PTR>();
#endregion
private bool _Initialized = false;
public CameraDisplay() {
InitializeComponent();
}
public void SetPatternInfo(PatternInfo patternInfo, eRoiIdx roiIdx = eRoiIdx.Roi0) {
_PatternInfos[roiIdx] = patternInfo;
}
public int Init(CameraBase cameraDev, eDisplayType displayType, CamConfig camConfig, FovInfo fovInfo, FovRecipe fovRecipe) {
if (_Initialized) {
return E1.OK;
}
_Logger = new Logger(string.Format("CameraDisplay[{0}]", fovRecipe.FovName));
_CameraDev = cameraDev;
_CamConfig = camConfig;
_DisplayType = displayType;
_FovInfo = fovInfo;
_FovRecipe = fovRecipe;
_PatternRecipe = VisionRecipeManager.GetPatternRecipe(_FovInfo.ToSubSysInfo(), _FovInfo.FovId);
_Calibrator = CalibratorManager.GetCalibrator(_FovInfo);
if (_CameraDev != null && _CamConfig != null && MilEnvironment.Instance.HasValidLicense()) {
// Config와 MilSystem은 Camera가 Activate된 이후에 사용할 수 있다.
// 그러나 시점상 Display관련 UI를 생성할 때는 위 객체들이 null이기 때문에 조치 필요..
// Camera Activate보다 View가 우선 실행되어 CamConfig를 직접 받는것으로 수정.. 문제 해결 후 원복
//_ImageSize = _CameraDev.GetImageSize();
_ImageSize = _CamConfig.ImageSize;
ImageId = MilEnvironment.GetCompatibleImageBuffer(
_ImageSize, _CamConfig.CamConnConfig.BoardType, _CamConfig.CamConnConfig.BoardSlotPos);
DisplayId = MilEnvironment.Instance.CreateDisplay(winFormPanel.Handle, ImageId);
MIL_ID sysId = MilEnvironment.Instance.GetSystem(_CamConfig.CamConnConfig.BoardType, _CamConfig.CamConnConfig.BoardSlotPos);
AllocGraphics(sysId);
SetObservable();
CreateGraphics();
DrawGuideLines();
SetHookFunc();
_Initialized = true;
}
else {
_Logger.FuncE("Failed to initialize camera display view.");
}
return E1.OK;
}
private void AllocGraphics(MIL_ID sysId) {
MIL.MgraAlloc(sysId, ref GraphicContext);
MIL.MgraAllocList(sysId, MIL.M_DEFAULT, ref StaticGraphicList);
MIL.MdispControl(DisplayId, MIL.M_MOUSE_USE, MIL.M_ENABLE);
MIL.MdispControl(DisplayId, MIL.M_SCALE_DISPLAY, MIL.M_ENABLE);
MIL.MdispControl(DisplayId, MIL.M_CENTER_DISPLAY, MIL.M_ENABLE);
MIL.MdispControl(DisplayId, MIL.M_MOUSE_CURSOR_CHANGE, MIL.M_DISABLE);
MIL.MdispControl(DisplayId, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
MIL.MdispControl(DisplayId, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, StaticGraphicList);
}
private void SetObservable() {
_EventDisposable = VisionEnv.AuroraEnv.EventObservable.AsObservable(DiplayModeEvent.On)
.Where(x => x.From == _FovRecipe.FovName)
.Where(x => ((DisplayModeParam)x.Param).DisplayType == _DisplayType)
.Subscribe(msg => OnDisplayMode(msg));
_EventDisposable = VisionEnv.AuroraEnv.EventObservable.AsObservable(DiplayModeEvent.Off)
.Where(x => x.From == _FovRecipe.FovName)
.Where(x => ((DisplayModeParam)x.Param).DisplayType == _DisplayType)
.Subscribe(msg => OffDisplayMode(msg));
}
public void OnDisplayMode(EventMessage msg) {
_Logger.FuncI();
if (_curDisplayMode != eDisplayMode.None) {
RulerModeOff(_curDisplayMode);
}
_curDisplayMode = eDisplayMode.None;
_displayMode = (msg.Param as DisplayModeParam).DisplayMode;
}
public void OffDisplayMode(EventMessage msg) {
_Logger.FuncI();
_curDisplayMode = eDisplayMode.None;
_displayMode?.Clear();
_displayMode = null;
}
private void CreateGraphics() {
_patternResultGraphics = new MilGraphics(DisplayId, StaticGraphicList);
_patternTrackingGraphics = new MilGraphics(DisplayId, StaticGraphicList);
_trainGraphics = new MilGraphics(DisplayId, StaticGraphicList);
_findGraphics = new MilGraphics(DisplayId, StaticGraphicList);
_gridGuideLine = new GridGuideLine(DisplayId, GraphicContext, StaticGraphicList, _FovInfo);
}
public void DrawGuideLines() {
var calFovRecipe = VisionRecipeManager.GetCalFovRecipe(_FovInfo);
var centerPos = new ImagePoint(_ImageSize.Width / 2, _ImageSize.Height / 2);
var color = MIL.M_RGB888(255, 165, 0); // Orange
_gridGuideLine.DrawGuideLines(_ImageSize, centerPos, 1, color, calFovRecipe.ErrRotationX);
//_gridGuideLine.DrawRefLine(_ImageSize, calFovRecipe.ErrRotationX);
//_gridGuideLine.DrawCoordDirection(_ImageSize);
}
private void SetHookFunc() {
if (!ThisPtr.IsAllocated) {
ThisPtr = GCHandle.Alloc(this);
MouseLeftDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseLeftDownHookFunc);
MouseLeftMoveHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseMoveHookFunc);
MouseRightDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseRightDownHookFunc);
MouseWheelHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseWheelHookFunc);
GraphicSelectionModifiedHookFuncPtr = new MIL_GRA_HOOK_FUNCTION_PTR(GraphicSelectionModifiedHookFunc);
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_LEFT_BUTTON_DOWN, MouseLeftDownHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_MOVE, MouseLeftMoveHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_RIGHT_BUTTON_DOWN, MouseRightDownHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_WHEEL, MouseWheelHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MgraHookFunction(StaticGraphicList, MIL.M_GRAPHIC_SELECTION_MODIFIED, GraphicSelectionModifiedHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
}
}
public MIL_INT MouseLeftDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr) {
if (_displayMode != null) {
_displayMode.MouseLeftDown(EventID);
}
return 0;
}
public MIL_INT MouseMoveHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr) {
if (_displayMode != null) {
_displayMode.MouseMove(EventID);
}
UpdateCurrentPointToStatusBar(EventID);
return 0;
}
public MIL_INT MouseRightDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr) {
if (_displayMode != null) {
_displayMode.MouseRightDown(EventID);
}
return 0;
}
public MIL_INT MouseWheelHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr) {
UpdateCurrentZoomToStatusBar();
UpdateCurrentPointToStatusBar(EventID);
return 0;
}
public MIL_INT GraphicSelectionModifiedHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr) {
if (_displayMode != null) {
_displayMode.GraphicSelectionModified(EventID);
}
return 0;
}
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
if (IsLoaded && (e.WidthChanged || e.HeightChanged)) {
ImageSize imageSize = MilEnvironment.GetImageSize(GetImage());
FitImage(imageSize);
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e) {
var imageId = GetImage();
if (imageId != MIL.M_NULL) {
ImageSize imageSize = MilEnvironment.GetImageSize(GetImage());
FitImage(imageSize);
}
}
public void ClearImage() {
MilEnvironment.ClearImage(this.ImageId);
}
public int FitImage(ImageSize imageSize) {
try {
if (DisplayId != MIL.M_NULL &&
MilEnvironment.Instance.HasValidLicense()) {
if (MilEnvironment.IsImageSizeNull(imageSize)) {
imageSize = _CameraDev.GetImageSize();
}
double zoomX = (double)winFormPanel.Width / imageSize.Width;
double zoomY = (double)winFormPanel.Height / imageSize.Height;
// 이미지 원본의 비율을 유지하면서 영상의 모든 영역이 디스플레이에 출력되어야 한다.
double minZoom = Math.Min(zoomX, zoomY);
SetAbsImageZoom(minZoom);
}
return E1.OK;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return E1.GENERIC;
}
public int SetImage(object image) {
var milImage = (MIL_ID)image;
if (this.ImageId != milImage) {
UpdateImageBufferSize(milImage);
MIL.MbufCopy(milImage, this.ImageId);
}
return E1.OK;
}
public bool IsSetImage() {
if (ImageId != MIL.M_NULL) {
return true;
}
else {
return false;
}
}
public void UpdateImageBufferSize(MIL_ID imageId) {
if (!MilEnvironment.Instance.HasValidLicense()) {
return;
}
if (IsTimeToUpdate(imageId)) {
MilEnvironment.FreeImage(ImageId);
_ImageSize = MilEnvironment.GetImageSize(imageId);
ImageId = MilEnvironment.GetCompatibleImageBuffer(
_ImageSize, _CamConfig.CamConnConfig.BoardType, _CamConfig.CamConnConfig.BoardSlotPos);
Application.Current.Dispatcher.Invoke(
new Action(() => {
MilEnvironment.Instance.SelectDisplay(winFormPanel.Handle, ImageId, DisplayId);
}));
FitImage(_ImageSize);
_gridGuideLine?.Update(_ImageSize);
}
}
private bool IsTimeToUpdate(MIL_ID imageId) {
if (ImageId == MIL.M_NULL) {
return true;
}
var displaySize = MilEnvironment.GetImageSize(ImageId);
var imageSize = MilEnvironment.GetImageSize(imageId);
if (displaySize.Width != imageSize.Width ||
displaySize.Height != imageSize.Height ||
displaySize.Channel != imageSize.Channel ||
displaySize.BitDepth != imageSize.BitDepth) {
return true;
}
return false;
}
public object GetImageObject() {
return (object)ImageId;
}
public MIL_ID GetImage() {
return ImageId;
}
public MIL_ID GetMilDisplayId() {
return DisplayId;
}
public MIL_ID GetGraphicContextId() {
return GraphicContext;
}
public MIL_ID GetGraphicListId() {
return StaticGraphicList;
}
public CamRecipe GetCamRecipe() {
return _FovRecipe.CamRecipe;
}
public FovInfo GetDisplayFovInfo() {
return _FovInfo;
}
public eDisplayType GetDisplayType() {
return _DisplayType;
}
public int RulerModeOn(eDisplayMode displayMode) {
if (_curDisplayMode != eDisplayMode.None) {
RulerModeOff(_curDisplayMode);
}
_curDisplayMode = displayMode;
ImageSize imageSize;
if (ImageId != MIL.M_NULL) {
imageSize = MilEnvironment.GetImageSize(ImageId);
}
else {
imageSize = new ImageSize() {
Width = (int)DEFAULT_IMAGE_WIDTH,
Height = (int)DEFAULT_IMAGE_HEIGHT
};
}
switch (displayMode) {
case eDisplayMode.DistanceAngle:
_displayMode = new RulerMode(
DisplayId, GraphicContext, StaticGraphicList, imageSize,
_FovRecipe.CalFovRecipe.PixelSize.Clone() as StaticPoint);
break;
case eDisplayMode.Position:
_displayMode = new PositionMode(
_FovInfo,
DisplayId, GraphicContext, StaticGraphicList, imageSize,
_FovRecipe.CalFovRecipe.PixelSize.Clone() as StaticPoint);
break;
case eDisplayMode.Circle:
_displayMode = new CircleMode(
DisplayId, GraphicContext, StaticGraphicList, imageSize,
_FovRecipe.CalFovRecipe.PixelSize.Clone() as StaticPoint);
break;
case eDisplayMode.MovePosition:
_displayMode = new MovePositionMode(_FovInfo, imageSize);
break;
default:
break;
}
return E1.OK;
}
public int RulerModeOff(eDisplayMode displayMode) {
_displayMode?.Clear();
_displayMode = null;
_curDisplayMode = eDisplayMode.None;
return E1.OK;
}
public void SetWideGridGuideLine() {
if (ImageId != MIL.M_NULL) {
_gridGuideLine.WideOn(MilEnvironment.GetImageSize(ImageId));
}
}
public void SetNarrowGridGuideLine() {
if (ImageId != MIL.M_NULL) {
_gridGuideLine.NarrowOn(MilEnvironment.GetImageSize(ImageId));
}
}
public void SetWideGridGuideLine_ErrRotation() {
if (ImageId != MIL.M_NULL) {
_gridGuideLine.WideOn(MilEnvironment.GetImageSize(ImageId), true);
}
}
public void SetNarrowGridGuideLine_ErrRotation() {
if (ImageId != MIL.M_NULL) {
_gridGuideLine.NarrowOn(MilEnvironment.GetImageSize(ImageId), true);
}
}
public void ClearGridGuidLine() {
_gridGuideLine.Clear();
}
public int SetPatternTracking(Cross newCross) {
if (_PatternRecipe.TrackingParam.Enabled) {
PatternTrackingManager.AddCross(_FovInfo, newCross);
}
return E1.OK;
}
public int DrawPatternTrackings(List<Cross> newCrosses) {
ClearPatternTrackingGraphics();
if (_PatternRecipe.TrackingParam.Enabled) {
Application.Current.Dispatcher.BeginInvoke(
new System.Action(() => {
var color = ColorConverter.ConvertColor(eColor.Orange);
var crossTrackings = PatternTrackingManager.GetCrosses(_FovInfo, _PatternRecipe.TrackingParam.Count + 1);
RemoveDuplicateCross(newCrosses, crossTrackings);
DisplayDrawer.AddCrosses(DisplayId, GraphicContext, StaticGraphicList, color, _patternTrackingGraphics, crossTrackings);
}));
}
return E1.OK;
}
private void RemoveDuplicateCross(List<Cross> newCrosses, List<Cross> crossTrackings) {
foreach (Cross newCross in newCrosses) {
for (int i = 0; i < crossTrackings.Count; i++) {
if (crossTrackings[i].Equals(newCross)) {
crossTrackings.Remove(newCross);
}
}
}
}
/// <summary>
/// 레퍼런스 위치에 십자가 그리기
/// </summary>
/// <param name="length">십자가 길이</param>
/// <param name="color">십자가 색상</param>
public void DrawRefCross(int length = 10, eColor color = eColor.Yellow) {
var refPointRecipe = VisionRecipeManager.GetRefPointRecipe(_FovInfo);
if (refPointRecipe == null) {
_Logger.E($"refPointRecipe is null");
return;
}
ImagePoint refPos = GetRefPos(_ImageSize);
AddCross(new Cross(refPos, length), color);
}
private ImagePoint GetRefPos(ImageSize imageSize) {
var calibrator = CalibratorManager.GetCalibrator(_FovInfo);
var staticRefPoint = VisionRecipeManager.GetRefPoint(_FovInfo);
var imageRefPoint = calibrator.TransformToImagePoint(staticRefPoint, imageSize);
return new ImagePoint(imageRefPoint.X, imageRefPoint.Y);
}
public void DrawStrReadResult(MIL_ID resultContextId, ROI roi) {
DisplayDrawer.DrawStrReadResult(DisplayId, resultContextId, GraphicContext, StaticGraphicList, _patternResultGraphics, roi);
}
public void DrawOcrReadResult(MIL_ID resultContextId, ROI roi) {
DisplayDrawer.DrawOcrReadResult(DisplayId, resultContextId, GraphicContext, StaticGraphicList, _patternResultGraphics, roi);
}
public int AddPatternEdge(MIL_ID resultContextId, ROI roi) {
DisplayDrawer.AddPatternEdge(DisplayId, resultContextId, GraphicContext, StaticGraphicList, _patternResultGraphics, roi);
return E1.OK;
}
public int AddCross(Cross cross, eColor color) {
return AddCross(cross, ColorConverter.ConvertColor(color));
}
public int AddCross(Cross cross, MIL_INT color) {
DisplayDrawer.AddCross(DisplayId, GraphicContext, StaticGraphicList, color, _patternResultGraphics, cross);
return E1.OK;
}
public int AddCrosses(List<Cross> crosses, MIL_INT color) {
DisplayDrawer.AddCrosses(DisplayId, GraphicContext, StaticGraphicList, color, _patternResultGraphics, crosses);
return E1.OK;
}
public int AddLine(eColor color, ImagePoint p1, ImagePoint p2) {
var line = new Line<ImagePoint>(p1, p2);
return AddLine(ColorConverter.ConvertColor(color), line, false);
}
public int AddLine(MIL_INT color, Line<ImagePoint> line, bool isEditable) {
DisplayDrawer.AddLine(GraphicContext, StaticGraphicList, color, _patternResultGraphics, line, isEditable);
return E1.OK;
}
public int AddLines(MIL_INT color, List<Line<ImagePoint>> lines) {
DisplayDrawer.AddLines(DisplayId, GraphicContext, StaticGraphicList, color, _patternResultGraphics, lines);
return E1.OK;
}
public int AddVectors(MIL_INT color, List<Line<ImagePoint>> lines, bool drawTail) {
DisplayDrawer.AddVectors(
DisplayId, GraphicContext, StaticGraphicList, color, _patternResultGraphics, lines, drawTail);
return E1.OK;
}
public void AddRoi(ROI roi, eColor color, bool isRotatable = false) {
if (ROI.IsNullOrEmpty(roi)) {
DisplayDrawer.AddRoi(
GraphicContext, StaticGraphicList, ColorConverter.ConvertColor(color), _patternResultGraphics, roi, false);
}
}
public int AddTrainRoi(ImagePoint imageCenter, bool isRotatable = false) {
var length = 200;
return AddTrainRoi(new ROI(imageCenter, length, length, new Angle()), isRotatable);
}
public int AddTrainRoi(ROI trainRoi, bool isRotatable = false) {
if (HasTrainRoi()) {
_trainGraphics.Remove(_trainRoiLabel);
}
MIL.MgraColor(GraphicContext, MIL.M_COLOR_BLUE);
MIL.MgraRectAngle(
GraphicContext,
StaticGraphicList,
trainRoi.Center.X,
trainRoi.Center.Y,
trainRoi.Width,
trainRoi.Height,
trainRoi.Angle.Degree,
MIL.M_CENTER_AND_DIMENSION);
MIL.MgraInquireList(StaticGraphicList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref _trainRoiLabel);
if (isRotatable) {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_ROTATABLE, MIL.M_ENABLE);
}
else {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_ROTATABLE, MIL.M_DISABLE);
}
SetTrainRoiChangedEvent();
_trainGraphics.Add();
return E1.OK;
}
public ROI GetTrainRoi() {
if (_trainRoiLabel == MIL.M_NULL) {
return new ROI(0, 0, 0, 0);
}
double centerX = 0;
double centerY = 0;
double width = 0;
double height = 0;
double angle = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_CENTER_X, ref centerX);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_CENTER_Y, ref centerY);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_WIDTH, ref width);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_HEIGHT, ref height);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_ANGLE, ref angle);
var convParam = ConvertDoubleToInt(centerX, centerY, width, height);
return new ROI(
convParam.centerX, convParam.centerY, convParam.width, convParam.height, Angle.CreateWithDegree(angle));
}
private (double centerX, double centerY, int width, int height) ConvertDoubleToInt(double centerX, double centerY, double width, double height) {
int left = (int)Math.Round(centerX - width / 2.0);
int top = (int)Math.Round(centerY - height / 2.0);
int right = (int)Math.Round(centerX + width / 2.0);
int bottom = (int)Math.Round(centerY + height / 2.0);
int intWidth = right - left;
int intHeight = bottom - top;
double dbCenterX = left + intWidth * 0.5;
double dbCenterY = top + intHeight * 0.5;
return (dbCenterX, dbCenterY, intWidth, intHeight);
}
public void UpdateAngleOfTrainRoi(double roiAngle) {
if (HasTrainRoi()) {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainRoiLabel), MIL.M_DEFAULT, MIL.M_ANGLE, roiAngle);
}
}
public bool HasTrainRoi() {
return _trainGraphics != null && _trainGraphics.HasGraphicLabel(_trainRoiLabel);
}
public int AddTrainOrigin(Cross imageCenter) {
if (_trainOriginLabel != MIL.M_NULL) {
return E1.GENERIC;
}
MIL.MgraArc(GraphicContext, StaticGraphicList, imageCenter.Origin.X, imageCenter.Origin.Y, 25, 25, 0, 360);
MIL.MgraInquireList(StaticGraphicList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref _trainOriginLabel);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_RESIZABLE, MIL.M_DISABLE);
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_SPECIFIC_FEATURES_EDITABLE, MIL.M_DISABLE);
_trainGraphics.Add();
return E1.OK;
}
public Cross GetTrainOrigin() {
if (_trainOriginLabel == MIL.M_NULL) {
return new Cross(new ImagePoint(0, 0));
}
double x = 0;
double y = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref x);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_trainOriginLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref y);
return new Cross(new ImagePoint(x, y));
}
public int AddDefaultFindRoi(ImageSize imageSize, bool isRotatable = false) {
if (!_findRoiLabels.ContainsKey(eRoiIdx.Roi0)) {
_findRoiLabels.Add(eRoiIdx.Roi0, MIL.M_NULL);
}
if (_findRoiLabels[eRoiIdx.Roi0] != MIL.M_NULL) {
return E1.GENERIC;
}
var roi = RoiUtil.GetDefaultFindRoi(imageSize);
return AddFindRoi(roi, isRotatable);
}
public int AddFindRoi(ROI findRoi, bool isRotatable = false) {
if (findRoi.RoiIdx == eRoiIdx.Roi0) {
ClearFindRoi(); // Multi Pattern의 경우 Clear가 필요 없음.
}
MIL.MgraColor(GraphicContext, ColorConverter.ConvertColor(findRoi.RoiColor));
MIL.MgraRectAngle(
GraphicContext,
StaticGraphicList,
findRoi.CenterX,
findRoi.CenterY,
findRoi.Width,
findRoi.Height,
findRoi.Angle.Degree,
MIL.M_CENTER_AND_DIMENSION);
var findRoiLabel = MIL.M_NULL;
MIL.MgraInquireList(StaticGraphicList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref findRoiLabel);
_findRoiLabels[findRoi.RoiIdx] = findRoiLabel;
if (isRotatable) {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[findRoi.RoiIdx]), MIL.M_DEFAULT, MIL.M_ROTATABLE, MIL.M_ENABLE);
}
else {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[findRoi.RoiIdx]), MIL.M_DEFAULT, MIL.M_ROTATABLE, MIL.M_DISABLE);
}
_findGraphics.Add();
AddFindRoiLabelNum(findRoi, findRoi.RoiIdx);
SetFindRoiChangedEvent(findRoi.RoiIdx);
return E1.OK;
}
private void AddFindRoiLabelNum(ROI findRoi, eRoiIdx roiIdx) {
if (roiIdx != eRoiIdx.Roi0) {
if (!_findLabelNumGraphicsDic.ContainsKey(roiIdx)) {
_findLabelNumGraphicsDic[roiIdx] = new MilGraphics(DisplayId, StaticGraphicList);
}
else {
_findLabelNumGraphicsDic[roiIdx].Clear();
}
var msgs = new List<string>() { ((int)roiIdx).ToString() };
var imageSize = MilEnvironment.GetImageSize(ImageId);
DisplayDrawer.AddTextList(DisplayId, GraphicContext, StaticGraphicList, ColorConverter.ConvertColor(eColor.Orange),
_findLabelNumGraphicsDic[roiIdx], imageSize, findRoi.RightBottom, msgs);
}
}
public ROI GetFindRoi(eRoiIdx roiIdx = eRoiIdx.Roi0) {
if (!HasFindRoi(roiIdx)) {
return new ROI() { RoiIdx = roiIdx };
}
double centerX = 0;
double centerY = 0;
double width = 0;
double height = 0;
double angle = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_CENTER_X, ref centerX);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_CENTER_Y, ref centerY);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_RECTANGLE_WIDTH, ref width);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_RECTANGLE_HEIGHT, ref height);
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_ANGLE, ref angle);
var convParam = ConvertDoubleToInt(centerX, centerY, width, height);
return new ROI(
convParam.centerX, convParam.centerY, convParam.width, convParam.height, Angle.CreateWithDegree(angle), roiIdx);
}
public void UpdateAngleOfFindRoi(double roiAngle, eRoiIdx roiIdx = eRoiIdx.Roi0) {
if (HasFindRoi(roiIdx)) {
MIL.MgraControlList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(_findRoiLabels[roiIdx]), MIL.M_DEFAULT, MIL.M_ANGLE, roiAngle);
}
}
public bool HasFindRoi(eRoiIdx roiIdx = eRoiIdx.Roi0) {
if (_findRoiLabels.ContainsKey(roiIdx)) {
return _findGraphics != null && _findGraphics.HasGraphicLabel(_findRoiLabels[roiIdx]);
}
return false;
}
public void ClearFindRoi(eRoiIdx roiIdx = eRoiIdx.Roi0) {
if (HasFindRoi(roiIdx)) {
_findGraphics.Remove(_findRoiLabels[roiIdx]);
_findRoiLabels.Remove(roiIdx);
}
}
public int AddPatternResultFindRoi(MIL_INT color, List<ROI> findRois) {
foreach (var roi in findRois) {
AddPatternResultFindRoi(color, roi);
}
return E1.OK;
}
public int AddPatternResultFindRoi(MIL_INT color, ROI findRoi) {
if (ROI.IsNullOrEmpty(findRoi)) {
var imageSize = MilEnvironment.GetImageSize(GetImage());
var defaultFindRoi = RoiUtil.GetDefaultFindRoi(imageSize);
DisplayDrawer.AddRoi(
GraphicContext, StaticGraphicList, color, _patternResultGraphics, defaultFindRoi, false);
}
else {
DisplayDrawer.AddRoi(
GraphicContext, StaticGraphicList, color, _patternResultGraphics, findRoi, false);
}
return E1.OK;
}
public int AddPatternResultDots(MIL_INT color, List<ImagePoint> dots) {
DisplayDrawer.AddPatternResultDots(
DisplayId, GraphicContext, StaticGraphicList,
color, _patternResultGraphics, dots);
return E1.OK;
}
public int AddTextList(eColor color, ImagePoint p, List<string> msgs) {
return AddTextList(ColorConverter.ConvertColor(color), p, msgs);
}
public int AddTextList(object color, ImagePoint p, List<string> msgs) {
var imageSize = MilEnvironment.GetImageSize(ImageId);
DisplayDrawer.AddTextList(
DisplayId, GraphicContext, StaticGraphicList, (MIL_INT)color, _patternResultGraphics, imageSize, p, msgs);
return E1.OK;
}
public int AddTextList(object color, ImagePoint p, List<string> msgs, int lineInterval) {
var imageSize = MilEnvironment.GetImageSize(ImageId);
DisplayDrawer.AddTextList(
DisplayId, GraphicContext, StaticGraphicList, (MIL_INT)color, _patternResultGraphics, imageSize, p, msgs, lineInterval);
return E1.OK;
}
public int AddColorTextList(ImagePoint p, List<ColorText> colorTextList) {
var imageSize = MilEnvironment.GetImageSize(ImageId);
DisplayDrawer.AddColorTextList(
DisplayId, GraphicContext, StaticGraphicList, _patternResultGraphics, imageSize, p, colorTextList);
return E1.OK;
}
public int AddColorTextList(ImagePoint p, List<ColorText> colorTextList, int lineInterval) {
var imageSize = MilEnvironment.GetImageSize(ImageId);
DisplayDrawer.AddColorTextList(
DisplayId, GraphicContext, StaticGraphicList, _patternResultGraphics, imageSize, p, colorTextList, lineInterval);
return E1.OK;
}
public int ClearAllGraphics() {
ClearMeasureGraphics();
ClearTrainGraphics();
ClearFindGraphics();
if (MilEnvironment.Instance.HasValidLicense()) {
MIL.MgraClear(GraphicContext, StaticGraphicList);
}
return E1.OK;
}
public int ClearMeasureGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) {
// Clear graphics of DisplayMode and PatternResult
_displayMode?.Clear();
_patternResultGraphics?.Clear();
return E1.OK;
}
public int ClearTrainGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) {
_trainGraphics?.Clear();
_trainRoiLabel = MIL.M_NULL;
_trainOriginLabel = MIL.M_NULL;
return E1.OK;
}
public int ClearFindGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) {
_findGraphics?.Clear();
for (int i = 0; i < _findRoiLabels.Count; i++) {
if (HasFindRoi((eRoiIdx)i)) {
_findRoiLabels[(eRoiIdx)i] = MIL.M_NULL;
}
}
return E1.OK;
}
public int ClearPatternTrackingGraphics(eGraphicToClear graphicToClear = eGraphicToClear.ALL) {
_patternTrackingGraphics?.Clear();
return E1.OK;
}
public void ClearFindLabelNumGraphicsAll() {
foreach (var itemPair in _findLabelNumGraphicsDic) {
MilGraphics milGraphics = itemPair.Value;
milGraphics?.Clear();
}
_findLabelNumGraphicsDic.Clear();
}
public void ClearFindLabelNumGraphics(eRoiIdx roiIdx) {
if (_findLabelNumGraphicsDic.ContainsKey(roiIdx)) {
_findLabelNumGraphicsDic[roiIdx]?.Clear();
}
}
// 메인 화면에 _FovInfo에 해당하는 디스플레이만 보이기
public void SetVisibility() {
var fovUiPos = VisionRecipeManager.GetFovUiPos(_FovRecipe, _DisplayType);
CameraViewManager.Instance.SetVisibilities(_FovInfo, fovUiPos, _DisplayType);
}
private void winFormPanel_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e) {
ImageSize imageSize = MilEnvironment.GetImageSize(GetImage());
FitImage(imageSize);
}
private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
bool isVisible = (bool)e.NewValue;
if (isVisible == true) {
RefreshVisionRecipes();
}
}
public void RefreshVisionRecipes() {
if (_FovInfo != null) {
_FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo);
_PatternRecipe = VisionRecipeManager.GetPatternRecipe(_FovInfo.ToSubSysInfo(), _FovInfo.FovId);
}
}
public void UpdateRecipeFromFile() {
throw new NotImplementedException();
}
public void UpdateRecipeFromUI() {
throw new NotImplementedException();
}
private void UpdateCurrentZoomToStatusBar() {
double imageZoom = GetImageZoom();
double displayZoom = GetDisplayZoom();
curZoom.Text = $"Zoom (X{imageZoom / displayZoom:F2}, {imageZoom:F2})";
}
public void SetAbsImageZoom(double zoom) {
if (zoom > 0) {
MIL.MdispZoom(DisplayId, zoom, zoom);
Application.Current.Dispatcher.BeginInvoke(
new Action(() => {
UpdateCurrentZoomToStatusBar();
}
));
}
}
public void SetRelativeImageZoom(double relZoom) {
SetAbsImageZoom(GetImageZoom() + relZoom);
}
public double GetImageZoom() {
double imageZoomX = 0;
double imageZoomY = 0;
MIL.MdispInquire(DisplayId, MIL.M_ZOOM_FACTOR_X, ref imageZoomX);
MIL.MdispInquire(DisplayId, MIL.M_ZOOM_FACTOR_Y, ref imageZoomY);
return Math.Round(Math.Min(imageZoomX, imageZoomY), 2);
}
public double GetDisplayZoom() {
MIL_INT sizeX = 0;
MIL_INT sizeY = 0;
MIL.MdispInquire(DisplayId, MIL.M_SIZE_X, ref sizeX);
MIL.MdispInquire(DisplayId, MIL.M_SIZE_Y, ref sizeY);
double displayZoomX = (double)sizeX / _ImageSize.Width;
double displayZoomY = (double)sizeY / _ImageSize.Height;
return Math.Round(Math.Min(displayZoomX, displayZoomY), 2);
}
private void UpdateCurrentPointToStatusBar(MIL_ID EventID) {
double x = 0;
double y = 0;
MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref x);
MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref y);
var imagePoint = new ImagePoint(x, y);
curImagePoint.Text = imagePoint.ToString();
if (_Calibrator != null) {
var staticPoint = _Calibrator.TransformToCalibratedSpace(new ImagePoint(x, y), _ImageSize);
curStaticPoint.Text = staticPoint.ToString();
}
}
#region IDisposible
public void Dispose() {
if (!_Initialized) {
return;
}
RemoveObservable();
if (MilEnvironment.Instance.HasValidLicense()) {
RemoveHookFunc();
RemoveGraphics();
FreeGraphics();
}
ClearGraEventSubscribers();
_Initialized = false;
}
#region TrainRoi & FindRoi Changed Event
private Dictionary<PatternInfo, IGraEventSubscriber> _GraEventSubscribers = new Dictionary<PatternInfo, IGraEventSubscriber>();
public void SetGraEventSubscriber(PatternInfo patternInfo, object viewModel) {
_GraEventSubscribers[patternInfo] = viewModel as IGraEventSubscriber;
}
private void ClearGraEventSubscribers() {
_GraEventSubscribers.Clear();
}
private void SetTrainRoiChangedEvent() {
RemoveTrainRoiChangedEvent();
if (!_TrainRoiChangedDataHandle.IsAllocated) {
if (_trainRoiLabel != MIL.M_NULL) {
_TrainRoiChangedDataHandle = GCHandle.Alloc(_trainRoiLabel);
_OnTrainRoiChangedFuncPtr = new MIL_GRA_HOOK_FUNCTION_PTR(OnTrainRoiChanged);
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED, _OnTrainRoiChangedFuncPtr, GCHandle.ToIntPtr(_TrainRoiChangedDataHandle));
}
}
}
private void SetFindRoiChangedEvent(eRoiIdx roiIdx) {
RemoveFindRoiChangedEvent(roiIdx);
if (!_FindRoiChangedDataHandles[roiIdx].IsAllocated) {
if (_findRoiLabels.ContainsKey(roiIdx) && _findRoiLabels[roiIdx] != MIL.M_NULL) {
_FindRoiChangedDataHandles[roiIdx] = GCHandle.Alloc(_findRoiLabels[roiIdx]);
_OnFindRoiChangedFuncPtrs[roiIdx] = new MIL_GRA_HOOK_FUNCTION_PTR(OnFindRoiChanged);
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED,
_OnFindRoiChangedFuncPtrs[roiIdx], GCHandle.ToIntPtr(_FindRoiChangedDataHandles[roiIdx]));
}
}
}
private void RemoveTrainRoiChangedEvent() {
if (_TrainRoiChangedDataHandle.IsAllocated) {
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED + MIL.M_UNHOOK, _OnTrainRoiChangedFuncPtr, GCHandle.ToIntPtr(_TrainRoiChangedDataHandle));
_OnTrainRoiChangedFuncPtr = null;
_TrainRoiChangedDataHandle.Free();
}
}
private void RemoveFindRoiChangedEvent(eRoiIdx roiIdx) {
if (_FindRoiChangedDataHandles.ContainsKey(roiIdx) && _FindRoiChangedDataHandles[roiIdx].IsAllocated) {
MIL.MgraHookFunction(StaticGraphicList, MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED + MIL.M_UNHOOK, _OnFindRoiChangedFuncPtrs[roiIdx], GCHandle.ToIntPtr(_FindRoiChangedDataHandles[roiIdx]));
_OnFindRoiChangedFuncPtrs[roiIdx] = null;
_FindRoiChangedDataHandles[roiIdx].Free();
}
_FindRoiChangedDataHandles[roiIdx] = new GCHandle();
}
private MIL_INT OnTrainRoiChanged(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr) {
return DoRoiChangedAction(eGraRoiType.TrainRoi, _trainRoiLabel, EventId, UserDataPtr);
}
private MIL_INT OnFindRoiChanged(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr) {
if (HookType == MIL.M_INTERACTIVE_GRAPHIC_STATE_MODIFIED) {
GCHandle retrievedHandle = GCHandle.FromIntPtr(UserDataPtr);
MIL_ID graphicLabel = (MIL_ID)retrievedHandle.Target;
if (_findRoiLabels.ContainsValue(graphicLabel)) {
eRoiIdx roiIdx = _findRoiLabels.Where(x => x.Value == graphicLabel).Select(x => x.Key).FirstOrDefault();
return DoRoiChangedAction(eGraRoiType.FindRoi, graphicLabel, EventId, UserDataPtr, roiIdx);
}
}
return MIL.M_NULL;
}
private MIL_INT DoRoiChangedAction(
eGraRoiType graRoiType, MIL_ID label, MIL_ID EventId, IntPtr UserDataPtr, eRoiIdx roiIdx = eRoiIdx.Roi0) {
try {
if (label == MIL.M_NULL) {
return MIL.M_NULL;
}
MIL_INT isRotatable = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(label), MIL.M_DEFAULT, MIL.M_ROTATABLE, ref isRotatable);
if (isRotatable == MIL.M_DISABLE) {
return MIL.M_NULL;
}
if (!IntPtr.Zero.Equals(UserDataPtr)) {
MIL_INT curState = 0;
MIL.MgraGetHookInfo(EventId, MIL.M_INTERACTIVE_GRAPHIC_STATE, ref curState);
// M_STATE_HANDLE_HOVERED, M_STATE_HANDLE_DRAGGED 필터링시, 두번째 클릭시 InterActive가 해제되는 문제가 있었음.
if (curState == MIL.M_STATE_GRAPHIC_HOVERED) {
ROI findRoi = GetFindRoi(roiIdx);
AddFindRoiLabelNum(findRoi, roiIdx);
return MIL.M_NULL;
}
if (curState == MIL.M_STATE_IDLE) {
return MIL.M_NULL;
}
MIL_INT modifiedGraphicLabel = 0;
MIL.MgraGetHookInfo(EventId, MIL.M_GRAPHIC_LABEL_VALUE, ref modifiedGraphicLabel);
if (modifiedGraphicLabel == label) {
double angle = 0;
MIL.MgraInquireList(StaticGraphicList, MIL.M_GRAPHIC_LABEL(label), MIL.M_DEFAULT, MIL.M_ANGLE, ref angle);
if (_GraEventSubscribers?.Count > 0) {
_GraEventSubscribers[_PatternInfos[roiIdx]]?.UpdateAngleOfRoi(graRoiType, angle);
}
}
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return MIL.M_NULL;
}
#endregion
private void RemoveHookFunc() {
RemoveTrainRoiChangedEvent();
for (int i = 0; i < _FindRoiChangedDataHandles.Count; i++) {
RemoveFindRoiChangedEvent((eRoiIdx)i);
}
if (ThisPtr.IsAllocated) {
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_LEFT_BUTTON_DOWN + MIL.M_UNHOOK, MouseLeftDownHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_MOVE + MIL.M_UNHOOK, MouseLeftMoveHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_RIGHT_BUTTON_DOWN + MIL.M_UNHOOK, MouseRightDownHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MdispHookFunction(DisplayId, MIL.M_MOUSE_WHEEL + MIL.M_UNHOOK, MouseWheelHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
MIL.MgraHookFunction(StaticGraphicList, MIL.M_GRAPHIC_SELECTION_MODIFIED + MIL.M_UNHOOK, GraphicSelectionModifiedHookFuncPtr, GCHandle.ToIntPtr(ThisPtr));
}
ThisPtr.Free();
MouseLeftDownHookFuncPtr = null;
MouseLeftMoveHookFuncPtr = null;
MouseRightDownHookFuncPtr = null;
GraphicSelectionModifiedHookFuncPtr = null;
}
private void RemoveGraphics() {
_patternResultGraphics = null;
_trainGraphics = null;
_findGraphics = null;
_findLabelNumGraphicsDic.Clear();
_gridGuideLine = null;
}
private void RemoveObservable() {
_EventDisposable?.Dispose();
_EventDisposable = null;
}
private void FreeGraphics() {
MIL.MbufFree(ImageId);
MIL.MgraFree(GraphicContext);
MIL.MgraFree(StaticGraphicList);
MIL.MdispFree(DisplayId);
}
#endregion
}
}