553 lines
21 KiB
C#
553 lines
21 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api;
|
|
using Aurora.Api.DataType;
|
|
using Aurora.View;
|
|
using VisionCommon;
|
|
using Hermes;
|
|
using Cognex.VisionPro;
|
|
using Cognex.VisionPro.Display;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using Brush = System.Windows.Media.Brush;
|
|
using Brushes = System.Windows.Media.Brushes;
|
|
using Pen = System.Windows.Media.Pen;
|
|
using Size = System.Windows.Size;
|
|
using Point = System.Windows.Point;
|
|
using Cursor = System.Windows.Forms.Cursor;
|
|
using CogPattern;
|
|
using CogCommon;
|
|
using VisionCommonUI;
|
|
using Cognex.VisionPro.PMAlign;
|
|
using VisionCommonUI.Resources;
|
|
using System.Collections.Generic;
|
|
using System.Windows.Controls.Primitives;
|
|
namespace CogUI {
|
|
/// <summary>
|
|
/// Interaction logic for ImageMaskView.xaml
|
|
/// </summary>
|
|
public partial class ImageMaskView : UserControl, IDisposable {
|
|
public Window ParentWindow { get; set; }
|
|
public ICommand CMD_SetMaskSize { get; }
|
|
public IEnumerable<string> MaskLayoutItems { get; } = MaskRegionUtil.GetMaskLayout();
|
|
|
|
private Logger _logger = new Logger("ImageMaskView");
|
|
private PatternAgentBase _patternAgent;
|
|
private PatternInfo _patternInfo;
|
|
|
|
private CogMaskGraphic _maskGraphic;
|
|
private ICogImage _modelImage = null;
|
|
private Cross _curTrainOrigin;
|
|
|
|
private int _crossLength = 200;
|
|
private int _maskSize = 5;
|
|
private bool _isMaskEnabled = true;
|
|
private const double ZOOM_STEP = 0.1;
|
|
|
|
public ImageMaskView(
|
|
PatternAgentBase patternAgent, PatternInfo patternInfo) {
|
|
InitializeComponent();
|
|
|
|
_patternAgent = patternAgent;
|
|
_patternInfo = patternInfo;
|
|
|
|
CMD_SetMaskSize = new DelegateCommand(SetMaskSize);
|
|
|
|
InitCogDisplay();
|
|
CreateMaskGraphic();
|
|
LoadModelImageToDisplay();
|
|
LoadMaskImageToOverlay();
|
|
LoadTrainOriginInModel();
|
|
|
|
UpdateMouseCursor(_maskSize);
|
|
|
|
DataContext = this;
|
|
}
|
|
|
|
private void InitCogDisplay() {
|
|
cogDisplay.AutoFitWithGraphics = true;
|
|
cogDisplay.VerticalScrollBar = false;
|
|
cogDisplay.HorizontalScrollBar = false;
|
|
cogDisplay.BackColor = System.Drawing.Color.Black;
|
|
cogDisplay.AutoFit = true;
|
|
cogDisplay.DoubleClick += OnDoubleClick;
|
|
}
|
|
|
|
private void OnDoubleClick(object sender, EventArgs e) {
|
|
cogDisplay?.Fit(true);
|
|
}
|
|
|
|
private void CreateMaskGraphic() {
|
|
if (_maskGraphic == null) {
|
|
_maskGraphic = new CogMaskGraphic();
|
|
_maskGraphic.Color = CogColorConstants.DarkGrey;
|
|
}
|
|
}
|
|
|
|
public void Dispose() {
|
|
CogEnvironment.FreeImage(_modelImage);
|
|
_maskGraphic?.Dispose();
|
|
DisplayDrawer.ClearGraphics(cogDisplay);
|
|
cogDisplay.DoubleClick -= OnDoubleClick;
|
|
}
|
|
|
|
private void LoadModelImageToDisplay() {
|
|
var patternMask = _patternAgent.GetPattern(_patternInfo) as IPatternMask;
|
|
_modelImage = patternMask.GetModelImage(); // mark Image
|
|
cogDisplay.Image = _modelImage;
|
|
DisplayDrawer.AddTrainEdge(cogDisplay, _patternAgent, _patternInfo);
|
|
}
|
|
|
|
private void LoadMaskImageToOverlay(ImageMaskEditWindow maskEditWidnow = null) {
|
|
if (maskEditWidnow == null) {
|
|
maskEditWidnow = new ImageMaskEditWindow(cogDisplay.Image, _patternAgent, _patternInfo);
|
|
}
|
|
|
|
var maskEditTool = maskEditWidnow.GetMaskEditTool();
|
|
CogColorConstants color;
|
|
CogMaskGraphicTransparencyConstants maskGraphicTransparency;
|
|
_maskGraphic.Image = (CogImage8Grey)maskEditTool.MaskImage;
|
|
maskEditTool.GetColorAndTransparencyMap(0, out color, out maskGraphicTransparency);
|
|
_maskGraphic.SetTransparencyMap(0, maskGraphicTransparency);
|
|
_maskGraphic.SetColorMap(0, color);
|
|
DisplayDrawer.AddMask(cogDisplay, color, _maskGraphic, CogConstants.KEY_MASK);
|
|
}
|
|
|
|
private void LoadTrainOriginInModel() {
|
|
var trainParam = _patternAgent.GetTrainParam(_patternInfo) as ImageTrainParam;
|
|
_crossLength = (int)(trainParam.TrainRoi.Width * 0.5);
|
|
_curTrainOrigin = trainParam.TrainOrigin.Clone() as Cross;
|
|
AddCross(trainParam);
|
|
}
|
|
|
|
private void OnMouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) {
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private Point GetMousePoint(System.Windows.Forms.MouseEventArgs e) {
|
|
var screenPoint = new ImagePoint(e.X, e.Y);
|
|
var imagePoint = TransformScreenPointToImagePoint(screenPoint);
|
|
|
|
return new Point(imagePoint.X, imagePoint.Y);
|
|
}
|
|
|
|
private void ZoomMinus_Button_Click(object sender, RoutedEventArgs e) {
|
|
RelativeZoomImage(ZOOM_STEP * (-1));
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private void FitImage_Button_Click(object sender, RoutedEventArgs e) {
|
|
cogDisplay.Fit(true);
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private void ZoomPlus_Button_Click(object sender, RoutedEventArgs e) {
|
|
RelativeZoomImage(ZOOM_STEP);
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
public int RelativeZoomImage(double zoom) {
|
|
try {
|
|
double curZoom = cogDisplay.Zoom;
|
|
return AbsZoomImage(curZoom + zoom);
|
|
}
|
|
catch (Exception e) {
|
|
_logger.FuncE(e.Message);
|
|
}
|
|
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
public int AbsZoomImage(double zoom) {
|
|
try {
|
|
if (zoom > 0) {
|
|
cogDisplay.Zoom = zoom;
|
|
}
|
|
return E1.OK;
|
|
}
|
|
catch (Exception e) {
|
|
_logger.FuncE(e.Message);
|
|
}
|
|
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
public ImagePoint TransformScreenPointToImagePoint(ImagePoint src) {
|
|
string screenSpace = "*";
|
|
string imageSpace = "@";
|
|
var transform = cogDisplay.GetTransform(imageSpace, screenSpace);
|
|
|
|
double transformedX, transformedY;
|
|
transform.MapPoint(src.X, src.Y, out transformedX, out transformedY);
|
|
|
|
return new ImagePoint(transformedX, transformedY);
|
|
}
|
|
|
|
private void MaskEditTool_Button_Click(object sender, RoutedEventArgs e) {
|
|
var maskEditWidnow = new ImageMaskEditWindow(
|
|
cogDisplay.Image, _patternAgent, _patternInfo);
|
|
maskEditWidnow.SetMaskImage(_maskGraphic.Image);
|
|
|
|
if (maskEditWidnow.ShowDialog() == true) {
|
|
LoadMaskImageToOverlay(maskEditWidnow);
|
|
UpdateMaskRegionButtonState();
|
|
RefreshUI();
|
|
}
|
|
}
|
|
|
|
private void SaveMask_Button_Click(object sender, RoutedEventArgs e) {
|
|
var patternMask = _patternAgent.GetPattern(_patternInfo) as IPatternMask;
|
|
patternMask.SetMaskImage(_maskGraphic.Image);
|
|
patternMask.SetTrainOrigin(_curTrainOrigin);
|
|
((IPatternFinder)patternMask).Save();
|
|
MessageBoxUtil.ShowMessageBoxOk(StrTokens.MSG_O_SaveCompleted);
|
|
}
|
|
|
|
private void SetMaskSize(object obj) {
|
|
var size = Convert.ToInt32(obj.ToString());
|
|
_maskSize = size;
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private void UpdateMouseCursor(int maskSize) {
|
|
Application.Current.Dispatcher.BeginInvoke(
|
|
new System.Action(() => {
|
|
cogDisplay.Cursor = GetCursor(maskSize);
|
|
}));
|
|
}
|
|
|
|
private Cursor GetCursor(int maskSize) {
|
|
var cursorSize = GetCursorSize(maskSize);
|
|
|
|
if (_isMaskEnabled) {
|
|
return WinformCursorHelper.CreateRectCursor(
|
|
Brushes.Magenta,
|
|
new Pen(Brushes.Magenta, 1),
|
|
new Size(cursorSize, cursorSize));
|
|
}
|
|
else {
|
|
return WinformCursorHelper.CreateRectCursor(
|
|
Brushes.Transparent,
|
|
new Pen(Brushes.Orange, 2),
|
|
new Size(cursorSize, cursorSize));
|
|
}
|
|
}
|
|
|
|
private int GetCursorSize(int maskSize) {
|
|
var curZoomFactor = GetCurZoomFactor();
|
|
var cursorSize = (int)Math.Floor(maskSize * curZoomFactor);
|
|
|
|
if (cursorSize < 1) {
|
|
cursorSize = 1;
|
|
}
|
|
else if (cogDisplay.Width < cursorSize || cogDisplay.Height < cursorSize) {
|
|
cursorSize = Math.Min(cogDisplay.Width, cogDisplay.Height);
|
|
}
|
|
|
|
return cursorSize;
|
|
}
|
|
|
|
private double GetCurZoomFactor() {
|
|
return cogDisplay.Zoom;
|
|
}
|
|
|
|
private void EnableMask_Button_Click(object sender, RoutedEventArgs e) {
|
|
_isMaskEnabled = true;
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private void EnableEraser_Button_Click(object sender, RoutedEventArgs e) {
|
|
_isMaskEnabled = false;
|
|
UpdateMouseCursor(_maskSize);
|
|
}
|
|
|
|
private void ClearMask_Button_Click(object sender, RoutedEventArgs e) {
|
|
_maskGraphic.Image.Dispose();
|
|
//MIL.MdispControl(_cogDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT);
|
|
}
|
|
|
|
private void Cancel_Button_Click(object sender, RoutedEventArgs e) {
|
|
ParentWindow?.Close();
|
|
}
|
|
|
|
private void TrainOrigin_Left_Up_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep() * (-1),
|
|
GetTrainOriginMoveStep() * (-1)));
|
|
}
|
|
|
|
private void TrainOrigin_Right_Up_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep(),
|
|
GetTrainOriginMoveStep() * (-1)));
|
|
}
|
|
|
|
private void TrainOrigin_Up_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
0,
|
|
GetTrainOriginMoveStep() * (-1)));
|
|
}
|
|
|
|
private void TrainOrigin_Left_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep() * (-1),
|
|
0));
|
|
}
|
|
|
|
private void TrainOrigin_Right_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep(),
|
|
0));
|
|
}
|
|
|
|
private void TrainOrigin_Left_Down_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep() * (-1),
|
|
GetTrainOriginMoveStep()));
|
|
}
|
|
|
|
private void TrainOrigin_Down_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(0, GetTrainOriginMoveStep()));
|
|
}
|
|
|
|
private void TrainOrigin_Right_Down_Button_Click(object sender, RoutedEventArgs e) {
|
|
MoveTrainOrigin(new ImagePoint(
|
|
GetTrainOriginMoveStep(),
|
|
GetTrainOriginMoveStep()));
|
|
}
|
|
|
|
private double GetTrainOriginMoveStep() {
|
|
return Convert.ToDouble(trainOriginMoveStep.Value);
|
|
}
|
|
|
|
private void MoveTrainOrigin(ImagePoint moveOffset) {
|
|
var trainParam = _patternAgent.GetTrainParam(_patternInfo) as ImageTrainParam;
|
|
_curTrainOrigin = new Cross((_curTrainOrigin.Origin + moveOffset) as ImagePoint);
|
|
DisplayDrawer.RemoveInteractiveGraphic(cogDisplay, CogConstants.KEY_MASK_CROSS);
|
|
AddCross(trainParam);
|
|
}
|
|
|
|
private void TrainOrigin_Center_Button_Click(object sender, RoutedEventArgs e) {
|
|
var trainParam = _patternAgent.GetTrainParam(_patternInfo) as ImageTrainParam;
|
|
_curTrainOrigin = new Cross(CogEnvironment.GetImageCenter(_modelImage));
|
|
_curTrainOrigin.Origin.X += trainParam.TrainRoi.Left;
|
|
_curTrainOrigin.Origin.Y += trainParam.TrainRoi.Top;
|
|
DisplayDrawer.RemoveInteractiveGraphic(cogDisplay, CogConstants.KEY_MASK_CROSS);
|
|
AddCross(trainParam);
|
|
}
|
|
|
|
private void AddCross(ImageTrainParam trainParam) {
|
|
DisplayDrawer.AddCross(
|
|
cogDisplay, CogColorConstants.Orange,
|
|
new Cross(_curTrainOrigin.Origin.Clone() as ImagePoint, trainParam.TrainRoi.Angle, _crossLength),
|
|
CogConstants.KEY_MASK_CROSS);
|
|
}
|
|
|
|
private void Set_MaskRegion_Button_Click(object sender, RoutedEventArgs e) {
|
|
var toggleButton = sender as ToggleButton;
|
|
var index1d = Convert.ToInt32(toggleButton.Tag.ToString());
|
|
var rowCount = GetMaskLayoutRowCount();
|
|
var colCount = GetMaskLayoutColCount();
|
|
|
|
if ((bool)toggleButton.IsChecked) {
|
|
MaskRegionUtil.SetMaskToMaskImage(
|
|
_maskGraphic.Image, 0,
|
|
rowCount, colCount, index1d);
|
|
toggleButton.Background = new System.Windows.Media.SolidColorBrush(
|
|
System.Windows.Media.Colors.DarkMagenta);
|
|
}
|
|
else {
|
|
MaskRegionUtil.SetMaskToMaskImage(
|
|
_maskGraphic.Image, 255,
|
|
rowCount, colCount, index1d);
|
|
toggleButton.Background = new System.Windows.Media.SolidColorBrush(
|
|
System.Windows.Media.Colors.WhiteSmoke);
|
|
}
|
|
|
|
RefreshUI();
|
|
}
|
|
|
|
private int GetMaskLayoutRowCount() {
|
|
var maskLayout = GetMaskLayout();
|
|
return MaskRegionUtil.GetMaskLayoutRowCount(maskLayout);
|
|
}
|
|
|
|
private int GetMaskLayoutColCount() {
|
|
var maskLayout = GetMaskLayout();
|
|
return MaskRegionUtil.GetMaskLayoutColCount(maskLayout);
|
|
}
|
|
|
|
private string GetMaskLayout() {
|
|
return comboBoxMaskLayout.SelectedItem.ToString();
|
|
}
|
|
|
|
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
|
UpdateMaskRegion();
|
|
}
|
|
|
|
private void UpdateMaskRegion() {
|
|
var rowCount = GetMaskLayoutRowCount();
|
|
var colCount = GetMaskLayoutColCount();
|
|
UpdateMaskRegion(rowCount, colCount);
|
|
UpdateMaskRegionButtonState();
|
|
RefreshUI();
|
|
}
|
|
|
|
private void UpdateMaskRegion(int rowCount, int colCount) {
|
|
gridMaskRegion.Children.Clear();
|
|
gridMaskRegion.RowDefinitions.Clear();
|
|
gridMaskRegion.ColumnDefinitions.Clear();
|
|
|
|
for (int i = 0; i < rowCount; i++) {
|
|
gridMaskRegion.RowDefinitions.Add(new RowDefinition());
|
|
}
|
|
|
|
for (int i = 0; i < colCount; i++) {
|
|
gridMaskRegion.ColumnDefinitions.Add(new ColumnDefinition());
|
|
}
|
|
|
|
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
for (int colIndex = 0; colIndex < colCount; colIndex++) {
|
|
var button = CreateMaskRegionButton(rowCount, colCount, rowIndex, colIndex);
|
|
Grid.SetRow(button, rowIndex);
|
|
Grid.SetColumn(button, colIndex);
|
|
gridMaskRegion.Children.Add(button);
|
|
}
|
|
}
|
|
}
|
|
|
|
private ToggleButton CreateMaskRegionButton(
|
|
int rowCount, int colCount, int rowIndex, int colIndex) {
|
|
var button = new ToggleButton();
|
|
button.Margin = new Thickness(5);
|
|
button.Tag = ((rowIndex * colCount) + colIndex).ToString();
|
|
button.Click += Set_MaskRegion_Button_Click;
|
|
CheckMaskRegionButton(button);
|
|
return button;
|
|
}
|
|
|
|
private void UpdateMaskRegionButtonState() {
|
|
try {
|
|
var rowCount = GetMaskLayoutRowCount();
|
|
var colCount = GetMaskLayoutColCount();
|
|
var maskImage = _maskGraphic.Image;
|
|
|
|
for (int i = 0; i < gridMaskRegion.Children.Count; i++) {
|
|
var toggleButton = gridMaskRegion.Children[i] as ToggleButton;
|
|
SetMaskRegionButtonState(maskImage, toggleButton, rowCount, colCount, i);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_logger.E(e.Message);
|
|
}
|
|
}
|
|
|
|
private void SetMaskRegionButtonState(
|
|
ICogImage maskImage,
|
|
ToggleButton toggleButton,
|
|
int rowCount, int colCount, int index1d) {
|
|
var threshold = 126;
|
|
var brightness = GetMaskRegionBrightness(maskImage, rowCount, colCount, index1d);
|
|
|
|
if (brightness.Avg <= threshold) {
|
|
CheckMaskRegionButton(toggleButton);
|
|
}
|
|
else {
|
|
UncheckMaskRegionButton(toggleButton);
|
|
}
|
|
}
|
|
|
|
private BrightnessResult GetMaskRegionBrightness(
|
|
ICogImage maskImage, int rowCount, int colCount, int index1d) {
|
|
var brightness = new BrightnessResult(new ImagePoint(), 0, 0, 0);
|
|
|
|
try {
|
|
var grayImageSize = CogEnvironment.GetImageSize(maskImage);
|
|
var rectangle = MaskRegionUtil.GetMaskRectangle(
|
|
grayImageSize.Width, grayImageSize.Height,
|
|
rowCount, colCount, index1d);
|
|
var roi = new ROI(
|
|
new ImagePoint(rectangle.CenterX, rectangle.CenterY),
|
|
(int)rectangle.Width, (int)rectangle.Height);
|
|
|
|
var cropImage = CogEnvironment.CropImage(maskImage, roi);
|
|
brightness = CogEnvironment.GetBrightness(cropImage, roi.Center);
|
|
}
|
|
catch (Exception e) {
|
|
_logger.E(e.Message);
|
|
}
|
|
|
|
return brightness;
|
|
}
|
|
|
|
private void CheckMaskRegionButton(ToggleButton toggleButton) {
|
|
toggleButton.IsChecked = true;
|
|
toggleButton.Background = new System.Windows.Media.SolidColorBrush(
|
|
System.Windows.Media.Colors.DarkMagenta);
|
|
}
|
|
|
|
private void UncheckMaskRegionButton(ToggleButton toggleButton) {
|
|
toggleButton.IsChecked = false;
|
|
toggleButton.Background = new System.Windows.Media.SolidColorBrush(
|
|
System.Windows.Media.Colors.WhiteSmoke);
|
|
}
|
|
|
|
private void UpdateGridLine() {
|
|
var imageSize = CogEnvironment.GetImageSize(_maskGraphic.Image);
|
|
var rowCount = GetMaskLayoutRowCount();
|
|
var colCount = GetMaskLayoutColCount();
|
|
var lines = new List<Line<ImagePoint>>();
|
|
var trainParam = _patternAgent.GetTrainParam(_patternInfo) as ImageTrainParam;
|
|
|
|
// Vertical lines
|
|
for (int colIndex = 1; colIndex < colCount; colIndex++) {
|
|
var rectangle = MaskRegionUtil.GetMaskRectangle(
|
|
imageSize.Width, imageSize.Height,
|
|
rowCount, colCount, 1, colIndex);
|
|
var lineStart = new ImagePoint(rectangle.X, 0);
|
|
var lineEnd = new ImagePoint(rectangle.X, imageSize.Height);
|
|
var drawOffset = new ImagePoint(
|
|
trainParam.TrainRoi.Left,
|
|
trainParam.TrainRoi.Top);
|
|
|
|
var verticalLine = new Line<ImagePoint>(
|
|
lineStart + drawOffset as ImagePoint,
|
|
lineEnd + drawOffset as ImagePoint);
|
|
lines.Add(verticalLine);
|
|
}
|
|
|
|
// Horizontal lines
|
|
for (int rowIndex = 1; rowIndex < rowCount; rowIndex++) {
|
|
var rectangle = MaskRegionUtil.GetMaskRectangle(
|
|
imageSize.Width, imageSize.Height,
|
|
rowCount, colCount, rowIndex, 1);
|
|
var lineStart = new ImagePoint(0, rectangle.Y);
|
|
var lineEnd = new ImagePoint(imageSize.Width, rectangle.Y);
|
|
var drawOffset = new ImagePoint(
|
|
trainParam.TrainRoi.Left,
|
|
trainParam.TrainRoi.Top);
|
|
|
|
var horizontalLine = new Line<ImagePoint>(
|
|
lineStart + drawOffset as ImagePoint,
|
|
lineEnd + drawOffset as ImagePoint);
|
|
lines.Add(horizontalLine);
|
|
}
|
|
|
|
DisplayDrawer.AddLines(cogDisplay, CogColorConstants.LightGrey, lines, CogConstants.KEY_MASK);
|
|
}
|
|
|
|
private void RefreshUI() {
|
|
cogDisplay.InteractiveGraphics.Clear();
|
|
UpdateGridLine();
|
|
DisplayDrawer.AddTrainEdge(cogDisplay, _patternAgent, _patternInfo);
|
|
DisplayDrawer.AddMask(cogDisplay, CogColorConstants.DarkRed, _maskGraphic, CogConstants.KEY_MASK);
|
|
MoveTrainOrigin(new ImagePoint());
|
|
}
|
|
}
|
|
}
|