vtk3DSurfaceSTLWidget.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   wxMaracas
00004   Module:    $RCSfile: vtk3DSurfaceSTLWidget.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2009/05/14 13:54:57 $
00007   Version:   $Revision: 1.1 $
00008 
00009   Copyright: (c) 2002, 2003
00010   License:
00011   
00012      This software is distributed WITHOUT ANY WARRANTY; without even 
00013      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014      PURPOSE.  See the above copyright notice for more information.
00015 
00016 =========================================================================*/
00017 
00018 #include "vtkClosePolyData.h"
00019 
00020 #include <vtkTriangleFilter.h>
00021 #include <vtkSTLWriter.h>
00022 #include <vtkInteractorStyleSwitch.h>
00023 #include <vtkPointPicker.h>
00024 #include <vtkCamera.h>
00025 #include <vtkPointData.h>
00026 #include <vtkFloatArray.h>
00027 //For STL
00028 #include <vtkCellLocator.h>
00029 #include <vtkInteractorStyleTrackballCamera.h>
00030 #include <vtkCellArray.h>
00031 #include <vtkStripper.h>
00032 //For rubber stuff:
00033 #include <vtkImplicitSelectionLoop.h>
00034 #include <vtkExtractPolyDataGeometry.h>
00035 #include <vtkPolyDataConnectivityFilter.h>
00036 #include <vtkPolyDataNormals.h>
00037 
00038 #include "vtk3DSurfaceSTLWidget.h"
00039 
00040 #include "volume.hxx"
00041 #include "marInterface.h"
00042 #include "matrix.h"
00043 
00044 
00045 
00055 //----------------------------------------------------------------------------
00056 BEGIN_EVENT_TABLE( vtk3DSurfaceSTLWidget, wxVTKRenderWindowInteractor )
00057 //EED    EVT_LEFT_DCLICK( vtk3DSurfaceSTLWidget::OnLeftDClick )
00058 END_EVENT_TABLE( );
00059 
00060 //----------------------------------------------------------------------------
00061 vtk3DSurfaceSTLWidget::vtk3DSurfaceSTLWidget(
00062         wxWindow* parent,
00063         wxWindowID id,
00064         const wxPoint& pos,
00065         const wxSize& size,
00066         long style,
00067         const wxString& name)
00068         : wxVTKRenderWindowInteractor( parent, id, pos, size, style, name ){
00069 
00070 
00071         //make current interactor style be trackbal camera, asked by radiologists.
00072 //      vtkInteractorStyleSwitch *iss = dynamic_cast<vtkInteractorStyleSwitch*>(this->GetInteractorStyle());
00073 //      iss->SetCurrentStyleToTrackballCamera();
00074   
00075 
00076   vtkInteractorStyle3DMaracas *interactorStyle3DMaracas = vtkInteractorStyle3DMaracas::New(); 
00077   interactorStyle3DMaracas->SetInteractor (this);
00078   this->SetInteractorStyle(interactorStyle3DMaracas);
00079 
00080 
00081         _pRenderer  = vtkRenderer::New( );
00082         InitialSphere = 0;
00083     _centralLine       = NULL;
00084     _centralLineMapper = NULL;
00085     _centralLineActor  = NULL;
00086     _axesMapper = NULL;
00087     _axesActor = NULL;
00088     for(int i=0; i<4; i++)
00089     {
00090         _spheres[ i ]           = NULL;
00091         _spheresMapper[ i ] = NULL;
00092         _spheresActor[ i ]      = NULL;
00093     }
00094         _axesActor                      = NULL;
00095         _axesMapper                     = NULL;
00096         _psc                            = NULL;
00097         _stlExternalVessel      = _stlInternalVessel    = NULL;
00098         _surfMapper                     = NULL;
00099         _actorExternalVessel= _actorVessel                      = NULL;
00100         _iasc                           = NULL;
00101 }
00102 //----------------------------------------------------------------------------
00103 vtk3DSurfaceSTLWidget::~vtk3DSurfaceSTLWidget()
00104 {
00105   //good luck:
00106   if( _outActor )           _outActor           ->Delete( );
00107   if( _outMapper )          _outMapper          ->Delete( );
00108   if( _outLine )            _outLine            ->Delete( );
00109   if( _surfActor )          _surfActor          ->Delete( );
00110   if( _surfMapper )         _surfMapper         ->Delete( );
00111   if( _mCubes )             _mCubes                     ->Delete( );
00112   if( _centralLine )        _centralLine        ->Delete( );
00113   if( _centralLineMapper )  _centralLineMapper->Delete( );
00114   if( _centralLineActor )   _centralLineActor ->Delete( );
00115   if( _axesActor )          _axesActor          ->Delete();
00116   if( _axesMapper )         _axesMapper         ->Delete();
00117   if( _actorVessel )        _actorVessel        ->Delete();
00118   if( _actorExternalVessel )_actorExternalVessel->Delete();
00119 //  if( _stlExternalVessel )  _stlExternalVessel->Delete();
00120 //  if( _stlInternalVessel )  _stlInternalVessel->Delete();
00121   if( _psc )                _psc                        ->Delete();
00122   if(_iasc)                 _iasc                       ->Delete();
00123   for(int i=0; i<4; i++)
00124   {
00125     if( _spheres[ i ] )       _spheres[ i ]                     ->Delete( );
00126     if( _spheresMapper[ i ] ) _spheresMapper[ i ]       ->Delete( );
00127     if( _spheresActor[ i ] )  _spheresActor[ i ]        ->Delete( );
00128   }
00129   if( _pRenderer )          _pRenderer          ->Delete( );
00130 }
00131 
00132 //----------------------------------------------------------------------------
00133 void vtk3DSurfaceSTLWidget::SetSurfaceColor( float red, float green, float blue )
00134 {
00135   _surfActor->GetProperty()->SetColor(red, green, blue );
00136   _pRenderWindow->Render();
00137 }
00138 //----------------------------------------------------------------------------
00139 void vtk3DSurfaceSTLWidget::SetSurfaceVisibility( bool visible )
00140 {
00141   _surfActor->SetVisibility( visible );
00142   _pRenderWindow->Render();
00143 }
00144 //----------------------------------------------------------------------------
00145 void vtk3DSurfaceSTLWidget::SetSTLSurfaceVisibility( bool intvisible , bool extvisible)
00146 {
00148   _actorVessel->SetVisibility( intvisible );
00149   _actorExternalVessel->SetVisibility( extvisible );
00150   _pRenderWindow->Render();
00151 }
00152 //----------------------------------------------------------------------------
00153 void vtk3DSurfaceSTLWidget::SetSurfaceIsoValue( int isoval )
00154 {
00155   _mCubes->SetValue(0, isoval);
00156   _pRenderWindow->Render();
00157 }
00158 //----------------------------------------------------------------------------
00159 void vtk3DSurfaceSTLWidget::SetSurfaceOpacity( int opaval )
00160 {
00161   //There is no way in Win32 to specify a slider different than 0->100
00162   _surfActor->GetProperty()->SetOpacity( (float)opaval/100 );
00163   _pRenderWindow->Render();
00164 }
00165 //----------------------------------------------------------------------------
00166 void vtk3DSurfaceSTLWidget::GetSphereCenter( double center[3] )
00167 {
00168         _spheres[ 3 ]->GetCenter( center );
00169 }
00170 //----------------------------------------------------------------------------
00171 void vtk3DSurfaceSTLWidget::SetAxis( vtkPolyData *axis )
00172 {
00173         _axesMapper = vtkPolyDataMapper::New( );
00174         _axesMapper->SetInput( axis );
00175         axis->Delete();
00176 
00177         _axesActor = vtkActor::New( );
00178         _axesActor->SetMapper( _axesMapper );
00179         _axesActor->GetProperty()->SetColor( 1, 0, 0 );
00180         _pRenderer->AddActor( _axesActor );
00181 
00182         _pRenderWindow->Render( );
00183 }
00184 //----------------------------------------------------------------------------
00185 void vtk3DSurfaceSTLWidget::RemoveAxis( )
00186 {
00187   if (_axesActor)
00188   {
00189       _pRenderer->RemoveActor(_axesActor);
00190       _axesActor->Delete();
00191       _axesActor = NULL;
00192       _pRenderWindow->Render( );
00193         }
00194 }
00195 //----------------------------------------------------------------------------
00196 void vtk3DSurfaceSTLWidget::SetCuttingMode( bool mode )
00197 {
00198   if( mode )
00199     {
00200       //start rubber/cutter mode
00201       if(!_iasc) 
00202         {
00203         _iasc = vtkInteractorStyleCutter::New();
00204         }
00205       this->SetInteractorStyle( _iasc );
00206     }
00207   else
00208     {
00212       if( _iasc )
00213       {
00214         _iasc->VisibilityOff(); //turn off the vtkInteractorStyleCutter
00215         vtkImplicitSelectionLoop *loop = vtkImplicitSelectionLoop::New();
00216         loop->SetLoop( _iasc->GetLoopPoints() );
00217         loop->SetNormal( _iasc->GetDirection() );
00218 
00219         vtkTriangleFilter *tf = vtkTriangleFilter::New();
00220         tf->SetInput( _stlInternalVessel );
00221 
00222         vtkExtractPolyDataGeometry *extract = vtkExtractPolyDataGeometry::New ();
00223         extract->SetInput ( tf->GetOutput());
00224         extract->SetImplicitFunction ( loop );
00225         extract->ExtractInsideOff ();
00226         extract->ExtractBoundaryCellsOff ();
00227         tf->Delete();
00228         loop->Delete();
00229 
00230         //#connectivity filter to keep only the largest part
00231         vtkPolyDataConnectivityFilter *connect = vtkPolyDataConnectivityFilter::New();
00232         connect->SetInput( extract->GetOutput() );
00233         connect->SetExtractionModeToLargestRegion ();
00234         extract->Delete();
00235 
00236         vtkClosePolyData *close = vtkClosePolyData::New();
00237         close->SetInput( connect->GetOutput() );
00238         connect->Delete();
00239 
00240         vtkStripper *strip = vtkStripper::New();
00241         strip->SetInput( close->GetOutput() );
00242         close->Delete();
00243 
00244         //If vtkClosePolyData was well written we wouldn't had to recompute the normals
00245         vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
00246         normals->SetInput( strip->GetOutput() );
00247         strip->Delete();
00248 
00249         /*vtkPolyDataWriter *polywriter = vtkPolyDataWriter::New();
00250         polywriter->SetInput( normals->GetOutput() );
00251         polywriter->SetFileName( "cutter.vtk" );
00252         polywriter->SetFileTypeToBinary();
00253         polywriter->Write();
00254         polywriter->Delete();*/
00255 
00256         normals->Update(); //important before a ShallowCopy Or DeepCopy
00257         _stlInternalVessel->DeepCopy( normals->GetOutput() ); //Use DeepCopy when using ShallowCopy afterwards
00258 
00259         tf->SetInput( _stlExternalVessel );
00260         normals->Update();  //important before a ShallowCopy
00261         _stlExternalVessel->ShallowCopy( normals->GetOutput() );
00262         _pRenderWindow->Render( );
00263       }
00264       //make current interactor style be trackbal camera, asked by radiologists.
00265       vtkInteractorStyleTrackballCamera *istc = vtkInteractorStyleTrackballCamera::New();
00266       this->SetInteractorStyle( istc );
00267       istc->Delete();
00268     }
00269 
00270 }
00271 //----------------------------------------------------------------------------
00272 void vtk3DSurfaceSTLWidget::ExportSurfaceAsSTL( const char* fileprefix )
00273 {
00274    std::string prefix;
00275 
00276    //Now save for real in STL format
00277    //Don't forget to go through a triangle filter
00278    vtkTriangleFilter *triangle = vtkTriangleFilter::New();
00279    triangle->SetInput( _stlInternalVessel );
00280    //In difficult case (such as BESSON) mesh can be more than one piece:
00281    vtkPolyDataConnectivityFilter *pdcf = vtkPolyDataConnectivityFilter::New();
00282    pdcf->SetInput( triangle->GetOutput() );
00283    //In difficult case (such as BESSON) mesh can still be open...close it !
00284    vtkClosePolyData *close = vtkClosePolyData::New();
00285    close->SetInput( pdcf->GetOutput() );
00286    
00287    vtkSTLWriter *internal_mold_stl = vtkSTLWriter::New();
00288    internal_mold_stl->SetInput( close->GetOutput() );
00289    prefix = fileprefix;
00290    prefix += "-internal.stl";
00291    internal_mold_stl->SetFileName( prefix.c_str() );
00292    internal_mold_stl->SetFileTypeToBinary();
00293    internal_mold_stl->Write();
00294    internal_mold_stl->Delete();
00295    
00296    //convert to triangles first:
00297    triangle->SetInput( _stlExternalVessel );
00298    
00299    vtkSTLWriter *external_mold_stl = vtkSTLWriter::New();
00300    external_mold_stl->SetInput( close->GetOutput() );
00301    prefix = fileprefix;
00302    prefix += "-external.stl";
00303    external_mold_stl->SetFileName( prefix.c_str() );
00304    external_mold_stl->SetFileTypeToBinary();
00305    external_mold_stl->Write();
00306    external_mold_stl->Delete();
00307    
00308    triangle->Delete();
00309    close->Delete();
00310    pdcf->Delete();
00311 }
00312 //----------------------------------------------------------------------------
00313 void vtk3DSurfaceSTLWidget::ShowMARACASData( marInterface* mar ){
00314     int whd[3];
00315     double minmax[2];
00316 
00317     _mar = mar;
00318     _marImageData = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
00319     _marImageData->GetDimensions( whd );
00320     _width  = whd[0];
00321     _height = whd[1];
00322     _depth  = whd[2];
00323 
00324     _marImageData->GetScalarRange( minmax );
00325     
00326     //Outline v2:
00327     // An outline provides context around the data.
00328     _outLine    = vtkOutlineFilter::New( );
00329     _outLine->SetInput( _marImageData );
00330     _outMapper  = vtkPolyDataMapper::New( );
00331     _outMapper->SetInput( _outLine->GetOutput( ) );
00332     _outActor   = vtkActor::New( );
00333     _outActor->SetMapper( _outMapper );
00334     _outActor->GetProperty( )->SetColor( 0.7, 0.0, 0.9 );
00335     //_outActor->PickableOff( );
00336     _pRenderer->AddActor( _outActor );
00337 
00338     // Surface
00339     _mCubes = vtkMarchingCubes::New( );
00340     _surfMapper = vtkPolyDataMapper::New( );
00341     _surfActor = vtkActor::New( );
00342 
00343     _mCubes->SetInput( _marImageData );
00344     _mCubes->SetValue( 0, minmax[1] / 4 );
00345 
00346     vtkStripper *stripper = vtkStripper::New();
00347     stripper->SetInput( _mCubes->GetOutput( ) );
00348 
00349         _surfMapper->SetInput( stripper->GetOutput() );
00350     _surfMapper->ScalarVisibilityOff( );
00351     stripper->Delete();
00352 
00353     _surfActor->SetMapper( _surfMapper );
00354     _surfActor->PickableOff( );
00355     _surfActor->GetProperty( )->SetColor( 0.9803, 0.9215, 0.8392 );
00356     _surfActor->GetProperty( )->SetOpacity( 0.5 );
00357     _pRenderer->AddActor( _surfActor );
00358 
00359     // 1. ParallelProjectionOn should be set after AddActor (otherwise call vtkRenderer::ResetCameraClippingRange
00360     // 2. ParallelProjectionOn is *necessary* for the vtkImplicitSelectionLoop
00361     // otherwise this give a cone instead of a cylinder cutting.
00362     _pRenderer->GetActiveCamera()->ParallelProjectionOn();
00363 
00364     this->ConfigureVTK( );
00365 }
00366 
00367 //----------------------------------------------------------------------------
00368 void vtk3DSurfaceSTLWidget::ShowMARACASDataAndAxe( marInterface* mar ){
00369   marAxis* temp;
00370   vtkPolyData* allData;
00371 
00372 
00373   this->ShowMARACASData( mar );
00374 
00375   _pRenderer->SetBackground( 0.75, 0.75, 0.75 );
00376 
00377   // Axis
00378   _mar->_experiment->setAxis( 0 );
00379   temp = _mar->_experiment->getAxis( );  // ??? getActualAxis ??
00380   allData = temp->Draw( );
00381   this->SetAxis( allData );
00382 }
00383 
00384 //----------------------------------------------------------------------------
00385 void vtk3DSurfaceSTLWidget::SetInitialPoint( double* pickPoint, double* cameraPos )
00386 {
00387     gtm::TVector< double > pO( 3 ), pF( 3 ), pp( 3 ), cp( 3 );
00388     gtm::TVector< double > xc( 3 );
00389     gtm::TVector< double > x1( 3 ), n1( 3 );
00390     gtm::TVector< double > x2( 3 ), n2( 3 );
00391     gtm::TVector< double > tmp( 3 );
00392     double fac;
00393     bool success = true;
00394 
00395     if( _centralLineActor )
00396     {
00397         _pRenderer->RemoveActor( _centralLineActor );
00398         _centralLineActor->Delete( );
00399     } // fi
00400     if( _centralLineMapper ) _centralLineMapper->Delete( );
00401     if( _centralLine )       _centralLine->Delete( );
00402 
00403     _centralLine       = NULL;
00404     _centralLineMapper = NULL;
00405     _centralLineActor  = NULL;
00406 
00407     for(int i=0; i<4; i++)
00408     {
00409       if( _spheresActor[ i ] )
00410       {
00411         _pRenderer->RemoveActor( _spheresActor[ i ] );
00412         _spheresActor[ i ]->Delete( );
00413       } // fi
00414       if( _spheresMapper[ i ] ) _spheresMapper[ i ]->Delete( );
00415       if( _spheres[ i ] )       _spheres[ i ]->Delete( );
00416       _spheres[ i ] = NULL;
00417       _spheresMapper[ i ] = NULL;
00418       _spheresActor[ i ] = NULL;
00419     } //rof
00420 
00421     fac = GTM_MAX( _width, _height );
00422     fac = 2 * GTM_MAX( fac, _depth );
00423     pp( 0 ) = pickPoint[ 0 ]; pp( 1 ) = pickPoint[ 1 ]; pp( 2 ) = pickPoint[ 2 ];
00424     cp( 0 ) = cameraPos[ 0 ]; cp( 1 ) = cameraPos[ 1 ]; cp( 2 ) = cameraPos[ 2 ];
00425 
00426     if( this->FindCubePointsFromPoints(
00427       pO.GetAnsiRef( ), pF.GetAnsiRef( ),
00428       pp.GetAnsiRef( ), cp.GetAnsiRef( )
00429     ) ) {
00430 
00431         if( this->GetPointAndNormalIntersection(
00432             x1.GetAnsiRef( ), n1.GetAnsiRef( ),
00433             pO.GetAnsiRef( ), pF.GetAnsiRef( )
00434     ) ) {
00435 
00436             if( this->GetPointAndNormalIntersection(
00437           x2.GetAnsiRef( ), n2.GetAnsiRef( ),
00438           ( x1 - n1 ).GetAnsiRef( ), ( x1 - ( n1 * fac ) ).GetAnsiRef( )
00439         ) ) {
00440 
00441                 xc = ( x2 + x1 ) * 0.5;
00442                 _mar->_experiment->setStartPoint( (int)xc( 0 ), (int)xc( 1 ), (int)xc( 2 ) );
00443       
00444       for(int i=0; i<4; i++)
00445       {
00446         _spheres[ i ] = vtkSphereSource::New( );
00447         _spheresMapper[ i ] = vtkPolyDataMapper::New( );
00448         _spheresMapper[ i ]->SetInput( _spheres[ i ]->GetOutput( ) );
00449         _spheresActor[ i ] = vtkActor::New( );
00450         _spheresActor[ i ]->SetMapper( _spheresMapper[ i ] );
00451         _spheresActor[ i ]->PickableOff( );
00452         _pRenderer->AddActor( _spheresActor[ i ] );
00453       }
00454 
00455                 _spheres[ 0 ]->SetCenter( x1( 0 ), x1( 1 ), x1( 2 ) );
00456                 _spheres[ 1 ]->SetCenter( x2( 0 ), x2( 1 ), x2( 2 ) );
00457                 _spheres[ 2 ]->SetCenter( xc( 0 ), xc( 1 ), xc( 2 ) );
00458                 _spheres[ 3 ]->SetCenter( xc( 0 ), xc( 1 ), xc( 2 ) );
00459 
00460                 _spheres[ 0 ]->SetRadius( 0.5 );
00461                 _spheres[ 1 ]->SetRadius( 0.5 );
00462                 _spheres[ 2 ]->SetRadius( 0.5 );
00463                 _spheres[ 3 ]->SetRadius( ( xc - x1 ).GetNorm( ) );
00464 
00465                 _spheresActor[ 0 ]->GetProperty( )->SetColor( 1.0, 0.0, 0.0 );
00466                 _spheresActor[ 1 ]->GetProperty( )->SetColor( 0.0, 1.0, 0.0 );
00467                 _spheresActor[ 2 ]->GetProperty( )->SetColor( 0.0, 0.0, 1.0 );
00468                 _spheresActor[ 3 ]->GetProperty( )->SetColor( 1.0, 0.0, 0.0 );
00469                 _spheresActor[ 3 ]->GetProperty( )->SetOpacity( 0.3 );
00470 
00471                 vtkPoints* points = vtkPoints::New( );
00472                 points->InsertNextPoint( x1.GetAnsiRef( ) );
00473                 points->InsertNextPoint( x2.GetAnsiRef( ) );
00474 
00475                 vtkCellArray* array = vtkCellArray::New( );
00476                 array->InsertNextCell( 2 );
00477                 array->InsertCellPoint( 0 );
00478                 array->InsertCellPoint( 1 );
00479 
00480                 _centralLine = vtkPolyData::New( );
00481                 _centralLine->SetPoints( points );
00482                 _centralLine->SetLines( array );
00483       points->Delete();
00484       array->Delete();
00485 
00486                 _centralLineMapper = vtkPolyDataMapper::New( );
00487                 _centralLineMapper->SetInput( _centralLine );
00488 
00489                 _centralLineActor = vtkActor::New( );
00490                 _centralLineActor->SetMapper( _centralLineMapper );
00491                 _centralLineActor->GetProperty( )->SetColor( 1.0, 1.0, 1.0 );
00492                 _centralLineActor->PickableOff( );
00493                 _pRenderer->AddActor( _centralLineActor );
00494 
00495             } // fi
00496 
00497         } else success = false;
00498 
00499     } else success = false;
00500 
00501     // Show a message, if any.
00502     if( !success )
00503         wxMessageBox(
00504         _T("Error: Initial point can't be set.\nPlease choose another point."),
00505         _T("Error"), wxOK | wxCENTRE | wxICON_HAND, this
00506         );
00507 
00508     // Finish
00509     _pRenderWindow->Render( );
00510     InitialSphere = success;
00511 }
00512 
00513 //----------------------------------------------------------------------------
00514 void vtk3DSurfaceSTLWidget::SetInitialPoint( double* point )
00515 {
00516 }
00517 //----------------------------------------------------------------------------
00518 void vtk3DSurfaceSTLWidget::ConfigureVTK( )
00519 {
00520   // get render window
00521   _pRenderWindow =  this->GetRenderWindow(  );
00522 
00523   // connect renderer and render window and configure render window
00524   _pRenderWindow->AddRenderer( _pRenderer );
00525 
00526   // configure renderer
00527   _pRenderer->SetBackground( 0.0, 0.0, 0.0 );
00528   //_pRenderer->SetBackground( 1, 1, 0);  //FIXME
00529   _pRenderer->GetActiveCamera( )->Zoom( 1.0 );
00530   _pRenderer->GetActiveCamera( )->SetClippingRange( 1, 1000 );
00531 }
00532 
00533 
00534 //----------------------------------------------------------------------------
00535 bool vtk3DSurfaceSTLWidget::IntersectPlaneWithLine( double* p, double* x1, double* x2, double* x3, double* x4, double* x5 )
00536 {
00537     gtm::TVector< double > vx1( 3 ), vx2( 3 ), vx3( 3 );
00538     gtm::TVector< double > vx4( 3 ), vx5( 3 ), vx6( p, 3, false );
00539     gtm::TMatrix< double > mU( 4, 4 ), mD( 4, 4 );
00540     double t;
00541     bool ret;
00542 
00543     vx1 = x1;
00544     vx2 = x2;
00545     vx3 = x3;
00546     vx4 = x4;
00547     vx5 = x5;
00548     vx6 = vx5 - vx4;
00549 
00550     mD( 0, 0 ) = mU( 0, 0 ) = 1;
00551     mD( 0, 1 ) = mU( 0, 1 ) = vx1( 0 );
00552     mD( 0, 2 ) = mU( 0, 2 ) = vx1( 1 );
00553     mD( 0, 3 ) = mU( 0, 3 ) = vx1( 2 );
00554     mD( 1, 0 ) = mU( 1, 0 ) = 1;
00555     mD( 1, 1 ) = mU( 1, 1 ) = vx2( 0 );
00556     mD( 1, 2 ) = mU( 1, 2 ) = vx2( 1 );
00557     mD( 1, 3 ) = mU( 1, 3 ) = vx2( 2 );
00558     mD( 2, 0 ) = mU( 2, 0 ) = 1;
00559     mD( 2, 1 ) = mU( 2, 1 ) = vx3( 0 );
00560     mD( 2, 2 ) = mU( 2, 2 ) = vx3( 1 );
00561     mD( 2, 3 ) = mU( 2, 3 ) = vx3( 2 );
00562     mU( 3, 0 ) = 1;
00563     mU( 3, 1 ) = vx4( 0 );
00564     mU( 3, 2 ) = vx4( 1 );
00565     mU( 3, 3 ) = vx4( 2 );
00566     mD( 3, 0 ) = 0;
00567     mD( 3, 1 ) = vx6( 0 );
00568     mD( 3, 2 ) = vx6( 1 );
00569     mD( 3, 3 ) = vx6( 2 );
00570 
00571     ret = ( mD.Det( ) != 0 );
00572     if( ret ) {
00573 
00574         t = mU.Det( ) / mD.Det( );
00575         vx6 = ( ( vx4 - vx5 ) * t ) + vx4;
00576 
00577     } // fi
00578     return( ret );
00579 
00580 }
00581 
00582 //----------------------------------------------------------------------------
00583 bool vtk3DSurfaceSTLWidget::FindCubePointsFromPoints( double* pO, double* pF, double* pickPoint, double* cameraPos )
00584 {
00585     gtm::TVector< double > p1( 3 ), p2( 3 ), p3( 3 ), p4( 3 ), p5( 3 ), p6( 3 );
00586     gtm::TVector< double > c( 3 );
00587     gtm::TVector< double >* swp;
00588     gtm::TVector< double > tpO( pO, 3, false ), tpF( pF, 3, false );
00589     std::vector< gtm::TVector< double >* > points;
00590     double x1[ 3 ], x2[ 3 ], x3[ 3 ], d1, d2;
00591     int i, j;
00592 
00593     // 1st plane intersection
00594     x1[ 0 ] = 0; x1[ 1 ] = _height; x1[ 2 ] =      0;
00595     x2[ 0 ] = 0; x2[ 1 ] =       0; x2[ 2 ] =      0;
00596     x3[ 0 ] = 0; x3[ 1 ] =       0; x3[ 2 ] = _depth;
00597     if( this->IntersectPlaneWithLine( p1.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00598         points.push_back( &p1 );
00599 
00600     // 2nd plane intersection
00601     x1[ 0 ] =      0; x1[ 1 ] = _height; x1[ 2 ] = _depth;
00602     x2[ 0 ] =      0; x2[ 1 ] =       0; x2[ 2 ] = _depth;
00603     x3[ 0 ] = _width; x3[ 1 ] =       0; x3[ 2 ] = _depth;
00604     if( this->IntersectPlaneWithLine( p2.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00605         points.push_back( &p2 );
00606 
00607     // 3rd plane intersection
00608     x1[ 0 ] =      0; x1[ 1 ] = 0; x1[ 2 ] = _depth;
00609     x2[ 0 ] =      0; x2[ 1 ] = 0; x2[ 2 ] =      0;
00610     x3[ 0 ] = _width; x3[ 1 ] = 0; x3[ 2 ] =      0;
00611     if( this->IntersectPlaneWithLine( p3.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00612         points.push_back( &p3 );
00613 
00614     // 4th plane intersection
00615     x1[ 0 ] = _width; x1[ 1 ] = _height; x1[ 2 ] = _depth;
00616     x2[ 0 ] = _width; x2[ 1 ] =       0; x2[ 2 ] = _depth;
00617     x3[ 0 ] = _width; x3[ 1 ] =       0; x3[ 2 ] =      0;
00618     if( this->IntersectPlaneWithLine( p4.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00619         points.push_back( &p4 );
00620 
00621     // 5th plane intersection
00622     x1[ 0 ] = _width; x1[ 1 ] =       0; x1[ 2 ] = 0;
00623     x2[ 0 ] =      0; x2[ 1 ] =       0; x2[ 2 ] = 0;
00624     x3[ 0 ] =      0; x3[ 1 ] = _height; x3[ 2 ] = 0;
00625     if( this->IntersectPlaneWithLine( p5.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00626         points.push_back( &p5 );
00627 
00628     // 6th plane intersection
00629     x1[ 0 ] =      0; x1[ 1 ] = _height; x1[ 2 ] =      0;
00630     x2[ 0 ] =      0; x2[ 1 ] = _height; x2[ 2 ] = _depth;
00631     x3[ 0 ] = _width; x3[ 1 ] = _height; x3[ 2 ] = _depth;
00632     if( this->IntersectPlaneWithLine( p6.GetAnsiRef( ), x1, x2, x3, cameraPos, pickPoint ) )
00633         points.push_back( &p6 );
00634 
00635     if( points.size( ) >= 2 ) { // Did I find at least 2 points?
00636 
00637         c( 0 ) = ( double )_width  / 2.0;
00638         c( 1 ) = ( double )_height / 2.0;
00639         c( 2 ) = ( double )_depth  / 2.0;
00640 
00641         // Sort with bubble sort. Only 30 iterations!
00642         for( i = 0; i < points.size( ); i++ ) {
00643             for( j = 0; j < points.size( ) - 1; j++ ) {
00644 
00645                 d1 = ( c - *points[ j ] ).GetNorm( );
00646                 d2 = ( c - *points[ j + 1 ] ).GetNorm( );
00647                 if( d2 < d1 ) {
00648 
00649                     swp = points[ j ];
00650                     points[ j ] = points[ j + 1 ];
00651                     points[ j + 1 ] = swp;
00652 
00653                 } // fi
00654 
00655     } // rof
00656 
00657         } // rof
00658 
00659         // Order the two points according to distance to camera.
00660         c = cameraPos;
00661         d1 = ( c - *points[ 0 ] ).GetNorm( );
00662         d2 = ( c - *points[ 1 ] ).GetNorm( );
00663         tpO = ( d1 < d2 )? *points[ 0 ]: *points[ 1 ];
00664         tpF = ( d1 > d2 )? *points[ 0 ]: *points[ 1 ];
00665         return( true );
00666 
00667     } else return( false );
00668 
00669 }
00670 
00671 //----------------------------------------------------------------------------
00672 bool vtk3DSurfaceSTLWidget::GetPointAndNormalIntersection( double* p, double* n, double* pO, double* pF )
00673 {
00674     gtm::TVector< double > n1( 3 ), n2( 3 ), n3( 3 );
00675     int subId, cellId, returnVal;
00676     double t, pcoords[ 3 ], x[ 3 ];
00677     double fpO[ 3 ], fpF[ 3 ];
00678     double p1[ 3 ], p2[ 3 ], p3[ 3 ];
00679     vtkPolyData* data = _mCubes->GetOutput( );
00680     vtkCellLocator* locator = vtkCellLocator::New( );
00681 
00682     locator->SetDataSet( data );
00683     locator->Initialize( );
00684     locator->Update( );
00685 
00686     fpO[ 0 ] = pO[ 0 ]; fpO[ 1 ] = pO[ 1 ]; fpO[ 2 ] = pO[ 2 ];
00687     fpF[ 0 ] = pF[ 0 ]; fpF[ 1 ] = pF[ 1 ]; fpF[ 2 ] = pF[ 2 ];
00688     returnVal = locator->IntersectWithLine( fpO, fpF, 0.1, t, x, pcoords, subId, cellId );
00689     locator->Delete( );
00690 
00691     if( returnVal )
00692     {
00693         vtkCell* cell = data->GetCell( cellId );
00694         vtkPoints* points = cell->GetPoints( );
00695 
00696         data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 0 ), n1.GetAnsiRef( ) );
00697         data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 1 ), n2.GetAnsiRef( ) );
00698         data->GetPointData( )->GetNormals( )->GetTuple( cell->GetPointIds( )->GetId( 2 ), n3.GetAnsiRef( ) );
00699    
00700         n1 += n2 + n3;
00701         n1 *= ( 1.0 / 3.0 );
00702         n1.Normalize( );
00703         n[ 0 ] = n1( 0 ); n[ 1 ] = n1( 1 ); n[ 2 ] = n1( 2 );
00704 
00705         points->GetPoint( 0, p1 );
00706         points->GetPoint( 1, p2 );
00707         points->GetPoint( 2, p3 );
00708         this->IntersectPlaneWithLine( p, p1, p2, p3, pO, pF );
00709         return( true );
00710     } else return( false );
00711 
00712 }
00713 //----------------------------------------------------------------------------
00719 vtkPolyData* vtk3DSurfaceSTLWidget::ConvertMarAxisToPolyData()
00720 {
00721   double p1[marAxis::INDX_count];
00722   //retrieve the actual axis
00723   marAxis* ax = _mar->_experiment->getAxis();
00724   //Number of axis points
00725   int numPoints = ax->getNumberOfControlPoints();
00726 
00727   vtkPolyData *axis = vtkPolyData::New();
00728   vtkPoints *points = vtkPoints::New();
00729   vtkFloatArray *scalars = vtkFloatArray::New();
00730   scalars->SetNumberOfComponents (2);
00731   //Field are : 1. radius (=INDX_RAYON) , 2. average (=INDX_SIGNALVALUE)
00732 
00733   double tmp1,tmp2;
00734   for(int i=0; i<numPoints; i++){
00735     ax->getControlPoint(i, p1, p1+3);
00736     points->InsertPoint(i, p1);
00737         tmp1 = p1[marAxis::INDX_RAYON];
00738 //      tmp2 = p1[marAxis::INDX_SIGNALVALUE];
00739         tmp2 = (double)ax->getSignal(i);
00740     scalars->InsertTuple2(i,tmp1, tmp2);
00741 
00742   }
00743 
00744   // We now assign the pieces to the vtkPolyData.
00745   axis->SetPoints(points);
00746   points->Delete();
00747   axis->GetPointData()->SetScalars(scalars);
00748   scalars->Delete();
00749  
00750   return axis;
00751 }
00752 //----------------------------------------------------------------------------
00753 void vtk3DSurfaceSTLWidget::ConstructVessel( )
00754 {
00755   vtkPolyData *axis = this->ConvertMarAxisToPolyData( );
00756 
00757   //retrieve the vtk image data
00758 
00759   if( !_psc) this->_psc = vtkImagePolyDataSeedConnectivity::New();
00760   this->_psc->SetInput( _marImageData );
00761   this->_psc->SetAxis( axis );
00762   this->_psc->Update();
00763   axis->Delete();
00764 
00765 /*  vtkStripper *strip = vtkStripper::New();
00766   strip->SetInput( this->_psc->GetOutput() );  //GetOutput() -> inner mold
00767   strip->Update(); //Important before a ShallowCopy !!!
00768   
00769   if( !_stlInternalVessel) _stlInternalVessel = vtkPolyData::New();
00770   _stlInternalVessel->ShallowCopy( strip->GetOutput() );
00771   strip->Delete();*/
00772   _stlInternalVessel = this->_psc->GetOutput();
00773 
00774 /*  if( !_stlExternalVessel) _stlExternalVessel = vtkPolyData::New();
00775   _stlExternalVessel->ShallowCopy( this->_psc->GetOuterMold() );
00776   //this->_psc->GetOuterMold()->Delete();*/
00777   _stlExternalVessel = this->_psc->GetOuterMold();
00778 
00779   vtkPolyDataMapper *dsm1 = vtkPolyDataMapper ::New();
00780   dsm1->SetInput ( _stlInternalVessel ); //fasten stuff
00781   dsm1->ScalarVisibilityOff();
00782 
00783   _actorVessel = vtkActor::New();
00784   _actorVessel->SetMapper (dsm1);
00785 
00786   //improve visibility:
00787   _actorVessel->GetProperty()->SetColor (1,0,0);
00788 
00789   vtkPolyDataMapper *dsm2 = vtkPolyDataMapper ::New();
00790   dsm2->SetInput ( _stlExternalVessel );
00791   dsm2->ScalarVisibilityOff();
00792 
00793   _actorExternalVessel = vtkActor::New();
00794   _actorExternalVessel->SetMapper (dsm2);
00795 
00796   //improve visibility:
00797   _actorExternalVessel->GetProperty()->SetRepresentationToWireframe();
00798 
00799   _pRenderer->AddActor( _actorVessel );
00800   _pRenderer->AddActor( _actorExternalVessel );
00801   _pRenderWindow->Render( );
00802 
00803   dsm1->Delete();
00804   dsm2->Delete();
00805 }
00806 //----------------------------------------------------------------------------
00807 void vtk3DSurfaceSTLWidget::SetSTLThresholdRatio(double ratio)
00808 {
00809   this->_psc->SetThresholdRatio( (double)(ratio/100) );
00810   _pRenderWindow->Render( );
00811 }
00812 //----------------------------------------------------------------------------
00813 float vtk3DSurfaceSTLWidget::GetSTLThreshold()
00814 {
00815   return  100*this->_psc->GetThresholdRatio( );
00816 }
00817 //----------------------------------------------------------------------------

Generated on 18 Mar 2010 for creaMaracasVisu_lib by  doxygen 1.6.1