#include <mitkVectorImageMapper2D.h>


Public Types | |
| typedef VectorImageMapper2D | Self |
| typedef GLMapper2D | Superclass |
| typedef itk::SmartPointer< Self > | Pointer |
| typedef itk::SmartPointer < const Self > | ConstPointer |
| typedef vtkFloatingPointType | vtkScalarType |
Public Member Functions | |
| virtual const char * | GetClassName () const |
| const mitk::Image * | GetInput (void) |
| virtual void | Paint (mitk::BaseRenderer *renderer) |
| Do the painting into the renderer. | |
| virtual void | SetImage (const mitk::Image *_arg) |
| virtual const mitk::Image * | GetImage () |
| virtual void | PaintCells (vtkPolyData *contour, const Geometry2D *worldGeometry, const DisplayGeometry *displayGeometry, vtkLinearTransform *vtktransform, BaseRenderer *renderer, vtkScalarsToColors *lut, mitk::Color color, float lwidth, vtkFloatingPointType *spacing) |
Static Public Member Functions | |
| static Pointer | New () |
Protected Member Functions | |
| int | GetCurrentTimeStep (mitk::BaseData *data, mitk::BaseRenderer *renderer) |
| VectorImageMapper2D () | |
| virtual | ~VectorImageMapper2D () |
Protected Attributes | |
| mitk::Image::ConstPointer | m_Image |
| vtkLookupTable * | m_LUT |
| vtkPlane * | m_Plane |
| vtkCutter * | m_Cutter |
Definition at line 44 of file mitkVectorImageMapper2D.h.
| typedef itk::SmartPointer<const Self> mitk::VectorImageMapper2D::ConstPointer |
Reimplemented from mitk::Mapper2D.
Definition at line 47 of file mitkVectorImageMapper2D.h.
| typedef itk::SmartPointer<Self> mitk::VectorImageMapper2D::Pointer |
Reimplemented from mitk::Mapper2D.
Definition at line 47 of file mitkVectorImageMapper2D.h.
Reimplemented from mitk::Mapper2D.
Definition at line 47 of file mitkVectorImageMapper2D.h.
Reimplemented from mitk::Mapper2D.
Definition at line 47 of file mitkVectorImageMapper2D.h.
| typedef vtkFloatingPointType mitk::VectorImageMapper2D::vtkScalarType |
Definition at line 49 of file mitkVectorImageMapper2D.h.
| mitk::VectorImageMapper2D::VectorImageMapper2D | ( | ) | [protected] |
Definition at line 482 of file mitkVectorImageMapper2D.cpp.
{
m_LUT = NULL;
m_Plane = vtkPlane::New();
m_Cutter = vtkCutter::New();
m_Cutter->SetCutFunction( m_Plane );
m_Cutter->GenerateValues( 1, 0, 1 );
}
| mitk::VectorImageMapper2D::~VectorImageMapper2D | ( | ) | [protected, virtual] |
| virtual const char* mitk::VectorImageMapper2D::GetClassName | ( | ) | const [virtual] |
Reimplemented from mitk::Mapper2D.
| int mitk::VectorImageMapper2D::GetCurrentTimeStep | ( | mitk::BaseData * | data, |
| mitk::BaseRenderer * | renderer | ||
| ) | [protected] |
Definition at line 503 of file mitkVectorImageMapper2D.cpp.
References mitk::BaseRenderer::GetCurrentWorldGeometry2D(), mitk::Geometry3D::GetTimeBounds(), mitk::TimeSlicedGeometry::GetTimeSteps(), mitk::BaseData::GetUpdatedTimeSlicedGeometry(), mitk::TimeSlicedGeometry::IsValidTime(), and mitk::TimeSlicedGeometry::MSToTimeStep().
{
//
// get the TimeSlicedGeometry of the input object
//
const TimeSlicedGeometry * dataTimeGeometry = data->GetUpdatedTimeSlicedGeometry();
if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->GetTimeSteps() == 0 ) )
{
itkWarningMacro( << "geometry of the given data object isn't a mitk::TimeSlicedGeometry, or the number of time steps is 0!" );
return 0;
}
//
// get the world time
//
Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
assert( worldGeometry.IsNotNull() );
ScalarType time = worldGeometry->GetTimeBounds() [ 0 ];
//
// convert the world time to time steps of the input object
//
int timestep = 0;
if ( time > ScalarTypeNumericTraits::NonpositiveMin() )
timestep = dataTimeGeometry->MSToTimeStep( time );
if ( dataTimeGeometry->IsValidTime( timestep ) == false )
{
itkWarningMacro( << timestep << " is not a valid time of the given data object!" );
return 0;
}
return timestep;
}
| virtual const mitk::Image* mitk::VectorImageMapper2D::GetImage | ( | ) | [virtual] |
| const mitk::Image * mitk::VectorImageMapper2D::GetInput | ( | void | ) |
Definition at line 63 of file mitkVectorImageMapper2D.cpp.
References mitk::Mapper::GetData(), and m_Image.
{
if ( m_Image.IsNotNull() )
return m_Image;
else
return dynamic_cast<const mitk::Image*>( this->GetData() );
}
| static Pointer mitk::VectorImageMapper2D::New | ( | ) | [static] |
Referenced by QmitkDeformableRegistrationView::Calculate(), QmitkDiffusionTensorEstimation::DirectionVolumesLoadButton(), QmitkDiffusionTensorEstimation::QBallStandardAlgorithmsDeconvolutionButton(), QmitkDiffusionTensorEstimation::QBallStandardAlgorithmsDirectionButton(), QmitkDiffusionTensorEstimation::StandardAlgorithmsDirectionButton(), and QmitkBasicImageProcessing::StartButtonClicked().
| void mitk::VectorImageMapper2D::Paint | ( | mitk::BaseRenderer * | renderer ) | [virtual] |
Do the painting into the renderer.
Implements mitk::GLMapper2D.
Definition at line 72 of file mitkVectorImageMapper2D.cpp.
References mitk::ColorProperty::GetColor(), mitk::BaseRenderer::GetCurrentWorldGeometry2D(), mitk::BaseRenderer::GetDisplayGeometry(), mitk::LookupTableProperty::GetLookupTable(), mitk::Geometry3D::GetOrigin(), mitk::GenericProperty< T >::GetValue(), mitk::LookupTable::GetVtkLookupTable(), min, vtkMaskedGlyph3D::New(), vtkMaskedGlyph3D::SetInputConnection(), and vtkMaskedGlyph3D::SetRandomMode().
{
//std::cout << "2d vector mapping..." << std::endl;
if ( IsVisible( renderer ) == false )
return ;
mitk::Image::Pointer input = const_cast<mitk::Image*>( this->GetInput() );
if ( input.IsNull() )
return ;
mitk::PlaneGeometry::Pointer worldPlaneGeometry2D = dynamic_cast< mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>( renderer->GetCurrentWorldGeometry2D() ) );
assert( worldPlaneGeometry2D.IsNotNull() );
vtkImageData* vtkImage = input->GetVtkImageData( this->GetCurrentTimeStep( input, renderer ) );
//
// set up the cutter orientation according to the current geometry of
// the renderers plane
//
Point3D point;
Vector3D normal;
Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );
if ( worldPlaneGeometry.IsNotNull() )
{
// set up vtkPlane according to worldGeometry
point = worldPlaneGeometry->GetOrigin();
normal = worldPlaneGeometry->GetNormal(); normal.Normalize();
m_Plane->SetTransform( (vtkAbstractTransform*)NULL );
}
else
{
itkWarningMacro( << "worldPlaneGeometry is NULL!" );
return ;
}
vtkFloatingPointType vp[ 3 ], vp_slice[ 3 ], vnormal[ 3 ];
vnl2vtk( point.Get_vnl_vector(), vp );
vnl2vtk( normal.Get_vnl_vector(), vnormal );
//std::cout << "Origin: " << vp[0] <<" "<< vp[1] <<" "<< vp[2] << std::endl;
//std::cout << "Normal: " << vnormal[0] <<" "<< vnormal[1] <<" "<< vnormal[2] << std::endl;
//normally, we would need to transform the surface and cut the transformed surface with the cutter.
//This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
//@todo It probably does not work for scaling operations yet:scaling operations have to be
//dealed with after the cut is performed by scaling the contour.
vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform();
vtkTransform* world2vtk = vtkTransform::New();
world2vtk->Identity();
world2vtk->Concatenate(vtktransform->GetLinearInverse());
double myscale[3];
world2vtk->GetScale(myscale);
world2vtk->PostMultiply();
world2vtk->Scale(1/myscale[0],1/myscale[1],1/myscale[2]);
world2vtk->TransformPoint( vp, vp );
world2vtk->TransformNormalAtPoint( vp, vnormal, vnormal );
world2vtk->Delete();
// vtk works in axis align coords
// thus the normal also must be axis align, since
// we do not allow arbitrary cutting through volume
//
// vnormal should already be axis align, but in order
// to get rid of precision effects, we set the two smaller
// components to zero here
int dims[3];
vtkImage->GetDimensions(dims);
double spac[3];
vtkImage->GetSpacing(spac);
vp_slice[0] = vp[0];
vp_slice[1] = vp[1];
vp_slice[2] = vp[2];
if(fabs(vnormal[0]) > fabs(vnormal[1]) && fabs(vnormal[0]) > fabs(vnormal[2]) )
{
if(fabs(vp_slice[0]/spac[0]) < 0.4)
vp_slice[0] = 0.4*spac[0];
if(fabs(vp_slice[0]/spac[0]) > (dims[0]-1)-0.4)
vp_slice[0] = ((dims[0]-1)-0.4)*spac[0];
vnormal[1] = 0;
vnormal[2] = 0;
}
if(fabs(vnormal[1]) > fabs(vnormal[0]) && fabs(vnormal[1]) > fabs(vnormal[2]) )
{
if(fabs(vp_slice[1]/spac[1]) < 0.4)
vp_slice[1] = 0.4*spac[1];
if(fabs(vp_slice[1]/spac[1]) > (dims[1]-1)-0.4)
vp_slice[1] = ((dims[1]-1)-0.4)*spac[1];
vnormal[0] = 0;
vnormal[2] = 0;
}
if(fabs(vnormal[2]) > fabs(vnormal[1]) && fabs(vnormal[2]) > fabs(vnormal[0]) )
{
if(fabs(vp_slice[2]/spac[2]) < 0.4)
vp_slice[2] = 0.4*spac[2];
if(fabs(vp_slice[2]/spac[2]) > (dims[2]-1)-0.4)
vp_slice[2] = ((dims[2]-1)-0.4)*spac[2];
vnormal[0] = 0;
vnormal[1] = 0;
}
m_Plane->SetOrigin( vp_slice );
m_Plane->SetNormal( vnormal );
vtkPolyData* cuttedPlane;
if(!( (dims[0] == 1 && vnormal[0] != 0) ||
(dims[1] == 1 && vnormal[1] != 0) ||
(dims[2] == 1 && vnormal[2] != 0) ))
{
m_Cutter->SetCutFunction( m_Plane );
m_Cutter->SetInput( vtkImage );
m_Cutter->GenerateCutScalarsOff();
m_Cutter->Update();
cuttedPlane = m_Cutter->GetOutput();
}
else
{
// cutting of a 2D-Volume does not work,
// so we have to build up our own polydata object
cuttedPlane = vtkPolyData::New();
vtkPoints* points = vtkPoints::New();
points->SetNumberOfPoints(vtkImage->GetNumberOfPoints());
for(int i=0; i<vtkImage->GetNumberOfPoints(); i++)
points->SetPoint(i, vtkImage->GetPoint(i));
cuttedPlane->SetPoints(points);
vtkFloatArray* pointdata = vtkFloatArray::New();
int comps = vtkImage->GetPointData()->GetScalars()->GetNumberOfComponents();
pointdata->SetNumberOfComponents(comps);
int tuples = vtkImage->GetPointData()->GetScalars()->GetNumberOfTuples();
pointdata->SetNumberOfTuples(tuples);
for(int i=0; i<tuples; i++)
pointdata->SetTuple(i,vtkImage->GetPointData()->GetScalars()->GetTuple(i));
pointdata->SetName( "vector" );
cuttedPlane->GetPointData()->AddArray(pointdata);
}
if ( cuttedPlane->GetNumberOfPoints() != 0)
{
//
// make sure, that we have point data with more than 1 component (as vectors)
//
vtkPointData * pointData = cuttedPlane->GetPointData();
if ( pointData == NULL )
{
itkWarningMacro( << "no point data associated with cutters result!" );
return ;
}
if ( pointData->GetNumberOfArrays() == 0 )
{
itkWarningMacro( << "point data returned by cutter doesn't have any arrays associated!" );
return ;
}
else if ( pointData->GetArray(0)->GetNumberOfComponents() <= 1)
{
itkWarningMacro( << "number of components <= 1!" );
return;
}
else if ( pointData->GetArrayName( 0 ) == NULL )
{
pointData->GetArray( 0 ) ->SetName( "vector" );
//std::cout << "array name = vectors now" << std::endl;
}
//std::cout << " projecting..."<< std::endl;
//
// constrain the vectors to lie on the plane, which means to remove the vector component,
// which is orthogonal to the plane.
//
vtkIdType numPoints, pointId;
numPoints = cuttedPlane->GetNumberOfPoints();
vtkDataArray* inVectors = cuttedPlane->GetPointData()->GetVectors( "vector" );
assert( inVectors != NULL );
vtkFloatArray* vectorMagnitudes = vtkFloatArray::New();
vectorMagnitudes->SetName("vectorMagnitudes");
vectorMagnitudes->SetNumberOfComponents(1);
vectorMagnitudes->SetNumberOfValues(numPoints);
vectorMagnitudes->SetNumberOfTuples(numPoints);
vtkFloatingPointType inVector[ 3 ], outVector[3], wnormal[3]; //, tmpVector[ 3 ], outVector[ 3 ];
vtkFloatingPointType k = 0.0;
vnl2vtk( normal.Get_vnl_vector(), wnormal );
vtkMath::Normalize( wnormal );
bool normalizeVecs;
m_DataNode->GetBoolProperty( "NormalizeVecs", normalizeVecs );
for ( pointId = 0; pointId < numPoints; ++pointId )
{
inVectors->GetTuple( pointId, inVector );
if(normalizeVecs)
{
vnl_vector<double> tmp(3);
vtk2vnl(inVector, tmp);
tmp.normalize();
vnl2vtk(tmp, inVector);
}
k = vtkMath::Dot( wnormal, inVector );
// Remove non orthogonal component.
outVector[ 0 ] = inVector[ 0 ] - ( wnormal[ 0 ] * k );
outVector[ 1 ] = inVector[ 1 ] - ( wnormal[ 1 ] * k );
outVector[ 2 ] = inVector[ 2 ] - ( wnormal[ 2 ] * k );
inVectors->SetTuple( pointId, outVector );
// ?? this was set to norm(inVector) before, but outVector made more sense to me
vectorMagnitudes->SetValue( pointId, vtkMath::Norm( outVector ) );
//std::cout << "method old: " << inVector[0] <<", " << inVector[1] << ", "<<inVector[2] << ", method new: " << outVector[0] << ", "<< outVector[1] << ", "<< outVector[2] << std::endl;
}
pointData->AddArray(vectorMagnitudes);
pointData->CopyAllOn();
//pointData->PrintSelf(std::cout, vtkIndent(4));
//std::cout << " ...done!"<< std::endl;
//std::cout << " glyphing..."<< std::endl;
// call glyph2D to generate 2D glyphs for each of the
// vectors
vtkGlyphSource2D* glyphSource = vtkGlyphSource2D::New();
//glyphSource->SetGlyphTypeToDash();
glyphSource->DashOn();
//glyphSource->SetScale( 0.1 );
//glyphSource->SetScale2( .5 );
//glyphSource->SetCenter( 0.5, 0.5, 0.5 );
glyphSource->CrossOff();
//glyphSource->FilledOff();
//glyphSource->Update();
double spacing[3];
vtkImage->GetSpacing(spacing);
double min = spacing[0];
min = min > spacing[1] ? spacing[1] : min;
min = min > spacing[2] ? spacing[2] : min;
float scale = 1;
mitk::FloatProperty::Pointer mitkScaleProp = dynamic_cast<mitk::FloatProperty*>(GetDataNode()->GetProperty("Scale"));
if (mitkScaleProp.IsNotNull())
{
scale = mitkScaleProp->GetValue();
}
vtkMaskedGlyph3D* glyphGenerator = vtkMaskedGlyph3D::New();
glyphGenerator->SetSource( glyphSource->GetOutput() );
glyphGenerator->SetInputConnection(cuttedPlane->GetProducerPort());
glyphGenerator->SetInputArrayToProcess (1, 0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector");
glyphGenerator->SetVectorModeToUseVector();
glyphGenerator->OrientOn();
glyphGenerator->SetScaleFactor( min*scale );
glyphGenerator->SetUseMaskPoints( true );
glyphGenerator->SetRandomMode( true );
glyphGenerator->SetMaximumNumberOfPoints( 128*128 );
glyphGenerator->Update();
vtkLookupTable* vtkLut = NULL;
mitk::LookupTableProperty::Pointer mitkLutProp = dynamic_cast<mitk::LookupTableProperty*>(GetDataNode()->GetProperty("LookupTable"));
if (mitkLutProp.IsNotNull())
{
vtkLut = mitkLutProp->GetLookupTable()->GetVtkLookupTable();
}
mitk::Color color;
mitk::ColorProperty::Pointer mitkColorProp = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty("color"));
if (mitkColorProp.IsNotNull())
{
color = mitkColorProp->GetColor();
}
else
{
color.SetRed(0);
color.SetBlue(1);
color.SetGreen(0);
}
float lwidth = 1;
mitk::FloatProperty::Pointer mitkLWidthProp = dynamic_cast<mitk::FloatProperty*>(GetDataNode()->GetProperty("LineWidth"));
if (mitkLWidthProp.IsNotNull())
{
lwidth = mitkLWidthProp->GetValue();
}
vtkTransform* trafo = vtkTransform::New();
trafo->Identity();
trafo->Concatenate(vtktransform);
trafo->PreMultiply();
double myscale[3];
trafo->GetScale(myscale);
trafo->Scale(1/myscale[0],1/myscale[1],1/myscale[2]);
this->PaintCells( glyphGenerator->GetOutput(), renderer->GetCurrentWorldGeometry2D(), renderer->GetDisplayGeometry(), trafo, renderer, NULL/*vtkLut*/, color, lwidth, spacing );
vectorMagnitudes->Delete();
glyphSource->Delete();
glyphGenerator->Delete();
trafo->Delete();
}
else
{
std::cout << " no points cutted!"<< std::endl;
}
//std::cout << "...done!" << std::endl;
}
| void mitk::VectorImageMapper2D::PaintCells | ( | vtkPolyData * | contour, |
| const Geometry2D * | worldGeometry, | ||
| const DisplayGeometry * | displayGeometry, | ||
| vtkLinearTransform * | vtktransform, | ||
| mitk::BaseRenderer * | renderer, | ||
| vtkScalarsToColors * | lut, | ||
| mitk::Color | color, | ||
| float | lwidth, | ||
| vtkFloatingPointType * | spacing | ||
| ) | [virtual] |
Definition at line 384 of file mitkVectorImageMapper2D.cpp.
References GL_LINE_LOOP, glBegin(), glColor3f(), glEnd(), glLineWidth(), glVertex2f(), mitk::Geometry2D::Map(), and mitk::DisplayGeometry::WorldToDisplay().
{
vtkPoints * points = glyphs->GetPoints();
vtkPointData * vpointdata = glyphs->GetPointData();
vtkDataArray* vpointscalars = vpointdata->GetArray("vectorMagnitudes");
//vtkDataArray* vpointpositions = vpointdata->GetArray("pointPositions");
assert(vpointscalars != NULL);
//std::cout << " Scalars range 2d:" << vpointscalars->GetRange()[0] << " " << vpointscalars->GetRange()[0] << std::endl;
Point3D p;
Point2D p2d;
vtkIdList* idList;
vtkCell* cell;
vtkFloatingPointType offset[3];
for (unsigned int i = 0; i < 3; ++i)
{
offset[i] = 0;
}
vtkIdType numCells = glyphs->GetNumberOfCells();
for ( vtkIdType cellId = 0; cellId < numCells; ++cellId )
{
vtkFloatingPointType vp[ 3 ];
cell = glyphs->GetCell( cellId );
idList = cell->GetPointIds();
int numPoints = idList->GetNumberOfIds();
if(numPoints == 1)
{
//take transformation via vtktransform into account
vtkFloatingPointType pos[ 3 ],vp_raster[3];
points->GetPoint( idList->GetId( 0 ), vp );
vp_raster[0] = vtkMath::Round(vp[0]/spacing[0])*spacing[0];
vp_raster[1] = vtkMath::Round(vp[1]/spacing[1])*spacing[1];
vp_raster[2] = vtkMath::Round(vp[2]/spacing[2])*spacing[2];
vtktransform->TransformPoint( vp_raster, pos );
offset[0] = pos[0] - vp[0];
offset[1] = pos[1] - vp[1];
offset[2] = pos[2] - vp[2];
}
else
{
glLineWidth(lwidth);
glBegin ( GL_LINE_LOOP );
for ( int pointNr = 0; pointNr < numPoints ;++pointNr )
{
points->GetPoint( idList->GetId( pointNr ), vp );
vp[0] = vp[0] + offset[0];
vp[1] = vp[1] + offset[1];
vp[2] = vp[2] + offset[2];
vtkFloatingPointType tmp[ 3 ];
vtktransform->TransformPoint( vp,tmp );
vtk2itk( vp, p );
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map( p, p2d );
//convert point (until now mm and in worldcoordinates) to display coordinates (units )
displayGeometry->WorldToDisplay( p2d, p2d );
if ( lut != NULL )
{
// color each point according to point data
vtkFloatingPointType * color;
if ( vpointscalars != NULL )
{
vpointscalars->GetComponent( pointNr, 0 );
color = lut->GetColor( vpointscalars->GetComponent( idList->GetId( pointNr ), 0 ) );
glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
}
}
else
{
glColor3f( color.GetRed(), color.GetGreen(), color.GetBlue() );
}
//std::cout << idList->GetId( pointNr )<< ": " << p2d[0]<< " "<< p2d[1] << std::endl;
//draw the line
glVertex2f( p2d[ 0 ], p2d[ 1 ] );
}
glEnd ();
}
}
}
| virtual void mitk::VectorImageMapper2D::SetImage | ( | const mitk::Image * | _arg ) | [virtual] |
Explicitly set an vector image. This image will be used for rendering instead of the image returned by GetData()
vtkCutter* mitk::VectorImageMapper2D::m_Cutter [protected] |
Definition at line 88 of file mitkVectorImageMapper2D.h.
Definition at line 82 of file mitkVectorImageMapper2D.h.
Referenced by GetInput().
vtkLookupTable* mitk::VectorImageMapper2D::m_LUT [protected] |
Definition at line 84 of file mitkVectorImageMapper2D.h.
vtkPlane* mitk::VectorImageMapper2D::m_Plane [protected] |
Definition at line 86 of file mitkVectorImageMapper2D.h.
1.7.2