Commit 8d9ff8e8 authored by David C. Lonie's avatar David C. Lonie

Fix marker scaling in GL2PS exports.

Added a regression test to check marker sizes.

Change-Id: I0532f47f870a718945b0da77d2a024af7d605b60
parent 92590280
......@@ -11,6 +11,7 @@ if(VTK_GHOSTSCRIPT_EXECUTABLE)
TestGL2PSExporterVolumeRaster.cxx,NO_VALID
TestGL2PSTextActor3D.cxx
TestGL2PSLabeledDataMapper.cxx
TestLinePlotGL2PS.cxx
TestStackedPlotGL2PS.cxx
)
endif()
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestLinePlotGL2PS.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkChartXY.h"
#include "vtkContextScene.h"
#include "vtkContextView.h"
#include "vtkFloatArray.h"
#include "vtkGL2PSExporter.h"
#include "vtkNew.h"
#include "vtkPlot.h"
#include "vtkPlotLine.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkTable.h"
#include "vtkTestingInteractor.h"
//----------------------------------------------------------------------------
int TestLinePlotGL2PS(int , char * [])
{
// Set up a 2D scene, add an XY chart to it
vtkNew<vtkContextView> view;
view->GetRenderWindow()->SetSize(400, 300);
vtkNew<vtkChartXY> chart;
view->GetScene()->AddItem(chart.GetPointer());
chart->SetShowLegend(true);
// Create a table with some points in it...
vtkNew<vtkTable> table;
vtkNew<vtkFloatArray> arrX;
arrX->SetName("X Axis");
table->AddColumn(arrX.GetPointer());
vtkNew<vtkFloatArray> arrC;
arrC->SetName("Cosine");
table->AddColumn(arrC.GetPointer());
vtkNew<vtkFloatArray> arrS;
arrS->SetName("Sine");
table->AddColumn(arrS.GetPointer());
vtkNew<vtkFloatArray> arrS2;
arrS2->SetName("Sine2");
table->AddColumn(arrS2.GetPointer());
vtkNew<vtkFloatArray> arr1;
arr1->SetName("One");
table->AddColumn(arr1.GetPointer());
vtkNew<vtkFloatArray> arr0;
arr0->SetName("Zero");
table->AddColumn(arr0.GetPointer());
// Test charting with a few more points...
int numPoints = 69;
float inc = 7.5 / (numPoints-1);
table->SetNumberOfRows(numPoints);
for (int i = 0; i < numPoints; ++i)
{
table->SetValue(i, 0, i * inc);
table->SetValue(i, 1, cos(i * inc) + 0.0);
table->SetValue(i, 2, sin(i * inc) + 0.0);
table->SetValue(i, 3, sin(i * inc) + 0.5);
table->SetValue(i, 4, 1.0);
table->SetValue(i, 5, 0.0);
}
// Add multiple line plots, setting the colors etc
vtkPlotLine *line = vtkPlotLine::SafeDownCast(chart->AddPlot(vtkChart::LINE));
line->SetInputData(table.GetPointer(), 0, 1);
line->SetColor(0, 255, 0, 255);
line->SetWidth(1.0);
line->SetMarkerStyle(vtkPlotLine::CIRCLE);
line = vtkPlotLine::SafeDownCast(chart->AddPlot(vtkChart::LINE));
line->SetInputData(table.GetPointer(), 0, 2);
line->SetColor(255, 0, 0, 255);
line->SetWidth(5.0);
line->SetMarkerStyle(vtkPlotLine::SQUARE);
line = vtkPlotLine::SafeDownCast(chart->AddPlot(vtkChart::LINE));
line->SetInputData(table.GetPointer(), 0, 3);
line->SetColor(0, 0, 255, 255);
line->SetWidth(4.0);
line->SetMarkerStyle(vtkPlotLine::DIAMOND);
line = vtkPlotLine::SafeDownCast(chart->AddPlot(vtkChart::LINE));
line->SetInputData(table.GetPointer(), 0, 4);
line->SetColor(0, 255, 255, 255);
line->SetWidth(4.0);
line->SetMarkerStyle(vtkPlotLine::CROSS);
line = vtkPlotLine::SafeDownCast(chart->AddPlot(vtkChart::LINE));
line->SetInputData(table.GetPointer(), 0, 5);
line->SetColor(255, 255, 0, 255);
line->SetWidth(4.0);
line->SetMarkerStyle(vtkPlotLine::PLUS);
// Render the scene and compare the image to a reference image
view->GetRenderWindow()->SetMultiSamples(0);
view->GetRenderWindow()->Render();
vtkNew<vtkGL2PSExporter> exp;
exp->SetRenderWindow(view->GetRenderWindow());
exp->SetFileFormatToPS();
exp->UsePainterSettings();
exp->CompressOff();
exp->DrawBackgroundOn();
std::string fileprefix = vtkTestingInteractor::TempDirectory +
std::string("/TestLinePlotGL2PS");
exp->SetFilePrefix(fileprefix.c_str());
exp->Write();
//Finally render the scene and compare the image to a reference image
view->GetInteractor()->Initialize();
view->GetInteractor()->Start();
return EXIT_SUCCESS;
}
......@@ -136,8 +136,6 @@ void vtkGL2PSContextDevice2D::DrawPolygon(float *points, int n)
}
}
//-----------------------------------------------------------------------------
void vtkGL2PSContextDevice2D::DrawEllipseWedge(float x, float y,
float outRx, float outRy,
......@@ -151,7 +149,7 @@ void vtkGL2PSContextDevice2D::DrawEllipseWedge(float x, float y,
// The path implementation can't handle start/stop angles. Defer to the
// superclass in this case.
if (fabs(startAngle) > 1e-5 || fabs(stopAngle - 360.0) > 1e-5)
if (std::fabs(startAngle) > 1e-5f || std::fabs(stopAngle - 360.0f) > 1e-5f)
{
this->Superclass::DrawEllipseWedge(x, y, outRx, outRy, inRx, inRy,
startAngle, stopAngle);
......@@ -160,11 +158,6 @@ void vtkGL2PSContextDevice2D::DrawEllipseWedge(float x, float y,
vtkNew<vtkPath> path;
this->AddEllipseToPath(path.GetPointer(), 0.f, 0.f, outRx, outRy, false);
this->AddEllipseToPath(path.GetPointer(), 0.f, 0.f, inRx, inRy, true);
this->TransformPath(path.GetPointer());
double origin[3] = {x, y, 0.f};
unsigned char color[4];
this->Brush->GetColor(color);
std::stringstream label;
label << "vtkGL2PSContextDevice2D::DrawEllipseWedge("
......@@ -172,8 +165,16 @@ void vtkGL2PSContextDevice2D::DrawEllipseWedge(float x, float y,
<< inRx << ", " << inRy << ", " << startAngle << ", " << stopAngle
<< ") path:";
vtkGL2PSUtilities::DrawPath(path.GetPointer(), origin, origin, color, NULL,
0.0, -1.f, label.str().c_str());
unsigned char color[4];
this->Brush->GetColor(color);
double rasterPos[3] = {static_cast<double>(x), static_cast<double>(y), 0.};
this->TransformPoint(x, y);
double windowPos[3] = {static_cast<double>(x), static_cast<double>(y), 0.};
vtkGL2PSUtilities::DrawPath(path.GetPointer(), rasterPos, windowPos, color,
NULL, 0.0, -1.f, label.str().c_str());
}
//-----------------------------------------------------------------------------
......@@ -324,13 +325,17 @@ void vtkGL2PSContextDevice2D::DrawCrossMarkers(bool highlight, float *points,
int n, unsigned char *colors,
int nc_comps)
{
float delta = this->GetPen()->GetWidth() * 0.475;
float oldWidth = this->Pen->GetWidth();
unsigned char oldColor[4];
this->Pen->GetColor(oldColor);
int oldLineType = this->Pen->GetLineType();
float halfWidth = oldWidth * 0.5f;
float deltaX = halfWidth;
float deltaY = halfWidth;
this->TransformSize(deltaX, deltaY);
if (highlight)
{
this->Pen->SetWidth(1.5);
......@@ -369,17 +374,17 @@ void vtkGL2PSContextDevice2D::DrawCrossMarkers(bool highlight, float *points,
}
// The first line of the cross:
curLine[0] = point[0] + delta;
curLine[1] = point[1] + delta;
curLine[2] = point[0] - delta;
curLine[3] = point[1] - delta;
curLine[0] = point[0] + deltaX;
curLine[1] = point[1] + deltaY;
curLine[2] = point[0] - deltaX;
curLine[3] = point[1] - deltaY;
this->DrawPoly(curLine, 2);
// And the second:
curLine[0] = point[0] + delta;
curLine[1] = point[1] - delta;
curLine[2] = point[0] - delta;
curLine[3] = point[1] + delta;
curLine[0] = point[0] + deltaX;
curLine[1] = point[1] - deltaY;
curLine[2] = point[0] - deltaX;
curLine[3] = point[1] + deltaY;
this->DrawPoly(curLine, 2);
}
......@@ -393,13 +398,17 @@ void vtkGL2PSContextDevice2D::DrawPlusMarkers(bool highlight, float *points,
int n, unsigned char *colors,
int nc_comps)
{
float delta = this->GetPen()->GetWidth() * 0.475;
float oldWidth = this->Pen->GetWidth();
unsigned char oldColor[4];
this->Pen->GetColor(oldColor);
int oldLineType = this->Pen->GetLineType();
float halfWidth = oldWidth * 0.5f;
float deltaX = halfWidth;
float deltaY = halfWidth;
this->TransformSize(deltaX, deltaY);
if (highlight)
{
this->Pen->SetWidth(1.5);
......@@ -438,17 +447,17 @@ void vtkGL2PSContextDevice2D::DrawPlusMarkers(bool highlight, float *points,
}
// The first line of the plus:
curLine[0] = point[0] - delta;
curLine[0] = point[0] - deltaX;
curLine[1] = point[1];
curLine[2] = point[0] + delta;
curLine[2] = point[0] + deltaX;
curLine[3] = point[1];
this->DrawPoly(curLine, 2);
// And the second:
curLine[0] = point[0];
curLine[1] = point[1] - delta;
curLine[1] = point[1] - deltaY;
curLine[2] = point[0];
curLine[3] = point[1] + delta;
curLine[3] = point[1] + deltaY;
this->DrawPoly(curLine, 2);
}
......@@ -463,13 +472,17 @@ void vtkGL2PSContextDevice2D::DrawSquareMarkers(bool /*highlight*/,
int n, unsigned char *colors,
int nc_comps)
{
float delta = this->GetPen()->GetWidth() * 0.475;
unsigned char oldColor[4];
this->Brush->GetColor(oldColor);
this->Brush->SetColor(this->Pen->GetColor());
float halfWidth = this->GetPen()->GetWidth() * 0.5f;
float deltaX = halfWidth;
float deltaY = halfWidth;
this->TransformSize(deltaX, deltaY);
float quad[8];
unsigned char color[4];
for (int i = 0; i < n; ++i)
......@@ -497,12 +510,12 @@ void vtkGL2PSContextDevice2D::DrawSquareMarkers(bool /*highlight*/,
this->Brush->SetColor(color);
}
quad[0] = point[0] - delta;
quad[1] = point[1] - delta;
quad[2] = point[0] + delta;
quad[0] = point[0] - deltaX;
quad[1] = point[1] - deltaY;
quad[2] = point[0] + deltaX;
quad[3] = quad[1];
quad[4] = quad[2];
quad[5] = point[1] + delta;
quad[5] = point[1] + deltaY;
quad[6] = quad[0];
quad[7] = quad[5];
......@@ -564,13 +577,17 @@ void vtkGL2PSContextDevice2D::DrawDiamondMarkers(bool /*highlight*/,
int n, unsigned char *colors,
int nc_comps)
{
float delta = this->GetPen()->GetWidth() * 0.475;
unsigned char oldColor[4];
this->Brush->GetColor(oldColor);
this->Brush->SetColor(this->Pen->GetColor());
float halfWidth = this->GetPen()->GetWidth() * 0.5f;
float deltaX = halfWidth;
float deltaY = halfWidth;
this->TransformSize(deltaX, deltaY);
float quad[8];
unsigned char color[4];
for (int i = 0; i < n; ++i)
......@@ -598,14 +615,14 @@ void vtkGL2PSContextDevice2D::DrawDiamondMarkers(bool /*highlight*/,
this->Brush->SetColor(color);
}
quad[0] = point[0] - delta;
quad[0] = point[0] - deltaX;
quad[1] = point[1];
quad[2] = point[0];
quad[3] = point[1] - delta;
quad[4] = point[0] + delta;
quad[3] = point[1] - deltaY;
quad[4] = point[0] + deltaX;
quad[5] = point[1];
quad[6] = point[0];
quad[7] = point[1] + delta;
quad[7] = point[1] + deltaY;
this->DrawQuad(quad,4);
}
......@@ -666,7 +683,7 @@ void vtkGL2PSContextDevice2D::AddEllipseToPath(vtkPath *path, float x, float y,
}
//-----------------------------------------------------------------------------
void vtkGL2PSContextDevice2D::TransformPath(vtkPath *path)
void vtkGL2PSContextDevice2D::TransformPath(vtkPath *path) const
{
// Transform the path with the modelview matrix:
float modelview[16];
......@@ -686,6 +703,28 @@ void vtkGL2PSContextDevice2D::TransformPath(vtkPath *path)
}
}
//-----------------------------------------------------------------------------
void vtkGL2PSContextDevice2D::TransformPoint(float &x, float &y) const
{
float modelview[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
float inX = x;
float inY = y;
x = modelview[0] * inX + modelview[4] * inY + modelview[12];
y = modelview[1] * inX + modelview[5] * inY + modelview[13];
}
//-----------------------------------------------------------------------------
void vtkGL2PSContextDevice2D::TransformSize(float &dx, float &dy) const
{
float modelview[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
dx /= modelview[0];
dy /= modelview[5];
}
//-----------------------------------------------------------------------------
void vtkGL2PSContextDevice2D::PrintSelf(ostream &os, vtkIndent indent)
{
......
......@@ -163,8 +163,15 @@ private:
unsigned char *colors, int nc_comps);
void AddEllipseToPath(vtkPath *path, float x, float y, float rx, float ry,
bool reverse);
// Transform the path using the current modelview matrix.
void TransformPath(vtkPath *path);
void TransformPath(vtkPath *path) const;
// Transform the 2D point using the current modelview matrix.
void TransformPoint(float &x, float &y) const;
// Transform the width and height from pixels to data units.
void TransformSize(float &dx, float &dy) const;
};
#endif //__vtkGL2PSContextDevice2D_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment