]> Creatis software - clitk.git/blob - vv/vvImageContour.cxx
- correct crop 2D bug
[clitk.git] / vv / vvImageContour.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 "vvImageContour.h"
20 #include "vvImage.h"
21 #include <vtkImageActor.h>
22 #include <vtkCamera.h>
23 #include <vtkRenderer.h>
24 #include <vtkMarchingSquares.h>
25 #include <vtkImageClip.h>
26 #include <vtkImageData.h>
27 #include <vtkPolyDataMapper.h>
28 #include <vtkProperty.h>
29
30 //------------------------------------------------------------------------------
31 vvImageContour::vvImageContour() {
32   mTSlice = -1;
33   mSlice = 0;
34   mHiddenImageIsUsed = false;
35   mDisplayModeIsPreserveMemory = true;
36 }
37 //------------------------------------------------------------------------------
38
39
40 //------------------------------------------------------------------------------
41 vvImageContour::~vvImageContour() {
42   for (unsigned int i = 0; i < mSlicer->GetImage()->GetVTKImages().size(); i++) {
43     mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
44   }
45   mSquaresActorList.clear();
46   mSquaresList.clear();
47   mClipperList.clear();
48 }
49 //------------------------------------------------------------------------------
50
51
52 //------------------------------------------------------------------------------
53 void vvImageContour::setSlicer(vvSlicer * slicer) {
54   mSlicer = slicer;  
55
56   for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
57     vtkImageClip * mClipper = vtkImageClip::New();
58     vtkMarchingSquares * mSquares = vtkMarchingSquares::New();
59     //    vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
60     vtkActor * mSquaresActor = vtkActor::New();
61
62     createNewActor(&mSquaresActor, &mSquares, &mClipper);
63     /*
64     mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
65     mSquares->SetInput(mClipper->GetOutput());
66     mSquaresMapper->SetInput(mSquares->GetOutput());
67     mSquaresMapper->ScalarVisibilityOff();
68     mSquaresActor->SetMapper(mSquaresMapper);
69     mSquaresActor->GetProperty()->SetColor(1.0,0,0);
70     mSquaresActor->SetPickable(0);
71     mSquaresActor->VisibilityOff();
72     mSlicer->GetRenderer()->AddActor(mSquaresActor);
73     */
74     mSquaresActorList.push_back(mSquaresActor);
75     mSquaresList.push_back(mSquares);
76     mClipperList.push_back(mClipper);
77   }
78 }
79 //------------------------------------------------------------------------------
80
81
82 //------------------------------------------------------------------------------
83 void vvImageContour::setImage(vvImage::Pointer image) {
84   DD("vvImageContour::setImage");
85   for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
86     mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
87   }
88   mHiddenImageIsUsed = true;
89   mHiddenImage = image;
90 }
91 //------------------------------------------------------------------------------
92
93
94 //------------------------------------------------------------------------------
95 void vvImageContour::setPreserveModeEnabled(bool b) {
96   DD("setPreserveModeEnabled");
97   DD(b);
98   DD(mDisplayModeIsPreserveMemory);
99   if (mDisplayModeIsPreserveMemory == b) return;
100   mDisplayModeIsPreserveMemory = b;
101   if (!b) {
102     initializeCacheMode();
103   }
104   else {
105     for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
106       mListOfCachedContourActors[d].clear();
107     mListOfCachedContourActors.clear();
108   }
109 }
110 //------------------------------------------------------------------------------
111
112
113 //------------------------------------------------------------------------------
114 void vvImageContour::setColor(double r, double g, double b) {
115   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
116     mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
117   }
118 }
119 //------------------------------------------------------------------------------
120
121
122 //------------------------------------------------------------------------------
123 void vvImageContour::hideActors() {
124   if (!mSlicer) return;
125   mSlice = mSlicer->GetSlice();
126   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
127     mSquaresActorList[i]->VisibilityOff();
128   }
129 }
130 //------------------------------------------------------------------------------
131
132   
133 //------------------------------------------------------------------------------
134 void vvImageContour::showActors() {
135   if (!mSlicer) return;
136   mSlice = mSlicer->GetSlice();
137   mTSlice = mSlicer->GetTSlice();
138   //  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
139   mSquaresActorList[mTSlice]->VisibilityOn();
140   update(mValue);
141   //}
142 }
143 //------------------------------------------------------------------------------
144
145   
146 //------------------------------------------------------------------------------
147 void vvImageContour::update(double value) {
148   if (!mSlicer) return;
149   // Get current threshold value
150   mValue= value;
151   // Get current slice
152   mSlice = mSlicer->GetSlice();
153
154   if (mDisplayModeIsPreserveMemory) {
155     updateWithPreserveMemoryMode();
156   }
157   else {
158     updateWithFastCacheMode();
159   }
160 }
161 //------------------------------------------------------------------------------
162
163
164 //------------------------------------------------------------------------------
165 void vvImageContour::updateWithPreserveMemoryMode() {
166
167   // Only change actor visibility if tslice change
168   if (mTSlice != mSlicer->GetTSlice()) {
169     if (mTSlice != -1) 
170       mSquaresActorList[mTSlice]->VisibilityOff();
171     mTSlice = mSlicer->GetTSlice();
172     mSquaresActorList[mTSlice]->VisibilityOn();
173   }
174   
175   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
176   vtkImageClip * mClipper = mClipperList[mTSlice];
177   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
178   int orientation = computeCurrentOrientation();
179   // DD(orientation);
180
181   updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
182
183   return;
184   
185   // Do it
186   mSquares->SetValue(0, mValue );
187
188   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
189   // DD(extent[0]);
190   // DD(extent[1]);
191   // DD(extent[2]);
192   // DD(extent[3]);
193   // DD(extent[4]);
194   // DD(extent[5]);
195
196   // int* extent2 = mClipper->GetInput()->GetDisplayExtent();
197   // DD(extent2[0]);
198   // DD(extent2[1]);
199   int* extent2 = new int[6];
200   if (mHiddenImageIsUsed) {
201     int * extent3;
202     extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
203     for(int i=0; i<6; i++) extent2[i] = extent3[i];
204     // DD(extent2[0]);
205     // DD(extent2[1]);
206     // DD(extent2[2]);
207     // DD(extent2[3]);
208     // DD(extent2[4]);
209     // DD(extent2[5]);
210     for(int i=0; i<6; i+=2) {
211       if (extent[i] != extent[i+1]) { 
212         // extent[i] = extent2[i]; 
213         // extent[i+1] = extent2[i+1]; 
214       }
215       else {
216         // DD(extent[i]);
217         // DD(mSlicer->GetImage()->GetSpacing()[i/2]);
218         // DD(mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]);
219
220         double s = (double)extent[i]*(double)mSlicer->GetImage()->GetSpacing()[i/2]; // in mm
221         // DD(s);
222         s = s+mSlicer->GetImage()->GetOrigin()[i/2]; // from origin
223         // DD(s);
224         s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[i/2]; // from corner second image
225         s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]; // in voxel
226         // DD(s);
227
228         if (s == floor(s)) { 
229           extent2[i] = extent2[i+1] = (int)floor(s);
230         }
231         else {
232           extent2[i] = (int)floor(s);
233           extent2[i+1] = extent2[i];
234         }
235         // DD(extent2[i]);
236       }
237     }
238   }
239   else extent2 = extent;
240   // DD(extent2[0]);
241   // DD(extent2[1]);
242   // DD(extent2[2]);
243   // DD(extent2[3]);
244   // DD(extent2[4]);
245   // DD(extent2[5]);
246   
247
248   mClipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
249                                  extent2[3],extent2[4],extent2[5]);
250   int i;
251   for (i = 0; i < 6;i = i+2) {
252     if (extent[i] == extent[i+1]) {
253       break;
254     }
255   }
256   
257   switch (i)
258     {
259     case 0:
260       if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > mSlice)
261         {
262           mSquaresActor->SetPosition(1,0,0);
263         }
264       else
265         {
266           mSquaresActor->SetPosition(-1,0,0);
267         }
268       break;
269     case 2:
270       if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > mSlice)
271         {
272           mSquaresActor->SetPosition(0,1,0);
273         }
274       else
275         {
276           mSquaresActor->SetPosition(0,-1,0);
277         }
278       break;
279     case 4:
280       if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > mSlice)
281         {
282           mSquaresActor->SetPosition(0,0,1);
283         }
284       else
285         {
286           mSquaresActor->SetPosition(0,0,-1);
287         }
288       break;
289     }
290   mSquares->Update();
291 }
292 //------------------------------------------------------------------------------
293
294
295 //------------------------------------------------------------------------------
296 void vvImageContour::initializeCacheMode() {
297   DD("vvImageContour::initializeCacheMode");
298     
299   mPreviousSlice = mPreviousOrientation = 0;
300   int dim;
301   if (mHiddenImageIsUsed) dim = mHiddenImage->GetNumberOfDimensions();
302   else dim = mSlicer->GetImage()->GetNumberOfDimensions();
303   DD(dim);
304
305   mListOfCachedContourActors.resize(dim);
306   for(int d=0; d<dim; d++) {
307     DD(d);
308     int size;
309     if (mHiddenImageIsUsed) size = mHiddenImage->GetSize()[d];
310     else size = mSlicer->GetImage()->GetSize()[d];
311     DD(size);
312     mListOfCachedContourActors[d].resize(size);
313     for(int j=0; j<size; j++) {
314       mListOfCachedContourActors[d][j] = NULL;
315       DD(mListOfCachedContourActors.size());
316       DD(mListOfCachedContourActors[d].size());
317     }
318   }
319 }
320 //------------------------------------------------------------------------------
321
322
323 //------------------------------------------------------------------------------
324 int vvImageContour::computeCurrentOrientation() {
325   // Get extent of image in the slicer
326   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
327   
328   // Compute orientation
329   int orientation;
330   for (orientation = 0; orientation < 6;orientation = orientation+2) {
331     if (extent[orientation] == extent[orientation+1]) {
332       break;
333     }
334   }
335   orientation = orientation/2;
336   // DD(orientation);
337   return orientation;
338 }
339 //------------------------------------------------------------------------------
340
341
342 //------------------------------------------------------------------------------
343 void vvImageContour::updateWithFastCacheMode() {
344   DD("vvImageContour::updateWithFastCacheMode");
345
346   // Compute orientation
347   int orientation = computeCurrentOrientation();
348
349   // Turn off previous actor
350   DD(mPreviousOrientation);
351   DD(mPreviousSlice);
352   if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
353     mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
354   mPreviousSlice = mSlice;
355   mPreviousOrientation = orientation;
356
357   // Display actor if it exist
358   vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
359   if (actor != NULL) {
360     DD("Actor exist");
361     mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
362   }
363   else {
364     vtkImageClip * mClipper;
365     vtkMarchingSquares * mSquares;
366     vtkActor * mSquaresActor;
367     createNewActor(&mSquaresActor, &mSquares, &mClipper);
368     updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
369     mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
370     mSquaresActor->VisibilityOn();
371   }
372 }
373 //------------------------------------------------------------------------------
374
375
376 //------------------------------------------------------------------------------
377 void vvImageContour::createNewActor(vtkActor ** actor, 
378                                     vtkMarchingSquares ** squares, 
379                                     vtkImageClip ** clipper) {
380   // DD("vvImageContour::CreateNewActor");
381   vtkActor * mSquaresActor = (*actor = vtkActor::New());
382   vtkImageClip * mClipper = (*clipper = vtkImageClip::New());
383   vtkMarchingSquares * mSquares = (*squares = vtkMarchingSquares::New());
384   vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
385   
386   if (mHiddenImageIsUsed) 
387     mClipper->SetInput(mHiddenImage->GetVTKImages()[0]);
388   else 
389     mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[0]);
390   mSquares->SetInput(mClipper->GetOutput());
391   mSquaresMapper->SetInput(mSquares->GetOutput());
392   mSquaresMapper->ScalarVisibilityOff();
393   mSquaresActor->SetMapper(mSquaresMapper);
394   mSquaresActor->GetProperty()->SetColor(1.0,0,0);
395   mSquaresActor->SetPickable(0);
396   mSquaresActor->VisibilityOff();
397   mSlicer->GetRenderer()->AddActor(mSquaresActor);  
398 }
399 //------------------------------------------------------------------------------
400
401
402 //------------------------------------------------------------------------------
403 void vvImageContour::updateActor(vtkActor * actor, 
404                                  vtkMarchingSquares * squares, 
405                                  vtkImageClip * clipper, 
406                                  int threshold, int orientation, int slice) {
407   // DD("Update Actor according to extend/threshold");
408   
409   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
410   clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
411                                  extent[3],extent[4],extent[5]);
412   squares->SetValue(0, threshold);
413
414   switch (orientation)  {
415   case 0: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
416       actor->SetPosition(1,0,0);
417     }
418     else {
419       actor->SetPosition(-1,0,0);
420     }
421     break;
422   case 1: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
423       actor->SetPosition(0,1,0);
424     }
425     else {
426       actor->SetPosition(0,-1,0);
427     }
428     break;
429   case 2: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
430       actor->SetPosition(0,0,1);
431     }
432     else {
433       actor->SetPosition(0,0,-1);
434     }
435     break;
436   }
437   squares->Update();
438 }
439 //------------------------------------------------------------------------------
440
441