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