You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3307 lines
101 KiB
C++
3307 lines
101 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkAxisActor.cxx
|
|
Thanks: Kathleen Bonnell, B Division, Lawrence Livermore Nat'l Laboratory
|
|
|
|
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 "vtkAxisActor.h"
|
|
|
|
#include "vtkAxisFollower.h"
|
|
#include "vtkCamera.h"
|
|
#include "vtkCellArray.h"
|
|
#include "vtkCoordinate.h"
|
|
#include "vtkFollower.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkPolyDataMapper.h"
|
|
#include "vtkProp3DAxisFollower.h"
|
|
#include "vtkProperty.h"
|
|
#include "vtkProperty2D.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkStringArray.h"
|
|
#include "vtkTextActor.h"
|
|
#include "vtkTextActor3D.h"
|
|
#include "vtkTextProperty.h"
|
|
#include "vtkTextRenderer.h"
|
|
#include "vtkTransform.h"
|
|
#include "vtkVectorText.h"
|
|
#include "vtkViewport.h"
|
|
#include "vtkWindow.h"
|
|
|
|
#define VTK_MAX_TICKS 1000
|
|
|
|
#include <sstream>
|
|
|
|
vtkStandardNewMacro(vtkAxisActor);
|
|
vtkCxxSetObjectMacro(vtkAxisActor, Camera, vtkCamera);
|
|
vtkCxxSetObjectMacro(vtkAxisActor, LabelTextProperty, vtkTextProperty);
|
|
vtkCxxSetObjectMacro(vtkAxisActor, TitleTextProperty, vtkTextProperty);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Instantiate this object.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
vtkAxisActor::vtkAxisActor()
|
|
{
|
|
this->Point1Coordinate = vtkCoordinate::New();
|
|
this->Point1Coordinate->SetCoordinateSystemToWorld();
|
|
this->Point1Coordinate->SetValue(0.0, 0.0, 0.0);
|
|
|
|
this->Point2Coordinate = vtkCoordinate::New();
|
|
this->Point2Coordinate->SetCoordinateSystemToWorld();
|
|
this->Point2Coordinate->SetValue(0.75, 0.0, 0.0);
|
|
|
|
this->Camera = NULL;
|
|
this->Title = NULL;
|
|
this->Exponent = NULL;
|
|
this->MinorTicksVisible = 1;
|
|
this->MajorTickSize = 1.0;
|
|
this->MinorTickSize = 0.5;
|
|
this->TickLocation = VTK_TICKS_INSIDE;
|
|
this->Range[0] = 0.0;
|
|
this->Range[1] = 1.0;
|
|
this->ScreenSize = 10.;
|
|
this->LabelOffset = 30.;
|
|
this->TitleOffset = 20.;
|
|
this->ExponentOffset = 20.;
|
|
this->TitleAlignLocation = VTK_ALIGN_BOTTOM;
|
|
this->ExponentLocation = VTK_ALIGN_POINT2;
|
|
|
|
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1;
|
|
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1;
|
|
|
|
this->UseTextActor3D = 0;
|
|
this->LabelFormat = new char[8];
|
|
sprintf(this->LabelFormat, "%s", "%-#6.3g");
|
|
|
|
this->TitleTextProperty = vtkTextProperty::New();
|
|
this->TitleTextProperty->SetColor(0., 0., 0.);
|
|
this->TitleTextProperty->SetFontFamilyToArial();
|
|
this->TitleTextProperty->SetFontSize(18.);
|
|
this->TitleTextProperty->SetVerticalJustificationToCentered();
|
|
this->TitleTextProperty->SetJustificationToCentered();
|
|
|
|
this->TitleVector = vtkVectorText::New();
|
|
this->TitleMapper = vtkPolyDataMapper::New();
|
|
this->TitleMapper->SetInputConnection(
|
|
this->TitleVector->GetOutputPort());
|
|
this->TitleActor = vtkAxisFollower::New();
|
|
this->TitleActor->SetAxis(this);
|
|
this->TitleActor->SetMapper(this->TitleMapper);
|
|
this->TitleActor->SetEnableDistanceLOD(0);
|
|
|
|
this->TitleProp3D = vtkProp3DAxisFollower::New();
|
|
this->TitleProp3D->SetAxis(this);
|
|
this->TitleProp3D->SetEnableDistanceLOD(0);
|
|
this->TitleActor3D = vtkTextActor3D::New();
|
|
this->TitleProp3D->SetProp3D(this->TitleActor3D);
|
|
this->TitleActor2D = vtkTextActor::New();
|
|
|
|
this->NumberOfLabelsBuilt = 0;
|
|
this->LabelVectors = NULL;
|
|
this->LabelMappers = NULL;
|
|
this->LabelActors = NULL;
|
|
this->LabelProps3D = NULL;
|
|
this->LabelActors3D = NULL;
|
|
this->LabelActors2D = NULL;
|
|
|
|
this->LabelTextProperty = vtkTextProperty::New();
|
|
this->LabelTextProperty->SetColor(0., 0., 0.);
|
|
this->LabelTextProperty->SetFontFamilyToArial();
|
|
this->LabelTextProperty->SetFontSize(14.);
|
|
this->LabelTextProperty->SetVerticalJustificationToBottom();
|
|
this->LabelTextProperty->SetJustificationToLeft();
|
|
|
|
this->ExponentVector = vtkVectorText::New();
|
|
this->ExponentMapper = vtkPolyDataMapper::New();
|
|
this->ExponentMapper->SetInputConnection(this->ExponentVector->GetOutputPort());
|
|
this->ExponentActor = vtkAxisFollower::New();
|
|
this->ExponentActor->SetAxis(this);
|
|
this->ExponentActor->SetMapper(this->ExponentMapper);
|
|
this->ExponentActor->SetEnableDistanceLOD(0);
|
|
this->ExponentActor2D = vtkTextActor::New();
|
|
|
|
this->ExponentProp3D = vtkProp3DAxisFollower::New();
|
|
this->ExponentProp3D->SetAxis(this);
|
|
this->ExponentProp3D->SetEnableDistanceLOD(0);
|
|
this->ExponentActor3D = vtkTextActor3D::New();
|
|
this->ExponentProp3D->SetProp3D(this->ExponentActor3D);
|
|
|
|
// Main line of axis
|
|
this->AxisLines = vtkPolyData::New();
|
|
this->AxisLinesMapper = vtkPolyDataMapper::New();
|
|
this->AxisLinesMapper->SetInputData(this->AxisLines);
|
|
this->AxisLinesActor = vtkActor::New();
|
|
this->AxisLinesActor->SetMapper(this->AxisLinesMapper);
|
|
|
|
// Major ticks
|
|
this->AxisMajorTicks = vtkPolyData::New();
|
|
this->AxisMajorTicksMapper = vtkPolyDataMapper::New();
|
|
this->AxisMajorTicksMapper->SetInputData(this->AxisMajorTicks);
|
|
this->AxisMajorTicksActor = vtkActor::New();
|
|
this->AxisMajorTicksActor->SetMapper(this->AxisMajorTicksMapper);
|
|
|
|
// Minor ticks
|
|
this->AxisMinorTicks = vtkPolyData::New();
|
|
this->AxisMinorTicksMapper = vtkPolyDataMapper::New();
|
|
this->AxisMinorTicksMapper->SetInputData(this->AxisMinorTicks);
|
|
this->AxisMinorTicksActor = vtkActor::New();
|
|
this->AxisMinorTicksActor->SetMapper(this->AxisMinorTicksMapper);
|
|
|
|
this->Gridlines = vtkPolyData::New();
|
|
this->GridlinesMapper = vtkPolyDataMapper::New();
|
|
this->GridlinesMapper->SetInputData(this->Gridlines);
|
|
this->GridlinesActor = vtkActor::New();
|
|
this->GridlinesActor->SetMapper(this->GridlinesMapper);
|
|
this->InnerGridlines = vtkPolyData::New();
|
|
this->InnerGridlinesMapper = vtkPolyDataMapper::New();
|
|
this->InnerGridlinesMapper->SetInputData(this->InnerGridlines);
|
|
this->InnerGridlinesActor = vtkActor::New();
|
|
this->InnerGridlinesActor->SetMapper(this->InnerGridlinesMapper);
|
|
this->Gridpolys = vtkPolyData::New();
|
|
this->GridpolysMapper = vtkPolyDataMapper::New();
|
|
this->GridpolysMapper->SetInputData(this->Gridpolys);
|
|
this->GridpolysActor = vtkActor::New();
|
|
this->GridpolysActor->SetMapper(this->GridpolysMapper);
|
|
|
|
this->AxisVisibility = 1;
|
|
this->TickVisibility = 1;
|
|
this->LabelVisibility = 1;
|
|
this->TitleVisibility = 1;
|
|
this->ExponentVisibility = false;
|
|
|
|
this->DrawGridlines = 0;
|
|
this->DrawGridlinesOnly = 0;
|
|
this->GridlineXLength = 1.;
|
|
this->GridlineYLength = 1.;
|
|
this->GridlineZLength = 1.;
|
|
|
|
this->DrawInnerGridlines = 0;
|
|
|
|
this->DrawGridpolys = 0;
|
|
|
|
this->AxisType = VTK_AXIS_TYPE_X;
|
|
this->Log = false;
|
|
//
|
|
// AxisPosition denotes which of the four possibilities in relation
|
|
// to the bounding box. An x-Type axis with min min, means the x-axis
|
|
// at minimum y and minimum z values of the bbox.
|
|
//
|
|
this->AxisPosition = VTK_AXIS_POS_MINMIN;
|
|
|
|
this->LastLabelStart = 100000;
|
|
|
|
this->LastAxisPosition = -1;
|
|
this->LastTickLocation = -1;
|
|
this->LastTickVisibility = -1;
|
|
this->LastDrawGridlines = -1;
|
|
this->LastDrawInnerGridlines = -1;
|
|
this->LastDrawGridpolys = -1;
|
|
this->LastMinorTicksVisible = -1;
|
|
this->LastRange[0] = -1.0;
|
|
this->LastRange[1] = -1.0;
|
|
|
|
this->MinorTickPts = vtkPoints::New();
|
|
this->MajorTickPts = vtkPoints::New();
|
|
this->GridlinePts = vtkPoints::New();
|
|
this->InnerGridlinePts = vtkPoints::New();
|
|
this->GridpolyPts = vtkPoints::New();
|
|
|
|
this->AxisHasZeroLength = false;
|
|
|
|
this->MinorStart = 0.;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
this->MajorStart[i] = 0.;
|
|
}
|
|
this->DeltaMinor = 1.;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
this->DeltaMajor[i] = 1.;
|
|
}
|
|
|
|
this->MinorRangeStart = 0.;
|
|
this->MajorRangeStart = 0.;
|
|
this->DeltaRangeMinor = 1.;
|
|
this->DeltaRangeMajor = 1.;
|
|
|
|
this->CalculateTitleOffset = 0;
|
|
this->CalculateLabelOffset = 0;
|
|
|
|
// Instance variables specific to 2D mode
|
|
this->Use2DMode = 0;
|
|
this->SaveTitlePosition = 0;
|
|
this->TitleConstantPosition[0] = this->TitleConstantPosition[1] = 0.;
|
|
this->VerticalOffsetXTitle2D = -40.;
|
|
this->HorizontalOffsetYTitle2D = -50.;
|
|
this->LastMinDisplayCoordinate[0] = 0;
|
|
this->LastMinDisplayCoordinate[1] = 0;
|
|
this->LastMinDisplayCoordinate[2] = 0;
|
|
this->LastMaxDisplayCoordinate[0] = 0;
|
|
this->LastMaxDisplayCoordinate[1] = 0;
|
|
this->LastMaxDisplayCoordinate[2] = 0;
|
|
|
|
// 0: All locations
|
|
this->DrawGridlinesLocation = this->LastDrawGridlinesLocation = 0;
|
|
|
|
// reset the base
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
this->AxisBaseForX[i] = this->AxisBaseForY[i] = this->AxisBaseForZ[i] = 0.0;
|
|
}
|
|
this->AxisBaseForX[0] = this->AxisBaseForY[1] = this->AxisBaseForZ[2] = 1.0;
|
|
this->AxisOnOrigin = 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAxisActor::~vtkAxisActor()
|
|
{
|
|
this->SetCamera(NULL);
|
|
|
|
if (this->Point1Coordinate)
|
|
{
|
|
this->Point1Coordinate->Delete();
|
|
this->Point1Coordinate = NULL;
|
|
}
|
|
|
|
if (this->Point2Coordinate)
|
|
{
|
|
this->Point2Coordinate->Delete();
|
|
this->Point2Coordinate = NULL;
|
|
}
|
|
|
|
delete [] this->LabelFormat;
|
|
this->LabelFormat = NULL;
|
|
|
|
if (this->TitleVector)
|
|
{
|
|
this->TitleVector->Delete();
|
|
this->TitleVector = NULL;
|
|
}
|
|
if (this->TitleMapper)
|
|
{
|
|
this->TitleMapper->Delete();
|
|
this->TitleMapper = NULL;
|
|
}
|
|
if (this->TitleActor)
|
|
{
|
|
this->TitleActor->Delete();
|
|
this->TitleActor = NULL;
|
|
}
|
|
this->TitleProp3D->Delete();
|
|
this->TitleProp3D = NULL;
|
|
this->TitleActor3D->Delete();
|
|
this->TitleActor3D = NULL;
|
|
if (this->TitleActor2D)
|
|
{
|
|
this->TitleActor2D->Delete();
|
|
this->TitleActor2D = NULL;
|
|
}
|
|
|
|
delete [] this->Title;
|
|
this->Title = NULL;
|
|
|
|
delete [] this->Exponent;
|
|
this->Exponent = NULL;
|
|
|
|
// delete exponent components
|
|
if (this->ExponentVector)
|
|
{
|
|
this->ExponentVector->Delete();
|
|
this->ExponentVector = NULL;
|
|
}
|
|
if (this->ExponentMapper)
|
|
{
|
|
this->ExponentMapper->Delete();
|
|
this->ExponentMapper = NULL;
|
|
}
|
|
if (this->ExponentActor)
|
|
{
|
|
this->ExponentActor->Delete();
|
|
this->ExponentActor = NULL;
|
|
}
|
|
this->ExponentProp3D->Delete();
|
|
this->ExponentProp3D = NULL;
|
|
this->ExponentActor3D->Delete();
|
|
this->ExponentActor3D = NULL;
|
|
if (this->ExponentActor2D)
|
|
{
|
|
this->ExponentActor2D->Delete();
|
|
this->ExponentActor2D = NULL;
|
|
}
|
|
|
|
if (this->TitleTextProperty)
|
|
{
|
|
this->TitleTextProperty->Delete();
|
|
this->TitleTextProperty = NULL;
|
|
}
|
|
|
|
if (this->LabelMappers != NULL)
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelVectors[i]->Delete();
|
|
this->LabelMappers[i]->Delete();
|
|
this->LabelActors[i]->Delete();
|
|
this->LabelProps3D[i]->Delete();
|
|
this->LabelActors3D[i]->Delete();
|
|
this->LabelActors2D[i]->Delete();
|
|
}
|
|
this->NumberOfLabelsBuilt = 0;
|
|
delete [] this->LabelVectors;
|
|
delete [] this->LabelMappers;
|
|
delete [] this->LabelActors;
|
|
delete [] this->LabelProps3D;
|
|
delete [] this->LabelActors3D;
|
|
delete [] this->LabelActors2D;
|
|
this->LabelVectors = NULL;
|
|
this->LabelMappers = NULL;
|
|
this->LabelActors = NULL;
|
|
this->LabelProps3D = NULL;
|
|
this->LabelActors3D = NULL;
|
|
this->LabelActors2D = NULL;
|
|
}
|
|
if (this->LabelTextProperty)
|
|
{
|
|
this->LabelTextProperty->Delete();
|
|
this->LabelTextProperty = NULL;
|
|
}
|
|
|
|
// main line of the axis
|
|
if (this->AxisLines)
|
|
{
|
|
this->AxisLines->Delete();
|
|
this->AxisLines = NULL;
|
|
}
|
|
if (this->AxisLinesMapper)
|
|
{
|
|
this->AxisLinesMapper->Delete();
|
|
this->AxisLinesMapper = NULL;
|
|
}
|
|
if (this->AxisLinesActor)
|
|
{
|
|
this->AxisLinesActor->Delete();
|
|
this->AxisLinesActor = NULL;
|
|
}
|
|
|
|
//major ticks components
|
|
if (this->AxisMajorTicks)
|
|
{
|
|
this->AxisMajorTicks->Delete();
|
|
this->AxisMajorTicks = NULL;
|
|
}
|
|
if (this->AxisMajorTicksMapper)
|
|
{
|
|
this->AxisMajorTicksMapper->Delete();
|
|
this->AxisMajorTicksMapper = NULL;
|
|
}
|
|
if (this->AxisMajorTicksActor)
|
|
{
|
|
this->AxisMajorTicksActor->Delete();
|
|
this->AxisMajorTicksActor = NULL;
|
|
}
|
|
|
|
//minor ticks components
|
|
if (this->AxisMinorTicks)
|
|
{
|
|
this->AxisMinorTicks->Delete();
|
|
this->AxisMinorTicks = NULL;
|
|
}
|
|
if (this->AxisMinorTicksMapper)
|
|
{
|
|
this->AxisMinorTicksMapper->Delete();
|
|
this->AxisMinorTicksMapper = NULL;
|
|
}
|
|
if (this->AxisMinorTicksActor)
|
|
{
|
|
this->AxisMinorTicksActor->Delete();
|
|
this->AxisMinorTicksActor = NULL;
|
|
}
|
|
|
|
if (this->Gridlines)
|
|
{
|
|
this->Gridlines->Delete();
|
|
this->Gridlines = NULL;
|
|
}
|
|
if (this->GridlinesMapper)
|
|
{
|
|
this->GridlinesMapper->Delete();
|
|
this->GridlinesMapper = NULL;
|
|
}
|
|
if (this->GridlinesActor)
|
|
{
|
|
this->GridlinesActor->Delete();
|
|
this->GridlinesActor = NULL;
|
|
}
|
|
|
|
if (this->InnerGridlines)
|
|
{
|
|
this->InnerGridlines->Delete();
|
|
this->InnerGridlines = NULL;
|
|
}
|
|
if (this->InnerGridlinesMapper)
|
|
{
|
|
this->InnerGridlinesMapper->Delete();
|
|
this->InnerGridlinesMapper = NULL;
|
|
}
|
|
if (this->InnerGridlinesActor)
|
|
{
|
|
this->InnerGridlinesActor->Delete();
|
|
this->InnerGridlinesActor = NULL;
|
|
}
|
|
|
|
if (this->Gridpolys)
|
|
{
|
|
this->Gridpolys->Delete();
|
|
this->Gridpolys = NULL;
|
|
}
|
|
if (this->GridpolysMapper)
|
|
{
|
|
this->GridpolysMapper->Delete();
|
|
this->GridpolysMapper = NULL;
|
|
}
|
|
if (this->GridpolysActor)
|
|
{
|
|
this->GridpolysActor->Delete();
|
|
this->GridpolysActor = NULL;
|
|
}
|
|
|
|
if (this->MinorTickPts)
|
|
{
|
|
this->MinorTickPts ->Delete();
|
|
this->MinorTickPts = NULL;
|
|
}
|
|
if (this->MajorTickPts)
|
|
{
|
|
this->MajorTickPts->Delete();
|
|
this->MajorTickPts = NULL;
|
|
}
|
|
if (this->GridlinePts)
|
|
{
|
|
this->GridlinePts->Delete();
|
|
this->GridlinePts = NULL;
|
|
}
|
|
if (this->InnerGridlinePts)
|
|
{
|
|
this->InnerGridlinePts->Delete();
|
|
this->InnerGridlinePts = NULL;
|
|
}
|
|
if (this->GridpolyPts)
|
|
{
|
|
this->GridpolyPts->Delete();
|
|
this->GridpolyPts = NULL;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::ReleaseGraphicsResources(vtkWindow *win)
|
|
{
|
|
this->TitleActor->ReleaseGraphicsResources(win);
|
|
this->TitleProp3D->ReleaseGraphicsResources(win);
|
|
this->TitleActor3D->ReleaseGraphicsResources(win);
|
|
this->TitleActor2D->ReleaseGraphicsResources(win);
|
|
this->ExponentActor->ReleaseGraphicsResources(win);
|
|
this->ExponentProp3D->ReleaseGraphicsResources(win);
|
|
this->ExponentActor3D->ReleaseGraphicsResources(win);
|
|
this->ExponentActor2D->ReleaseGraphicsResources(win);
|
|
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors[i]->ReleaseGraphicsResources(win);
|
|
this->LabelProps3D[i]->ReleaseGraphicsResources(win);
|
|
this->LabelActors3D[i]->ReleaseGraphicsResources(win);
|
|
this->LabelActors2D[i]->ReleaseGraphicsResources(win);
|
|
}
|
|
this->AxisLinesActor->ReleaseGraphicsResources(win);
|
|
this->AxisMajorTicksActor->ReleaseGraphicsResources(win);
|
|
this->AxisMinorTicksActor->ReleaseGraphicsResources(win);
|
|
|
|
this->GridlinesActor->ReleaseGraphicsResources(win);
|
|
this->InnerGridlinesActor->ReleaseGraphicsResources(win);
|
|
this->GridpolysActor->ReleaseGraphicsResources(win);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int vtkAxisActor::RenderOpaqueGeometry(vtkViewport *viewport)
|
|
{
|
|
int renderedSomething = 0;
|
|
|
|
this->BuildAxis(viewport, false);
|
|
|
|
// Everything is built, just have to render
|
|
|
|
if (!this->AxisHasZeroLength)
|
|
{
|
|
if (this->DrawGridlinesOnly && this->DrawGridlines)
|
|
{
|
|
// Exit !!!!
|
|
return this->GridlinesActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
if (this->Title != NULL && this->Title[0] != 0 && this->TitleVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->TitleActor2D->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->TitleProp3D->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
}
|
|
if (this->AxisVisibility)
|
|
{
|
|
renderedSomething += this->AxisLinesActor->RenderOpaqueGeometry(viewport);
|
|
if (this->TickVisibility)
|
|
{
|
|
renderedSomething += this->AxisMajorTicksActor->RenderOpaqueGeometry(viewport);
|
|
renderedSomething += this->AxisMinorTicksActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
}
|
|
if (this->DrawGridlines)
|
|
{
|
|
renderedSomething += this->GridlinesActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
if (this->DrawInnerGridlines)
|
|
{
|
|
renderedSomething += this->InnerGridlinesActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
if (this->LabelVisibility)
|
|
{
|
|
for (int i = 0; i<this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething +=
|
|
this->LabelActors2D[i]->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething +=
|
|
this->LabelActors3D[i]->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething +=
|
|
this->LabelActors[i]->RenderOpaqueGeometry(viewport);
|
|
}
|
|
}
|
|
|
|
if (this->ExponentVisibility && this->Exponent != NULL && this->Exponent[0] != 0)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->ExponentActor2D->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->ExponentProp3D->RenderOpaqueGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->ExponentActor->RenderOpaqueGeometry(viewport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return renderedSomething;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Build the translucent poly actors and render.
|
|
//-----------------------------------------------------------------------------
|
|
int vtkAxisActor::RenderTranslucentGeometry(vtkViewport *viewport)
|
|
{
|
|
return this->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Build the translucent poly actors and render.
|
|
//-----------------------------------------------------------------------------
|
|
int vtkAxisActor::RenderTranslucentPolygonalGeometry(vtkViewport *viewport)
|
|
{
|
|
|
|
int renderedSomething = 0;
|
|
|
|
this->BuildAxis(viewport, false);
|
|
|
|
// Everything is built, just have to render
|
|
|
|
if (!this->AxisHasZeroLength && !this->DrawGridlinesOnly)
|
|
{
|
|
if (this->DrawGridpolys)
|
|
{
|
|
renderedSomething += this->GridpolysActor->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
if (this->Title != NULL && this->Title[0] != 0 && this->TitleVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->TitleActor2D->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->TitleProp3D->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->TitleActor->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
}
|
|
if (this->LabelVisibility)
|
|
{
|
|
for (int i = 0; i<this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething +=
|
|
this->LabelActors2D[i]->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething +=
|
|
this->LabelProps3D[i]->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething +=
|
|
this->LabelActors[i]->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
}
|
|
if (this->ExponentVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->ExponentActor2D->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->ExponentProp3D->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->ExponentActor->RenderTranslucentPolygonalGeometry(viewport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return renderedSomething;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Render the 2d annotations.
|
|
//-----------------------------------------------------------------------------
|
|
int vtkAxisActor::RenderOverlay(vtkViewport *viewport)
|
|
{
|
|
int renderedSomething = 0;
|
|
|
|
// Everything is built, just have to render
|
|
if (!this->AxisHasZeroLength && !this->DrawGridlinesOnly)
|
|
{
|
|
if (this->TitleVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->TitleActor2D->RenderOverlay(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->TitleProp3D->RenderOverlay(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->TitleActor->RenderOverlay(viewport);
|
|
}
|
|
}
|
|
if (this->LabelVisibility)
|
|
{
|
|
for (int i = 0; i<this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->LabelActors2D[i]->RenderOverlay(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->LabelProps3D[i]->RenderOverlay(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->LabelActors[i]->RenderOverlay(viewport);
|
|
}
|
|
}
|
|
if (this->ExponentVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
renderedSomething += this->ExponentActor2D->RenderOverlay(viewport);
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
renderedSomething += this->ExponentProp3D->RenderOverlay(viewport);
|
|
}
|
|
else
|
|
{
|
|
renderedSomething += this->ExponentActor->RenderOverlay(viewport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return renderedSomething;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
int vtkAxisActor::HasTranslucentPolygonalGeometry()
|
|
{
|
|
if (this->Visibility && !this->AxisHasZeroLength)
|
|
{
|
|
if (this->TitleVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
if (this->TitleActor2D->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
if (this->TitleProp3D->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this->TitleActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->LabelVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; ++i)
|
|
{
|
|
if (this->LabelActors2D[i]->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
} // end if
|
|
} // end for
|
|
} // end 2D
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; ++i)
|
|
{
|
|
//if (this->LabelActors3D[i]->HasTranslucentPolygonalGeometry())
|
|
if (this->LabelProps3D[i]->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
} // end if
|
|
} // end for
|
|
} // end 3D
|
|
else
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; ++i)
|
|
{
|
|
if (this->LabelActors[i]->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
} // end if
|
|
} // end for
|
|
} // end 3D
|
|
if (this->ExponentVisibility)
|
|
{
|
|
if (this->Use2DMode)
|
|
{
|
|
if (this->ExponentActor2D->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else if (this->UseTextActor3D)
|
|
{
|
|
if (this->ExponentProp3D->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this->ExponentActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
} // end label vis
|
|
|
|
if (this->AxisLinesActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (this->TickVisibility &&
|
|
this->AxisMajorTicksActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
if (this->TickVisibility &&
|
|
this->AxisMinorTicksActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (this->DrawGridlines &&
|
|
this->GridlinesActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (this->DrawInnerGridlines &&
|
|
this->InnerGridlinesActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (this->DrawGridpolys &&
|
|
this->GridpolysActor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return this->Superclass::HasTranslucentPolygonalGeometry();
|
|
} // end this vis
|
|
return 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
// Perform some initialization, determine which Axis type we are
|
|
//-----------------------------------------------------------------------------*
|
|
void vtkAxisActor::BuildAxis(vtkViewport *viewport, bool force)
|
|
{
|
|
// We'll do our computation in world coordinates. First determine the
|
|
// location of the endpoints.
|
|
double *x, p1[3], p2[3];
|
|
x = this->Point1Coordinate->GetValue();
|
|
p1[0] = x[0]; p1[1] = x[1]; p1[2] = x[2];
|
|
x = this->Point2Coordinate->GetValue();
|
|
p2[0] = x[0]; p2[1] = x[1]; p2[2] = x[2];
|
|
|
|
//
|
|
// Test for axis of zero length.
|
|
//
|
|
if (p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2])
|
|
{
|
|
vtkDebugMacro(<< "Axis has zero length, not building.");
|
|
this->AxisHasZeroLength = true;
|
|
return;
|
|
}
|
|
this->AxisHasZeroLength = false;
|
|
|
|
if (!force && this->GetMTime() < this->BuildTime.GetMTime() &&
|
|
viewport->GetMTime() < this->BuildTime.GetMTime())
|
|
{
|
|
return; //already built
|
|
}
|
|
|
|
if (this->Log)
|
|
{
|
|
if (this->Range[0] <= 0.0)
|
|
{
|
|
vtkWarningMacro(<< "Range value undefined for log scale enabled. "
|
|
<< "Current Range: (" << this->Range[0] << ", " << this->Range[1] << ")"
|
|
<< "Range[0] must be > 0.0. "
|
|
<< ".");
|
|
return;
|
|
}
|
|
if (this->MinorRangeStart <= 0.0 || this->MajorRangeStart <= 0.0)
|
|
{
|
|
vtkWarningMacro(<< "MinorRangeStart value or MajorRangeStart value undefined for log scale enabled"
|
|
<< "MinorRangeStart: " << this->MinorRangeStart << ", MajorRangeStart: " << this->MajorRangeStart << ". "
|
|
<< "MinorRangeStart and MajorRangeStart must be > 0.0. "
|
|
<< ".");
|
|
return;
|
|
}
|
|
}
|
|
|
|
vtkDebugMacro(<< "Rebuilding axis");
|
|
|
|
if (force || this->GetProperty()->GetMTime() > this->BuildTime.GetMTime())
|
|
{
|
|
//this->AxisLinesActor->SetProperty(this->GetProperty());
|
|
this->TitleActor->SetProperty(this->GetProperty());
|
|
this->TitleActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->TitleActor->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
if (this->UseTextActor3D)
|
|
{
|
|
this->TitleActor3D->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Generate the axis and tick marks.
|
|
//
|
|
bool ticksRebuilt;
|
|
ticksRebuilt = this->BuildTickPoints(p1, p2, force);
|
|
|
|
bool tickVisChanged = this->TickVisibilityChanged();
|
|
|
|
if (force || ticksRebuilt || tickVisChanged || this->LastDrawGridlinesLocation != this->DrawGridlinesLocation)
|
|
{
|
|
this->LastDrawGridlinesLocation = this->DrawGridlinesLocation;
|
|
this->SetAxisPointsAndLines();
|
|
}
|
|
|
|
// If the ticks have been rebuilt it is more than likely
|
|
// that the labels should follow...
|
|
this->BuildLabels(viewport, force || ticksRebuilt);
|
|
if (this->Use2DMode == 1)
|
|
{
|
|
this->BuildLabels2D(viewport, force || ticksRebuilt);
|
|
}
|
|
|
|
if (this->Title != NULL && this->Title[0] != 0)
|
|
{
|
|
this->InitTitle();
|
|
}
|
|
|
|
if (this->ExponentVisibility && this->Exponent != NULL && this->Exponent[0] != 0)
|
|
{
|
|
this->InitExponent();
|
|
}
|
|
|
|
if (this->Title != NULL && this->Title[0] != 0)
|
|
{
|
|
this->BuildTitle(force || ticksRebuilt);
|
|
if (this->Use2DMode == 1)
|
|
{
|
|
this->BuildTitle2D(viewport, force || ticksRebuilt);
|
|
}
|
|
}
|
|
|
|
if (this->ExponentVisibility && this->Exponent != NULL && this->Exponent[0] != 0)
|
|
{
|
|
// build exponent
|
|
this->BuildExponent(force);
|
|
if (this->Use2DMode == 1)
|
|
{
|
|
this->BuildExponent2D(viewport, force);
|
|
}
|
|
}
|
|
|
|
this->LastAxisPosition = this->AxisPosition;
|
|
this->LastRange[0] = this->Range[0];
|
|
this->LastRange[1] = this->Range[1];
|
|
this->BuildTime.Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Set label values and properties.
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
vtkAxisActor::BuildLabels(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!force && !this->LabelVisibility)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double maxLabelScale = 0.0;
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors[i]->SetCamera(this->Camera);
|
|
this->LabelProps3D[i]->SetCamera(this->Camera);
|
|
this->LabelActors[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
|
|
this->LabelActors[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
|
|
this->LabelActors[i]->SetOrientation(0., 0., this->LabelTextProperty->GetOrientation());
|
|
this->LabelProps3D[i]->SetOrientation(0., 0., this->LabelTextProperty->GetOrientation());
|
|
|
|
if (this->UseTextActor3D)
|
|
{
|
|
this->LabelActors3D[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
|
|
|
|
double labelActorsBounds[6];
|
|
this->LabelActors[i]->GetMapper()->GetBounds(labelActorsBounds);
|
|
const double labelActorsWidth = (labelActorsBounds[1] - labelActorsBounds[0]);
|
|
|
|
int labelActors3DBounds[4];
|
|
this->LabelActors3D[i]->GetBoundingBox(labelActors3DBounds);
|
|
const double labelActors3DWidth =
|
|
static_cast<double>(labelActors3DBounds[1] - labelActors3DBounds[0]);
|
|
|
|
if (labelActorsWidth / labelActors3DWidth > maxLabelScale)
|
|
{
|
|
maxLabelScale = labelActorsWidth / labelActors3DWidth;
|
|
}
|
|
}
|
|
|
|
this->LabelActors[i]->SetAutoCenter(1);
|
|
this->LabelProps3D[i]->SetAutoCenter(1);
|
|
}
|
|
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors3D[i]->SetScale(maxLabelScale);
|
|
}
|
|
|
|
if (force || this->BuildTime.GetMTime() < this->BoundsTime.GetMTime() ||
|
|
this->AxisPosition != this->LastAxisPosition ||
|
|
this->LastRange[0] != this->Range[0] ||
|
|
this->LastRange[1] != this->Range[1])
|
|
{
|
|
this->SetLabelPositions(viewport, force);
|
|
}
|
|
}
|
|
|
|
static const int vtkAxisActorMultiplierTable1[4] = { -1, -1, 1, 1};
|
|
static const int vtkAxisActorMultiplierTable2[4] = { -1, 1, 1, -1};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determine and set scale factor and position for labels.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetLabelPositions(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// xadjust & yadjust are used for positioning the label correctly
|
|
// depending upon the 'orientation' of the axis as determined
|
|
// by its position in view space (via transformed bounds).
|
|
//
|
|
double displayBounds[6] = { 0., 0., 0., 0., 0., 0.};
|
|
this->TransformBounds(viewport, displayBounds);
|
|
|
|
double bounds[6], tickBottom[3], tickTop[3], pos[3];
|
|
double labelAngle = vtkMath::RadiansFromDegrees(this->LabelTextProperty->GetOrientation());
|
|
double labelCos = fabs(cos(labelAngle));
|
|
double labelSin = fabs(sin(labelAngle));
|
|
vtkAxisFollower* pAxisFollower = NULL;
|
|
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt &&
|
|
i < this->MajorTickPts->GetNumberOfPoints(); i++)
|
|
{
|
|
int ptIdx = 4 * i;
|
|
this->MajorTickPts->GetPoint(ptIdx, tickTop);
|
|
this->MajorTickPts->GetPoint(ptIdx + 1, tickBottom);
|
|
|
|
pAxisFollower = this->LabelActors[i];
|
|
|
|
// get Label actor Transform matrix
|
|
vtkRenderer* ren = vtkRenderer::SafeDownCast(viewport);
|
|
if (ren)
|
|
{
|
|
pAxisFollower->ComputeTransformMatrix(ren);
|
|
}
|
|
|
|
// WARNING: calling GetBounds() before ComputeTransformMatrix(), prevent this->Transform to be updated
|
|
|
|
// previous version: this->LabelActors[i]->GetMapper()->GetBounds(bounds); didn't include scale labels
|
|
// vtkProp3D::GetBounds() include previous transform (scale, orientation, translation)
|
|
pAxisFollower->GetBounds(bounds);
|
|
double labelWidth = (bounds[1] - bounds[0]);
|
|
double labelHeight = (bounds[3] - bounds[2]);
|
|
|
|
if (this->CalculateLabelOffset)
|
|
{
|
|
vtkWarningMacro("CalculateLabelOffset flag is now deprecated and has no effect");
|
|
}
|
|
|
|
if (this->TickVisibility)
|
|
{
|
|
pos[0] = tickBottom[0];
|
|
pos[1] = tickBottom[1];
|
|
pos[2] = tickBottom[2];
|
|
}
|
|
else
|
|
{
|
|
pos[0] = (tickTop[0] + tickBottom[0]) / 2;
|
|
pos[1] = (tickTop[1] + tickBottom[1]) / 2;
|
|
pos[2] = (tickTop[2] + tickBottom[2]) / 2;
|
|
}
|
|
|
|
double delta = 0.5 * (labelWidth * labelSin + labelHeight * labelCos);
|
|
pAxisFollower->SetScreenOffset(this->LabelOffset + (delta) * this->ScreenSize);
|
|
this->LabelProps3D[i]->SetScreenOffset(this->LabelOffset + (delta) * this->ScreenSize);
|
|
|
|
pAxisFollower->SetPosition(pos[0], pos[1], pos[2]);
|
|
this->LabelProps3D[i]->SetPosition(pos[0], pos[1], pos[2]);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Set 2D label values and properties.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildLabels2D(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors2D[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
|
|
this->LabelActors2D[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
|
|
this->LabelActors2D[i]->GetTextProperty()->ShallowCopy(this->LabelTextProperty);
|
|
}
|
|
|
|
this->NeedBuild2D = this->BoundsDisplayCoordinateChanged(viewport);
|
|
if (force || this->NeedBuild2D)
|
|
{
|
|
this->SetLabelPositions2D(viewport, force);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determine and set scale factor and position for 2D labels.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetLabelPositions2D(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!force && (!this->LabelVisibility || this->NumberOfLabelsBuilt == 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int xmult = 0;
|
|
int ymult = 0;
|
|
double xcoeff = 0.;
|
|
double ycoeff = 0.;
|
|
|
|
// we are in 2D mode, so no Z axis
|
|
switch (this->AxisType)
|
|
{
|
|
case VTK_AXIS_TYPE_X :
|
|
xmult = 0;
|
|
ymult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
xcoeff = 0.5;
|
|
ycoeff = 1.0;
|
|
break;
|
|
case VTK_AXIS_TYPE_Y :
|
|
xmult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
ymult = 0;
|
|
xcoeff = 1.0;
|
|
ycoeff = 0.5;
|
|
break;
|
|
default:
|
|
// shouldn't get here
|
|
break;
|
|
}
|
|
|
|
int ptIdx;
|
|
//
|
|
// xadjust & yadjust are used for positioning the label correctly
|
|
// depending upon the 'orientation' of the axis as determined
|
|
// by its position in view space (via transformed bounds).
|
|
//
|
|
double displayBounds[6] = { 0., 0., 0., 0., 0., 0.};
|
|
this->TransformBounds(viewport, displayBounds);
|
|
double xadjust = (displayBounds[0] > displayBounds[1] ? -1 : 1);
|
|
double yadjust = (displayBounds[2] > displayBounds[3] ? -1 : 1);
|
|
double transpos[3] = {0., 0., 0.};
|
|
double center[3], tick[3], pos[2];
|
|
|
|
vtkTextRenderer *tren = vtkTextRenderer::GetInstance();
|
|
if (!tren)
|
|
{
|
|
vtkErrorMacro(<< "Unable to obtain the vtkTextRenderer instance!");
|
|
return;
|
|
}
|
|
|
|
vtkWindow *win = viewport->GetVTKWindow();
|
|
if (!win)
|
|
{
|
|
vtkErrorMacro(<< "No render window available: cannot determine DPI.");
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
ptIdx = 4*i + 1;
|
|
|
|
this->MajorTickPts->GetPoint(ptIdx, tick);
|
|
|
|
center[0] = tick[0] + xmult * this->MinorTickSize;
|
|
center[1] = tick[1] + ymult * this->MinorTickSize;
|
|
center[2] = tick[2];
|
|
|
|
viewport->SetWorldPoint(center[0], center[1], center[2], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transpos);
|
|
|
|
int bbox[4];
|
|
if (!tren->GetBoundingBox(this->LabelActors2D[i]->GetTextProperty(),
|
|
this->LabelActors2D[i]->GetInput(), bbox,
|
|
win->GetDPI()))
|
|
{
|
|
vtkErrorMacro(<< "Unable to calculate bounding box for label "
|
|
<< this->LabelActors2D[i]->GetInput());
|
|
continue;
|
|
}
|
|
|
|
double width = (bbox[1] -bbox[0]);
|
|
double height = (bbox[3] -bbox[2]);
|
|
|
|
pos[0] = (transpos[0] - xadjust*width*xcoeff);
|
|
pos[1] = (transpos[1] - yadjust*height*ycoeff);
|
|
|
|
this->LabelActors2D[i]->SetPosition(pos[0], pos[1]);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::InitTitle()
|
|
{
|
|
// ---------- Title ----------
|
|
// Classic
|
|
// Source => Mapper => Actor
|
|
// TitleVector => TitleMapper => TitleActor
|
|
|
|
// Text 3D
|
|
// vtkTextActor3D::TitleActor3D _ vtkProp3DAxisFollower::TitleProp3D
|
|
// relation: TitleProp3D->SetProp3D(this->TitleActor3D)
|
|
this->TitleVector->SetText(this->Title);
|
|
this->TitleActor3D->SetInput(this->Title);
|
|
|
|
this->TitleActor->SetProperty(this->GetProperty());
|
|
this->TitleActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->TitleActor->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
|
|
this->TitleActor3D->SetTextProperty(this->TitleTextProperty);
|
|
|
|
this->TitleActor->SetCamera(this->Camera);
|
|
this->TitleProp3D->SetCamera(this->Camera);
|
|
|
|
// axis follower origin is on top-left corner, auto-center put it on the center of the label
|
|
this->TitleActor->SetAutoCenter(1);
|
|
this->TitleProp3D->SetAutoCenter(1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::InitExponent()
|
|
{
|
|
std::stringstream expStr;
|
|
expStr << "e" << this->Exponent;
|
|
this->ExponentVector->SetText(expStr.str().c_str());
|
|
this->ExponentActor3D->SetInput(expStr.str().c_str());
|
|
this->ExponentActor->SetProperty(this->GetProperty());
|
|
this->ExponentActor3D->SetTextProperty(this->TitleTextProperty);
|
|
this->ExponentActor->SetCamera(this->Camera);
|
|
this->ExponentProp3D->SetCamera(this->Camera);
|
|
this->ExponentActor->SetAutoCenter(1);
|
|
this->ExponentProp3D->SetAutoCenter(1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determines scale and position for the Title. Currently,
|
|
// title can only be centered with respect to its axis.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildTitle(bool force)
|
|
{
|
|
this->NeedBuild2D = false;
|
|
|
|
if (!force && !this->TitleVisibility)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!force && this->TitleTextTime.GetMTime() < this->BuildTime.GetMTime() &&
|
|
this->BoundsTime.GetMTime() < this->BuildTime.GetMTime() &&
|
|
this->LabelBuildTime.GetMTime() < this->BuildTime.GetMTime())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Text property
|
|
this->TitleActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->TitleActor->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
|
|
// ---------- labels size ----------
|
|
// local orientation (in the plane of the label)
|
|
double labelAngle = vtkMath::RadiansFromDegrees(this->LabelTextProperty->GetOrientation());
|
|
double labelCos = fabs(cos(labelAngle)), labelSin = fabs(sin(labelAngle));
|
|
double labBounds[6];
|
|
double offset[2] = {0, this->TitleOffset};
|
|
|
|
// find max height label (with the label text property considered)
|
|
// only when title is on bottom
|
|
if (this->LabelVisibility &&
|
|
this->TitleAlignLocation != VTK_ALIGN_TOP)
|
|
{
|
|
double labelMaxHeight, labHeight;
|
|
labelMaxHeight = labHeight = 0;
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors[i]->GetMapper()->GetBounds(labBounds);
|
|
|
|
// labels actor aren't oriented yet, width and height are considered in
|
|
// their local coordinate system
|
|
// however, LabelTextProperty can orient it, but locally (in its plane)
|
|
labHeight =
|
|
(labBounds[1] - labBounds[0]) * labelSin +
|
|
(labBounds[3] - labBounds[2]) * labelCos;
|
|
labelMaxHeight = (labHeight > labelMaxHeight ? labHeight : labelMaxHeight);
|
|
}
|
|
offset[1] += this->LabelOffset + this->ScreenSize * labelMaxHeight;
|
|
}
|
|
|
|
// ---------- title size ----------
|
|
double titleBounds[6];
|
|
this->TitleActor->GetMapper()->GetBounds(titleBounds);
|
|
double halfTitleHeight =
|
|
(titleBounds[3] - titleBounds[2]) * 0.5;
|
|
double halfTitleWidth =
|
|
(titleBounds[1] - titleBounds[0]) * 0.5;
|
|
offset[1] += this->ScreenSize * halfTitleHeight;
|
|
|
|
double *p1 = this->Point1Coordinate->GetValue();
|
|
double *p2 = this->Point2Coordinate->GetValue();
|
|
double pos[3];
|
|
if (this->CalculateTitleOffset)
|
|
{
|
|
vtkWarningMacro("CalculateTitleOffset flag is now deprecated and has no effect");
|
|
}
|
|
int vertOffsetSign = 1;
|
|
switch (this->TitleAlignLocation)
|
|
{
|
|
case (VTK_ALIGN_TOP):
|
|
vertOffsetSign = -1;
|
|
VTK_FALLTHROUGH;
|
|
// NO BREAK
|
|
case (VTK_ALIGN_BOTTOM):
|
|
// Position to center of axis
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p1[i] + (p2[i] - p1[i]) / 2.0;
|
|
}
|
|
break;
|
|
case (VTK_ALIGN_POINT1):
|
|
// Position to p1
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p1[i];
|
|
}
|
|
offset[0] += this->ScreenSize * halfTitleWidth + 3;
|
|
break;
|
|
case (VTK_ALIGN_POINT2):
|
|
// Position to p2
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p2[i];
|
|
}
|
|
offset[0] += this->ScreenSize * halfTitleWidth + 3;
|
|
break;
|
|
default:
|
|
// shouldn't get there
|
|
break;
|
|
}
|
|
|
|
if (this->TickVisibility &&
|
|
(this->TickLocation == VTK_TICKS_BOTH
|
|
|| (this->TickLocation == VTK_TICKS_INSIDE &&
|
|
this->TitleAlignLocation == VTK_ALIGN_TOP) ||
|
|
(this->TickLocation == VTK_TICKS_OUTSIDE &&
|
|
this->TitleAlignLocation != VTK_ALIGN_TOP)))
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] += vertOffsetSign * this->TickVector[i];
|
|
}
|
|
}
|
|
|
|
offset[1] *= vertOffsetSign;
|
|
this->TitleActor->SetScreenOffsetVector(offset);
|
|
this->TitleProp3D->SetScreenOffsetVector(offset);
|
|
|
|
if (this->UseTextActor3D)
|
|
{
|
|
int titleActor3DBounds[4];
|
|
this->TitleActor3D->GetBoundingBox(titleActor3DBounds);
|
|
const double titleActor3DWidth =
|
|
static_cast<double>(titleActor3DBounds[1] - titleActor3DBounds[0]);
|
|
|
|
// Convert from font coordinate system to world coordinate system:
|
|
this->TitleActor3D->SetScale(
|
|
(titleBounds[1] - titleBounds[0]) / titleActor3DWidth);
|
|
}
|
|
this->TitleActor->SetPosition(pos);
|
|
this->TitleProp3D->SetPosition(pos);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildExponent(bool force)
|
|
{
|
|
if (!force && (!this->ExponentVisibility || !this->Exponent))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!force && this->ExponentTextTime.GetMTime() < this->BuildTime.GetMTime() &&
|
|
this->BoundsTime.GetMTime() < this->BuildTime.GetMTime() &&
|
|
this->LabelBuildTime.GetMTime() < this->BuildTime.GetMTime())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Text property
|
|
this->ExponentActor->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->ExponentActor->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
|
|
// ---------- labels size ----------
|
|
// local orientation (in the plane of the label)
|
|
double labelAngle = vtkMath::RadiansFromDegrees(this->LabelTextProperty->GetOrientation());
|
|
double labelCos = fabs(cos(labelAngle)), labelSin = fabs(sin(labelAngle));
|
|
double labBounds[6];
|
|
double offset[2] = { 0, this->ExponentOffset};
|
|
|
|
// find max height label (with the label text property considered)
|
|
// only when title is on bottom
|
|
if (this->LabelVisibility &&
|
|
this->ExponentLocation != VTK_ALIGN_TOP)
|
|
{
|
|
double labelMaxHeight, labHeight;
|
|
labelMaxHeight = labHeight = 0;
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelActors[i]->GetMapper()->GetBounds(labBounds);
|
|
|
|
// labels actor aren't oriented yet, width and height are considered in
|
|
// their local coordinate system
|
|
// however, LabelTextProperty can orient it, but locally (in its plane)
|
|
labHeight =
|
|
(labBounds[1] - labBounds[0]) * labelSin +
|
|
(labBounds[3] - labBounds[2]) * labelCos;
|
|
labelMaxHeight = (labHeight > labelMaxHeight ? labHeight : labelMaxHeight);
|
|
}
|
|
offset[1] += this->LabelOffset + this->ScreenSize * labelMaxHeight;
|
|
}
|
|
|
|
// ---------- title size ----------
|
|
double titleBounds[6];
|
|
this->TitleActor->GetMapper()->GetBounds(titleBounds);
|
|
if (this->TitleVisibility &&
|
|
this->TitleAlignLocation == this->ExponentLocation)
|
|
{
|
|
offset[1] += this->TitleOffset + this->ScreenSize * titleBounds[3] - titleBounds[2];
|
|
}
|
|
|
|
// ---------- exponent size ----------
|
|
double exponentBounds[6];
|
|
this->ExponentActor->GetMapper()->GetBounds(exponentBounds);
|
|
double halfExponentHeight = (exponentBounds[3] - exponentBounds[2]) * 0.5;
|
|
double halfExponentWidth = (exponentBounds[1] - exponentBounds[0]) * 0.5;
|
|
offset[1] += this->ScreenSize * halfExponentHeight;
|
|
|
|
double *p1 = this->Point1Coordinate->GetValue();
|
|
double *p2 = this->Point2Coordinate->GetValue();
|
|
double pos[3];
|
|
|
|
int offsetSign = 1;
|
|
switch (this->ExponentLocation)
|
|
{
|
|
case (VTK_ALIGN_TOP):
|
|
offsetSign = -1;
|
|
VTK_FALLTHROUGH;
|
|
// NO BREAK
|
|
case (VTK_ALIGN_BOTTOM):
|
|
// Position to center of axis
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p1[i] + (p2[i] - p1[i]) / 2.0;
|
|
}
|
|
break;
|
|
case (VTK_ALIGN_POINT1):
|
|
// Position to p1
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p1[i];
|
|
}
|
|
offset[0] += this->ScreenSize * halfExponentWidth + 3;
|
|
break;
|
|
case (VTK_ALIGN_POINT2):
|
|
// Position to p2
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] = p2[i];
|
|
}
|
|
offset[0] += this->ScreenSize * halfExponentWidth + 3;
|
|
break;
|
|
default:
|
|
// shouldn't get there
|
|
break;
|
|
}
|
|
|
|
if (this->TickVisibility &&
|
|
(this->TickLocation == VTK_TICKS_BOTH
|
|
|| (this->TickLocation == VTK_TICKS_INSIDE &&
|
|
this->ExponentLocation == VTK_ALIGN_TOP) ||
|
|
(this->TickLocation == VTK_TICKS_OUTSIDE &&
|
|
this->ExponentLocation != VTK_ALIGN_TOP)))
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
pos[i] += offsetSign * this->TickVector[i];
|
|
}
|
|
}
|
|
|
|
// Offset is: ExponentOffset + TitleOffset is visible + LabelOffset if visible
|
|
// + ScreenSize of all
|
|
offset[1] *= offsetSign;
|
|
this->ExponentActor->SetScreenOffsetVector(offset);
|
|
this->ExponentProp3D->SetScreenOffsetVector(offset);
|
|
|
|
if (this->UseTextActor3D)
|
|
{
|
|
int exponentActor3DBounds[4];
|
|
this->ExponentActor3D->GetBoundingBox(exponentActor3DBounds);
|
|
const double exponentActor3DWidth =
|
|
static_cast<double>(exponentActor3DBounds[1] - exponentActor3DBounds[0]);
|
|
|
|
// Convert from font coordinate system to world coordinate system:
|
|
this->ExponentActor3D->SetScale(
|
|
(exponentBounds[1] - exponentBounds[0]) / exponentActor3DWidth);
|
|
}
|
|
|
|
this->ExponentActor->SetPosition(pos);
|
|
this->ExponentProp3D->SetPosition(pos);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Determines scale and position for the 2D Title. Currently,
|
|
// title can only be centered with respect to its axis.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildTitle2D(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!this->NeedBuild2D && !force && !this->TitleVisibility)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// for textactor instead of follower
|
|
this->TitleActor2D->SetInput(this->TitleVector->GetText());
|
|
this->TitleActor2D->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->TitleActor2D->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
this->TitleActor2D->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
|
|
|
|
if (this->AxisType == VTK_AXIS_TYPE_Y)
|
|
{
|
|
if (strlen(this->TitleActor2D->GetInput()) > 2)
|
|
{
|
|
// warning : orientation have to be set on vtkTextActor and not on the vtkTextActor's vtkTextProperty
|
|
// otherwise there is a strange effect (first letter is not align with the others)
|
|
this->TitleActor2D->SetOrientation(90);
|
|
}
|
|
else
|
|
{
|
|
// if in the previous rendering, the orientation was set.
|
|
this->TitleActor2D->SetOrientation(0);
|
|
}
|
|
}
|
|
|
|
// stuff for 2D axis with TextActor
|
|
double transpos[3];
|
|
double* pos = this->TitleActor->GetPosition();
|
|
viewport->SetWorldPoint(pos[0], pos[1], pos[2], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transpos);
|
|
|
|
int offsetSign = 1;
|
|
if (this->TitleAlignLocation == VTK_ALIGN_TOP)
|
|
{
|
|
offsetSign = -1;
|
|
}
|
|
|
|
if (this->AxisType == VTK_AXIS_TYPE_X)
|
|
{
|
|
transpos[1] += offsetSign * this->VerticalOffsetXTitle2D;
|
|
}
|
|
else if (this->AxisType == VTK_AXIS_TYPE_Y)
|
|
{
|
|
transpos[0] += offsetSign * this->HorizontalOffsetYTitle2D;
|
|
}
|
|
if (transpos[1] < 10.)
|
|
{
|
|
transpos[1] = 10.;
|
|
}
|
|
if (transpos[0] < 10.)
|
|
{
|
|
transpos[0] = 10.;
|
|
}
|
|
|
|
if (this->SaveTitlePosition == 0)
|
|
{
|
|
this->TitleActor2D->SetPosition(transpos[0], transpos[1]);
|
|
}
|
|
else
|
|
{
|
|
if (this->SaveTitlePosition == 1)
|
|
{
|
|
this->TitleConstantPosition[0] = transpos[0];
|
|
this->TitleConstantPosition[1] = transpos[1];
|
|
this->SaveTitlePosition = 2;
|
|
}
|
|
this->TitleActor2D->SetPosition(this->TitleConstantPosition[0], this->TitleConstantPosition[1]);
|
|
}
|
|
this->RotateActor2DFromAxisProjection(this->TitleActor2D);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildExponent2D(vtkViewport *viewport, bool force)
|
|
{
|
|
if (!this->NeedBuild2D && !force && !this->LabelVisibility)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// for textactor instead of follower
|
|
this->ExponentActor2D->SetInput(this->ExponentVector->GetText());
|
|
this->ExponentActor2D->GetProperty()->SetColor(this->TitleTextProperty->GetColor());
|
|
this->ExponentActor2D->GetProperty()->SetOpacity(this->TitleTextProperty->GetOpacity());
|
|
this->ExponentActor2D->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
|
|
|
|
if (this->AxisType == VTK_AXIS_TYPE_Y)
|
|
{
|
|
if (strlen(this->ExponentActor2D->GetInput()) > 2)
|
|
{
|
|
// warning : orientation have to be set on vtkTextActor and not on the vtkTextActor's vtkTextProperty
|
|
// otherwise there is a strange effect (first letter is not align with the others)
|
|
this->ExponentActor2D->SetOrientation(90);
|
|
}
|
|
else
|
|
{
|
|
// if in the previous rendering, the orientation was set.
|
|
this->ExponentActor2D->SetOrientation(0);
|
|
}
|
|
}
|
|
|
|
// stuff for 2D axis with TextActor
|
|
double transpos[3];
|
|
double* pos = this->ExponentActor->GetPosition();
|
|
viewport->SetWorldPoint(pos[0], pos[1], pos[2], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transpos);
|
|
|
|
int offsetSign = 1;
|
|
if (this->ExponentLocation == VTK_ALIGN_TOP)
|
|
{
|
|
offsetSign = -1;
|
|
}
|
|
|
|
int titleMult = 1;
|
|
if (this->TitleVisibility &&
|
|
this->TitleAlignLocation == this->ExponentLocation)
|
|
{
|
|
titleMult = 2;
|
|
}
|
|
|
|
if (this->AxisType == VTK_AXIS_TYPE_X)
|
|
{
|
|
transpos[1] += offsetSign * titleMult * this->VerticalOffsetXTitle2D;
|
|
}
|
|
else if (this->AxisType == VTK_AXIS_TYPE_Y)
|
|
{
|
|
transpos[0] += offsetSign * titleMult * this->HorizontalOffsetYTitle2D;
|
|
}
|
|
if (transpos[1] < 10.)
|
|
{
|
|
transpos[1] = 10.;
|
|
}
|
|
if (transpos[0] < 10.)
|
|
{
|
|
transpos[0] = 10.;
|
|
}
|
|
|
|
this->ExponentActor2D->SetPosition(transpos[0], transpos[1]);
|
|
|
|
this->RotateActor2DFromAxisProjection(this->ExponentActor2D);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Transform the bounding box to display coordinates. Used
|
|
// in determining orientation of the axis.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::TransformBounds(vtkViewport *viewport, double bnds[6])
|
|
{
|
|
double minPt[3], maxPt[3], transMinPt[3], transMaxPt[3];
|
|
minPt[0] = this->Bounds[0];
|
|
minPt[1] = this->Bounds[2];
|
|
minPt[2] = this->Bounds[4];
|
|
maxPt[0] = this->Bounds[1];
|
|
maxPt[1] = this->Bounds[3];
|
|
maxPt[2] = this->Bounds[5];
|
|
|
|
viewport->SetWorldPoint(minPt[0], minPt[1], minPt[2], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transMinPt);
|
|
viewport->SetWorldPoint(maxPt[0], maxPt[1], maxPt[2], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transMaxPt);
|
|
|
|
bnds[0] = transMinPt[0];
|
|
bnds[2] = transMinPt[1];
|
|
bnds[4] = transMinPt[2];
|
|
bnds[1] = transMaxPt[0];
|
|
bnds[3] = transMaxPt[1];
|
|
bnds[5] = transMaxPt[2];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
|
|
os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
|
|
os << indent << "Number Of Labels Built: "
|
|
<< this->NumberOfLabelsBuilt << "\n";
|
|
os << indent << "Range: ("
|
|
<< this->Range[0] << ", "
|
|
<< this->Range[1] << ")\n";
|
|
|
|
os << indent << "UseTextActor3D: " << this->UseTextActor3D << "\n";
|
|
os << indent << "Label Format: " << this->LabelFormat << "\n";
|
|
|
|
os << indent << "Axis Visibility: "
|
|
<< (this->AxisVisibility ? "On\n" : "Off\n");
|
|
|
|
os << indent << "Tick Visibility: "
|
|
<< (this->TickVisibility ? "On\n" : "Off\n");
|
|
|
|
os << indent << "Label Visibility: "
|
|
<< (this->LabelVisibility ? "On\n" : "Off\n");
|
|
|
|
os << indent << "Title Visibility: "
|
|
<< (this->TitleVisibility ? "On\n" : "Off\n");
|
|
|
|
os << indent << "Point1 Coordinate: " << this->Point1Coordinate << "\n";
|
|
this->Point1Coordinate->PrintSelf(os, indent.GetNextIndent());
|
|
|
|
os << indent << "Point2 Coordinate: " << this->Point2Coordinate << "\n";
|
|
this->Point2Coordinate->PrintSelf(os, indent.GetNextIndent());
|
|
|
|
os << indent << "AxisType: ";
|
|
switch (this->AxisType)
|
|
{
|
|
case VTK_AXIS_TYPE_X:
|
|
os << "X Axis" << endl;
|
|
break;
|
|
case VTK_AXIS_TYPE_Y:
|
|
os << "Y Axis" << endl;
|
|
break;
|
|
case VTK_AXIS_TYPE_Z:
|
|
os << "Z Axis" << endl;
|
|
break;
|
|
default:
|
|
// shouldn't get here
|
|
break;
|
|
}
|
|
|
|
os << indent << "DeltaMajor: "
|
|
<< this->DeltaMajor[0] << ","
|
|
<< this->DeltaMajor[1] << ","
|
|
<< this->DeltaMajor[2] << endl;
|
|
os << indent << "DeltaMinor: " << this->DeltaMinor << endl;
|
|
os << indent << "DeltaRangeMajor: " << this->DeltaRangeMajor << endl;
|
|
os << indent << "DeltaRangeMinor: " << this->DeltaRangeMinor << endl;
|
|
os << indent << "MajorRangeStart: " << this->MajorRangeStart << endl;
|
|
os << indent << "MinorRangeStart: " << this->MinorRangeStart << endl;
|
|
|
|
os << indent << "MinorTicksVisible: " << this->MinorTicksVisible << endl;
|
|
|
|
os << indent << "TitleActor: ";
|
|
if (this->TitleActor)
|
|
{
|
|
os << indent << "TitleActor: (" << this->TitleActor << ")\n";
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
|
|
os << indent << "Camera: ";
|
|
if (this->Camera)
|
|
{
|
|
this->Camera->PrintSelf(os, indent);
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
|
|
os << indent << "MajorTickSize: " << this->MajorTickSize << endl;
|
|
os << indent << "MinorTickSize: " << this->MinorTickSize << endl;
|
|
|
|
os << indent << "DrawGridlines: " << this->DrawGridlines << endl;
|
|
|
|
os << indent << "MajorStart: "
|
|
<< this->MajorStart[0] << ","
|
|
<< this->MajorStart[1] << ","
|
|
<< this->MajorStart[2] << endl;
|
|
|
|
os << indent << "AxisPosition: " << this->AxisPosition << endl;
|
|
|
|
os << indent << "GridlineXLength: " << this->GridlineXLength << endl;
|
|
os << indent << "GridlineYLength: " << this->GridlineYLength << endl;
|
|
os << indent << "GridlineZLength: " << this->GridlineZLength << endl;
|
|
|
|
os << indent << "DrawInnerGridpolys: " << this->DrawGridpolys << endl;
|
|
os << indent << "DrawInnerGridlines: " << this->DrawInnerGridlines << endl;
|
|
|
|
os << indent << "TickLocation: " << this->TickLocation << endl;
|
|
|
|
os << indent << "CalculateLabelOffset: " << this->CalculateLabelOffset << std::endl;
|
|
os << indent << "CalculateTitleOffset: " << this->CalculateTitleOffset << std::endl;
|
|
|
|
os << indent << "LabelTextProperty: " << this->LabelTextProperty << endl;
|
|
os << indent << "TitleTextProperty: " << this->TitleTextProperty << endl;
|
|
|
|
os << indent << "Use2DMode: " << this->Use2DMode << endl;
|
|
os << indent << "SaveTitlePosition: " << this->SaveTitlePosition << endl;
|
|
os << indent << "VerticalOffsetXTitle2D" << this->VerticalOffsetXTitle2D << endl;
|
|
os << indent << "HorizontalOffsetYTitle2D" << this->HorizontalOffsetYTitle2D << endl;
|
|
os << indent << "LastMinDisplayCoordinates: ("
|
|
<< this->LastMinDisplayCoordinate[0] << ", "
|
|
<< this->LastMinDisplayCoordinate[1] << ", "
|
|
<< this->LastMinDisplayCoordinate[2] << ")" << endl;
|
|
os << indent << "LastMaxDisplayCoordinates: ("
|
|
<< this->LastMaxDisplayCoordinate[0] << ", "
|
|
<< this->LastMaxDisplayCoordinate[1] << ", "
|
|
<< this->LastMaxDisplayCoordinate[2] << ")" << endl;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Sets text string for label vectors. Allocates memory if necessary.
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetLabels(vtkStringArray *labels)
|
|
{
|
|
//
|
|
// If the number of labels has changed, re-allocate the correct
|
|
// amount of memory.
|
|
//
|
|
int numLabels = labels->GetNumberOfValues();
|
|
if (numLabels < 0)
|
|
{
|
|
vtkErrorMacro(<< "Number of labels " << numLabels << " is invalid");
|
|
return;
|
|
}
|
|
if (this->NumberOfLabelsBuilt != numLabels)
|
|
{
|
|
if (this->LabelMappers != NULL)
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->LabelVectors[i]->Delete();
|
|
this->LabelMappers[i]->Delete();
|
|
this->LabelActors[i]->Delete();
|
|
this->LabelProps3D[i]->Delete();
|
|
this->LabelActors3D[i]->Delete();
|
|
this->LabelActors2D[i]->Delete();
|
|
}
|
|
delete [] this->LabelVectors;
|
|
delete [] this->LabelMappers;
|
|
delete [] this->LabelActors;
|
|
delete [] this->LabelProps3D;
|
|
delete [] this->LabelActors3D;
|
|
delete [] this->LabelActors2D;
|
|
}
|
|
|
|
this->LabelVectors = new vtkVectorText * [numLabels];
|
|
this->LabelMappers = new vtkPolyDataMapper * [numLabels];
|
|
this->LabelActors = new vtkAxisFollower * [numLabels];
|
|
this->LabelProps3D = new vtkProp3DAxisFollower * [numLabels];
|
|
this->LabelActors3D = new vtkTextActor3D * [numLabels];
|
|
this->LabelActors2D = new vtkTextActor * [numLabels];
|
|
|
|
for (int i = 0; i < numLabels; i++)
|
|
{
|
|
this->LabelVectors[i] = vtkVectorText::New();
|
|
this->LabelMappers[i] = vtkPolyDataMapper::New();
|
|
this->LabelMappers[i]->SetInputConnection(
|
|
this->LabelVectors[i]->GetOutputPort());
|
|
this->LabelActors[i] = vtkAxisFollower::New();
|
|
this->LabelActors[i]->SetAxis(this);
|
|
this->LabelActors[i]->SetMapper(this->LabelMappers[i]);
|
|
this->LabelActors[i]->SetEnableDistanceLOD(0);
|
|
this->LabelActors[i]->GetProperty()->SetAmbient(1.);
|
|
this->LabelActors[i]->GetProperty()->SetDiffuse(0.);
|
|
this->LabelActors[i]->GetProperty()->SetColor(this->LabelTextProperty->GetColor());
|
|
this->LabelActors[i]->GetProperty()->SetOpacity(this->LabelTextProperty->GetOpacity());
|
|
this->LabelProps3D[i] = vtkProp3DAxisFollower::New();
|
|
this->LabelProps3D[i]->SetAxis(this);
|
|
this->LabelProps3D[i]->SetEnableDistanceLOD(0);
|
|
this->LabelActors3D[i] = vtkTextActor3D::New();
|
|
this->LabelProps3D[i]->SetProp3D(this->LabelActors3D[i]);
|
|
this->LabelActors2D[i] = vtkTextActor::New();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the label vector text.
|
|
//
|
|
for (int i = 0; i < numLabels; i++)
|
|
{
|
|
this->LabelVectors[i]->SetText(labels->GetValue(i).c_str());
|
|
this->LabelActors3D[i]->SetInput(this->LabelVectors[i]->GetText());
|
|
this->LabelActors2D[i]->SetInput(this->LabelVectors[i]->GetText());
|
|
}
|
|
this->NumberOfLabelsBuilt = numLabels;
|
|
this->LabelBuildTime.Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
// Creates Poly data (lines) from tickmarks (minor/major), gridlines, and axis.
|
|
//-----------------------------------------------------------------------------*
|
|
void vtkAxisActor::SetAxisPointsAndLines()
|
|
{
|
|
vtkPoints *mainLinePts = vtkPoints::New();
|
|
vtkPoints *axisMajorTicksPts = vtkPoints::New();
|
|
vtkPoints *axisMinorTicksPts = vtkPoints::New();
|
|
|
|
vtkCellArray *mainLine = vtkCellArray::New();
|
|
vtkCellArray *axisMajorTicksLines = vtkCellArray::New();
|
|
vtkCellArray *axisMinorTicksLines = vtkCellArray::New();
|
|
|
|
vtkCellArray *gridlines = vtkCellArray::New();
|
|
vtkCellArray *innerGridlines = vtkCellArray::New();
|
|
vtkCellArray *polys = vtkCellArray::New();
|
|
|
|
this->AxisLines->SetPoints(mainLinePts);
|
|
this->AxisLines->SetLines(mainLine);
|
|
|
|
this->AxisMajorTicks->SetPoints(axisMajorTicksPts);
|
|
this->AxisMajorTicks->SetLines(axisMajorTicksLines);
|
|
|
|
this->AxisMinorTicks->SetPoints(axisMinorTicksPts);
|
|
this->AxisMinorTicks->SetLines(axisMinorTicksLines);
|
|
|
|
this->Gridlines->SetPoints(this->GridlinePts);
|
|
this->Gridlines->SetLines(gridlines);
|
|
this->InnerGridlines->SetPoints(this->InnerGridlinePts);
|
|
this->InnerGridlines->SetLines(innerGridlines);
|
|
this->Gridpolys->SetPoints(this->GridpolyPts);
|
|
this->Gridpolys->SetPolys(polys);
|
|
|
|
mainLinePts->Delete();
|
|
axisMajorTicksPts->Delete();
|
|
axisMinorTicksPts->Delete();
|
|
|
|
mainLine->Delete();
|
|
axisMajorTicksLines->Delete();
|
|
axisMinorTicksLines->Delete();
|
|
|
|
gridlines->Delete();
|
|
innerGridlines->Delete();
|
|
polys->Delete();
|
|
int numMinorTickPts, numGridlines, numInnerGridlines, numMajorTickPts, numGridpolys, numLines;
|
|
vtkIdType ptIds[2];
|
|
vtkIdType polyPtIds[4];
|
|
|
|
if (this->TickVisibility)
|
|
{
|
|
if (this->MinorTicksVisible)
|
|
{
|
|
// In 2D mode, the minorTickPts for yz portion or xz portion have been removed.
|
|
numMinorTickPts = this->MinorTickPts->GetNumberOfPoints();
|
|
for (int i = 0; i < numMinorTickPts; i++)
|
|
{
|
|
axisMinorTicksPts->InsertNextPoint(this->MinorTickPts->GetPoint(i));
|
|
}
|
|
}
|
|
numMajorTickPts = this->MajorTickPts->GetNumberOfPoints();
|
|
if (this->Use2DMode == 0)
|
|
{
|
|
for (int i = 0; i < numMajorTickPts; i++)
|
|
{
|
|
axisMajorTicksPts->InsertNextPoint(this->MajorTickPts->GetPoint(i));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// In 2D mode, we don't need the pts for the xz portion or yz portion of the major tickmarks
|
|
// majorTickPts not modified because all points are used for labels' positions.
|
|
for (int i = 0; i < numMajorTickPts; i += 4)
|
|
{
|
|
axisMajorTicksPts->InsertNextPoint(this->MajorTickPts->GetPoint(i));
|
|
axisMajorTicksPts->InsertNextPoint(this->MajorTickPts->GetPoint(i + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
// create major ticks lines
|
|
numLines = axisMajorTicksPts->GetNumberOfPoints() / 2;
|
|
for (int i = 0; i < numLines; i++)
|
|
{
|
|
ptIds[0] = 2*i;
|
|
ptIds[1] = 2*i + 1;
|
|
axisMajorTicksLines->InsertNextCell(2, ptIds);
|
|
}
|
|
|
|
// create major ticks lines
|
|
numLines = axisMinorTicksPts->GetNumberOfPoints() / 2;
|
|
for (int i = 0; i < numLines; i++)
|
|
{
|
|
ptIds[0] = 2*i;
|
|
ptIds[1] = 2*i + 1;
|
|
axisMinorTicksLines->InsertNextCell(2, ptIds);
|
|
}
|
|
|
|
if (this->AxisVisibility)
|
|
{
|
|
//first axis point
|
|
ptIds[0] = mainLinePts->InsertNextPoint(this->Point1Coordinate->GetValue());
|
|
//last axis point
|
|
ptIds[1] = mainLinePts->InsertNextPoint(this->Point2Coordinate->GetValue());
|
|
mainLine->InsertNextCell(2, ptIds);
|
|
}
|
|
// create grid lines
|
|
if (this->DrawGridlines && this->AxisOnOrigin == 0)
|
|
{
|
|
numGridlines = this->GridlinePts->GetNumberOfPoints() / 2;
|
|
int start =
|
|
(this->DrawGridlinesLocation == 0 || this->DrawGridlinesLocation == 1)
|
|
? 0 : 1;
|
|
int increment = (this->DrawGridlinesLocation == 0) ? 1 : 2;
|
|
for (int i = start; i < numGridlines; i += increment)
|
|
{
|
|
ptIds[0] = 2*i;
|
|
ptIds[1] = 2*i + 1;
|
|
gridlines->InsertNextCell(2, ptIds);
|
|
}
|
|
}
|
|
|
|
// create inner grid lines
|
|
if (this->DrawInnerGridlines && this->AxisOnOrigin == 0)
|
|
{
|
|
numInnerGridlines = this->InnerGridlinePts->GetNumberOfPoints() / 2;
|
|
for (int i = 0; i < numInnerGridlines; i++)
|
|
{
|
|
ptIds[0] = 2*i;
|
|
ptIds[1] = 2*i + 1;
|
|
innerGridlines->InsertNextCell(2, ptIds);
|
|
}
|
|
}
|
|
|
|
// create polys (grid polys)
|
|
if (this->DrawGridpolys && this->AxisOnOrigin == 0)
|
|
{
|
|
numGridpolys = this->GridpolyPts->GetNumberOfPoints() / 4;
|
|
for (int i = 0; i < numGridpolys; i++)
|
|
{
|
|
polyPtIds[0] = 4*i;
|
|
polyPtIds[1] = 4*i + 1;
|
|
polyPtIds[2] = 4*i + 2;
|
|
polyPtIds[3] = 4*i + 3;
|
|
polys->InsertNextCell(4, polyPtIds);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Returns true if any tick vis attribute has changed since last check.
|
|
//-----------------------------------------------------------------------------**
|
|
bool vtkAxisActor::TickVisibilityChanged()
|
|
{
|
|
bool retVal = (this->TickVisibility != this->LastTickVisibility) ||
|
|
(this->DrawGridlines != this->LastDrawGridlines) ||
|
|
(this->MinorTicksVisible != this->LastMinorTicksVisible);
|
|
|
|
this->LastTickVisibility = this->TickVisibility;
|
|
this->LastDrawGridlines = this->DrawGridlines;
|
|
this->LastMinorTicksVisible = this->MinorTicksVisible;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Set the bounds for this actor to use. Sets timestamp BoundsModified.
|
|
//-----------------------------------------------------------------------------**
|
|
void
|
|
vtkAxisActor::SetBounds(const double b[6])
|
|
{
|
|
if ((this->Bounds[0] != b[0]) ||
|
|
(this->Bounds[1] != b[1]) ||
|
|
(this->Bounds[2] != b[2]) ||
|
|
(this->Bounds[3] != b[3]) ||
|
|
(this->Bounds[4] != b[4]) ||
|
|
(this->Bounds[5] != b[5]))
|
|
{
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
this->Bounds[i] = b[i];
|
|
}
|
|
this->BoundsTime.Modified();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Retrieves the bounds of this actor.
|
|
//-----------------------------------------------------------------------------**
|
|
void vtkAxisActor::
|
|
SetBounds(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
|
|
{
|
|
if ((this->Bounds[0] != xmin) ||
|
|
(this->Bounds[1] != xmax) ||
|
|
(this->Bounds[2] != ymin) ||
|
|
(this->Bounds[3] != ymax) ||
|
|
(this->Bounds[4] != zmin) ||
|
|
(this->Bounds[5] != zmax))
|
|
{
|
|
this->Bounds[0] = xmin;
|
|
this->Bounds[1] = xmax;
|
|
this->Bounds[2] = ymin;
|
|
this->Bounds[3] = ymax;
|
|
this->Bounds[4] = zmin;
|
|
this->Bounds[5] = zmax;
|
|
|
|
this->BoundsTime.Modified();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Retrieves the bounds of this actor.
|
|
//-----------------------------------------------------------------------------**
|
|
double* vtkAxisActor::GetBounds()
|
|
{
|
|
return this->Bounds;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Retrieves the bounds of this actor.
|
|
//-----------------------------------------------------------------------------**
|
|
|
|
void vtkAxisActor::GetBounds(double b[6])
|
|
{
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
b[i] = this->Bounds[i];
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Method: vtkAxisActor::ComputeMaxLabelLength
|
|
//-----------------------------------------------------------------------------**
|
|
double vtkAxisActor::ComputeMaxLabelLength(const double vtkNotUsed(center)[3])
|
|
{
|
|
double bounds[6];
|
|
double xsize, ysize;
|
|
vtkProperty *newProp = this->NewLabelProperty();
|
|
double maxXSize = 0;
|
|
double maxYSize = 0;
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
if (this->UseTextActor3D)
|
|
{
|
|
this->LabelProps3D[i]->SetCamera(this->Camera);
|
|
this->LabelActors3D[i]->GetBounds(bounds);
|
|
}
|
|
else
|
|
{
|
|
this->LabelActors[i]->SetCamera(this->Camera);
|
|
this->LabelActors[i]->SetProperty(newProp);
|
|
this->LabelActors[i]->GetMapper()->GetBounds(bounds);
|
|
}
|
|
xsize = bounds[1] - bounds[0];
|
|
ysize = bounds[3] - bounds[2];
|
|
maxXSize = (xsize > maxXSize ? xsize : maxXSize);
|
|
maxYSize = (ysize > maxYSize ? ysize : maxYSize);
|
|
}
|
|
newProp->Delete();
|
|
return sqrt(maxXSize*maxXSize + maxYSize*maxYSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
// Method: vtkAxisActor::ComputeTitleLength
|
|
//-----------------------------------------------------------------------------**
|
|
double vtkAxisActor::ComputeTitleLength(const double vtkNotUsed(center)[3])
|
|
{
|
|
double bounds[6];
|
|
double xsize, ysize;
|
|
double length;
|
|
|
|
if (this->UseTextActor3D)
|
|
{
|
|
this->TitleActor3D->SetInput(this->Title);
|
|
this->TitleProp3D->SetCamera(this->Camera);
|
|
this->TitleActor3D->GetBounds(bounds);
|
|
}
|
|
else
|
|
{
|
|
this->TitleVector->SetText(this->Title);
|
|
this->TitleActor->SetCamera(this->Camera);
|
|
vtkProperty * newProp = this->NewTitleProperty();
|
|
this->TitleActor->SetProperty(newProp);
|
|
newProp->Delete();
|
|
this->TitleActor->GetMapper()->GetBounds(bounds);
|
|
}
|
|
xsize = bounds[1] - bounds[0];
|
|
ysize = bounds[3] - bounds[2];
|
|
length = sqrt(xsize*xsize + ysize*ysize);
|
|
|
|
return length;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
void vtkAxisActor::SetLabelScale(const double s)
|
|
{
|
|
for (int i = 0; i < this->NumberOfLabelsBuilt; i++)
|
|
{
|
|
this->SetLabelScale(i, s);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
void vtkAxisActor::SetLabelScale(int label, const double s)
|
|
{
|
|
this->LabelActors[label]->SetScale(s);
|
|
this->LabelProps3D[label]->SetScale(s);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
void vtkAxisActor::SetTitleScale(const double s)
|
|
{
|
|
this->TitleActor->SetScale(s);
|
|
this->TitleProp3D->SetScale(s);
|
|
this->ExponentActor->SetScale(s);
|
|
this->ExponentProp3D->SetScale(s);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------**
|
|
void vtkAxisActor::SetTitle(const char *t)
|
|
{
|
|
if (this->Title == NULL && t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if (this->Title && t && (!strcmp(this->Title, t)))
|
|
{
|
|
return;
|
|
}
|
|
delete [] this->Title;
|
|
if (t)
|
|
{
|
|
this->Title = new char[strlen(t) + 1];
|
|
strcpy(this->Title, t);
|
|
}
|
|
else
|
|
{
|
|
this->Title = NULL;
|
|
}
|
|
this->TitleTextTime.Modified();
|
|
this->Modified();
|
|
}
|
|
|
|
void vtkAxisActor::SetExponent(const char *t)
|
|
{
|
|
if (this->Exponent == NULL && t == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if (this->Exponent && t && (!strcmp(this->Exponent, t)))
|
|
{
|
|
return;
|
|
}
|
|
delete [] this->Exponent;
|
|
if (t)
|
|
{
|
|
this->Exponent = new char[strlen(t) + 1];
|
|
strcpy(this->Exponent, t);
|
|
}
|
|
else
|
|
{
|
|
this->Exponent = NULL;
|
|
}
|
|
this->ExponentTextTime.Modified();
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetAxisLinesProperty(vtkProperty *prop)
|
|
{
|
|
this->SetAxisMainLineProperty(prop);
|
|
this->SetAxisMajorTicksProperty(prop);
|
|
this->SetAxisMinorTicksProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetAxisLinesProperty()
|
|
{
|
|
return this->AxisLinesActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetAxisMainLineProperty(vtkProperty *prop)
|
|
{
|
|
this->AxisLinesActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
vtkProperty* vtkAxisActor::GetAxisMainLineProperty()
|
|
{
|
|
return this->GetAxisLinesProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetAxisMajorTicksProperty(vtkProperty *prop)
|
|
{
|
|
this->AxisMajorTicksActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetAxisMajorTicksProperty()
|
|
{
|
|
return this->AxisMajorTicksActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetAxisMinorTicksProperty(vtkProperty *prop)
|
|
{
|
|
this->AxisMinorTicksActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetAxisMinorTicksProperty()
|
|
{
|
|
return this->AxisMinorTicksActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetGridlinesProperty(vtkProperty *prop)
|
|
{
|
|
this->GridlinesActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetGridlinesProperty()
|
|
{
|
|
return this->GridlinesActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetInnerGridlinesProperty(vtkProperty *prop)
|
|
{
|
|
this->InnerGridlinesActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetInnerGridlinesProperty()
|
|
{
|
|
return this->InnerGridlinesActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetGridpolysProperty(vtkProperty *prop)
|
|
{
|
|
this->GridpolysActor->SetProperty(prop);
|
|
this->Modified();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::GetGridpolysProperty()
|
|
{
|
|
return this->GridpolysActor->GetProperty();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::NewTitleProperty()
|
|
{
|
|
vtkProperty *newProp = vtkProperty::New();
|
|
newProp->DeepCopy(this->GetProperty());
|
|
newProp->SetColor(this->TitleTextProperty->GetColor());
|
|
return newProp;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkProperty* vtkAxisActor::NewLabelProperty()
|
|
{
|
|
vtkProperty *newProp = vtkProperty::New();
|
|
newProp->DeepCopy(this->GetProperty());
|
|
newProp->SetColor(this->LabelTextProperty->GetColor());
|
|
return newProp;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
double vtkAxisActor::GetDeltaMajor(int axis)
|
|
{
|
|
return (axis >= 0 && axis <= 2) ? this->DeltaMajor[axis] : 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetDeltaMajor(int axis, double value)
|
|
{
|
|
if (axis >= 0 && axis <= 2)
|
|
{
|
|
this->DeltaMajor[axis] = value;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
double vtkAxisActor::GetMajorStart(int axis)
|
|
{
|
|
return (axis >= 0 && axis <= 2) ? this->MajorStart[axis] : 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::SetMajorStart(int axis, double value){
|
|
if (axis >= 0 && axis <= 2)
|
|
{
|
|
this->MajorStart[axis] = value;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAxisActor::BoundsDisplayCoordinateChanged(vtkViewport *viewport)
|
|
{
|
|
double transMinPt[3], transMaxPt[3];
|
|
viewport->SetWorldPoint(this->Bounds[0], this->Bounds[2], this->Bounds[4], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transMinPt);
|
|
viewport->SetWorldPoint(this->Bounds[1], this->Bounds[3], this->Bounds[5], 1.0);
|
|
viewport->WorldToDisplay();
|
|
viewport->GetDisplayPoint(transMaxPt);
|
|
|
|
if (this->LastMinDisplayCoordinate[0] != transMinPt[0]
|
|
|| this->LastMinDisplayCoordinate[1] != transMinPt[1]
|
|
|| this->LastMinDisplayCoordinate[2] != transMinPt[2]
|
|
|| this->LastMaxDisplayCoordinate[0] != transMaxPt[0]
|
|
|| this->LastMaxDisplayCoordinate[1] != transMaxPt[1]
|
|
|| this->LastMaxDisplayCoordinate[2] != transMaxPt[2])
|
|
{
|
|
for (int i = 0 ; i<3 ; ++i)
|
|
{
|
|
this->LastMinDisplayCoordinate[i] = transMinPt[i];
|
|
this->LastMaxDisplayCoordinate[i] = transMaxPt[i];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
// endpoint-related methods
|
|
//-----------------------------------------------------------------------------
|
|
vtkCoordinate* vtkAxisActor::GetPoint1Coordinate()
|
|
{
|
|
vtkDebugMacro(<< this->GetClassName() << " (" << this
|
|
<< "): returning Point1 Coordinate address "
|
|
<< this->Point1Coordinate);
|
|
return this->Point1Coordinate;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
vtkCoordinate* vtkAxisActor::GetPoint2Coordinate()
|
|
{
|
|
vtkDebugMacro(<< this->GetClassName() << " (" << this
|
|
<< "): returning Point2 Coordinate address "
|
|
<< this->Point2Coordinate);
|
|
return this->Point2Coordinate;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkAxisActor::SetPoint1(double x, double y, double z)
|
|
{
|
|
this->Point1Coordinate->SetValue(x, y, z);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkAxisActor::SetPoint2(double x, double y, double z)
|
|
{
|
|
this->Point2Coordinate->SetValue(x, y, z);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
double* vtkAxisActor::GetPoint1()
|
|
{
|
|
return this->Point1Coordinate->GetValue();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
double* vtkAxisActor::GetPoint2()
|
|
{
|
|
return this->Point2Coordinate->GetValue();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates points for ticks (minor, major, gridlines) in correct position
|
|
// for a generic axis.
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAxisActor::BuildTickPoints(double p1[3], double p2[3], bool force)
|
|
{
|
|
// Prevent any unwanted computation
|
|
if (!force && (this->AxisPosition == this->LastAxisPosition) &&
|
|
(this->TickLocation == this->LastTickLocation) &&
|
|
(this->BoundsTime.GetMTime() < this->BuildTime.GetMTime()) &&
|
|
(this->Point1Coordinate->GetMTime() < this->BuildTickPointsTime.GetMTime()) &&
|
|
(this->Point2Coordinate->GetMTime() < this->BuildTickPointsTime.GetMTime()) &&
|
|
(this->Range[0] == this->LastRange[0]) &&
|
|
(this->Range[1] == this->LastRange[1]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Reset previous objects
|
|
this->MinorTickPts->Reset();
|
|
this->MajorTickPts->Reset();
|
|
this->GridlinePts->Reset();
|
|
this->InnerGridlinePts->Reset();
|
|
this->GridpolyPts->Reset();
|
|
|
|
// As we assume that the Axis is not necessery alined to the absolute X/Y/Z
|
|
// axis, we will convert the absolut XYZ information to relative one
|
|
// using a base composed as follow (axis, u, v)
|
|
|
|
double coordSystem[3][3]; //axisVector, uVector, vVector
|
|
|
|
switch (this->AxisType)
|
|
{
|
|
case VTK_AXIS_TYPE_X:
|
|
memcpy(&coordSystem[0], this->AxisBaseForX, 3*sizeof(double));
|
|
memcpy(&coordSystem[1], this->AxisBaseForY, 3*sizeof(double));
|
|
memcpy(&coordSystem[2], this->AxisBaseForZ, 3*sizeof(double));
|
|
break;
|
|
|
|
case VTK_AXIS_TYPE_Y:
|
|
memcpy(&coordSystem[0], this->AxisBaseForY, 3*sizeof(double));
|
|
memcpy(&coordSystem[1], this->AxisBaseForX, 3*sizeof(double));
|
|
memcpy(&coordSystem[2], this->AxisBaseForZ, 3*sizeof(double));
|
|
break;
|
|
|
|
case VTK_AXIS_TYPE_Z:
|
|
memcpy(&coordSystem[0], this->AxisBaseForZ, 3*sizeof(double));
|
|
memcpy(&coordSystem[1], this->AxisBaseForX, 3*sizeof(double));
|
|
memcpy(&coordSystem[2], this->AxisBaseForY, 3*sizeof(double));
|
|
break;
|
|
|
|
default:
|
|
// shouldn't get here
|
|
break;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
// Build Minor Ticks
|
|
//-----------------------------------------------------------------------------*
|
|
if (this->Log)
|
|
{
|
|
this->BuildMinorTicksLog(p1, p2, coordSystem);
|
|
}
|
|
else
|
|
{
|
|
this->BuildMinorTicks(p1, p2, coordSystem);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
// Build Gridline + GridPoly points + InnerGrid (Only for Orthonormal base)
|
|
//-----------------------------------------------------------------------------*
|
|
if (!this->Log)
|
|
{
|
|
BuildAxisGridLines(p1, p2, coordSystem);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------*
|
|
// Build Major ticks
|
|
//-----------------------------------------------------------------------------*
|
|
if (this->Log)
|
|
{
|
|
BuildMajorTicksLog(p1, p2, coordSystem);
|
|
}
|
|
else
|
|
{
|
|
BuildMajorTicks(p1, p2, coordSystem);
|
|
}
|
|
|
|
this->BuildTickPointsTime.Modified();
|
|
this->LastTickLocation = this->TickLocation;
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildAxisGridLines(double p1[3], double p2[3], double localCoordSys[3][3])
|
|
{
|
|
int uIndex = 0, vIndex = 0;
|
|
double uGridLength = 0.0, vGridLength = 0.0;
|
|
double gridPointClosest[3], gridPointFarest[3], gridPointU[3], gridPointV[3];
|
|
double innerGridPointClosestU[3], innerGridPointClosestV[3];
|
|
double innerGridPointFarestU[3], innerGridPointFarestV[3];
|
|
double deltaVector[3];
|
|
|
|
int uMult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
int vMult = vtkAxisActorMultiplierTable2[this->AxisPosition];
|
|
|
|
double* axisVector = localCoordSys[0];
|
|
double* uVector = localCoordSys[1];
|
|
double* vVector = localCoordSys[2];
|
|
|
|
switch (this->AxisType)
|
|
{
|
|
case VTK_AXIS_TYPE_X:
|
|
uGridLength = this->GridlineYLength;
|
|
vGridLength = this->GridlineZLength;
|
|
uIndex = 1; vIndex = 2;
|
|
break;
|
|
case VTK_AXIS_TYPE_Y:
|
|
uGridLength = this->GridlineXLength;
|
|
vGridLength = this->GridlineZLength;
|
|
uIndex = 0; vIndex = 2;
|
|
break;
|
|
case VTK_AXIS_TYPE_Z:
|
|
uGridLength = this->GridlineXLength;
|
|
vGridLength = this->GridlineYLength;
|
|
uIndex = 0; vIndex = 1;
|
|
break;
|
|
default:
|
|
// shouldn't get here
|
|
break;
|
|
}
|
|
|
|
bool hasOrthogonalVectorBase =
|
|
this->AxisBaseForX[0] == 1 && this->AxisBaseForX[1] == 0 && this->AxisBaseForX[2] == 0 &&
|
|
this->AxisBaseForY[0] == 0 && this->AxisBaseForY[1] == 1 && this->AxisBaseForY[2] == 0 &&
|
|
this->AxisBaseForZ[0] == 0 && this->AxisBaseForZ[1] == 0 && this->AxisBaseForZ[2] == 1;
|
|
|
|
// - Initialize all points to be on the axis
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
gridPointClosest[i] = gridPointFarest[i] = gridPointU[i] = gridPointV[i] = p1[i];
|
|
deltaVector[i] = (p2[i] - p1[i]);
|
|
}
|
|
|
|
double axisLength = vtkMath::Norm(deltaVector);
|
|
double rangeScale = axisLength / (this->Range[1] - this->Range[0]);
|
|
|
|
// - Reduce the deltaVector to correspond to a major tick step
|
|
vtkMath::Normalize(deltaVector);
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
deltaVector[i] *= this->DeltaMajor[this->AxisType];
|
|
}
|
|
|
|
// - Move base points
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
gridPointU[i] -= uVector[i] * uMult * uGridLength;
|
|
gridPointV[i] -= vVector[i] * vMult * vGridLength;
|
|
gridPointFarest[i] -= uVector[i] * uMult * uGridLength + vVector[i] * vMult * vGridLength;
|
|
}
|
|
|
|
// - Add the initial shift if any
|
|
double axisShift = (this->MajorRangeStart - this->Range[0])*rangeScale;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
gridPointU[i] += axisVector[i] * axisShift;
|
|
gridPointV[i] += axisVector[i] * axisShift;
|
|
gridPointFarest[i] += axisVector[i] * axisShift;
|
|
gridPointClosest[i] += axisVector[i] * axisShift;
|
|
}
|
|
|
|
// - Insert Gridlines points along the axis using the DeltaMajor vector
|
|
double nbIterationAsDouble = (axisLength - axisShift) / vtkMath::Norm(deltaVector);
|
|
int nbIteration = vtkMath::Floor(nbIterationAsDouble + 2*FLT_EPSILON) + 1;
|
|
nbIteration = (nbIteration < VTK_MAX_TICKS) ? nbIteration : VTK_MAX_TICKS;
|
|
for (int nbTicks = 0; nbTicks < nbIteration; nbTicks++)
|
|
{
|
|
// Closest U
|
|
this->GridlinePts->InsertNextPoint(gridPointClosest);
|
|
this->GridlinePts->InsertNextPoint(gridPointU);
|
|
|
|
// Farest U
|
|
this->GridlinePts->InsertNextPoint(gridPointFarest);
|
|
this->GridlinePts->InsertNextPoint(gridPointU);
|
|
|
|
// Closest V
|
|
this->GridlinePts->InsertNextPoint(gridPointClosest);
|
|
this->GridlinePts->InsertNextPoint(gridPointV);
|
|
|
|
// Farest V
|
|
this->GridlinePts->InsertNextPoint(gridPointFarest);
|
|
this->GridlinePts->InsertNextPoint(gridPointV);
|
|
|
|
// PolyPoints
|
|
this->GridpolyPts->InsertNextPoint(gridPointClosest);
|
|
this->GridpolyPts->InsertNextPoint(gridPointU);
|
|
this->GridpolyPts->InsertNextPoint(gridPointFarest);
|
|
this->GridpolyPts->InsertNextPoint(gridPointV);
|
|
|
|
// Move forward along the axis
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
gridPointClosest[i] += deltaVector[i];
|
|
gridPointU[i] += deltaVector[i];
|
|
gridPointFarest[i] += deltaVector[i];
|
|
gridPointV[i] += deltaVector[i];
|
|
}
|
|
}
|
|
|
|
// - Insert InnerGridLines points
|
|
|
|
// We can only handle inner grid line with orthonormal base, otherwise
|
|
// we would need to change the API of AxisActor which we don't want for
|
|
// backward compatibility.
|
|
if (hasOrthogonalVectorBase)
|
|
{
|
|
double axis, u, v;
|
|
axis = this->MajorStart[this->AxisType];
|
|
innerGridPointClosestU[vIndex] = this->GetBounds()[vIndex*2];
|
|
innerGridPointFarestU[vIndex] = this->GetBounds()[vIndex*2 + 1];
|
|
innerGridPointClosestV[uIndex] = this->GetBounds()[uIndex*2];
|
|
innerGridPointFarestV[uIndex] = this->GetBounds()[uIndex*2 + 1];
|
|
while (axis <= p2[this->AxisType])
|
|
{
|
|
innerGridPointClosestU[this->AxisType]
|
|
= innerGridPointClosestV[this->AxisType]
|
|
= innerGridPointFarestU[this->AxisType]
|
|
= innerGridPointFarestV[this->AxisType]
|
|
= axis;
|
|
|
|
// u lines
|
|
u = this->MajorStart[uIndex];
|
|
while (u <= p2[uIndex] && this->DeltaMajor[uIndex] > 0)
|
|
{
|
|
innerGridPointClosestU[uIndex] = innerGridPointFarestU[uIndex] = u;
|
|
this->InnerGridlinePts->InsertNextPoint(innerGridPointClosestU);
|
|
this->InnerGridlinePts->InsertNextPoint(innerGridPointFarestU);
|
|
u += this->DeltaMajor[uIndex];
|
|
}
|
|
|
|
// v lines
|
|
v = this->MajorStart[vIndex];
|
|
while (v <= p2[vIndex] && this->DeltaMajor[vIndex] > 0)
|
|
{
|
|
innerGridPointClosestV[vIndex] = innerGridPointFarestV[vIndex] = v;
|
|
this->InnerGridlinePts->InsertNextPoint(innerGridPointClosestV);
|
|
this->InnerGridlinePts->InsertNextPoint(innerGridPointFarestV);
|
|
v += this->DeltaMajor[vIndex];
|
|
}
|
|
|
|
axis += this->DeltaMajor[this->AxisType];
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildMinorTicks(double p1[3], double p2[3], double localCoordSys[3][3])
|
|
{
|
|
// (p2 - p1) vector
|
|
double deltaVector[3];
|
|
|
|
// inside point: point shifted toward x,y,z direction
|
|
// outside points: point shifted toward -x,-y,-z direction
|
|
double vPointInside[3], vPointOutside[3], uPointInside[3], uPointOutside[3];
|
|
|
|
int uMult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
int vMult = vtkAxisActorMultiplierTable2[this->AxisPosition];
|
|
|
|
double* axisVector = localCoordSys[0];
|
|
double* uVector = localCoordSys[1];
|
|
double* vVector = localCoordSys[2];
|
|
|
|
// - Initialize all points to be on the axis
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
|
|
deltaVector[i] = (p2[i] - p1[i]);
|
|
}
|
|
|
|
double axisLength = vtkMath::Norm(deltaVector);
|
|
double rangeScale = axisLength / (this->Range[1] - this->Range[0]);
|
|
|
|
// - Move outside points if needed (Axis -> Outside)
|
|
if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointOutside[i] += uVector[i] * uMult * this->MinorTickSize;
|
|
vPointOutside[i] += vVector[i] * vMult * this->MinorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Move inside points if needed (Axis -> Inside)
|
|
if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] -= uVector[i] * uMult * this->MinorTickSize;
|
|
vPointInside[i] -= vVector[i] * vMult * this->MinorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Add the initial shift if any
|
|
double axisShift = (this->MinorRangeStart - this->Range[0])*rangeScale;
|
|
axisLength -= axisShift;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] += axisVector[i] * axisShift;
|
|
vPointInside[i] += axisVector[i] * axisShift;
|
|
uPointOutside[i] += axisVector[i] * axisShift;
|
|
vPointOutside[i] += axisVector[i] * axisShift;
|
|
}
|
|
|
|
// - Reduce the deltaVector to correspond to a tick step
|
|
vtkMath::Normalize(deltaVector);
|
|
double deltaMinor = this->DeltaRangeMinor * rangeScale;
|
|
|
|
if (deltaMinor <= 0.0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// - Insert tick points along the axis using the deltaVector
|
|
|
|
// step is a multiple of deltaMajor value
|
|
// currentStep as well, except for the last value, it doesn't exceed axisLength
|
|
|
|
double step = 0.0, currentStep = 0.0;
|
|
double tickPoint[3];
|
|
while (currentStep < axisLength)
|
|
{
|
|
currentStep = (step > axisLength) ? axisLength : step;
|
|
|
|
// axis/u side
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
tickPoint[i] = deltaVector[i] * currentStep + uPointInside[i];
|
|
}
|
|
this->MinorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/u side
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
tickPoint[i] = deltaVector[i] * currentStep + uPointOutside[i];
|
|
}
|
|
this->MinorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/v side
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
tickPoint[i] = deltaVector[i] * currentStep + vPointInside[i];
|
|
}
|
|
this->MinorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/v side
|
|
for (int i = 0;i<3;i++)
|
|
tickPoint[i] = deltaVector[i] * currentStep + vPointOutside[i];
|
|
this->MinorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
step += deltaMinor;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildMajorTicks(double p1[3], double p2[3],
|
|
double localCoordSys[3][3])
|
|
{
|
|
double deltaVector[3];
|
|
double* axisVector = localCoordSys[0];
|
|
double* uVector = localCoordSys[1];
|
|
double* vVector = localCoordSys[2];
|
|
|
|
// inside point: point shifted toward x,y,z direction
|
|
// outside points: point shifted toward -x,-y,-z direction
|
|
double vPointInside[3], vPointOutside[3], uPointInside[3], uPointOutside[3];
|
|
|
|
int uMult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
int vMult = vtkAxisActorMultiplierTable2[this->AxisPosition];
|
|
|
|
// init deltaVector
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
deltaVector[i] = (p2[i] - p1[i]);
|
|
}
|
|
|
|
double axisLength = vtkMath::Norm(deltaVector);
|
|
|
|
//factor of conversion world coord <-> range
|
|
double rangeScale = axisLength / (this->Range[1] - this->Range[0]);
|
|
|
|
// Delta vector is already initialized with the Major tick scale
|
|
// - Initialize all points to be on the axis
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
|
|
this->TickVector[i] = uVector[i] * uMult * this->MajorTickSize;
|
|
}
|
|
|
|
// - Move outside points if needed (Axis -> Outside)
|
|
if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointOutside[i] += this->TickVector[i];
|
|
vPointOutside[i] += vVector[i] * vMult * this->MajorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Move inside points if needed (Axis -> Inside)
|
|
if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] -= this->TickVector[i];
|
|
vPointInside[i] -= vVector[i] * vMult * this->MajorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Add the initial shift if any
|
|
double axisShift = (this->MajorRangeStart - this->Range[0])*rangeScale;
|
|
axisLength -= axisShift;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] += axisVector[i] * axisShift;
|
|
vPointInside[i] += axisVector[i] * axisShift;
|
|
uPointOutside[i] += axisVector[i] * axisShift;
|
|
vPointOutside[i] += axisVector[i] * axisShift;
|
|
}
|
|
|
|
// - Reduce the deltaVector to correspond to a major tick step
|
|
vtkMath::Normalize(deltaVector);
|
|
double deltaMajor = this->DeltaRangeMajor * rangeScale;
|
|
|
|
if (deltaMajor <= 0.0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// - Insert tick points along the axis using the deltaVector
|
|
|
|
// step is a multiple of deltaMajor value
|
|
// currentStep as well, except for the last value, it doesn't exceed axisLength
|
|
|
|
double step = 0.0, currentStep = 0.0;
|
|
double tickPoint[3];
|
|
while (currentStep < axisLength)
|
|
{
|
|
currentStep = (step > axisLength) ? axisLength : step;
|
|
|
|
// axis/u side
|
|
for (int i = 0;i<3;i++)
|
|
tickPoint[i] = deltaVector[i] * currentStep + uPointInside[i];
|
|
this->MajorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/u side
|
|
for (int i = 0;i<3;i++)
|
|
tickPoint[i] = deltaVector[i] * currentStep + uPointOutside[i];
|
|
this->MajorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/v side
|
|
for (int i = 0;i<3;i++)
|
|
tickPoint[i] = deltaVector[i] * currentStep + vPointInside[i];
|
|
this->MajorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
// axis/v side
|
|
for (int i = 0;i<3;i++)
|
|
tickPoint[i] = deltaVector[i] * currentStep + vPointOutside[i];
|
|
this->MajorTickPts->InsertNextPoint(tickPoint);
|
|
|
|
step += deltaMajor;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildMinorTicksLog(double p1[3], double p2[3],
|
|
double localCoordSys[3][3])
|
|
{
|
|
double deltaVector[3];
|
|
|
|
double* axisVector = localCoordSys[0];
|
|
double* uVector = localCoordSys[1];
|
|
double* vVector = localCoordSys[2];
|
|
|
|
// inside point: point shifted toward x,y,z direction
|
|
// outside points: point shifted toward -x,-y,-z direction
|
|
double uPointInside[3], vPointInside[3], uPointOutside[3], vPointOutside[3];
|
|
|
|
for (int i = 0; i<3; i++)
|
|
{
|
|
uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
|
|
deltaVector[i] = (p2[i] - p1[i]);
|
|
}
|
|
|
|
double axisLength = vtkMath::Norm(deltaVector);
|
|
|
|
//factor of conversion world coord <-> range
|
|
double rangeScale = axisLength / log10(this->Range[1] / this->Range[0]);
|
|
|
|
vtkMath::Normalize(deltaVector);
|
|
|
|
int uMult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
int vMult = vtkAxisActorMultiplierTable2[this->AxisPosition];
|
|
// - Move outside points if needed (Axis -> Outside)
|
|
if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointOutside[i] += uVector[i] * uMult * this->MinorTickSize;
|
|
vPointOutside[i] += vVector[i] * vMult * this->MinorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Move inside points if needed (Axis -> Inside)
|
|
if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] -= uVector[i] * uMult * this->MinorTickSize;
|
|
vPointInside[i] -= vVector[i] * vMult * this->MinorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Add the initial shift if any
|
|
double axisShift = log10(this->MinorRangeStart / this->Range[0])*rangeScale;
|
|
axisLength -= axisShift;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] += axisVector[i] * axisShift;
|
|
vPointInside[i] += axisVector[i] * axisShift;
|
|
uPointOutside[i] += axisVector[i] * axisShift;
|
|
vPointOutside[i] += axisVector[i] * axisShift;
|
|
}
|
|
|
|
double base = 10.0, index;
|
|
double step, tickRangeVal, tickVal;
|
|
|
|
//pre set values
|
|
double log10Range0 = log10(this->Range[0]), log10Range1 = log10(this->Range[1]);
|
|
double lowBound = pow(base, floor(log10Range0)), upBound = pow(base, ceil(log10Range1));
|
|
|
|
double minorTickPoint[3], minorTickOnAxis[3];
|
|
|
|
// step match the minor tick log step, varying between each major tick.
|
|
// for log10: minor step is 0.1 between 0.1 and 1.0, then 1.0 between 1.0 and 10.0, and so on
|
|
for (step = lowBound; step < upBound; step *= base)
|
|
{
|
|
// number of minor tick between two major tick. for log10, index goes to 2.0 to 9.0
|
|
for (index = 2.0; index < base; index += 1.0)
|
|
{
|
|
tickRangeVal = index * step;
|
|
|
|
// particular cases:
|
|
if (tickRangeVal <= Range[0])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// over upper bound
|
|
if (tickRangeVal >= Range[1])
|
|
{
|
|
break;
|
|
}
|
|
|
|
tickVal = (log10(tickRangeVal) - log10Range0)*rangeScale;
|
|
|
|
//set tick point on axis (not inserted)
|
|
for (int i = 0; i<3; i++)
|
|
{
|
|
minorTickOnAxis[i] = deltaVector[i]*(tickVal);
|
|
}
|
|
//vtkMath::Add(minorTickOnAxis, p1, minorTickOnAxis); // handled later
|
|
|
|
//u inside point
|
|
vtkMath::Add(minorTickOnAxis, uPointInside, minorTickPoint);
|
|
this->MinorTickPts->InsertNextPoint(minorTickPoint);
|
|
|
|
//u outside point
|
|
vtkMath::Add(minorTickOnAxis, uPointOutside, minorTickPoint);
|
|
this->MinorTickPts->InsertNextPoint(minorTickPoint);
|
|
|
|
if (this->Use2DMode == 0)
|
|
{
|
|
//v inside point
|
|
vtkMath::Add(minorTickOnAxis, vPointInside, minorTickPoint);
|
|
this->MinorTickPts->InsertNextPoint(minorTickPoint);
|
|
|
|
//v outside point
|
|
vtkMath::Add(minorTickOnAxis, vPointOutside, minorTickPoint);
|
|
this->MinorTickPts->InsertNextPoint(minorTickPoint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::BuildMajorTicksLog(double p1[3], double p2[3], double localCoordSys[3][3])
|
|
{
|
|
double deltaVector[3];
|
|
|
|
double* axisVector = localCoordSys[0];
|
|
double* uVector = localCoordSys[1];
|
|
double* vVector = localCoordSys[2];
|
|
|
|
// inside point: point shifted toward x,y,z direction
|
|
// outside points: point shifted toward -x,-y,-z direction
|
|
double vPointInside[3], vPointOutside[3], uPointInside[3], uPointOutside[3];
|
|
|
|
for (int i = 0; i<3; i++)
|
|
{
|
|
uPointInside[i] = vPointInside[i] = uPointOutside[i] = vPointOutside[i] = p1[i];
|
|
deltaVector[i] = (p2[i] - p1[i]);
|
|
}
|
|
|
|
// length of axis (wold coord system)
|
|
double axisLength = vtkMath::Norm(deltaVector);
|
|
|
|
//factor of conversion world coord <-> range
|
|
double rangeScale = axisLength / log10(this->Range[1] / this->Range[0]);
|
|
|
|
vtkMath::Normalize(deltaVector);
|
|
|
|
int uMult = vtkAxisActorMultiplierTable1[this->AxisPosition];
|
|
int vMult = vtkAxisActorMultiplierTable2[this->AxisPosition];
|
|
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
this->TickVector[i] = uVector[i] * uMult * this->MajorTickSize;
|
|
}
|
|
|
|
// - Move outside points if needed (Axis -> Outside)
|
|
if (this->TickLocation == VTK_TICKS_OUTSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointOutside[i] += this->TickVector[i];
|
|
vPointOutside[i] += vVector[i] * vMult * this->MajorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Move inside points if needed (Axis -> Inside)
|
|
if (this->TickLocation == VTK_TICKS_INSIDE || this->TickLocation == VTK_TICKS_BOTH)
|
|
{
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] -= this->TickVector[i];
|
|
vPointInside[i] -= vVector[i] * vMult * this->MajorTickSize;
|
|
}
|
|
}
|
|
|
|
// - Add the initial shift if any
|
|
double axisShift = log10(this->MajorRangeStart / this->Range[0])*rangeScale;
|
|
axisLength -= axisShift;
|
|
for (int i = 0;i<3;i++)
|
|
{
|
|
uPointInside[i] += axisVector[i] * axisShift;
|
|
vPointInside[i] += axisVector[i] * axisShift;
|
|
uPointOutside[i] += axisVector[i] * axisShift;
|
|
vPointOutside[i] += axisVector[i] * axisShift;
|
|
}
|
|
|
|
double base = 10.0;
|
|
double indexTickRangeValue;
|
|
double tickVal, tickRangeVal;
|
|
double log10Range0 = log10(this->Range[0]), log10Range1 = log10(this->Range[1]);
|
|
double lowBound = pow(base, (int)floor(log10Range0)), upBound = pow(base, (int)ceil(log10Range1));
|
|
|
|
double majorTickOnAxis[3], majorTickPoint[3];
|
|
for (indexTickRangeValue = lowBound; indexTickRangeValue <= upBound; indexTickRangeValue *= base)
|
|
{
|
|
tickRangeVal = indexTickRangeValue;
|
|
|
|
if (indexTickRangeValue < this->Range[0])
|
|
{
|
|
tickRangeVal = this->Range[0];
|
|
}
|
|
else if (indexTickRangeValue > this->Range[1])
|
|
{
|
|
tickRangeVal = this->Range[1];
|
|
}
|
|
|
|
tickVal = (log10(tickRangeVal) - log10Range0)*rangeScale;
|
|
|
|
for (int i = 0; i<3; i++)
|
|
{
|
|
majorTickOnAxis[i] = deltaVector[i]*tickVal;
|
|
}
|
|
|
|
//u inside point
|
|
vtkMath::Add(majorTickOnAxis, uPointInside, majorTickPoint);
|
|
this->MajorTickPts->InsertNextPoint(majorTickPoint);
|
|
|
|
//u outside point
|
|
vtkMath::Add(majorTickOnAxis, uPointOutside, majorTickPoint);
|
|
this->MajorTickPts->InsertNextPoint(majorTickPoint);
|
|
|
|
//v inside point
|
|
vtkMath::Add(majorTickOnAxis, vPointInside, majorTickPoint);
|
|
this->MajorTickPts->InsertNextPoint(majorTickPoint);
|
|
|
|
//v outside point
|
|
vtkMath::Add(majorTickOnAxis, vPointOutside, majorTickPoint);
|
|
this->MajorTickPts->InsertNextPoint(majorTickPoint);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAxisActor::RotateActor2DFromAxisProjection(vtkTextActor* pActor2D)
|
|
{
|
|
double *p1 = this->Point1Coordinate->GetValue();
|
|
double *p2 = this->Point2Coordinate->GetValue();
|
|
|
|
vtkMatrix4x4* matModelView = this->Camera->GetModelViewTransformMatrix();
|
|
double near = this->Camera->GetClippingRange()[0];
|
|
|
|
// Need view coordinate points.
|
|
double viewPt1[4] = {p1[0], p1[1], p1[2], 1.0};
|
|
double viewPt2[4] = {p2[0], p2[1], p2[2], 1.0};
|
|
|
|
matModelView->MultiplyPoint(viewPt1, viewPt1);
|
|
matModelView->MultiplyPoint(viewPt2, viewPt2);
|
|
|
|
if (viewPt1[2] == 0.0 || viewPt2[2] == 0.0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double p1Pjt[3] = { -near* viewPt1[0] / viewPt1[2], -near* viewPt1[1] / viewPt1[2], -near};
|
|
double p2Pjt[3] = { -near* viewPt2[0] / viewPt2[2], -near* viewPt2[1] / viewPt2[2], -near};
|
|
|
|
double axisOnScreen[2] = {p2Pjt[0] - p1Pjt[0], p2Pjt[1] - p1Pjt[1]};
|
|
double x[2] = {1.0, 0.0}, y[2] = {0.0, 1.0};
|
|
|
|
double dotProd = vtkMath::Dot2D(x, axisOnScreen);
|
|
|
|
double orient = 0.0;
|
|
if (vtkMath::Norm2D(axisOnScreen) == 0.0)
|
|
{
|
|
pActor2D->SetOrientation(0.0);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
orient = acos(dotProd / vtkMath::Norm2D(axisOnScreen));
|
|
orient = vtkMath::DegreesFromRadians(orient);
|
|
}
|
|
|
|
// adjust angle
|
|
if (vtkMath::Dot2D(y, axisOnScreen) < 0.0)
|
|
{
|
|
orient *= -1.0;
|
|
}
|
|
|
|
if (vtkMath::Dot2D(x, axisOnScreen) < 0.0)
|
|
{
|
|
orient += 180.0;
|
|
}
|
|
|
|
pActor2D->SetOrientation(orient);
|
|
}
|