|
|
|
|
#include "FITKLegendScaleActor.h"
|
|
|
|
|
#include "vtkActor2D.h"
|
|
|
|
|
#include "vtkAxisActor2D.h"
|
|
|
|
|
#include "vtkCamera.h"
|
|
|
|
|
#include "vtkCellArray.h"
|
|
|
|
|
#include "vtkCellData.h"
|
|
|
|
|
#include "vtkCommand.h"
|
|
|
|
|
#include "vtkCoordinate.h"
|
|
|
|
|
#include "vtkMath.h"
|
|
|
|
|
#include "vtkObjectFactory.h"
|
|
|
|
|
#include "vtkPoints.h"
|
|
|
|
|
#include "vtkPolyData.h"
|
|
|
|
|
#include "vtkPolyDataMapper2D.h"
|
|
|
|
|
#include "vtkRenderer.h"
|
|
|
|
|
#include "vtkTextMapper.h"
|
|
|
|
|
#include "vtkTextProperty.h"
|
|
|
|
|
#include "vtkUnsignedCharArray.h"
|
|
|
|
|
#include "vtkWindow.h"
|
|
|
|
|
|
|
|
|
|
vtkStandardNewMacro(FITKLegendScaleActor);
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FITKLegendScaleActor::FITKLegendScaleActor()
|
|
|
|
|
{
|
|
|
|
|
this->BottomAxis = vtkAxisActor2D::New();
|
|
|
|
|
this->BottomAxis->GetPositionCoordinate()->SetCoordinateSystemToViewport();
|
|
|
|
|
this->BottomAxis->GetPosition2Coordinate()->SetCoordinateSystemToViewport();
|
|
|
|
|
this->BottomAxis->GetPositionCoordinate()->SetReferenceCoordinate(nullptr);
|
|
|
|
|
this->BottomAxis->SetFontFactor(0.6);
|
|
|
|
|
this->BottomAxis->SetNumberOfLabels(5);
|
|
|
|
|
this->BottomAxis->AdjustLabelsOff();
|
|
|
|
|
this->BottomAxis->SetVisibility(false);
|
|
|
|
|
|
|
|
|
|
this->BottomAxisVisibility = 0;
|
|
|
|
|
|
|
|
|
|
this->Legend = vtkPolyData::New();
|
|
|
|
|
this->LegendPoints = vtkPoints::New();
|
|
|
|
|
this->Legend->SetPoints(this->LegendPoints);
|
|
|
|
|
this->LegendMapper = vtkPolyDataMapper2D::New();
|
|
|
|
|
this->LegendMapper->SetInputData(this->Legend);
|
|
|
|
|
this->LegendActor = vtkActor2D::New();
|
|
|
|
|
this->LegendActor->SetMapper(this->LegendMapper);
|
|
|
|
|
|
|
|
|
|
// Create the legend
|
|
|
|
|
vtkIdType pts[4];
|
|
|
|
|
this->LegendPoints->SetNumberOfPoints(10);
|
|
|
|
|
vtkCellArray* legendPolys = vtkCellArray::New();
|
|
|
|
|
|
|
|
|
|
//#if VTK_MAJOR_VERSION < 9
|
|
|
|
|
// legendPolys->Allocate(4, 4);
|
|
|
|
|
//#else
|
|
|
|
|
// legendPolys->AllocateEstimate(4, 4);
|
|
|
|
|
//#endif
|
|
|
|
|
|
|
|
|
|
pts[0] = 0;
|
|
|
|
|
pts[1] = 1;
|
|
|
|
|
pts[2] = 6;
|
|
|
|
|
pts[3] = 5;
|
|
|
|
|
legendPolys->InsertNextCell(4, pts);
|
|
|
|
|
pts[0] = 1;
|
|
|
|
|
pts[1] = 2;
|
|
|
|
|
pts[2] = 7;
|
|
|
|
|
pts[3] = 6;
|
|
|
|
|
legendPolys->InsertNextCell(4, pts);
|
|
|
|
|
pts[0] = 2;
|
|
|
|
|
pts[1] = 3;
|
|
|
|
|
pts[2] = 8;
|
|
|
|
|
pts[3] = 7;
|
|
|
|
|
legendPolys->InsertNextCell(4, pts);
|
|
|
|
|
pts[0] = 3;
|
|
|
|
|
pts[1] = 4;
|
|
|
|
|
pts[2] = 9;
|
|
|
|
|
pts[3] = 8;
|
|
|
|
|
legendPolys->InsertNextCell(4, pts);
|
|
|
|
|
this->Legend->SetPolys(legendPolys);
|
|
|
|
|
legendPolys->Delete();
|
|
|
|
|
|
|
|
|
|
// Create the cell data
|
|
|
|
|
vtkUnsignedCharArray* colors = vtkUnsignedCharArray::New();
|
|
|
|
|
colors->SetNumberOfComponents(3);
|
|
|
|
|
colors->SetNumberOfTuples(4);
|
|
|
|
|
colors->SetTuple3(0, 0, 0, 0);
|
|
|
|
|
colors->SetTuple3(1, 255, 255, 255);
|
|
|
|
|
colors->SetTuple3(2, 0, 0, 0);
|
|
|
|
|
colors->SetTuple3(3, 255, 255, 255);
|
|
|
|
|
this->Legend->GetCellData()->SetScalars(colors);
|
|
|
|
|
colors->Delete();
|
|
|
|
|
|
|
|
|
|
// Now the text. The first five are for the 0,1/4,1/2,3/4,1 labels.
|
|
|
|
|
this->LegendLabelProperty = vtkTextProperty::New();
|
|
|
|
|
this->LegendLabelProperty->SetJustificationToCentered();
|
|
|
|
|
this->LegendLabelProperty->SetVerticalJustificationToTop();
|
|
|
|
|
this->LegendLabelProperty->SetBold(1);
|
|
|
|
|
this->LegendLabelProperty->SetItalic(0);
|
|
|
|
|
this->LegendLabelProperty->SetShadow(1);
|
|
|
|
|
this->LegendLabelProperty->SetFontFamilyToArial();
|
|
|
|
|
this->LegendLabelProperty->SetFontSize(14);
|
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
|
{
|
|
|
|
|
this->LabelMappers[i] = vtkTextMapper::New();
|
|
|
|
|
this->LabelMappers[i]->SetTextProperty(this->LegendLabelProperty);
|
|
|
|
|
this->LabelActors[i] = vtkActor2D::New();
|
|
|
|
|
this->LabelActors[i]->SetMapper(this->LabelMappers[i]);
|
|
|
|
|
}
|
|
|
|
|
this->LabelMappers[0]->SetInput("0");
|
|
|
|
|
this->LabelMappers[1]->SetInput("1/4");
|
|
|
|
|
this->LabelMappers[2]->SetInput("1/2");
|
|
|
|
|
this->LabelMappers[3]->SetInput("3/4");
|
|
|
|
|
this->LabelMappers[4]->SetInput("1");
|
|
|
|
|
|
|
|
|
|
this->Coordinate = vtkCoordinate::New();
|
|
|
|
|
this->Coordinate->SetCoordinateSystemToDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FITKLegendScaleActor::~FITKLegendScaleActor()
|
|
|
|
|
{
|
|
|
|
|
this->BottomAxis->Delete();
|
|
|
|
|
|
|
|
|
|
this->Legend->Delete();
|
|
|
|
|
this->LegendPoints->Delete();
|
|
|
|
|
this->LegendMapper->Delete();
|
|
|
|
|
this->LegendActor->Delete();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
|
{
|
|
|
|
|
this->LabelMappers[i]->Delete();
|
|
|
|
|
this->LabelActors[i]->Delete();
|
|
|
|
|
}
|
|
|
|
|
this->LegendLabelProperty->Delete();
|
|
|
|
|
this->Coordinate->Delete();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FITKLegendScaleActor::GetActors2D(vtkPropCollection* pc)
|
|
|
|
|
{
|
|
|
|
|
pc->AddItem(this->BottomAxis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FITKLegendScaleActor::ReleaseGraphicsResources(vtkWindow* w)
|
|
|
|
|
{
|
|
|
|
|
this->BottomAxis->ReleaseGraphicsResources(w);
|
|
|
|
|
|
|
|
|
|
this->LegendActor->ReleaseGraphicsResources(w);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
this->LabelActors[i]->ReleaseGraphicsResources(w);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
int FITKLegendScaleActor::RenderOpaqueGeometry(vtkViewport* viewport)
|
|
|
|
|
{
|
|
|
|
|
this->BuildRepresentation(viewport);
|
|
|
|
|
|
|
|
|
|
int renderedSomething = 0;
|
|
|
|
|
if (this->BottomAxisVisibility)
|
|
|
|
|
{
|
|
|
|
|
renderedSomething += this->BottomAxis->RenderOpaqueGeometry(viewport);
|
|
|
|
|
}
|
|
|
|
|
renderedSomething += this->LegendActor->RenderOpaqueGeometry(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[0]->RenderOpaqueGeometry(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[1]->RenderOpaqueGeometry(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[2]->RenderOpaqueGeometry(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[3]->RenderOpaqueGeometry(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[4]->RenderOpaqueGeometry(viewport);
|
|
|
|
|
|
|
|
|
|
return renderedSomething;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
int FITKLegendScaleActor::RenderOverlay(vtkViewport* viewport)
|
|
|
|
|
{
|
|
|
|
|
int renderedSomething = 0;
|
|
|
|
|
if (this->BottomAxisVisibility)
|
|
|
|
|
{
|
|
|
|
|
renderedSomething += this->BottomAxis->RenderOverlay(viewport);
|
|
|
|
|
}
|
|
|
|
|
renderedSomething += this->LegendActor->RenderOverlay(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[0]->RenderOverlay(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[1]->RenderOverlay(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[2]->RenderOverlay(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[3]->RenderOverlay(viewport);
|
|
|
|
|
renderedSomething += this->LabelActors[4]->RenderOverlay(viewport);
|
|
|
|
|
|
|
|
|
|
return renderedSomething;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FITKLegendScaleActor::BuildRepresentation(vtkViewport* viewport)
|
|
|
|
|
{
|
|
|
|
|
if (1) // it's probably best just to rerender every time
|
|
|
|
|
// if ( this->GetMTime() > this->BuildTime ||
|
|
|
|
|
// (this->Renderer && this->Renderer->GetVTKWindow() &&
|
|
|
|
|
// this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
|
|
|
|
|
{
|
|
|
|
|
// Specify the locations of the axes.
|
|
|
|
|
const int* size = viewport->GetSize();
|
|
|
|
|
|
|
|
|
|
// Now specify the axis values
|
|
|
|
|
// distance between points
|
|
|
|
|
double* xL = this->BottomAxis->GetPositionCoordinate()->GetComputedWorldValue(viewport);
|
|
|
|
|
double* xR = this->BottomAxis->GetPosition2Coordinate()->GetComputedWorldValue(viewport);
|
|
|
|
|
double d = sqrt(vtkMath::Distance2BetweenPoints(xL, xR));
|
|
|
|
|
|
|
|
|
|
char buf0[256];
|
|
|
|
|
snprintf(buf0, sizeof(buf0), "%.3g", -d / 2.0);
|
|
|
|
|
this->LabelMappers[0]->SetInput(buf0);
|
|
|
|
|
|
|
|
|
|
char buf1[256];
|
|
|
|
|
snprintf(buf1, sizeof(buf1), "%.3g", -d / 4.0);
|
|
|
|
|
this->LabelMappers[1]->SetInput(buf1);
|
|
|
|
|
|
|
|
|
|
char buf2[256];
|
|
|
|
|
snprintf(buf2, sizeof(buf2), "%.3g", 0);
|
|
|
|
|
this->LabelMappers[2]->SetInput(buf2);
|
|
|
|
|
|
|
|
|
|
char buf3[256];
|
|
|
|
|
snprintf(buf3, sizeof(buf3), "%.3g", d / 4.0);
|
|
|
|
|
this->LabelMappers[3]->SetInput(buf3);
|
|
|
|
|
|
|
|
|
|
char buf4[256];
|
|
|
|
|
snprintf(buf4, sizeof(buf4), "%.3g", d / 2.0);
|
|
|
|
|
this->LabelMappers[4]->SetInput(buf4);
|
|
|
|
|
|
|
|
|
|
this->BottomAxis->SetRange(-d / 2.0, d / 2.0);
|
|
|
|
|
|
|
|
|
|
// Update the position
|
|
|
|
|
double posXScale = 0.25;
|
|
|
|
|
double x1 = posXScale * size[0];
|
|
|
|
|
double delX = size[0] * (1 - posXScale * 2) / 4.;
|
|
|
|
|
|
|
|
|
|
this->BottomAxis->GetPositionCoordinate()->SetValue(
|
|
|
|
|
x1, 0, 0.0);
|
|
|
|
|
|
|
|
|
|
this->LegendPoints->SetPoint(0, x1, 30, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(1, x1 + delX, 30, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(2, x1 + 2 * delX, 30, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(3, x1 + 3 * delX, 30, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(4, x1 + 4 * delX, 30, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(5, x1, 40, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(6, x1 + delX, 40, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(7, x1 + 2 * delX, 40, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(8, x1 + 3 * delX, 40, 0);
|
|
|
|
|
this->LegendPoints->SetPoint(9, x1 + 4 * delX, 40, 0);
|
|
|
|
|
this->LegendPoints->Modified();
|
|
|
|
|
|
|
|
|
|
this->BottomAxis->GetPosition2Coordinate()->SetValue(
|
|
|
|
|
size[0] - x1, 0,
|
|
|
|
|
0.0);
|
|
|
|
|
|
|
|
|
|
// Specify the position of the legend title
|
|
|
|
|
this->Coordinate->SetValue(0.33333 * size[0], 15, 0.0);
|
|
|
|
|
double* x = this->Coordinate->GetComputedWorldValue(viewport);
|
|
|
|
|
xL[0] = x[0];
|
|
|
|
|
xL[1] = x[1];
|
|
|
|
|
xL[2] = x[2];
|
|
|
|
|
this->Coordinate->SetValue(0.66667 * size[0], 15, 0.0);
|
|
|
|
|
x = this->Coordinate->GetComputedWorldValue(viewport);
|
|
|
|
|
xR[0] = x[0];
|
|
|
|
|
xR[1] = x[1];
|
|
|
|
|
xR[2] = x[2];
|
|
|
|
|
|
|
|
|
|
// Now specify the position of the legend labels
|
|
|
|
|
x = this->LegendPoints->GetPoint(0);
|
|
|
|
|
this->LabelActors[0]->SetPosition(x[0], x[1] - 1);
|
|
|
|
|
x = this->LegendPoints->GetPoint(1);
|
|
|
|
|
this->LabelActors[1]->SetPosition(x[0], x[1] - 1);
|
|
|
|
|
x = this->LegendPoints->GetPoint(2);
|
|
|
|
|
this->LabelActors[2]->SetPosition(x[0], x[1] - 1);
|
|
|
|
|
x = this->LegendPoints->GetPoint(3);
|
|
|
|
|
this->LabelActors[3]->SetPosition(x[0], x[1] - 1);
|
|
|
|
|
x = this->LegendPoints->GetPoint(4);
|
|
|
|
|
this->LabelActors[4]->SetPosition(x[0], x[1] - 1);
|
|
|
|
|
|
|
|
|
|
this->BuildTime.Modified();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
void FITKLegendScaleActor::PrintSelf(ostream& os, vtkIndent indent)
|
|
|
|
|
{
|
|
|
|
|
// Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
|
|
|
|
|
this->Superclass::PrintSelf(os, indent);
|
|
|
|
|
|
|
|
|
|
os << indent << "Bottom Axis Visibility: " << (this->BottomAxisVisibility ? "On\n" : "Off\n");
|
|
|
|
|
|
|
|
|
|
os << indent << "Legend Label Property: ";
|
|
|
|
|
if (this->LegendLabelProperty)
|
|
|
|
|
{
|
|
|
|
|
os << this->LegendLabelProperty << "\n";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
os << "(none)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
os << indent << "Bottom Axis: ";
|
|
|
|
|
if (this->BottomAxis)
|
|
|
|
|
{
|
|
|
|
|
os << this->BottomAxis << "\n";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
os << "(none)\n";
|
|
|
|
|
}
|
|
|
|
|
}
|