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