]> Creatis software - clitk.git/blob - vv/vvImageContour.cxx
ROI & Contour Debug Try
[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://www.centreleonberard.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 <vtkVersion.h>
22 #include <vtkImageActor.h>
23 #include <vtkCamera.h>
24 #include <vtkRenderer.h>
25 #include <vtkMarchingSquares.h>
26 #include <vtkImageClip.h>
27 #include <vtkImageData.h>
28 #include <vtkPolyDataMapper.h>
29 #include <vtkProperty.h>
30
31 //------------------------------------------------------------------------------
32 vvImageContour::vvImageContour()
33 { //out << __func__ << endl;
34   mTSlice = -1;
35   mSlice = 0;
36   mHiddenImageIsUsed = false;
37   mDisplayModeIsPreserveMemory = true;
38   SetPreserveMemoryModeEnabled(true);
39   mPreviousOrientation = -1;
40   mDepth = 1.0;
41   mSlice = 0;
42 }
43 //------------------------------------------------------------------------------
44
45
46 //------------------------------------------------------------------------------
47 vvImageContour::~vvImageContour()
48 { //out << __func__ << endl;
49   mSquaresActorList.clear();
50 }
51 //------------------------------------------------------------------------------
52
53
54 //------------------------------------------------------------------------------
55 void vvImageContour::RemoveActors()
56 { //out << __func__ << endl;
57   for (unsigned int i = 0; i < mSquaresActorList.size(); i++) {
58     if (mSlicer != 0) {
59       if (mSlicer!= NULL) {
60         if (mSlicer->GetRenderer() != NULL) {
61           if (mSquaresActorList[i] != NULL)  {
62             mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
63           }
64         }
65       }   
66     }
67   }
68 }
69 //------------------------------------------------------------------------------
70
71
72 //------------------------------------------------------------------------------
73 void vvImageContour::SetSlicer(vvSlicer * slicer) 
74 { //out << __func__ << endl;
75   mSlicer = slicer;  
76   // Create an actor for each time slice
77   for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
78     CreateNewActor(numImage);
79   }
80 }
81 //------------------------------------------------------------------------------
82
83
84 //------------------------------------------------------------------------------
85 void vvImageContour::SetImage(vvImage::Pointer image) 
86 { //out << __func__ << endl;
87   for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
88 #if VTK_MAJOR_VERSION <= 5
89     mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
90 #else
91     mClipperList[numImage]->SetInputData(image->GetVTKImages()[numImage]);
92 #endif
93   }
94   mHiddenImageIsUsed = true;
95   mHiddenImage = image;
96 }
97 //------------------------------------------------------------------------------
98
99
100 //------------------------------------------------------------------------------
101 void vvImageContour::SetPreserveMemoryModeEnabled(bool b) 
102 { //out << __func__ << endl;
103   // FastCache mode work only if threshold is always the same
104   if (mDisplayModeIsPreserveMemory == b) return;
105   mDisplayModeIsPreserveMemory = b;
106   if (!b) {
107     clitkExceptionMacro("TODO : not implemented yet");
108     HideActors();
109     InitializeCacheMode();
110   }
111   else {
112     for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
113       mListOfCachedContourActors[d].clear();
114     mListOfCachedContourActors.clear();
115     ShowActors();
116   }
117 }
118 //------------------------------------------------------------------------------
119
120
121 //------------------------------------------------------------------------------
122 void vvImageContour::SetColor(double r, double g, double b) 
123 { //out << __func__ << endl;
124   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
125     mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
126   }
127 }
128 //------------------------------------------------------------------------------
129
130
131 //------------------------------------------------------------------------------
132 void vvImageContour::SetLineWidth(double w)
133 { //out << __func__ << endl;
134   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
135     mSquaresActorList[i]->GetProperty()->SetLineWidth(w);
136   }
137 }
138 //------------------------------------------------------------------------------
139
140
141 //------------------------------------------------------------------------------
142 void vvImageContour::HideActors() 
143 { //out << __func__ << endl;
144   if (!mSlicer) return;
145   mSlice = mSlicer->GetSlice();
146   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
147     mSquaresActorList[i]->VisibilityOff();
148   }
149 }
150 //------------------------------------------------------------------------------
151
152
153 //------------------------------------------------------------------------------
154 void vvImageContour::ShowActors() 
155 { //out << __func__ << endl;
156   if (!mSlicer) return;
157   mSlice = mSlicer->GetSlice();
158   mTSlice = mSlicer->GetTSlice();
159   mSquaresActorList[mTSlice]->VisibilityOn();
160   Update(mValue);
161 }
162 //------------------------------------------------------------------------------
163
164
165 //------------------------------------------------------------------------------
166 void vvImageContour::SetDepth(double d) 
167 { //out << __func__ << endl;
168   mDepth = d;
169   // Move the actor to be visible
170   double position[3] = {0, 0, 0};
171   int orientation = ComputeCurrentOrientation();
172   position[orientation] = -mDepth;
173
174   for(unsigned int i=0; i<mSquaresActorList.size(); i++)
175     mSquaresActorList[i]->SetPosition(position);
176 }
177 //------------------------------------------------------------------------------
178
179 //------------------------------------------------------------------------------
180 void vvImageContour::Update(double value) 
181 { //out << __func__ << endl;
182   if (!mSlicer) return;
183   if (mPreviousValue == value) {
184     if (mPreviousSlice == mSlicer->GetSlice()) {
185       if (mPreviousTSlice == mSlicer->GetTSlice()) {
186         if (mPreviousOrientation == ComputeCurrentOrientation()) {
187           return; // Nothing to do
188         }
189       }
190     }
191   }
192
193   // Get current threshold value
194   mValue = value;
195
196   // Get current slice
197   mSlice = mSlicer->GetSlice();
198
199   if (mDisplayModeIsPreserveMemory) {
200     UpdateWithPreserveMemoryMode();
201   }
202   else {
203     UpdateWithFastCacheMode();
204   }
205
206   //mSlicer->Render(); //DS ---> REMOVE ??
207
208   mPreviousTSlice = mSlicer->GetTSlice();
209   mPreviousSlice  = mSlicer->GetSlice();
210   mPreviousValue  = value;
211   mPreviousOrientation = ComputeCurrentOrientation();
212 }
213 //------------------------------------------------------------------------------
214
215
216 //------------------------------------------------------------------------------
217 void vvImageContour::UpdateWithPreserveMemoryMode() 
218 { //out << __func__ << endl;
219   // Only change actor visibility if tslice change
220   mPreviousTslice = mTSlice;
221   mTSlice = mSlicer->GetTSlice();
222
223   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
224   vtkPolyDataMapper* mapper = mSquaresMapperList[mTSlice];
225   vtkImageClip * mClipper = mClipperList[mTSlice];
226   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
227   int orientation = ComputeCurrentOrientation();
228
229   //UpdateActor(mSquaresActor, mapper, mSquares, mClipper, mValue, orientation, mSlice);
230
231   if (mPreviousTslice != mTSlice) {
232     if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
233   }
234   
235   mSlicer->Render();
236 }
237 //------------------------------------------------------------------------------
238
239
240 //------------------------------------------------------------------------------
241 void vvImageContour::InitializeCacheMode() 
242 { //out << __func__ << endl;
243 clitkExceptionMacro("TODO : not implemented yet");
244   mPreviousSlice = mPreviousOrientation = 0;
245   int dim = mSlicer->GetImage()->GetNumberOfDimensions();
246
247   mListOfCachedContourActors.resize(dim);
248   for(int d=0; d<dim; d++) {
249     int size = mSlicer->GetImage()->GetSize()[d];
250     mListOfCachedContourActors[d].resize(size);
251     for(int j=0; j<size; j++) {
252       mListOfCachedContourActors[d][j] = NULL;
253     }
254   }
255 }
256 //------------------------------------------------------------------------------
257
258
259 //------------------------------------------------------------------------------
260 int vvImageContour::ComputeCurrentOrientation() 
261 { //out << __func__ << endl;
262   // Get extent of image in the slicer
263   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
264
265   // Compute orientation
266   int orientation;
267   for (orientation = 0; orientation < 6; orientation = orientation+2) {
268     if (extent[orientation] == extent[orientation+1]) {
269       break;
270     }
271   }
272   orientation = orientation/2;
273   return orientation;
274 }
275 //------------------------------------------------------------------------------
276
277
278 //------------------------------------------------------------------------------
279 void vvImageContour::UpdateWithFastCacheMode() 
280 { //out << __func__ << endl;
281 clitkExceptionMacro("TODO : not implemented yet");
282
283   // Compute orientation
284   int orientation = ComputeCurrentOrientation();
285
286   if ((mPreviousSlice == mSlice) && (mPreviousOrientation == orientation)) return;
287
288   vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
289   if (actor != NULL) {
290     mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
291   } else {
292     CreateNewActor(0);
293     //SR: commented out, this code is never reached anyway
294     //UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
295     //mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
296     //mSquaresActor->VisibilityOn();
297   }
298
299   if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
300     mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
301   mPreviousSlice = mSlice;
302   mPreviousOrientation = orientation;
303 }
304 //------------------------------------------------------------------------------
305
306
307 //------------------------------------------------------------------------------
308 void vvImageContour::CreateNewActor(int numImage) 
309 { //out << __func__ << endl;
310   vtkSmartPointer<vtkActor> squaresActor = vtkSmartPointer<vtkActor>::New();
311   vtkSmartPointer<vtkImageClip> clipper = vtkSmartPointer<vtkImageClip>::New();
312   vtkSmartPointer<vtkMarchingSquares> squares = vtkSmartPointer<vtkMarchingSquares>::New();
313   vtkSmartPointer<vtkPolyDataMapper> squaresMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
314
315   if (mHiddenImageIsUsed) {
316 #if VTK_MAJOR_VERSION <= 5
317     clipper->SetInput(mHiddenImage->GetVTKImages()[0]);
318 #else
319     clipper->SetInputData(mHiddenImage->GetVTKImages()[0]);
320 #endif
321   } else {
322 #if VTK_MAJOR_VERSION <= 5
323     clipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
324 #else
325     clipper->SetInputData(mSlicer->GetImage()->GetVTKImages()[numImage]);
326 #endif
327   }
328 clipper->Update();
329 #if VTK_MAJOR_VERSION <= 5
330   squares->SetInput(clipper->GetOutput());
331   squaresMapper->SetInput(squares->GetOutput());
332 #else
333   squares->SetInputData(clipper->GetOutput());
334   squaresMapper->SetInputData(squares->GetOutput());
335 #endif
336 squares->Update();
337 squaresMapper->Update();
338   squaresMapper->ScalarVisibilityOff();
339   squaresActor->SetMapper(squaresMapper);
340   squaresActor->GetProperty()->SetColor(1.0,0,0);
341   squaresActor->SetPickable(0);
342   squaresActor->VisibilityOff();
343   mSlicer->GetRenderer()->AddActor(squaresActor);
344
345   mSquaresActorList.push_back(squaresActor);
346   mClipperList.push_back(clipper);
347   mSquaresList.push_back(squares);
348   mSquaresMapperList.push_back(squaresMapper);
349 }
350 //------------------------------------------------------------------------------
351
352
353 //------------------------------------------------------------------------------
354 void vvImageContour::UpdateActor(vtkActor * actor, 
355                                  vtkPolyDataMapper * mapper, 
356                                  vtkMarchingSquares * squares, 
357                                  vtkImageClip * clipper, 
358                                  double threshold, int orientation, int slice) 
359 { //out << __func__ << endl;
360   // Set parameter for the MarchigSquare
361   squares->SetValue(0, threshold);
362   
363   // Get image extent
364   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
365
366   // Change extent if needed
367   int* extent2;
368   if (mHiddenImageIsUsed) {
369     extent2 = new int[6];
370     int * extent3;
371     extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
372
373     for(int i=0; i<6; i++) extent2[i] = extent3[i];
374
375     double s = (double)extent[orientation*2]*(double)mSlicer->GetImage()->GetSpacing()[orientation]; // in mm
376     s = s+mSlicer->GetImage()->GetOrigin()[orientation]; // from origin
377     s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[orientation]; // from corner second image
378     s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[orientation]; // in voxel
379
380     // Rint to the closest slice
381     extent2[orientation*2+1] = extent2[orientation*2] = (int)lrint(s);
382
383     // Do not display a contour if there is no contour on this slice
384     // DD(extent2[orientation*2+1]);
385     // DD(extent3[orientation*2+1]);
386     // DD(extent2[orientation*2]);
387     // DD(extent3[orientation*2]);
388     if ((extent2[orientation*2+1] > extent3[orientation*2+1]) ||
389         (extent2[orientation*2] < extent3[orientation*2])) {
390       actor->VisibilityOff();
391       return;
392     }
393     else actor->VisibilityOn();
394
395   } else {
396     extent2 = extent;
397     actor->VisibilityOn();
398   }
399   
400   clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
401                                 extent2[3],extent2[4],extent2[5]);
402                                 clipper->Update();
403                                 clipper->Print(cout);
404
405   if (mHiddenImageIsUsed) delete extent2;
406
407   // Move the actor to be visible
408   SetDepth(mDepth);
409   // double position[3] = {0, 0, 0};
410   // DD(mDepth);
411   // position[orientation] = -mDepth;
412   // actor->SetPosition(position);
413   
414   mapper->Update();
415 }
416 //------------------------------------------------------------------------------
417
418