00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkAffineInteractor.h"
00020 #include "mitkInteractionConst.h"
00021 #include "mitkDataNode.h"
00022 #include "mitkGeometry3D.h"
00023 #include "mitkRotationOperation.h"
00024 #include "mitkPointOperation.h"
00025 #include "mitkPositionEvent.h"
00026 #include "mitkStateEvent.h"
00027 #include "mitkOperationEvent.h"
00028 #include "mitkUndoController.h"
00029 #include "mitkDisplayPositionEvent.h"
00030 #include "vtkTransform.h"
00031 #include "mitkVtkPropRenderer.h"
00032 #include "mitkProperties.h"
00033 #include <itkBoundingBox.h>
00034 #include <itkFixedArray.h>
00035 #include "mitkAction.h"
00036
00037
00038 #include "mitkRenderingManager.h"
00039
00040 #include <math.h>
00041
00042 #include <vtkWorldPointPicker.h>
00043 #include <vtkPicker.h>
00044 #include "mitkGlobalInteraction.h"
00045 #include "mitkFocusManager.h"
00046 #include "mitkEventMapper.h"
00047 #include "vtkProp3D.h"
00048 #include "mitkVtkInteractorCameraController.h"
00049 #include <vtkInteractorObserver.h>
00050 #include "vtkRenderer.h"
00051 #include "vtkCamera.h"
00052 #include <vtkInteractorObserver.h>
00053
00054 #include <iostream>
00055
00056 mitk::AffineInteractor::AffineInteractor(const char * type, DataNode* dataNode)
00057 : Interactor(type, dataNode)
00058 {
00059 }
00060
00061 bool mitk::AffineInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
00062 {
00063 bool ok = false;
00064
00065 TimeSlicedGeometry* inputtimegeometry = GetData()->GetTimeSlicedGeometry();
00066 if (inputtimegeometry == NULL)
00067 return false;
00068
00069 Geometry3D* geometry = inputtimegeometry->GetGeometry3D(m_TimeStep);
00070
00071 mitk::DisplayPositionEvent const *event = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
00072 switch (action->GetActionId())
00073 {
00074 case AcCHECKELEMENT:
00075 {
00076 mitk::Point3D worldPoint = event->GetWorldPosition();
00077
00078 mitk::BoolProperty::Pointer selected;
00079 mitk::ColorProperty::Pointer color;
00080 mitk::StateEvent* newStateEvent = NULL;
00081
00082 selected = dynamic_cast<mitk::BoolProperty*>(m_DataNode->GetProperty("selected"));
00083
00084 if ( selected.IsNull() ) {
00085 selected = mitk::BoolProperty::New();
00086 m_DataNode->GetPropertyList()->SetProperty("selected", selected);
00087 }
00088
00089 color = dynamic_cast<mitk::ColorProperty*>(m_DataNode->GetProperty("color"));
00090
00091 if ( color.IsNull() ) {
00092 color = mitk::ColorProperty::New();
00093 m_DataNode->GetPropertyList()->SetProperty("color", color);
00094 }
00095
00096 if (this->CheckSelected(worldPoint, m_TimeStep))
00097 {
00098 newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
00099 selected->SetValue(true);
00100 color->SetColor(1.0, 1.0, 0.0);
00101 }
00102 else
00103 {
00104 newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
00105 selected = mitk::BoolProperty::New(false);
00106 color->SetColor(0.0, 0.0, 1.0);
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 }
00118
00119
00120 this->HandleEvent( newStateEvent );
00121 ok = true;
00122 break;
00123 }
00124 case AcADD:
00125 {
00126 mitk::Point3D worldPoint = event->GetWorldPosition();
00127 mitk::StateEvent* newStateEvent = NULL;
00128 if (this->CheckSelected(worldPoint, m_TimeStep))
00129 {
00130 newStateEvent = new mitk::StateEvent(EIDYES, event);
00131 m_DataNode->GetPropertyList()->SetProperty("selected", mitk::BoolProperty::New(true));
00132 }
00133 else
00134 {
00135 newStateEvent = new mitk::StateEvent(EIDNO, event);
00136 }
00137
00138 this->HandleEvent( newStateEvent );
00139 ok = true;
00140 break;
00141 }
00142 case AcTRANSLATESTART:
00143 case AcROTATESTART:
00144 case AcSCALESTART:
00145 {
00146 m_LastMousePosition = event->GetWorldPosition();
00147 ok = true;
00148 break;
00149 }
00150 case AcTRANSLATE:
00151 {
00152 mitk::Point3D newPosition;
00153 newPosition = event->GetWorldPosition();
00154 newPosition -= m_LastMousePosition.GetVectorFromOrigin();
00155 m_LastMousePosition = event->GetWorldPosition();
00156
00157
00158 mitk::PointOperation* doOp = new mitk::PointOperation(OpMOVE, newPosition, 0);
00159 if (m_UndoEnabled)
00160 {
00161 mitk::Point3D oldPosition=geometry->GetCornerPoint(0);
00162
00163 PointOperation* undoOp = new mitk::PointOperation(OpMOVE, oldPosition, 0);
00164 OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
00165 m_UndoController->SetOperationEvent(operationEvent);
00166 }
00167
00168 geometry->ExecuteOperation(doOp);
00169 ok = true;
00170 break;
00171 }
00172 case AcTRANSLATEEND:
00173 {
00174 m_UndoController->SetOperationEvent(new UndoStackItem("Move object"));
00175 break;
00176 }
00177 case AcROTATE:
00178 {
00179 mitk::Point3D p = event->GetWorldPosition();
00180
00181 mitk::Vector3D newPosition = p.GetVectorFromOrigin();
00182
00183 mitk::Point3D dataPosition = geometry->GetCenter();
00184
00185 newPosition = newPosition - dataPosition.GetVectorFromOrigin();
00186
00187 mitk::Vector3D startPosition = m_LastMousePosition.GetVectorFromOrigin() - dataPosition.GetVectorFromOrigin();
00188
00189
00190 mitk::Vector3D rotationaxis;
00191 rotationaxis[0] = startPosition[1] * newPosition[2] - startPosition[2] * newPosition[1];
00192 rotationaxis[1] = startPosition[2] * newPosition[0] - startPosition[0] * newPosition[2];
00193 rotationaxis[2] = startPosition[0] * newPosition[1] - startPosition[1] * newPosition[0];
00194
00195
00196 mitk::ScalarType angle = atan2((mitk::ScalarType)rotationaxis.GetNorm(), (mitk::ScalarType) (newPosition * startPosition)) * (180/vnl_math::pi);
00197 m_LastMousePosition = p;
00198
00199
00200 mitk::RotationOperation* doOp = new mitk::RotationOperation(OpROTATE, dataPosition, rotationaxis, angle);
00201
00202 if (m_UndoEnabled)
00203 {
00204 RotationOperation* undoOp = new mitk::RotationOperation(OpROTATE, dataPosition, rotationaxis, -angle);
00205 OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
00206 m_UndoController->SetOperationEvent(operationEvent);
00207 }
00208
00209 geometry->ExecuteOperation(doOp);
00210 ok = true;
00211 break;
00212 }
00213 case AcROTATEEND:
00214 {
00215 m_UndoController->SetOperationEvent(new UndoStackItem("Rotate object"));
00216 break;
00217 }
00218 case AcSCALE:
00219 {
00220 mitk::Point3D p = event->GetWorldPosition();
00221
00222 mitk::Vector3D v = p - m_LastMousePosition;
00223
00224 mitk::Point3D newScale;
00225 newScale[0] = (geometry->GetAxisVector(0) * v) / geometry->GetExtentInMM(0);
00226 newScale[1] = (geometry->GetAxisVector(1) * v) / geometry->GetExtentInMM(1);
00227 newScale[2] = (geometry->GetAxisVector(2) * v) / geometry->GetExtentInMM(2);
00228
00229
00230 Vector3D start;
00231 Vector3D end;
00232 mitk::ScalarType convert[3];
00233 itk2vtk(m_LastMousePosition, convert);
00234 geometry->GetVtkTransform()->GetInverse()->TransformPoint(convert, convert);
00235 start[0] = fabs(convert[0]); start[1] = fabs(convert[1]); start[2] = fabs(convert[2]);
00236 itk2vtk(p, convert);
00237 geometry->GetVtkTransform()->GetInverse()->TransformPoint(convert, convert);
00238 end[0] = fabs(convert[0]); end[1] = fabs(convert[1]); end[2] = fabs(convert[2]);
00239
00240
00241 Vector3D vLocal = start - end;
00242 newScale[0] = (vLocal[0] > 0.0) ? -fabs(newScale[0]) : +fabs(newScale[0]);
00243 newScale[1] = (vLocal[1] > 0.0) ? -fabs(newScale[1]) : +fabs(newScale[1]);
00244 newScale[2] = (vLocal[2] > 0.0) ? -fabs(newScale[2]) : +fabs(newScale[2]);
00245
00246 m_LastMousePosition = p;
00247
00248
00249 PointOperation* doOp = new mitk::PointOperation(OpSCALE, newScale, 0);
00250 if (m_UndoEnabled)
00251 {
00252 mitk::Point3D oldScaleData;
00253 oldScaleData[0] = -newScale[0];
00254 oldScaleData[1] = -newScale[1];
00255 oldScaleData[2] = -newScale[2];
00256
00257 PointOperation* undoOp = new mitk::PointOperation(OpSCALE, oldScaleData, 0);
00258 OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
00259 m_UndoController->SetOperationEvent(operationEvent);
00260 }
00261
00262 geometry->ExecuteOperation(doOp);
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 ok = true;
00273 break;
00274 }
00275 case AcSCALEEND:
00276 {
00277 m_UndoController->SetOperationEvent(new UndoStackItem("Scale object"));
00278 break;
00279 }
00280 default:
00281 ok = Superclass::ExecuteAction(action, stateEvent);
00282 }
00283 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00284 return ok;
00285 }
00286
00287 bool mitk::AffineInteractor::CheckSelected(const mitk::Point3D& worldPoint, int timestep )
00288 {
00289 bool selected = false;
00290 if (m_DataNode->GetBoolProperty("selected", selected) == false)
00291 m_DataNode->SetProperty("selected", mitk::BoolProperty::New(false));
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 {
00303 const Geometry3D* geometry = GetData()->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( timestep );
00304 selected = geometry->IsInside(worldPoint);
00305 }
00306 return selected;
00307 }
00308
00309 bool mitk::AffineInteractor::ConvertDisplayEventToWorldPosition(mitk::DisplayPositionEvent const* displayEvent, mitk::Point3D& worldPoint)
00310 {
00311 mitk::Point2D displayPoint = displayEvent->GetDisplayPosition();
00312
00313 double focalPoint[4], position[4];
00314 double z;
00315
00316 FocusManager::FocusElement* fe = mitk::GlobalInteraction::GetInstance()->GetFocus();
00317 mitk::VtkPropRenderer* glRenderer = dynamic_cast<mitk::VtkPropRenderer*>( fe );
00318 if ( glRenderer == NULL )
00319 {
00320 return false;
00321 }
00322
00323 vtkRenderer *renderer = glRenderer->GetVtkRenderer();
00324 vtkCamera *camera = renderer->GetActiveCamera();
00325 if ( !camera )
00326 {
00327 return false;
00328 }
00329
00330 camera->GetFocalPoint(focalPoint);
00331
00332 renderer->SetWorldPoint(focalPoint[0], focalPoint[1], focalPoint[2], 1.0);
00333 renderer->WorldToDisplay();
00334 renderer->GetDisplayPoint(focalPoint);
00335 z = focalPoint[2];
00336
00337 renderer->SetDisplayPoint(displayPoint[0], displayPoint[1], z);
00338 renderer->DisplayToWorld();
00339 renderer->GetWorldPoint(position);
00340 if (position[3])
00341 {
00342 worldPoint[0] = position[0] / position[3];
00343 worldPoint[1] = position[1] / position[3];
00344 worldPoint[2] = position[2] / position[3];
00345 position[3] = 1.0;
00346 }
00347 else
00348 {
00349 worldPoint[0] = position[0];
00350 worldPoint[1] = position[1];
00351 worldPoint[2] = position[2];
00352 }
00353 return true;
00354 }
00355
00356 float mitk::AffineInteractor::CanHandleEvent( StateEvent const* stateEvent ) const
00357 {
00358 float jd = 0.0f;
00359
00360 if ( stateEvent->GetEvent()->GetSender()->GetMapperID() == mitk::BaseRenderer::Standard3D )
00361 {
00362 MITK_DEBUG << "Sorry, mitkAffineInteractor does not support interaction in a 3D view at the moment.";
00363 return jd;
00364 }
00365
00366 return Superclass::CanHandleEvent( stateEvent );
00367 }