00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkSurfaceDeformationInteractor3D.h"
00020 #include "mitkPointOperation.h"
00021 #include "mitkDisplayPositionEvent.h"
00022 #include "mitkWheelEvent.h"
00023 #include "mitkStatusBar.h"
00024 #include "mitkDataNode.h"
00025 #include "mitkInteractionConst.h"
00026 #include "mitkAction.h"
00027 #include "mitkStateEvent.h"
00028 #include "mitkOperationEvent.h"
00029 #include "mitkUndoController.h"
00030 #include "mitkStateMachineFactory.h"
00031 #include "mitkStateTransitionOperation.h"
00032 #include "mitkBaseRenderer.h"
00033 #include "mitkRenderingManager.h"
00034 #include "mitkSurface.h"
00035
00036
00037 #include <vtkRenderWindow.h>
00038 #include <vtkRenderWindowInteractor.h>
00039 #include <vtkInteractorStyle.h>
00040 #include <vtkPolyData.h>
00041 #include <vtkPointData.h>
00042 #include <vtkDataArray.h>
00043 #include <vtkPointData.h>
00044 #include <vtkDataArray.h>
00045
00046
00047
00048
00049 mitk::SurfaceDeformationInteractor3D
00050 ::SurfaceDeformationInteractor3D(const char * type, DataNode* dataNode, int )
00051 : Interactor( type, dataNode ),
00052 m_Precision( 6.5 ),
00053 m_PickedSurfaceNode( NULL ),
00054 m_PickedSurface( NULL ),
00055 m_GaussSigma( 30.0 )
00056 {
00057 m_OriginalPolyData = vtkPolyData::New();
00058
00059
00060 m_ObjectNormal[0] = 0.0;
00061 m_ObjectNormal[1] = 0.0;
00062 m_ObjectNormal[2] = 1.0;
00063 }
00064
00065 mitk::SurfaceDeformationInteractor3D::~SurfaceDeformationInteractor3D()
00066 {
00067 m_OriginalPolyData->Delete();
00068 }
00069
00070 void mitk::SurfaceDeformationInteractor3D::SetPrecision( mitk::ScalarType precision )
00071 {
00072 m_Precision = precision;
00073 }
00074
00075
00076 float mitk::SurfaceDeformationInteractor3D
00077 ::CanHandleEvent(StateEvent const* stateEvent) const
00078 {
00079 float returnValue = 0.5;
00080
00081
00082
00083
00084 mitk::DisplayPositionEvent const *disPosEvent =
00085 dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
00086
00087
00088 if (disPosEvent == NULL)
00089 {
00090
00091 if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
00092 {
00093 return 0.5;
00094 }
00095 else
00096 {
00097 return 0.0;
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
00109 {
00110 returnValue = 0.5;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 return returnValue;
00134 }
00135
00136
00137 bool mitk::SurfaceDeformationInteractor3D
00138 ::ExecuteAction( Action *action, mitk::StateEvent const *stateEvent )
00139 {
00140 bool ok = false;
00141
00142
00143 mitk::BaseData *data = m_DataNode->GetData();
00144 if ( data == NULL )
00145 {
00146 MITK_ERROR << "No data object present!";
00147 return ok;
00148 }
00149
00150
00151 const mitk::Event *event = stateEvent->GetEvent();
00152 mitk::BaseRenderer *renderer = NULL;
00153 vtkRenderWindow *renderWindow = NULL;
00154 vtkRenderWindowInteractor *renderWindowInteractor = NULL;
00155
00156 if ( event != NULL )
00157 {
00158 renderer = event->GetSender();
00159 if ( renderer != NULL )
00160 {
00161 renderWindow = renderer->GetRenderWindow();
00162 if ( renderWindow != NULL )
00163 {
00164 renderWindowInteractor = renderWindow->GetInteractor();
00165 }
00166 }
00167 }
00168
00169
00170 const mitk::DisplayPositionEvent *dpe =
00171 dynamic_cast< const mitk::DisplayPositionEvent * >( stateEvent->GetEvent() );
00172 if ( dpe != NULL )
00173 {
00174 m_PickedSurfaceNode = dpe->GetPickedObjectNode();
00175 m_CurrentPickedPoint = dpe->GetWorldPosition();
00176 m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition();
00177 }
00178
00179
00180
00181 int timeStep = 0;
00182 mitk::ScalarType timeInMS = 0.0;
00183 if ( renderer != NULL )
00184 {
00185 timeStep = renderer->GetTimeStep( data );
00186 timeInMS = renderer->GetTime();
00187 }
00188
00189
00190 m_Surface = dynamic_cast< Surface * >( data );
00191 if ( m_Surface != NULL )
00192 {
00193 m_PolyData = m_Surface->GetVtkPolyData( timeStep );
00194 }
00195 else
00196 {
00197 m_PolyData = NULL;
00198 }
00199
00200
00201 vtkPointData *pointData = m_PolyData->GetPointData();
00202 if ( pointData != NULL )
00203 {
00204 vtkDataArray *normal = m_PolyData->GetPointData()->GetVectors( "planeNormal" );
00205 if ( normal != NULL )
00206 {
00207 m_ObjectNormal[0] = normal->GetComponent( 0, 0 );
00208 m_ObjectNormal[1] = normal->GetComponent( 0, 1 );
00209 m_ObjectNormal[2] = normal->GetComponent( 0, 2 );
00210 }
00211 }
00212
00213
00214 m_Geometry = data->GetGeometry( timeStep );
00215
00216
00217
00218
00219 data->Expand( timeStep+1 );
00220
00221
00222 switch (action->GetActionId())
00223 {
00224 case AcDONOTHING:
00225 ok = true;
00226 break;
00227
00228
00229 case AcCHECKOBJECT:
00230 {
00231
00232 m_PickedSurface = NULL;
00233 m_PickedPolyData = NULL;
00234
00235 if ( m_PickedSurfaceNode != NULL )
00236 {
00237 m_PickedSurface = dynamic_cast< mitk::Surface * >( m_PickedSurfaceNode->GetData() );
00238 if ( m_PickedSurface != NULL )
00239 {
00240 m_PickedPolyData = m_PickedSurface->GetVtkPolyData( timeStep );
00241 }
00242 }
00243
00244 mitk::StateEvent *newStateEvent;
00245 if ( (m_PickedSurfaceNode == m_DataNode) && (m_PickedSurface != NULL) )
00246 {
00247
00248 newStateEvent = new mitk::StateEvent( EIDYES );
00249
00250
00251 if ( renderWindowInteractor != NULL )
00252 {
00253 renderWindowInteractor->Disable();
00254 }
00255 }
00256 else
00257 {
00258
00259 newStateEvent = new mitk::StateEvent( EIDNO );
00260
00261
00262 if ( renderWindowInteractor != NULL )
00263 {
00264 renderWindowInteractor->Enable();
00265 }
00266 }
00267
00268 this->HandleEvent( newStateEvent );
00269
00270
00271 m_SurfaceColorizationCenter = m_CurrentPickedPoint;
00272
00273 ok = true;
00274 break;
00275 }
00276
00277 case AcDESELECTOBJECT:
00278 {
00279
00280 m_DataNode->SetColor( 1.0, 1.0, 1.0 );
00281 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00282
00283
00284 this->ColorizeSurface( m_PolyData,
00285 m_SurfaceColorizationCenter, COLORIZATION_CONSTANT, -1.0 );
00286
00287 ok = true;
00288 break;
00289 }
00290
00291 case AcSELECTPICKEDOBJECT:
00292 {
00293
00294 m_DataNode->SetColor( 1.0, 0.0, 0.0 );
00295 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00296
00297
00298 this->ColorizeSurface( m_PolyData,
00299 m_SurfaceColorizationCenter, COLORIZATION_GAUSS );
00300
00301 ok = true;
00302 break;
00303 }
00304
00305 case AcINITMOVE:
00306 {
00307
00308 m_InitialPickedPoint = m_CurrentPickedPoint;
00309 m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint;
00310
00311 if ( renderWindowInteractor != NULL )
00312 {
00313 vtkInteractorObserver::ComputeDisplayToWorld(
00314 renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(),
00315 m_InitialPickedDisplayPoint[0],
00316 m_InitialPickedDisplayPoint[1],
00317 0.0,
00318 m_InitialPickedPointWorld );
00319 }
00320
00321
00322
00323 m_OriginalPolyData->DeepCopy( m_PolyData );
00324
00325 ok = true;
00326 break;
00327 }
00328
00329 case AcMOVE:
00330 {
00331 if ( renderWindowInteractor != NULL )
00332 {
00333 vtkInteractorObserver::ComputeDisplayToWorld(
00334 renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(),
00335 m_CurrentPickedDisplayPoint[0],
00336 m_CurrentPickedDisplayPoint[1],
00337 0.0,
00338 m_CurrentPickedPointWorld );
00339 }
00340
00341
00342
00343 mitk::Vector3D interactionMove;
00344 interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0];
00345 interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1];
00346 interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2];
00347
00348
00349 data->UpdateOutputInformation();
00350 mitk::Point3D origin; origin.Fill( 0.0 );
00351 m_Geometry->WorldToIndex( origin, interactionMove, interactionMove );
00352
00353
00354
00355 mitk::Point3D pickedPoint;
00356 m_Geometry->WorldToIndex( m_InitialPickedPoint, pickedPoint );
00357 mitk::Vector3D v1 = pickedPoint.GetVectorFromOrigin();
00358
00359 mitk::Vector3D v2 = m_ObjectNormal * (interactionMove * m_ObjectNormal);
00360
00361
00362 vtkPoints *originalPoints = m_OriginalPolyData->GetPoints();
00363 vtkPoints *deformedPoints = m_PolyData->GetPoints();
00364
00365 double denom = m_GaussSigma * m_GaussSigma * 2;
00366 double point[3];
00367 for ( unsigned int i = 0; i < deformedPoints->GetNumberOfPoints(); ++i )
00368 {
00369
00370 vtkFloatingPointType *originalPoint = originalPoints->GetPoint( i );
00371 mitk::Vector3D v0;
00372 v0[0] = originalPoint[0];
00373 v0[1] = originalPoint[1];
00374 v0[2] = originalPoint[2];
00375
00376
00377
00378 double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm();
00379
00380 mitk::Vector3D t = v2 * exp( - d * d / denom );
00381
00382 point[0] = originalPoint[0] + t[0];
00383 point[1] = originalPoint[1] + t[1];
00384 point[2] = originalPoint[2] + t[2];
00385 deformedPoints->SetPoint( i, point );
00386 }
00387
00388
00389
00390 m_SurfaceColorizationCenter = m_InitialPickedPoint;
00391
00392 m_PolyData->Modified();
00393 m_Surface->Modified();
00394
00395 mitk::RenderingManager::GetInstance()->RequestUpdateAll(
00396 mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS );
00397 ok = false;
00398 break;
00399 }
00400
00401 case AcMODIFY:
00402 {
00403
00404 const mitk::WheelEvent *we =
00405 dynamic_cast< const mitk::WheelEvent * >( stateEvent->GetEvent() );
00406 if ( we == NULL )
00407 {
00408 ok = true;
00409 break;
00410 }
00411
00412 m_GaussSigma += (double) (we->GetDelta()) / 20;;
00413 if ( m_GaussSigma < 10.0 )
00414 {
00415 m_GaussSigma = 10.0;
00416 }
00417 else if ( m_GaussSigma > 128.0 )
00418 {
00419 m_GaussSigma = 128.0;
00420 }
00421
00422
00423 this->ColorizeSurface( m_PolyData,
00424 m_SurfaceColorizationCenter, COLORIZATION_GAUSS );
00425
00426
00427 mitk::RenderingManager::GetInstance()->RequestUpdateAll(
00428 mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS );
00429 ok = true;
00430 break;
00431 }
00432
00433
00434 default:
00435 return Superclass::ExecuteAction( action, stateEvent );
00436 }
00437
00438 return ok;
00439 }
00440
00441
00442 bool mitk::SurfaceDeformationInteractor3D::ColorizeSurface( vtkPolyData *polyData,
00443 const Point3D &pickedPoint, int mode, double scalar )
00444 {
00445 if ( polyData == NULL )
00446 {
00447 return false;
00448 }
00449
00450 vtkPoints *points = polyData->GetPoints();
00451 vtkPointData *pointData = polyData->GetPointData();
00452 if ( pointData == NULL )
00453 {
00454 return false;
00455 }
00456
00457 vtkDataArray *scalars = pointData->GetScalars();
00458 if ( scalars == NULL )
00459 {
00460 return false;
00461 }
00462
00463 if ( mode == COLORIZATION_GAUSS )
00464 {
00465
00466 mitk::Point3D localPickedPoint;
00467 m_Geometry->WorldToIndex( pickedPoint, localPickedPoint );
00468 mitk::Vector3D v1 = localPickedPoint.GetVectorFromOrigin();
00469
00470 double denom = m_GaussSigma * m_GaussSigma * 2;
00471 for ( unsigned int i = 0; i < points->GetNumberOfPoints(); ++i )
00472 {
00473
00474 vtkFloatingPointType *point = points->GetPoint( i );
00475 mitk::Vector3D v0;
00476 v0[0] = point[0];
00477 v0[1] = point[1];
00478 v0[2] = point[2];
00479
00480
00481 double d = itk::CrossProduct( m_ObjectNormal, (v1 - v0) ).GetNorm();
00482 double t = exp( - d * d / denom );
00483
00484 scalars->SetComponent( i, 0, t );
00485 }
00486 }
00487 else if ( mode == COLORIZATION_CONSTANT )
00488 {
00489 for ( unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i )
00490 {
00491 scalars->SetComponent( i, 0, scalar );
00492 }
00493 }
00494
00495 polyData->Modified();
00496 pointData->Update();
00497
00498 return true;
00499 }