17 #include "vtkContext2D.h" 18 #include "vtkContextDevice2D.h" 19 #include "vtkOpenGLContextDevice2D.h" 22 #include "vtkTextProperty.h" 24 #define _USE_MATH_DEFINES 31 : m_NodeModified(true), m_NodeModifiedObserverTag(0), m_NodeModifiedObserverAdded(false), m_Initialized(false)
39 if (m_NodeModifiedObserverAdded &&
GetDataNode() !=
nullptr)
41 GetDataNode()->RemoveObserver(m_NodeModifiedObserverTag);
47 float rgba[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
53 this->m_Pen->SetColorF((
double)rgba[0], (
double)rgba[1], (
double)rgba[2], (
double)rgba[3]);
58 this->m_Pen = vtkSmartPointer<vtkPen>::New();
59 vtkOpenGLContextDevice2D *device =
nullptr;
60 device = vtkOpenGLContextDevice2D::New();
63 this->m_Context->Begin(device);
65 this->m_Initialized =
true;
66 this->m_Context->ApplyPen(this->m_Pen);
76 if (!this->m_Initialized)
80 vtkOpenGLContextDevice2D::SafeDownCast(
94 if (!planarFigure->IsPlaced())
101 if (planarFigurePlaneGeometry ==
nullptr)
103 MITK_ERROR <<
"PlanarFigure does not have valid PlaneGeometry!";
114 if ((planarFigurePlaneGeometry !=
nullptr) && (rendererPlaneGeometry !=
nullptr))
116 double planeThickness = planarFigurePlaneGeometry->
GetExtentInMM(2);
117 if (!planarFigurePlaneGeometry->
IsParallel(rendererPlaneGeometry) ||
118 !(planarFigurePlaneGeometry->
DistanceFromPlane(rendererPlaneGeometry) < planeThickness / 3.0))
144 else if (m_IsHovering)
154 RenderLines(lineDisplayMode, planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
158 double annotationOffset = 0.0;
161 float globalOpacity = 1.0;
164 if (m_DrawControlPoints)
167 RenderControlPoints(planarFigure, lineDisplayMode, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
171 const std::string name = node->
GetName();
172 if (m_DrawName && !name.empty())
174 RenderAnnotations(renderer, name, anchorPoint, globalOpacity, lineDisplayMode, annotationOffset);
179 if (m_DrawQuantities)
181 RenderQuantities(planarFigure, renderer, anchorPoint, annotationOffset, globalOpacity, lineDisplayMode);
184 this->m_Context->GetDevice()->End();
198 std::vector<mitk::Point2D> pointlist;
199 for (
auto iter = vertices.cbegin(); iter != vertices.cend(); ++iter)
205 pointlist.push_back(displayPoint);
207 if (displayPoint[0] > rightMostPoint[0])
208 rightMostPoint = displayPoint;
218 vertices.cbegin()[0], displayPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
220 pointlist.push_back(displayPoint);
225 std::vector<float> points;
226 points.reserve(pointlist.size() * 2);
228 for (
unsigned int i = 0 ; i < pointlist.size() ; ++i)
230 points.push_back(pointlist[i][0]);
231 points.push_back(pointlist[i][1]);
234 if (2 <= pointlist.size())
235 m_Context->DrawPoly(points.data(), pointlist.size());
237 anchorPoint = rightMostPoint;
247 for (
auto loop = 0; loop < numberOfPolyLines; ++loop)
252 polyline, figure->
IsClosed(), anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
265 for (
unsigned int loop = 0; loop < numberOfHelperPolyLines; ++loop)
267 const auto helperPolyLine =
277 this->
PaintPolyLine(helperPolyLine,
false, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
290 objectGeometry->
Map(point2D, point3D);
310 if (markerOpacity == 0 && lineOpacity == 0)
317 this->m_Context->GetPen()->SetColorF((
double)markerColor[0], (
double)markerColor[1], (
double)markerColor[2], markerOpacity);
318 this->m_Context->GetPen()->SetWidth(lineWidth);
327 if (markerOpacity > 0)
329 m_Context->DrawRect(displayPoint[0] - 4, displayPoint[1] - 4, 8, 8);
333 this->m_Context->GetPen()->SetColorF((
double)lineColor[0], (
double)lineColor[1], (
double)lineColor[2], (
double)lineOpacity);
335 std::array<float, 8> outline = {{
336 static_cast<float>(displayPoint[0] - 4),
337 static_cast<float>(displayPoint[1] - 4),
338 static_cast<float>(displayPoint[0] - 4),
339 static_cast<float>(displayPoint[1] + 4),
340 static_cast<float>(displayPoint[0] + 4),
341 static_cast<float>(displayPoint[1] + 4),
342 static_cast<float>(displayPoint[0] + 4),
343 static_cast<float>(displayPoint[1] - 4)
346 m_Context->DrawLines(outline.data(), 4);
389 m_IsSelected =
false;
390 m_IsHovering =
false;
391 m_DrawOutline =
false;
392 m_DrawQuantities =
false;
393 m_DrawShadow =
false;
394 m_DrawControlPoints =
false;
396 m_DrawDashed =
false;
397 m_DrawHelperDashed =
false;
398 m_AnnotationsShadow =
false;
400 m_ShadowWidthFactor = 1.2;
402 m_OutlineWidth = 4.0;
403 m_HelperlineWidth = 2.0;
405 m_DevicePixelRatio = 1.0;
455 if (!m_NodeModifiedObserverAdded)
457 itk::SimpleMemberCommand<mitk::PlanarFigureMapper2D>::Pointer nodeModifiedCommand =
458 itk::SimpleMemberCommand<mitk::PlanarFigureMapper2D>::New();
460 m_NodeModifiedObserverTag = node->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);
461 m_NodeModifiedObserverAdded =
true;
470 m_NodeModified =
false;
473 float globalOpacity = 1.0;
480 node->
GetBoolProperty(
"planarfigure.drawquantities", m_DrawQuantities);
481 node->
GetBoolProperty(
"planarfigure.drawcontrolpoints", m_DrawControlPoints);
485 node->
GetBoolProperty(
"planarfigure.helperline.drawdashed", m_DrawHelperDashed);
488 node->
GetFloatProperty(
"planarfigure.shadow.widthmodifier", m_ShadowWidthFactor);
492 node->
GetFloatProperty(
"planarfigure.devicepixelratio", m_DevicePixelRatio);
493 node->
GetStringProperty(
"planarfigure.annotations.font.family", m_AnnotationFontFamily);
494 node->
GetBoolProperty(
"planarfigure.annotations.font.bold", m_DrawAnnotationBold);
495 node->
GetBoolProperty(
"planarfigure.annotations.font.italic", m_DrawAnnotationItalic);
496 node->
GetIntProperty(
"planarfigure.annotations.font.size", m_AnnotationSize);
497 if (!node->
GetBoolProperty(
"planarfigure.annotations.shadow", m_AnnotationsShadow))
504 if (styleProperty.IsNotNull())
506 m_ControlPointShape = styleProperty->GetShape();
511 if (!node->
GetColor(m_LineColor[
PF_DEFAULT],
nullptr,
"planarfigure.default.line.color"))
513 node->
GetColor(m_LineColor[PF_DEFAULT],
nullptr,
"color");
515 node->
GetFloatProperty(
"planarfigure.default.line.opacity", m_LineOpacity[PF_DEFAULT]);
517 if (!node->
GetColor(m_OutlineColor[PF_DEFAULT],
nullptr,
"planarfigure.default.outline.color"))
519 node->
GetColor(m_OutlineColor[PF_DEFAULT],
nullptr,
"color");
521 node->
GetFloatProperty(
"planarfigure.default.outline.opacity", m_OutlineOpacity[PF_DEFAULT]);
523 if (!node->
GetColor(m_HelperlineColor[PF_DEFAULT],
nullptr,
"planarfigure.default.helperline.color"))
525 node->
GetColor(m_HelperlineColor[PF_DEFAULT],
nullptr,
"color");
527 node->
GetFloatProperty(
"planarfigure.default.helperline.opacity", m_HelperlineOpacity[PF_DEFAULT]);
529 node->
GetColor(m_MarkerlineColor[PF_DEFAULT],
nullptr,
"planarfigure.default.markerline.color");
530 node->
GetFloatProperty(
"planarfigure.default.markerline.opacity", m_MarkerlineOpacity[PF_DEFAULT]);
531 node->
GetColor(m_MarkerColor[PF_DEFAULT],
nullptr,
"planarfigure.default.marker.color");
532 node->
GetFloatProperty(
"planarfigure.default.marker.opacity", m_MarkerOpacity[PF_DEFAULT]);
533 if (!node->
GetColor(m_AnnotationColor[PF_DEFAULT],
nullptr,
"planarfigure.default.annotation.color"))
535 if (!node->
GetColor(m_AnnotationColor[PF_DEFAULT],
nullptr,
"planarfigure.default.line.color"))
537 node->
GetColor(m_AnnotationColor[PF_DEFAULT],
nullptr,
"color");
542 node->
GetColor(m_LineColor[
PF_HOVER],
nullptr,
"planarfigure.hover.line.color");
543 node->
GetFloatProperty(
"planarfigure.hover.line.opacity", m_LineOpacity[PF_HOVER]);
544 node->
GetColor(m_OutlineColor[PF_HOVER],
nullptr,
"planarfigure.hover.outline.color");
545 node->
GetFloatProperty(
"planarfigure.hover.outline.opacity", m_OutlineOpacity[PF_HOVER]);
546 node->
GetColor(m_HelperlineColor[PF_HOVER],
nullptr,
"planarfigure.hover.helperline.color");
547 node->
GetFloatProperty(
"planarfigure.hover.helperline.opacity", m_HelperlineOpacity[PF_HOVER]);
548 node->
GetColor(m_MarkerlineColor[PF_HOVER],
nullptr,
"planarfigure.hover.markerline.color");
549 node->
GetFloatProperty(
"planarfigure.hover.markerline.opacity", m_MarkerlineOpacity[PF_HOVER]);
550 node->
GetColor(m_MarkerColor[PF_HOVER],
nullptr,
"planarfigure.hover.marker.color");
551 node->
GetFloatProperty(
"planarfigure.hover.marker.opacity", m_MarkerOpacity[PF_HOVER]);
552 if (!node->
GetColor(m_AnnotationColor[PF_HOVER],
nullptr,
"planarfigure.hover.annotation.color"))
554 if (!node->
GetColor(m_AnnotationColor[PF_HOVER],
nullptr,
"planarfigure.hover.line.color"))
556 node->
GetColor(m_AnnotationColor[PF_HOVER],
nullptr,
"color");
562 node->
GetFloatProperty(
"planarfigure.selected.line.opacity", m_LineOpacity[PF_SELECTED]);
563 node->
GetColor(m_OutlineColor[PF_SELECTED],
nullptr,
"planarfigure.selected.outline.color");
564 node->
GetFloatProperty(
"planarfigure.selected.outline.opacity", m_OutlineOpacity[PF_SELECTED]);
565 node->
GetColor(m_HelperlineColor[PF_SELECTED],
nullptr,
"planarfigure.selected.helperline.color");
566 node->
GetFloatProperty(
"planarfigure.selected.helperline.opacity", m_HelperlineOpacity[PF_SELECTED]);
567 node->
GetColor(m_MarkerlineColor[PF_SELECTED],
nullptr,
"planarfigure.selected.markerline.color");
568 node->
GetFloatProperty(
"planarfigure.selected.markerline.opacity", m_MarkerlineOpacity[PF_SELECTED]);
569 node->
GetColor(m_MarkerColor[PF_SELECTED],
nullptr,
"planarfigure.selected.marker.color");
570 node->
GetFloatProperty(
"planarfigure.selected.marker.opacity", m_MarkerOpacity[PF_SELECTED]);
571 if (!node->
GetColor(m_AnnotationColor[PF_SELECTED],
nullptr,
"planarfigure.selected.annotation.color"))
573 if (!node->
GetColor(m_AnnotationColor[PF_SELECTED],
nullptr,
"planarfigure.selected.line.color"))
575 node->
GetColor(m_AnnotationColor[PF_SELECTED],
nullptr,
"color");
580 for (
unsigned int i = 0; i <
PF_COUNT; ++i)
582 m_LineOpacity[i] *= globalOpacity;
583 m_OutlineOpacity[i] *= globalOpacity;
584 m_HelperlineOpacity[i] *= globalOpacity;
585 m_MarkerlineOpacity[i] *= globalOpacity;
586 m_MarkerOpacity[i] *= globalOpacity;
592 m_NodeModified =
true;
659 bool isEditable =
true;
667 for (
unsigned int i = 0; i < numberOfControlPoints; ++i)
673 if (i == selectedControlPointsIdx)
677 else if (m_IsHovering && isEditable)
683 if (m_MarkerOpacity[pointDisplayMode] == 0 && m_MarkerlineOpacity[pointDisplayMode] == 0)
694 m_OutlineColor[lineDisplayMode],
695 m_MarkerlineOpacity[pointDisplayMode],
696 m_OutlineColor[lineDisplayMode],
697 m_MarkerOpacity[pointDisplayMode],
700 planarFigurePlaneGeometry,
701 rendererPlaneGeometry,
706 m_MarkerlineColor[pointDisplayMode],
707 m_MarkerlineOpacity[pointDisplayMode],
708 m_MarkerColor[pointDisplayMode],
709 m_MarkerOpacity[pointDisplayMode],
712 planarFigurePlaneGeometry,
713 rendererPlaneGeometry,
726 planarFigurePlaneGeometry,
727 rendererPlaneGeometry,
733 const std::string name,
737 double &annotationOffset)
744 vtkTextProperty* textProp = vtkTextProperty::New();
745 textProp->SetFontSize(m_AnnotationSize);
746 textProp->SetFontFamilyAsString(m_AnnotationFontFamily.c_str());
747 textProp->SetJustificationToLeft();
748 textProp->SetOpacity(globalOpacity);
749 textProp->SetShadow(0);
750 textProp->SetBold(m_DrawAnnotationBold);
751 textProp->SetItalic(m_DrawAnnotationItalic);
757 scaledAnchorPoint[0] = anchorPoint[0] * m_DevicePixelRatio;
758 scaledAnchorPoint[1] = anchorPoint[1] * m_DevicePixelRatio;
760 offset[0] = offset[0] * m_DevicePixelRatio;
761 offset[1] = offset[1] * m_DevicePixelRatio;
766 textProp->SetColor(0.0,0.0,0.0);
767 this->m_Context->ApplyTextProp(textProp);
768 this->m_Context->DrawString(scaledAnchorPoint[0]+offset[0]+1, scaledAnchorPoint[1]+offset[1]-1, name.c_str());
770 textProp->SetColor(m_AnnotationColor[lineDisplayMode][0],
771 m_AnnotationColor[lineDisplayMode][1],
772 m_AnnotationColor[lineDisplayMode][2]);
773 this->m_Context->ApplyTextProp(textProp);
774 this->m_Context->DrawString(scaledAnchorPoint[0]+offset[0], scaledAnchorPoint[1]+offset[1], name.c_str());
776 annotationOffset -= 15.0;
784 double &annotationOffset,
793 std::stringstream quantityString;
794 quantityString.setf(ios::fixed, ios::floatfield);
795 quantityString.precision(1);
797 bool firstActiveFeature =
true;
802 if (!firstActiveFeature)
804 quantityString <<
" x ";
806 quantityString << planarFigure->
GetQuantity(i) <<
" ";
808 firstActiveFeature =
false;
812 vtkTextProperty* textProp = vtkTextProperty::New();
813 textProp->SetFontSize(m_AnnotationSize);
814 textProp->SetFontFamilyAsString(m_AnnotationFontFamily.c_str());
815 textProp->SetJustificationToLeft();
816 textProp->SetOpacity(globalOpacity);
817 textProp->SetShadow(0);
818 textProp->SetBold(m_DrawAnnotationBold);
819 textProp->SetItalic(m_DrawAnnotationItalic);
825 scaledAnchorPoint[0] = anchorPoint[0] * m_DevicePixelRatio;
826 scaledAnchorPoint[1] = anchorPoint[1] * m_DevicePixelRatio;
828 offset[0] = offset[0] * m_DevicePixelRatio;
829 offset[1] = offset[1] * m_DevicePixelRatio;
834 textProp->SetColor(0,0,0);
835 this->m_Context->ApplyTextProp(textProp);
836 this->m_Context->DrawString(scaledAnchorPoint[0]+offset[0]+1, scaledAnchorPoint[1]+offset[1]-1, quantityString.str().c_str());
838 textProp->SetColor(m_AnnotationColor[lineDisplayMode][0],
839 m_AnnotationColor[lineDisplayMode][1],
840 m_AnnotationColor[lineDisplayMode][2]);
841 this->m_Context->ApplyTextProp(textProp);
842 this->m_Context->DrawString(scaledAnchorPoint[0]+offset[0], scaledAnchorPoint[1]+offset[1], quantityString.str().c_str());
844 annotationOffset -= 15.0;
859 const float *color = m_OutlineColor[lineDisplayMode];
860 const float opacity = m_OutlineOpacity[lineDisplayMode];
864 this->m_Context->GetPen()->SetColorF((
double)color[0], (
double)color[1], (
double)color[2], opacity);
865 this->m_Context->GetPen()->SetWidth(m_OutlineWidth);
868 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
870 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
873 this->
DrawMainLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
875 this->m_Context->GetPen()->SetWidth(m_HelperlineWidth);
877 if (m_DrawHelperDashed)
878 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
880 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
883 this->
DrawHelperLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
890 const float opacity = m_OutlineOpacity[lineDisplayMode];
891 float shadowOpacity = 0.0f;
893 shadowOpacity = opacity - 0.2f;
896 this->m_Context->GetPen()->SetColorF(0, 0, 0, shadowOpacity);
897 this->m_Context->GetPen()->SetWidth(m_OutlineWidth * m_ShadowWidthFactor);
900 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
902 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
905 this->
DrawMainLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
907 this->m_Context->GetPen()->SetWidth(m_HelperlineWidth);
909 if (m_DrawHelperDashed)
910 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
912 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
915 this->
DrawHelperLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
920 const float *color = m_LineColor[lineDisplayMode];
921 const float opacity = m_LineOpacity[lineDisplayMode];
925 this->m_Context->GetPen()->SetColorF((
double)color[0], (
double)color[1], (
double)color[2], (
double)opacity);
926 this->m_Context->GetPen()->SetWidth(m_LineWidth);
929 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
931 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
934 this->
DrawMainLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
936 const float *helperColor = m_HelperlineColor[lineDisplayMode];
937 const float helperOpacity = m_HelperlineOpacity[lineDisplayMode];
940 this->m_Context->GetPen()->SetColorF((
double)helperColor[0], (
double)helperColor[1], (
double)helperColor[2], (
double)helperOpacity);
941 this->m_Context->GetPen()->SetWidth(m_HelperlineWidth);
943 if (m_DrawHelperDashed)
944 this->m_Context->GetPen()->SetLineType(vtkPen::DASH_LINE);
946 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
950 this->
DrawHelperLines(planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, renderer);
953 if (m_DrawDashed || m_DrawHelperDashed)
954 this->m_Context->GetPen()->SetLineType(vtkPen::SOLID_LINE);
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr, bool fallBackOnDataProperties=true) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
vtkRenderer * GetVtkRenderer() const
bool GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for string properties (instances of StringProperty)
virtual DataNode * GetDataNode() const
Get the DataNode containing the data to map. Method only returns valid DataNode Pointer if the mapper...
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
Organizes the rendering process.
double GetScaleFactorMMPerDisplayUnit() const
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)
bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey="opacity") const
Convenience access method for opacity properties (instances of FloatProperty)
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
ScalarType GetExtentInMM(int direction) const
Get the extent of the bounding-box in the specified direction in mm.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
Add the property (instance of BaseProperty) if it does not exist (or always ifoverwrite istrue) with ...
ScalarType DistanceFromPlane(const Point3D &pt3d_mm) const
Distance of the point from the plane (bounding-box not considered)
bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="color") const
Convenience access method for color properties (instances of ColorProperty)
mitk::DataNode * m_DataNode
bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey="visible") const
Convenience access method for visibility properties (instances of BoolProperty with property-key "vis...
virtual int * GetViewportSize() const
bool IsParallel(const PlaneGeometry *plane) const
Returns whether the plane is parallel to another plane.
MITKCORE_EXPORT const ScalarType eps
Describes a two-dimensional, rectangular plane.
void WorldToView(const Point3D &worldIndex, Point2D &viewPoint) const
This method converts a 3D world index to the point on the viewport using the geometry of the renderWi...
Class for nodes of the DataTree.
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...