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