diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp index 9eb5967c04..da8e2286d2 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp @@ -1,754 +1,781 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPlanarFigureMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkGL.h" #include "mitkVtkPropRenderer.h" #define _USE_MATH_DEFINES #include // offset which moves the planarfigures on top of the other content // the crosshair is rendered into the z = 1 layer. static const float PLANAR_OFFSET = 0.5f; mitk::PlanarFigureMapper2D::PlanarFigureMapper2D() { this->InitializeDefaultPlanarFigureProperties(); } mitk::PlanarFigureMapper2D::~PlanarFigureMapper2D() { } void mitk::PlanarFigureMapper2D::Paint( mitk::BaseRenderer *renderer ) { - bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; + // Get PlanarFigure from input mitk::PlanarFigure *planarFigure = const_cast< mitk::PlanarFigure * >( static_cast< const mitk::PlanarFigure * >( GetDataNode()->GetData() ) ); // Check if PlanarFigure has already been placed; otherwise, do nothing if ( !planarFigure->IsPlaced() ) { return; } // Get 2D geometry frame of PlanarFigure mitk::Geometry2D *planarFigureGeometry2D = dynamic_cast< Geometry2D * >( planarFigure->GetGeometry( 0 ) ); if ( planarFigureGeometry2D == NULL ) { MITK_ERROR << "PlanarFigure does not have valid Geometry2D!"; return; } // Get current world 2D geometry from renderer const mitk::Geometry2D *rendererGeometry2D = renderer->GetCurrentWorldGeometry2D(); // If the PlanarFigure geometry is a plane geometry, check if current // world plane is parallel to and within the planar figure geometry bounds // (otherwise, display nothing) mitk::PlaneGeometry *planarFigurePlaneGeometry = dynamic_cast< PlaneGeometry * >( planarFigureGeometry2D ); const mitk::PlaneGeometry *rendererPlaneGeometry = dynamic_cast< const PlaneGeometry * >( rendererGeometry2D ); if ( (planarFigurePlaneGeometry != NULL) && (rendererPlaneGeometry != NULL) ) { double planeThickness = planarFigurePlaneGeometry->GetExtentInMM( 2 ); if ( !planarFigurePlaneGeometry->IsParallel( rendererPlaneGeometry ) || !(planarFigurePlaneGeometry->DistanceFromPlane( rendererPlaneGeometry ) < planeThickness / 3.0) ) { // Planes are not parallel or renderer plane is not within PlanarFigure // geometry bounds --> exit return; } } else { // Plane is not valid (curved reformations are not possible yet) return; } // Get display geometry mitk::DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry != NULL ); // Apply visual appearance properties from the PropertyList ApplyColorAndOpacityProperties( renderer ); // Enable line antialiasing glEnable( GL_LINE_SMOOTH ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glEnable(GL_DEPTH_TEST); // Get properties from node (if present) const mitk::DataNode* node=this->GetDataNode(); this->InitializePlanarFigurePropertiesFromDataNode( node ); PlanarFigureDisplayMode lineDisplayMode = PF_DEFAULT; if ( m_IsSelected ) { lineDisplayMode = PF_SELECTED; } else if ( m_IsHovering ) { lineDisplayMode = PF_HOVER; } mitk::Point2D firstPoint; firstPoint[0] = 0; firstPoint[1] = 1; if ( m_DrawOutline ) { // Draw the outline for all polylines if requested this->DrawMainLines( planarFigure, m_OutlineColor[lineDisplayMode], m_OutlineOpacity[lineDisplayMode], m_DrawShadow, m_OutlineWidth, m_ShadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); // Draw the outline for all helper objects if requested this->DrawHelperLines( planarFigure, m_OutlineColor[lineDisplayMode], m_OutlineOpacity[lineDisplayMode], m_DrawShadow, m_OutlineWidth, m_ShadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } // Draw the main line for all polylines this->DrawMainLines( planarFigure, m_LineColor[lineDisplayMode], m_LineOpacity[lineDisplayMode], m_DrawShadow, m_LineWidth, m_ShadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); double annotationOffset = 0.0; //Get Global Opacity float globalOpacity = 1.0; node->GetFloatProperty("opacity", globalOpacity); // draw name near the first point (if present) std::string name = node->GetName(); if ( m_DrawName && !name.empty() ) { mitk::VtkPropRenderer* openGLrenderer = dynamic_cast( renderer ); if ( openGLrenderer ) { openGLrenderer->WriteSimpleText( name, firstPoint[0] + 6.0, firstPoint[1] + 4.0, 0, 0, 0, globalOpacity ); //this is a shadow openGLrenderer->WriteSimpleText( name, firstPoint[0] + 5.0, firstPoint[1] + 5.0, m_LineColor[lineDisplayMode][0], m_LineColor[lineDisplayMode][1], m_LineColor[lineDisplayMode][2], globalOpacity ); // If drawing is successful, add approximate height to annotation offset annotationOffset -= 15.0; } } // draw feature quantities (if requested) new the first point if ( m_DrawQuantities ) { std::stringstream quantityString; quantityString.setf( ios::fixed, ios::floatfield ); quantityString.precision( 1 ); bool firstActiveFeature = true; for ( unsigned int i = 0; i < planarFigure->GetNumberOfFeatures(); ++i ) { if( planarFigure->IsFeatureActive(i) && planarFigure->IsFeatureVisible( i ) ) { if ( ! firstActiveFeature ) { quantityString << " x "; } quantityString << planarFigure->GetQuantity( i ) << " "; quantityString << planarFigure->GetFeatureUnit( i ); firstActiveFeature = false; } } mitk::VtkPropRenderer* openGLrenderer = dynamic_cast( renderer ); if ( openGLrenderer ) { openGLrenderer->WriteSimpleText( quantityString.str().c_str(), firstPoint[0] + 6.0, firstPoint[1] + 4.0 + annotationOffset, 0, 0, 0, globalOpacity ); //this is a shadow openGLrenderer->WriteSimpleText( quantityString.str().c_str(), firstPoint[0] + 5.0, firstPoint[1] + 5.0 + annotationOffset, m_LineColor[lineDisplayMode][0], m_LineColor[lineDisplayMode][1], m_LineColor[lineDisplayMode][2], globalOpacity ); // If drawing is successful, add approximate height to annotation offset annotationOffset -= 15.0; } } // Draw helper objects this->DrawHelperLines( planarFigure, m_HelperlineColor[lineDisplayMode], m_HelperlineOpacity[lineDisplayMode], m_DrawShadow, m_LineWidth, m_ShadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); if ( m_DrawControlPoints ) { // Draw markers at control points (selected control point will be colored) for ( unsigned int i = 0; i < planarFigure->GetNumberOfControlPoints(); ++i ) { bool isEditable = true; m_DataNode->GetBoolProperty( "planarfigure.iseditable", isEditable ); PlanarFigureDisplayMode pointDisplayMode = PF_DEFAULT; // Only if planar figure is marked as editable: display markers (control points) in a // different style if mouse is over them or they are selected if ( isEditable ) { if ( i == (unsigned int) planarFigure->GetSelectedControlPoint() ) { pointDisplayMode = PF_SELECTED; } else if ( m_IsHovering ) { pointDisplayMode = PF_HOVER; } } if ( m_DrawOutline ) { // draw outlines for markers as well // linewidth for the contour is only half, as full width looks // much too thick! this->DrawMarker( planarFigure->GetControlPoint( i ), m_OutlineColor[lineDisplayMode], m_MarkerlineOpacity[pointDisplayMode], m_OutlineColor[lineDisplayMode], m_MarkerOpacity[pointDisplayMode], m_OutlineWidth/2, m_ControlPointShape, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } this->DrawMarker( planarFigure->GetControlPoint( i ), m_MarkerlineColor[pointDisplayMode], m_MarkerlineOpacity[pointDisplayMode], m_MarkerColor[pointDisplayMode], m_MarkerOpacity[pointDisplayMode], m_LineWidth, m_ControlPointShape, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } if ( planarFigure->IsPreviewControlPointVisible() ) { this->DrawMarker( planarFigure->GetPreviewControlPoint(), m_MarkerlineColor[PF_HOVER], m_MarkerlineOpacity[PF_HOVER], m_MarkerColor[PF_HOVER], m_MarkerOpacity[PF_HOVER], m_LineWidth, m_ControlPointShape, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } } glLineWidth( 1.0f ); } void mitk::PlanarFigureMapper2D::PaintPolyLine( mitk::PlanarFigure::PolyLineType vertices, bool closed, float* color, float opacity, float lineWidth, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry) { glColor4f( color[0], color[1], color[2], opacity ); glLineWidth(lineWidth); - glBegin( GL_LINE_STRIP ); + + if ( closed ) + { + glBegin( GL_LINE_LOOP ); + } + else + { + glBegin( GL_LINE_STRIP ); + } for ( PlanarFigure::PolyLineType::iterator iter = vertices.begin(); iter!=vertices.end(); iter++ ) { // Draw this 2D point as OpenGL vertex mitk::Point2D displayPoint; this->TransformObjectToDisplay( iter->Point, displayPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); if(iter == vertices.begin()) firstPoint = displayPoint; glVertex3f( displayPoint[0], displayPoint[1], PLANAR_OFFSET ); } if(closed && (vertices.begin() != vertices.end())) { // complete line loop to the first point again mitk::Point2D displayPoint; this->TransformObjectToDisplay( vertices.begin()->Point, displayPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); glVertex3f( displayPoint[0], displayPoint[1], PLANAR_OFFSET ); } glEnd(); } void mitk::PlanarFigureMapper2D::DrawMainLines( mitk::PlanarFigure* figure, float* color, float opacity, bool drawShadow, float lineWidth, float shadowWidthFactor, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry) { + + if ( m_DrawDashed ) + { + glLineStipple(1, 0x00FF); + glEnable(GL_LINE_STIPPLE); + } + for ( unsigned short loop = 0; loop < figure->GetPolyLinesSize(); ++loop ) { PlanarFigure::PolyLineType polyline = figure->GetPolyLine(loop); if ( drawShadow ) { float* shadow = new float[3]; shadow[0] = 0; shadow[1] = 0; shadow[2] = 0; //set shadow opacity float shadowOpacity = 0.0f; if( opacity > 0.2f ) shadowOpacity = opacity - 0.2f; this->PaintPolyLine( polyline, figure->IsClosed(), shadow, shadowOpacity, lineWidth*shadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); delete shadow; } this->PaintPolyLine( polyline, figure->IsClosed(), color, opacity, lineWidth, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } + + if ( m_DrawDashed ) + { + glDisable(GL_LINE_STIPPLE); + } + } void mitk::PlanarFigureMapper2D::DrawHelperLines( mitk::PlanarFigure* figure, float* color, float opacity, bool drawShadow, float lineWidth, float shadowWidthFactor, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry) { // Draw helper objects for ( unsigned int loop = 0; loop < figure->GetHelperPolyLinesSize(); ++loop ) { const mitk::PlanarFigure::PolyLineType helperPolyLine = figure->GetHelperPolyLine(loop, displayGeometry->GetScaleFactorMMPerDisplayUnit(), displayGeometry->GetDisplayHeight() ); // Check if the current helper objects is to be painted if ( !figure->IsHelperToBePainted( loop ) ) { continue; } // check if shadow shall be painted around the figure if ( drawShadow ) { float* shadow = new float[3]; shadow[0] = 0; shadow[1] = 0; shadow[2] = 0; //set shadow opacity float shadowOpacity = 0.0f; if( opacity > 0.2f ) shadowOpacity = opacity - 0.2f; // paint shadow by painting the figure twice // one in black with a slightly broader line-width ... this->PaintPolyLine( helperPolyLine, false, shadow, shadowOpacity, lineWidth*shadowWidthFactor, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); delete shadow; } // ... and once normally above the shadow. this->PaintPolyLine( helperPolyLine, false, color, opacity, lineWidth, firstPoint, planarFigureGeometry2D, rendererGeometry2D, displayGeometry ); } } void mitk::PlanarFigureMapper2D::TransformObjectToDisplay( const mitk::Point2D &point2D, mitk::Point2D &displayPoint, const mitk::Geometry2D *objectGeometry, const mitk::Geometry2D *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ) { mitk::Point3D point3D; // Map circle point from local 2D geometry into 3D world space objectGeometry->Map( point2D, point3D ); // Project 3D world point onto display geometry rendererGeometry->Map( point3D, displayPoint ); displayGeometry->WorldToDisplay( displayPoint, displayPoint ); } void mitk::PlanarFigureMapper2D::DrawMarker( const mitk::Point2D &point, float* lineColor, float lineOpacity, float* markerColor, float markerOpacity, float lineWidth, PlanarFigureControlPointStyleProperty::Shape shape, const mitk::Geometry2D *objectGeometry, const mitk::Geometry2D *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ) { mitk::Point2D displayPoint; if ( markerOpacity == 0 && lineOpacity == 0 ) return; this->TransformObjectToDisplay( point, displayPoint, objectGeometry, rendererGeometry, displayGeometry ); glColor4f( markerColor[0], markerColor[1], markerColor[2], markerOpacity ); glLineWidth( lineWidth ); switch ( shape ) { case PlanarFigureControlPointStyleProperty::Square: default: // Paint filled square // Disable line antialiasing (does not look nice for squares) glDisable( GL_LINE_SMOOTH ); glRectf( displayPoint[0] - 4, displayPoint[1] - 4, displayPoint[0] + 4, displayPoint[1] + 4 ); // Paint outline glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity ); glBegin( GL_LINE_LOOP ); glVertex3f( displayPoint[0] - 4, displayPoint[1] - 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] - 4, displayPoint[1] + 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] + 4, displayPoint[1] + 4, PLANAR_OFFSET ); glVertex3f( displayPoint[0] + 4, displayPoint[1] - 4, PLANAR_OFFSET ); glEnd(); break; case PlanarFigureControlPointStyleProperty::Circle: // Paint filled circle glBegin( GL_POLYGON ); float radius = 4.0; for ( int angle = 0; angle < 8; ++angle ) { float angleRad = angle * (float) 3.14159 / 4.0; float x = displayPoint[0] + radius * (float)cos( angleRad ); float y = displayPoint[1] + radius * (float)sin( angleRad ); glVertex3f(x, y, PLANAR_OFFSET); } glEnd(); // Paint outline glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity ); glBegin( GL_LINE_LOOP ); for ( int angle = 0; angle < 8; ++angle ) { float angleRad = angle * (float) 3.14159 / 4.0; float x = displayPoint[0] + radius * (float)cos( angleRad ); float y = displayPoint[1] + radius * (float)sin( angleRad ); glVertex3f(x, y, PLANAR_OFFSET); } glEnd(); break; } // end switch } void mitk::PlanarFigureMapper2D::InitializeDefaultPlanarFigureProperties() { m_IsSelected = false; m_IsHovering = false; m_DrawOutline = false; m_DrawQuantities = false; m_DrawShadow = false; m_DrawControlPoints = false; m_DrawName = true; + m_DrawDashed = true; m_ShadowWidthFactor = 1.2; m_LineWidth = 1.0; m_OutlineWidth = 4.0; m_HelperlineWidth = 2.0; m_ControlPointShape = PlanarFigureControlPointStyleProperty::Square; this->SetColorProperty( m_LineColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_LineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_DEFAULT, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_DEFAULT, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_DEFAULT, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_DEFAULT, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_DEFAULT, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_DEFAULT, 0.0 ); this->SetColorProperty( m_LineColor, PF_HOVER, 1.0, 0.7, 0.0 ); this->SetFloatProperty( m_LineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_HOVER, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_HOVER, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_HOVER, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_HOVER, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_HOVER, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_HOVER, 1.0, 0.6, 0.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_HOVER, 0.2 ); this->SetColorProperty( m_LineColor, PF_SELECTED, 1.0, 0.0, 0.0 ); this->SetFloatProperty( m_LineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_OutlineColor, PF_SELECTED, 0.0, 0.0, 1.0 ); this->SetFloatProperty( m_OutlineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_HelperlineColor, PF_SELECTED, 0.4, 0.8, 0.2 ); this->SetFloatProperty( m_HelperlineOpacity, PF_SELECTED, 0.4 ); this->SetColorProperty( m_MarkerlineColor, PF_SELECTED, 1.0, 1.0, 1.0 ); this->SetFloatProperty( m_MarkerlineOpacity, PF_SELECTED, 1.0 ); this->SetColorProperty( m_MarkerColor, PF_SELECTED, 1.0, 0.6, 0.0 ); this->SetFloatProperty( m_MarkerOpacity, PF_SELECTED, 1.0 ); } void mitk::PlanarFigureMapper2D::InitializePlanarFigurePropertiesFromDataNode( const mitk::DataNode* node ) { if ( node == NULL ) { return; } //Get Global Opacity float globalOpacity = 1.0; node->GetFloatProperty("opacity", globalOpacity); node->GetBoolProperty( "selected", m_IsSelected ); node->GetBoolProperty( "planarfigure.ishovering", m_IsHovering ); node->GetBoolProperty( "planarfigure.drawoutline", m_DrawOutline ); node->GetBoolProperty( "planarfigure.drawshadow", m_DrawShadow ); node->GetBoolProperty( "planarfigure.drawquantities", m_DrawQuantities ); node->GetBoolProperty( "planarfigure.drawcontrolpoints", m_DrawControlPoints ); node->GetBoolProperty( "planarfigure.drawname", m_DrawName ); + node->GetBoolProperty( "planarfigure.drawdashed", m_DrawDashed ); + + node->GetFloatProperty( "planarfigure.line.width", m_LineWidth ); node->GetFloatProperty( "planarfigure.shadow.widthmodifier", m_ShadowWidthFactor ); node->GetFloatProperty( "planarfigure.outline.width", m_OutlineWidth ); node->GetFloatProperty( "planarfigure.helperline.width", m_HelperlineWidth ); PlanarFigureControlPointStyleProperty::Pointer styleProperty = dynamic_cast< PlanarFigureControlPointStyleProperty* >( node->GetProperty( "planarfigure.controlpointshape" ) ); if ( styleProperty.IsNotNull() ) { m_ControlPointShape = styleProperty->GetShape(); } //Set default color and opacity //If property "planarfigure.default.*.color" exists, then use that color. Otherwise global "color" property is used. if( !node->GetColor( m_LineColor[PF_DEFAULT], NULL, "planarfigure.default.line.color")) { node->GetColor( m_LineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.line.opacity", m_LineOpacity[PF_DEFAULT] ); if( !node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "planarfigure.default.outline.color")) { node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.outline.opacity", m_OutlineOpacity[PF_DEFAULT] ); if( !node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "planarfigure.default.helperline.color")) { node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "color" ); } node->GetFloatProperty( "planarfigure.default.helperline.opacity", m_HelperlineOpacity[PF_DEFAULT] ); node->GetColor( m_MarkerlineColor[PF_DEFAULT], NULL, "planarfigure.default.markerline.color" ); node->GetFloatProperty( "planarfigure.default.markerline.opacity", m_MarkerlineOpacity[PF_DEFAULT] ); node->GetColor( m_MarkerColor[PF_DEFAULT], NULL, "planarfigure.default.marker.color" ); node->GetFloatProperty( "planarfigure.default.marker.opacity", m_MarkerOpacity[PF_DEFAULT] ); //Set hover color and opacity node->GetColor( m_LineColor[PF_HOVER], NULL, "planarfigure.hover.line.color" ); node->GetFloatProperty( "planarfigure.hover.line.opacity", m_LineOpacity[PF_HOVER] ); node->GetColor( m_OutlineColor[PF_HOVER], NULL, "planarfigure.hover.outline.color" ); node->GetFloatProperty( "planarfigure.hover.outline.opacity", m_OutlineOpacity[PF_HOVER] ); node->GetColor( m_HelperlineColor[PF_HOVER], NULL, "planarfigure.hover.helperline.color" ); node->GetFloatProperty( "planarfigure.hover.helperline.opacity", m_HelperlineOpacity[PF_HOVER] ); node->GetColor( m_MarkerlineColor[PF_HOVER], NULL, "planarfigure.hover.markerline.color" ); node->GetFloatProperty( "planarfigure.hover.markerline.opacity", m_MarkerlineOpacity[PF_HOVER] ); node->GetColor( m_MarkerColor[PF_HOVER], NULL, "planarfigure.hover.marker.color" ); node->GetFloatProperty( "planarfigure.hover.marker.opacity", m_MarkerOpacity[PF_HOVER] ); //Set selected color and opacity node->GetColor( m_LineColor[PF_SELECTED], NULL, "planarfigure.selected.line.color" ); node->GetFloatProperty( "planarfigure.selected.line.opacity", m_LineOpacity[PF_SELECTED] ); node->GetColor( m_OutlineColor[PF_SELECTED], NULL, "planarfigure.selected.outline.color" ); node->GetFloatProperty( "planarfigure.selected.outline.opacity", m_OutlineOpacity[PF_SELECTED] ); node->GetColor( m_HelperlineColor[PF_SELECTED], NULL, "planarfigure.selected.helperline.color" ); node->GetFloatProperty( "planarfigure.selected.helperline.opacity", m_HelperlineOpacity[PF_SELECTED] ); node->GetColor( m_MarkerlineColor[PF_SELECTED], NULL, "planarfigure.selected.markerline.color" ); node->GetFloatProperty( "planarfigure.selected.markerline.opacity", m_MarkerlineOpacity[PF_SELECTED] ); node->GetColor( m_MarkerColor[PF_SELECTED], NULL, "planarfigure.selected.marker.color" ); node->GetFloatProperty( "planarfigure.selected.marker.opacity", m_MarkerOpacity[PF_SELECTED] ); //adapt opacity values to global "opacity" property for( unsigned int i = 0; i < PF_COUNT; ++i ) { m_LineOpacity[i] *= globalOpacity; m_OutlineOpacity[i] *= globalOpacity; m_HelperlineOpacity[i] *= globalOpacity; m_MarkerlineOpacity[i] *= globalOpacity; m_MarkerOpacity[i] *= globalOpacity; } } void mitk::PlanarFigureMapper2D::SetDefaultProperties( mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite ) { node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite ); //node->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); //node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); //node->AddProperty( "planarfigure.ishovering", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawoutline", mitk::BoolProperty::New(true) ); //node->AddProperty( "planarfigure.drawquantities", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawshadow", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawcontrolpoints", mitk::BoolProperty::New(true) ); node->AddProperty( "planarfigure.drawname", mitk::BoolProperty::New(true) ); + node->AddProperty( "planarfigure.drawdashed", mitk::BoolProperty::New(false) ); + node->AddProperty("planarfigure.line.width", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.outline.width", mitk::FloatProperty::New(2.0) ); node->AddProperty("planarfigure.helperline.width", mitk::FloatProperty::New(2.0) ); node->AddProperty( "planarfigure.default.line.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.outline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.helperline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); node->AddProperty( "planarfigure.default.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(1.0,1.0,1.0) ); node->AddProperty( "planarfigure.default.marker.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.line.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.outline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.helperline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.markerline.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.hover.marker.color", mitk::ColorProperty::New(0.0,1.0,0.0) ); node->AddProperty( "planarfigure.hover.marker.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.line.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.outline.opacity", mitk::FloatProperty::New(1.0)); node->AddProperty( "planarfigure.selected.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.helperline.opacity",mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.markerline.opacity", mitk::FloatProperty::New(1.0) ); node->AddProperty( "planarfigure.selected.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) ); node->AddProperty( "planarfigure.selected.marker.opacity",mitk::FloatProperty::New(1.0)); } diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h index cac9489522..48538220b1 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h @@ -1,244 +1,245 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITK_PLANAR_FIGURE_MAPPER_2D_H_ #define MITK_PLANAR_FIGURE_MAPPER_2D_H_ #include "mitkCommon.h" #include "PlanarFigureExports.h" #include "mitkGLMapper.h" #include "mitkPlanarFigure.h" #include "mitkPlanarFigureControlPointStyleProperty.h" namespace mitk { class BaseRenderer; class Contour; /** * \brief OpenGL-based mapper to render display sub-class instances of mitk::PlanarFigure * * The appearance of planar figures can be configured through properties. If no properties are specified, * default values will be used. There are four elements a planar figure consists of: * *
    *
  1. "line": the main line segments of the planar figure (note: text is drawn in the same style) *
  2. "helperline": additional line segments of planar figures, such as arrow tips, arches of angles, etc. *
  3. "outline": background which is drawn behind the lines and helperlines of the planar figure (optional) *
  4. "marker": the markers (control points) of a planar figure *
  5. "markerline": the lines by which markers (control points) are surrounded *
