1 /*=========================================================================
4 Module: $RCSfile: vtk3DSurfaceWidget.cxx,v $
6 Date: $Date: 2008/10/31 16:32:41 $
7 Version: $Revision: 1.1 $
9 Copyright: (c) 2002, 2003
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.
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>
29 #include "UtilVtk3DGeometriSelection.h"
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:
38 * http://public.kitware.com/pipermail/vtkusers/2003-August/019548.html
39 * http://www.creatis.insa-lyon.fr/~malaterre/vtk/wheel.patch
42 //----------------------------------------------------------------------------
43 BEGIN_EVENT_TABLE( vtk3DSurfaceWidget, wxVTKRenderWindowInteractor )
44 EVT_LEFT_DCLICK( vtk3DSurfaceWidget::OnLeftDClick )
45 EVT_MOUSEWHEEL( vtk3DSurfaceWidget::OnMouseWheel )
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 )
54 //make current interactor style be trackbal camera, asked by radiologists.
57 vtkInteractorStyleSwitch *iss = dynamic_cast<vtkInteractorStyleSwitch*>(this->GetInteractorStyle());
58 iss->SetCurrentStyleToTrackballCamera();
62 vtkInteractorStyle3DMaracas *interactorStyle3DMaracas = vtkInteractorStyle3DMaracas::New();
63 // interactorStyle3DMaracas->SetInteractor (this);
64 this->SetInteractorStyle(interactorStyle3DMaracas);
67 _pRenderer = vtkRenderer::New( );
70 _centralLineMapper = NULL;
71 _centralLineActor = NULL;
74 for(int i=0; i<4; i++) {
76 _spheresMapper[ i ] = NULL;
77 _spheresActor[ i ] = NULL;
89 //----------------------------------------------------------------------------
90 vtk3DSurfaceWidget::~vtk3DSurfaceWidget(){
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++)
106 if( _spheres[ i ] ) _spheres[ i ] ->Delete( );
107 if( _spheresMapper[ i ] ) _spheresMapper[ i ] ->Delete( );
108 if( _spheresActor[ i ] ) _spheresActor[ i ] ->Delete( );
110 if( _pRenderer ) _pRenderer -> Delete( );
115 //----------------------------------------------------------------------------
117 void vtk3DSurfaceWidget::OnMouseWheel( wxMouseEvent& event ){
118 if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnMouseWheel(event);}
120 //----------------------------------------------------------------------------
121 void vtk3DSurfaceWidget::OnLeftDClick( wxMouseEvent& event ){
122 double pp[ 3 ], cp[ 3 ];
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 );
131 this->SetLast3DClickPoint( pp, cp );
132 if (_intVtkPanWid!=NULL) { _intVtkPanWid->CallBackOnLeftDClick(event); }
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];
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];
152 //----------------------------------------------------------------------------
153 void vtk3DSurfaceWidget::Render( ){
154 _pRenderWindow->Render();
156 //----------------------------------------------------------------------------
157 void vtk3DSurfaceWidget::InitCameraReset( ){
158 _pRenderer->ResetCameraClippingRange();
159 vtkCamera *cam=_pRenderer->GetActiveCamera();
164 //----------------------------------------------------------------------------
165 void vtk3DSurfaceWidget::SetSurfaceColor( float red, float green, float blue )
167 _surfActor->GetProperty()->SetColor(red, green, blue );
168 _pRenderWindow->Render();
170 //----------------------------------------------------------------------------
171 void vtk3DSurfaceWidget::SetSurfaceVisibility( bool visible )
173 _surfActor->SetVisibility( visible );
174 _pRenderWindow->Render();
176 //----------------------------------------------------------------------------
177 void vtk3DSurfaceWidget::SetSurfaceIsoValue( int isoval )
179 _mCubes->SetValue(0, isoval);
180 _pRenderWindow->Render();
182 //----------------------------------------------------------------------------
183 void vtk3DSurfaceWidget::SetSurfaceOpacity( int opaval )
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();
189 //----------------------------------------------------------------------------
190 void vtk3DSurfaceWidget::GetSphereCenter( double center[3] )
192 _spheres[ 3 ]->GetCenter( center );
194 //----------------------------------------------------------------------------
195 void vtk3DSurfaceWidget::SetAxis( vtkPolyData *axis )
197 _axesMapper = vtkPolyDataMapper::New( );
198 _axesMapper->SetInput( axis );
199 _axesMapper->Update();
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 );
208 //Generate a new vtkwindow ???
210 // _pRenderWindow->Render( );
212 //----------------------------------------------------------------------------
213 void vtk3DSurfaceWidget::RemoveAxis( )
217 _pRenderer->RemoveActor(_axesActor);
218 _axesActor->Delete();
220 _pRenderWindow->Render( );
223 //----------------------------------------------------------------------------
224 void vtk3DSurfaceWidget::ShowMARACASData( marInterface* mar ){
228 _marImageData = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
229 _marImageData->GetDimensions( whd );
234 _marImageData->GetScalarRange( _range );
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 );
249 _mCubes = vtkMarchingCubes::New( );
250 _surfMapper = vtkPolyDataMapper::New( );
251 _surfActor = vtkActor::New( );
253 _mCubes->SetInput( _marImageData );
254 _mCubes->SetValue( 0, _range[1] / 4 );
256 vtkStripper *stripper = vtkStripper::New();
257 stripper->SetInput( _mCubes->GetOutput( ) );
259 _surfMapper->SetInput( stripper->GetOutput() );
260 _surfMapper->ScalarVisibilityOff( );
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 );
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();
275 //----------------------------------------------------------------------------
276 void vtk3DSurfaceWidget::ShowMARACASDataCT( marInterfaceCT* mar ){
281 _marImageData = _marCT->getDynData()->getVolume()->castVtk();
282 _marImageData->GetDimensions( whd );
287 _marImageData->GetScalarRange( _range );
289 int a = (_marCT->GetExperiment())->getQuantStart();
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 );
303 _mCubes = vtkMarchingCubes::New( );
304 _surfMapper = vtkPolyDataMapper::New( );
305 _surfActor = vtkActor::New( );
307 _mCubes->SetInput( _marImageData );
308 _mCubes->SetValue( 0, _range[1] / 4 );
310 vtkStripper *stripper = vtkStripper::New();
311 stripper->SetInput( _mCubes->GetOutput( ) );
313 _surfMapper->SetInput( stripper->GetOutput() );
314 _surfMapper->ScalarVisibilityOff( );
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 );
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();
329 //----------------------------------------------------------------------------
330 void vtk3DSurfaceWidget::SetInitialPoint(){
331 this->SetInitialPoint( _lastPickPoint, _lastCameraPos );
333 //----------------------------------------------------------------------------
334 void vtk3DSurfaceWidget::SetInitialPoint( float* pickPoint, float* cameraPos ){
335 marDictionary marDict;
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 );
345 int notSuccessType = 0;
347 if( _centralLineActor )
349 _pRenderer->RemoveActor( _centralLineActor );
350 _centralLineActor->Delete( );
352 if( _centralLineMapper ) _centralLineMapper->Delete( );
353 if( _centralLine ) _centralLine->Delete( );
356 _centralLineMapper = NULL;
357 _centralLineActor = NULL;
359 for(int i=0; i<4; i++)
361 if( _spheresActor[ i ] )
363 _pRenderer->RemoveActor( _spheresActor[ i ] );
364 _spheresActor[ i ]->Delete( );
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;
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 ];
379 UtilVtk3DGeometriSelection utilVtk3DGeometriSelection;
380 utilVtk3DGeometriSelection.SetDimentions(_width,_height,_depth);
381 utilVtk3DGeometriSelection.SetMarchingCube(_mCubes);
383 if( utilVtk3DGeometriSelection.FindCubePointsFromPoints(
384 pO.GetAnsiRef( ), pF.GetAnsiRef( ),
385 pp.GetAnsiRef( ), cp.GetAnsiRef( )
388 if( utilVtk3DGeometriSelection.GetPointAndNormalIntersection(
389 x1.GetAnsiRef( ), n1.GetAnsiRef( ),
390 pO.GetAnsiRef( ), pF.GetAnsiRef( )
393 if( utilVtk3DGeometriSelection.GetPointAndNormalIntersection(
394 x2.GetAnsiRef( ), n2.GetAnsiRef( ),
395 ( x1 - n1 ).GetAnsiRef( ), ( x1 - ( n1 * fac ) ).GetAnsiRef( )
398 xc = ( x2 + x1 ) * 0.5;
401 double dd=12; // EED ****** ATENTION ****************
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)
408 _mar->_experiment->setStartPoint( (int)xc( 0 ), (int)xc( 1 ), (int)xc( 2 ) );
409 _mar->_experiment->getParameters( )->setROIStep( 2*( xc - x1 ).GetNorm( ) );
411 for(int i=0; i<4; i++)
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 ] );
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 ) );
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( ) );
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 );
438 vtkPoints* points = vtkPoints::New( );
439 points->InsertNextPoint( x1.GetAnsiRef( ) );
440 points->InsertNextPoint( x2.GetAnsiRef( ) );
442 vtkCellArray* array = vtkCellArray::New( );
443 array->InsertNextCell( 2 );
444 array->InsertCellPoint( 0 );
445 array->InsertCellPoint( 1 );
447 _centralLine = vtkPolyData::New( );
448 _centralLine->SetPoints( points );
449 _centralLine->SetLines( array );
453 _centralLineMapper = vtkPolyDataMapper::New( );
454 _centralLineMapper->SetInput( _centralLine );
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 );
463 } else {success = false; notSuccessType=1; }
467 } else success = false;
469 } else success = false;
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);
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);
483 _pRenderWindow->Render( );
484 InitialSphere = success;
487 //----------------------------------------------------------------------------
488 void vtk3DSurfaceWidget::ConfigureVTK( )
491 _pRenderWindow = this->GetRenderWindow( );
493 // connect renderer and render window and configure render window
494 _pRenderWindow->AddRenderer( _pRenderer );
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( );
504 // AttachRenderWindow();
509 //----------------------------------------------------------------------------
510 vtkRenderer* vtk3DSurfaceWidget::GetRenderer(){
513 //----------------------------------------------------------------------------