]> Creatis software - bbtk.git/blob - packages/vtk/src/bbvtkImagePlanes.cxx
comment out useless std::cout
[bbtk.git] / packages / vtk / src / bbvtkImagePlanes.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbvtkImagePlanes.cxx,v $
4   Language:  C++
5   Date:      $Date: 2010/05/06 09:05:32 $
6   Version:   $Revision: 1.33 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *  \file 
33  *  \brief 
34  */
35
36 #ifdef _USE_VTK_
37 #include "bbvtkImagePlanes.h"
38 #include "bbvtkPackage.h"
39 #include "vtkCellPicker.h"
40 #include "vtkProperty.h"
41 #include "vtkPolyData.h"
42
43
44 #include "vtkMetaImageWriter.h"
45 #include "vtkPNGWriter.h"
46
47 #include "bbstdCast.h"
48 #include <vtkCommand.h>
49
50 #include "vtkImageData.h"
51 //#include "vtkOutlineFilter.h"
52 //#include "vtkPolyDataMapper.h"
53 //#include "vtkActor.h"
54 #include "vtkImagePlaneWidget.h"
55 #include "vtkCellPicker.h"
56 //#include "vtkProperty.h"
57
58 //#include "vtkRenderer.h"
59 //#include "vtkCamera.h"
60
61 #include "vtkPlaneWidget.h"
62
63 #include <vtkImplicitPlaneWidget.h>
64
65 #include "bbstdRelay.h"
66
67 #include "vtkObjectFactory.h"
68
69
70 namespace bbstd
71 {
72
73   //====================================================================
74   BBTK_BLACK_BOX_TEMPLATE2_IMPLEMENTATION(Cast,
75                                           bbtk::AtomicBlackBox);
76   //====================================================================
77   //====================================================================
78 //  BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION(Relay,
79 //                                       bbtk::AtomicBlackBox);
80   //====================================================================
81
82 }
83 using namespace bbstd;
84 /*
85 namespace bbtk
86 {
87         typedef vtkImageData::Pointer vtkImageDataPointer;
88   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(vtkImageDataPointer,
89                                        "vtkImageDataPointer");
90 }
91 */
92 namespace bbvtk
93 {
94
95   //====================================================================
96   // Add the specialized adaptors to the package
97   typedef vtkImagePlaneWidget* I;
98   typedef vtkInteractorObserver* O;
99
100   BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(vtk,Cast,I,O);
101
102   BBTK_DEFINE_RELAY_BLACK_BOX(vtkImageDataPointer,vtk,vtkImageDataPointerRelay);
103   BBTK_BLACK_BOX_IMPLEMENTATION(vtkImageDataPointerRelay,bbtk::AtomicBlackBox);
104
105   BBTK_ADD_BLACK_BOX_TO_PACKAGE(vtk,vtkImageDataPointerRelay);
106  // BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(vtk,Relay,vtkImageDataPointer);
107   //Pointer);
108
109 }
110
111 namespace bbvtk
112 {
113
114   //================================================================
115  class ImagePlanes::VtkCallbackType : public vtkCommand
116  {
117  public:
118    static VtkCallbackType *New()
119    {
120      return new VtkCallbackType;
121    }
122    //vtkTypeRevisionMacro(VtkCallbackType,vtkCommand);
123
124    virtual void Execute(vtkObject *caller, unsigned long, void*)
125    {
126        mBlackBox->Process();
127        mBlackBox->bbSignalOutputModification();
128    } 
129    void SetBlackBox(ImagePlanes *BB) { mBlackBox = BB;};    
130    //   void SetVtkPlaneWidget( vtkImagePlaneWidget *planeWidget );
131    VtkCallbackType() {};
132
133  private:
134    //   vtkPlaneWidget *planeWidget;
135    ImagePlanes *mBlackBox;
136  };
137   //================================================================
138
139   //vtkCxxRevisionMacro(ImagePlanes::VtkCallbackType, "$Revision: 1.33 $");
140
141   //================================================================
142
143    BBTK_ADD_BLACK_BOX_TO_PACKAGE(vtk,ImagePlanes)
144    BBTK_BLACK_BOX_IMPLEMENTATION(ImagePlanes,bbtk::AtomicBlackBox);
145
146    void ImagePlanes::bbUserSetDefaultValues() 
147    { 
148      bbSetOutputPlaneX(0);
149      bbSetOutputPlaneY(0);
150      bbSetOutputPlaneZ(0);
151      bbSetOutputImageX(0);
152      bbSetOutputImageY(0);
153      bbSetOutputImageZ(0);
154      bbSetInputIn(0);
155      std::vector<double> vect;
156      vect.push_back(0);
157      vect.push_back(0);
158      bbSetInputWindowLevel (vect);  
159      mVtkCallback = 0;
160
161      std::vector<int> vectpoints;
162
163      bbSetOutputPlane3Pts(0);
164      bbSetOutputImage3Pts(0);
165      bbSetInputPointsX(vectpoints);
166      bbSetInputPointsY(vectpoints);
167      bbSetInputPointsZ(vectpoints);
168
169      _imageReslicer = NULL;
170      image          = NULL;
171      _transform     = NULL;
172      _matrix        = NULL;
173    }
174
175         
176    void ImagePlanes::bbUserInitializeProcessing() 
177    {  
178      /// CREATION DES WIDGETS
179      if (bbGetOutputPlaneX() != 0) return;
180        
181      // The shared picker enables us to use 3 planes at one time
182      // and gets the picking order right
183      vtkCellPicker* picker = vtkCellPicker::New();
184      picker->SetTolerance(0.005);
185   
186      // The 3 image plane widgets 
187      vtkImagePlaneWidget* planeWidgetX = GetPlaneWidget('x', 1, 0, 0, picker);
188      vtkImagePlaneWidget* planeWidgetY = GetPlaneWidget('y', 1, 1, 0, picker);
189      planeWidgetY->SetLookupTable(planeWidgetX->GetLookupTable());
190
191      vtkImagePlaneWidget* planeWidgetZ = GetPlaneWidget('z', 0, 0, 1, picker);     
192      planeWidgetZ->SetLookupTable(planeWidgetX->GetLookupTable());
193
194      vtkImagePlaneWidget* planeWidget3Pts = GetPlaneWidget('3', 0, 1, 1, picker);        
195      planeWidget3Pts->SetLookupTable(planeWidgetX->GetLookupTable());
196
197      bbSetOutputPlaneX(planeWidgetX);
198      bbSetOutputPlaneY(planeWidgetY);
199      bbSetOutputPlaneZ(planeWidgetZ);
200      bbSetOutputPlane3Pts(planeWidget3Pts);      
201      bbSetOutputImageX(planeWidgetX->GetResliceOutput());
202      bbSetOutputImageY(planeWidgetY->GetResliceOutput());
203      bbSetOutputImageZ(planeWidgetZ->GetResliceOutput());
204      bbSetInputInteractor(0);
205      //bbSetOutputImage3Pts(planeWidget3Pts->GetResliceOutput());
206
207      picker->UnRegister(NULL);
208      
209      mVtkCallback = VtkCallbackType::New();
210      mVtkCallback->SetBlackBox(this);
211      planeWidgetX->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);
212      planeWidgetY->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);
213      planeWidgetZ->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);  
214    }
215
216 //---------------------------------------------------------------------
217   void ImagePlanes::bbUserFinalizeProcessing()
218   {
219             
220     if (bbGetOutputPlaneX()) 
221       {
222
223         /*
224           bbGetOutputPlaneX()->RemoveObserver(mVtkCallback);
225           bbGetOutputPlaneY()->RemoveObserver(mVtkCallback);
226           bbGetOutputPlaneZ()->RemoveObserver(mVtkCallback);
227
228         bbGetOutputPlaneX()->Delete();
229         bbGetOutputPlaneY()->Delete();
230         bbGetOutputPlaneZ()->Delete();
231         mVtkCallback->Delete();
232         */
233         //bbGetOutputPlaneX()->SetInput(NULL);
234         //bbGetOutputPlaneY()->SetInput(NULL);
235         //bbGetOutputPlaneZ()->SetInput(NULL);
236
237       }
238   }
239   
240 //---------------------------------------------------------------------  
241   void ImagePlanes::Process()
242   {
243         if (bbGetInputIn()!=0)
244         {
245                 int xMin, xMax, yMin, yMax, zMin, zMax;
246                 bbGetInputIn()->GetExtent(xMin, xMax, yMin, yMax, zMin, zMax);
247
248                 if ( image != bbGetInputIn()){//bbGetInputStatus("In") != bbtk::UPTODATE ){
249                         // Input image has changed : reinitialize planes
250                         image = bbGetInputIn();                 
251
252                         // Initial values : center of the volume (in real world, not in pixels!)
253                         double xSpacing, ySpacing, zSpacing;
254                         bbGetInputIn()->GetSpacing(xSpacing, ySpacing, zSpacing);
255
256                         bbGetOutputPlaneX()->SetInput(bbGetInputIn());
257                         bbGetOutputPlaneX()->SetPlaneOrientationToXAxes();       
258                         bbGetOutputPlaneX()->SetSlicePosition((xMax+xMin)/2.*xSpacing);
259
260                         //                 bbGetOutputPlaneX()->SetOrigin( 58*xSpacing , 80*ySpacing , 82*zSpacing );
261                         //                 bbGetOutputPlaneX()->SetPoint1( 0*xSpacing, 146*ySpacing, 186*zSpacing);
262                         //                 bbGetOutputPlaneX()->SetPoint2( 126*xSpacing, 146*ySpacing, 0*zSpacing);
263
264                         bbGetOutputPlaneY()->SetInput(bbGetInputIn());
265                         bbGetOutputPlaneY()->SetPlaneOrientationToYAxes();
266                         bbGetOutputPlaneY()->SetSlicePosition((yMax+yMin)/2.*ySpacing);
267
268                         bbGetOutputPlaneZ()->SetInput(bbGetInputIn());
269                         bbGetOutputPlaneZ()->SetPlaneOrientationToZAxes();
270                         bbGetOutputPlaneZ()->SetSlicePosition((zMax+zMin)/2.*zSpacing);
271
272                         if (bbGetInputWindowLevel()[0]!=0)
273                         {
274                                 bbGetOutputPlaneZ()->SetWindowLevel(bbGetInputWindowLevel()[0],
275                                                                 bbGetInputWindowLevel()[1]);
276                         }
277                         else 
278                         {
279                                 double *range = image->GetScalarRange();
280                                 bbGetOutputPlaneZ()->SetWindowLevel(range[1]-range[0],
281                                                                0.5*(range[1]+range[0]));
282                         }
283                         updateInteractor();
284            }
285                         // UPDATE DES SORTIES 
286                 bbGetOutputPlaneX()->GetResliceOutput()->Update();
287                 bbGetOutputPlaneY()->GetResliceOutput()->Update(); 
288                 bbGetOutputPlaneZ()->GetResliceOutput()->Update();               
289
290                 std::vector<int> pointsx = bbGetInputPointsX();
291                 std::vector<int> pointsy = bbGetInputPointsY();
292                 std::vector<int> pointsz = bbGetInputPointsZ();
293
294                 //std::cout<<pointsx.size()<<pointsy.size()<<pointsz.size()<<std::endl;
295
296                 if (pointsx.size()==pointsy.size() && pointsx.size()==pointsz.size()&&pointsx.size()>=3)
297                 {
298
299                         //Get the corresponding three points out of the vectors
300                         double origin[3];
301                         origin[0] = pointsx[0];
302                         origin[1] = pointsy[0];
303                         origin[2] = pointsz[0];
304
305                         double point1[3];
306                         point1[0] = pointsx[1];
307                         point1[1] = pointsy[1];
308                         point1[2] = pointsz[1];
309                         double point2[3];
310                         point2[0]= pointsx[2];
311                         point2[1]= pointsy[2];
312                         point2[2]= pointsz[2];  
313
314                         //With the three points we create the corresponding X, Y and Z vectors all orthogonal to each other
315                         double* vect1= getNormal(makeVector(origin, point1));
316                         double* vect2= getNormal(makeVector(origin, point2));                           
317                         double* crossp = getCrossProduct(vect1, vect2);
318
319                         double *newx = getCrossProduct(vect2, crossp);
320
321                         int ext[6],factor=0;
322                         bbGetInputIn()->GetExtent(ext);
323
324                         factor = ext[0]<ext[3]? ext[3] : ext[0];
325                         factor = factor<ext[5]? ext[5] : factor;
326
327         //for the plane widgets
328                         vtkImagePlaneWidget* plane3pts = (vtkImagePlaneWidget*)bbGetOutputPlane3Pts();
329                         plane3pts->SetInput(bbGetInputIn());                    
330                         double xSpacing, ySpacing, zSpacing;
331                         bbGetInputIn()->GetSpacing(xSpacing, ySpacing, zSpacing);
332                         plane3pts->SetOrigin(pointsx[0]*xSpacing,pointsy[0]*ySpacing,pointsz[0]*zSpacing);      
333                         plane3pts->SetPoint1((origin[0]+newx[0]*factor)*xSpacing,
334                                                                         (origin[1]+newx[1]*factor)*ySpacing,
335                                                                         (origin[2]+newx[2]*factor)*zSpacing);
336                         plane3pts->SetPoint2((origin[0]+vect2[0]*factor)*xSpacing,
337                                                                         (origin[1]+vect2[1]*factor)*ySpacing,
338                                                                         (origin[2]+vect2[2]*factor)*zSpacing);
339                         plane3pts->GetResliceOutput()->Update();
340 //To get the slice of image out of the selected volume
341                         if (_imageReslicer==NULL){
342                                 _imageReslicer = vtkImageReslice::New();                                        
343                                 _imageReslicer->SetOutputDimensionality(2);
344                                 _imageReslicer->SetInterpolationModeToLinear();
345                                 _transform = vtkTransform::New();
346                                 _matrix = vtkMatrix4x4::New();  
347                         }
348                         _imageReslicer->SetInput( bbGetInputIn() );
349                         _imageReslicer->SetInformationInput(bbGetInputIn());    
350                         //fill out the information with the created vectors and using the spacing of the image
351                         _imageReslicer->SetResliceAxesDirectionCosines(newx[0]*xSpacing,newx[1]*xSpacing,newx[2]*xSpacing,
352                                                                         vect2[0]*ySpacing,vect2[1]*ySpacing,vect2[2]*ySpacing,
353                                                                         crossp[0]*zSpacing,crossp[1]*zSpacing,crossp[2]*zSpacing);                      
354                         _imageReslicer->SetResliceAxesOrigin(origin[0]*xSpacing,origin[1]*ySpacing,origin[2]*zSpacing);
355                         _imageReslicer->GetOutput()->Update();
356                         _imageReslicer->GetOutput()->UpdateInformation();
357
358                         bbSetOutputImage3Pts(_imageReslicer->GetOutput());
359
360                         _matrix->Identity();    
361
362                         _matrix->SetElement(0,0,newx[0]*xSpacing);
363                         _matrix->SetElement(1,0,newx[1]*xSpacing);
364                         _matrix->SetElement(2,0,newx[2]*xSpacing);
365                         _matrix->SetElement(0,1,vect2[0]*ySpacing);
366                         _matrix->SetElement(1,1,vect2[1]*ySpacing);
367                         _matrix->SetElement(2,1,vect2[2]*ySpacing);
368                         _matrix->SetElement(0,2,crossp[0]*zSpacing);
369                         _matrix->SetElement(1,2,crossp[1]*zSpacing);
370                         _matrix->SetElement(2,2,crossp[2]*zSpacing);
371                         _matrix->SetElement(0,3,origin[0]*xSpacing);
372                         _matrix->SetElement(1,3,origin[1]*ySpacing);
373                         _matrix->SetElement(2,3,origin[2]*zSpacing);
374
375                         _transform->SetMatrix(_matrix);
376
377                         //set the transformation out to be used by other bbBoxes
378                         bbSetOutputTransform3Pts((vtkLinearTransform*)_transform);                      
379                 }       
380         }
381   }
382         
383   void ImagePlanes::updateInteractor(){
384
385         vtkRenderWindowInteractor* interactor = bbGetInputInteractor();
386
387         if(interactor){
388                 bbGetOutputPlaneX()->SetInteractor(interactor);
389                 bbGetOutputPlaneX()->EnabledOn();
390                 bbGetOutputPlaneY()->SetInteractor(interactor);
391                 bbGetOutputPlaneY()->EnabledOn();
392                 bbGetOutputPlaneZ()->SetInteractor(interactor);
393                 bbGetOutputPlaneZ()->EnabledOn();
394                 bbGetOutputPlane3Pts()->SetInteractor(interactor);
395                 bbGetOutputPlane3Pts()->EnabledOn();
396         }
397   }
398         //-----------------------------------------------------------------     
399   void vtkImageDataPointerRelay::bbUserSetDefaultValues()
400         {
401                 
402         }
403         
404         //-----------------------------------------------------------------     
405   void vtkImageDataPointerRelay::bbUserInitializeProcessing()
406         {
407         }
408         
409         //-----------------------------------------------------------------     
410   void vtkImageDataPointerRelay::bbUserFinalizeProcessing()
411         {
412         }
413         
414   vtkImagePlaneWidget* ImagePlanes::GetPlaneWidget(unsigned char activationkey, double r, double g, double b, vtkCellPicker* picker)
415   {
416                 vtkProperty* prop1 = 0;         
417                 vtkImagePlaneWidget* planeWidget = 0;
418
419                 planeWidget = vtkImagePlaneWidget::New();
420                 planeWidget->DisplayTextOn();
421                 planeWidget->SetPicker(picker);
422                 planeWidget->SetKeyPressActivationValue(activationkey);
423                 prop1 = planeWidget->GetPlaneProperty();
424                 prop1->SetColor(r, g, b);
425
426                 return planeWidget;
427   }
428
429   double* ImagePlanes::getCrossProduct(double* vect0,double* vect1){
430         double* vectCross;
431         vectCross = new double[3];
432         vectCross[0] = vect0[1]*vect1[2]-(vect0[2]*vect1[1]);
433         vectCross[1] = -(vect0[0]*vect1[2]-(vect0[2]*vect1[0]));
434         vectCross[2] = vect0[0]*vect1[1]-(vect0[1]*vect1[0]);
435
436         return vectCross;
437   }
438 /**
439 **      Returns the magnitud of the given vector
440 **/
441   double ImagePlanes::getMagnitud(double* vect){
442
443         double mag;
444         mag = sqrt(pow(vect[0],2) + pow(vect[1],2) + pow(vect[2],2));
445         //std::cout<<"mag "<<mag <<std::endl;
446         return mag;
447   }
448 /**
449 **      returns the unitary vector of the given vector
450 **      u = 1/|vect| . vect
451 **/
452   double* ImagePlanes::getNormal(double* vect){
453
454         double* vectnorm;
455         double mag = getMagnitud(vect);
456
457         vectnorm = new double[3];
458
459         if(mag!=0){
460                 vectnorm[0] = vect[0]/mag;
461                 vectnorm[1] = vect[1]/mag;
462                 vectnorm[2] = vect[2]/mag;
463         }else{
464                 vectnorm[0] = 0;
465                 vectnorm[1] = 0;
466                 vectnorm[2] = 0;
467         }
468
469         return vectnorm;
470   }
471
472   double* ImagePlanes::makeVector(double podouble0[3], double podouble1[3]){
473         double *vect;
474         vect = new double[3];
475
476         vect[0]= podouble1[0]-podouble0[0];
477         vect[1]= podouble1[1]-podouble0[1];
478         vect[2]= podouble1[2]-podouble0[2];
479
480         return vect;
481   }
482         
483 }//namespace bbtk
484
485 #endif // _USE_VTK_