* * In the following, all appearance-related planar figure properties are listed: * *
    *
  1. General properties for the planar figure *
      *
    • "planarfigure.drawoutline": if true, the "outline" lines is drawn *
    • "planarfigure.drawquantities": if true, the quantities (text) associated with the planar figure is drawn *
    • "planarfigure.drawname": if true, the name specified by the dataNode is drawn *
    • "planarfigure.drawshadow": if true, a black shadow is drawn around the planar figure *
    • "planarfigure.controlpointshape": style of the control points (enum) *
    *
  2. Line widths of planar figure elements *
      *
    • "planarfigure.line.width": width of "line" segments (float value, in mm) *
    • "planarfigure.shadow.widthmodifier": the width of the shadow is defined by width of the "line" * this modifier *
    • "planarfigure.outline.width": width of "outline" segments (float value, in mm) *
    • "planarfigure.helperline.width": width of "helperline" segments (float value, in mm) *
    *
  3. Color/opacity of planar figure elements in normal mode (unselected) *
      *
    • "planarfigure.default.line.color" *
    • "planarfigure.default.line.opacity" *
    • "planarfigure.default.outline.color" *
    • "planarfigure.default.outline.opacity" *
    • "planarfigure.default.helperline.color" *
    • "planarfigure.default.helperline.opacity" *
    • "planarfigure.default.markerline.color" *
    • "planarfigure.default.markerline.opacity" *
    • "planarfigure.default.marker.color" *
    • "planarfigure.default.marker.opacity" *
    *
  4. Color/opacity of planar figure elements in hover mode (mouse-over) *
      *
    • "planarfigure.hover.line.color" *
    • "planarfigure.hover.line.opacity" *
    • "planarfigure.hover.outline.color" *
    • "planarfigure.hover.outline.opacity" *
    • "planarfigure.hover.helperline.color" *
    • "planarfigure.hover.helperline.opacity" *
    • "planarfigure.hover.markerline.color" *
    • "planarfigure.hover.markerline.opacity" *
    • "planarfigure.hover.marker.color" *
    • "planarfigure.hover.marker.opacity" *
    *
  5. Color/opacity of planar figure elements in selected mode *
      *
    • "planarfigure.selected.line.color" *
    • "planarfigure.selected.line.opacity" *
    • "planarfigure.selected.outline.color" *
    • "planarfigure.selected.outline.opacity" *
    • "planarfigure.selected.helperline.color" *
    • "planarfigure.selected.helperline.opacity" *
    • "planarfigure.selected.markerline.color;" *
    • "planarfigure.selected.markerline.opacity" *
    • "planarfigure.selected.marker.color" *
    • "planarfigure.selected.marker.opacity" *
    *
