13 #define PLANARFIGUREINTERACTOR_DBG MITK_DEBUG("PlanarFigureInteractor") << __LINE__ << ": " 31 :
DataInteractor(), m_Precision(6.5), m_MinimumPointDistance(25.0), m_IsHovering(false), m_LastPointWasValid(false)
77 bool isFigureFinished =
false;
78 planarFigure->
GetPropertyList()->GetBoolProperty(
"initiallyplaced", isFigureFinished);
80 return planarFigure->
IsPlaced() && isFigureFinished;
86 if (positionEvent ==
nullptr)
89 bool isEditable =
true;
98 if (abstractTransformGeometry !=
nullptr)
109 planarFigure->InvokeEvent(StartInteractionPlanarFigureEvent());
112 bool hidecontrolpointsduringinteraction =
false;
121 planarFigure->SetCurrentControlPoint(point2D);
124 planarFigure->EvaluateFeatures();
134 planarFigure->Modified();
136 planarFigure->RemoveLastControlPoint();
140 planarFigure->InvokeEvent(EndPlacementPlanarFigureEvent());
141 planarFigure->InvokeEvent(EndInteractionPlanarFigureEvent());
144 planarFigure->EvaluateFeatures();
153 planarFigure->Modified();
154 planarFigure->InvokeEvent(EndInteractionPlanarFigureEvent());
160 if (interactionEvent->
GetSender() ==
nullptr)
174 m_IsHovering =
false;
175 planarFigure->InvokeEvent(EndHoverPlanarFigureEvent());
186 planarFigure->RemoveAllObservers();
213 bool isExtendable(
false);
221 bool isDeletable(
true);
229 bool isEditable(
true);
243 planarFigure->Modified();
244 planarFigure->InvokeEvent(EndInteractionPlanarFigureEvent());
256 if (positionEvent ==
nullptr)
282 bool isFigureFinished =
false;
283 data->GetPropertyList()->GetBoolProperty(
"initiallyplaced", isFigureFinished);
285 bool selected =
false;
286 bool isEditable =
true;
288 node->GetBoolProperty(
"selected", selected);
289 node->GetBoolProperty(
"planarfigure.iseditable", isEditable);
291 if (!selected || !isEditable)
300 if (dynamic_cast<PlanarBezierCurve *>(planarFigure) !=
nullptr && isFigureFinished)
307 if (abstractTransformGeometry !=
nullptr)
311 if (planarFigure->GetNumberOfControlPoints() >= planarFigure->GetMaximumNumberOfControlPoints())
318 Point2D point2D, projectedPoint;
334 if (dynamic_cast<mitk::PlanarPolygon *>(planarFigure) && isFigureFinished)
337 this->
IsPositionOverFigure(positionEvent, planarFigure, planarFigureGeometry, projectionPlane, projectedPoint);
342 if (planarFigure->IsPreviewControlPointVisible())
344 point2D = planarFigure->GetPreviewControlPoint();
347 planarFigure->AddControlPoint(point2D, planarFigure->GetControlPointForPolylinePoint(nextIndex, 0));
349 if (planarFigure->IsPreviewControlPointVisible())
351 planarFigure->SelectControlPoint(nextIndex);
352 planarFigure->ResetPreviewContolPoint();
356 planarFigure->EvaluateFeatures();
367 if (positionEvent ==
nullptr)
372 auto *planarFigureGeometry =
dynamic_cast<PlaneGeometry *
>(planarFigure->GetGeometry(0));
377 planarFigure->InvokeEvent(StartPlacementPlanarFigureEvent());
382 if (planeGeometry !=
nullptr && abstractTransformGeometry ==
nullptr)
384 planarFigureGeometry = planeGeometry;
385 planarFigure->SetPlaneGeometry(planeGeometry);
401 planarFigure->PlaceFigure(point2D);
404 planarFigure->EvaluateFeatures();
421 if (positionEvent ==
nullptr)
430 planarFigure->InvokeEvent(StartHoverPlanarFigureEvent());
443 if (positionEvent ==
nullptr)
449 planarFigure->DeselectControlPoint();
453 bool selected(
false);
454 bool isExtendable(
false);
455 bool isEditable(
true);
460 if (selected && isExtendable && isEditable)
462 renderer->
DisplayToPlane(pointProjectedOntoLine, pointProjectedOntoLine);
463 planarFigure->SetPreviewControlPoint(pointProjectedOntoLine);
483 const auto *positionEvent =
485 if (positionEvent ==
nullptr)
491 auto *abstractTransformGeometry =
495 if (abstractTransformGeometry !=
nullptr)
500 positionEvent, planarFigure, planarFigureGeometry, projectionPlane, pointProjectedOntoLine);
502 bool isHovering = (previousControlPoint != -1);
518 const auto *positionEvent =
520 if (positionEvent ==
nullptr)
530 if (abstractTransformGeometry !=
nullptr)
535 positionEvent, planarFigure, planarFigureGeometry, projectionPlane, renderer);
549 bool selected =
false;
558 planarFigure->InvokeEvent(SelectPlanarFigureEvent());
565 if (positionEvent ==
nullptr)
575 if (abstractTransformGeometry !=
nullptr)
579 positionEvent, planarFigure, planarFigureGeometry, projectionPlane, renderer);
584 planarFigure->SelectControlPoint(pointIndex);
588 planarFigure->DeselectControlPoint();
598 const auto *positionEvent =
600 if (positionEvent ==
nullptr)
606 return m_LastPointWasValid;
614 const int selectedControlPoint = planarFigure->GetSelectedControlPoint();
615 planarFigure->RemoveControlPoint(selectedControlPoint);
618 planarFigure->EvaluateFeatures();
619 planarFigure->Modified();
622 planarFigure->InvokeEvent(EndInteractionPlanarFigureEvent());
632 bool selected =
false;
638 planarFigure->InvokeEvent(SelectPlanarFigureEvent());
641 planarFigure->InvokeEvent(ContextMenuPlanarFigureEvent());
648 bool isEditable =
true;
652 return isEditable && planarFigure->ResetOnPointSelectNeeded();
657 const auto *posEvent =
660 if (posEvent ==
nullptr)
663 const mitk::Point3D worldPoint3D = posEvent->GetPositionInWorld();
670 if (abstractTransformGeometry !=
nullptr)
673 const double planeThickness = planarFigurePlaneGeometry->
GetExtentInMM(2);
674 if (planarFigurePlaneGeometry->
Distance(worldPoint3D) > planeThickness)
684 m_Precision = precision;
689 m_MinimumPointDistance = minimumDistance;
699 if (planarFigureGeometry->
Distance(worldPoint3D) > 0.1)
705 planarFigureGeometry->
Map(worldPoint3D, point2D);
718 objectGeometry->
Map(point2D, point3D);
720 const double planeThickness = objectGeometry->
GetExtentInMM(2);
723 if (rendererGeometry->
Distance(point3D) < planeThickness / 3.0)
742 const double l1 = n1 * (point - startPoint);
743 const double l2 = -n1 * (point - endPoint);
747 projectedPoint = crossPoint;
749 const float dist1 = crossPoint.SquaredEuclideanDistanceTo(point);
750 const float dist2 = endPoint.SquaredEuclideanDistanceTo(point);
751 const float dist3 = startPoint.SquaredEuclideanDistanceTo(point);
756 if (((dist1 < 20.0) && (l1 > 0.0) && (l2 > 0.0)) || dist2 < 20.0 || dist3 < 20.0)
768 Point2D &pointProjectedOntoLine)
const 779 for (
unsigned short loop = 0; loop < planarFigure->
GetPolyLinesSize(); ++loop)
781 const VertexContainerType polyLine = planarFigure->
GetPolyLine(loop);
783 bool firstPoint(
true);
784 for (
auto it = polyLine.begin(); it != polyLine.end(); ++it)
788 *it, polyLinePoint, planarFigureGeometry, rendererGeometry, positionEvent->
GetSender()))
795 firstPolyLinePoint = polyLinePoint;
798 else if (this->
IsPointNearLine(displayPosition, previousPolyLinePoint, polyLinePoint, pointProjectedOntoLine))
801 return std::distance(polyLine.begin(), it);
803 previousPolyLinePoint = polyLinePoint;
808 this->
IsPointNearLine(displayPosition, polyLinePoint, firstPolyLinePoint, pointProjectedOntoLine))
829 for (
int i = 0; i < numberOfControlPoints; i++)
832 planarFigure->
GetControlPoint(i), displayControlPoint, planarFigureGeometry, rendererGeometry, renderer))
835 if (displayPosition.SquaredEuclideanDistanceTo(displayControlPoint) < 20.0)
847 MITK_INFO <<
"PlanarFigure: " << planarFigure->GetNameOfClass();
858 assert(positionEvent && planarFigure);
864 const int timeStep(renderer->
GetTimeStep(planarFigure));
866 bool tooClose(
false);
873 if (abstractTransformGeometry !=
nullptr)
885 const Point2D correctedPoint =
const_cast<PlanarFigure *
>(planarFigure)->ApplyControlPointConstraints(0, point2D);
890 planarFigureGeometry->
Map(correctedPoint, newPoint3D);
897 if (i != selectedControlPoint)
908 renderer->
WorldToDisplay(previousPoint3D, previousDisplayPosition);
912 const double a = newDisplayPosition[0] - previousDisplayPosition[0];
913 const double b = newDisplayPosition[1] - previousDisplayPosition[1];
916 tooClose = (a * a + b * b < m_MinimumPointDistance);
930 std::string precision =
"";
931 if (properties->GetStringProperty(
"precision", precision))
933 m_Precision = atof(precision.c_str());
940 std::string minPointDistance =
"";
941 if (properties->GetStringProperty(
"minPointDistance", minPointDistance))
943 m_MinimumPointDistance = atof(minPointDistance.c_str());
Super class for all position events.
bool HandleEvent(InteractionEvent *event, DataNode *dataNode)
Point3D GetPositionInWorld() const
Organizes the rendering process.
void DisplayToPlane(const Point2D &displayPoint, Point2D &planePointInMM) const
This method converts a display point to the 2D world index, mapped onto the display plane using the g...
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 2D point in mm (pt2d_m...
bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for bool properties (instances of BoolProperty)
void WorldToDisplay(const Point3D &worldIndex, Point2D &displayPoint) const
This method converts a 3D world index to the display point using the geometry of the renderWindow...
DataNode * GetDataNode() const
ScalarType GetExtentInMM(int direction) const
Get the extent of the bounding-box in the specified direction in mm.
BaseRenderer * GetSender() const
Base class from with interactors that handle DataNodes are to be derived.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
static RenderingManager * GetInstance()
Represents an action, that is executed after a certain event (in statemachine-mechanism) TODO: implem...
virtual unsigned int GetTimeStep() const
virtual MapperSlotId GetMapperID()
Get the MapperSlotId to use.
const mitk::PlaneGeometry * GetCurrentPlaneGeometry()
Returns the currently selected Plane in the current BaseGeometry (if existent).
mitk::PropertyList::Pointer GetPropertyList() const
Get the data's property list.
void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting boolean properties (instances of BoolProperty)
#define CONNECT_CONDITION(a, f)
ScalarType Distance(const Point3D &pt3d_mm) const
Distance of the point from the geometry (bounding-box not considered)
Point2D GetPointerPositionOnScreen() const
virtual SliceNavigationController * GetSliceNavigationController()
PropertyList::Pointer GetAttributes() const
static Pointer New(BaseRenderer *_arga, DataInteractor *_argb, const std::string &_argc)
Describes a two-dimensional, rectangular plane.
#define CONNECT_FUNCTION(a, f)
virtual DataStorage::Pointer GetDataStorage() const
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.