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