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