00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkImageMapperGL2D.h"
00019 #include "widget.h"
00020 #include "picimage.h"
00021 #include "pic2vtk.h"
00022 #include "mitkTimeSlicedGeometry.h"
00023 #include "mitkPlaneGeometry.h"
00024 #include "mitkDataNode.h"
00025 #include "mitkVtkPropRenderer.h"
00026 #include "mitkLookupTableProperty.h"
00027 #include "mitkProperties.h"
00028 #include "mitkLevelWindowProperty.h"
00029 #include "mitkVtkResliceInterpolationProperty.h"
00030 #include "mitkVolumeCalculator.h"
00031
00032 #include "mitkAbstractTransformGeometry.h"
00033 #include "mitkDataNodeFactory.h"
00034
00035 #include "mitkResliceMethodProperty.h"
00036
00037 #include <vtkTransform.h>
00038 #include <vtkGeneralTransform.h>
00039 #include <vtkMatrix4x4.h>
00040 #include <vtkLookupTable.h>
00041 #include <vtkImageData.h>
00042 #include <vtkPoints.h>
00043 #include <vtkFloatArray.h>
00044 #include <vtkLinearTransform.h>
00045 #include <vtkImageReslice.h>
00046 #include <vtkImageChangeInformation.h>
00047
00048 #include "vtkMitkThickSlicesFilter.h"
00049 #include "itkRGBAPixel.h"
00050
00051
00052 int mitk::ImageMapperGL2D::numRenderer = 0;
00053
00054 mitk::ImageMapperGL2D::ImageMapperGL2D()
00055 {
00056 }
00057
00058
00059 mitk::ImageMapperGL2D::~ImageMapperGL2D()
00060 {
00061 this->Clear();
00062 this->InvokeEvent( itk::DeleteEvent() );
00063 }
00064
00065
00066 void
00067 mitk::ImageMapperGL2D::Paint( mitk::BaseRenderer *renderer )
00068 {
00069 if ( !this->IsVisible( renderer ) )
00070 {
00071 return;
00072 }
00073
00074 this->Update( renderer );
00075
00076 RendererInfo &rendererInfo = this->AccessRendererInfo( renderer );
00077 iil4mitkPicImage *image = rendererInfo.Get_iil4mitkImage();
00078
00079 if ( ( image == NULL ) || ( image->image() == NULL ) )
00080 {
00081 return;
00082 }
00083
00084 const mitk::DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
00085
00086 Vector2D topLeft = displayGeometry->GetOriginInMM();
00087 Vector2D bottomRight = topLeft + displayGeometry->GetSizeInMM();
00088
00089 topLeft[0] *= rendererInfo.m_PixelsPerMM[0];
00090 topLeft[1] *= rendererInfo.m_PixelsPerMM[1];
00091
00092 bottomRight[0] *= rendererInfo.m_PixelsPerMM[0];
00093 bottomRight[1] *= rendererInfo.m_PixelsPerMM[1];
00094
00095 topLeft += rendererInfo.m_Overlap;
00096 bottomRight += rendererInfo.m_Overlap;
00097
00098 Vector2D diag = ( topLeft - bottomRight );
00099
00100
00101 glMatrixMode( GL_PROJECTION );
00102 glLoadIdentity();
00103 glOrtho( topLeft[0], bottomRight[0], topLeft[1], bottomRight[1], 0.0, 1.0 );
00104 glMatrixMode( GL_MODELVIEW );
00105 glDepthMask(GL_FALSE);
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 GLdouble eqn0[4] = {0.0, 1.0, 0.0, 0.0};
00131 GLdouble eqn1[4] = {1.0, 0.0, 0.0, 0.0};
00132 GLdouble eqn2[4] = {-1.0, 0.0 , 0.0, image->width()};
00133 GLdouble eqn3[4] = {0, -1.0, 0.0, image->height() };
00134
00135 glClipPlane( GL_CLIP_PLANE0, eqn0 );
00136 glEnable( GL_CLIP_PLANE0 );
00137 glClipPlane( GL_CLIP_PLANE1, eqn1 );
00138 glEnable( GL_CLIP_PLANE1 );
00139 glClipPlane( GL_CLIP_PLANE2, eqn2 );
00140 glEnable( GL_CLIP_PLANE2 );
00141 glClipPlane( GL_CLIP_PLANE3, eqn3 );
00142 glEnable( GL_CLIP_PLANE3 );
00143
00144
00145
00146 image->setInterpolation( rendererInfo.m_TextureInterpolation );
00147
00148
00149 image->display( renderer->GetRenderWindow() );
00150
00151
00152
00153 glDisable( GL_CLIP_PLANE0 );
00154 glDisable( GL_CLIP_PLANE1 );
00155 glDisable( GL_CLIP_PLANE2 );
00156 glDisable( GL_CLIP_PLANE3 );
00157
00158
00159
00160 bool shouldShowVolume = false, binary = false;
00161 float segmentationVolume = -1.0;
00162
00163 mitk::DataNode *node = this->GetDataNode();
00164 mitk::Image* mitkimage = dynamic_cast<mitk::Image*>(node->GetData());
00165
00166
00167
00168
00169
00170
00171 if (
00172 (node->GetBoolProperty("showVolume", shouldShowVolume)) &&
00173 (shouldShowVolume) &&
00174 (
00175 (node->GetFloatProperty("volume", segmentationVolume) )
00176 ||
00177 (mitkimage != NULL &&
00178 mitkimage->GetDimension() >= 3 &&
00179 node->GetBoolProperty("binary", binary) &&
00180 binary)
00181 )
00182 )
00183 {
00184
00185 mitkIpPicDescriptor* pic = image->image();
00186
00187
00188
00189 int s_x = 0;
00190 int s_y = 0;
00191 int s_n = 0;
00192
00193 for(unsigned int y=0;y<pic->n[1];y++)
00194 for(unsigned int x=0;x<pic->n[0];x++)
00195 {
00196 bool set=false;
00197 switch ( pic->bpe )
00198 {
00199 case 8: {
00200 mitkIpInt1_t *current = static_cast< mitkIpInt1_t *>( pic->data );
00201 current += y*pic->n[0] + x;
00202 if(current[0]) set=true;
00203 break; }
00204 case 16: {
00205 mitkIpInt2_t *current = static_cast< mitkIpInt2_t *>( pic->data );
00206 current += y*pic->n[0] + x;
00207 if(current[0]) set=true;
00208 break; }
00209 case 24: {
00210 mitkIpInt1_t *current = static_cast< mitkIpInt1_t *>( pic->data );
00211 current += ( y*pic->n[0] + x )*3;
00212 if(current[0]||current[1]||current[2]) set=true;
00213 break; }
00214 }
00215 if(set)
00216 {
00217 s_x+=x;
00218 s_y+=y;
00219 s_n++;
00220 }
00221 }
00222
00223
00224 if ( s_n>0 )
00225 {
00226
00227 if( segmentationVolume <= 0 )
00228 {
00229
00230 if( mitkimage->GetScalarValueMax( renderer->GetTimeStep() ) == 1 )
00231 {
00232
00233 segmentationVolume = mitk::VolumeCalculator::ComputeVolume(
00234 mitkimage->GetSlicedGeometry()->GetSpacing(), mitkimage->GetCountOfMaxValuedVoxelsNoRecompute(renderer->GetTimeStep()));
00235 }
00236 }
00237
00238
00239 std::stringstream volumeString;
00240 volumeString << std::fixed << std::setprecision(1) << segmentationVolume;
00241
00242 std::string unit;
00243 if (node->GetStringProperty("volume annotation unit", unit))
00244 {
00245 volumeString << " " << unit;
00246 }
00247 else
00248 {
00249 volumeString << " ml";
00250 }
00251
00252
00253
00254 mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
00255
00256
00257 Point2D pt2D;
00258
00259 pt2D[0] = s_x/double(s_n);
00260 pt2D[1] = s_y/double(s_n);
00261
00262
00263 const Geometry2D *worldGeometry = renderer->GetCurrentWorldGeometry2D();
00264
00265
00266 worldGeometry->IndexToWorld( pt2D, pt2D );
00267 displayGeometry->WorldToDisplay( pt2D, pt2D );
00268
00269 mitk::ColorProperty::Pointer annotationColorProp;
00270 mitk::Color annotationColor;
00271 annotationColor.Set(0,1,0);
00272
00273 if (node->GetProperty(annotationColorProp, "volume annotation color"))
00274 {
00275 annotationColor = annotationColorProp->GetColor();
00276 }
00277
00278 OpenGLrenderer->WriteSimpleText(volumeString.str(), pt2D[0]+1, pt2D[1]-1,0,0,0);
00279 OpenGLrenderer->WriteSimpleText(volumeString.str(), pt2D[0] , pt2D[1] ,annotationColor.GetRed()
00280 ,annotationColor.GetGreen()
00281 ,annotationColor.GetBlue());
00282 }
00283
00284 }
00285
00286
00287 glMatrixMode( GL_PROJECTION );
00288 glLoadIdentity();
00289 glOrtho(
00290 0.0, displayGeometry->GetDisplayWidth(),
00291 0.0, displayGeometry->GetDisplayHeight(),
00292 0.0, 1.0
00293 );
00294
00295 glDepthMask(GL_TRUE);
00296
00297
00298 }
00299
00300
00301 const mitk::ImageMapperGL2D::InputImageType *
00302 mitk::ImageMapperGL2D::GetInput( void )
00303 {
00304 return static_cast< const mitk::ImageMapperGL2D::InputImageType * >( this->GetData() );
00305 }
00306
00307
00308 int
00309 mitk::ImageMapperGL2D::GetAssociatedChannelNr( mitk::BaseRenderer *renderer )
00310 {
00311 RendererInfo &rendererInfo = this->AccessRendererInfo( renderer );
00312
00313 return rendererInfo.GetRendererID();
00314 }
00315
00316
00317 void
00318 mitk::ImageMapperGL2D::GenerateData( mitk::BaseRenderer *renderer )
00319 {
00320 mitk::Image *input = const_cast< mitk::ImageMapperGL2D::InputImageType * >(
00321 this->GetInput()
00322 );
00323 input->Update();
00324
00325 if ( input == NULL )
00326 {
00327 return;
00328 }
00329
00330 RendererInfo &rendererInfo = this->AccessRendererInfo( renderer );
00331 rendererInfo.Squeeze();
00332
00333
00334 iil4mitkPicImage *image = new iil4mitkPicImage( 512 );
00335 rendererInfo.Set_iil4mitkImage( image );
00336
00337 this->ApplyProperties( renderer );
00338
00339 const Geometry2D *worldGeometry = renderer->GetCurrentWorldGeometry2D();
00340
00341 if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->GetReferenceGeometry() ))
00342 {
00343 return;
00344 }
00345
00346
00347 if ( ! input->IsVolumeSet( this->GetTimestep() ) ) return;
00348
00349 Image::RegionType requestedRegion = input->GetLargestPossibleRegion();
00350 requestedRegion.SetIndex( 3, this->GetTimestep() );
00351 requestedRegion.SetSize( 3, 1 );
00352 requestedRegion.SetSize( 4, 1 );
00353 input->SetRequestedRegion( &requestedRegion );
00354 input->Update();
00355
00356 vtkImageData* inputData = input->GetVtkImageData( this->GetTimestep() );
00357
00358 if ( inputData == NULL )
00359 {
00360 return;
00361 }
00362
00363 vtkFloatingPointType spacing[3];
00364 inputData->GetSpacing( spacing );
00365
00366
00367 mitk::ScalarType widthInMM, heightInMM;
00368
00369
00370 Point3D origin;
00371 Vector3D right, bottom, normal;
00372 Vector3D rightInIndex, bottomInIndex;
00373
00374
00375 const TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry();
00376 const Geometry3D* inputGeometry = inputTimeGeometry->GetGeometry3D( this->GetTimestep() );
00377
00378 ScalarType mmPerPixel[2];
00379
00380
00381
00382
00383 vtkFloatingPointType bounds[6];
00384 bool boundsInitialized = false;
00385
00386 for ( int i = 0; i < 6; ++i )
00387 {
00388 bounds[i] = 0.0;
00389 }
00390
00391
00392 if ( dynamic_cast< const PlaneGeometry * >( worldGeometry ) != NULL )
00393 {
00394 const PlaneGeometry *planeGeometry =
00395 static_cast< const PlaneGeometry * >( worldGeometry );
00396
00397 origin = planeGeometry->GetOrigin();
00398 right = planeGeometry->GetAxisVector( 0 );
00399 bottom = planeGeometry->GetAxisVector( 1 );
00400 normal = planeGeometry->GetNormal();
00401
00402 bool inPlaneResampleExtentByGeometry = false;
00403 GetDataNode()->GetBoolProperty(
00404 "in plane resample extent by geometry",
00405 inPlaneResampleExtentByGeometry, renderer
00406 );
00407
00408 if ( inPlaneResampleExtentByGeometry )
00409 {
00410
00411
00412
00413 rendererInfo.m_Extent[0] = worldGeometry->GetExtent( 0 );
00414 rendererInfo.m_Extent[1] = worldGeometry->GetExtent( 1 );
00415 }
00416 else
00417 {
00418
00419
00420
00421
00422 inputGeometry->WorldToIndex( origin, right, rightInIndex );
00423 inputGeometry->WorldToIndex( origin, bottom, bottomInIndex );
00424 rendererInfo.m_Extent[0] = rightInIndex.GetNorm();
00425 rendererInfo.m_Extent[1] = bottomInIndex.GetNorm();
00426 }
00427
00428
00429
00430
00431 widthInMM = worldGeometry->GetExtentInMM( 0 );
00432 heightInMM = worldGeometry->GetExtentInMM( 1 );
00433
00434 mmPerPixel[0] = widthInMM / rendererInfo.m_Extent[0];
00435 mmPerPixel[1] = heightInMM / rendererInfo.m_Extent[1];
00436
00437 right.Normalize();
00438 bottom.Normalize();
00439 normal.Normalize();
00440
00441 origin += right * ( mmPerPixel[0] * 0.5 );
00442 origin += bottom * ( mmPerPixel[1] * 0.5 );
00443
00444 widthInMM -= mmPerPixel[0];
00445 heightInMM -= mmPerPixel[1];
00446
00447
00448 rendererInfo.m_Reslicer->SetResliceTransform(
00449 inputGeometry->GetVtkTransform()->GetLinearInverse() );
00450
00451
00452 rendererInfo.m_Reslicer->SetBackgroundLevel( -32768 );
00453
00454
00455
00456
00457
00458
00459
00460
00461 if ( worldGeometry->GetReferenceGeometry() )
00462 {
00463 rendererInfo.m_ReferenceGeometry = worldGeometry->GetReferenceGeometry();
00464
00465
00466
00467
00468
00469 boundsInitialized = this->CalculateClippedPlaneBounds(
00470 rendererInfo.m_ReferenceGeometry, planeGeometry, bounds );
00471 }
00472 }
00473
00474
00475 else if ( dynamic_cast< const AbstractTransformGeometry * >( worldGeometry ) )
00476 {
00477 const mitk::AbstractTransformGeometry* abstractGeometry =
00478 dynamic_cast< const AbstractTransformGeometry * >(worldGeometry);
00479
00480 rendererInfo.m_Extent[0] = abstractGeometry->GetParametricExtent(0);
00481 rendererInfo.m_Extent[1] = abstractGeometry->GetParametricExtent(1);
00482
00483 widthInMM = abstractGeometry->GetParametricExtentInMM(0);
00484 heightInMM = abstractGeometry->GetParametricExtentInMM(1);
00485
00486 mmPerPixel[0] = widthInMM / rendererInfo.m_Extent[0];
00487 mmPerPixel[1] = heightInMM / rendererInfo.m_Extent[1];
00488
00489 origin = abstractGeometry->GetPlane()->GetOrigin();
00490
00491 right = abstractGeometry->GetPlane()->GetAxisVector(0);
00492 right.Normalize();
00493
00494 bottom = abstractGeometry->GetPlane()->GetAxisVector(1);
00495 bottom.Normalize();
00496
00497 normal = abstractGeometry->GetPlane()->GetNormal();
00498 normal.Normalize();
00499
00500
00501
00502 vtkGeneralTransform *composedResliceTransform = vtkGeneralTransform::New();
00503 composedResliceTransform->Identity();
00504 composedResliceTransform->Concatenate(
00505 inputGeometry->GetVtkTransform()->GetLinearInverse() );
00506 composedResliceTransform->Concatenate(
00507 abstractGeometry->GetVtkAbstractTransform()
00508 );
00509
00510 rendererInfo.m_Reslicer->SetResliceTransform( composedResliceTransform );
00511 composedResliceTransform->UnRegister( NULL );
00512
00513
00514
00515 rendererInfo.m_Reslicer->SetBackgroundLevel( -1023 );
00516 }
00517 else
00518 {
00519 return;
00520 }
00521
00522
00523
00524 if ( (rendererInfo.m_Extent[0] <= 2) && (rendererInfo.m_Extent[1] <= 2) )
00525 {
00526 return;
00527 }
00528
00529
00530
00531 if ( (input->GetDimension() >= 3) && (input->GetDimension(2) > 1) )
00532 {
00533 VtkResliceInterpolationProperty *resliceInterpolationProperty;
00534 this->GetDataNode()->GetProperty(
00535 resliceInterpolationProperty, "reslice interpolation" );
00536
00537 int interpolationMode = VTK_RESLICE_NEAREST;
00538 if ( resliceInterpolationProperty != NULL )
00539 {
00540 interpolationMode = resliceInterpolationProperty->GetInterpolation();
00541 }
00542
00543 switch ( interpolationMode )
00544 {
00545 case VTK_RESLICE_NEAREST:
00546 rendererInfo.m_Reslicer->SetInterpolationModeToNearestNeighbor();
00547 break;
00548
00549 case VTK_RESLICE_LINEAR:
00550 rendererInfo.m_Reslicer->SetInterpolationModeToLinear();
00551 break;
00552
00553 case VTK_RESLICE_CUBIC:
00554 rendererInfo.m_Reslicer->SetInterpolationModeToCubic();
00555 break;
00556 }
00557 }
00558 else
00559 {
00560 rendererInfo.m_Reslicer->SetInterpolationModeToNearestNeighbor();
00561 }
00562
00563 int thickSlicesMode = 0;
00564
00565 int thickSlicesNum = 1;
00566
00567
00568 if( inputData->GetNumberOfScalarComponents() == 1 )
00569 {
00570 DataNode *dn=renderer->GetCurrentWorldGeometry2DNode();
00571 if(dn)
00572 {
00573 ResliceMethodProperty *resliceMethodEnumProperty=0;
00574
00575 if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty )
00576 thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
00577
00578 IntProperty *intProperty=0;
00579 if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
00580 {
00581 thickSlicesNum = intProperty->GetValue();
00582 if(thickSlicesNum < 1) thickSlicesNum=1;
00583 if(thickSlicesNum > 10) thickSlicesNum=10;
00584 }
00585 }
00586 else
00587 {
00588 MITK_WARN << "no associated widget plane data tree node found";
00589 }
00590 }
00591
00592 rendererInfo.m_UnitSpacingImageFilter->SetInput( inputData );
00593 rendererInfo.m_Reslicer->SetInput( rendererInfo.m_UnitSpacingImageFilter->GetOutput() );
00594
00595
00596
00597 rendererInfo.m_PixelsPerMM[0] = 1.0 / mmPerPixel[0];
00598 rendererInfo.m_PixelsPerMM[1] = 1.0 / mmPerPixel[1];
00599
00600
00601 double originArray[3];
00602 itk2vtk( origin, originArray );
00603
00604 rendererInfo.m_Reslicer->SetResliceAxesOrigin( originArray );
00605
00606 double cosines[9];
00607
00608
00609 vnl2vtk( right.Get_vnl_vector(), cosines );
00610
00611
00612 vnl2vtk( bottom.Get_vnl_vector(), cosines + 3 );
00613
00614
00615 vnl2vtk( normal.Get_vnl_vector(), cosines + 6 );
00616
00617 rendererInfo.m_Reslicer->SetResliceAxesDirectionCosines( cosines );
00618
00619 int xMin, xMax, yMin, yMax;
00620 if ( boundsInitialized )
00621 {
00622
00623 xMin = static_cast< int >( bounds[0] / mmPerPixel[0] + 0.5 );
00624 xMax = static_cast< int >( bounds[1] / mmPerPixel[0] + 0.5 );
00625 yMin = static_cast< int >( bounds[2] / mmPerPixel[1] + 0.5 );
00626 yMax = static_cast< int >( bounds[3] / mmPerPixel[1] + 0.5 );
00627
00628
00629
00630 rendererInfo.m_Overlap[0] = -xMin;
00631 rendererInfo.m_Overlap[1] = -yMin;
00632 }
00633 else
00634 {
00635
00636
00637 rendererInfo.m_Overlap.Fill( 0.0 );
00638
00639 xMin = yMin = 0;
00640 xMax = static_cast< int >( rendererInfo.m_Extent[0]
00641 - rendererInfo.m_PixelsPerMM[0] + 0.5 );
00642 yMax = static_cast< int >( rendererInfo.m_Extent[1]
00643 - rendererInfo.m_PixelsPerMM[1] + 0.5 );
00644 }
00645
00646
00647
00648 if ( (xMax-xMin) * (yMax-yMin) > 4096*4096 )
00649 {
00650 return;
00651 }
00652
00653
00654
00655
00656
00657 double dataZSpacing = 1.0;
00658
00659 normal.Normalize();
00660 Vector3D normInIndex;
00661 inputGeometry->WorldToIndex( origin, normal, normInIndex );
00662
00663 if(thickSlicesMode > 0)
00664 {
00665 dataZSpacing = 1.0 / normInIndex.GetNorm();
00666 rendererInfo.m_Reslicer->SetOutputDimensionality( 3 );
00667 rendererInfo.m_Reslicer->SetOutputExtent( xMin, xMax-1, yMin, yMax-1, -thickSlicesNum, 0+thickSlicesNum );
00668 }
00669 else
00670 {
00671 rendererInfo.m_Reslicer->SetOutputDimensionality( 2 );
00672 rendererInfo.m_Reslicer->SetOutputExtent( xMin, xMax-1, yMin, yMax-1, 0, 0 );
00673 }
00674
00675 rendererInfo.m_Reslicer->SetOutputOrigin( 0.0, 0.0, 0.0 );
00676 rendererInfo.m_Reslicer->SetOutputSpacing( mmPerPixel[0], mmPerPixel[1], dataZSpacing );
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 vtkImageData* reslicedImage = 0;
00692
00693 if(thickSlicesMode>0)
00694 {
00695 rendererInfo.m_TSFilter->SetThickSliceMode( thickSlicesMode-1 );
00696 rendererInfo.m_TSFilter->SetInput( rendererInfo.m_Reslicer->GetOutput() );
00697 rendererInfo.m_TSFilter->Modified();
00698 rendererInfo.m_TSFilter->Update();
00699 reslicedImage = rendererInfo.m_TSFilter->GetOutput();
00700 }
00701 else
00702 {
00703 rendererInfo.m_Reslicer->Modified();
00704 rendererInfo.m_Reslicer->Update();
00705 reslicedImage = rendererInfo.m_Reslicer->GetOutput();
00706 }
00707
00708 if((reslicedImage == NULL) || (reslicedImage->GetDataDimension() < 1))
00709 {
00710 MITK_WARN << "reslicer returned empty image";
00711 return;
00712 }
00713
00714
00715
00716 mitkIpPicDescriptor *pic = Pic2vtk::convert( reslicedImage );
00717
00718 if (pic == NULL)
00719 {
00720 return;
00721 }
00722
00723 bool imageIs2D = true;
00724
00725 if ( pic->dim == 1 )
00726 {
00727 pic->dim = 2;
00728 pic->n[1] = 1;
00729 imageIs2D = false;
00730 }
00731 assert( pic->dim == 2 );
00732
00733 rendererInfo.m_Pic = pic;
00734
00735 if ( pic->bpe == 24 && reslicedImage->GetScalarType()==VTK_UNSIGNED_CHAR )
00736 m_iil4mitkMode = iil4mitkImage::RGB;
00737 else if ( pic->bpe == 32 && reslicedImage->GetScalarType()==VTK_UNSIGNED_CHAR )
00738 m_iil4mitkMode = iil4mitkImage::RGBA;
00739
00740 image->setImage( pic, m_iil4mitkMode );
00741 image->setInterpolation( false );
00742 image->setRegion( 0, 0, pic->n[0], pic->n[1] );
00743
00744
00745
00746 if ( imageIs2D )
00747 {
00748 if ( rendererInfo.m_Image == NULL )
00749 {
00750 rendererInfo.m_Image = vtkImageData::New();
00751 }
00752 rendererInfo.m_Image->DeepCopy( reslicedImage );
00753 rendererInfo.m_Image->Update();
00754 }
00755 else
00756 {
00757 if ( rendererInfo.m_Image != NULL )
00758 {
00759 rendererInfo.m_Image->Delete();
00760 }
00761 rendererInfo.m_Image = NULL;
00762 }
00763
00764
00765 rendererInfo.m_LastUpdateTime.Modified();
00766 }
00767
00768
00769 double
00770 mitk::ImageMapperGL2D::CalculateSpacing( const mitk::Geometry3D *geometry, const mitk::Vector3D &d ) const
00771 {
00772
00773
00774
00775
00776
00777
00778
00779 const mitk::Vector3D &spacing = geometry->GetSpacing();
00780
00781 double scaling = d[0]*d[0] / (spacing[0] * spacing[0])
00782 + d[1]*d[1] / (spacing[1] * spacing[1])
00783 + d[2]*d[2] / (spacing[2] * spacing[2]);
00784
00785 scaling = sqrt( scaling );
00786
00787 return ( sqrt( d[0]*d[0] + d[1]*d[1] + d[2]*d[2] ) / scaling );
00788 }
00789
00790 bool
00791 mitk::ImageMapperGL2D
00792 ::LineIntersectZero( vtkPoints *points, int p1, int p2,
00793 vtkFloatingPointType *bounds )
00794 {
00795 vtkFloatingPointType point1[3];
00796 vtkFloatingPointType point2[3];
00797 points->GetPoint( p1, point1 );
00798 points->GetPoint( p2, point2 );
00799
00800 if ( (point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]) )
00801 {
00802 double x, y;
00803 x = ( point1[0] * point2[2] - point1[2] * point2[0] ) / ( point2[2] - point1[2] );
00804 y = ( point1[1] * point2[2] - point1[2] * point2[1] ) / ( point2[2] - point1[2] );
00805
00806 if ( x < bounds[0] ) { bounds[0] = x; }
00807 if ( x > bounds[1] ) { bounds[1] = x; }
00808 if ( y < bounds[2] ) { bounds[2] = y; }
00809 if ( y > bounds[3] ) { bounds[3] = y; }
00810 bounds[4] = bounds[5] = 0.0;
00811 return true;
00812 }
00813 return false;
00814 }
00815
00816
00817 bool
00818 mitk::ImageMapperGL2D
00819 ::CalculateClippedPlaneBounds( const Geometry3D *boundingGeometry,
00820 const PlaneGeometry *planeGeometry, vtkFloatingPointType *bounds )
00821 {
00822
00823
00824
00825
00826
00827 const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox();
00828
00829 mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum();
00830 mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum();
00831 mitk::BoundingBox::PointType bbCenter = boundingBox->GetCenter();
00832
00833 vtkPoints *points = vtkPoints::New();
00834 if(boundingGeometry->GetImageGeometry())
00835 {
00836 points->InsertPoint( 0, bbMin[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 );
00837 points->InsertPoint( 1, bbMin[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 );
00838 points->InsertPoint( 2, bbMin[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 );
00839 points->InsertPoint( 3, bbMin[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 );
00840 points->InsertPoint( 4, bbMax[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 );
00841 points->InsertPoint( 5, bbMax[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 );
00842 points->InsertPoint( 6, bbMax[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 );
00843 points->InsertPoint( 7, bbMax[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 );
00844 }
00845 else
00846 {
00847 points->InsertPoint( 0, bbMin[0], bbMin[1], bbMin[2] );
00848 points->InsertPoint( 1, bbMin[0], bbMin[1], bbMax[2] );
00849 points->InsertPoint( 2, bbMin[0], bbMax[1], bbMax[2] );
00850 points->InsertPoint( 3, bbMin[0], bbMax[1], bbMin[2] );
00851 points->InsertPoint( 4, bbMax[0], bbMin[1], bbMin[2] );
00852 points->InsertPoint( 5, bbMax[0], bbMin[1], bbMax[2] );
00853 points->InsertPoint( 6, bbMax[0], bbMax[1], bbMax[2] );
00854 points->InsertPoint( 7, bbMax[0], bbMax[1], bbMin[2] );
00855 }
00856
00857 vtkPoints *newPoints = vtkPoints::New();
00858
00859 vtkTransform *transform = vtkTransform::New();
00860 transform->Identity();
00861 transform->Concatenate(
00862 planeGeometry->GetVtkTransform()->GetLinearInverse()
00863 );
00864
00865 transform->Concatenate( boundingGeometry->GetVtkTransform() );
00866
00867 transform->TransformPoints( points, newPoints );
00868
00869 bounds[0] = bounds[2] = 10000000.0;
00870 bounds[1] = bounds[3] = -10000000.0;
00871 bounds[4] = bounds[5] = 0.0;
00872
00873 this->LineIntersectZero( newPoints, 0, 1, bounds );
00874 this->LineIntersectZero( newPoints, 1, 2, bounds );
00875 this->LineIntersectZero( newPoints, 2, 3, bounds );
00876 this->LineIntersectZero( newPoints, 3, 0, bounds );
00877 this->LineIntersectZero( newPoints, 0, 4, bounds );
00878 this->LineIntersectZero( newPoints, 1, 5, bounds );
00879 this->LineIntersectZero( newPoints, 2, 6, bounds );
00880 this->LineIntersectZero( newPoints, 3, 7, bounds );
00881 this->LineIntersectZero( newPoints, 4, 5, bounds );
00882 this->LineIntersectZero( newPoints, 5, 6, bounds );
00883 this->LineIntersectZero( newPoints, 6, 7, bounds );
00884 this->LineIntersectZero( newPoints, 7, 4, bounds );
00885
00886
00887 points->Delete();
00888 newPoints->Delete();
00889 transform->Delete();
00890
00891 if ( (bounds[0] > 9999999.0) || (bounds[2] > 9999999.0)
00892 || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0) )
00893 {
00894 return false;
00895 }
00896 else
00897 {
00898
00899
00900 const float *planeSpacing = planeGeometry->GetFloatSpacing();
00901 bounds[0] *= planeSpacing[0];
00902 bounds[1] *= planeSpacing[0];
00903 bounds[2] *= planeSpacing[1];
00904 bounds[3] *= planeSpacing[1];
00905 bounds[4] *= planeSpacing[2];
00906 bounds[5] *= planeSpacing[2];
00907 return true;
00908 }
00909 }
00910
00911
00912
00913 void
00914 mitk::ImageMapperGL2D::GenerateAllData()
00915 {
00916 RendererInfoMap::iterator it, end = m_RendererInfo.end();
00917
00918 for ( it = m_RendererInfo.begin(); it != end; ++it)
00919 {
00920 this->Update( it->first );
00921 }
00922 }
00923
00924
00925 void
00926 mitk::ImageMapperGL2D::Clear()
00927 {
00928 RendererInfoMap::iterator it, end = m_RendererInfo.end();
00929 for ( it = m_RendererInfo.begin(); it != end; ++it )
00930 {
00931 it->second.RemoveObserver();
00932 it->second.Squeeze();
00933 }
00934 m_RendererInfo.clear();
00935 }
00936
00937
00938 void
00939 mitk::ImageMapperGL2D::ApplyProperties(mitk::BaseRenderer* renderer)
00940 {
00941 RendererInfo &rendererInfo = this->AccessRendererInfo( renderer );
00942 iil4mitkPicImage *image = rendererInfo.Get_iil4mitkImage();
00943
00944 assert( image != NULL );
00945
00946 float rgba[4]= { 1.0f, 1.0f, 1.0f, 1.0f };
00947 float opacity = 1.0f;
00948
00949
00950 GetColor( rgba, renderer );
00951
00952 GetOpacity( opacity, renderer );
00953 rgba[3] = opacity;
00954
00955
00956 bool textureInterpolation = false;
00957 GetDataNode()->GetBoolProperty(
00958 "texture interpolation", textureInterpolation, renderer
00959 );
00960
00961 rendererInfo.m_TextureInterpolation = textureInterpolation;
00962
00963 mitk::LevelWindow levelWindow;
00964 mitk::LevelWindow opacLevelWindow;
00965
00966 bool binary = false;
00967 this->GetDataNode()->GetBoolProperty( "binary", binary, renderer );
00968
00969 if ( binary )
00970 {
00971
00972 image->setExtrema(0, 1);
00973 image->setOpacityExtrema( 0.0, 255.0 );
00974 image->setBinary(true);
00975
00976 bool binaryOutline = false;
00977 if ( this->GetInput()->GetPixelType().GetBpe() <= 8 )
00978 {
00979 if (this->GetDataNode()->GetBoolProperty( "outline binary", binaryOutline, renderer ))
00980 {
00981 image->setOutline(binaryOutline);
00982 float binaryOutlineWidth(1.0);
00983 if (this->GetDataNode()->GetFloatProperty( "outline width", binaryOutlineWidth, renderer ))
00984 {
00985 image->setOutlineWidth(binaryOutlineWidth);
00986 }
00987 }
00988 }
00989 else
00990 {
00991
00992
00993
00994
00995 MITK_WARN << "Type of all binary images should be (un)signed char. Outline does not work on other pixel types!";
00996 }
00997 }
00998 else
00999 {
01000 if( !this->GetLevelWindow( levelWindow, renderer, "levelWindow" ) )
01001 {
01002 this->GetLevelWindow( levelWindow, renderer );
01003 }
01004
01005 image->setExtrema( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() );
01006
01007
01008 if( this->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) )
01009 {
01010 image->setOpacityExtrema( opacLevelWindow.GetLowerWindowBound(), opacLevelWindow.GetUpperWindowBound() );
01011 }
01012 else
01013 {
01014 image->setOpacityExtrema( 0.0, 255.0 );
01015 }
01016 }
01017
01018 bool useColor = false;
01019 GetDataNode()->GetBoolProperty( "use color", useColor, renderer );
01020 mitk::LookupTableProperty::Pointer LookupTableProp;
01021
01022 if ( !useColor )
01023 {
01024 LookupTableProp = dynamic_cast<mitk::LookupTableProperty*>(
01025 this->GetDataNode()->GetProperty("LookupTable"));
01026
01027 if ( LookupTableProp.IsNull() )
01028 {
01029 useColor = true;
01030 }
01031 }
01032
01033 if ( useColor || binary )
01034 {
01035
01036 m_iil4mitkMode = iil4mitkImage::INTENSITY_ALPHA;
01037 image->setColor( rgba[0], rgba[1], rgba[2], rgba[3] );
01038 }
01039 else
01040 {
01041
01042 m_iil4mitkMode = iil4mitkImage::COLOR_ALPHA;
01043
01044 if ( LookupTableProp->GetLookupTable()->GetMTime()
01045 <= this->GetDataNode()->GetPropertyList()->GetMTime() )
01046 {
01047 LookupTableProp->GetLookupTable()->ChangeOpacityForAll( opacity );
01048 LookupTableProp->GetLookupTable()->ChangeOpacity(0, 0.0);
01049 }
01050 image->setColors(LookupTableProp->GetLookupTable()->GetRawLookupTable());
01051 }
01052 }
01053
01054 void
01055 mitk::ImageMapperGL2D::Update(mitk::BaseRenderer* renderer)
01056 {
01057 mitk::Image* data = const_cast<mitk::ImageMapperGL2D::InputImageType *>(
01058 this->GetInput()
01059 );
01060
01061 if ( data == NULL )
01062 {
01063 return;
01064 }
01065
01066 if ( !IsVisible(renderer) )
01067 {
01068 return;
01069 }
01070
01071
01072 this->CalculateTimeStep( renderer );
01073
01074
01075 const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry();
01076 if ( ( dataTimeGeometry == NULL )
01077 || ( dataTimeGeometry->GetTimeSteps() == 0 )
01078 || ( !dataTimeGeometry->IsValidTime( this->GetTimestep() ) ) )
01079 {
01080 return;
01081 }
01082
01083
01084 const DataNode *node = this->GetDataNode();
01085
01086 RendererInfo& rendererInfo = AccessRendererInfo( renderer );
01087 iil4mitkPicImage* image = rendererInfo.Get_iil4mitkImage();
01088
01089 data->UpdateOutputInformation();
01090
01091 if ( (image == NULL)
01092 || (rendererInfo.m_LastUpdateTime < node->GetMTime())
01093 || (rendererInfo.m_LastUpdateTime < data->GetPipelineMTime())
01094 || (rendererInfo.m_LastUpdateTime
01095 < renderer->GetCurrentWorldGeometry2DUpdateTime())
01096 || (rendererInfo.m_LastUpdateTime
01097 < renderer->GetDisplayGeometryUpdateTime()) )
01098 {
01099 this->GenerateData( renderer );
01100 }
01101 else if ( rendererInfo.m_LastUpdateTime
01102 < renderer->GetCurrentWorldGeometry2D()->GetMTime() )
01103 {
01104 this->GenerateData( renderer );
01105 }
01106 else if ( (rendererInfo.m_LastUpdateTime < node->GetPropertyList()->GetMTime())
01107 || (rendererInfo.m_LastUpdateTime
01108 < node->GetPropertyList(renderer)->GetMTime()) )
01109 {
01110 this->GenerateData( renderer );
01111
01112
01113
01114 rendererInfo.m_LastUpdateTime.Modified();
01115 }
01116 }
01117
01118
01119 void
01120 mitk::ImageMapperGL2D
01121 ::DeleteRendererCallback( itk::Object *object, const itk::EventObject & )
01122 {
01123 mitk::BaseRenderer *renderer = dynamic_cast< mitk::BaseRenderer* >( object );
01124 if ( renderer )
01125 {
01126 m_RendererInfo.erase( renderer );
01127 }
01128 }
01129
01130
01131 mitk::ImageMapperGL2D::RendererInfo
01132 ::RendererInfo()
01133 : m_RendererID(-1),
01134 m_iil4mitkImage(NULL),
01135 m_Renderer(NULL),
01136 m_Pic(NULL),
01137 m_UnitSpacingImageFilter( NULL ),
01138 m_Reslicer( NULL ),
01139 m_TSFilter( NULL ),
01140 m_Image(NULL),
01141 m_ReferenceGeometry(NULL),
01142 m_TextureInterpolation(true),
01143 m_ObserverID( 0 )
01144 {
01145 m_PixelsPerMM.Fill(0);
01146 };
01147
01148
01149 mitk::ImageMapperGL2D::RendererInfo
01150 ::~RendererInfo()
01151 {
01152 this->Squeeze();
01153
01154 if ( m_UnitSpacingImageFilter != NULL )
01155 {
01156 m_UnitSpacingImageFilter->Delete();
01157 }
01158 if ( m_Reslicer != NULL )
01159 {
01160 m_Reslicer->Delete();
01161 }
01162 if ( m_TSFilter != NULL )
01163 {
01164 m_TSFilter->Delete();
01165 }
01166 if ( m_Image != NULL )
01167 {
01168 m_Image->Delete();
01169 }
01170 }
01171
01172
01173 void
01174 mitk::ImageMapperGL2D::RendererInfo
01175 ::Set_iil4mitkImage( iil4mitkPicImage *iil4mitkImage )
01176 {
01177 assert( iil4mitkImage != NULL );
01178
01179 delete m_iil4mitkImage;
01180 m_iil4mitkImage = iil4mitkImage;
01181 }
01182
01183 void
01184 mitk::ImageMapperGL2D::RendererInfo::Squeeze()
01185 {
01186 delete m_iil4mitkImage;
01187 m_iil4mitkImage = NULL;
01188 if ( m_Pic != NULL )
01189 {
01190 mitkIpPicFree(m_Pic);
01191 m_Pic = NULL;
01192 }
01193 if ( m_Image != NULL )
01194 {
01195 m_Image->Delete();
01196 m_Image = NULL;
01197 }
01198 }
01199
01200 void
01201 mitk::ImageMapperGL2D::RendererInfo::RemoveObserver()
01202 {
01203 if ( m_ObserverID != 0 )
01204 {
01205
01206 m_Renderer->RemoveObserver( m_ObserverID-1 );
01207 }
01208 }
01209
01210
01211 void mitk::ImageMapperGL2D::RendererInfo::Initialize( int rendererID, mitk::BaseRenderer *renderer,
01212 unsigned long observerID )
01213 {
01214
01215 m_ObserverID = observerID+1;
01216
01217 assert(rendererID>=0);
01218 assert(m_RendererID<0);
01219
01220 m_RendererID = rendererID;
01221 m_Renderer = renderer;
01222
01223 m_Image = vtkImageData::New();
01224
01225 m_Reslicer = vtkImageReslice::New();
01226 m_TSFilter = vtkMitkThickSlicesFilter::New();
01227
01228 m_Reslicer->ReleaseDataFlagOn();
01229 m_TSFilter->ReleaseDataFlagOn();
01230
01231 m_UnitSpacingImageFilter = vtkImageChangeInformation::New();
01232 m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 );
01233 }
01234
01235 void mitk::ImageMapperGL2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
01236 {
01237 mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
01238
01239
01240 node->AddProperty( "use color", mitk::BoolProperty::New( true ), renderer, overwrite );
01241 node->AddProperty( "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite );
01242 node->AddProperty( "outline width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );
01243 if(image->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) );
01244 else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() );
01245 node->AddProperty( "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) );
01246 node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) );
01247 node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) );
01248
01249
01250
01251
01252 if(image->GetScalarValueMax() == image->GetScalarValue2ndMin()&& image->GetScalarValueMin() == image->GetScalarValue2ndMax())
01253 {
01254 node->AddProperty( "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite );
01255 node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
01256 node->AddProperty( "binary", mitk::BoolProperty::New( true ), renderer, overwrite );
01257 node->AddProperty("layer", mitk::IntProperty::New(10), renderer, overwrite);
01258 }
01259 else
01260 {
01261 node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite );
01262 node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite );
01263 node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite );
01264 node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite);
01265 }
01266
01267 if(image.IsNotNull() && image->IsInitialized())
01268 {
01269 if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL))
01270 {
01271 mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
01272 mitk::LevelWindow levelwindow;
01273 levelwindow.SetAuto( image );
01274 levWinProp->SetLevelWindow( levelwindow );
01275 node->SetProperty( "levelwindow", levWinProp, renderer );
01276 }
01277 if(((overwrite) || (node->GetProperty("opaclevelwindow", renderer)==NULL))
01278 && *(image->GetPixelType().GetItkTypeId()) == typeid(itk::RGBAPixel<unsigned char>))
01279 {
01280 mitk::LevelWindow opaclevwin;
01281 opaclevwin.SetRangeMinMax(0,255);
01282 opaclevwin.SetWindowBounds(0,255);
01283 mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin);
01284 node->SetProperty( "opaclevelwindow", prop, renderer );
01285 }
01286 if((overwrite) || (node->GetProperty("LookupTable", renderer)==NULL))
01287 {
01288
01289 mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
01290 vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable();
01291 vtkLut->SetHueRange(0.6667, 0.0);
01292 vtkLut->SetTableRange(0.0, 20.0);
01293 vtkLut->Build();
01294 mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New();
01295 mitkLutProp->SetLookupTable(mitkLut);
01296 node->SetProperty( "LookupTable", mitkLutProp );
01297 }
01298 }
01299
01300 Superclass::SetDefaultProperties(node, renderer, overwrite);
01301 }
01302