]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
2255cce74c5b8a719ec671caaddbea425636eb4b
[clitk.git] / vv / vvSlicer.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ======================================================================-====*/
18
19 #include "vvSlicer.h"
20 #include "vvImage.h"
21 #include "vvSlicerManagerCommand.h"
22 #include "vvGlyphSource.h"
23 #include "vvGlyph2D.h"
24 #include "vvImageMapToWLColors.h"
25
26 #include <vtkTextProperty.h>
27 #include <vtkTextActor.h>
28 #include <vtkTextSource.h>
29 #include <vtkActor2D.h>
30 #include <vtkCursor2D.h>
31 #include <vtkPolyDataMapper2D.h>
32 #include <vtkProperty2D.h>
33 #include <vtkCornerAnnotation.h>
34 #include <vtkImageMapToWindowLevelColors.h>
35 #include <vtkImageData.h>
36 #include <vtkImageActor.h>
37 #include <vvBlendImageActor.h>
38 #include <vtkToolkits.h>
39 #include <vtkObjectFactory.h>
40 #include <vtkPointData.h>
41 #include <vtkDataArray.h>
42 #include <vtkFloatArray.h>
43 #include <vtkClipPolyData.h>
44 #include <vtkGlyph3D.h>
45 #include <vtkMath.h>
46 #include <vtkCursor3D.h>
47 #include <vtkProperty.h>
48 #include <vtkLight.h>
49 #include <vtkLightCollection.h>
50 #include <vtkScalarBarActor.h>
51 #include <vtkLookupTable.h>
52
53 #include <vtkRenderer.h>
54 #include <vtkRendererCollection.h>
55 #include <vtkRenderWindow.h>
56 #include <vtkRenderWindowInteractor.h>
57 #include <vtkCamera.h>
58 #include <vtkCallbackCommand.h>
59 #include <vtkCommand.h>
60 #include <vtkPolyDataMapper.h>
61 #include <vtkBox.h>
62
63 #include <vtkExtractVOI.h>
64 #include <vtkSphereSource.h>
65 #include <vtkCutter.h>
66 #include <vtkAssignAttribute.h>
67 #include <vtkImageAccumulate.h>
68 #include <vtkImageReslice.h>
69
70 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
71 vtkStandardNewMacro(vvSlicer);
72
73 //------------------------------------------------------------------------------
74 vvSlicer::vvSlicer()
75 {
76   this->UnInstallPipeline();
77   mImage = NULL;
78   mCurrentTSlice = 0;
79   mUseReducedExtent = false;
80
81   mCurrent[0] = -VTK_DOUBLE_MAX;
82   mCurrent[1] = -VTK_DOUBLE_MAX;
83   mCurrent[2] = -VTK_DOUBLE_MAX;
84
85   mCursor[0] = -VTK_DOUBLE_MAX;
86   mCursor[1] = -VTK_DOUBLE_MAX;
87   mCursor[2] = -VTK_DOUBLE_MAX;
88   mCursor[3] = -VTK_DOUBLE_MAX;
89
90   mSubSampling = 5;
91   mScale = 1;
92   mVFLog = 0;
93   mVFWidth = 1;
94   mVFColor[0] = 0;
95   mVFColor[1] = 1;
96   mVFColor[2] = 0;
97
98   std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
99   text += "F5 = horizontal flip; F6 = vertical flip\n\n";
100   text += "0,1,2,3,4,5 : preset windowing\n";
101   text += "6,7,8,9 : preset colormap\n";
102   text += "z : local windowing\n";
103   text += "r : reset view\n";
104   text += "l : reload image\n";
105   text += "f : fly to mouse position\n";
106   text += "g : go to cross hair position\n\n";
107   text += "Up,down : change slice\n";
108   text += "Left,right : change tenporal slice\n\n";
109   text += "Scrollbar (or w/x) : zoom in/out\n";
110   text += "left button : synchronize all views\n";
111   text += "middle button : grab image\n";
112   text += "right button : change windowing\n";
113
114   crossCursor = vtkSmartPointer<vtkCursor2D>::New();
115   crossCursor->AllOff();
116   crossCursor->AxesOn();
117   crossCursor->SetTranslationMode(1);
118   crossCursor->SetRadius(2);
119
120   pdm = vtkSmartPointer<vtkPolyDataMapper2D>::New();
121   pdm->SetInput(crossCursor->GetOutput());
122
123   pdmA = vtkSmartPointer<vtkActor2D>::New();
124   pdmA->SetMapper(pdm);
125   pdmA->GetProperty()->SetColor(255,10,212);
126   pdmA->SetVisibility(0);
127   pdmA->SetPickable(0);
128
129   ca = vtkSmartPointer<vtkCornerAnnotation>::New();
130   ca->GetTextProperty()->SetColor(255,10,212);
131   ca->SetVisibility(1);
132   mFileName = "";
133
134   mVF = NULL;
135   mOverlay = NULL;
136   mFusion = NULL;
137   mLandmarks = NULL;
138
139   legend = vtkSmartPointer<vtkScalarBarActor>::New();
140   //legend->SetTitle("test!");
141   legend->SetPosition(0.82,0.18);
142   legend->SetWidth(0.1);
143   legend->SetVisibility(0);
144   legend->SetLabelFormat("%.1f");
145   this->GetRenderer()->AddActor(legend);
146
147   this->WindowLevel->Delete();
148   this->WindowLevel = vvImageMapToWLColors::New();
149
150   this->InstallPipeline();
151 }
152 //------------------------------------------------------------------------------
153
154
155 //------------------------------------------------------------------------------
156 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper()
157 {
158   return mOverlayMapper.GetPointer();
159 }
160 //------------------------------------------------------------------------------
161
162
163 //------------------------------------------------------------------------------
164 vvBlendImageActor* vvSlicer::GetOverlayActor()
165 {
166   return mOverlayActor.GetPointer();
167 }
168 //------------------------------------------------------------------------------
169
170
171 //------------------------------------------------------------------------------
172 vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper()
173 {
174   return mFusionMapper.GetPointer();
175 }
176 //------------------------------------------------------------------------------
177
178
179 //------------------------------------------------------------------------------
180 vtkImageActor* vvSlicer::GetFusionActor()
181 {
182   return mFusionActor.GetPointer();
183 }
184 //------------------------------------------------------------------------------
185
186
187 //------------------------------------------------------------------------------
188 vtkActor* vvSlicer::GetVFActor()
189 {
190   return mVFActor.GetPointer();
191 }
192 //------------------------------------------------------------------------------
193
194
195 //------------------------------------------------------------------------------
196 vtkCornerAnnotation* vvSlicer::GetAnnotation()
197 {
198   return ca.GetPointer();
199 }
200 //------------------------------------------------------------------------------
201
202
203 //------------------------------------------------------------------------------
204 void vvSlicer::EnableReducedExtent(bool b)
205 {
206   mUseReducedExtent = b;
207 }
208 //------------------------------------------------------------------------------
209
210
211 //------------------------------------------------------------------------------
212 void vvSlicer::SetReducedExtent(int * ext)
213 {
214   mReducedExtent = ext;
215 }
216 //------------------------------------------------------------------------------
217
218
219 //------------------------------------------------------------------------------
220 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
221 {
222
223   mSurfaceCutActors.push_back(new vvMeshActor());
224   if (propagate)
225     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
226   else
227     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
228   mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
229   this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
230
231   SetContourSlice();
232 }
233 //------------------------------------------------------------------------------
234
235
236 //------------------------------------------------------------------------------
237 void vvSlicer::ToggleContourSuperposition()
238 {
239   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
240        i!=mSurfaceCutActors.end(); i++)
241     (*i)->ToggleSuperposition();
242 }
243 //------------------------------------------------------------------------------
244
245
246 //------------------------------------------------------------------------------
247 void vvSlicer::SetCursorColor(int r,int g, int b)
248 {
249   pdmA->GetProperty()->SetColor(r,g,b);
250 }
251 //------------------------------------------------------------------------------
252
253
254 //------------------------------------------------------------------------------
255 void vvSlicer::SetCursorVisibility(bool s)
256 {
257   pdmA->SetVisibility(s);
258 }
259 //------------------------------------------------------------------------------
260
261
262 //------------------------------------------------------------------------------
263 bool vvSlicer::GetCursorVisibility()
264 {
265   return pdmA->GetVisibility();
266 }
267 //------------------------------------------------------------------------------
268
269
270 //------------------------------------------------------------------------------
271 void vvSlicer::SetCornerAnnotationVisibility(bool s)
272 {
273   ca->SetVisibility(s);
274 }
275 //------------------------------------------------------------------------------
276
277
278 //------------------------------------------------------------------------------
279 bool vvSlicer::GetCornerAnnotationVisibility()
280 {
281   return ca->GetVisibility();
282 }
283 //------------------------------------------------------------------------------
284
285
286 //------------------------------------------------------------------------------
287 vvSlicer::~vvSlicer()
288 {
289   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
290        i!=mSurfaceCutActors.end(); i++)
291     delete (*i);
292 }
293 //------------------------------------------------------------------------------
294
295
296 //------------------------------------------------------------------------------
297 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
298 {
299   mCurrent[0] = x;
300   mCurrent[1] = y;
301   mCurrent[2] = z;
302   mCurrentTSlice = t;
303 }
304 //------------------------------------------------------------------------------
305
306
307 //------------------------------------------------------------------------------
308 void vvSlicer::SetImage(vvImage::Pointer image)
309 {
310   if (image->GetVTKImages().size()) {
311     mImage = image;
312     this->Superclass::SetInput(image->GetTransformedVTKImages()[0]);
313
314     int extent[6];
315     this->GetInput()->GetWholeExtent(extent);
316
317     // Prevent crash when reload -> change slice if outside extent
318     if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
319       Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0;
320     }
321
322     // Make sure that the required part image has been computed
323     extent[SliceOrientation*2] = Slice;
324     extent[SliceOrientation*2+1] = Slice;
325     image->GetTransformedVTKImages()[0]->SetUpdateExtent(extent);
326     image->GetTransformedVTKImages()[0]->Update();
327
328     this->UpdateDisplayExtent();
329
330     mCurrentTSlice = 0;
331     ca->SetText(0,mFileName.c_str());
332   }
333 }
334 //------------------------------------------------------------------------------
335
336
337 //------------------------------------------------------------------------------
338 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
339 {
340   if (overlay->GetVTKImages().size()) {
341     mOverlay = overlay;
342
343     if (!mOverlayMapper)
344       mOverlayMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
345     mOverlayMapper->SetInput(overlay->GetTransformedVTKImages()[0]);
346
347     if (!mOverlayActor) {
348       mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
349       mOverlayActor->SetInput(mOverlayMapper->GetOutput());
350       mOverlayActor->SetPickable(0);
351       mOverlayActor->SetVisibility(false);
352       mOverlayActor->SetOpacity(0.5);
353       this->UpdateDisplayExtent();
354     }
355
356     //stupid but necessary : the Overlay need to be rendered before fusion
357     if (mFusionActor) {
358       this->GetRenderer()->RemoveActor(mFusionActor);
359       this->GetRenderer()->AddActor(mOverlayActor);
360       this->GetRenderer()->AddActor(mFusionActor);
361     } else
362       this->GetRenderer()->AddActor(mOverlayActor);
363
364     //Synchronize slice
365     SetTSlice(mCurrentTSlice);
366   }
367 }
368 //------------------------------------------------------------------------------
369
370
371 //------------------------------------------------------------------------------
372 void vvSlicer::SetFusion(vvImage::Pointer fusion)
373 {
374   if (fusion->GetVTKImages().size()) {
375     mFusion = fusion;
376
377     if (!mFusionMapper)
378       mFusionMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
379     mFusionMapper->SetInput(fusion->GetTransformedVTKImages()[0]);
380
381     if (!mFusionActor) {
382       mFusionActor = vtkSmartPointer<vtkImageActor>::New();
383       mFusionActor->SetInput(mFusionMapper->GetOutput());
384       mFusionActor->SetPickable(0);
385       mFusionActor->SetVisibility(false);
386       mFusionActor->SetOpacity(0.7);
387       this->UpdateDisplayExtent();
388       this->GetRenderer()->AddActor(mFusionActor);
389     }
390
391     //Synchronize slice
392     SetTSlice(mCurrentTSlice);
393   }
394 }
395 //------------------------------------------------------------------------------
396
397
398 //------------------------------------------------------------------------------
399 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
400 {
401   if (actor_type == "vector") {
402     this->mVFActor->SetVisibility(vis);
403   }
404   if (actor_type == "overlay") {
405     this->mOverlayActor->SetVisibility(vis);
406   }
407   if (actor_type == "fusion") {
408     this->mFusionActor->SetVisibility(vis);
409   }
410   if (actor_type == "contour")
411     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
412   UpdateDisplayExtent();
413 }
414 //------------------------------------------------------------------------------
415
416
417 //------------------------------------------------------------------------------
418 void vvSlicer::SetVF(vvImage::Pointer vf)
419 {
420   if (vf->GetVTKImages().size()) {
421     mVF = vf;
422
423     if (!mAAFilter) {
424       mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
425       mVOIFilter = vtkSmartPointer<vtkExtractVOI>::New();
426       mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
427     }
428     mVOIFilter->SetInput(vf->GetTransformedVTKImages()[0]);
429     mAAFilter->SetInput(mVOIFilter->GetOutput());
430     ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
431     mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
432
433     if (!mArrow)
434       mArrow = vtkSmartPointer<vvGlyphSource>::New();
435     mArrow->SetGlyphTypeToSpecificArrow();
436     mArrow->SetScale(mScale);
437     mArrow->FilledOff();
438
439     // Glyph the gradient vector (with arrows)
440     if (!mGlyphFilter)
441       mGlyphFilter = vtkSmartPointer<vvGlyph2D>::New();
442     mGlyphFilter->SetInput(mAAFilter->GetOutput());
443     mGlyphFilter->SetSource(mArrow->GetOutput());
444     mGlyphFilter->ScalingOn();
445     mGlyphFilter->SetScaleModeToScaleByVector();
446     mGlyphFilter->OrientOn();
447     mGlyphFilter->SetVectorModeToUseVector();
448     mGlyphFilter->SetColorModeToColorByVector();
449
450     if (!mVFColorLUT)
451       mVFColorLUT = vtkSmartPointer<vtkLookupTable>::New();
452
453     double mVFColorHSV[3];
454     vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
455     mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
456     mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
457     mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
458
459     if (!mVFMapper)
460       mVFMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
461     mVFMapper->SetInput(mGlyphFilter->GetOutput());
462     mVFMapper->ImmediateModeRenderingOn();
463     mVFMapper->SetLookupTable(mVFColorLUT);
464
465     if (!mVFActor)
466       mVFActor = vtkSmartPointer<vtkActor>::New();
467     mVFActor->SetMapper(mVFMapper);
468     mVFActor->SetPickable(0);
469     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
470     this->UpdateDisplayExtent();
471     this->GetRenderer()->AddActor(mVFActor);
472
473     //Synchronize slice
474     SetTSlice(mCurrentTSlice);
475   }
476 }
477 //------------------------------------------------------------------------------
478
479
480 //------------------------------------------------------------------------------
481 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
482 {
483   mLandmarks = landmarks;
484   if (landmarks) {
485
486     if (!mCross)
487       mCross = vtkSmartPointer<vtkCursor3D>::New();
488     mCross->SetFocalPoint(0.0,0.0,0.0);
489     mCross->SetModelBounds(-10,10,-10,10,-10,10);
490     mCross->AllOff();
491     mCross->AxesOn();
492
493     if (!mLandGlyph)
494       mLandGlyph = vtkSmartPointer<vtkGlyph3D>::New();
495     mLandGlyph->SetSource(mCross->GetOutput());
496     mLandGlyph->SetInput(landmarks->GetOutput());
497     //mLandGlyph->SetIndexModeToScalar();
498     mLandGlyph->SetRange(0,1);
499     mLandGlyph->ScalingOff();
500
501     mLandGlyph->SetColorModeToColorByScalar();
502
503     if (!mClipBox)
504       mClipBox = vtkSmartPointer<vtkBox>::New();
505     if (!mLandClipper)
506       mLandClipper = vtkSmartPointer<vtkClipPolyData>::New();
507     mLandClipper->InsideOutOn();
508     mLandClipper->SetInput(mLandGlyph->GetOutput());
509     mLandClipper->SetClipFunction(mClipBox);
510
511     if (!mLandMapper)
512       mLandMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
513     mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
514     //mLandMapper->ScalarVisibilityOff();
515
516     if (!mLandActor)
517       mLandActor = vtkSmartPointer<vtkActor>::New();
518     mLandActor->SetMapper(mLandMapper);
519     mLandActor->GetProperty()->SetColor(255,10,212);
520     mLandActor->SetPickable(0);
521     mLandActor->SetVisibility(true);
522     this->UpdateDisplayExtent();
523     this->GetRenderer()->AddActor(mLandActor);
524   }
525 }
526 //------------------------------------------------------------------------------
527
528 //------------------------------------------------------------------------------
529 //FIXME: this function leaks memory, we should fix it someday :)
530 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
531 {
532   if (actor_type == "vector") {
533     Renderer->RemoveActor(mVFActor);
534     mGlyphFilter=NULL;
535     mVF = NULL;
536     mArrow = NULL;
537     mAAFilter=NULL;
538     mVOIFilter = NULL;
539     mVFMapper = NULL;
540     mVFActor = NULL;
541   }
542   if (actor_type == "overlay") {
543     Renderer->RemoveActor(mOverlayActor);
544     mOverlay = NULL;
545     mOverlayActor = NULL;
546     mOverlayMapper = NULL;
547   }
548   if (actor_type == "fusion") {
549     Renderer->RemoveActor(mFusionActor);
550     mFusion = NULL;
551     mFusionActor = NULL;
552     mFusionMapper = NULL;
553   }
554   if (actor_type == "contour") {
555     Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
556     mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
557   }
558 }
559 //------------------------------------------------------------------------------
560
561
562 //------------------------------------------------------------------------------
563 void vvSlicer::SetVFSubSampling(int sub)
564 {
565   if (mVOIFilter) {
566     mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
567     mSubSampling = sub;
568   }
569   UpdateDisplayExtent();
570   Render();
571 }
572 //------------------------------------------------------------------------------
573
574
575 //------------------------------------------------------------------------------
576 void vvSlicer::SetVFScale(int scale)
577 {
578   mScale = scale;
579   if (mArrow)
580     mArrow->SetScale(mScale);
581   UpdateDisplayExtent();
582   Render();
583 }
584 //------------------------------------------------------------------------------
585
586 //------------------------------------------------------------------------------
587 void vvSlicer::SetVFWidth(int width)
588 {
589   mVFWidth = width;
590   if (mVFActor)
591     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
592   UpdateDisplayExtent();
593   Render();
594 }
595 //------------------------------------------------------------------------------
596
597
598 //------------------------------------------------------------------------------
599 void vvSlicer::SetVFLog(int log)
600 {
601   mVFLog = log;
602   if (mGlyphFilter) {
603     mGlyphFilter->SetUseLog(mVFLog);
604     mGlyphFilter->Modified();
605   }
606   UpdateDisplayExtent();
607   Render();
608 }
609 //------------------------------------------------------------------------------
610
611
612 //------------------------------------------------------------------------------
613 void vvSlicer::SetTSlice(int t)
614 {
615   if (t < 0)
616     t = 0;
617   else if ((unsigned int)t >= mImage->GetVTKImages().size())
618     t = mImage->GetVTKImages().size() -1;
619
620   if (mCurrentTSlice == t) return;
621
622   mCurrentTSlice = t;
623   this->SetInput(mImage->GetTransformedVTKImages()[t]);
624   if (mVF && mVFActor->GetVisibility()) {
625     if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
626       mVOIFilter->SetInput(mVF->GetTransformedVTKImages()[mCurrentTSlice]);
627   }
628   if (mOverlay && mOverlayActor->GetVisibility()) {
629     if (mOverlay->GetTransformedVTKImages().size() > (unsigned int)mCurrentTSlice)
630       mOverlayMapper->SetInput(mOverlay->GetTransformedVTKImages()[mCurrentTSlice]);
631   }
632   if (mFusion && mFusionActor->GetVisibility()) {
633     if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
634       mFusionMapper->SetInput(mFusion->GetTransformedVTKImages()[mCurrentTSlice]);
635   }
636   if (mSurfaceCutActors.size() > 0)
637     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
638          i!=mSurfaceCutActors.end(); i++)
639       (*i)->SetTimeSlice(mCurrentTSlice);
640   UpdateDisplayExtent();
641 }
642 //------------------------------------------------------------------------------
643
644
645 //------------------------------------------------------------------------------
646 int vvSlicer::GetTSlice()
647 {
648   return mCurrentTSlice;
649 }
650 //------------------------------------------------------------------------------
651
652
653 //------------------------------------------------------------------------------
654 void vvSlicer::SetSliceOrientation(int orientation)
655 {
656   //if 2D image, force to watch in Axial View
657   int extent[6];
658   this->GetInput()->GetWholeExtent(extent);
659   if (extent[5]-extent[4] <= 2)
660     orientation=2;
661
662   if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
663       orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) {
664     vtkErrorMacro("Error - invalid slice orientation " << orientation);
665     return;
666   }
667
668   this->SliceOrientation = orientation;
669
670   // Update the viewer
671   int *range = this->GetSliceRange();
672   if (range)
673     this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
674
675   // Go to current cursor position
676   // double* cursorPos = GetCursorPosition();
677   // DDV(cursorPos, 3);
678   // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
679
680   this->UpdateOrientation();
681   this->UpdateDisplayExtent();
682
683   if (this->Renderer && this->GetInput()) {
684     double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
685     this->Renderer->ResetCamera();
686     this->Renderer->GetActiveCamera()->SetParallelScale(scale);
687   }
688
689   SetContourSlice();
690 }
691 //----------------------------------------------------------------------------
692
693
694 //----------------------------------------------------------------------------
695 int * vvSlicer::GetExtent()
696 {
697   int *w_ext;
698   if (mUseReducedExtent) {
699     w_ext = mReducedExtent;
700   } else w_ext = GetInput()->GetWholeExtent();
701   return w_ext;
702 }
703 //----------------------------------------------------------------------------
704
705
706 //----------------------------------------------------------------------------
707 int vvSlicer::GetOrientation()
708 {
709   return this->SliceOrientation;
710 }
711 //----------------------------------------------------------------------------
712
713 //----------------------------------------------------------------------------
714 void vvSlicer::UpdateDisplayExtent()
715 {
716   vtkImageData *input = this->GetInput();
717   if (!input || !this->ImageActor) {
718     return;
719   }
720   input->UpdateInformation();
721
722   // Local copy of extent
723   int w_ext[6];
724   for(unsigned int i=0; i<6; i++){
725     if (mUseReducedExtent)
726       w_ext[i] = mReducedExtent[i];
727     else  
728       w_ext[i] = input->GetWholeExtent()[i];
729   }
730
731   // Set slice value
732   w_ext[ this->SliceOrientation*2   ] = this->Slice;
733   w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
734   
735   // Image actor
736   this->ImageActor->SetDisplayExtent(w_ext);
737   
738   // Position vector
739   double position[3] = {0.,0.,0.};
740   double positionInc = (Renderer->GetActiveCamera()->GetPosition()[this->SliceOrientation] > this->Slice)?10:-10;
741   position[this->SliceOrientation] += positionInc;
742   
743   // Overlay image actor
744   if (mOverlay && mOverlayActor->GetVisibility()) {
745     int overExtent[6];
746     mOverlay->GetTransformedVTKImages()[0]->UpdateInformation();
747     this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlay->GetTransformedVTKImages()[0], overExtent);
748     ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
749     mOverlayActor->SetDisplayExtent( overExtent );
750     mOverlayActor->SetPosition(position);
751   }
752   position[this->SliceOrientation] += positionInc;
753
754   // Fusion image actor
755   if (mFusion && mFusionActor->GetVisibility()) {
756     int fusExtent[6];
757     mFusion->GetTransformedVTKImages()[0]->UpdateInformation();
758     this->ConvertImageToImageDisplayExtent(input, w_ext, mFusion->GetTransformedVTKImages()[0], fusExtent);
759     ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
760     mFusionActor->SetDisplayExtent(fusExtent);
761     mFusionActor->SetPosition(position);
762   }
763   position[this->SliceOrientation] += positionInc;
764
765   // Vector field actor
766   if (mVF && mVFActor->GetVisibility()) {
767     int vfExtent[6];
768     mVF->GetTransformedVTKImages()[0]->UpdateInformation();
769     this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetTransformedVTKImages()[0], vfExtent);
770     ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
771     mVOIFilter->SetVOI(vfExtent);
772     int orientation[3] = {1,1,1};
773     orientation[this->SliceOrientation] = 0;
774     mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]);
775     mVFMapper->Update();
776     mVFActor->SetPosition(position);
777   }
778   position[this->SliceOrientation] += positionInc;
779
780   // Landmarks actor
781   if (mLandActor) {
782     if (mClipBox) {
783       double bounds [6];
784       for(unsigned int i=0; i<6; i++)
785         bounds[i] = ImageActor->GetBounds()[i];
786       bounds[ this->SliceOrientation*2   ] = ImageActor->GetBounds()[ this->SliceOrientation*2  ]-fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]);
787       bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]);
788       mClipBox->SetBounds(bounds);
789       UpdateLandmarks();
790     }
791     mLandActor->SetPosition(position);
792   }
793
794   // Figure out the correct clipping range
795   if (this->Renderer) {
796     if (this->InteractorStyle &&
797         this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
798       this->Renderer->ResetCameraClippingRange();
799     } else {
800       vtkCamera *cam = this->Renderer->GetActiveCamera();
801       if (cam) {
802         double bounds[6];
803         this->ImageActor->GetBounds(bounds);
804         double spos = (double)bounds[this->SliceOrientation * 2];
805         double cpos = (double)cam->GetPosition()[this->SliceOrientation];
806         double range = fabs(spos - cpos);
807         double *spacing = input->GetSpacing();
808         double avg_spacing =
809           ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
810         cam->SetClippingRange(range - avg_spacing * 3.0, range + avg_spacing * 3.0);
811       }
812     }
813   }
814 }
815 //----------------------------------------------------------------------------
816
817 //----------------------------------------------------------------------------
818 void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6],
819                                                 vtkImageData *targetImage, int targetExtent[6])
820 {
821   double dExtents[6];
822   for(unsigned int i=0; i<6; i++) {
823     // From source voxel coordinates to world coordinates
824     dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i];
825
826     // From world coordinates to floating point target voxel coordinates
827     dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
828     
829     // Round to nearest
830     targetExtent[i] = itk::Math::Round(dExtents[i]);
831   }
832 }
833 //----------------------------------------------------------------------------
834
835 //----------------------------------------------------------------------------
836 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
837 {
838   bool out = false;
839   int maxBound = 6;
840
841   //2D overlay on 3D image specific case
842   if (refExtent[4] == refExtent[5]) {
843     maxBound = 4;
844     extent[4] = refExtent[4];
845     extent[5] = refExtent[5];
846   }
847
848   for (int i = 0; i < maxBound; i = i+2) {
849     //if we are totally outside the image
850     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
851       out = true;
852       break;
853     }
854     //crop to the limit of the image
855     extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
856     extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
857     extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
858     extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
859   }
860   if (out)
861     for (int i = 0; i < maxBound; i = i+2) {
862       extent[i] = refExtent[i];
863       extent[i+1] = refExtent[i];
864     }
865 }
866 //----------------------------------------------------------------------------
867
868
869 //----------------------------------------------------------------------------
870 void vvSlicer::UpdateOrientation()
871 {
872   // Set the camera position
873   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
874   if (cam) {
875     switch (this->SliceOrientation) {
876     case vtkImageViewer2::SLICE_ORIENTATION_XY:
877       cam->SetFocalPoint(0,0,0);
878       cam->SetPosition(0,0,-1); // -1 if medical ?
879       cam->SetViewUp(0,-1,0);
880       break;
881
882     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
883       cam->SetFocalPoint(0,0,0);
884       cam->SetPosition(0,-1,0); // 1 if medical ?
885       cam->SetViewUp(0,0,1);
886       break;
887
888     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
889       cam->SetFocalPoint(0,0,0);
890       cam->SetPosition(-1,0,0); // -1 if medical ?
891       cam->SetViewUp(0,0,1);
892       break;
893     }
894   }
895 }
896 //----------------------------------------------------------------------------
897
898
899 //----------------------------------------------------------------------------
900 void vvSlicer::SetOpacity(double s)
901 {
902   this->GetImageActor()->SetOpacity(s);
903 }
904 //----------------------------------------------------------------------------
905
906
907 //----------------------------------------------------------------------------
908 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
909 {
910   this->Superclass::SetRenderWindow(rw);
911   this->SetupInteractor(rw->GetInteractor());
912   ca->SetImageActor(this->GetImageActor());
913   ca->SetWindowLevel(this->GetWindowLevel());
914   ca->SetText(2, "<slice>");
915   ca->SetText(3, "<window>\n<level>");
916
917   double bounds[6];
918   double max = 65000;
919
920   bounds[0] = -max;
921   bounds[1] = max;
922   bounds[2] = -max;
923   bounds[3] = max;
924   bounds[4] = -max;
925   bounds[5] = max;
926
927   crossCursor->SetModelBounds(bounds);
928   this->GetRenderer()->AddActor(pdmA);
929   this->GetRenderer()->AddActor(ca);
930   this->GetRenderer()->ResetCamera();
931
932   //this is just a mapping between the labeling of the orientations presented to the user and
933   //the one used by vtk
934   SetSliceOrientation(2-(orientation%3));
935   ResetCamera();
936 }
937 //----------------------------------------------------------------------------
938
939
940 //----------------------------------------------------------------------------
941 void vvSlicer::ResetCamera()
942 {
943   this->GetRenderer()->ResetCamera();
944 }
945 //----------------------------------------------------------------------------
946
947
948 //----------------------------------------------------------------------------
949 void vvSlicer::SetDisplayMode(bool i)
950 {
951   this->GetImageActor()->SetVisibility(i);
952   this->GetAnnotation()->SetVisibility(i);
953   this->GetRenderer()->SetDraw(i);
954   if (mLandActor)
955     mLandActor->SetVisibility(i);
956   pdmA->SetVisibility(i);
957   if (i)
958     UpdateDisplayExtent();
959 }
960 //----------------------------------------------------------------------------
961
962
963 //----------------------------------------------------------------------------
964 void vvSlicer::FlipHorizontalView()
965 {
966   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
967   if (cam) {
968     double *position = cam->GetPosition();
969     switch (this->SliceOrientation) {
970     case vtkImageViewer2::SLICE_ORIENTATION_XY:
971       cam->SetPosition(position[0],position[1],-position[2]);
972       break;
973
974     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
975       cam->SetPosition(position[0],-position[1],position[2]);
976       break;
977
978     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
979       cam->SetPosition(-position[0],position[1],position[2]);
980       break;
981     }
982     this->Renderer->ResetCameraClippingRange();
983     this->UpdateDisplayExtent();
984   }
985 }
986 //----------------------------------------------------------------------------
987
988
989 //----------------------------------------------------------------------------
990 void vvSlicer::FlipVerticalView()
991 {
992   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
993   if (cam) {
994     FlipHorizontalView();
995     double *viewup = cam->GetViewUp();
996     cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
997     this->UpdateDisplayExtent();
998   }
999 }
1000 //----------------------------------------------------------------------------
1001
1002
1003 //----------------------------------------------------------------------------
1004 void vvSlicer::SetColorWindow(double window)
1005 {
1006   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1007   if ( LUT ) {
1008     double level = this->GetWindowLevel()->GetLevel();
1009     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1010     LUT->Build();
1011   }
1012   this->vtkImageViewer2::SetColorWindow(window);
1013 }
1014 //----------------------------------------------------------------------------
1015
1016
1017 //----------------------------------------------------------------------------
1018 void vvSlicer::SetColorLevel(double level)
1019 {
1020   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1021   if ( LUT ) {
1022     double window = this->GetWindowLevel()->GetWindow();
1023     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1024     LUT->Build();
1025   }
1026   this->vtkImageViewer2::SetColorLevel(level);
1027 }
1028 //----------------------------------------------------------------------------
1029
1030 //----------------------------------------------------------------------------
1031 // Returns the min an the max value in a 41x41 region around the mouse pointer
1032 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1033 {
1034   //Get mouse pointer position in view coordinates
1035   double fLocalExtents[6];
1036   for(int i=0; i<3; i++) {
1037     fLocalExtents[i*2  ] = mCurrent[i];
1038     fLocalExtents[i*2+1] = mCurrent[i];
1039   }
1040   this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1041   this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1042   for(int i=0; i<3; i++) {
1043     if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1044       fLocalExtents[i*2  ] -= 0.2;
1045       fLocalExtents[i*2+1] += 0.2;
1046     }
1047   }
1048   this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1049   this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1050
1051   //Convert to image pixel coordinates (rounded)
1052   int iLocalExtents[6];
1053   for(int i=0; i<3; i++) {
1054     fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1055     fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1056
1057     iLocalExtents[i*2  ] = lrint(fLocalExtents[i*2  ]);
1058     iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1059
1060     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
1061       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1062   }
1063
1064   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1065   voiFilter->SetInput(this->GetInput());
1066   voiFilter->SetVOI(iLocalExtents);
1067   voiFilter->Update();
1068   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1069     min = 0;
1070     max = 0;
1071     return;
1072   }
1073
1074   vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1075   accFilter->SetInput(voiFilter->GetOutput());
1076   accFilter->Update();
1077
1078   min = *(accFilter->GetMin());
1079   max = *(accFilter->GetMax());
1080 }
1081 //----------------------------------------------------------------------------
1082
1083 //----------------------------------------------------------------------------
1084 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, int X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1085 {
1086   ix = lrint(X);
1087   iy = lrint(Y);
1088   iz = lrint(Z);
1089   if (ix < image->GetWholeExtent()[0] ||
1090       ix > image->GetWholeExtent()[1] ||
1091       iy < image->GetWholeExtent()[2] ||
1092       iy > image->GetWholeExtent()[3] ||
1093       iz < image->GetWholeExtent()[4] ||
1094       iz > image->GetWholeExtent()[5] )
1095     return sqrt(-1.);
1096
1097   image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1098   image->Update();
1099   return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1100 }
1101 //----------------------------------------------------------------------------
1102
1103 //----------------------------------------------------------------------------
1104 void vvSlicer::Render()
1105 {
1106   if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion) {
1107     legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1108     legend->SetVisibility(1);
1109   } else legend->SetVisibility(0);
1110
1111   if (ca->GetVisibility()) {
1112     std::string worldPos = "";
1113     std::stringstream world1;
1114     std::stringstream world2;
1115     std::stringstream world3;
1116     world1 << (int)mCurrent[0];
1117     world2 << (int)mCurrent[1];
1118     world3 << (int)mCurrent[2];
1119     double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1120     double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1121     double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1122     
1123 //     if (X < this->GetInput()->GetWholeExtent()[0]) X = this->GetInput()->GetWholeExtent()[0];
1124 //     else if (X > this->GetInput()->GetWholeExtent()[1]) X = this->GetInput()->GetWholeExtent()[1]; 
1125 //     if (Y < this->GetInput()->GetWholeExtent()[2]) Y = this->GetInput()->GetWholeExtent()[2];
1126 //     else if (Y > this->GetInput()->GetWholeExtent()[3]) Y = this->GetInput()->GetWholeExtent()[3]; 
1127 //     if (Z < this->GetInput()->GetWholeExtent()[4]) Z = this->GetInput()->GetWholeExtent()[4];
1128 //     else if (Z > this->GetInput()->GetWholeExtent()[5]) Z = this->GetInput()->GetWholeExtent()[5]; 
1129
1130     if (X >= this->GetInput()->GetWholeExtent()[0] &&
1131         X <= this->GetInput()->GetWholeExtent()[1] &&
1132         Y >= this->GetInput()->GetWholeExtent()[2] &&
1133         Y <= this->GetInput()->GetWholeExtent()[3] &&
1134         Z >= this->GetInput()->GetWholeExtent()[4] &&
1135         Z <= this->GetInput()->GetWholeExtent()[5]) {
1136
1137       
1138       int ix, iy, iz;
1139       double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz);
1140
1141       std::stringstream pixel1;
1142       std::stringstream pixel2;
1143       std::stringstream pixel3;
1144       std::stringstream temps;
1145       pixel1 << ix;
1146       pixel2 << iy;
1147       pixel3 << iz;
1148       temps << mCurrentTSlice;
1149
1150       std::stringstream val;
1151       val << value;
1152       worldPos += "data value : " + val.str();
1153       worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1154         world3.str() + " " + temps.str();
1155       worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1156         pixel3.str() + " " + temps.str();
1157     }
1158     ca->SetText(1,worldPos.c_str());
1159   }
1160
1161   if (pdmA->GetVisibility()) {
1162     double x = mCursor[0];
1163     double y = mCursor[1];
1164     double z = mCursor[2];
1165     double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1166     double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1167     double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1168
1169     if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1170         xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1171         yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1172         yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1173         zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1174         zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) {
1175       vtkRenderer * renderer = this->Renderer;
1176
1177       renderer->WorldToView(x,y,z);
1178       renderer->ViewToNormalizedViewport(x,y,z);
1179       renderer->NormalizedViewportToViewport(x,y);
1180       renderer->ViewportToNormalizedDisplay(x,y);
1181       renderer->NormalizedDisplayToDisplay(x,y);
1182       crossCursor->SetFocalPoint(x,y,z);
1183     } else
1184       crossCursor->SetFocalPoint(-1,-1,z);
1185   }
1186
1187
1188   if (mOverlay && mOverlayActor->GetVisibility()) {
1189     mOverlayMapper->SetWindow(this->GetColorWindow());
1190     mOverlayMapper->SetLevel(this->GetColorLevel());
1191     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1192     mOverlayMapper->GetOutput()->Update();
1193     mOverlayMapper->Update();
1194   }
1195   if (mLandMapper)
1196     UpdateLandmarks();
1197
1198   this->GetRenderWindow()->Render();
1199 }
1200 //----------------------------------------------------------------------------
1201
1202
1203 //----------------------------------------------------------------------------
1204 void vvSlicer::UpdateCursorPosition()
1205 {
1206   if (this->GetImageActor()->GetVisibility()) {
1207     pdmA->SetVisibility(true);
1208     mCursor[0] = mCurrent[0];
1209     mCursor[1] = mCurrent[1];
1210     mCursor[2] = mCurrent[2];
1211     mCursor[3] = mCurrentTSlice;
1212   }
1213 }
1214 //----------------------------------------------------------------------------
1215
1216
1217 //----------------------------------------------------------------------------
1218 void vvSlicer::UpdateLandmarks()
1219 {
1220   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1221   if (pd->GetPoints()) {
1222     mLandGlyph->SetRange(0,1);
1223     mLandGlyph->Modified();
1224     mLandGlyph->Update();
1225
1226     mClipBox->Modified();
1227     mLandClipper->Update();
1228     mLandMapper->Update();
1229   }
1230
1231 }
1232 //----------------------------------------------------------------------------
1233
1234
1235 //----------------------------------------------------------------------------
1236 void vvSlicer::SetSlice(int slice)
1237 {
1238   int *range = this->GetSliceRange();
1239   if (range) {
1240     if (slice < range[0]) {
1241       slice = range[0];
1242     } else if (slice > range[1]) {
1243       slice = range[1];
1244     }
1245   }
1246
1247   if (this->Slice == slice) {
1248     return;
1249   }
1250
1251   this->Slice = slice;
1252   SetContourSlice();
1253   this->Modified();
1254   this->UpdateDisplayExtent();
1255
1256   // Seems to work without this line
1257   //this->Render();
1258 }
1259 //----------------------------------------------------------------------------
1260
1261
1262 //----------------------------------------------------------------------------
1263 void vvSlicer::SetContourSlice()
1264 {
1265   if (mSurfaceCutActors.size() > 0)
1266     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1267          i!=mSurfaceCutActors.end(); i++)
1268       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1269                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1270 }
1271 //----------------------------------------------------------------------------
1272
1273
1274 //----------------------------------------------------------------------------
1275 void vvSlicer::ForceUpdateDisplayExtent()
1276 {
1277   this->UpdateDisplayExtent();
1278 }
1279 //----------------------------------------------------------------------------
1280
1281
1282 //----------------------------------------------------------------------------
1283 int* vvSlicer::GetDisplayExtent()
1284 {
1285   return this->GetImageActor()->GetDisplayExtent();
1286 }
1287 //----------------------------------------------------------------------------
1288
1289
1290 //----------------------------------------------------------------------------
1291 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1292 {
1293   this->Superclass::PrintSelf(os, indent);
1294 }
1295 //----------------------------------------------------------------------------
1296
1297 //----------------------------------------------------------------------------
1298 void vvSlicer::SetVFColor(double r, double g, double b)
1299 {
1300   double mVFColorHSV[3];
1301   mVFColor[0] = r;
1302   mVFColor[1] = g;
1303   mVFColor[2] = b;
1304
1305   vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1306   mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1307   mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1308   mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1309
1310   this->Render();
1311 }  
1312