4 #include "vvSlicerManagerCommand.h"
5 #include "vvGlyphSource.h"
7 #include "vvImageMapToWLColors.h"
9 #include <vtkTextProperty.h>
10 #include <vtkTextActor.h>
11 #include <vtkTextSource.h>
12 #include <vtkActor2D.h>
13 #include <vtkCursor2D.h>
14 #include <vtkPolyDataMapper2D.h>
15 #include <vtkProperty2D.h>
16 #include <vtkCornerAnnotation.h>
17 #include <vtkImageMapToWindowLevelColors.h>
18 #include <vtkImageData.h>
19 #include <vtkImageActor.h>
20 #include <vtkToolkits.h>
21 #include <vtkObjectFactory.h>
22 #include <vtkPointData.h>
23 #include <vtkDataArray.h>
24 #include <vtkFloatArray.h>
25 #include <vtkClipPolyData.h>
26 #include <vtkGlyph3D.h>
28 #include <vtkCursor3D.h>
29 #include <vtkProperty.h>
31 #include <vtkLightCollection.h>
32 #include <vtkScalarBarActor.h>
33 #include <vtkLookupTable.h>
35 #include <vtkRenderer.h>
36 #include <vtkRendererCollection.h>
37 #include <vtkRenderWindow.h>
38 #include <vtkRenderWindowInteractor.h>
39 #include <vtkCamera.h>
40 #include <vtkCallbackCommand.h>
41 #include <vtkCommand.h>
42 #include <vtkPolyDataMapper.h>
45 #include <vtkExtractVOI.h>
46 #include <vtkSphereSource.h>
47 #include <vtkCutter.h>
48 #include <vtkAssignAttribute.h>
49 #include <vtkImageAccumulate.h>
51 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
52 vtkStandardNewMacro(vvSlicer);
54 //------------------------------------------------------------------------------
59 mUseReducedExtent = false;
61 mCurrent[0] = -VTK_DOUBLE_MAX;
62 mCurrent[1] = -VTK_DOUBLE_MAX;
63 mCurrent[2] = -VTK_DOUBLE_MAX;
65 mCursor[0] = -VTK_DOUBLE_MAX;
66 mCursor[1] = -VTK_DOUBLE_MAX;
67 mCursor[2] = -VTK_DOUBLE_MAX;
68 mCursor[3] = -VTK_DOUBLE_MAX;
74 std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
75 text += "F5 = horizontal flip; F6 = vertical flip\n\n";
76 text += "0,1,2,3,4,5 : preset windowing\n";
77 text += "6,7,8,9 : preset colormap\n";
78 text += "z : local windowing\n";
79 text += "r : reset view\n";
80 text += "l : reload image\n";
81 text += "f : fly to mouse position\n";
82 text += "g : go to cross hair position\n\n";
83 text += "Up,down : change slice\n";
84 text += "Left,right : change tenporal slice\n\n";
85 text += "Scrollbar (or w/x) : zoom in/out\n";
86 text += "left button : synchronize all views\n";
87 text += "middle button : grab image\n";
88 text += "right button : change windowing\n";
90 crossCursor = vtkCursor2D::New();
91 crossCursor->AllOff();
92 crossCursor->AxesOn();
93 crossCursor->SetTranslationMode(1);
94 crossCursor->SetRadius(2);
96 pdm = vtkPolyDataMapper2D::New();
97 pdm->SetInput(crossCursor->GetOutput());
99 pdmA = vtkActor2D::New();
100 pdmA->SetMapper(pdm);
101 pdmA->GetProperty()->SetColor(255,10,212);
102 pdmA->SetVisibility(0);
103 pdmA->SetPickable(0);
105 ca = vtkCornerAnnotation::New();
106 ca->GetTextProperty()->SetColor(255,10,212);
107 ca->SetVisibility(1);
115 legend = vtkSmartPointer<vtkScalarBarActor>::New();
116 //legend->SetTitle("test!");
117 legend->SetPosition(0.82,0.18);
118 legend->SetWidth(0.1);
119 legend->SetVisibility(0);
120 legend->SetLabelFormat("%.1f");
121 this->GetRenderer()->AddActor(legend);
123 this->WindowLevel->Delete();
124 this->WindowLevel = vvImageMapToWLColors::New();
125 this->InstallPipeline();
127 //------------------------------------------------------------------------------
130 //------------------------------------------------------------------------------
131 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() {
132 return mOverlayMapper.GetPointer();
134 //------------------------------------------------------------------------------
137 //------------------------------------------------------------------------------
138 vtkImageActor* vvSlicer::GetOverlayActor() {
139 return mOverlayActor.GetPointer();
141 //------------------------------------------------------------------------------
144 //------------------------------------------------------------------------------
145 vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() {
146 return mFusionMapper.GetPointer();
148 //------------------------------------------------------------------------------
151 //------------------------------------------------------------------------------
152 vtkImageActor* vvSlicer::GetFusionActor() {
153 return mFusionActor.GetPointer();
155 //------------------------------------------------------------------------------
158 //------------------------------------------------------------------------------
159 vtkActor* vvSlicer::GetVFActor() {
160 return mVFActor.GetPointer();
162 //------------------------------------------------------------------------------
165 //------------------------------------------------------------------------------
166 vtkCornerAnnotation* vvSlicer::GetAnnotation() {
167 return ca.GetPointer();
169 //------------------------------------------------------------------------------
172 //------------------------------------------------------------------------------
173 void vvSlicer::EnableReducedExtent(bool b) {
174 mUseReducedExtent = b;
176 //------------------------------------------------------------------------------
179 //------------------------------------------------------------------------------
180 void vvSlicer::SetReducedExtent(int * ext) {
181 mReducedExtent = ext;
183 //------------------------------------------------------------------------------
186 //------------------------------------------------------------------------------
187 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
190 mSurfaceCutActors.push_back(new vvMeshActor());
192 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
194 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
195 mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
196 this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
200 //------------------------------------------------------------------------------
203 //------------------------------------------------------------------------------
204 void vvSlicer::ToggleContourSuperposition()
206 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
207 i!=mSurfaceCutActors.end();i++)
208 (*i)->ToggleSuperposition();
210 //------------------------------------------------------------------------------
213 //------------------------------------------------------------------------------
214 void vvSlicer::SetCursorColor(int r,int g, int b)
216 pdmA->GetProperty()->SetColor(r,g,b);
218 //------------------------------------------------------------------------------
221 //------------------------------------------------------------------------------
222 void vvSlicer::SetCursorVisibility(bool s)
224 pdmA->SetVisibility(s);
226 //------------------------------------------------------------------------------
229 //------------------------------------------------------------------------------
230 bool vvSlicer::GetCursorVisibility()
232 return pdmA->GetVisibility();
234 //------------------------------------------------------------------------------
237 //------------------------------------------------------------------------------
238 vvSlicer::~vvSlicer()
240 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
241 i!=mSurfaceCutActors.end();i++)
244 //------------------------------------------------------------------------------
247 //------------------------------------------------------------------------------
248 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
255 //------------------------------------------------------------------------------
258 //------------------------------------------------------------------------------
259 void vvSlicer::SetImage(vvImage::Pointer image)
261 if (image->GetVTKImages().size())
264 this->Superclass::SetInput(image->GetVTKImages()[0]);
265 this->UpdateDisplayExtent();
267 ca->SetText(0,mFileName.c_str());
270 //------------------------------------------------------------------------------
273 //------------------------------------------------------------------------------
274 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
276 if (overlay->GetVTKImages().size())
281 mOverlayMapper = vtkImageMapToWindowLevelColors::New();
282 mOverlayMapper->SetInput(overlay->GetVTKImages()[0]);
286 mOverlayActor = vtkImageActor::New();
287 mOverlayActor->SetInput(mOverlayMapper->GetOutput());
288 mOverlayActor->SetPickable(0);
289 mOverlayActor->SetVisibility(false);
290 mOverlayActor->SetOpacity(0.5);
291 this->UpdateDisplayExtent();
294 //stupid but necessary : the Overlay need to be rendered before fusion
297 this->GetRenderer()->RemoveActor(mFusionActor);
298 this->GetRenderer()->AddActor(mOverlayActor);
299 this->GetRenderer()->AddActor(mFusionActor);
302 this->GetRenderer()->AddActor(mOverlayActor);
305 SetTSlice(mCurrentTSlice);
308 //------------------------------------------------------------------------------
311 //------------------------------------------------------------------------------
312 void vvSlicer::SetFusion(vvImage::Pointer fusion)
314 if (fusion->GetVTKImages().size())
319 mFusionMapper = vtkImageMapToWindowLevelColors::New();
320 mFusionMapper->SetInput(fusion->GetVTKImages()[0]);
324 mFusionActor = vtkImageActor::New();
325 mFusionActor->SetInput(mFusionMapper->GetOutput());
326 mFusionActor->SetPickable(0);
327 mFusionActor->SetVisibility(false);
328 mFusionActor->SetOpacity(0.7);
329 this->UpdateDisplayExtent();
330 this->GetRenderer()->AddActor(mFusionActor);
334 SetTSlice(mCurrentTSlice);
337 //------------------------------------------------------------------------------
340 //------------------------------------------------------------------------------
341 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
343 if (actor_type == "vector")
345 this->mVFActor->SetVisibility(vis);
347 if (actor_type == "overlay")
349 this->mOverlayActor->SetVisibility(vis);
351 if (actor_type == "fusion")
353 this->mFusionActor->SetVisibility(vis);
355 if (actor_type == "contour")
356 this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
357 UpdateDisplayExtent();
359 //------------------------------------------------------------------------------
362 //------------------------------------------------------------------------------
363 void vvSlicer::SetVF(vvImage::Pointer vf)
365 if (vf->GetVTKImages().size())
371 mAAFilter=vtkAssignAttribute::New();
372 mVOIFilter = vtkExtractVOI::New();
373 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
375 mVOIFilter->SetInput(vf->GetVTKImages()[0]);
376 mAAFilter->SetInput(mVOIFilter->GetOutput());
377 ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
378 mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
381 mArrow = vvGlyphSource::New();
382 mArrow->SetGlyphTypeToSpecificArrow();
383 mArrow->SetScale(mScale);
386 // Glyph the gradient vector (with arrows)
388 mGlyphFilter = vvGlyph2D::New();
389 mGlyphFilter->SetInput(mAAFilter->GetOutput());
390 mGlyphFilter->SetSource(mArrow->GetOutput());
391 mGlyphFilter->ScalingOn();
392 mGlyphFilter->SetScaleModeToScaleByVector();
393 mGlyphFilter->OrientOn();
394 mGlyphFilter->SetVectorModeToUseVector();
395 mGlyphFilter->SetColorModeToColorByVector();
398 mVFMapper = vtkPolyDataMapper::New();
399 //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
400 mVFMapper->SetInput(mGlyphFilter->GetOutput());
401 mVFMapper->ImmediateModeRenderingOn();
404 mVFActor = vtkActor::New();
405 mVFActor->SetMapper(mVFMapper);
406 mVFActor->SetPickable(0);
407 this->UpdateDisplayExtent();
408 this->GetRenderer()->AddActor(mVFActor);
411 SetTSlice(mCurrentTSlice);
414 //------------------------------------------------------------------------------
417 //------------------------------------------------------------------------------
418 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
420 mLandmarks = landmarks;
425 mCross = vtkCursor3D::New();
426 mCross->SetFocalPoint(0.0,0.0,0.0);
427 mCross->SetModelBounds(-10,10,-10,10,-10,10);
432 mLandGlyph = vtkGlyph3D::New();
433 mLandGlyph->SetSource(mCross->GetOutput());
434 mLandGlyph->SetInput(landmarks->GetOutput());
435 //mLandGlyph->SetIndexModeToScalar();
436 mLandGlyph->SetRange(0,1);
437 mLandGlyph->ScalingOff();
439 mLandGlyph->SetColorModeToColorByScalar();
442 mClipBox = vtkBox::New();
444 mLandClipper = vtkClipPolyData::New();
445 mLandClipper->InsideOutOn();
446 mLandClipper->SetInput(mLandGlyph->GetOutput());
447 mLandClipper->SetClipFunction(mClipBox);
450 mLandMapper = vtkPolyDataMapper::New();
451 mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
452 //mLandMapper->ScalarVisibilityOff();
455 mLandActor = vtkActor::New();
456 mLandActor->SetMapper(mLandMapper);
457 mLandActor->GetProperty()->SetColor(255,10,212);
458 mLandActor->SetPickable(0);
459 mLandActor->SetVisibility(true);
460 this->UpdateDisplayExtent();
461 this->GetRenderer()->AddActor(mLandActor);
464 //------------------------------------------------------------------------------
466 //------------------------------------------------------------------------------
467 //FIXME: this function leaks memory, we should fix it someday :)
468 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
470 if (actor_type == "vector")
472 Renderer->RemoveActor(mVFActor);
481 if (actor_type == "overlay")
483 Renderer->RemoveActor(mOverlayActor);
485 mOverlayActor = NULL;
486 mOverlayMapper = NULL;
488 if (actor_type == "fusion")
490 Renderer->RemoveActor(mFusionActor);
493 mFusionMapper = NULL;
495 if (actor_type == "contour")
497 Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
498 mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
501 //------------------------------------------------------------------------------
504 //------------------------------------------------------------------------------
505 void vvSlicer::SetVFSubSampling(int sub)
509 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
512 UpdateDisplayExtent();
515 //------------------------------------------------------------------------------
518 //------------------------------------------------------------------------------
519 void vvSlicer::SetVFScale(int scale)
523 mArrow->SetScale(mScale);
524 UpdateDisplayExtent();
527 //------------------------------------------------------------------------------
530 //------------------------------------------------------------------------------
531 void vvSlicer::SetVFLog(int log)
536 mGlyphFilter->SetUseLog(mVFLog);
537 mGlyphFilter->Modified();
539 UpdateDisplayExtent();
542 //------------------------------------------------------------------------------
545 //------------------------------------------------------------------------------
546 void vvSlicer::SetTSlice(int t)
550 else if ((unsigned int)t >= mImage->GetVTKImages().size())
551 t = mImage->GetVTKImages().size() -1;
553 this->SetInput(mImage->GetVTKImages()[t]);
554 if (mVF && mVFActor->GetVisibility())
556 if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
557 mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
559 if (mOverlay && mOverlayActor->GetVisibility())
561 if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
562 mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
564 if (mFusion && mFusionActor->GetVisibility())
566 if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
567 mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
569 if (mSurfaceCutActors.size() > 0)
570 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
571 i!=mSurfaceCutActors.end();i++)
572 (*i)->SetTimeSlice(mCurrentTSlice);
573 UpdateDisplayExtent();
575 //------------------------------------------------------------------------------
578 //------------------------------------------------------------------------------
579 int vvSlicer::GetTSlice()
581 return mCurrentTSlice;
583 //------------------------------------------------------------------------------
586 //------------------------------------------------------------------------------
587 void vvSlicer::SetSliceOrientation(int orientation)
589 //if 2D image, force to watch in Axial View
591 this->GetInput()->GetWholeExtent(extent);
592 if (extent[5]-extent[4] <= 2)
595 if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
596 orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
598 vtkErrorMacro("Error - invalid slice orientation " << orientation);
602 this->SliceOrientation = orientation;
605 int *range = this->GetSliceRange();
607 this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
609 this->UpdateOrientation();
610 this->UpdateDisplayExtent();
612 if (this->Renderer && this->GetInput())
614 double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
615 this->Renderer->ResetCamera();
616 this->Renderer->GetActiveCamera()->SetParallelScale(scale);
622 //----------------------------------------------------------------------------
623 void vvSlicer::UpdateDisplayExtent()
625 vtkImageData *input = this->GetInput();
626 if (!input || !this->ImageActor)
630 input->UpdateInformation();
631 int *w_ext;// = input->GetWholeExtent();
633 if (mUseReducedExtent) {
634 w_ext = mReducedExtent;
636 else w_ext = input->GetWholeExtent();
638 switch (this->SliceOrientation)
640 case vtkImageViewer2::SLICE_ORIENTATION_XY:
641 this->ImageActor->SetDisplayExtent(
642 w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
643 if (mVF && mVFActor->GetVisibility())
646 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
647 mVOIFilter->SetVOI(vfExtent);
648 mGlyphFilter->SetOrientation(1,1,0);
650 // put the vector field between the image and the camera
651 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
652 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
654 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
656 if (mOverlay && mOverlayActor->GetVisibility())
659 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
660 mOverlayActor->SetDisplayExtent(overExtent);
661 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
662 mOverlayActor->SetPosition(0,0,1);
664 mOverlayActor->SetPosition(0,0,-1);
666 if (mFusion && mFusionActor->GetVisibility())
669 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
670 mFusionActor->SetDisplayExtent(fusExtent);
671 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
672 mFusionActor->SetPosition(0,0,1.5);
674 mFusionActor->SetPosition(0,0,-1.5);
681 bounds[0] = ImageActor->GetBounds()[0];
682 bounds[1] = ImageActor->GetBounds()[1];
683 bounds[2] = ImageActor->GetBounds()[2];
684 bounds[3] = ImageActor->GetBounds()[3];
685 bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
686 bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
687 mClipBox->SetBounds(bounds);
690 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
691 mLandActor->SetPosition(0,0,1.5);
693 mLandActor->SetPosition(0,0,-1.5);
697 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
698 this->ImageActor->SetDisplayExtent(
699 w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
700 if (mVF && mVFActor->GetVisibility())
703 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
704 mVOIFilter->SetVOI(vfExtent);
705 mGlyphFilter->SetOrientation(1,0,1);
707 // put the vector field between the image aSpacingnd the camera
708 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
709 mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
711 mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
713 if (mOverlay && mOverlayActor->GetVisibility())
716 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
717 mOverlayActor->SetDisplayExtent(overExtent);
718 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
719 mOverlayActor->SetPosition(0,1,0);
721 mOverlayActor->SetPosition(0,-1,0);
723 if (mFusion && mFusionActor->GetVisibility())
726 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
727 mFusionActor->SetDisplayExtent(fusExtent);
728 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
729 mFusionActor->SetPosition(0,1.5,0);
731 mFusionActor->SetPosition(0,-1.5,0);
738 bounds[0] = ImageActor->GetBounds()[0];
739 bounds[1] = ImageActor->GetBounds()[1];
740 bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
741 bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
742 bounds[4] = ImageActor->GetBounds()[4];
743 bounds[5] = ImageActor->GetBounds()[5];
744 mClipBox->SetBounds(bounds);
747 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
748 mLandActor->SetPosition(0,1.5,0);
750 mLandActor->SetPosition(0,-1.5,0);
754 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
755 this->ImageActor->SetDisplayExtent(
756 this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
757 if (mVF && mVFActor->GetVisibility())
760 ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
761 mVOIFilter->SetVOI(vfExtent);
762 mGlyphFilter->SetOrientation(0,1,1);
764 // put the vector field between the image and the camera
765 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
766 mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
768 mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
770 if (mOverlay && mOverlayActor->GetVisibility())
773 ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
774 mOverlayActor->SetDisplayExtent(overExtent);
775 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
776 mOverlayActor->SetPosition(1,0,0);
778 mOverlayActor->SetPosition(-1,0,0);
780 if (mFusion && mFusionActor->GetVisibility())
783 ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
784 mFusionActor->SetDisplayExtent(fusExtent);
785 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
786 mFusionActor->SetPosition(1.5,0,0);
788 mFusionActor->SetPosition(-1.5,0,0);
795 bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
796 bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
797 bounds[2] = ImageActor->GetBounds()[2];
798 bounds[3] = ImageActor->GetBounds()[3];
799 bounds[4] = ImageActor->GetBounds()[4];
800 bounds[5] = ImageActor->GetBounds()[5];
801 mClipBox->SetBounds(bounds);
804 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
805 mLandActor->SetPosition(1.5,0,0);
807 mLandActor->SetPosition(-1.5,0,0);
812 // Figure out the correct clipping range
816 if (this->InteractorStyle &&
817 this->InteractorStyle->GetAutoAdjustCameraClippingRange())
819 this->Renderer->ResetCameraClippingRange();
823 vtkCamera *cam = this->Renderer->GetActiveCamera();
827 this->ImageActor->GetBounds(bounds);
828 double spos = (double)bounds[this->SliceOrientation * 2];
829 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
830 double range = fabs(spos - cpos);
831 double *spacing = input->GetSpacing();
833 ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
834 cam->SetClippingRange(
835 range - avg_spacing * 3.0, range + avg_spacing * 3.0);
840 //----------------------------------------------------------------------------
843 //----------------------------------------------------------------------------
844 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
846 vtkImageData* image=this->GetInput();
847 vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
848 mVF->GetSpacing()[0];
849 vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
850 mVF->GetSpacing()[0];
851 vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
852 mVF->GetSpacing()[1];
853 vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
854 mVF->GetSpacing()[1];
855 vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
856 mVF->GetSpacing()[2];
857 vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
858 mVF->GetSpacing()[2];
860 ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
862 //----------------------------------------------------------------------------
865 //----------------------------------------------------------------------------
866 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
868 vtkImageData* image=this->GetInput();
869 overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
870 mOverlay->GetSpacing()[0];
871 overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
872 mOverlay->GetSpacing()[0];
873 overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
874 mOverlay->GetSpacing()[1];
875 overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
876 mOverlay->GetSpacing()[1];
877 overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
878 mOverlay->GetSpacing()[2];
879 overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
880 mOverlay->GetSpacing()[2];
881 ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
883 //----------------------------------------------------------------------------
886 //----------------------------------------------------------------------------
887 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
889 vtkImageData* image=this->GetInput();
890 fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
891 mFusion->GetSpacing()[0];
892 fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
893 mFusion->GetSpacing()[0];
894 fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
895 mFusion->GetSpacing()[1];
896 fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
897 mFusion->GetSpacing()[1];
898 fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
899 mFusion->GetSpacing()[2];
900 fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
901 mFusion->GetSpacing()[2];
902 ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
904 //----------------------------------------------------------------------------
907 //----------------------------------------------------------------------------
908 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
913 //2D overlay on 3D image specific case
914 if (refExtent[4] == refExtent[5])
917 extent[4] = refExtent[4];
918 extent[5] = refExtent[5];
921 for (int i = 0; i < maxBound; i = i+2)
923 //if we are totally outside the image
924 if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] )
929 //crop to the limit of the image
930 extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
931 extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
932 extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
933 extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
936 for (int i = 0; i < maxBound; i = i+2)
938 extent[i] = refExtent[i];
939 extent[i+1] = refExtent[i];
942 //----------------------------------------------------------------------------
945 //----------------------------------------------------------------------------
946 void vvSlicer::UpdateOrientation()
948 // Set the camera position
949 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
952 switch (this->SliceOrientation)
954 case vtkImageViewer2::SLICE_ORIENTATION_XY:
955 cam->SetFocalPoint(0,0,0);
956 cam->SetPosition(0,0,-1); // -1 if medical ?
957 cam->SetViewUp(0,-1,0);
960 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
961 cam->SetFocalPoint(0,0,0);
962 cam->SetPosition(0,-1,0); // 1 if medical ?
963 cam->SetViewUp(0,0,1);
966 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
967 cam->SetFocalPoint(0,0,0);
968 cam->SetPosition(-1,0,0); // -1 if medical ?
969 cam->SetViewUp(0,0,1);
974 //----------------------------------------------------------------------------
977 //----------------------------------------------------------------------------
978 void vvSlicer::SetOpacity(double s)
980 this->GetImageActor()->SetOpacity(s);
982 //----------------------------------------------------------------------------
985 //----------------------------------------------------------------------------
986 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
988 this->Superclass::SetRenderWindow(rw);
989 this->SetupInteractor(rw->GetInteractor());
990 ca->SetImageActor(this->GetImageActor());
991 ca->SetWindowLevel(this->GetWindowLevel());
992 ca->SetText(2, "<slice>");
993 ca->SetText(3, "<window>\n<level>");
1005 crossCursor->SetModelBounds(bounds);
1006 this->GetRenderer()->AddActor(pdmA);
1007 this->GetRenderer()->AddActor(ca);
1008 this->GetRenderer()->ResetCamera();
1010 //this is just a mapping between the labeling of the orientations presented to the user and
1011 //the one used by vtk
1012 SetSliceOrientation(2-(orientation%3));
1015 //----------------------------------------------------------------------------
1018 //----------------------------------------------------------------------------
1019 void vvSlicer::ResetCamera()
1021 if (this->GetInput())
1023 double* input_bounds=this->GetInput()->GetBounds();
1024 double bmax=input_bounds[1]-input_bounds[0];
1025 if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
1026 if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
1027 this->GetRenderer()->ResetCamera();
1028 this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
1031 //----------------------------------------------------------------------------
1034 //----------------------------------------------------------------------------
1035 void vvSlicer::SetDisplayMode(bool i)
1037 this->GetImageActor()->SetVisibility(i);
1038 this->GetAnnotation()->SetVisibility(i);
1039 this->GetRenderer()->SetDraw(i);
1041 mLandActor->SetVisibility(i);
1042 pdmA->SetVisibility(i);
1044 UpdateDisplayExtent();
1046 //----------------------------------------------------------------------------
1049 //----------------------------------------------------------------------------
1050 void vvSlicer::FlipHorizontalView()
1052 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1055 double *position = cam->GetPosition();
1056 switch (this->SliceOrientation)
1058 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1059 cam->SetPosition(position[0],position[1],-position[2]);
1062 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1063 cam->SetPosition(position[0],-position[1],position[2]);
1066 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1067 cam->SetPosition(-position[0],position[1],position[2]);
1070 this->Renderer->ResetCameraClippingRange();
1071 this->UpdateDisplayExtent();
1074 //----------------------------------------------------------------------------
1077 //----------------------------------------------------------------------------
1078 void vvSlicer::FlipVerticalView()
1080 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1083 FlipHorizontalView();
1084 double *viewup = cam->GetViewUp();
1085 cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1086 this->UpdateDisplayExtent();
1089 //----------------------------------------------------------------------------
1092 //----------------------------------------------------------------------------
1093 void vvSlicer::SetColorWindow(double window)
1095 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1098 double level = this->GetWindowLevel()->GetLevel();
1099 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1102 this->vtkImageViewer2::SetColorWindow(window);
1104 //----------------------------------------------------------------------------
1107 //----------------------------------------------------------------------------
1108 void vvSlicer::SetColorLevel(double level)
1110 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1113 double window = this->GetWindowLevel()->GetWindow();
1114 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1117 this->vtkImageViewer2::SetColorLevel(level);
1119 //----------------------------------------------------------------------------
1121 //----------------------------------------------------------------------------
1122 // Returns the min an the max value in a 41x41 region around the mouse pointer
1123 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1125 //Get mouse pointer position in view coordinates
1126 double fLocalExtents[6];
1127 for(int i=0; i<3; i++)
1129 fLocalExtents[i*2 ] = mCurrent[i];
1130 fLocalExtents[i*2+1] = mCurrent[i];
1132 this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1133 this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1134 for(int i=0; i<3; i++)
1136 if (i!=SliceOrientation) //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1138 fLocalExtents[i*2 ] -= 0.2;
1139 fLocalExtents[i*2+1] += 0.2;
1142 this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1143 this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1145 //Convert to image pixel coordinates (rounded)
1146 int iLocalExtents[6];
1147 for(int i=0; i<3; i++)
1149 fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1150 fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1152 iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]);
1153 iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1155 if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
1156 std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1159 vtkSmartPointer<vtkExtractVOI> voiFilter = vtkExtractVOI::New();
1160 voiFilter->SetInput(this->GetInput());
1161 voiFilter->SetVOI(iLocalExtents);
1163 vtkSmartPointer<vtkImageAccumulate> accFilter = vtkImageAccumulate::New();
1164 accFilter->SetInput(voiFilter->GetOutput());
1165 accFilter->Update();
1167 min = *(accFilter->GetMin());
1168 max = *(accFilter->GetMax());
1170 //----------------------------------------------------------------------------
1172 //----------------------------------------------------------------------------
1173 void vvSlicer::Render()
1175 if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
1177 legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1178 legend->SetVisibility(1);
1180 else legend->SetVisibility(0);
1182 if (ca->GetVisibility())
1184 std::string worldPos = "";
1185 std::stringstream world1;
1186 std::stringstream world2;
1187 std::stringstream world3;
1188 world1 << (int)mCurrent[0];
1189 world2 << (int)mCurrent[1];
1190 world3 << (int)mCurrent[2];
1191 double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1192 double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1193 double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1195 if (pdmA->GetVisibility())
1197 double x = mCursor[0];
1198 double y = mCursor[1];
1199 double z = mCursor[2];
1200 double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1201 double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1202 double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1204 if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1205 xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1206 yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1207 yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1208 zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1209 zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1211 vtkRenderer * renderer = this->Renderer;
1213 renderer->WorldToView(x,y,z);
1214 renderer->ViewToNormalizedViewport(x,y,z);
1215 renderer->NormalizedViewportToViewport(x,y);
1216 renderer->ViewportToNormalizedDisplay(x,y);
1217 renderer->NormalizedDisplayToDisplay(x,y);
1218 crossCursor->SetFocalPoint(x,y,z);
1221 crossCursor->SetFocalPoint(-1,-1,z);
1224 if (X >= this->GetInput()->GetWholeExtent()[0] &&
1225 X <= this->GetInput()->GetWholeExtent()[1] &&
1226 Y >= this->GetInput()->GetWholeExtent()[2] &&
1227 Y <= this->GetInput()->GetWholeExtent()[3] &&
1228 Z >= this->GetInput()->GetWholeExtent()[4] &&
1229 Z <= this->GetInput()->GetWholeExtent()[5])
1231 std::stringstream pixel1;
1232 std::stringstream pixel2;
1233 std::stringstream pixel3;
1234 std::stringstream temps;
1238 temps << mCurrentTSlice;
1239 double value = this->GetInput()->GetScalarComponentAsDouble(
1244 std::stringstream val;
1246 worldPos += "data value : " + val.str();
1247 worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1248 world3.str() + " " + temps.str();
1249 worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1250 pixel3.str() + " " + temps.str();
1252 ca->SetText(1,worldPos.c_str());
1254 if (mOverlay && mOverlayActor->GetVisibility())
1256 mOverlayMapper->SetWindow(this->GetColorWindow());
1257 mOverlayMapper->SetLevel(this->GetColorLevel());
1258 mOverlayMapper->Update();
1262 //this->Superclass::Render();
1263 this->GetRenderWindow()->Render();
1265 //----------------------------------------------------------------------------
1268 //----------------------------------------------------------------------------
1269 void vvSlicer::UpdateCursorPosition()
1271 if (this->GetImageActor()->GetVisibility())
1273 pdmA->SetVisibility(true);
1274 mCursor[0] = mCurrent[0];
1275 mCursor[1] = mCurrent[1];
1276 mCursor[2] = mCurrent[2];
1277 mCursor[3] = mCurrentTSlice;
1280 //----------------------------------------------------------------------------
1283 //----------------------------------------------------------------------------
1284 void vvSlicer::UpdateLandmarks()
1286 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1287 if (pd->GetPoints())
1289 mLandGlyph->SetRange(0,1);
1290 mLandGlyph->Modified();
1291 mLandGlyph->Update();
1293 mClipBox->Modified();
1294 mLandClipper->Update();
1295 mLandMapper->Update();
1299 //----------------------------------------------------------------------------
1302 //----------------------------------------------------------------------------
1303 void vvSlicer::SetSlice(int slice)
1305 int *range = this->GetSliceRange();
1308 if (slice < range[0])
1312 else if (slice > range[1])
1318 if (this->Slice == slice)
1323 this->Slice = slice;
1326 this->UpdateDisplayExtent();
1329 //----------------------------------------------------------------------------
1332 //----------------------------------------------------------------------------
1333 void vvSlicer::SetContourSlice()
1335 if (mSurfaceCutActors.size() > 0)
1336 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1337 i!=mSurfaceCutActors.end();i++)
1338 (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1339 this->GetImage()->GetOrigin()[this->SliceOrientation]);
1341 //----------------------------------------------------------------------------
1344 //----------------------------------------------------------------------------
1345 void vvSlicer::ForceUpdateDisplayExtent()
1347 this->UpdateDisplayExtent();
1349 //----------------------------------------------------------------------------
1352 //----------------------------------------------------------------------------
1353 int* vvSlicer::GetDisplayExtent()
1355 return this->GetImageActor()->GetDisplayExtent();
1357 //----------------------------------------------------------------------------
1360 //----------------------------------------------------------------------------
1361 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1363 this->Superclass::PrintSelf(os, indent);
1365 //----------------------------------------------------------------------------