* * \ingroup Mapper */ class PlanarFigure_EXPORT PlanarFigureMapper2D : public GLMapper { public: mitkClassMacro(PlanarFigureMapper2D, GLMapper); itkNewMacro(Self); /** * reimplemented from Baseclass */ virtual void Paint(BaseRenderer * renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: enum PlanarFigureDisplayMode { PF_DEFAULT = 0, PF_HOVER = 1, PF_SELECTED = 2, PF_COUNT = 3 //helper variable }; PlanarFigureMapper2D(); virtual ~PlanarFigureMapper2D(); void TransformObjectToDisplay( const mitk::Point2D &point2D, mitk::Point2D &displayPoint, const mitk::Geometry2D *objectGeometry, const mitk::Geometry2D *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ); void DrawMarker( const mitk::Point2D &point, float* lineColor, float lineOpacity, float* markerColor, float markerOpacity, float lineWidth, PlanarFigureControlPointStyleProperty::Shape shape, const mitk::Geometry2D *objectGeometry, const mitk::Geometry2D *rendererGeometry, const mitk::DisplayGeometry *displayGeometry ); void PaintPolyLine( mitk::PlanarFigure::PolyLineType vertices, bool closed, float* color, float opacity, float lineWidth, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry); void DrawMainLines( mitk::PlanarFigure* figure, float* color, float opacity, bool drawShadow, float lineWidth, float shadowWidthFactor, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry) ; void DrawHelperLines( mitk::PlanarFigure* figure, float* color, float opacity, bool drawShadow, float lineWidth, float shadowWidthFactor, Point2D& firstPoint, const Geometry2D* planarFigureGeometry2D, const Geometry2D* rendererGeometry2D, const DisplayGeometry* displayGeometry) ; void InitializeDefaultPlanarFigureProperties(); void InitializePlanarFigurePropertiesFromDataNode( const mitk::DataNode* node ); void SetColorProperty( float property[3][3], PlanarFigureDisplayMode mode, float red, float green, float blue ) { property[mode][0] = red; property[mode][1] = green; property[mode][2] = blue; } void SetFloatProperty( float* property, PlanarFigureDisplayMode mode, float value ) { property[mode] = value; } private: bool m_IsSelected; bool m_IsHovering; bool m_DrawOutline; bool m_DrawQuantities; bool m_DrawShadow; bool m_DrawControlPoints; bool m_DrawName; + bool m_DrawDashed; // the width of the shadow is defined as 'm_LineWidth * m_ShadowWidthFactor' float m_LineWidth; float m_ShadowWidthFactor; float m_OutlineWidth; float m_HelperlineWidth; float m_PointWidth; PlanarFigureControlPointStyleProperty::Shape m_ControlPointShape; float m_LineColor[3][3]; float m_LineOpacity[3]; float m_OutlineColor[3][3]; float m_OutlineOpacity[3]; float m_HelperlineColor[3][3]; float m_HelperlineOpacity[3]; float m_MarkerlineColor[3][3]; float m_MarkerlineOpacity[3]; float m_MarkerColor[3][3]; float m_MarkerOpacity[3]; }; } // namespace mitk #endif /* MITK_PLANAR_FIGURE_MAPPER_2D_H_ */