1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
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
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
19 #include "vvImageContour.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>
30 //------------------------------------------------------------------------------
31 vvImageContour::vvImageContour()
35 mHiddenImageIsUsed = false;
36 mDisplayModeIsPreserveMemory = true;
37 SetPreserveMemoryModeEnabled(true);
39 //------------------------------------------------------------------------------
42 //------------------------------------------------------------------------------
43 vvImageContour::~vvImageContour()
45 for (unsigned int i = 0; i < mSlicer->GetImage()->GetVTKImages().size(); i++) {
46 mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
49 //------------------------------------------------------------------------------
52 //------------------------------------------------------------------------------
53 void vvImageContour::SetSlicer(vvSlicer * slicer) {
55 // Create an actor for each time slice
56 for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
57 CreateNewActor(numImage);
60 //------------------------------------------------------------------------------
63 //------------------------------------------------------------------------------
64 void vvImageContour::SetImage(vvImage * image) {
65 for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
66 mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
68 mHiddenImageIsUsed = true;
71 //------------------------------------------------------------------------------
74 //------------------------------------------------------------------------------
75 void vvImageContour::SetPreserveMemoryModeEnabled(bool b) {
76 // FastCache mode work only if threshold is always the same
77 if (mDisplayModeIsPreserveMemory == b) return;
78 mDisplayModeIsPreserveMemory = b;
80 clitkExceptionMacro("TODO : not implemented yet");
82 InitializeCacheMode();
85 for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
86 mListOfCachedContourActors[d].clear();
87 mListOfCachedContourActors.clear();
91 //------------------------------------------------------------------------------
94 //------------------------------------------------------------------------------
95 void vvImageContour::SetColor(double r, double g, double b) {
96 for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
97 mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
100 //------------------------------------------------------------------------------
103 //------------------------------------------------------------------------------
104 void vvImageContour::SetLineWidth(double w)
106 for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
107 mSquaresActorList[i]->GetProperty()->SetLineWidth(w);
110 //------------------------------------------------------------------------------
113 //------------------------------------------------------------------------------
114 void vvImageContour::HideActors() {
115 if (!mSlicer) return;
116 mSlice = mSlicer->GetSlice();
117 for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
118 mSquaresActorList[i]->VisibilityOff();
121 //------------------------------------------------------------------------------
124 //------------------------------------------------------------------------------
125 void vvImageContour::ShowActors() {
126 if (!mSlicer) return;
127 mSlice = mSlicer->GetSlice();
128 mTSlice = mSlicer->GetTSlice();
129 mSquaresActorList[mTSlice]->VisibilityOn();
132 //------------------------------------------------------------------------------
135 //------------------------------------------------------------------------------
136 void vvImageContour::Update(double value) {
137 if (!mSlicer) return;
138 if (mPreviousValue == value) {
139 if (mPreviousSlice == mSlicer->GetSlice()) {
140 if (mPreviousTSlice == mSlicer->GetTSlice()) {
141 return; // Nothing to do
146 // Get current threshold value
150 mSlice = mSlicer->GetSlice();
152 if (mDisplayModeIsPreserveMemory) {
153 UpdateWithPreserveMemoryMode();
156 UpdateWithFastCacheMode();
159 // mSlicer->Render(); //DS ---> REMOVE ??
161 mPreviousTSlice = mSlicer->GetTSlice();
162 mPreviousSlice = mSlicer->GetSlice();
163 mPreviousValue = value;
165 //------------------------------------------------------------------------------
168 //------------------------------------------------------------------------------
169 void vvImageContour::UpdateWithPreserveMemoryMode() {
170 // Only change actor visibility if tslice change
171 int mPreviousTslice = mTSlice;
172 mTSlice = mSlicer->GetTSlice();
174 vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
175 vtkImageClip * mClipper = mClipperList[mTSlice];
176 vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
177 int orientation = ComputeCurrentOrientation();
179 UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
180 //mSquaresActorList[mTSlice]->VisibilityOn();
182 if (mPreviousTslice != mTSlice) {
183 if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
186 //------------------------------------------------------------------------------
189 //------------------------------------------------------------------------------
190 void vvImageContour::InitializeCacheMode() {
191 clitkExceptionMacro("TODO : not implemented yet");
192 mPreviousSlice = mPreviousOrientation = 0;
193 int dim = mSlicer->GetImage()->GetNumberOfDimensions();
195 mListOfCachedContourActors.resize(dim);
196 for(int d=0; d<dim; d++) {
197 int size = mSlicer->GetImage()->GetSize()[d];
198 mListOfCachedContourActors[d].resize(size);
199 for(int j=0; j<size; j++) {
200 mListOfCachedContourActors[d][j] = NULL;
204 //------------------------------------------------------------------------------
207 //------------------------------------------------------------------------------
208 int vvImageContour::ComputeCurrentOrientation() {
209 // Get extent of image in the slicer
210 int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
212 // Compute orientation
214 for (orientation = 0; orientation < 6; orientation = orientation+2) {
215 if (extent[orientation] == extent[orientation+1]) {
219 orientation = orientation/2;
222 //------------------------------------------------------------------------------
225 //------------------------------------------------------------------------------
226 void vvImageContour::UpdateWithFastCacheMode() {
227 clitkExceptionMacro("TODO : not implemented yet");
229 // Compute orientation
230 int orientation = ComputeCurrentOrientation();
232 if ((mPreviousSlice == mSlice) && (mPreviousOrientation == orientation)) return;
234 vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
236 mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
239 //SR: commented out, this code is never reached anyway
240 //UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
241 //mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
242 //mSquaresActor->VisibilityOn();
245 if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
246 mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
247 mPreviousSlice = mSlice;
248 mPreviousOrientation = orientation;
250 //------------------------------------------------------------------------------
253 //------------------------------------------------------------------------------
254 void vvImageContour::CreateNewActor(int numImage) {
255 vtkSmartPointer<vtkActor> squaresActor = vtkSmartPointer<vtkActor>::New();
256 vtkSmartPointer<vtkImageClip> clipper = vtkSmartPointer<vtkImageClip>::New();
257 vtkSmartPointer<vtkMarchingSquares> squares = vtkSmartPointer<vtkMarchingSquares>::New();
258 vtkSmartPointer<vtkPolyDataMapper> squaresMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
260 if (mHiddenImageIsUsed)
261 clipper->SetInput(mHiddenImage->GetVTKImages()[0]);
263 clipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
264 squares->SetInput(clipper->GetOutput());
265 squaresMapper->SetInput(squares->GetOutput());
266 squaresMapper->ScalarVisibilityOff();
267 squaresActor->SetMapper(squaresMapper);
268 squaresActor->GetProperty()->SetColor(1.0,0,0);
269 squaresActor->SetPickable(0);
270 squaresActor->VisibilityOff();
271 mSlicer->GetRenderer()->AddActor(squaresActor);
273 mSquaresActorList.push_back(squaresActor);
274 mClipperList.push_back(clipper);
275 mSquaresList.push_back(squares);
276 mSquaresMapperList.push_back(squaresMapper);
278 //------------------------------------------------------------------------------
281 //------------------------------------------------------------------------------
282 void vvImageContour::UpdateActor(vtkActor * actor,
283 vtkMarchingSquares * squares,
284 vtkImageClip * clipper,
285 double threshold, int orientation, int slice) {
286 // Set parameter for the MarchigSquare
287 squares->SetValue(0, threshold);
290 int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
292 // Change extent if needed
294 if (mHiddenImageIsUsed) {
295 extent2 = new int[6];
297 extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
299 for(int i=0; i<6; i++) extent2[i] = extent3[i];
301 double s = (double)extent[orientation*2]*(double)mSlicer->GetImage()->GetSpacing()[orientation]; // in mm
302 s = s+mSlicer->GetImage()->GetOrigin()[orientation]; // from origin
303 s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[orientation]; // from corner second image
304 s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[orientation]; // in voxel
307 extent2[orientation*2] = extent2[orientation*2+1] = (int)floor(s);
309 extent2[orientation*2] = (int)floor(s);
310 extent2[orientation*2+1] = extent2[orientation*2];
313 // Do not display a contour if there is no contour on this slice
314 if (extent2[orientation*2+1] > extent3[orientation*2+1]) {
315 actor->VisibilityOff();
318 else actor->VisibilityOn();
324 clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
325 extent2[3],extent2[4],extent2[5]);
327 if (mHiddenImageIsUsed) delete extent2;
329 // Move the actor to be visible
330 switch (orientation) {
332 actor->SetPosition(-1,0,0);
334 // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0]);
335 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
336 actor->SetPosition(1,0,0);
338 actor->SetPosition(-1,0,0);
342 actor->SetPosition(0,-1,0);
344 // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1]);
345 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
346 actor->SetPosition(0,1,0);
348 actor->SetPosition(0,-1,0);
353 actor->SetPosition(0,0,-1);
355 DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2]);
356 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
358 actor->SetPosition(0,0,1);
361 actor->SetPosition(0,0,-1);
369 //------------------------------------------------------------------------------