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