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