File LUTControl.xaml.cs¶
File List > PGRControls > LUTControl.xaml.cs
Go to the documentation of this file
//=============================================================================
// Copyright (c) 2026 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR).
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================
using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using SpinnakerNET.GenApi;
namespace SpinnakerNET.GUI
{
namespace WPFControls
{
public sealed partial class LUTControl : BaseClass
{
private bool _disposed = false;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LUTControl));
int _width = 2048;
int _height = 512;
private IInteger m_indexNode;
private IInteger m_valueNode;
private IBool m_enableNode;
private IRegister m_lutValueAll;
private bool _LUTEnabled;
private const float MinPointRange = 10;
private const uint NumGridPartitions = 4;
private OpenFileDialog m_openFileDialog;
private SaveFileDialog m_saveFileDialog;
private ObservableCollection<Point>_points = new ObservableCollection<Point>();
private uint[] m_lutEntries = null;
private ArrayList m_keyPoints = new ArrayList();
private Point m_currentSelectedPoint = new Point();
private bool m_isCurrentlyMovingPoint;
private LineStyle _lineStyle;
private int m_currentSelectedPointPosition;
private float m_pointRangeMax = 0;
private float m_pointRangeMin = 0;
private bool m_stopUpdateEntries;
private List<Ellipse>_paintedKeyPoints;
private int _xStart;
private int _xMiddle;
private int _xEnd;
private int _yMiddle;
private int _yEnd;
private bool _skipCallBack;
#region FIELDS
public bool LUTEnabled
{
get
{
return _LUTEnabled;
}
set
{
_LUTEnabled = value;
NotifyPropertyChanged("LUTEnabled");
}
}
public int XStart
{
get
{
return _xStart;
}
set
{
_xStart = value;
NotifyPropertyChanged("XStart");
}
}
public int XMiddle
{
get
{
return _xMiddle;
}
set
{
_xMiddle = value;
NotifyPropertyChanged("XMiddle");
}
}
public int XEnd
{
get
{
return _xEnd;
}
set
{
_xEnd = value;
NotifyPropertyChanged("XEnd");
}
}
public int YMiddle
{
get
{
return _yMiddle;
}
set
{
_yMiddle = value;
NotifyPropertyChanged("YMiddle");
}
}
public int YEnd
{
get
{
return _yEnd;
}
set
{
_yEnd = value;
NotifyPropertyChanged("YEnd");
}
}
public int GraphWidth
{
get
{
return _width;
}
set
{
_width = value;
NotifyPropertyChanged("GraphWidth");
}
}
public int GraphHeight
{
get
{
return _height;
}
set
{
_height = value;
NotifyPropertyChanged("GraphHeight");
}
}
public ObservableCollection<Point>Points
{
get
{
return _points;
}
set
{
_points = value;
NotifyPropertyChanged("Points");
}
}
#endregion
#region CONSTRUCTORS
public LUTControl()
{
this.DataContext = this;
InitializeComponent();
_paintedKeyPoints = new List<Ellipse>();
SetupAxisLabels();
ResetLUTEntries();
UpdatePointsOnUI();
m_openFileDialog = new OpenFileDialog();
m_openFileDialog.FileName = "lutdata";
m_openFileDialog.Filter = "Look up table data files (*.lut)|*.lut";
m_saveFileDialog = new SaveFileDialog();
m_saveFileDialog.Filter = "Look up table data files (*.lut)|*.lut";
}
~LUTControl()
{
Disconnect();
}
internal LUTControl(LUTControl originalControl)
{
InitializeComponent();
// Common Properties
this.SetMapper(originalControl.GetMapper());
this.Connect(
originalControl.NodeMap, originalControl.GetNodeToControl(), originalControl.GetControlNameLabel());
this.SetNameLabelBoldness(originalControl.NameLabelBoldness);
this.SetVisibility(originalControl.Visibility);
this.SetControlID(originalControl.ControlID);
this.SetMin(originalControl.GetMin());
this.SetMax(originalControl.GetMax());
this.SetControlNameLabel(originalControl.ControlNameLabel);
this.SetNameLabelVisibility(originalControl.GetNameLabelVisibility());
this.SetNameLabelBoldness(originalControl.GetNameLabelBoldness());
try
{
this.SetToolTip(originalControl.GetToolTip());
}
catch
{
}
this.SetMaximumControlSize(originalControl.GetMaximumControlSize());
this.SetMinimumControlSize(originalControl.GetMinimumControlSize());
this.SetControlHeight(originalControl.GetControlHeight());
this.SetControlWidth(originalControl.GetControlWidth());
this.SetRefreshTime(originalControl.GetRefreshTime());
this.SetMargin(originalControl.GetMargin());
}
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
// Consider GenICam callbacks as unmanaged resource
Disconnect();
_disposed = true;
}
// Call Dispose in the base class.
base.Dispose(disposing);
}
#endregion
#region ICameraControlInterface
public override void Connect(INodeMap nodemap, string nodename, string namelabel = "")
{
if (nodemap == null)
{
throw new Exception("NodeMap is null.");
}
// Check whether LUT is supported on this camera
try
{
this._nodeMap = nodemap;
m_enableNode = nodemap.GetNode<IBool>("LUTEnable");
if (m_enableNode == null)
{
// Remove inner children
IsEnabled = false;
_featureAvailable = false;
return;
}
// Set control status
LUTEnabled = m_enableNode.Value;
// Get SelectorNode
m_indexNode = nodemap.GetNode<IInteger>("LUTIndex");
m_valueNode = nodemap.GetNode<IInteger>("LUTValue");
m_lutValueAll = nodemap.GetNode<IRegister>("LUTValueAll");
chkEnableLUT.Connect(nodemap, "LUTEnable", "");
cboLUTBanks.Connect(nodemap, "LUTSelector", "");
// Check whether LUT is supported
if (m_enableNode == null || m_indexNode == null || m_valueNode == null || m_lutValueAll == null ||
!m_enableNode.IsImplemented || !m_enableNode.IsAvailable)
{
throw new Exception(string.Format("LUT is not supported by current device"));
}
if (m_indexNode.IsAvailable && m_valueNode.IsAvailable)
{
GraphHeight = (int) m_valueNode.Max - (int) m_valueNode.Min + 1;
GraphWidth = (int) m_indexNode.Max - (int) m_indexNode.Min + 1;
SetupAxisLabels();
}
// Initialize Drawing Area
if (LUTEnabled)
{
// initialize the lut entries from camera
OnLoadFromCamera();
}
// Register GenIcam callback
RegisterGeniCamCallbacks();
_featureAvailable = true;
}
catch (Exception ex)
{
log.Debug("LUT feature is not available.", ex);
// Remove inner children
_featureAvailable = false;
}
// Acquire device serial number
if (string.IsNullOrWhiteSpace(_serialNumber))
{
_serialNumber = RetrieveSerialNumber(nodemap);
}
// Acquire device model name
if (string.IsNullOrWhiteSpace(_deviceModelName))
{
_deviceModelName = RetrieveModelName(nodemap);
}
if (!_featureAvailable)
{
log.Debug(string.Format("{0}LUT is not supported by current device.", FormattedSerialNumber));
throw new Exception(
string.Format("{0}LUT is not supported by current device.", FormattedSerialNumber));
}
_callbackRegistered = true;
RegisterInterfaceEvents();
}
public override void Disconnect()
{
if (_callbackRegistered)
{
UnregisterGeniCamCallbacks();
chkEnableLUT.Disconnect();
cboLUTBanks.Disconnect();
base.Disconnect();
}
}
private void RegisterGeniCamCallbacks()
{
if (m_enableNode != null)
{
m_enableNode.Updated += new NodeEventHandler(enableNode_Updated);
}
if (m_valueNode != null)
{
m_valueNode.Updated += new NodeEventHandler(m_valueNode_Updated);
}
_callbackRegistered = true;
}
private void UnregisterGeniCamCallbacks()
{
if (_callbackRegistered)
{
if (m_enableNode != null)
{
m_enableNode.Updated -= new NodeEventHandler(enableNode_Updated);
}
if (m_valueNode != null)
{
m_valueNode.Updated -= new NodeEventHandler(m_valueNode_Updated);
}
_callbackRegistered = false;
}
}
void m_valueNode_Updated(INode node)
{
if (_skipCallBack)
{
return;
}
if (!IsVisible)
{
return;
}
try
{
_skipCallBack = true;
int index = 0;
int value = 0;
if (m_indexNode != null && m_indexNode.IsReadable)
{
index = (int) m_indexNode.Value;
}
if (m_valueNode != null && m_valueNode.IsReadable)
{
value = (int) m_valueNode.Value;
}
UpdateLutEntries(index, value);
}
catch (System.Exception /*ex*/)
{
}
finally
{
_skipCallBack = false;
}
}
private void selectorNode_Updated(INode node)
{
if (_skipCallBack)
{
return;
}
if (!IsVisible)
{
return;
}
try
{
_skipCallBack = true;
OnLoadFromCamera();
}
catch (System.Exception ex)
{
log.Debug(ex);
}
finally
{
_skipCallBack = false;
}
}
private void enableNode_Updated(INode node)
{
if (_skipCallBack)
{
return;
}
if (!IsVisible)
{
return;
}
try
{
_skipCallBack = true;
if (m_enableNode != null && m_enableNode.IsReadable)
{
LUTEnabled = m_enableNode.Value;
if (m_indexNode.IsAvailable && m_valueNode.IsAvailable)
{
GraphHeight = (int) m_valueNode.Max - (int) m_valueNode.Min + 1;
GraphWidth = (int) m_indexNode.Max - (int) m_indexNode.Min + 1;
SetupAxisLabels();
OnLoadFromCamera();
}
}
}
catch (System.Exception ex)
{
log.Debug(ex);
}
finally
{
_skipCallBack = false;
}
}
private bool DetermineDeviceEndianness()
{
bool isBigEndian = true;
bool operationCompleted = false;
// Check for interface type
// U3V is always small endian
try
{
Integer U3VCPCapability = _nodeMap.GetNode<Integer>("U3VCPCapability");
if (U3VCPCapability != null)
{
isBigEndian = false;
}
operationCompleted = true;
}
catch (Exception ex)
{
log.Debug(ex);
}
if (operationCompleted)
{
return isBigEndian;
}
try
{
Enumeration DeviceRegistersEndianness = _nodeMap.GetNode<Enumeration>("DeviceRegistersEndianness");
long bigEndianValue = 0;
foreach(EnumEntry entry in DeviceRegistersEndianness.Entries)
{
if (entry.DisplayName.ToLower().Contains("standard"))
{
bigEndianValue = entry.Value;
}
}
if (DeviceRegistersEndianness.Value == bigEndianValue)
{
isBigEndian = true;
}
else
{
isBigEndian = false;
}
operationCompleted = true;
}
catch (Exception ex)
{
log.Debug(ex);
}
if (operationCompleted)
{
return isBigEndian;
}
else
{
throw new SpinnakerException("Cannot determine device endianness.");
}
}
private void OnLoadFromCamera()
{
try
{
if (m_valueNode == null || !m_valueNode.IsReadable || !m_indexNode.IsReadable)
{
return;
}
byte[] entries = new byte[m_lutValueAll.Length];
uint[] intEntries = new uint[entries.Length / 4];
// Get Byte array
m_lutValueAll.Read(out entries);
bool isBigEndian = DetermineDeviceEndianness();
// convert byte array to little endian as BitConverter is in little endian
if (isBigEndian)
{
SwapSingles(entries);
}
for (int i = 0; i < entries.Length; i += 4)
{
intEntries[i / 4] = BitConverter.ToUInt32(entries, i);
}
SetLutEntries(intEntries);
UpdatePointsOnUI();
log.Logger.Log(null, log4net.Core.Level.Notice, "LUT data loaded from device", null);
}
catch (Exception ex)
{
log.Error("There was a problem loading LUT data from device.", ex);
}
}
private static unsafe void SwapSingles(byte[] data)
{
int cnt = data.Length / 4;
fixed(byte * d = data)
{
byte * p = d;
while (cnt-- > 0)
{
byte a = *p;
p++;
byte b = *p;
*p = *(p + 1);
p++;
*p = b;
p++;
*(p - 3) = *p;
*p = a;
p++;
}
}
}
internal void UpdateControlStatus()
{
try
{
IValue m_enableNode = _nodeMap.GetNode<IBool>("LUTEnable");
}
catch (System.Exception /*ex*/)
{
this.IsEnabled = false;
return;
}
}
public override void SetToolTip(string tooltip)
{
this.ToolTip = tooltip;
}
public override void SetControlNameLabel(string nameLabel)
{
return;
}
public override void SetNameLabelVisibility(System.Windows.Visibility visibility)
{
return;
}
public override void SetRefreshTime(int seconds)
{
}
public override void Refresh()
{
}
public override string GetToolTip()
{
return this.ToolTip.ToString();
}
public override string GetControlNameLabel()
{
return string.Empty;
}
public override System.Windows.Visibility GetNameLabelVisibility()
{
return this.Visibility;
}
#endregion
#region UI Controls
private void SetupAxisLabels()
{
XStart = 0;
XMiddle = (int) GraphWidth / 2 - 1;
XEnd = (int) GraphWidth - 1;
YMiddle = (int) GraphHeight / 2 - 1;
YEnd = (int) GraphHeight - 1;
}
private void SetLutEntries(uint[] entries)
{
m_lutEntries = new uint[_width];
for (uint i = 0; i < m_lutEntries.Length; i++)
{
m_lutEntries[i] = (uint) entries[i];
}
// set default line style to free mode.
_lineStyle = LineStyle.Free;
}
private void ResetLUTEntries()
{
if (_width == 0)
{
log.Debug("Problem resetting LUT entries. Width is zero.");
return;
}
float slope = (float) _height / (float) _width;
m_lutEntries = new uint[_width];
for (int i = 0; i < m_lutEntries.Length; i++)
{
uint last_y = (uint)((float) i * slope);
if (last_y < 0)
last_y = (int) 0;
if (last_y > _height)
last_y = (uint) _height;
m_lutEntries[i] = last_y; // Canvas's origin is at top left corner.
}
}
private void UpdatePointsOnUI()
{
if (m_lutEntries == null)
{
return;
}
ObservableCollection<Point>points = new ObservableCollection<Point>();
for (int x = 0; x < m_lutEntries.Length; x += 1)
{
points.Add(new Point(x, m_lutEntries[x]));
}
this.Points = points;
if (_lineStyle != LineStyle.Free)
{
DrawKeyPoints();
}
else
{
ClearKeyPoints();
}
}
// Draw a simple graph.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
const double margin = 10;
double xmax = canGraph.Width - margin;
double ymax = canGraph.Height - margin;
// Make the X axis.
GeometryGroup xaxis_geom = new GeometryGroup();
xaxis_geom.Children.Add(new LineGeometry(new Point(0, 0), new Point(canGraph.Width, 0)));
Path xaxis_path = new Path();
xaxis_path.StrokeThickness = 1;
xaxis_path.Stroke = Brushes.Black;
xaxis_path.Data = xaxis_geom;
canGraph.Children.Add(xaxis_path);
// Make the Y axis.
GeometryGroup yaxis_geom = new GeometryGroup();
yaxis_geom.Children.Add(new LineGeometry(new Point(0, 0), new Point(0, canGraph.Height)));
Path yaxis_path = new Path();
yaxis_path.StrokeThickness = 1;
yaxis_path.Stroke = Brushes.Black;
yaxis_path.Data = yaxis_geom;
canGraph.Children.Add(yaxis_path);
}
private void ClearKeyPoints()
{
// clear current ones
foreach(Ellipse pt in _paintedKeyPoints)
{
try
{
canGraph.Children.Remove(pt);
}
catch
{
}
}
_paintedKeyPoints.Clear();
}
private void DrawKeyPoints()
{
ClearKeyPoints();
foreach(Point point in m_keyPoints)
{
Ellipse myEllipse = new Ellipse();
myEllipse.Fill = Brushes.Red;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.Red;
myEllipse.Width = 10;
myEllipse.Height = 10;
Canvas.SetTop(myEllipse, _height - point.Y - (myEllipse.Height / 2));
Canvas.SetLeft(myEllipse, point.X - (myEllipse.Width / 2));
canGraph.Children.Add(myEllipse);
_paintedKeyPoints.Add(myEllipse);
}
}
private void UpdateKeyPoints(uint numOfKeyPoints)
{
m_keyPoints.Clear();
float outputMax = _height;
for (int i = 0; i < numOfKeyPoints; i++)
{
float entryValue = m_lutEntries[(m_lutEntries.Length - 1) * i / (numOfKeyPoints - 1)];
if (((numOfKeyPoints - 1) == 0) || outputMax == 0)
{
log.Debug(string.Format(
"Invalid data for new key point. numOfkeypoints == {0}, outputMax == {1}",
numOfKeyPoints,
outputMax));
continue;
}
m_keyPoints.Add(new Point(
(i * (_width - 1)) / (numOfKeyPoints - 1), _height - ((entryValue * _height) / outputMax)));
}
}
private int FindClosestPoint(float x)
{
int index = 0;
for (int i = 1; i < m_keyPoints.Count; i++)
{
float distance = (float) Math.Abs(((Point) m_keyPoints[i]).X - x);
float minDistance = (float) Math.Abs(((Point) m_keyPoints[index]).X - x);
if (distance < minDistance)
{
index = i;
}
}
return index;
}
private void UpdateLutEntries(int index, int value)
{
if (m_lutEntries != null)
{
m_lutEntries[index] = (uint) value;
UpdatePointsOnUI();
}
}
private void UpdateLutEntries()
{
if (m_keyPoints.Count < 2)
{
// should have at least 2 key point, otherwise set all value zero
if (m_lutEntries != null)
{
m_lutEntries.Initialize();
}
return;
}
if (_lineStyle == LineStyle.Linear)
{
int keyPointIndex = 0;
Point startKeyPoint = (Point) m_keyPoints[keyPointIndex];
Point endKeyPoint = (Point) m_keyPoints[keyPointIndex + 1];
// line up dots
for (int index = 0; index <= m_lutEntries.Length - 1; index++)
{
int coordinateXForGraphic = (index * _width) / m_lutEntries.Length;
if (coordinateXForGraphic < startKeyPoint.X)
{
m_lutEntries[index] = 0;
continue;
}
if (coordinateXForGraphic > endKeyPoint.X)
{
keyPointIndex++;
if (keyPointIndex < m_keyPoints.Count - 1)
{
startKeyPoint = (Point) m_keyPoints[keyPointIndex];
endKeyPoint = (Point) m_keyPoints[keyPointIndex + 1];
}
else
{
m_lutEntries[index] = 0;
continue;
}
}
float relatedHeight =
(float) -
(startKeyPoint.Y - endKeyPoint.Y); // this equation is from (outputMax- startKeyPoint.Y)
// -(outputMax - endKeyPoint.Y);
if ((startKeyPoint.X - endKeyPoint.X) == 0)
{
log.Debug("startKeyPoint.X == endKeyPoint.X! Abortn updating LUT Entries.");
return;
}
float relatedYoffsetToStartKeyPoint = (float)(coordinateXForGraphic - startKeyPoint.X) *
relatedHeight / (float)(startKeyPoint.X - endKeyPoint.X);
m_lutEntries[index] =
(uint)((int) relatedYoffsetToStartKeyPoint + _height - (int) startKeyPoint.Y);
}
}
else if (_lineStyle == LineStyle.Spline)
{
// spline mode
int numOfKeyPoints = m_keyPoints.Count;
float[] keyPointX = new float[numOfKeyPoints];
float[] keyPointY = new float[numOfKeyPoints];
for (int i = 0; i < numOfKeyPoints; i++)
{
keyPointX[i] = (float)((Point) m_keyPoints[i]).X;
keyPointY[i] = (float)((Point) m_keyPoints[i]).Y;
}
float[] tangentValueOfKeyPointY = MathUtilities.GetTangentPoints(keyPointY, numOfKeyPoints);
for (float i = keyPointX[0]; i <= keyPointX[numOfKeyPoints - 1]; i++)
{
int index = Convert.ToInt32(i);
float entryValue = MathUtilities.SplineFunction(
keyPointX, keyPointY, tangentValueOfKeyPointY, i, numOfKeyPoints);
m_lutEntries[index] = (uint)(_height - (int) entryValue);
}
// finalize the entries' data
Point startKeyPoint = (Point) m_keyPoints[0];
Point endKeyPoint = (Point) m_keyPoints[m_keyPoints.Count - 1];
for (int i = 0; i < m_lutEntries.Length; i++)
{
float coordinateXForGraphic = (i * _width) / m_lutEntries.Length;
if (coordinateXForGraphic < startKeyPoint.X || coordinateXForGraphic > endKeyPoint.X)
{
m_lutEntries[i] = 0;
continue;
}
if (m_lutEntries[i] < 0)
{
m_lutEntries[i] = 0;
}
else if (m_lutEntries[i] > _height)
{
m_lutEntries[i] = (uint) _height;
}
}
}
else
{
// free mode!?
// actually if it is free mode, this function will never called
// so it might be a bug if code goes here and current line style is free.
log.Error(string.Format("{0}. Unexpected drawing mode.", _lineStyle));
}
}
private void canGraph_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
float x = (float) e.GetPosition(this.canGraph).X;
float y = (float) e.GetPosition(this.canGraph).Y;
if (_lineStyle == LineStyle.Free)
{
// do nothing
}
else
{
if (m_isCurrentlyMovingPoint)
{
int tempIndex = FindClosestPoint(x);
m_keyPoints.RemoveAt(tempIndex);
}
int pointIndex;
for (pointIndex = 0; pointIndex < m_keyPoints.Count; pointIndex++)
{
double px = ((Point) m_keyPoints[pointIndex]).X;
if (px > x)
{
// find the position which the point should insert
break;
}
}
m_currentSelectedPointPosition = pointIndex;
if (pointIndex == 0)
{
m_pointRangeMin = 0;
// TODO: fix no key point bug
m_pointRangeMax = (float)((Point) m_keyPoints[0]).X;
}
else if (pointIndex > m_keyPoints.Count - 1)
{
m_pointRangeMax = _width;
m_pointRangeMin = (float)((Point) m_keyPoints[pointIndex - 1]).X;
}
else
{
m_pointRangeMax = (float)((Point) m_keyPoints[pointIndex]).X;
m_pointRangeMin = (float)((Point) m_keyPoints[pointIndex - 1]).X;
}
}
// Update graph
UpdatePointsOnUI();
}
private void canGraph_MouseMove(object sender, MouseEventArgs e)
{
float x = (float) e.GetPosition(this.canGraph).X;
float y = (float) e.GetPosition(this.canGraph).Y;
if (x > _width)
{
// take care of the corner condition to allow setting free line at 0 and 511
x = _width;
}
else if (x < 0)
{
// take care of the corner condition to allow setting free line at 0
x = 0;
}
if (y > _height)
{
y = _height;
}
else if (y < 0)
{
y = 0;
}
if (_lineStyle == LineStyle.Free)
{
Mouse.OverrideCursor = null;
if (e.LeftButton == MouseButtonState.Pressed && !m_stopUpdateEntries)
{
int endIndex = (int) x;
int startIndex = (int) m_currentSelectedPoint.X;
while (startIndex != endIndex)
{
try
{
m_lutEntries[startIndex] = (uint)(y);
if (startIndex > endIndex)
{
startIndex--;
}
else
{
startIndex++;
}
}
catch (System.Exception ex)
{
log.Debug(ex);
return;
}
}
m_currentSelectedPoint.X = x;
// Update graphics
UpdatePointsOnUI();
}
else
{
m_currentSelectedPoint.X = x;
m_stopUpdateEntries = false;
}
}
else
{
if (m_keyPoints.Count == 0)
{
log.Debug("Key points count == 0");
return;
}
float distance = (float) Math.Abs(((Point) m_keyPoints[FindClosestPoint(x)]).X - x);
if (distance < MinPointRange)
{
m_isCurrentlyMovingPoint = true;
Mouse.OverrideCursor = Cursors.SizeAll;
}
else
{
m_isCurrentlyMovingPoint = false;
Mouse.OverrideCursor = Cursors.Cross;
}
if (m_currentSelectedPointPosition != -1)
{
// take care of the corner condition to allow setting keypoints at 0 and 511
if (x == -1)
{
m_currentSelectedPoint.X = 0;
}
else if (x == _width)
{
m_currentSelectedPoint.X = _width - 1;
}
else
{
m_currentSelectedPoint.X = x;
}
m_currentSelectedPoint.Y = _height - y;
if (m_currentSelectedPoint.X <= m_pointRangeMax && m_currentSelectedPoint.X >= m_pointRangeMin)
{
m_keyPoints.Insert(m_currentSelectedPointPosition, m_currentSelectedPoint);
Mouse.OverrideCursor = Cursors.SizeAll;
// update normal points
UpdateLutEntries();
m_keyPoints.Remove(m_currentSelectedPoint);
// Update graphic
UpdatePointsOnUI();
}
else
{
UpdateLutEntries();
// Update graphic
UpdatePointsOnUI();
}
}
}
}
private void canGraph_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_lineStyle == LineStyle.Free)
{
// do nothing
}
else
{
// start to insert a key point
if (m_currentSelectedPointPosition != -1 && m_currentSelectedPoint.X <= m_pointRangeMax &&
m_currentSelectedPoint.X >= m_pointRangeMin)
{
if (m_currentSelectedPoint.Y < 0)
{
m_currentSelectedPoint.Y = 0;
}
else if (m_currentSelectedPoint.Y > (float) _height)
{
m_currentSelectedPoint.Y = _height;
}
m_keyPoints.Insert(m_currentSelectedPointPosition, m_currentSelectedPoint);
}
m_currentSelectedPointPosition = -1;
if (m_keyPoints.Count < 2)
{
// if there is less than 2 key points,
// it will cause problem of update LUT entries
UpdateKeyPoints(2);
}
UpdateLutEntries();
}
Mouse.OverrideCursor = null;
// Update graph
UpdatePointsOnUI();
}
private void canGraph_MouseLeave(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = null;
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox cbo = sender as ComboBox;
switch (cbo.SelectedIndex)
{
case 0:
// Free
_lineStyle = LineStyle.Free;
UpdateKeyPoints(0);
break;
case 1:
// Linear
_lineStyle = LineStyle.Linear;
UpdateKeyPoints((NumGridPartitions * 2) + 1);
UpdateLutEntries();
break;
case 2:
// Spline
_lineStyle = LineStyle.Spline;
UpdateKeyPoints((NumGridPartitions * 2) + 1);
UpdateLutEntries();
break;
default:
// Free
break;
}
// Update graph
UpdatePointsOnUI();
}
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
ResetLUTEntries();
UpdatePointsOnUI();
cbo_linestyle.SelectedIndex = 0;
}
private void SaveToFile_Click(object sender, RoutedEventArgs e)
{
string initialFileName = "TempLUT";
m_saveFileDialog.FileName = initialFileName + ".lut";
if (m_saveFileDialog.ShowDialog() == true)
{
m_stopUpdateEntries = true;
System.IO.StreamWriter fileStream;
try
{
fileStream = new System.IO.StreamWriter(m_saveFileDialog.FileName);
}
catch (UnauthorizedAccessException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. The access is unauthorized. Please contact administrator for more information.\n",
"Error Opening File",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (System.Security.SecurityException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file due to security policy.\n",
"SecurityException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (ArgumentException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. Invalid file name or mode.\n",
"ArgumentException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (System.IO.IOException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. Read file data failed.\n",
"IOException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
if (this.m_lutEntries == null)
{
System.Windows.Forms.MessageBox.Show(
"Cannot Read LUT Entry file. Read file data failed\n",
"Read Data Fail",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
for (uint i = 0; i < m_lutEntries.Length; ++i)
{
string currLine;
try
{
currLine = string.Format("{0},{1}", i, m_lutEntries[i]);
fileStream.WriteLine(currLine);
}
catch (FormatException ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
fileStream.Close();
System.Windows.Forms.MessageBox.Show(
"There was an argument which does not meet the parameter specifications. Aborting file write.",
"FormatException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
break;
}
catch (System.IO.IOException ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
fileStream.Close();
System.Windows.Forms.MessageBox.Show(
"Error writing the current string to file. Aborting file write.",
"IOException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
break;
}
catch (ArgumentNullException ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
fileStream.Close();
System.Windows.Forms.MessageBox.Show(
"Error writing to file. The current string is null. Aborting file write",
"ArgumentNullException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
break;
}
}
fileStream.Close();
}
}
private void LoadFromFile_Click(object sender, RoutedEventArgs e)
{
if (m_openFileDialog.ShowDialog() == true)
{
// fix a bug: when user click close dialog and mouse is on the drawing area,
// the data in m_lutEntries will be overwrite (it means that click will also affect to drawing
// area), so the update from drawing area should stop now when open File Dialog shows up
m_stopUpdateEntries = true;
System.IO.StreamReader fileStream;
try
{
fileStream = new System.IO.StreamReader(m_openFileDialog.FileName);
}
catch (UnauthorizedAccessException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. The access is unauthorized.\n Please contact administrator for more information.\n",
"UnauthorizedAccessException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (System.Security.SecurityException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file due to security policy\n",
"SecurityException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (ArgumentException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. Invalid file name or mode\n",
"ArgumentException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
catch (System.IO.IOException /*ex*/)
{
System.Windows.Forms.MessageBox.Show(
"Cannot open the file. Read file data failed\n",
"IOException",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
for (uint i = 0; i < m_lutEntries.Length; i++)
{
uint currInput = 0;
uint currResult = 0;
string currLine = fileStream.ReadLine();
if (currLine == null)
{
m_lutEntries[i] = 0;
continue;
}
string[] numbersFromCurrLine = currLine.Split(new char[]{','});
if (numbersFromCurrLine.Length != 2)
{
System.Windows.Forms.MessageBox.Show(
"Required format not found. Aborting file load.",
"Error reading LUT data from file",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
fileStream.Close();
return;
}
try
{
currInput = Convert.ToUInt32(numbersFromCurrLine[0]);
currResult = Convert.ToUInt32(numbersFromCurrLine[1]);
}
catch (Exception ex)
{
Debug.WriteLine("Invalid LUT data detected. {1}", ex.Message);
m_lutEntries[i] = 0;
continue;
}
if (currInput < 0 || currInput >= m_lutEntries.Length || currInput != i)
{
System.Windows.Forms.DialogResult result;
result = System.Windows.Forms.MessageBox.Show(
"LUT data appears to be invalid\r\n. Do you wish to abort file load.",
"Invalid LUT data detected",
System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Error);
if (result == System.Windows.Forms.DialogResult.No)
{
m_lutEntries[i] = 0;
continue;
}
else
{
fileStream.Close();
return;
}
}
// Data passed validation check, add it to the list of entries
m_lutEntries[i] = currResult;
}
fileStream.Close();
// set default line style to free mode.
UpdatePointsOnUI();
cbo_linestyle.SelectedIndex = 0;
}
}
#endregion
private void LoadFromCamera_Click(object sender, RoutedEventArgs e)
{
OnLoadFromCamera();
}
private void SaveToCamera_Click(object sender, RoutedEventArgs e)
{
if (this.m_lutEntries == null)
{
return;
}
_skipCallBack = true;
try
{
Mouse.OverrideCursor = Cursors.Wait;
UnregisterGeniCamCallbacks();
for (uint i = 0; i < m_lutEntries.Length; ++i)
{
m_indexNode.Value = i;
m_valueNode.Value = m_lutEntries[i];
}
log.Logger.Log(null, log4net.Core.Level.Notice, "LUT data has been saved to device", null);
}
catch (SpinnakerException ex)
{
log.Error("Problem setting LUT Value.", ex);
}
catch (System.Exception ex)
{
log.Error("Problem setting LUT Value.", ex);
}
finally
{
RegisterGeniCamCallbacks();
Mouse.OverrideCursor = null;
}
_skipCallBack = false;
}
}
public enum LineStyle { Free = 0, Linear, Spline }
#region IValueConverter Members
public class MyPointCollectionConverter : IValueConverter
{
public object Convert(
object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
var regPtsColl = new PointCollection(); // regular points collection.
var obsPtsColl = (ObservableCollection<Point>) value; // observable which is used to raise INCC event.
foreach(var point in obsPtsColl) regPtsColl.Add(point);
return regPtsColl;
}
public object ConvertBack(
object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
return null;
}
}
#endregion
}
}