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