00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkConnectPointsInteractor.h"
00020 #include <mitkLineOperation.h>
00021 #include <mitkPositionEvent.h>
00022 #include <mitkState.h>
00023 #include <mitkStateEvent.h>
00024 #include <mitkUndoController.h>
00025 #include <mitkMesh.h>
00026 #include <mitkDataNode.h>
00027 #include <mitkInteractionConst.h>
00028 #include <mitkAction.h>
00029 #include <vtkLinearTransform.h>
00030
00031
00032
00033 const int PRECISION = 5;
00034
00035 mitk::ConnectPointsInteractor::ConnectPointsInteractor(const char * type, DataNode* dataNode, int n)
00036 :Interactor(type, dataNode), m_N(n), m_CurrentCellId(0), m_Precision(PRECISION)
00037 {
00038 m_LastPoint.Fill(0);
00039 m_SumVec.Fill(0);
00040 }
00041
00042 mitk::ConnectPointsInteractor::~ConnectPointsInteractor()
00043 {
00044 }
00045
00046 void mitk::ConnectPointsInteractor::SetPrecision(unsigned int precision)
00047 {
00048 m_Precision = precision;
00049 }
00050
00051
00052
00053 float mitk::ConnectPointsInteractor::CanHandleEvent(StateEvent const* stateEvent) const
00054 {
00055 float returnValue = 0;
00056
00057 mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
00058
00059 if (posEvent == NULL)
00060 {
00061
00062 if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
00063 {
00064 return 0.5;
00065 }
00066 else
00067 {
00068 return 0;
00069 }
00070 }
00071
00072
00073
00074 if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
00075 {
00076 return 0;
00077 }
00078
00079
00080 mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
00081 if (pointSet == NULL)
00082 return 0;
00083
00084
00085
00086
00087 mitk::Point3D worldPoint = posEvent->GetWorldPosition();
00088 float p[3];
00089 itk2vtk(worldPoint, p);
00090
00091 m_DataNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p);
00092 vtk2itk(p, worldPoint);
00093
00094 float distance = 5;
00095 int index = pointSet->SearchPoint(worldPoint, distance);
00096 if (index>-1)
00097
00098 {
00099
00100 mitk::PointSet::PointType point;
00101 pointSet->GetPointSet()->GetPoint(index, &point);
00102 returnValue = point.EuclideanDistanceTo(worldPoint);
00103
00104
00105 returnValue = 1 - ( returnValue / distance );
00106 if (returnValue<0 || returnValue>1)
00107 {
00108 itkWarningMacro("Difficulties in calculating Jurisdiction. Check PointInteractor");
00109 return 0;
00110 }
00111
00112
00113 returnValue = 0.5 + (returnValue / 2);
00114
00115 return returnValue;
00116 }
00117 else
00118 {
00119 return 0;
00120 }
00121 }
00122
00123 bool mitk::ConnectPointsInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
00124 {
00125 bool ok = false;
00126
00127
00128 mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataNode->GetData());
00129 if (mesh == NULL)
00130 return false;
00131
00132
00133
00134
00135
00136
00137 switch (action->GetActionId())
00138 {
00139 case AcDONOTHING:
00140 ok = true;
00141 break;
00142 case AcADDPOINT:
00143 {
00144 mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
00145 if (posEvent == NULL)
00146 return false;
00147
00148 mitk::Point3D worldPoint;
00149 worldPoint = posEvent->GetWorldPosition();
00150
00151 int position = mesh->SearchPoint(worldPoint, m_Precision);
00152 if (position >= 0)
00153 {
00154
00155 bool deleteLine=false;
00156 if(mesh->GetMesh()->GetCells()->Size() > 0)
00157 {
00158 Mesh::CellAutoPointer cellAutoPointer;
00159 ok = mesh->GetMesh()->GetCell(m_CurrentCellId, cellAutoPointer);
00160 if(ok)
00161 {
00162 Mesh::PointIdIterator last = cellAutoPointer->PointIdsEnd();
00163 --last;
00164 int foundCell = mesh->SearchFirstCell( (unsigned long) position );
00165 if (foundCell != -1)
00166 deleteLine = ((unsigned int)foundCell == m_CurrentCellId) && (*last == (unsigned int)position);
00167 }
00168 }
00169 if(deleteLine)
00170 {
00171 LineOperation* doOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position);
00172 if (m_UndoEnabled)
00173 {
00174 LineOperation* undoOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position);
00175 OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Delete line");
00176 m_UndoController->SetOperationEvent(operationEvent);
00177 }
00178
00179 mesh->ExecuteOperation(doOp );
00180 }
00181 else
00182 {
00183
00184 if(mesh->GetNewCellId() == 0)
00185
00186 {
00187
00188 m_CurrentCellId = mesh->GetNewCellId();
00189
00190
00191 LineOperation* doOp = new mitk::LineOperation(OpNEWCELL, m_CurrentCellId);
00192 if (m_UndoEnabled)
00193 {
00194 LineOperation* undoOp = new mitk::LineOperation(OpDELETECELL, m_CurrentCellId);
00195 OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add cell");
00196 m_UndoController->SetOperationEvent(operationEvent);
00197 }
00198 mesh->ExecuteOperation(doOp);
00199 }
00200
00201 if(mesh->SearchFirstCell(position) < 0)
00202 {
00203 LineOperation* doOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position);
00204 if (m_UndoEnabled)
00205 {
00206 LineOperation* undoOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position);
00207 OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add line");
00208 m_UndoController->SetOperationEvent(operationEvent);
00209 }
00210
00211 mesh->ExecuteOperation(doOp );
00212 }
00213 }
00214 }
00215 ok = true;
00216 break;
00217 }
00218 case AcREMOVEPOINT:
00219 {
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 ok = true;
00245 break;
00246 }
00247 case AcCHECKELEMENT:
00248
00249 {
00250 mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
00251 if (posEvent != NULL)
00252 {
00253 mitk::Point3D worldPoint = posEvent->GetWorldPosition();
00254
00255 int position = mesh->SearchPoint(worldPoint, m_Precision);
00256 if (position>=0)
00257 {
00258 PointSet::PointType pt = mesh->GetPoint(position);
00259 mitk::Point2D displPoint;
00260 displPoint[0] = worldPoint[0]; displPoint[1] = worldPoint[1];
00261
00262 mitk::PositionEvent const* newPosEvent = new mitk::PositionEvent(posEvent->GetSender(), Type_None, BS_NoButton, BS_NoButton, Key_none, displPoint, pt);
00263 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, newPosEvent);
00264
00265 this->HandleEvent( newStateEvent );
00266 ok = true;
00267 }
00268 else
00269 {
00270
00271 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
00272 this->HandleEvent(newStateEvent );
00273 ok = true;
00274 }
00275 }
00276 else
00277 {
00278 mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
00279 if (disPosEvent != NULL)
00280 {
00281 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
00282 this->HandleEvent(newStateEvent );
00283 ok = true;
00284 }
00285 }
00286 break;
00287 }
00288 case AcCHECKNMINUS1:
00289 {
00290 if (m_N<0)
00291 {
00292 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
00293 this->HandleEvent( newStateEvent );
00294 ok = true;
00295 }
00296 else
00297 {
00298 if (mesh->GetSize()<(m_N-1))
00299
00300 {
00301 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
00302 this->HandleEvent( newStateEvent );
00303 ok = true;
00304 }
00305 else
00306
00307 {
00308 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTLARGERNMINUS1, stateEvent->GetEvent());
00309 this->HandleEvent(newStateEvent );
00310 ok = true;
00311 }
00312 }
00313 }
00314 break;
00315 case AcCHECKEQUALS1:
00316 {
00317 if (mesh->GetSize()<=1)
00318 {
00319 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
00320 this->HandleEvent( newStateEvent );
00321 ok = true;
00322 }
00323 else
00324 {
00325 mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
00326 this->HandleEvent(newStateEvent );
00327 ok = true;
00328 }
00329 }
00330 break;
00331 default:
00332 return Superclass::ExecuteAction( action, stateEvent );
00333
00334
00335
00336
00337
00338 }
00339
00340 return ok;
00341 }