]> Creatis software - clitk.git/blob - vv/vvImageContour.cxx
- bug corrected
[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   // Create an actor for each time slice
56   for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
57     vtkImageClip * mClipper = vtkImageClip::New();
58     vtkMarchingSquares * mSquares = vtkMarchingSquares::New();
59     vtkActor * mSquaresActor = vtkActor::New();
60     createNewActor(&mSquaresActor, &mSquares, &mClipper, numImage);
61     mSquaresActorList.push_back(mSquaresActor);
62     mSquaresList.push_back(mSquares);
63     mClipperList.push_back(mClipper);
64   }
65 }
66 //------------------------------------------------------------------------------
67
68
69 //------------------------------------------------------------------------------
70 void vvImageContour::setImage(vvImage::Pointer image) {
71   for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
72     mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
73   }
74   mHiddenImageIsUsed = true;
75   mHiddenImage = image;
76 }
77 //------------------------------------------------------------------------------
78
79
80 //------------------------------------------------------------------------------
81 void vvImageContour::setPreserveMemoryModeEnabled(bool b) {
82   // FastCache mode work only if threshold is always the same
83   if (mDisplayModeIsPreserveMemory == b) return;
84   mDisplayModeIsPreserveMemory = b;
85   if (!b) {
86     hideActors();
87     initializeCacheMode();
88   }
89   else {
90     for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
91       mListOfCachedContourActors[d].clear();
92     mListOfCachedContourActors.clear();
93     showActors();
94   }
95 }
96 //------------------------------------------------------------------------------
97
98
99 //------------------------------------------------------------------------------
100 void vvImageContour::setColor(double r, double g, double b) {
101   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
102     mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
103   }
104 }
105 //------------------------------------------------------------------------------
106
107
108 //------------------------------------------------------------------------------
109 void vvImageContour::hideActors() {
110   if (!mSlicer) return;
111   mSlice = mSlicer->GetSlice();
112   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
113     mSquaresActorList[i]->VisibilityOff();
114   }
115 }
116 //------------------------------------------------------------------------------
117
118   
119 //------------------------------------------------------------------------------
120 void vvImageContour::showActors() {
121   if (!mSlicer) return;
122   mSlice = mSlicer->GetSlice();
123   mTSlice = mSlicer->GetTSlice();
124   //  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
125   mSquaresActorList[mTSlice]->VisibilityOn();
126   update(mValue);
127   //}
128 }
129 //------------------------------------------------------------------------------
130
131   
132 //------------------------------------------------------------------------------
133 void vvImageContour::update(double value) {
134   if (!mSlicer) return;
135   if (mPreviousValue == value) {
136     if (mPreviousSlice == mSlicer->GetSlice()) {
137       if (mPreviousTSlice == mSlicer->GetTSlice()) {
138         return; // Nothing to do
139       }
140     }
141   }
142
143   // Get current threshold value
144   mValue = value;
145
146   // Get current slice
147   mSlice = mSlicer->GetSlice();
148
149   if (mDisplayModeIsPreserveMemory) {
150     updateWithPreserveMemoryMode();
151   }
152   else {
153     updateWithFastCacheMode();
154   }
155   mSlicer->Render();
156   mPreviousTSlice = mSlicer->GetTSlice();
157   mPreviousSlice  = mSlicer->GetSlice();
158   mPreviousValue  = value;
159 }
160 //------------------------------------------------------------------------------
161
162
163 //------------------------------------------------------------------------------
164 void vvImageContour::updateWithPreserveMemoryMode() {
165   // Only change actor visibility if tslice change
166   //DD(mTSlice);
167   //DD(mSlice);
168   int mPreviousTslice = mTSlice;
169   //    ;
170   //   if (mTSlice != mSlicer->GetTSlice()) {
171   //     if (mTSlice != -1) mTsliceToSetOff = mTSlice;
172   //       mSquaresActorList[mTSlice]->VisibilityOff();
173   mTSlice = mSlicer->GetTSlice();
174   //   }
175   //  else return;
176   //  DD(mTSlice);
177   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
178   vtkImageClip * mClipper = mClipperList[mTSlice];
179   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
180   int orientation = computeCurrentOrientation();
181   updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
182   mSquaresActorList[mTSlice]->VisibilityOn();
183   if (mPreviousTslice != mTSlice) {
184     if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
185   }
186 }
187 //------------------------------------------------------------------------------
188
189
190 //------------------------------------------------------------------------------
191 void vvImageContour::initializeCacheMode() {
192   mPreviousSlice = mPreviousOrientation = 0;
193   int dim = mSlicer->GetImage()->GetNumberOfDimensions();
194
195   mListOfCachedContourActors.resize(dim);
196   for(int d=0; d<dim; d++) {
197     int size = mSlicer->GetImage()->GetSize()[d];
198     //DD(size);
199     mListOfCachedContourActors[d].resize(size);
200     for(int j=0; j<size; j++) {
201       mListOfCachedContourActors[d][j] = NULL;
202     }
203   }
204 }
205 //------------------------------------------------------------------------------
206
207
208 //------------------------------------------------------------------------------
209 int vvImageContour::computeCurrentOrientation() {
210   // Get extent of image in the slicer
211   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
212   
213   // Compute orientation
214   int orientation;
215   for (orientation = 0; orientation < 6;orientation = orientation+2) {
216     if (extent[orientation] == extent[orientation+1]) {
217       break;
218     }
219   }
220   orientation = orientation/2;
221   return orientation;
222 }
223 //------------------------------------------------------------------------------
224
225
226 //------------------------------------------------------------------------------
227 void vvImageContour::updateWithFastCacheMode() {
228   // Compute orientation
229   int orientation = computeCurrentOrientation();
230
231   if ((mPreviousSlice == mSlice) && (mPreviousOrientation == orientation)) return;
232
233   vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
234   if (actor != NULL) {
235     mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
236   }
237   else {
238     vtkImageClip * mClipper;
239     vtkMarchingSquares * mSquares;
240     vtkActor * mSquaresActor;
241     createNewActor(&mSquaresActor, &mSquares, &mClipper, 0);
242     updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
243     mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
244     mSquaresActor->VisibilityOn();
245   }
246
247   if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
248     mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
249   mPreviousSlice = mSlice;
250   mPreviousOrientation = orientation;
251 }
252 //------------------------------------------------------------------------------
253
254
255 //------------------------------------------------------------------------------
256 void vvImageContour::createNewActor(vtkActor ** actor, 
257                                     vtkMarchingSquares ** squares, 
258                                     vtkImageClip ** clipper, 
259                                     int numImage) {
260   vtkActor * mSquaresActor = (*actor = vtkActor::New());
261   vtkImageClip * mClipper = (*clipper = vtkImageClip::New());
262   vtkMarchingSquares * mSquares = (*squares = vtkMarchingSquares::New());
263   vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
264   
265   if (mHiddenImageIsUsed) 
266     mClipper->SetInput(mHiddenImage->GetVTKImages()[0]);
267   else 
268     mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
269   mSquares->SetInput(mClipper->GetOutput());
270   mSquaresMapper->SetInput(mSquares->GetOutput());
271   mSquaresMapper->ScalarVisibilityOff();
272   mSquaresActor->SetMapper(mSquaresMapper);
273   mSquaresActor->GetProperty()->SetColor(1.0,0,0);
274   mSquaresActor->SetPickable(0);
275   mSquaresActor->VisibilityOff();
276   mSlicer->GetRenderer()->AddActor(mSquaresActor);  
277 }
278 //------------------------------------------------------------------------------
279
280
281 //------------------------------------------------------------------------------
282 void vvImageContour::updateActor(vtkActor * actor, 
283                                  vtkMarchingSquares * squares, 
284                                  vtkImageClip * clipper, 
285                                  double threshold, int orientation, int slice) {
286   
287   // Set parameter for the MarchigSquare
288   squares->SetValue(0, threshold);
289
290   // Get image extent
291   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
292
293   // Change extent if needed
294   int* extent2;
295   if (mHiddenImageIsUsed) {
296     extent2 = new int[6];
297     int * extent3;
298     extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
299     for(int i=0; i<6; i++) extent2[i] = extent3[i];
300     
301     double s = (double)extent[orientation*2]*(double)mSlicer->GetImage()->GetSpacing()[orientation]; // in mm
302     s = s+mSlicer->GetImage()->GetOrigin()[orientation]; // from origin
303     s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[orientation]; // from corner second image
304     s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[orientation]; // in voxel
305     
306     if (s == floor(s)) { 
307       extent2[orientation*2] = extent2[orientation*2+1] = (int)floor(s);
308     }
309     else {
310       extent2[orientation*2] = (int)floor(s);
311       extent2[orientation*2+1] = extent2[orientation*2];
312     }
313   }
314   else {
315     extent2 = extent;
316   }
317   clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
318                                 extent2[3],extent2[4],extent2[5]);
319
320   if (mHiddenImage) delete extent2;
321
322   // Move the actor to be visible
323   // DD(orientation);
324 //   DD(slice);
325
326   //TO SIMPLiFY :!!!!!!!!! == ???????
327   // actor->SetPosition(-1,-1,-1);
328  
329   switch (orientation)  {
330   case 0: 
331     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0]);
332     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
333       actor->SetPosition(1,0,0);
334     }
335     else {
336       actor->SetPosition(-1,0,0);
337     }
338     break;
339   case 1: 
340     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1]);
341     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
342       actor->SetPosition(0,1,0);
343     }
344     else {
345       actor->SetPosition(0,-1,0);
346     }
347     break;
348   case 2: 
349     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2]);
350     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
351       // DD("1");
352       actor->SetPosition(0,0,1);
353     }
354     else {
355       // DD("-1");
356       actor->SetPosition(0,0,-1);
357     }
358     break;
359   }
360
361   squares->Update();
362 }
363 //------------------------------------------------------------------------------
364
365