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