]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/include/vtk3DSurfaceWidget.cxx
*** empty log message ***
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / include / vtk3DSurfaceWidget.cxx
1 /*=========================================================================
2
3   Program:   wxMaracas
4   Module:    $RCSfile: vtk3DSurfaceWidget.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/05/14 13:54:57 $
7   Version:   $Revision: 1.1 $
8
9   Copyright: (c) 2002, 2003
10   License:
11   
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notice for more information.
15
16 =========================================================================*/
17 #include "vtk3DSurfaceWidget.h"
18 #include "../marDictionary.h"
19 #include <vtkInteractorStyleSwitch.h>
20 #include <vtkPointPicker.h>
21 #include <vtkPointData.h>
22 #include <vtkCellLocator.h>
23 #include <vtkCellArray.h>
24 #include <vtkStripper.h>
25 #include <vtkCamera.h>
26 #include "matrix.h"
27
28
29 #include "UtilVtk3DGeometriSelection.h"
30
31
32
33 /**
34  * Again wxVTK is an hybrid class, double click was done using wxWindows, simply
35  * because VTK doesn't provide such facility (as opposed to wheel support that is
36  * supposed to be merged in VTK trunk sooner or later:
37  *
38  * http://public.kitware.com/pipermail/vtkusers/2003-August/019548.html
39  * http://www.creatis.insa-lyon.fr/~malaterre/vtk/wheel.patch
40  */
41
42 //----------------------------------------------------------------------------
43 BEGIN_EVENT_TABLE( vtk3DSurfaceWidget, wxVTKRenderWindowInteractor )
44     EVT_LEFT_DCLICK( vtk3DSurfaceWidget::OnLeftDClick )
45         EVT_MOUSEWHEEL( vtk3DSurfaceWidget::OnMouseWheel )
46 END_EVENT_TABLE( );
47
48 //----------------------------------------------------------------------------
49 vtk3DSurfaceWidget::vtk3DSurfaceWidget( wxWindow* parent, wxWindowID id,
50                                        const wxPoint& pos, const wxSize& size,
51                                        long style, const wxString& name) 
52                                        : wxVTKRenderWindowInteractor( parent, id, pos, size, style, name )
53 {
54   //make current interactor style be trackbal camera, asked by radiologists.
55
56         /*
57   vtkInteractorStyleSwitch *iss = dynamic_cast<vtkInteractorStyleSwitch*>(this->GetInteractorStyle());
58   iss->SetCurrentStyleToTrackballCamera();
59   */
60
61
62   vtkInteractorStyle3DMaracas *interactorStyle3DMaracas = vtkInteractorStyle3DMaracas::New(); 
63 //  interactorStyle3DMaracas->SetInteractor (this);
64   this->SetInteractorStyle(interactorStyle3DMaracas);
65
66
67   _pRenderer                    = vtkRenderer::New( );
68   InitialSphere                 = 0;
69   _centralLine                  = NULL;
70   _centralLineMapper    = NULL;
71   _centralLineActor             = NULL;
72   _axesMapper                   = NULL;
73   _axesActor                    = NULL;
74   for(int i=0; i<4; i++) {
75     _spheres[ i ]               = NULL;
76     _spheresMapper[ i ] = NULL;
77     _spheresActor[ i ]  = NULL;
78   }
79   _axesActor                    = NULL;
80   _axesMapper                   = NULL;
81   _surfActor                    = NULL;
82   _surfMapper                   = NULL;
83   _intVtkPanWid                 = NULL;
84   _outActor                             = NULL;
85   _outMapper                    = NULL;
86   _outLine                              = NULL;
87   _mCubes                               = NULL;
88 }
89 //----------------------------------------------------------------------------
90 vtk3DSurfaceWidget::~vtk3DSurfaceWidget(){
91
92   //good luck:
93   if( _outActor )           _outActor                   ->      Delete( );
94   if( _outMapper )          _outMapper                  ->      Delete( );
95   if( _outLine )            _outLine                    ->      Delete( );
96   if( _surfActor )          _surfActor                  ->      Delete( );
97   if( _surfMapper )         _surfMapper                 ->      Delete( );
98   if( _mCubes )             _mCubes                             ->      Delete( );
99   if( _centralLine )        _centralLine                ->      Delete( );
100   if( _centralLineMapper )  _centralLineMapper  ->      Delete( );
101   if( _centralLineActor )   _centralLineActor   ->      Delete( );
102   if( _axesActor )          _axesActor                  ->      Delete();
103   if( _axesMapper )         _axesMapper                 ->      Delete();
104   for(int i=0; i<4; i++)
105   {
106     if( _spheres[ i ] )       _spheres[ i ]                     ->Delete( );
107     if( _spheresMapper[ i ] ) _spheresMapper[ i ]       ->Delete( );
108     if( _spheresActor[ i ] )  _spheresActor[ i ]        ->Delete( );
109   }
110   if( _pRenderer )          _pRenderer                  ->  Delete( );
111 }
112
113
114
115 //----------------------------------------------------------------------------
116 // virtual
117 void vtk3DSurfaceWidget::OnMouseWheel( wxMouseEvent& event ){ 
118         if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnMouseWheel(event);}
119 }
120 //----------------------------------------------------------------------------
121 void vtk3DSurfaceWidget::OnLeftDClick( wxMouseEvent& event ){
122         double pp[ 3 ], cp[ 3 ];
123         int eventrwi[2];
124         vtkPointPicker* picker = vtkPointPicker::New( );        
125         this->GetEventPosition( eventrwi );
126         picker->Pick( eventrwi[0], eventrwi[1], 0.0, _pRenderer );
127         _pRenderer->GetActiveCamera( )->GetPosition( cp );
128         picker->GetPickPosition( pp );
129
130         picker->Delete( );
131         this->SetLast3DClickPoint( pp, cp );
132         if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnLeftDClick(event); }
133 }
134 //----------------------------------------------------------------------------
135 void vtk3DSurfaceWidget::GetLast3DClickPoint( double *pp, double *cp ){
136         pp[0]=_lastPickPoint[0];
137         pp[1]=_lastPickPoint[1];
138         pp[2]=_lastPickPoint[2];
139         cp[0]=_lastCameraPos[0];
140         cp[1]=_lastCameraPos[1];
141         cp[2]=_lastCameraPos[2];
142 }
143 //----------------------------------------------------------------------------
144 void vtk3DSurfaceWidget::SetLast3DClickPoint( double *pp, double *cp ){
145         _lastPickPoint[0]=pp[0];
146         _lastPickPoint[1]=pp[1];
147         _lastPickPoint[2]=pp[2];
148         _lastCameraPos[0]=cp[0];
149         _lastCameraPos[1]=cp[1];
150         _lastCameraPos[2]=cp[2];
151 }
152 //----------------------------------------------------------------------------
153 void vtk3DSurfaceWidget::Render( ){
154         _pRenderWindow->Render();
155 }
156 //----------------------------------------------------------------------------
157 void vtk3DSurfaceWidget::InitCameraReset( ){
158         _pRenderer->ResetCameraClippingRange();
159         vtkCamera *cam=_pRenderer->GetActiveCamera();
160         cam->Zoom(1.8);
161 // EED 31 Mai 2007
162 //      Render();
163 }
164 //----------------------------------------------------------------------------
165 void vtk3DSurfaceWidget::SetSurfaceColor( float red, float green, float blue )
166 {
167   _surfActor->GetProperty()->SetColor(red, green, blue );
168   _pRenderWindow->Render();
169 }
170 //----------------------------------------------------------------------------
171 void vtk3DSurfaceWidget::SetSurfaceVisibility( bool visible )
172 {
173   _surfActor->SetVisibility( visible );
174   _pRenderWindow->Render();
175 }
176 //----------------------------------------------------------------------------
177 void vtk3DSurfaceWidget::SetSurfaceIsoValue( int isoval )
178 {
179   _mCubes->SetValue(0, isoval);
180   _pRenderWindow->Render();
181 }
182 //----------------------------------------------------------------------------
183 void vtk3DSurfaceWidget::SetSurfaceOpacity( int opaval )
184 {
185   //There is no way in Win32 to specify a slider different than 0->100
186   _surfActor->GetProperty()->SetOpacity( (double)opaval/100.0 );
187   _pRenderWindow->Render();
188 }
189 //----------------------------------------------------------------------------
190 void vtk3DSurfaceWidget::GetSphereCenter( double center[3] )
191 {
192         _spheres[ 3 ]->GetCenter( center );
193 }
194 //----------------------------------------------------------------------------
195 void vtk3DSurfaceWidget::SetAxis( vtkPolyData *axis )
196 {
197         _axesMapper = vtkPolyDataMapper::New( );
198         _axesMapper->SetInput( axis );
199         _axesMapper->Update();
200     //axis->Delete();
201
202         _axesActor = vtkActor::New( );
203         _axesActor->SetMapper( _axesMapper );
204         _axesActor->GetProperty()->SetColor( 1, 0, 0 );
205         _axesActor->GetProperty()->SetLineWidth( 2.0 );
206         _pRenderer->AddActor( _axesActor );
207
208         //Generate a new vtkwindow ???
209 //EED 31 Mai 2007
210 //      _pRenderWindow->Render( );
211  }
212 //----------------------------------------------------------------------------
213 void vtk3DSurfaceWidget::RemoveAxis( )
214 {
215   if (_axesActor)
216   {
217       _pRenderer->RemoveActor(_axesActor);
218       _axesActor->Delete();
219       _axesActor = NULL;
220       _pRenderWindow->Render( );
221         }
222 }
223 //----------------------------------------------------------------------------
224 void vtk3DSurfaceWidget::ShowMARACASData( marInterface* mar ){
225     int whd[3];
226
227     _mar = mar;
228     _marImageData = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
229     _marImageData->GetDimensions( whd );
230     _width  = whd[0];
231     _height = whd[1];
232     _depth  = whd[2];
233
234     _marImageData->GetScalarRange( _range );
235     
236     //Outline v2:
237     // An outline provides context around the data.
238     _outLine    = vtkOutlineFilter::New( );
239     _outLine->SetInput( _marImageData );
240     _outMapper  = vtkPolyDataMapper::New( );
241     _outMapper->SetInput( _outLine->GetOutput( ) );
242     _outActor   = vtkActor::New( );
243     _outActor->SetMapper( _outMapper );
244     _outActor->GetProperty( )->SetColor( 0.7, 0.0, 0.9 );
245     //_outActor->PickableOff( );
246     _pRenderer->AddActor( _outActor );
247
248     // Surface
249     _mCubes = vtkMarchingCubes::New( );
250     _surfMapper = vtkPolyDataMapper::New( );
251     _surfActor = vtkActor::New( );
252
253     _mCubes->SetInput( _marImageData );
254     _mCubes->SetValue( 0, _range[1] / 4 );
255
256     vtkStripper *stripper = vtkStripper::New();
257     stripper->SetInput( _mCubes->GetOutput( ) );
258
259          _surfMapper->SetInput( stripper->GetOutput() );
260     _surfMapper->ScalarVisibilityOff( );
261     stripper->Delete();
262
263     _surfActor->SetMapper( _surfMapper );
264     _surfActor->PickableOff( );
265     _surfActor->GetProperty( )->SetColor( 0.9803, 0.9215, 0.8392 );
266     _surfActor->GetProperty( )->SetOpacity( 0.5 );
267     _pRenderer->AddActor( _surfActor );
268
269     // 1. ParallelProjectionOn should be set after AddActor (otherwise call vtkRenderer::ResetCameraClippingRange
270     // 2. ParallelProjectionOn is *necessary* for the vtkImplicitSelectionLoop
271     // otherwise this give a cone instead of a cylinder cutting.
272     _pRenderer->GetActiveCamera()->ParallelProjectionOn();
273
274 }
275 //----------------------------------------------------------------------------
276 void vtk3DSurfaceWidget::ShowMARACASDataCT( marInterfaceCT* mar ){
277     int whd[3];
278
279
280     _marCT = mar;
281     _marImageData = _marCT->getDynData()->getVolume()->castVtk();
282     _marImageData->GetDimensions( whd );
283     _width  = whd[0];
284     _height = whd[1];
285     _depth  = whd[2];
286
287     _marImageData->GetScalarRange( _range );
288     
289         int a = (_marCT->GetExperiment())->getQuantStart();
290     //Outline v2:
291     // An outline provides context around the data.
292     _outLine    = vtkOutlineFilter::New( );
293     _outLine->SetInput( _marImageData );
294     _outMapper  = vtkPolyDataMapper::New( );
295     _outMapper->SetInput( _outLine->GetOutput( ) );
296     _outActor   = vtkActor::New( );
297     _outActor->SetMapper( _outMapper );
298     _outActor->GetProperty( )->SetColor( 0.7, 0.0, 0.9 );
299     //_outActor->PickableOff( );
300     _pRenderer->AddActor( _outActor );
301
302     // Surface
303     _mCubes = vtkMarchingCubes::New( );
304     _surfMapper = vtkPolyDataMapper::New( );
305     _surfActor = vtkActor::New( );
306
307     _mCubes->SetInput( _marImageData );
308     _mCubes->SetValue( 0, _range[1] / 4 );
309
310     vtkStripper *stripper = vtkStripper::New();
311     stripper->SetInput( _mCubes->GetOutput( ) );
312
313          _surfMapper->SetInput( stripper->GetOutput() );
314     _surfMapper->ScalarVisibilityOff( );
315     stripper->Delete();
316
317     _surfActor->SetMapper( _surfMapper );
318     _surfActor->PickableOff( );
319     _surfActor->GetProperty( )->SetColor( 0.9803, 0.9215, 0.8392 );
320     _surfActor->GetProperty( )->SetOpacity( 0.5 );
321     _pRenderer->AddActor( _surfActor );
322
323     // 1. ParallelProjectionOn should be set after AddActor (otherwise call vtkRenderer::ResetCameraClippingRange
324     // 2. ParallelProjectionOn is *necessary* for the vtkImplicitSelectionLoop
325     // otherwise this give a cone instead of a cylinder cutting.
326     _pRenderer->GetActiveCamera()->ParallelProjectionOn();
327
328 }
329 //----------------------------------------------------------------------------
330 void vtk3DSurfaceWidget::SetInitialPoint(){
331         this->SetInitialPoint( _lastPickPoint, _lastCameraPos );
332 }
333 //----------------------------------------------------------------------------
334 void vtk3DSurfaceWidget::SetInitialPoint( float* pickPoint, float* cameraPos ){
335         marDictionary marDict;
336         char ttmp[256];
337
338     gtm::TVector< double > pO( 3 ), pF( 3 ), pp( 3 ), cp( 3 );
339     gtm::TVector< double > xc( 3 );
340     gtm::TVector< double > x1( 3 ), n1( 3 );
341     gtm::TVector< double > x2( 3 ), n2( 3 );
342     gtm::TVector< double > tmp( 3 );
343     double fac;
344     bool success                = true;
345     int notSuccessType  = 0;
346
347     if( _centralLineActor )
348     {
349         _pRenderer->RemoveActor( _centralLineActor );
350         _centralLineActor->Delete( );
351     } // fi
352     if( _centralLineMapper ) _centralLineMapper->Delete( );
353     if( _centralLine )       _centralLine->Delete( );
354
355     _centralLine       = NULL;
356     _centralLineMapper = NULL;
357     _centralLineActor  = NULL;
358
359     for(int i=0; i<4; i++)
360     {
361       if( _spheresActor[ i ] )
362       {
363         _pRenderer->RemoveActor( _spheresActor[ i ] );
364         _spheresActor[ i ]->Delete( );
365       } // fi
366       if( _spheresMapper[ i ] ) _spheresMapper[ i ]->Delete( );
367       if( _spheres[ i ] )       _spheres[ i ]->Delete( );
368       _spheres[ i ] = NULL;
369       _spheresMapper[ i ] = NULL;
370       _spheresActor[ i ] = NULL;
371     } //rof
372
373     fac = GTM_MAX( _width, _height );
374     fac = 2 * GTM_MAX( fac, _depth );
375     pp( 0 ) = pickPoint[ 0 ]; pp( 1 ) = pickPoint[ 1 ]; pp( 2 ) = pickPoint[ 2 ];
376     cp( 0 ) = cameraPos[ 0 ]; cp( 1 ) = cameraPos[ 1 ]; cp( 2 ) = cameraPos[ 2 ];
377
378
379         UtilVtk3DGeometriSelection utilVtk3DGeometriSelection;
380         utilVtk3DGeometriSelection.SetDimentions(_width,_height,_depth);
381         utilVtk3DGeometriSelection.SetMarchingCube(_mCubes);
382
383     if( utilVtk3DGeometriSelection.FindCubePointsFromPoints(
384       pO.GetAnsiRef( ), pF.GetAnsiRef( ),
385       pp.GetAnsiRef( ), cp.GetAnsiRef( )
386     ) ) {
387
388         if( utilVtk3DGeometriSelection.GetPointAndNormalIntersection(
389             x1.GetAnsiRef( ), n1.GetAnsiRef( ),
390             pO.GetAnsiRef( ), pF.GetAnsiRef( )
391     ) ) {
392
393             if( utilVtk3DGeometriSelection.GetPointAndNormalIntersection(
394           x2.GetAnsiRef( ), n2.GetAnsiRef( ),
395           ( x1 - n1 ).GetAnsiRef( ), ( x1 - ( n1 * fac ) ).GetAnsiRef( )
396         ) ) {
397
398                 xc = ( x2 + x1 ) * 0.5;
399
400
401                 double dd=12; // EED   ****** ATENTION ****************
402
403                 if (!(
404                         (xc(0)<dd) || (xc(1)<dd) || (xc(2)<dd) || 
405                         (fabs(xc(0)-_width)<dd) || (fabs(xc(1)-_height)<dd) || (fabs(xc(2)-_depth)<dd) 
406                         )){
407
408                 _mar->_experiment->setStartPoint( (int)xc( 0 ), (int)xc( 1 ), (int)xc( 2 ) );
409         _mar->_experiment->getParameters( )->setROIStep( 2*( xc - x1 ).GetNorm( ) );
410
411       for(int i=0; i<4; i++)
412       {
413         _spheres[ i ] = vtkSphereSource::New( );
414         _spheresMapper[ i ] = vtkPolyDataMapper::New( );
415         _spheresMapper[ i ]->SetInput( _spheres[ i ]->GetOutput( ) );
416         _spheresActor[ i ] = vtkActor::New( );
417         _spheresActor[ i ]->SetMapper( _spheresMapper[ i ] );
418         _spheresActor[ i ]->PickableOff( );
419         _pRenderer->AddActor( _spheresActor[ i ] );
420       }
421
422                 _spheres[ 0 ]->SetCenter( x1( 0 ), x1( 1 ), x1( 2 ) );
423                 _spheres[ 1 ]->SetCenter( x2( 0 ), x2( 1 ), x2( 2 ) );
424                 _spheres[ 2 ]->SetCenter( xc( 0 ), xc( 1 ), xc( 2 ) );
425                 _spheres[ 3 ]->SetCenter( xc( 0 ), xc( 1 ), xc( 2 ) );
426
427                 _spheres[ 0 ]->SetRadius( 0.5 );
428                 _spheres[ 1 ]->SetRadius( 0.5 );
429                 _spheres[ 2 ]->SetRadius( 0.5 );
430                 _spheres[ 3 ]->SetRadius( ( xc - x1 ).GetNorm( ) );
431
432                 _spheresActor[ 0 ]->GetProperty( )->SetColor( 1.0, 0.0, 0.0 );
433                 _spheresActor[ 1 ]->GetProperty( )->SetColor( 0.0, 1.0, 0.0 );
434                 _spheresActor[ 2 ]->GetProperty( )->SetColor( 0.0, 0.0, 1.0 );
435                 _spheresActor[ 3 ]->GetProperty( )->SetColor( 1.0, 0.0, 0.0 );
436                 _spheresActor[ 3 ]->GetProperty( )->SetOpacity( 0.3 );
437
438                 vtkPoints* points = vtkPoints::New( );
439                 points->InsertNextPoint( x1.GetAnsiRef( ) );
440                 points->InsertNextPoint( x2.GetAnsiRef( ) );
441
442                 vtkCellArray* array = vtkCellArray::New( );
443                 array->InsertNextCell( 2 );
444                 array->InsertCellPoint( 0 );
445                 array->InsertCellPoint( 1 );
446
447                 _centralLine = vtkPolyData::New( );
448                 _centralLine->SetPoints( points );
449                 _centralLine->SetLines( array );
450       points->Delete();
451       array->Delete();
452
453                 _centralLineMapper = vtkPolyDataMapper::New( );
454                 _centralLineMapper->SetInput( _centralLine );
455
456                 _centralLineActor = vtkActor::New( );
457                 _centralLineActor->SetMapper( _centralLineMapper );
458                 _centralLineActor->GetProperty( )->SetColor( 1.0, 1.0, 1.0 );
459                 _centralLineActor->PickableOff( );
460                 _pRenderer->AddActor( _centralLineActor );
461
462
463            } else  {success = false; notSuccessType=1; }
464
465         } // fi
466
467         } else success = false;
468
469     } else success = false;
470
471     // Show a message, if any.
472     if (( !success ) && (notSuccessType==0)) {
473                 strcpy( ttmp , marDict.GetString(905) ); strcat( ttmp , "\n \n" ); strcat( ttmp , marDict.GetString(910) );
474         wxMessageBox( wxString(ttmp, wxConvUTF8) , // "Set an initial point.\n \n (Double click over the interest artery.)"
475                                           _T("DxMM : MARACAS"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
476         }
477     if ((!success ) && (notSuccessType==1)) {
478                 strcpy( ttmp , marDict.GetString(915) ); strcat( ttmp , "\n \n" ); strcat( ttmp , marDict.GetString(920) );
479         wxMessageBox( wxString(ttmp, wxConvUTF8), //"The initial point should be far \n of the limits of the volume."
480                                           _T("DxMM : MARACAS"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
481         }
482     // Finish
483     _pRenderWindow->Render( );
484     InitialSphere = success;
485
486 }
487 //----------------------------------------------------------------------------
488 void vtk3DSurfaceWidget::ConfigureVTK( )
489 {
490   // get render window
491   _pRenderWindow =  this->GetRenderWindow(  );
492
493   // connect renderer and render window and configure render window
494   _pRenderWindow->AddRenderer( _pRenderer );
495
496   // configure renderer
497   _pRenderer->SetBackground( 0.0, 0.0, 0.0 );
498   //_pRenderer->SetBackground( 1, 1, 0);  //FIXME
499   _pRenderer->GetActiveCamera( )->Zoom( 1.0 );
500   _pRenderer->GetActiveCamera( )->SetClippingRange( 1, 1000 );
501   _pRenderer->ResetCamera( );
502
503 //EED 22Mai2007 
504 //  AttachRenderWindow();
505
506 }
507
508
509 //----------------------------------------------------------------------------
510 vtkRenderer* vtk3DSurfaceWidget::GetRenderer(){
511         return _pRenderer;
512 }
513 //----------------------------------------------------------------------------
514
515