]> Creatis software - clitk.git/blob - vv/vvImageContour.cxx
Fusion windows level is now 4 decimals
[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   //  mSlicer->Render(); //DS ---> REMOVE ??
171
172   mPreviousTSlice = mSlicer->GetTSlice();
173   mPreviousSlice  = mSlicer->GetSlice();
174   mPreviousValue  = value;
175 }
176 //------------------------------------------------------------------------------
177
178
179 //------------------------------------------------------------------------------
180 void vvImageContour::UpdateWithPreserveMemoryMode() {
181   // Only change actor visibility if tslice change
182   //DD(mTSlice);
183   //DD(mSlice);
184   int mPreviousTslice = mTSlice;
185   //    ;
186   //   if (mTSlice != mSlicer->GetTSlice()) {
187   //     if (mTSlice != -1) mTsliceToSetOff = mTSlice;
188   //       mSquaresActorList[mTSlice]->VisibilityOff();
189   mTSlice = mSlicer->GetTSlice();
190   //   }
191   //  else return;
192   //  DD(mTSlice);
193   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
194   vtkImageClip * mClipper = mClipperList[mTSlice];
195   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
196   int orientation = ComputeCurrentOrientation();
197   //  DD(orientation);
198   //DD(mValue);
199   //DD(mSlice);
200   //DD(mPreviousTslice);
201   UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
202   mSquaresActorList[mTSlice]->VisibilityOn();
203   if (mPreviousTslice != mTSlice) {
204     if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
205   }
206 }
207 //------------------------------------------------------------------------------
208
209
210 //------------------------------------------------------------------------------
211 void vvImageContour::InitializeCacheMode() {
212   mPreviousSlice = mPreviousOrientation = 0;
213   int dim = mSlicer->GetImage()->GetNumberOfDimensions();
214
215   mListOfCachedContourActors.resize(dim);
216   for(int d=0; d<dim; d++) {
217     int size = mSlicer->GetImage()->GetSize()[d];
218     //DD(size);
219     mListOfCachedContourActors[d].resize(size);
220     for(int j=0; j<size; j++) {
221       mListOfCachedContourActors[d][j] = NULL;
222     }
223   }
224 }
225 //------------------------------------------------------------------------------
226
227
228 //------------------------------------------------------------------------------
229 int vvImageContour::ComputeCurrentOrientation() {
230   // Get extent of image in the slicer
231   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
232
233   // Compute orientation
234   int orientation;
235   for (orientation = 0; orientation < 6; orientation = orientation+2) {
236     if (extent[orientation] == extent[orientation+1]) {
237       break;
238     }
239   }
240   orientation = orientation/2;
241   return orientation;
242 }
243 //------------------------------------------------------------------------------
244
245
246 //------------------------------------------------------------------------------
247 void vvImageContour::UpdateWithFastCacheMode() {
248   // Compute orientation
249   int orientation = ComputeCurrentOrientation();
250
251   if ((mPreviousSlice == mSlice) && (mPreviousOrientation == orientation)) return;
252
253   vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
254   if (actor != NULL) {
255     mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
256   } else {
257     vtkImageClip * mClipper;
258     vtkMarchingSquares * mSquares;
259     vtkActor * mSquaresActor;
260     CreateNewActor(&mSquaresActor, &mSquares, &mClipper, 0);
261     UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
262     mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
263     mSquaresActor->VisibilityOn();
264   }
265
266   if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
267     mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
268   mPreviousSlice = mSlice;
269   mPreviousOrientation = orientation;
270 }
271 //------------------------------------------------------------------------------
272
273
274 //------------------------------------------------------------------------------
275 void vvImageContour::CreateNewActor(vtkActor ** actor, 
276                                     vtkMarchingSquares ** squares, 
277                                     vtkImageClip ** clipper, 
278                                     int numImage) {
279   vtkActor * mSquaresActor = (*actor = vtkActor::New());
280   vtkImageClip * mClipper = (*clipper = vtkImageClip::New());
281   vtkMarchingSquares * mSquares = (*squares = vtkMarchingSquares::New());
282   vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
283
284   if (mHiddenImageIsUsed)
285     mClipper->SetInput(mHiddenImage->GetVTKImages()[0]);
286   else
287     mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
288   mSquares->SetInput(mClipper->GetOutput());
289   mSquaresMapper->SetInput(mSquares->GetOutput());
290   mSquaresMapper->ScalarVisibilityOff();
291   mSquaresActor->SetMapper(mSquaresMapper);
292   mSquaresActor->GetProperty()->SetColor(1.0,0,0);
293   mSquaresActor->SetPickable(0);
294   mSquaresActor->VisibilityOff();
295   mSlicer->GetRenderer()->AddActor(mSquaresActor);
296 }
297 //------------------------------------------------------------------------------
298
299
300 //------------------------------------------------------------------------------
301 void vvImageContour::UpdateActor(vtkActor * actor, 
302                                  vtkMarchingSquares * squares, 
303                                  vtkImageClip * clipper, 
304                                  double threshold, int orientation, int slice) {
305   // Set parameter for the MarchigSquare
306   squares->SetValue(0, threshold);
307
308   // Get image extent
309   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
310
311   // Change extent if needed
312   int* extent2;
313   if (mHiddenImageIsUsed) {
314     extent2 = new int[6];
315     int * extent3;
316     extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
317     for(int i=0; i<6; i++) extent2[i] = extent3[i];
318
319     double s = (double)extent[orientation*2]*(double)mSlicer->GetImage()->GetSpacing()[orientation]; // in mm
320     s = s+mSlicer->GetImage()->GetOrigin()[orientation]; // from origin
321     s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[orientation]; // from corner second image
322     s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[orientation]; // in voxel
323
324     if (s == floor(s)) {
325       extent2[orientation*2] = extent2[orientation*2+1] = (int)floor(s);
326     } else {
327       extent2[orientation*2] = (int)floor(s);
328       extent2[orientation*2+1] = extent2[orientation*2];
329     }
330   } else {
331     extent2 = extent;
332   }
333   clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
334                                 extent2[3],extent2[4],extent2[5]);
335
336   if (mHiddenImage) delete extent2;
337
338   // Move the actor to be visible
339   // DD(orientation);
340   //   DD(slice);
341
342   //TO SIMPLiFY :!!!!!!!!! == ???????
343   // actor->SetPosition(-1,-1,-1);
344
345   switch (orientation)  {
346   case 0:
347     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0]);
348     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
349       actor->SetPosition(1,0,0);
350     } else {
351       actor->SetPosition(-1,0,0);
352     }
353     break;
354   case 1:
355     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1]);
356     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
357       actor->SetPosition(0,1,0);
358     } else {
359       actor->SetPosition(0,-1,0);
360     }
361     break;
362   case 2:
363     // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2]);
364     if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
365       // DD("1");
366       actor->SetPosition(0,0,1);
367     } else {
368       // DD("-1");
369       actor->SetPosition(0,0,-1);
370     }
371     break;
372   }
373
374   squares->Update();
375 }
376 //------------------------------------------------------------------------------
377
378