Interaction for mitk::Mesh: Connect existing points to lines. More...
#include <mitkConnectPointsInteractor.h>
Public Types | |
typedef ConnectPointsInteractor | Self |
typedef Interactor | Superclass |
typedef itk::SmartPointer< Self > | Pointer |
typedef itk::SmartPointer < const Self > | ConstPointer |
Public Member Functions | |
virtual const char * | GetClassName () const |
void | SetPrecision (unsigned int precision) |
Sets the amount of precision. | |
virtual float | CanHandleEvent (StateEvent const *stateEvent) const |
calculates how good the data, this statemachine handles, is hit by the event. | |
Static Public Member Functions | |
static Pointer | New (const char *_arga, DataNode *_argb, int _argc) |
static Pointer | New (const char *_arga, DataNode *_argb) |
NewMacro with two parameters for calling itk::Lightobject::New(..) method. | |
Protected Member Functions | |
ConnectPointsInteractor (const char *type, DataNode *dataNode, int n=-1) | |
Constructor with Param n for limited Set of Points. | |
virtual | ~ConnectPointsInteractor () |
virtual bool | ExecuteAction (Action *action, mitk::StateEvent const *stateEvent) |
Method called in HandleEvent after Statechange. | |
void | UnselectAll () |
deselects the Points in the PointSet. supports Undo if enabled | |
void | SelectPoint (int position) |
Selects the point. supports Undo if enabled. |
Interaction for mitk::Mesh: Connect existing points to lines.
Definition at line 33 of file mitkConnectPointsInteractor.h.
typedef itk::SmartPointer<const Self> mitk::ConnectPointsInteractor::ConstPointer |
Reimplemented from mitk::Interactor.
Definition at line 36 of file mitkConnectPointsInteractor.h.
typedef itk::SmartPointer<Self> mitk::ConnectPointsInteractor::Pointer |
Reimplemented from mitk::Interactor.
Definition at line 36 of file mitkConnectPointsInteractor.h.
Reimplemented from mitk::Interactor.
Definition at line 36 of file mitkConnectPointsInteractor.h.
Reimplemented from mitk::Interactor.
Definition at line 36 of file mitkConnectPointsInteractor.h.
mitk::ConnectPointsInteractor::ConnectPointsInteractor | ( | const char * | type, |
DataNode * | dataNode, | ||
int | n = -1 |
||
) | [protected] |
Constructor with Param n for limited Set of Points.
if no n is set, then the number of points is unlimited*
Definition at line 35 of file mitkConnectPointsInteractor.cpp.
:Interactor(type, dataNode), m_N(n), m_CurrentCellId(0), m_Precision(PRECISION) { m_LastPoint.Fill(0); m_SumVec.Fill(0); }
mitk::ConnectPointsInteractor::~ConnectPointsInteractor | ( | ) | [protected, virtual] |
Definition at line 42 of file mitkConnectPointsInteractor.cpp.
{ }
float mitk::ConnectPointsInteractor::CanHandleEvent | ( | StateEvent const * | stateEvent ) | const [virtual] |
calculates how good the data, this statemachine handles, is hit by the event.
overwritten, cause we don't look at the boundingbox, we look at each point
overwritten cause this class can handle it better!
Reimplemented from mitk::Interactor.
Definition at line 53 of file mitkConnectPointsInteractor.cpp.
References QuadProgPP::distance(), mitk::StateEvent::GetEvent(), mitk::StateEvent::GetId(), mitk::PointSet::GetPointSet(), mitk::Event::GetType(), mitk::DisplayPositionEvent::GetWorldPosition(), mitk::PointSet::SearchPoint(), and mitk::Type_MouseMove.
{ float returnValue = 0; mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent()); //checking if a keyevent can be handled: if (posEvent == NULL) { //check, if the current state has a transition waiting for that key event. if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL) { return 0.5; } else { return 0; } } //Mouse event handling: //on MouseMove do nothing! reimplement if needed differently if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove) { return 0; } //check on the right data-type mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData()); if (pointSet == NULL) return 0; //since we now have 3D picking in GlobalInteraction and all events send are DisplayEvents with 3D information, //we concentrate on 3D coordinates mitk::Point3D worldPoint = posEvent->GetWorldPosition(); float p[3]; itk2vtk(worldPoint, p); //transforming the Worldposition to local coordinatesystem m_DataNode->GetData()->GetGeometry()->GetVtkTransform()->GetInverse()->TransformPoint(p, p); vtk2itk(p, worldPoint); float distance = 5; int index = pointSet->SearchPoint(worldPoint, distance); if (index>-1) //how far away is the line from the point? { //get the point and calculate the jurisdiction out of it. mitk::PointSet::PointType point; pointSet->GetPointSet()->GetPoint(index, &point); returnValue = point.EuclideanDistanceTo(worldPoint); //between 1 and 0. 1 if directly hit returnValue = 1 - ( returnValue / distance ); if (returnValue<0 || returnValue>1) { itkWarningMacro("Difficulties in calculating Jurisdiction. Check PointInteractor"); return 0; } //and now between 0,5 and 1 returnValue = 0.5 + (returnValue / 2); return returnValue; } else //not found { return 0; } }
bool mitk::ConnectPointsInteractor::ExecuteAction | ( | Action * | action, |
mitk::StateEvent const * | stateEvent | ||
) | [protected, virtual] |
Method called in HandleEvent after Statechange.
look up which object method is associated to the given action and call the method
Each statechange has actions, which can be assigned by it's number. If you are developing a new statemachine, declare all your operations here and send them to Undo-Controller and to the Data. Object- and group-EventId can also be accessed through static methods from OperationEvent
Reimplemented from mitk::StateMachine.
Definition at line 123 of file mitkConnectPointsInteractor.cpp.
References mitk::AcADDPOINT, mitk::AcCHECKELEMENT, mitk::AcCHECKEQUALS1, mitk::AcCHECKNMINUS1, mitk::AcDONOTHING, mitk::AcREMOVEPOINT, mitk::BS_NoButton, mitk::EIDNO, mitk::EIDSTLARGERNMINUS1, mitk::EIDSTSMALERNMINUS1, mitk::EIDYES, mitk::Mesh::ExecuteOperation(), mitk::Action::GetActionId(), mitk::StateEvent::GetEvent(), mitk::Mesh::GetMesh(), mitk::Mesh::GetNewCellId(), mitk::PointSet::GetPoint(), mitk::Event::GetSender(), mitk::PointSet::GetSize(), mitk::DisplayPositionEvent::GetWorldPosition(), int(), mitk::Key_none, mitk::OpADDLINE, mitk::OpDELETECELL, mitk::OpDELETELINE, mitk::OpNEWCELL, mitk::Mesh::SearchFirstCell(), mitk::PointSet::SearchPoint(), and mitk::Type_None.
{ bool ok = false;//for return type bool //checking corresponding Data; has to be a Mesh or a subclass mitk::Mesh* mesh = dynamic_cast<mitk::Mesh*>(m_DataNode->GetData()); if (mesh == NULL) return false; //for reading on the points, Id's etc //mitk::PointSet::DataType *itkpointSet = mesh->GetPointSet(); //mitk::PointSet::PointsContainer *points = itkpointSet->GetPoints();//Warning Fix: not used! /*Each case must watch the type of the event!*/ switch (action->GetActionId()) { case AcDONOTHING: ok = true; break; case AcADDPOINT: { mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent()); if (posEvent == NULL) return false; mitk::Point3D worldPoint; worldPoint = posEvent->GetWorldPosition(); int position = mesh->SearchPoint(worldPoint, m_Precision); if (position >= 0)//found a point near enough to the given point { // if the point is the last in current cell, remove it (this has to be moved in a separate action) bool deleteLine=false; if(mesh->GetMesh()->GetCells()->Size() > 0) { Mesh::CellAutoPointer cellAutoPointer; ok = mesh->GetMesh()->GetCell(m_CurrentCellId, cellAutoPointer); if(ok) { Mesh::PointIdIterator last = cellAutoPointer->PointIdsEnd(); --last; int foundCell = mesh->SearchFirstCell( (unsigned long) position ); if (foundCell != -1)//not found deleteLine = ((unsigned int)foundCell == m_CurrentCellId) && (*last == (unsigned int)position); } } if(deleteLine) { LineOperation* doOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position); if (m_UndoEnabled) { LineOperation* undoOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position); OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Delete line"); m_UndoController->SetOperationEvent(operationEvent); } //execute the Operation mesh->ExecuteOperation(doOp ); } else { // add new cell if necessary if(mesh->GetNewCellId() == 0) //allow single line only //allow multiple lines: if((mesh->SearchFirstCell(position) >= 0) || ((m_CurrentCellId == 0) && (mesh->GetNewCellId() == 0))) { //get the next cellId and set m_CurrentCellId m_CurrentCellId = mesh->GetNewCellId(); //now reserv a new cell in m_ItkData LineOperation* doOp = new mitk::LineOperation(OpNEWCELL, m_CurrentCellId); if (m_UndoEnabled) { LineOperation* undoOp = new mitk::LineOperation(OpDELETECELL, m_CurrentCellId); OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add cell"); m_UndoController->SetOperationEvent(operationEvent); } mesh->ExecuteOperation(doOp); } // add line if point is not yet included in current cell if(mesh->SearchFirstCell(position) < 0) { LineOperation* doOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position); if (m_UndoEnabled) { LineOperation* undoOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position); OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp, "Add line"); m_UndoController->SetOperationEvent(operationEvent); } //execute the Operation mesh->ExecuteOperation(doOp ); } } } ok = true; break; } case AcREMOVEPOINT: { //mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent()); //if (posEvent == NULL) // return false; //mitk::Point3D worldPoint; //worldPoint = posEvent->GetWorldPosition(); //int position = mesh->SearchPoint(worldPoint, m_Precision); //if (position>=0)//found a point near enough to the given point //{ // // if the point is in the current cell, remove it (this has to be moved in a separate action) // if(mesh->SearchFirstCell(position) == m_CurrentCellId) // { // LineOperation* doOp = new mitk::LineOperation(OpDELETELINE, m_CurrentCellId, position); // if (m_UndoEnabled) // { // LineOperation* undoOp = new mitk::LineOperation(OpADDLINE, m_CurrentCellId, position); // OperationEvent *operationEvent = new OperationEvent(mesh, doOp, undoOp); // m_UndoController->SetOperationEvent(operationEvent); // } // //execute the Operation // mesh->ExecuteOperation(doOp ); // } //} ok = true; break; } case AcCHECKELEMENT: /*checking if the Point transmitted is close enough to one point. Then generate a new event with the point and let this statemaschine handle the event.*/ { mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent()); if (posEvent != NULL) { mitk::Point3D worldPoint = posEvent->GetWorldPosition(); int position = mesh->SearchPoint(worldPoint, m_Precision); if (position>=0)//found a point near enough to the given point { PointSet::PointType pt = mesh->GetPoint(position);//get that point, the one meant by the user! mitk::Point2D displPoint; displPoint[0] = worldPoint[0]; displPoint[1] = worldPoint[1]; //new Event with information YES and with the correct point mitk::PositionEvent const* newPosEvent = new mitk::PositionEvent(posEvent->GetSender(), Type_None, BS_NoButton, BS_NoButton, Key_none, displPoint, pt); mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, newPosEvent); //call HandleEvent to leave the guard-state this->HandleEvent( newStateEvent ); ok = true; } else { //new Event with information NO mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent); this->HandleEvent(newStateEvent ); ok = true; } } else { mitk::DisplayPositionEvent const *disPosEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent()); if (disPosEvent != NULL) {//2d Koordinates for 3D Interaction; return false to redo the last statechange mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent); this->HandleEvent(newStateEvent ); ok = true; } } break; } case AcCHECKNMINUS1://generate Events if the set will be full after the addition of the point or not. { if (m_N<0)//number of points not limited->pass on "Amount of points in Set is smaller then N-1" { mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent()); this->HandleEvent( newStateEvent ); ok = true; } else { if (mesh->GetSize()<(m_N-1)) //pointset after addition won't be full { mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent()); this->HandleEvent( newStateEvent ); ok = true; } else //(mesh->GetSize()>=(m_N-1)) //after the addition of a point, the container will be full { mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDSTLARGERNMINUS1, stateEvent->GetEvent()); this->HandleEvent(newStateEvent ); ok = true; }//else }//else } break; case AcCHECKEQUALS1: { if (mesh->GetSize()<=1)//the number of points in the list is 1 (or smaler) { mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent()); this->HandleEvent( newStateEvent ); ok = true; } else //more than 1 points in list, so stay in the state! { mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent()); this->HandleEvent(newStateEvent ); ok = true; } } break; default: return Superclass::ExecuteAction( action, stateEvent ); //mitk::StatusBar::GetInstance()->DisplayText("Message from mitkConnectPointsInteractor: I do not understand the Action!", 10000); //ok = false; //a false here causes the statemachine to undo its last statechange. //otherwise it will end up in a different state, but without done Action. //if a transition really has no Action, than call donothing } return ok; }
virtual const char* mitk::ConnectPointsInteractor::GetClassName | ( | ) | const [virtual] |
Reimplemented from mitk::Interactor.
static Pointer mitk::ConnectPointsInteractor::New | ( | const char * | _arga, |
DataNode * | _argb, | ||
int | _argc | ||
) | [inline, static] |
Definition at line 37 of file mitkConnectPointsInteractor.h.
Referenced by mitkDataNodeExtTestClass::TestInteractorSetting().
:
//##Documentation
static Pointer mitk::ConnectPointsInteractor::New | ( | const char * | _arga, |
DataNode * | _argb | ||
) | [inline, static] |
NewMacro with two parameters for calling itk::Lightobject::New(..) method.
Reimplemented from mitk::Interactor.
Definition at line 38 of file mitkConnectPointsInteractor.h.
:
//##Documentation
void mitk::ConnectPointsInteractor::SelectPoint | ( | int | position ) | [protected] |
Selects the point. supports Undo if enabled.
position | is the index of the point that has to be selected |
void mitk::ConnectPointsInteractor::SetPrecision | ( | unsigned int | precision ) |
Sets the amount of precision.
Definition at line 46 of file mitkConnectPointsInteractor.cpp.
{ m_Precision = precision; }
void mitk::ConnectPointsInteractor::UnselectAll | ( | ) | [protected] |
deselects the Points in the PointSet. supports Undo if enabled