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.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/Interaction/Widgets/vtkResliceCursorRepresentat...

920 lines
28 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkResliceCursorRepresentation.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkResliceCursorRepresentation.h"
#include "vtkResliceCursor.h"
#include "vtkResliceCursorPolyDataAlgorithm.h"
#include "vtkHandleRepresentation.h"
#include "vtkCoordinate.h"
#include "vtkRenderer.h"
#include "vtkMath.h"
#include "vtkWindow.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor2D.h"
#include "vtkTextMapper.h"
#include "vtkTextProperty.h"
#include "vtkTextActor.h"
#include "vtkProperty2D.h"
#include "vtkPointHandleRepresentation2D.h"
#include "vtkObjectFactory.h"
#include "vtkImageReslice.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkImageData.h"
#include "vtkPlaneSource.h"
#include "vtkPlane.h"
#include "vtkLookupTable.h"
#include "vtkScalarsToColors.h"
#include "vtkImageMapToWindowLevelColors.h"
#include "vtkInteractorObserver.h"
#include "vtkActor.h"
#include "vtkTexture.h"
#include "vtkImageActor.h"
#include "vtkCamera.h"
#include "vtkImageMapper3D.h"
#include <sstream>
vtkCxxSetObjectMacro(vtkResliceCursorRepresentation, ColorMap, vtkImageMapToColors);
//----------------------------------------------------------------------
vtkResliceCursorRepresentation::vtkResliceCursorRepresentation()
{
this->ManipulationMode = None;
this->Modifier = 0;
this->Tolerance = 5;
this->ShowReslicedImage = 1;
this->RestrictPlaneToVolume = 1;
this->OriginalWindow = 1.0;
this->OriginalLevel = 0.5;
this->InitialWindow = 1.0;
this->InitialLevel = 0.5;
this->CurrentWindow = 1.0;
this->CurrentLevel = 0.5;
this->ThicknessTextProperty = vtkTextProperty::New();
this->ThicknessTextProperty->SetBold(1);
this->ThicknessTextProperty->SetItalic(1);
this->ThicknessTextProperty->SetShadow(1);
this->ThicknessTextProperty->SetFontFamilyToArial();
this->ThicknessTextMapper = vtkTextMapper::New();
this->ThicknessTextMapper->SetTextProperty(this->ThicknessTextProperty);
this->ThicknessTextMapper->SetInput("0.0");
this->ThicknessTextActor = vtkActor2D::New();
this->ThicknessTextActor->SetMapper(this->ThicknessTextMapper);
this->ThicknessTextActor->VisibilityOff();
this->Reslice = NULL;
this->CreateDefaultResliceAlgorithm();
this->PlaneSource = vtkPlaneSource::New();
this->ThicknessLabelFormat = new char[6];
sprintf(this->ThicknessLabelFormat,"%s","%0.3g");
this->ResliceAxes = vtkMatrix4x4::New();
this->NewResliceAxes = vtkMatrix4x4::New();
this->LookupTable = 0;
this->ColorMap = vtkImageMapToColors::New();
this->Texture = vtkTexture::New();
this->Texture->SetInputConnection(
this->ColorMap->GetOutputPort());
this->Texture->SetInterpolate(1);
this->TexturePlaneActor = vtkActor::New();
this->LookupTable = this->CreateDefaultLookupTable();
this->ColorMap->SetLookupTable(this->LookupTable);
this->ColorMap->SetOutputFormatToRGBA();
this->ColorMap->PassAlphaToOutputOn();
vtkPolyDataMapper* texturePlaneMapper = vtkPolyDataMapper::New();
texturePlaneMapper->SetInputConnection(
this->PlaneSource->GetOutputPort());
texturePlaneMapper->SetResolveCoincidentTopologyToPolygonOffset();
this->Texture->SetQualityTo32Bit();
this->Texture->MapColorScalarsThroughLookupTableOff();
this->Texture->SetInterpolate(1);
this->Texture->RepeatOff();
this->Texture->SetLookupTable(this->LookupTable);
this->TexturePlaneActor->SetMapper(texturePlaneMapper);
this->TexturePlaneActor->SetTexture(this->Texture);
this->TexturePlaneActor->PickableOn();
texturePlaneMapper->Delete();
this->UseImageActor = false;
this->ImageActor = vtkImageActor::New();
this->ImageActor->GetMapper()->SetInputConnection(
this->ColorMap->GetOutputPort());
// Represent the text: annotation for cursor position and W/L
this->DisplayText = 1;
this->TextActor = vtkTextActor::New();
this->GenerateText();
}
//----------------------------------------------------------------------
vtkResliceCursorRepresentation::~vtkResliceCursorRepresentation()
{
this->ThicknessTextProperty->Delete();
this->ThicknessTextMapper->Delete();
this->ThicknessTextActor->Delete();
this->SetThicknessLabelFormat(0);
this->ImageActor->Delete();
if (this->Reslice)
{
this->Reslice->Delete();
}
this->PlaneSource->Delete();
this->ResliceAxes->Delete();
this->NewResliceAxes->Delete();
if ( this->LookupTable )
{
this->LookupTable->UnRegister(this);
}
this->ColorMap->Delete();
this->Texture->Delete();
this->TexturePlaneActor->Delete();
this->TextActor->Delete();
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::SetLookupTable(vtkScalarsToColors *l)
{
vtkSetObjectBodyMacro(LookupTable, vtkScalarsToColors, l);
this->LookupTable = l;
if (this->ColorMap)
{
this->ColorMap->SetLookupTable(this->LookupTable);
}
}
//----------------------------------------------------------------------
char* vtkResliceCursorRepresentation::GetThicknessLabelText()
{
return this->ThicknessTextMapper->GetInput();
}
//----------------------------------------------------------------------
double* vtkResliceCursorRepresentation::GetThicknessLabelPosition()
{
return this->ThicknessTextActor->GetPosition();
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::GetThicknessLabelPosition(double pos[3])
{
this->ThicknessTextActor->GetPositionCoordinate()->GetValue(pos);
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::GetWorldThicknessLabelPosition(double pos[3])
{
double viewportPos[3], worldPos[4];
pos[0] = pos[1] = pos[2] = 0.0;
if (!this->Renderer)
{
vtkErrorMacro("GetWorldLabelPosition: no renderer!");
return;
}
this->ThicknessTextActor->GetPositionCoordinate()->GetValue(viewportPos);
this->Renderer->ViewportToNormalizedViewport(viewportPos[0], viewportPos[1]);
this->Renderer->NormalizedViewportToView(viewportPos[0], viewportPos[1], viewportPos[2]);
this->Renderer->SetViewPoint(viewportPos);
this->Renderer->ViewToWorld();
this->Renderer->GetWorldPoint(worldPos);
if (worldPos[3] != 0.0)
{
pos[0] = worldPos[0]/worldPos[3];
pos[1] = worldPos[1]/worldPos[3];
pos[2] = worldPos[2]/worldPos[3];
}
else
{
vtkErrorMacro("GetWorldLabelPosition: world position at index 3 is 0, not dividing by 0");
}
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::SetManipulationMode( int m )
{
this->ManipulationMode = m;
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::BuildRepresentation()
{
this->Reslice->SetInputData(this->GetResliceCursor()->GetImage());
this->TexturePlaneActor->SetVisibility(
this->GetResliceCursor()->GetImage() ?
(this->ShowReslicedImage && !this->UseImageActor): 0);
this->ImageActor->SetVisibility(
this->GetResliceCursor()->GetImage() ?
(this->ShowReslicedImage && this->UseImageActor) : 0);
// Update the reslice plane if the plane is being manipulated
if (this->GetManipulationMode() != WindowLevelling )
{
this->UpdateReslicePlane();
}
this->ImageActor->SetDisplayExtent(this->ColorMap->GetOutput()->GetExtent());
// Update any text annotations
this->ManageTextDisplay();
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::InitializeReslicePlane()
{
if ( !this->GetResliceCursor()->GetImage())
{
return;
}
// this->GetResliceCursor()->GetImage()->UpdateInformation();
// Initialize the reslice plane origins. Offset should be zero within
// this function here.
this->ComputeReslicePlaneOrigin();
// Finally reset the camera to whatever orientation they were staring in
this->ResetCamera();
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::ResetCamera()
{
// Reset the camera back to the default and the focal point to where
// the cursor center is
if (this->Renderer)
{
double center[3], camPos[3], n[3];
this->GetResliceCursor()->GetCenter(center);
this->Renderer->GetActiveCamera()->SetFocalPoint(center);
const int normalAxis = this->GetCursorAlgorithm()->GetReslicePlaneNormal();
this->GetResliceCursor()->GetPlane(normalAxis)->GetNormal(n);
vtkMath::Add( center, n, camPos );
this->Renderer->GetActiveCamera()->SetPosition(camPos);
// Reset the camera in response to changes.
this->Renderer->ResetCamera();
this->Renderer->ResetCameraClippingRange();
}
}
//----------------------------------------------------------------------------
// This is the first axis of the reslice on the currently resliced plane
//
void vtkResliceCursorRepresentation::GetVector1(double v1[3])
{
// From the initial view up vector, compute its cross product with the
// current plane normal. This is Vector1. Then Vector2 is the cross product
// of Vector1 and the normal.
double v2[3];
double* p2 = this->PlaneSource->GetPoint2();
double* o = this->PlaneSource->GetOrigin();
// Vector p2 -> o
vtkMath::Subtract( p2, o, v2 );
const int planeOrientation =
this->GetCursorAlgorithm()->GetReslicePlaneNormal();
vtkPlane *plane = this->GetResliceCursor()->GetPlane(planeOrientation);
double planeNormal[3];
plane->GetNormal(planeNormal);
vtkMath::Cross( v2, planeNormal, v1 );
vtkMath::Normalize(v1);
}
//----------------------------------------------------------------------------
// This is the second axis of the reslice on the currently resliced plane
// It is orthogonal to v1 and to the plane normal. Note that this is not the
// same as the reslice cursor's axes, which need not be orthogonal to each
// other. The goal of vector1 and vector2 is to compute the X and Y axes of
// the resliced plane.
//
void vtkResliceCursorRepresentation::GetVector2(double v2[3])
{
const int planeOrientation =
this->GetCursorAlgorithm()->GetReslicePlaneNormal();
vtkPlane *plane = this->GetResliceCursor()->GetPlane(planeOrientation);
double planeNormal[3];
plane->GetNormal(planeNormal);
double v1[3];
this->GetVector1(v1);
vtkMath::Cross( planeNormal, v1, v2 );
vtkMath::Normalize(v2);
}
//----------------------------------------------------------------------
// Compute the origin of the reslice plane prior to transformations.
//
void vtkResliceCursorRepresentation::ComputeReslicePlaneOrigin()
{
double bounds[6];
this->GetResliceCursor()->GetImage()->GetBounds(bounds);
double center[3], imageCenter[3], offset[3];
this->GetResliceCursor()->GetCenter(center);
this->GetResliceCursor()->GetImage()->GetCenter(imageCenter);
// Offset based on the center of the image and how far from it the
// reslice cursor is. This allows us to capture the whole image even
// if we resliced in awkward places.
for (int i = 0; i < 3; i++)
{
offset[i] = -fabs(center[i] - imageCenter[i]);
}
// Now resize the plane based on these offsets.
const int planeOrientation =
this->GetCursorAlgorithm()->GetReslicePlaneNormal();
// Now set the size of the plane based on the location of the cursor so as to
// at least completely cover the viewed region
if ( planeOrientation == 1 )
{
this->PlaneSource->SetOrigin(bounds[0]+offset[0],center[1],bounds[4]+offset[2]);
this->PlaneSource->SetPoint1(bounds[1]-offset[0],center[1],bounds[4]+offset[2]);
this->PlaneSource->SetPoint2(bounds[0]+offset[0],center[1],bounds[5]-offset[2]);
}
else if ( planeOrientation == 2 )
{
this->PlaneSource->SetOrigin(bounds[0]+offset[0],bounds[2]+offset[1],center[2]);
this->PlaneSource->SetPoint1(bounds[1]-offset[0],bounds[2]+offset[1],center[2]);
this->PlaneSource->SetPoint2(bounds[0]+offset[0],bounds[3]-offset[1],center[2]);
}
else if ( planeOrientation == 0 )
{
this->PlaneSource->SetOrigin(center[0],bounds[2]+offset[1],bounds[4]+offset[2]);
this->PlaneSource->SetPoint1(center[0],bounds[3]-offset[1],bounds[4]+offset[2]);
this->PlaneSource->SetPoint2(center[0],bounds[2]+offset[1],bounds[5]-offset[2]);
}
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::UpdateReslicePlane()
{
if ( !this->GetResliceCursor()->GetImage() ||
!this->TexturePlaneActor->GetVisibility() )
{
return;
}
// Reinitialize the reslice plane.. We will recompute everything here.
if (this->PlaneSource->GetPoint1()[0] == 0.5 &&
this->PlaneSource->GetOrigin()[0] == -0.5)
{
this->InitializeReslicePlane();
}
// Calculate appropriate pixel spacing for the reslicing
//
// this->GetResliceCursor()->UpdateInformation();
double spacing[3];
this->GetResliceCursor()->GetImage()->GetSpacing(spacing);
double origin[3];
this->GetResliceCursor()->GetImage()->GetOrigin(origin);
int extent[6];
this->GetResliceCursor()->GetImage()->GetExtent(extent);
for (int i = 0; i < 3; i++)
{
if (extent[2*i] > extent[2*i + 1])
{
vtkErrorMacro("Invalid extent ["
<< extent[0] << ", " << extent[1] << ", "
<< extent[2] << ", " << extent[3] << ", "
<< extent[4] << ", " << extent[5] << "]."
<< " Perhaps the input data is empty?");
break;
}
}
const int planeOrientation =
this->GetCursorAlgorithm()->GetReslicePlaneNormal();
vtkPlane *plane = this->GetResliceCursor()->GetPlane(planeOrientation);
double planeNormal[3];
plane->GetNormal(planeNormal);
// Compute the origin of the reslice plane prior to transformations.
this->ComputeReslicePlaneOrigin();
this->PlaneSource->SetNormal(planeNormal);
this->PlaneSource->SetCenter(plane->GetOrigin());
double planeAxis1[3];
double planeAxis2[3];
double* p1 = this->PlaneSource->GetPoint1();
double* o = this->PlaneSource->GetOrigin();
vtkMath::Subtract( p1, o, planeAxis1 );
double* p2 = this->PlaneSource->GetPoint2();
vtkMath::Subtract( p2, o, planeAxis2 );
// The x,y dimensions of the plane
//
const double planeSizeX = vtkMath::Normalize(planeAxis1);
const double planeSizeY = vtkMath::Normalize(planeAxis2);
double normal[3];
this->PlaneSource->GetNormal(normal);
this->NewResliceAxes->Identity();
for ( int i = 0; i < 3; i++ )
{
this->NewResliceAxes->SetElement(0,i,planeAxis1[i]);
this->NewResliceAxes->SetElement(1,i,planeAxis2[i]);
this->NewResliceAxes->SetElement(2,i,normal[i]);
}
const double spacingX = fabs(planeAxis1[0]*spacing[0])+
fabs(planeAxis1[1]*spacing[1])+
fabs(planeAxis1[2]*spacing[2]);
const double spacingY = fabs(planeAxis2[0]*spacing[0])+
fabs(planeAxis2[1]*spacing[1])+
fabs(planeAxis2[2]*spacing[2]);
double planeOrigin[4];
this->PlaneSource->GetOrigin(planeOrigin);
planeOrigin[3] = 1.0;
double originXYZW[4];
double neworiginXYZW[4];
this->NewResliceAxes->MultiplyPoint(planeOrigin, originXYZW);
this->NewResliceAxes->Transpose();
this->NewResliceAxes->MultiplyPoint(originXYZW, neworiginXYZW);
this->NewResliceAxes->SetElement(0,3,neworiginXYZW[0]);
this->NewResliceAxes->SetElement(1,3,neworiginXYZW[1]);
this->NewResliceAxes->SetElement(2,3,neworiginXYZW[2]);
// Compute a new set of resliced extents
int extentX, extentY;
// Pad extent up to a power of two for efficient texture mapping
// make sure we're working with valid values
double realExtentX = ( spacingX == 0 ) ? VTK_INT_MAX : planeSizeX / spacingX;
// Sanity check the input data:
// * if realExtentX is too large, extentX will wrap
// * if spacingX is 0, things will blow up.
if (realExtentX > (VTK_INT_MAX >> 1))
{
vtkErrorMacro(<<"Invalid X extent: " << realExtentX);
extentX = 0;
}
else
{
extentX = 1;
while (extentX < realExtentX)
{
extentX = extentX << 1;
}
}
// make sure extentY doesn't wrap during padding
double realExtentY = ( spacingY == 0 ) ? VTK_INT_MAX : planeSizeY / spacingY;
if (realExtentY > (VTK_INT_MAX >> 1))
{
vtkErrorMacro(<<"Invalid Y extent: " << realExtentY);
extentY = 0;
}
else
{
extentY = 1;
while (extentY < realExtentY)
{
extentY = extentY << 1;
}
}
double outputSpacingX = (extentX == 0) ? 1.0 : planeSizeX/extentX;
double outputSpacingY = (extentY == 0) ? 1.0 : planeSizeY/extentY;
bool modify = false;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
double d = this->NewResliceAxes->GetElement(i,j);
if (d != this->ResliceAxes->GetElement(i,j))
{
this->ResliceAxes->SetElement(i,j,d);
modify = true;
}
}
}
if (modify)
{
this->ResliceAxes->Modified();
}
this->SetResliceParameters( outputSpacingX, outputSpacingY,
extentX, extentY );
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::ComputeOrigin(vtkMatrix4x4 *m)
{
double center[4] = {0,0,0,1};
double centerTransformed[4];
this->GetResliceCursor()->GetCenter(center);
m->MultiplyPoint(center, centerTransformed);
for (int i = 0; i < 3; i++)
{
m->SetElement(i, 3,
m->GetElement(i,3) + center[i] - centerTransformed[i]);
}
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation
::SetResliceParameters( double outputSpacingX, double outputSpacingY,
int extentX, int extentY )
{
vtkImageReslice *reslice = vtkImageReslice::SafeDownCast(this->Reslice);
if (reslice)
{
// Set the default color the minimum scalar value
double range[2];
vtkImageData::SafeDownCast(reslice->GetInput())->
GetScalarRange( range );
reslice->SetBackgroundLevel(range[0]);
this->ColorMap->SetInputConnection(reslice->GetOutputPort());
reslice->TransformInputSamplingOff();
reslice->AutoCropOutputOn();
reslice->SetResliceAxes(this->ResliceAxes);
reslice->SetOutputSpacing(outputSpacingX, outputSpacingY, 1);
reslice->SetOutputOrigin(0.5*outputSpacingX, 0.5*outputSpacingY, 0);
reslice->SetOutputExtent(0, extentX-1, 0, extentY-1, 0, 0);
}
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation
::SetWindowLevel(double window, double level, int copy)
{
if ( copy )
{
this->CurrentWindow = window;
this->CurrentLevel = level;
return;
}
if ( this->CurrentWindow == window && this->CurrentLevel == level )
{
return;
}
// if the new window is negative and the old window was positive invert table
if ( (( window < 0 && this->CurrentWindow > 0 ) ||
( window > 0 && this->CurrentWindow < 0 )) )
{
this->InvertTable();
}
this->CurrentWindow = window;
this->CurrentLevel = level;
double rmin = this->CurrentLevel - 0.5*fabs( this->CurrentWindow );
double rmax = rmin + fabs( this->CurrentWindow );
this->LookupTable->SetRange( rmin, rmax );
this->Modified();
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::GetWindowLevel(double wl[2])
{
wl[0] = this->CurrentWindow;
wl[1] = this->CurrentLevel;
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::WindowLevel(double X, double Y)
{
if ( !this->Renderer )
{
return;
}
int *size = this->Renderer->GetSize();
double window = this->InitialWindow;
double level = this->InitialLevel;
// Compute normalized delta
double dx = 2.0 * ( X - this->StartEventPosition[0] ) / size[0];
double dy = 2.0 * ( this->StartEventPosition[1] - Y ) / size[1];
// Scale by current values
if ( fabs( window ) > 0.01 )
{
dx = dx * window;
}
else
{
dx = dx * ( window < 0 ? -0.01 : 0.01 );
}
if ( fabs( level ) > 0.01 )
{
dy = dy * level;
}
else
{
dy = dy * ( level < 0 ? -0.01 : 0.01 );
}
// Abs so that direction does not flip
if ( window < 0.0 )
{
dx = -1 * dx;
}
if ( level < 0.0 )
{
dy = -1 * dy;
}
// Compute new window level
double newWindow = dx + window;
double newLevel = level - dy;
if ( fabs( newWindow ) < 0.01 )
{
newWindow = 0.01 * ( newWindow < 0 ? -1 : 1 );
}
if ( fabs( newLevel ) < 0.01 )
{
newLevel = 0.01 * ( newLevel < 0 ? -1 : 1 );
}
if (( newWindow < 0 && this->CurrentWindow > 0 ) ||
( newWindow > 0 && this->CurrentWindow < 0 ))
{
this->InvertTable();
}
double rmin = newLevel - 0.5*fabs( newWindow );
double rmax = rmin + fabs( newWindow );
this->LookupTable->SetRange( rmin, rmax );
if (this->DisplayText && (this->CurrentWindow != newWindow ||
this->CurrentLevel != newLevel) )
{
this->CurrentWindow = newWindow;
this->CurrentLevel = newLevel;
}
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::InvertTable()
{
vtkLookupTable *lut = vtkLookupTable::SafeDownCast(this->LookupTable);
if ( lut )
{
int index = lut->GetNumberOfTableValues();
unsigned char swap[4];
size_t num = 4*sizeof(unsigned char);
vtkUnsignedCharArray* table = lut->GetTable();
for ( int count = 0; count < --index; count++ )
{
unsigned char *rgba1 = table->GetPointer(4*count);
unsigned char *rgba2 = table->GetPointer(4*index);
memcpy( swap, rgba1, num );
memcpy( rgba1, rgba2, num );
memcpy( rgba2, swap, num );
}
// force the lookuptable to update its InsertTime to avoid
// rebuilding the array
lut->SetTableValue( 0, lut->GetTableValue( 0 ) );
}
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::CreateDefaultResliceAlgorithm()
{
// Allows users to optionally use their own reslice filters or other
// algorithms here.
if (!this->Reslice)
{
this->Reslice = vtkImageReslice::New();
}
}
//----------------------------------------------------------------------------
vtkScalarsToColors* vtkResliceCursorRepresentation::CreateDefaultLookupTable()
{
vtkLookupTable* lut = vtkLookupTable::New();
lut->Register(this);
lut->Delete();
lut->SetNumberOfColors( 256);
lut->SetHueRange( 0, 0);
lut->SetSaturationRange( 0, 0);
lut->SetValueRange( 0 ,1);
lut->SetAlphaRange( 1, 1);
lut->Build();
return lut;
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::ActivateText(int i)
{
this->TextActor->SetVisibility(this->Renderer &&
this->GetVisibility() && i && this->DisplayText );
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::ManageTextDisplay()
{
if ( !this->DisplayText )
{
return;
}
if ( this->ManipulationMode ==
vtkResliceCursorRepresentation::WindowLevelling )
{
sprintf(this->TextBuff,"Window, Level: ( %g, %g )",
this->CurrentWindow, this->CurrentLevel );
}
else if (this->ManipulationMode ==
vtkResliceCursorRepresentation::ResizeThickness )
{
// For now all the thickness' are the same anyway.
sprintf(this->TextBuff,"Reslice Thickness: %g mm",
this->GetResliceCursor()->GetThickness()[0] );
}
this->TextActor->SetInput(this->TextBuff);
this->TextActor->Modified();
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::SetTextProperty(vtkTextProperty* tprop)
{
this->TextActor->SetTextProperty(tprop);
}
//----------------------------------------------------------------------------
vtkTextProperty* vtkResliceCursorRepresentation::GetTextProperty()
{
return this->TextActor->GetTextProperty();
}
//----------------------------------------------------------------------------
void vtkResliceCursorRepresentation::GenerateText()
{
sprintf(this->TextBuff,"NA");
this->TextActor->SetInput(this->TextBuff);
this->TextActor->SetTextScaleModeToNone();
vtkTextProperty* textprop = this->TextActor->GetTextProperty();
textprop->SetColor(1,1,1);
textprop->SetFontFamilyToArial();
textprop->SetFontSize(18);
textprop->BoldOff();
textprop->ItalicOff();
textprop->ShadowOff();
textprop->SetJustificationToLeft();
textprop->SetVerticalJustificationToBottom();
vtkCoordinate* coord = this->TextActor->GetPositionCoordinate();
coord->SetCoordinateSystemToNormalizedViewport();
coord->SetValue(.01, .01);
this->TextActor->VisibilityOff();
}
//----------------------------------------------------------------------
// Prints an object if it exists.
#define vtkPrintMemberObjectMacro( obj, os, indent ) \
os << indent << #obj << ": "; \
if (this->obj) \
{ \
os << this->obj << "\n"; \
} \
else \
{ \
os << "(null)\n"; \
}
//----------------------------------------------------------------------
void vtkResliceCursorRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
//Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
this->Superclass::PrintSelf(os,indent);
os << indent << "Tolerance: " << this->Tolerance << "\n";
os << indent << "Thickness Label Text: " << this->GetThicknessLabelText() << "\n";
os << indent << "PlaneSource: " << this->PlaneSource << "\n";
if (this->PlaneSource)
{
this->PlaneSource->PrintSelf(os,indent.GetNextIndent());
}
os << indent << "PlaneSource: " << this->PlaneSource << "\n";
vtkPrintMemberObjectMacro( ThicknessLabelFormat, os, indent );
vtkPrintMemberObjectMacro( Reslice, os, indent );
vtkPrintMemberObjectMacro( ThicknessTextProperty, os, indent );
vtkPrintMemberObjectMacro( ThicknessTextMapper, os, indent );
vtkPrintMemberObjectMacro( ThicknessTextActor, os, indent );
vtkPrintMemberObjectMacro( ResliceAxes, os, indent );
vtkPrintMemberObjectMacro( NewResliceAxes, os, indent );
vtkPrintMemberObjectMacro( ColorMap, os, indent );
vtkPrintMemberObjectMacro( TexturePlaneActor, os, indent );
vtkPrintMemberObjectMacro( Texture, os, indent );
vtkPrintMemberObjectMacro( LookupTable, os, indent );
vtkPrintMemberObjectMacro( ImageActor, os, indent );
vtkPrintMemberObjectMacro( TextActor, os, indent );
os << indent << "RestrictPlaneToVolume: "
<< this->RestrictPlaneToVolume << "\n";
os << indent << "ShowReslicedImage: "
<< this->ShowReslicedImage << "\n";
os << indent << "OriginalWindow: "
<< this->OriginalWindow << "\n";
os << indent << "OriginalLevel: "
<< this->OriginalLevel << "\n";
os << indent << "CurrentWindow: "
<< this->CurrentWindow << "\n";
os << indent << "CurrentLevel: "
<< this->CurrentLevel << "\n";
os << indent << "InitialWindow: "
<< this->InitialWindow << "\n";
os << indent << "InitialLevel: "
<< this->InitialLevel << "\n";
os << indent << "UseImageActor: "
<< this->UseImageActor << "\n";
os << indent << "DisplayText: "
<< this->DisplayText << "\n";
// this->ManipulationMode
// this->LastEventPosition[2]
// this->TextBuff[128];
// this->ResliceAxes;
// this->LookupTable;
// this->Reslice;
// this->ThicknessLabelFormat;
// this->ColorMap;
// this->ImageActor;
// this->ThicknessTextProperty;
// this->ThicknessTextMapper;
// this->ThicknessTextActor;
// this->NewResliceAxes;
// this->TexturePlaneActor;
// this->Texture;
// this->TextActor;
}