376 lines
14 KiB
C#
376 lines
14 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using Kitware.VTK;
|
|||
|
|
|
|||
|
|
namespace vtkControl
|
|||
|
|
{
|
|||
|
|
class vtkMaxScaleWidget : vtkMaxBorderWidget
|
|||
|
|
{
|
|||
|
|
// Variables
|
|||
|
|
private double _width;
|
|||
|
|
private double _barWidth;
|
|||
|
|
private double _barWidthInModelUnits;
|
|||
|
|
private double _barHeight;
|
|||
|
|
private int _numOffields;
|
|||
|
|
private int _padding;
|
|||
|
|
private string _labelFormat;
|
|||
|
|
private string _unit;
|
|||
|
|
|
|||
|
|
protected vtkTextMapper[] _scaleTextMappers;
|
|||
|
|
protected vtkActor2D[] _scaleTextActors;
|
|||
|
|
|
|||
|
|
protected vtkPolyDataMapper2D _scaleBorderMapper;
|
|||
|
|
protected vtkActor2D _scaleBorderActor;
|
|||
|
|
|
|||
|
|
protected vtkPolyDataMapper2D _scaleBackgroundMapper;
|
|||
|
|
protected vtkActor2D _scaleBackgroundActor;
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Constructors
|
|||
|
|
public vtkMaxScaleWidget()
|
|||
|
|
{
|
|||
|
|
_width = 300;
|
|||
|
|
//
|
|||
|
|
_barWidth = _width;
|
|||
|
|
_barHeight = 10;
|
|||
|
|
_numOffields = 5;
|
|||
|
|
_padding = 5;
|
|||
|
|
_labelFormat = "G4";
|
|||
|
|
_unit = "";
|
|||
|
|
//
|
|||
|
|
InitializeLabels();
|
|||
|
|
InitializeBackground();
|
|||
|
|
InitializeBorder();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Private methods
|
|||
|
|
private void InitializeLabels()
|
|||
|
|
{
|
|||
|
|
// Text property
|
|||
|
|
vtkTextProperty textProperty = vtkTextProperty.New();
|
|||
|
|
//
|
|||
|
|
_scaleTextMappers = new vtkTextMapper[_numOffields + 1];
|
|||
|
|
_scaleTextActors = new vtkActor2D[_scaleTextMappers.Length];
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i < _scaleTextMappers.Length; i++)
|
|||
|
|
{
|
|||
|
|
// Mapper
|
|||
|
|
_scaleTextMappers[i] = vtkTextMapper.New();
|
|||
|
|
_scaleTextMappers[i].SetTextProperty(textProperty);
|
|||
|
|
// Actor
|
|||
|
|
_scaleTextActors[i] = vtkActor2D.New();
|
|||
|
|
_scaleTextActors[i].SetMapper(_scaleTextMappers[i]);
|
|||
|
|
// Set relative text position
|
|||
|
|
_scaleTextActors[i].GetPositionCoordinate().SetCoordinateSystemToDisplay(); // set offsets in pixels
|
|||
|
|
_scaleTextActors[i].GetPositionCoordinate().SetReferenceCoordinate(_positionCoordinate);
|
|||
|
|
_scaleTextActors[i].GetPositionCoordinate().SetValue(0, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
private void InitializeBackground()
|
|||
|
|
{
|
|||
|
|
// Bar border
|
|||
|
|
vtkPolyData backgroundPolyData = vtkPolyData.New();
|
|||
|
|
backgroundPolyData.SetPoints(vtkPoints.New());
|
|||
|
|
backgroundPolyData.SetPolys(vtkCellArray.New());
|
|||
|
|
//
|
|||
|
|
_scaleBackgroundMapper = vtkPolyDataMapper2D.New();
|
|||
|
|
_scaleBackgroundMapper.SetInput(backgroundPolyData);
|
|||
|
|
//
|
|||
|
|
vtkProperty2D backgroundProperty = vtkProperty2D.New();
|
|||
|
|
backgroundProperty.SetColor(0, 0, 0);
|
|||
|
|
//
|
|||
|
|
_scaleBackgroundActor = vtkActor2D.New();
|
|||
|
|
_scaleBackgroundActor.SetMapper(_scaleBackgroundMapper);
|
|||
|
|
_scaleBackgroundActor.SetProperty(backgroundProperty);
|
|||
|
|
//
|
|||
|
|
_scaleBackgroundActor.GetPositionCoordinate().SetCoordinateSystemToDisplay(); // set offsets in pixels
|
|||
|
|
_scaleBackgroundActor.GetPositionCoordinate().SetReferenceCoordinate(_positionCoordinate);
|
|||
|
|
}
|
|||
|
|
private void InitializeBorder()
|
|||
|
|
{
|
|||
|
|
// Bar border
|
|||
|
|
vtkPolyData borderPolyData = vtkPolyData.New();
|
|||
|
|
borderPolyData.SetPoints(vtkPoints.New());
|
|||
|
|
borderPolyData.SetPolys(vtkCellArray.New());
|
|||
|
|
//
|
|||
|
|
_scaleBorderMapper = vtkPolyDataMapper2D.New();
|
|||
|
|
_scaleBorderMapper.SetInput(borderPolyData);
|
|||
|
|
//
|
|||
|
|
vtkProperty2D borderProperty = vtkProperty2D.New();
|
|||
|
|
borderProperty.SetColor(0, 0, 0);
|
|||
|
|
//
|
|||
|
|
_scaleBorderActor = vtkActor2D.New();
|
|||
|
|
_scaleBorderActor.SetMapper(_scaleBorderMapper);
|
|||
|
|
_scaleBorderActor.SetProperty(borderProperty);
|
|||
|
|
//
|
|||
|
|
_scaleBorderActor.GetPositionCoordinate().SetCoordinateSystemToDisplay(); // set offsets in pixels
|
|||
|
|
_scaleBorderActor.GetPositionCoordinate().SetReferenceCoordinate(_positionCoordinate);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void GenerateGeometry()
|
|||
|
|
{
|
|||
|
|
UpdateSize();
|
|||
|
|
//
|
|||
|
|
GenerateLableValues(); // must be before Background
|
|||
|
|
GenerateBackground(); // must be before Borders
|
|||
|
|
GenerateBorders();
|
|||
|
|
UpdateOuterBorder();
|
|||
|
|
PositionLabels();
|
|||
|
|
}
|
|||
|
|
private void UpdateSize()
|
|||
|
|
{
|
|||
|
|
// Get world projection from display position
|
|||
|
|
_renderer.SetDisplayPoint(0, 0, 0);
|
|||
|
|
_renderer.DisplayToWorld();
|
|||
|
|
double[] first = _renderer.GetWorldPoint();
|
|||
|
|
//
|
|||
|
|
_renderer.SetDisplayPoint(0, _width, 0);
|
|||
|
|
_renderer.DisplayToWorld();
|
|||
|
|
double[] second = _renderer.GetWorldPoint();
|
|||
|
|
//
|
|||
|
|
double len = Math.Sqrt(Math.Pow(first[0] - second[0], 2)
|
|||
|
|
+ Math.Pow(first[1] - second[1], 2)
|
|||
|
|
+ Math.Pow(first[2] - second[2], 2));
|
|||
|
|
//
|
|||
|
|
if (!double.IsNaN(len) && len != 0)
|
|||
|
|
{
|
|||
|
|
//System.Diagnostics.Debug.WriteLine(DateTime.Now.TimeOfDay + " Len: " + len);
|
|||
|
|
double prevWidth = _barWidth;
|
|||
|
|
double p = Math.Floor(Math.Log10(len));
|
|||
|
|
len /= Math.Pow(10, p);
|
|||
|
|
int numOfIntervals = 5;
|
|||
|
|
double ratio = Math.Round(numOfIntervals * len) / numOfIntervals / len;
|
|||
|
|
//
|
|||
|
|
_barWidth = _width * ratio;
|
|||
|
|
_barWidthInModelUnits = Math.Round(numOfIntervals * len) / numOfIntervals * Math.Pow(10, p);
|
|||
|
|
//
|
|||
|
|
_position[0] -= (_barWidth - prevWidth) / 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
private void GenerateLableValues()
|
|||
|
|
{
|
|||
|
|
double maxValue = _barWidthInModelUnits;
|
|||
|
|
double dx = maxValue / _numOffields;
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i < _scaleTextMappers.Length; i++)
|
|||
|
|
{
|
|||
|
|
_scaleTextMappers[i].SetInput((i * dx).ToString(_labelFormat));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
private void GenerateBackground()
|
|||
|
|
{
|
|||
|
|
// Text size
|
|||
|
|
int[] sizeOfFirst = vtkMaxWidgetTools.GetTextSize(_scaleTextMappers[0], _renderer);
|
|||
|
|
// Number of vertical lines
|
|||
|
|
int n = _numOffields + 1;
|
|||
|
|
//
|
|||
|
|
vtkPoints backgroundPoints = vtkPoints.New();
|
|||
|
|
vtkCellArray backgroundPolygon = vtkCellArray.New();
|
|||
|
|
//
|
|||
|
|
backgroundPoints.SetNumberOfPoints(2 * n);
|
|||
|
|
//
|
|||
|
|
double dx = _barWidth / _numOffields;
|
|||
|
|
double dy = _barHeight;
|
|||
|
|
double x0 = sizeOfFirst[0] / 2 + _padding;
|
|||
|
|
double y0 = sizeOfFirst[1] + 2 * _padding;
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i <= _numOffields; i++)
|
|||
|
|
{
|
|||
|
|
backgroundPoints.SetPoint(2 * i, x0 + i * dx, y0, 0);
|
|||
|
|
backgroundPoints.SetPoint(2 * i + 1, x0 + i * dx, y0 + dy, 0);
|
|||
|
|
}
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i < _numOffields; i+=2)
|
|||
|
|
{
|
|||
|
|
backgroundPolygon.InsertNextCell(4);
|
|||
|
|
backgroundPolygon.InsertCellPoint(2 * i);
|
|||
|
|
backgroundPolygon.InsertCellPoint(2 * (i + 1));
|
|||
|
|
backgroundPolygon.InsertCellPoint(2 * (i + 1) + 1);
|
|||
|
|
backgroundPolygon.InsertCellPoint(2 * i + 1);
|
|||
|
|
}
|
|||
|
|
//
|
|||
|
|
vtkPolyData backgroundPoly = _scaleBackgroundMapper.GetInput();
|
|||
|
|
backgroundPoly.SetPoints(backgroundPoints);
|
|||
|
|
backgroundPoly.SetPolys(backgroundPolygon);
|
|||
|
|
}
|
|||
|
|
private void GenerateBorders()
|
|||
|
|
{
|
|||
|
|
vtkCellArray borderLines = vtkCellArray.New();
|
|||
|
|
// Vertical lines
|
|||
|
|
for (int i = 0; i <= _numOffields; i++)
|
|||
|
|
{
|
|||
|
|
borderLines.InsertNextCell(2);
|
|||
|
|
borderLines.InsertCellPoint(2 * i);
|
|||
|
|
borderLines.InsertCellPoint(2 * i + 1);
|
|||
|
|
}
|
|||
|
|
// Horizontal lines
|
|||
|
|
borderLines.InsertNextCell(2);
|
|||
|
|
borderLines.InsertCellPoint(0);
|
|||
|
|
borderLines.InsertCellPoint(2 * _numOffields);
|
|||
|
|
//
|
|||
|
|
borderLines.InsertNextCell(2);
|
|||
|
|
borderLines.InsertCellPoint(1);
|
|||
|
|
borderLines.InsertCellPoint(2 * _numOffields + 1);
|
|||
|
|
// PolyData
|
|||
|
|
vtkPolyData borderPoly = _scaleBorderMapper.GetInput();
|
|||
|
|
borderPoly.SetPoints(_scaleBackgroundMapper.GetInput().GetPoints());
|
|||
|
|
borderPoly.SetLines(borderLines);
|
|||
|
|
}
|
|||
|
|
private void PositionLabels()
|
|||
|
|
{
|
|||
|
|
vtkPoints points = _scaleBackgroundMapper.GetInput().GetPoints();
|
|||
|
|
//
|
|||
|
|
int[] size;
|
|||
|
|
double[] point;
|
|||
|
|
for (int i = 0; i < _scaleTextMappers.Length; i++)
|
|||
|
|
{
|
|||
|
|
point = points.GetPoint(2 * i);
|
|||
|
|
size = vtkMaxWidgetTools.GetTextSize(_scaleTextMappers[i], _renderer);
|
|||
|
|
//
|
|||
|
|
_scaleTextActors[i].GetPositionCoordinate().SetValue(point[0] - size[0] / 2, _padding);
|
|||
|
|
}
|
|||
|
|
//
|
|||
|
|
string lastLabel = _scaleTextMappers[_scaleTextMappers.Length - 1].GetInput();
|
|||
|
|
_scaleTextMappers[_scaleTextMappers.Length - 1].SetInput(lastLabel + " " + _unit);
|
|||
|
|
}
|
|||
|
|
private void UpdateOuterBorder()
|
|||
|
|
{
|
|||
|
|
// Text size
|
|||
|
|
int[] sizeOfFirst = vtkMaxWidgetTools.GetTextSize(_scaleTextMappers[0], _renderer);
|
|||
|
|
int[] sizeOfLast = vtkMaxWidgetTools.GetTextSize(_scaleTextMappers[_scaleTextMappers.Length - 1], _renderer);
|
|||
|
|
//
|
|||
|
|
double outerWidth = _padding + sizeOfFirst[0] / 2 + _barWidth + sizeOfLast[0] / 2 + _padding;
|
|||
|
|
double outerHeight = _padding + sizeOfLast[1] + _padding + _barHeight + _padding + sizeOfFirst[1] + _padding;
|
|||
|
|
//
|
|||
|
|
_size[0] = outerWidth;
|
|||
|
|
_size[1] = outerHeight;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Public methods
|
|||
|
|
public void SetUnit(string unit)
|
|||
|
|
{
|
|||
|
|
_unit = unit;
|
|||
|
|
GenerateGeometry();
|
|||
|
|
}
|
|||
|
|
public override void OnRenderWindowModified()
|
|||
|
|
{
|
|||
|
|
if (_visibility)
|
|||
|
|
{
|
|||
|
|
base.OnRenderWindowModified();
|
|||
|
|
OnSizeChanged();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public override void CameraModified()
|
|||
|
|
{
|
|||
|
|
if (_visibility)
|
|||
|
|
{
|
|||
|
|
base.CameraModified();
|
|||
|
|
OnSizeChanged();
|
|||
|
|
//System.Diagnostics.Debug.WriteLine(DateTime.Now.TimeOfDay + " CameraModified");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public override void OnSizeChanged()
|
|||
|
|
{
|
|||
|
|
GenerateGeometry();
|
|||
|
|
OnMovedOrSizeChanged();
|
|||
|
|
}
|
|||
|
|
public override void VisibilityOn()
|
|||
|
|
{
|
|||
|
|
if (_visibility == false)
|
|||
|
|
{
|
|||
|
|
base.VisibilityOn();
|
|||
|
|
//
|
|||
|
|
if (_scaleBackgroundActor != null) _renderer.AddActor(_scaleBackgroundActor);
|
|||
|
|
if (_scaleBorderActor != null) _renderer.AddActor(_scaleBorderActor);
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i < _scaleTextActors.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (_scaleTextActors[i] != null) _renderer.AddActor(_scaleTextActors[i]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public override void VisibilityOff()
|
|||
|
|
{
|
|||
|
|
if (_visibility == true)
|
|||
|
|
{
|
|||
|
|
base.VisibilityOff();
|
|||
|
|
//
|
|||
|
|
if (_scaleBackgroundActor != null) _renderer.RemoveActor(_scaleBackgroundActor);
|
|||
|
|
if (_scaleBorderActor != null) _renderer.RemoveActor(_scaleBorderActor);
|
|||
|
|
//
|
|||
|
|
for (int i = 0; i < _scaleTextActors.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (_scaleTextActors[i] != null) _renderer.RemoveActor(_scaleTextActors[i]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Public setters
|
|||
|
|
public override void SetInteractor(vtkRenderer renderer, vtkRenderWindowInteractor renderWindowInteractor)
|
|||
|
|
{
|
|||
|
|
base.SetInteractor(renderer, renderWindowInteractor);
|
|||
|
|
//
|
|||
|
|
_renderer.AddActor(_scaleBackgroundActor);
|
|||
|
|
_renderer.AddActor(_scaleBorderActor);
|
|||
|
|
for (int i = 0; i < _scaleTextActors.Length; i++)
|
|||
|
|
{
|
|||
|
|
_renderer.AddActor(_scaleTextActors[i]);
|
|||
|
|
}
|
|||
|
|
//
|
|||
|
|
OnSizeChanged();
|
|||
|
|
}
|
|||
|
|
public override void RemoveInteractor()
|
|||
|
|
{
|
|||
|
|
_renderer.RemoveActor(_scaleBackgroundActor);
|
|||
|
|
_renderer.RemoveActor(_scaleBorderActor);
|
|||
|
|
for (int i = 0; i < _scaleTextActors.Length; i++)
|
|||
|
|
{
|
|||
|
|
_renderer.RemoveActor(_scaleTextActors[i]);
|
|||
|
|
}
|
|||
|
|
//
|
|||
|
|
base.RemoveInteractor();
|
|||
|
|
}
|
|||
|
|
public void SetWidth(int width)
|
|||
|
|
{
|
|||
|
|
_width = width;
|
|||
|
|
OnSizeChanged();
|
|||
|
|
}
|
|||
|
|
public void SetLabelFormat(string labelFormat)
|
|||
|
|
{
|
|||
|
|
if (_labelFormat != labelFormat)
|
|||
|
|
{
|
|||
|
|
_labelFormat = labelFormat;
|
|||
|
|
OnSizeChanged();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void SetTextProperty(vtkTextProperty textProperty)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < _scaleTextMappers.Length; i++)
|
|||
|
|
{
|
|||
|
|
_scaleTextMappers[i].SetTextProperty(textProperty);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void SetPadding(int padding)
|
|||
|
|
{
|
|||
|
|
if (padding != _padding)
|
|||
|
|
{
|
|||
|
|
_padding = padding;
|
|||
|
|
OnSizeChanged();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Public getters
|
|||
|
|
public string GetLabelFormat()
|
|||
|
|
{
|
|||
|
|
return _labelFormat;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|