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