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