]> Creatis software - bbtk.git/blob - packages/vtk/src/bbvtkImagePlanes.cxx
vtkPlanes with different way of calculating the plane of the image
[bbtk.git] / packages / vtk / src / bbvtkImagePlanes.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbvtkImagePlanes.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/06/23 15:58:56 $
6   Version:   $Revision: 1.27 $
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
42 #include "vtkMetaImageWriter.h"
43 #include "vtkPNGWriter.h"
44
45 #include "bbstdCast.h"
46 #include <vtkCommand.h>
47
48 #include "vtkImageData.h"
49 //#include "vtkOutlineFilter.h"
50 //#include "vtkPolyDataMapper.h"
51 //#include "vtkActor.h"
52 #include "vtkImagePlaneWidget.h"
53 #include "vtkCellPicker.h"
54 //#include "vtkProperty.h"
55
56 //#include "vtkRenderer.h"
57 //#include "vtkCamera.h"
58
59 #include "vtkPlaneWidget.h"
60
61 #include <vtkImplicitPlaneWidget.h>
62
63 #include "bbstdRelay.h"
64
65 #include "vtkObjectFactory.h"
66
67
68 namespace bbstd
69 {
70
71   //====================================================================
72   BBTK_BLACK_BOX_TEMPLATE2_IMPLEMENTATION(Cast,
73                                           bbtk::AtomicBlackBox);
74   //====================================================================
75   //====================================================================
76 //  BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION(Relay,
77 //                                       bbtk::AtomicBlackBox);
78   //====================================================================
79
80 }
81 using namespace bbstd;
82 /*
83 namespace bbtk
84 {
85         typedef vtkImageData::Pointer vtkImageDataPointer;
86   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(vtkImageDataPointer,
87                                        "vtkImageDataPointer");
88 }
89 */
90 namespace bbvtk
91 {
92
93
94   //====================================================================
95   // Add the specialized adaptors to the package
96   typedef vtkImagePlaneWidget* I;
97   typedef vtkInteractorObserver* O;
98
99   BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(vtk,Cast,I,O);
100
101   BBTK_DEFINE_RELAY_BLACK_BOX(vtkImageDataPointer,vtk,vtkImageDataPointerRelay);
102   BBTK_BLACK_BOX_IMPLEMENTATION(vtkImageDataPointerRelay,bbtk::AtomicBlackBox);
103
104   BBTK_ADD_BLACK_BOX_TO_PACKAGE(vtk,vtkImageDataPointerRelay);
105  // BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(vtk,Relay,vtkImageDataPointer);
106   //Pointer);
107
108 }
109
110 namespace bbvtk
111 {
112
113   //================================================================
114  class ImagePlanes::VtkCallbackType : public vtkCommand
115  {
116  public:
117    static VtkCallbackType *New()
118    {
119      return new VtkCallbackType;
120    }
121    //vtkTypeRevisionMacro(VtkCallbackType,vtkCommand);
122
123    virtual void Execute(vtkObject *caller, unsigned long, void*)
124    {
125        mBlackBox->Process();
126        mBlackBox->bbSignalOutputModification();
127    } 
128    void SetBlackBox(ImagePlanes *BB) { mBlackBox = BB;};    
129    //   void SetVtkPlaneWidget( vtkImagePlaneWidget *planeWidget );
130    VtkCallbackType() {};
131
132  private:
133    //   vtkPlaneWidget *planeWidget;
134    ImagePlanes *mBlackBox;
135  };
136   //================================================================
137
138   //vtkCxxRevisionMacro(ImagePlanes::VtkCallbackType, "$Revision: 1.27 $");
139
140   //================================================================
141
142    BBTK_ADD_BLACK_BOX_TO_PACKAGE(vtk,ImagePlanes)
143    BBTK_BLACK_BOX_IMPLEMENTATION(ImagePlanes,bbtk::AtomicBlackBox);
144
145         
146         
147    void ImagePlanes::bbUserSetDefaultValues() 
148    { 
149      bbSetOutputPlaneX(0);
150      bbSetOutputPlaneY(0);
151      bbSetOutputPlaneZ(0);
152      bbSetOutputImageX(0);
153      bbSetOutputImageY(0);
154      bbSetOutputImageZ(0);
155      bbSetInputIn(0);
156      std::vector<double> vect;
157      vect.push_back(0);
158      vect.push_back(0);
159      bbSetInputWindowLevel (vect);  
160      mVtkCallback = 0;
161
162
163          std::vector<int> vectpoints;
164
165      bbSetOutputPlane3Pts(0);
166          bbSetOutputImage3Pts(0);
167          bbSetInputPointsX(vectpoints);
168          bbSetInputPointsY(vectpoints);
169          bbSetInputPointsZ(vectpoints);
170
171          _imageReslicer = NULL;
172          image=NULL;
173    }
174    
175
176         
177    void ImagePlanes::bbUserInitializeProcessing() 
178    {  
179
180      /// CREATION DES WIDGETS
181      if (bbGetOutputPlaneX() != 0) return;
182        
183      // The shared picker enables us to use 3 planes at one time
184      // and gets the picking order right
185      vtkCellPicker* picker = vtkCellPicker::New();
186      picker->SetTolerance(0.005);
187   
188      // The 3 image plane widgets 
189      vtkImagePlaneWidget* planeWidgetX = vtkImagePlaneWidget::New();
190      planeWidgetX->DisplayTextOn();
191      planeWidgetX->SetPicker(picker);
192      planeWidgetX->SetKeyPressActivationValue('x');
193      vtkProperty* prop1 = planeWidgetX->GetPlaneProperty();
194      prop1->SetColor(1, 0, 0);
195
196      vtkImagePlaneWidget* planeWidgetY = vtkImagePlaneWidget::New();
197      planeWidgetY->DisplayTextOn();
198      planeWidgetY->SetPicker(picker);
199      planeWidgetY->SetKeyPressActivationValue('y');
200      vtkProperty* prop2 = planeWidgetY->GetPlaneProperty();
201      prop2->SetColor(1, 1, 0);
202      planeWidgetY->SetLookupTable(planeWidgetX->GetLookupTable());
203
204      vtkImagePlaneWidget* planeWidgetZ = vtkImagePlaneWidget::New();
205      planeWidgetZ->DisplayTextOn();
206      planeWidgetZ->SetPicker(picker);
207      planeWidgetZ->SetKeyPressActivationValue('z');
208      vtkProperty* prop3 = planeWidgetZ->GetPlaneProperty();
209      prop3->SetColor(0, 0, 1);
210      planeWidgetZ->SetLookupTable(planeWidgetX->GetLookupTable());
211
212          vtkImagePlaneWidget* planeWidget3Pts = vtkImagePlaneWidget::New();
213          //vtkPlaneWidget* planeWidget3Pts = vtkPlaneWidget::New();
214      planeWidget3Pts->DisplayTextOn();
215      planeWidget3Pts->SetPicker(picker);
216      planeWidget3Pts->SetKeyPressActivationValue('3');
217      vtkProperty* prop3Pts = planeWidget3Pts->GetPlaneProperty();
218      prop3Pts->SetColor(0, 1, 1);
219      planeWidget3Pts->SetLookupTable(planeWidgetX->GetLookupTable());
220
221      bbSetOutputPlaneX(planeWidgetX);
222      bbSetOutputPlaneY(planeWidgetY);
223      bbSetOutputPlaneZ(planeWidgetZ);
224          bbSetOutputPlane3Pts(planeWidget3Pts);  
225      bbSetOutputImageX(planeWidgetX->GetResliceOutput());
226      bbSetOutputImageY(planeWidgetY->GetResliceOutput());
227      bbSetOutputImageZ(planeWidgetZ->GetResliceOutput());
228          //bbSetOutputImage3Pts(planeWidget3Pts->GetResliceOutput());
229
230      picker->UnRegister(NULL);
231      
232      mVtkCallback = VtkCallbackType::New();
233      mVtkCallback->SetBlackBox(this);
234      planeWidgetX->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);
235      planeWidgetY->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);
236      planeWidgetZ->AddObserver(vtkCommand::InteractionEvent,mVtkCallback);  
237    }
238
239 //---------------------------------------------------------------------
240   void ImagePlanes::bbUserFinalizeProcessing()
241   {
242             
243     if (bbGetOutputPlaneX()) 
244       {
245
246         /*
247
248           bbGetOutputPlaneX()->RemoveObserver(mVtkCallback);
249           bbGetOutputPlaneY()->RemoveObserver(mVtkCallback);
250           bbGetOutputPlaneZ()->RemoveObserver(mVtkCallback);
251         
252         
253         bbGetOutputPlaneX()->Delete();
254         bbGetOutputPlaneY()->Delete();
255         bbGetOutputPlaneZ()->Delete();
256         mVtkCallback->Delete();
257         */
258         //bbGetOutputPlaneX()->SetInput(NULL);
259         //bbGetOutputPlaneY()->SetInput(NULL);
260         //bbGetOutputPlaneZ()->SetInput(NULL);
261         
262       }
263     
264   }
265   
266 //---------------------------------------------------------------------  
267 void ImagePlanes::Process()
268 {
269         if (bbGetInputIn()!=0)
270         {
271
272                 if ( image != bbGetInputIn()){//bbGetInputStatus("In") != bbtk::UPTODATE ){
273                         // Input image has changed : reinitialize planes
274                         image = bbGetInputIn();
275
276                         int xMin, xMax, yMin, yMax, zMin, zMax;
277                         bbGetInputIn()->GetExtent(xMin, xMax, yMin, yMax, zMin, zMax);
278
279                         // Initial values : center of the volume (in real world, not in pixels!)
280                         double xSpacing, ySpacing, zSpacing;
281                         bbGetInputIn()->GetSpacing(xSpacing, ySpacing, zSpacing);
282
283                         bbGetOutputPlaneX()->SetInput(bbGetInputIn());
284                         bbGetOutputPlaneX()->SetPlaneOrientationToXAxes();       
285                         bbGetOutputPlaneX()->SetSlicePosition((xMax+xMin)/2.*xSpacing);
286
287
288                         //                 bbGetOutputPlaneX()->SetOrigin( 58*xSpacing , 80*ySpacing , 82*zSpacing );
289                         //                 bbGetOutputPlaneX()->SetPoint1( 0*xSpacing, 146*ySpacing, 186*zSpacing);
290                         //                 bbGetOutputPlaneX()->SetPoint2( 126*xSpacing, 146*ySpacing, 0*zSpacing);
291
292
293                         bbGetOutputPlaneY()->SetInput(bbGetInputIn());
294                         bbGetOutputPlaneY()->SetPlaneOrientationToYAxes();
295                         bbGetOutputPlaneY()->SetSlicePosition((yMax+yMin)/2.*ySpacing);
296
297                         bbGetOutputPlaneZ()->SetInput(bbGetInputIn());
298                         bbGetOutputPlaneZ()->SetPlaneOrientationToZAxes();
299                         bbGetOutputPlaneZ()->SetSlicePosition((zMax+zMin)/2.*zSpacing);
300
301                         if (bbGetInputWindowLevel()[0]!=0)
302                         {
303                                 bbGetOutputPlaneZ()->SetWindowLevel(bbGetInputWindowLevel()[0],
304                                                                 bbGetInputWindowLevel()[1]);
305                         }
306                         else 
307                         {
308                                 double *range = image->GetScalarRange();
309                                 bbGetOutputPlaneZ()->SetWindowLevel(range[1] - range[0],
310                                                                 0.5*(range[1]+range[0]));
311                         }               
312
313            }
314                         // UPDATE DES SORTIES 
315                 bbGetOutputPlaneX()->GetResliceOutput()->Update();
316                 bbGetOutputPlaneY()->GetResliceOutput()->Update(); 
317                 bbGetOutputPlaneZ()->GetResliceOutput()->Update();               
318
319                 std::vector<int> pointsx = bbGetInputPointsX();
320                 std::vector<int> pointsy = bbGetInputPointsY();
321                 std::vector<int> pointsz = bbGetInputPointsZ();
322
323                 std::cout<<pointsx.size()<<pointsy.size()<<pointsz.size()<<std::endl;
324
325                 if(pointsx.size()==pointsy.size() && pointsx.size()==pointsz.size()&&pointsx.size()>=3){
326                         vtkImagePlaneWidget* plane3pts = (vtkImagePlaneWidget*)bbGetOutputPlane3Pts();
327                         //vtkPlaneWidget* plane3pts = (vtkPlaneWidget*)bbGetOutputPlane3Pts();
328
329                         plane3pts->SetInput(bbGetInputIn());
330
331                         //xSpacing = ySpacing = zSpacing = 1;
332                         double xSpacing, ySpacing, zSpacing;
333                         bbGetInputIn()->GetSpacing(xSpacing, ySpacing, zSpacing);
334
335                         plane3pts->SetOrigin(pointsx[0]*xSpacing,pointsy[0]*ySpacing,pointsz[0]*zSpacing);                              
336                         plane3pts->SetPoint1(pointsx[1]*xSpacing,pointsy[1]*ySpacing,pointsz[1]*zSpacing);
337                         //plane3pts->SetPoint1((pointsx[1]-pointsx[0])*xSpacing,(pointsy[1]-pointsy[0])*ySpacing,(pointsz[1]-pointsz[0])*zSpacing);
338                         plane3pts->SetPoint2(pointsx[2]*xSpacing,pointsy[2]*ySpacing,pointsz[2]*zSpacing);
339                         //plane3pts->SetPoint2((pointsx[2]-pointsx[0])*xSpacing,(pointsy[2]-pointsy[0])*ySpacing,(pointsz[2]-pointsz[0])*zSpacing);
340                         plane3pts->GetResliceOutput()->Update();
341
342
343
344                         if (_imageReslicer==NULL){
345                                 _imageReslicer = vtkImageReslice::New();                                        
346                                 _imageReslicer->SetOutputDimensionality(2);
347                                 _imageReslicer->SetInterpolationModeToLinear();
348                         }
349
350                         _imageReslicer->SetInput( bbGetInputIn() );
351                         _imageReslicer->SetInformationInput(bbGetInputIn());
352
353                         double origin[3];
354                         origin[0] = pointsx[0];
355                         origin[1] = pointsy[0];
356                         origin[2] = pointsz[0];
357
358                         double point1[3];
359                         point1[0] = pointsx[1];
360                         point1[1] = pointsy[1];
361                         point1[2] = pointsz[1];
362                         double point2[3];
363                         point2[0]= pointsx[2];
364                         point2[1]= pointsy[2];
365                         point2[2]= pointsz[2];                          
366
367                         double* vect1= getNormal(makeVector(origin, point1));
368                         double* vect2= getNormal(makeVector(origin, point2));                           
369                         double* crossp = getCrossProduct(vect1, vect2);
370
371                         /*std::cout<<"origin "<<origin[0]<<" "<<origin[1]<<" "<<origin[2]<<" "<<std::endl;
372                         std::cout<<"point1 "<<point1[0]<<" "<<point1[1]<<" "<<point1[2]<<" "<<std::endl;
373                         std::cout<<"point2 "<<point2[0]<<" "<<point2[1]<<" "<<point2[2]<<" "<<std::endl;
374                         std::cout<<"vect1 "<<vect1[0]<<" "<<vect1[1]<<" "<<vect1[2]<<" "<<std::endl;                            
375                         std::cout<<"vect2 "<<vect2[0]<<" "<<vect2[1]<<" "<<vect2[2]<<" "<<std::endl;
376                         std::cout<<"crossp "<<crossp[0]<<" "<<crossp[1]<<" "<<crossp[2]<<" "<<std::endl;*/
377
378
379                         _imageReslicer->SetResliceAxesDirectionCosines(vect1[0],vect1[1],vect1[2],
380                                                                                                                         vect2[0],vect2[1],vect2[2],
381                                                                                                                         crossp[0],crossp[1],crossp[2]);
382                         //_imageReslicer->SetResliceAxesOrigin(0,0,0);
383                         _imageReslicer->SetResliceAxesOrigin(origin[0],origin[1],origin[2]);
384
385                         _imageReslicer->GetOutput()->Update;
386                         _imageReslicer->GetOutput()->UpdateInformation();
387
388                         bbSetOutputImage3Pts(_imageReslicer->GetOutput());
389
390                         
391                 }
392                 
393         }
394 }
395         
396         
397         //-----------------------------------------------------------------     
398         void vtkImageDataPointerRelay::bbUserSetDefaultValues()
399         {
400         }
401         
402         //-----------------------------------------------------------------     
403         void vtkImageDataPointerRelay::bbUserInitializeProcessing()
404         {
405         }
406         
407         //-----------------------------------------------------------------     
408         void vtkImageDataPointerRelay::bbUserFinalizeProcessing()
409         {
410         }
411         
412         
413
414 double* ImagePlanes::getCrossProduct(double* vect0,double* vect1){
415         double* vectCross;
416         vectCross = new double[3];
417         vectCross[0] = vect0[1]*vect1[2]-(vect0[2]*vect1[1]);
418         vectCross[1] = -(vect0[0]*vect1[2]-(vect0[2]*vect1[0]));
419         vectCross[2] = vect0[0]*vect1[1]-(vect0[1]*vect1[0]);
420
421         return vectCross;
422 }
423 /**
424 **      Returns the magnitud of the given vector
425 **/
426 double ImagePlanes::getMagnitud(double* vect){
427
428         double mag;
429
430         mag = sqrt(pow(vect[0],2) + pow(vect[1],2) + pow(vect[2],2));
431
432         std::cout<<"mag "<<mag <<std::endl;
433
434         return mag;
435
436 }
437 /**
438 **      returns the unitary vector of the given vector
439 **      u = 1/|vect| . vect
440 **/
441 double* ImagePlanes::getNormal(double* vect){
442
443         double* vectnorm;
444         double mag = getMagnitud(vect);
445
446         vectnorm = new double[3];
447         
448
449         if(mag!=0){
450                 vectnorm[0] = vect[0]/mag;
451                 vectnorm[1] = vect[1]/mag;
452                 vectnorm[2] = vect[2]/mag;
453         }else{
454                 vectnorm[0] = 0;
455                 vectnorm[1] = 0;
456                 vectnorm[2] = 0;
457         }
458
459         return vectnorm;
460
461
462 }
463
464 double* ImagePlanes::makeVector(double podouble0[3], double podouble1[3]){
465         double *vect;
466         vect = new double[3];
467
468         vect[0]= podouble0[0]-podouble1[0];
469         vect[1]= podouble0[1]-podouble1[1];
470         vect[2]= podouble0[2]-podouble1[2];
471
472         return vect;
473
474 }
475         
476 }//namespace bbtk
477
478 #endif // _USE_VTK_
479
480