Files
wg_cpso/vtkControl/vtkMax/Widget/02_vtkMaxScaleWidget.cs
2026-03-25 18:20:24 +08:00

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;
}
}
}