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() {
34 mHiddenImageIsUsed = false;
35 mDisplayModeIsPreserveMemory = true;
37 //------------------------------------------------------------------------------
40 //------------------------------------------------------------------------------
41 vvImageContour::~vvImageContour() {
42 for (unsigned int i = 0; i < mSlicer->GetImage()->GetVTKImages().size(); i++) {
43 mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
45 mSquaresActorList.clear();
49 //------------------------------------------------------------------------------
52 //------------------------------------------------------------------------------
53 void vvImageContour::setSlicer(vvSlicer * slicer) {
56 for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
57 vtkImageClip * mClipper = vtkImageClip::New();
58 vtkMarchingSquares * mSquares = vtkMarchingSquares::New();
59 // vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
60 vtkActor * mSquaresActor = vtkActor::New();
62 createNewActor(&mSquaresActor, &mSquares, &mClipper);
64 mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
65 mSquares->SetInput(mClipper->GetOutput());
66 mSquaresMapper->SetInput(mSquares->GetOutput());
67 mSquaresMapper->ScalarVisibilityOff();
68 mSquaresActor->SetMapper(mSquaresMapper);
69 mSquaresActor->GetProperty()->SetColor(1.0,0,0);
70 mSquaresActor->SetPickable(0);
71 mSquaresActor->VisibilityOff();
72 mSlicer->GetRenderer()->AddActor(mSquaresActor);
74 mSquaresActorList.push_back(mSquaresActor);
75 mSquaresList.push_back(mSquares);
76 mClipperList.push_back(mClipper);
79 //------------------------------------------------------------------------------
82 //------------------------------------------------------------------------------
83 void vvImageContour::setImage(vvImage::Pointer image) {
84 DD("vvImageContour::setImage");
85 for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
86 mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
88 mHiddenImageIsUsed = true;
91 //------------------------------------------------------------------------------
94 //------------------------------------------------------------------------------
95 void vvImageContour::setPreserveModeEnabled(bool b) {
96 DD("setPreserveModeEnabled");
98 DD(mDisplayModeIsPreserveMemory);
99 if (mDisplayModeIsPreserveMemory == b) return;
100 mDisplayModeIsPreserveMemory = b;
102 initializeCacheMode();
105 for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
106 mListOfCachedContourActors[d].clear();
107 mListOfCachedContourActors.clear();
110 //------------------------------------------------------------------------------
113 //------------------------------------------------------------------------------
114 void vvImageContour::setColor(double r, double g, double b) {
115 for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
116 mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
119 //------------------------------------------------------------------------------
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();
130 //------------------------------------------------------------------------------
133 //------------------------------------------------------------------------------
134 void vvImageContour::showActors() {
135 if (!mSlicer) return;
136 mSlice = mSlicer->GetSlice();
137 mTSlice = mSlicer->GetTSlice();
138 // for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
139 mSquaresActorList[mTSlice]->VisibilityOn();
143 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
147 void vvImageContour::update(double value) {
148 if (!mSlicer) return;
149 // Get current threshold value
152 mSlice = mSlicer->GetSlice();
154 if (mDisplayModeIsPreserveMemory) {
155 updateWithPreserveMemoryMode();
158 updateWithFastCacheMode();
161 //------------------------------------------------------------------------------
164 //------------------------------------------------------------------------------
165 void vvImageContour::updateWithPreserveMemoryMode() {
167 // Only change actor visibility if tslice change
168 if (mTSlice != mSlicer->GetTSlice()) {
170 mSquaresActorList[mTSlice]->VisibilityOff();
171 mTSlice = mSlicer->GetTSlice();
172 mSquaresActorList[mTSlice]->VisibilityOn();
175 vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
176 vtkImageClip * mClipper = mClipperList[mTSlice];
177 vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
178 int orientation = computeCurrentOrientation();
181 updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
186 mSquares->SetValue(0, mValue );
188 int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
196 // int* extent2 = mClipper->GetInput()->GetDisplayExtent();
199 int* extent2 = new int[6];
200 if (mHiddenImageIsUsed) {
202 extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
203 for(int i=0; i<6; i++) extent2[i] = extent3[i];
210 for(int i=0; i<6; i+=2) {
211 if (extent[i] != extent[i+1]) {
212 // extent[i] = extent2[i];
213 // extent[i+1] = extent2[i+1];
217 // DD(mSlicer->GetImage()->GetSpacing()[i/2]);
218 // DD(mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]);
220 double s = (double)extent[i]*(double)mSlicer->GetImage()->GetSpacing()[i/2]; // in mm
222 s = s+mSlicer->GetImage()->GetOrigin()[i/2]; // from origin
224 s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[i/2]; // from corner second image
225 s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]; // in voxel
229 extent2[i] = extent2[i+1] = (int)floor(s);
232 extent2[i] = (int)floor(s);
233 extent2[i+1] = extent2[i];
239 else extent2 = extent;
248 mClipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
249 extent2[3],extent2[4],extent2[5]);
251 for (i = 0; i < 6;i = i+2) {
252 if (extent[i] == extent[i+1]) {
260 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > mSlice)
262 mSquaresActor->SetPosition(1,0,0);
266 mSquaresActor->SetPosition(-1,0,0);
270 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > mSlice)
272 mSquaresActor->SetPosition(0,1,0);
276 mSquaresActor->SetPosition(0,-1,0);
280 if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > mSlice)
282 mSquaresActor->SetPosition(0,0,1);
286 mSquaresActor->SetPosition(0,0,-1);
292 //------------------------------------------------------------------------------
295 //------------------------------------------------------------------------------
296 void vvImageContour::initializeCacheMode() {
297 DD("vvImageContour::initializeCacheMode");
299 mPreviousSlice = mPreviousOrientation = 0;
301 if (mHiddenImageIsUsed) dim = mHiddenImage->GetNumberOfDimensions();
302 else dim = mSlicer->GetImage()->GetNumberOfDimensions();
305 mListOfCachedContourActors.resize(dim);
306 for(int d=0; d<dim; d++) {
309 if (mHiddenImageIsUsed) size = mHiddenImage->GetSize()[d];
310 else size = mSlicer->GetImage()->GetSize()[d];
312 mListOfCachedContourActors[d].resize(size);
313 for(int j=0; j<size; j++) {
314 mListOfCachedContourActors[d][j] = NULL;
315 DD(mListOfCachedContourActors.size());
316 DD(mListOfCachedContourActors[d].size());
320 //------------------------------------------------------------------------------
323 //------------------------------------------------------------------------------
324 int vvImageContour::computeCurrentOrientation() {
325 // Get extent of image in the slicer
326 int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
328 // Compute orientation
330 for (orientation = 0; orientation < 6;orientation = orientation+2) {
331 if (extent[orientation] == extent[orientation+1]) {
335 orientation = orientation/2;
339 //------------------------------------------------------------------------------
342 //------------------------------------------------------------------------------
343 void vvImageContour::updateWithFastCacheMode() {
344 DD("vvImageContour::updateWithFastCacheMode");
346 // Compute orientation
347 int orientation = computeCurrentOrientation();
349 // Turn off previous actor
350 DD(mPreviousOrientation);
352 if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
353 mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
354 mPreviousSlice = mSlice;
355 mPreviousOrientation = orientation;
357 // Display actor if it exist
358 vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
361 mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
364 vtkImageClip * mClipper;
365 vtkMarchingSquares * mSquares;
366 vtkActor * mSquaresActor;
367 createNewActor(&mSquaresActor, &mSquares, &mClipper);
368 updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
369 mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
370 mSquaresActor->VisibilityOn();
373 //------------------------------------------------------------------------------
376 //------------------------------------------------------------------------------
377 void vvImageContour::createNewActor(vtkActor ** actor,
378 vtkMarchingSquares ** squares,
379 vtkImageClip ** clipper) {
380 // DD("vvImageContour::CreateNewActor");
381 vtkActor * mSquaresActor = (*actor = vtkActor::New());
382 vtkImageClip * mClipper = (*clipper = vtkImageClip::New());
383 vtkMarchingSquares * mSquares = (*squares = vtkMarchingSquares::New());
384 vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
386 if (mHiddenImageIsUsed)
387 mClipper->SetInput(mHiddenImage->GetVTKImages()[0]);
389 mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[0]);
390 mSquares->SetInput(mClipper->GetOutput());
391 mSquaresMapper->SetInput(mSquares->GetOutput());
392 mSquaresMapper->ScalarVisibilityOff();
393 mSquaresActor->SetMapper(mSquaresMapper);
394 mSquaresActor->GetProperty()->SetColor(1.0,0,0);
395 mSquaresActor->SetPickable(0);
396 mSquaresActor->VisibilityOff();
397 mSlicer->GetRenderer()->AddActor(mSquaresActor);
399 //------------------------------------------------------------------------------
402 //------------------------------------------------------------------------------
403 void vvImageContour::updateActor(vtkActor * actor,
404 vtkMarchingSquares * squares,
405 vtkImageClip * clipper,
406 int threshold, int orientation, int slice) {
407 // DD("Update Actor according to extend/threshold");
409 int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
410 clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
411 extent[3],extent[4],extent[5]);
412 squares->SetValue(0, threshold);
414 switch (orientation) {
415 case 0: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
416 actor->SetPosition(1,0,0);
419 actor->SetPosition(-1,0,0);
422 case 1: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
423 actor->SetPosition(0,1,0);
426 actor->SetPosition(0,-1,0);
429 case 2: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
430 actor->SetPosition(0,0,1);
433 actor->SetPosition(0,0,-1);
439 //------------------------------------------------------------------------------