diff --git a/Core/Code/Rendering/mitkGLMapper2D.cpp b/Core/Code/Rendering/mitkGLMapper.cpp similarity index 56% rename from Core/Code/Rendering/mitkGLMapper2D.cpp rename to Core/Code/Rendering/mitkGLMapper.cpp index 8c02c43300..ad6673c2b9 100644 --- a/Core/Code/Rendering/mitkGLMapper2D.cpp +++ b/Core/Code/Rendering/mitkGLMapper.cpp @@ -1,61 +1,56 @@ /*=================================================================== 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 "mitkGL.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" -mitk::GLMapper2D::GLMapper2D() -{ +mitk::GLMapper::GLMapper() +{ } - -mitk::GLMapper2D::~GLMapper2D() +mitk::GLMapper::~GLMapper() { } -void mitk::GLMapper2D::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer) +void mitk::GLMapper::MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType /* type */) { - if(IsVisible(renderer)==false) - return; + bool visible = true; - Paint(renderer); -} -void mitk::GLMapper2D::MitkRenderTranslucentGeometry(mitk::BaseRenderer* /*renderer*/) -{ + GetDataNode()->GetVisibility(visible, renderer, "visible"); -} -void mitk::GLMapper2D::MitkRenderOverlay(mitk::BaseRenderer* /*renderer*/) -{ + if(!visible) + return; + Paint(renderer); } -void mitk::GLMapper2D::MitkRenderVolumetricGeometry(mitk::BaseRenderer* /*renderer*/) +bool mitk::GLMapper::IsVtkBased() const { - + return false; } -void mitk::GLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer) +void mitk::GLMapper::ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor) { float rgba[4]={1.0f,1.0f,1.0f,1.0f}; // check for color prop and use it for rendering if it exists - GetColor(rgba, renderer); + GetDataNode()->GetColor(rgba, renderer, "color"); // check for opacity prop and use it for rendering if it exists - GetOpacity(rgba[3], renderer); + GetDataNode()->GetOpacity(rgba[3], renderer, "opacity"); glColor4fv(rgba); } diff --git a/Core/Code/Rendering/mitkGLMapper.h b/Core/Code/Rendering/mitkGLMapper.h new file mode 100644 index 0000000000..3f9fa755cd --- /dev/null +++ b/Core/Code/Rendering/mitkGLMapper.h @@ -0,0 +1,102 @@ +/*=================================================================== + +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 MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 +#define MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 + +#include +#include "mitkMapper.h" +#include "mitkBaseRenderer.h" +#include "mitkVtkPropRenderer.h" + +namespace mitk { + + +/** \brief Base class of all OpenGL-based mappers. +* +* Those must implement the abstract method Paint(BaseRenderer), which is called by +* method MitkRender(). +* The Paint() method should be used to paint into a renderer via OpenGL-drawing commands. +* The OpenGL context matrices (GL_MODELVIEWMATRIX/GL_PROJECTIONMATRIX) are preinitialized by +* the mitkVtkPropRenderer so that the origin of the 2D-coordinate system of the 2D render +* window is located in the lower left corner and has the width and height in display pixels +* of the respective renderwindow. The x-axis is horizontally oriented, while the y-axis is +* vertically oriented. The drawing commands are directly interpreted as display coordinates. +* ApplyColorAndOpacity() can be used in the subclasses to apply color and opacity properties +* read from the PropertyList. +* +* \ingroup Mapper +*/ +class MITK_CORE_EXPORT GLMapper : public Mapper +{ + public: + /** \brief Do the painting into the \a renderer */ + virtual void Paint(mitk::BaseRenderer *renderer) = 0; + + /** \brief Apply color and opacity properties read from the PropertyList + * @deprecated Use ApplyColorAndOpacityProperties(...) instead + */ + DEPRECATED(inline virtual void ApplyProperties(mitk::BaseRenderer* renderer) + { + ApplyColorAndOpacityProperties(renderer); + }); + + /** \brief Apply color and opacity properties read from the PropertyList. + * The actor is not used in the GLMappers. Called by mapper subclasses. + */ + virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL); + + + /** \brief Checks visibility and calls the paint method + * + * Note: The enumeration is disregarded, since OpenGL rendering only needs a + * single render pass. + */ + void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); + + /** \brief Returns whether this is a vtk-based mapper + * \return false, since all mappers deriving from this class are OpenGL mappers + * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead + */ + DEPRECATED( virtual bool IsVtkBased() const ); + + /** \brief Returns whether this mapper allows picking in the renderwindow + virtual bool IsPickable() const { return false; }*/ + + protected: + + /** constructor */ + GLMapper(); + + /** virtual destructor in order to derive from this class */ + virtual ~GLMapper(); + + private: + + /** copy constructor */ + GLMapper( const GLMapper &); + + /** assignment operator */ + GLMapper & operator=(const GLMapper &); + +}; + +} // namespace mitk + + + +#endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ diff --git a/Core/Code/Rendering/mitkGLMapper2D.h b/Core/Code/Rendering/mitkGLMapper2D.h index 07cfe071cc..d332e5ee60 100644 --- a/Core/Code/Rendering/mitkGLMapper2D.h +++ b/Core/Code/Rendering/mitkGLMapper2D.h @@ -1,66 +1,35 @@ /*=================================================================== 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 MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 #define MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 -#include -#include "mitkMapper2D.h" -#include "mitkBaseRenderer.h" +#include "mitkGLMapper.h" namespace mitk { -//##Documentation -//## @brief Base class of all OpenGL-based 2D-Mappers -//## -//## Those must implement the abstract method Paint(BaseRenderer). -//## @ingroup Mapper -class MITK_CORE_EXPORT GLMapper2D : public Mapper2D -{ - public: - //##Documentation - //## @brief Do the painting into the @a renderer - virtual void Paint(mitk::BaseRenderer *renderer) = 0; - - //##Documentation - //## @brief Apply color and opacity read from the PropertyList - virtual void ApplyProperties(mitk::BaseRenderer* renderer); - - void MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer); - void MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer); - void MitkRenderOverlay(mitk::BaseRenderer* renderer); - void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer); - - /** - * \brief Returns whether this is an vtk-based mapper - */ - virtual bool IsVtkBased() const { return false; } - - - - protected: - GLMapper2D(); - virtual ~GLMapper2D(); -}; + // typedef allows integration of mappers into the new mapper architecture + // @deprecated Use GLMapper instead + DEPRECATED(typedef GLMapper GLMapper2D); } // namespace mitk #endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ diff --git a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp index 9c93cd002b..dbf0bd9e86 100644 --- a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp +++ b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp @@ -1,665 +1,665 @@ /*=================================================================== 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 "mitkGL.h" #include "mitkGeometry2DDataMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkSmartPointerProperty.h" #include "mitkPlaneOrientationProperty.h" #include "mitkGeometry2DDataToSurfaceFilter.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkLine.h" #include "mitkNodePredicateDataType.h" #include "mitkResliceMethodProperty.h" mitk::Geometry2DDataMapper2D::Geometry2DDataMapper2D() : m_SurfaceMapper( NULL ), m_DataStorage(NULL), m_ParentNode(NULL), m_OtherGeometry2Ds(), m_RenderOrientationArrows( false ), m_ArrowOrientationPositive( true ) { } mitk::Geometry2DDataMapper2D::~Geometry2DDataMapper2D() { } const mitk::Geometry2DData* mitk::Geometry2DDataMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } - -void mitk::Geometry2DDataMapper2D::GenerateData() +void mitk::Geometry2DDataMapper2D::GenerateDataForRenderer(mitk::BaseRenderer* /* renderer */) { // collect all Geometry2DDatas accessible from the DataStorage m_OtherGeometry2Ds.clear(); if (m_DataStorage.IsNull()) return; mitk::NodePredicateDataType::Pointer p = mitk::NodePredicateDataType::New("Geometry2DData"); mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetDerivations(m_ParentNode, p, false); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { if(it->Value().IsNull()) continue; BaseData* data = it->Value()->GetData(); if (data == NULL) continue; Geometry2DData* geometry2dData = dynamic_cast(data); if(geometry2dData == NULL) continue; PlaneGeometry* planegeometry = dynamic_cast(geometry2dData->GetGeometry2D()); if (planegeometry != NULL) m_OtherGeometry2Ds.push_back(it->Value()); } } void mitk::Geometry2DDataMapper2D::Paint(BaseRenderer *renderer) { - if ( !this->IsVisible(renderer) ) - { - return; - } + bool visible = true; + + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) return; Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput()); // intersecting with ourself? if ( input.IsNull() || (this->GetInput()->GetGeometry2D() == renderer->GetCurrentWorldGeometry2D()) ) { return; // do nothing! } const PlaneGeometry *inputPlaneGeometry = dynamic_cast< const PlaneGeometry * >( input->GetGeometry2D() ); const PlaneGeometry *worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldGeometry2D() ); if ( worldPlaneGeometry && inputPlaneGeometry && inputPlaneGeometry->GetReferenceGeometry() ) { DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); const Geometry3D *referenceGeometry = inputPlaneGeometry->GetReferenceGeometry(); // calculate intersection of the plane data with the border of the // world geometry rectangle Point2D lineFrom, lineTo; typedef Geometry3D::TransformType TransformType; const TransformType *transform = dynamic_cast< const TransformType * >( referenceGeometry->GetIndexToWorldTransform() ); TransformType::Pointer inverseTransform = TransformType::New(); transform->GetInverse( inverseTransform ); Line3D crossLine, otherCrossLine; // Calculate the intersection line of the input plane with the world plane if ( worldPlaneGeometry->IntersectionLine( inputPlaneGeometry, crossLine ) ) { BoundingBox::PointType boundingBoxMin, boundingBoxMax; boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum(); boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum(); if(referenceGeometry->GetImageGeometry()) { for(unsigned int i = 0; i < 3; ++i) { boundingBoxMin[i]-=0.5; boundingBoxMax[i]-=0.5; } } crossLine.Transform( *inverseTransform ); Point3D point1, point2; // Then, clip this line with the (transformed) bounding box of the // reference geometry. if ( crossLine.BoxLineIntersection( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], crossLine.GetPoint(), crossLine.GetDirection(), point1, point2 ) == 2 ) { // Transform the resulting line start and end points into display // coordinates. worldPlaneGeometry->Map( transform->TransformPoint( point1 ), lineFrom ); worldPlaneGeometry->Map( transform->TransformPoint( point2 ), lineTo ); Line< ScalarType, 2 > mainLine, otherLine; Line< ScalarType, 2 > primaryHelperLine, secondaryHelperLine; mainLine.SetPoints( lineFrom, lineTo ); primaryHelperLine.SetPoints( lineFrom, lineTo ); secondaryHelperLine.SetPoints( lineFrom, lineTo ); displayGeometry->WorldToDisplay( lineFrom, lineFrom ); displayGeometry->WorldToDisplay( lineTo, lineTo ); ScalarType lengthInDisplayUnits = (lineTo - lineFrom).GetNorm(); Vector2D mainLineDirectionOrthogonal; mainLineDirectionOrthogonal[0] = -mainLine.GetDirection()[1]; mainLineDirectionOrthogonal[1] = mainLine.GetDirection()[0]; // lineParams stores the individual segments of the line, which are // separated by a gap each (to mark the intersection with another // displayed line) std::vector< ScalarType > mainLineParams; std::vector< ScalarType > primaryHelperLineParams; std::vector< ScalarType > secondaryHelperLineParams; mainLineParams.reserve( m_OtherGeometry2Ds.size() + 2 ); mainLineParams.push_back( 0.0 ); mainLineParams.push_back( 1.0 ); primaryHelperLineParams.reserve( m_OtherGeometry2Ds.size() + 2 ); primaryHelperLineParams.push_back( 0.0 ); primaryHelperLineParams.push_back( 1.0 ); secondaryHelperLineParams.reserve( m_OtherGeometry2Ds.size() + 2 ); secondaryHelperLineParams.push_back( 0.0 ); secondaryHelperLineParams.push_back( 1.0 ); // Now iterate through all other lines displayed in this window and // calculate the positions of intersection with the line to be // rendered; these positions will be stored in lineParams to form a // gap afterwards. NodesVectorType::iterator otherPlanesIt = m_OtherGeometry2Ds.begin(); NodesVectorType::iterator otherPlanesEnd = m_OtherGeometry2Ds.end(); //int mainLineThickSlicesMode = 0; int mainLineThickSlicesNum = 1; DataNode* dataNodeOfInputPlaneGeometry = NULL; // Now we have to find the DataNode that contains the inputPlaneGeometry // in order to determine the state of the thick-slice rendering while ( otherPlanesIt != otherPlanesEnd ) { PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( static_cast< Geometry2DData * >( (*otherPlanesIt)->GetData() )->GetGeometry2D() ); // if we have found the correct node if ( (otherPlane == inputPlaneGeometry) && worldPlaneGeometry->IntersectionLine( otherPlane, otherCrossLine ) ) { dataNodeOfInputPlaneGeometry = (*otherPlanesIt); // if( dataNodeOfInputPlaneGeometry ) // { // mainLineThickSlicesMode = this->DetermineThickSliceMode(dataNodeOfInputPlaneGeometry, mainLineThickSlicesNum); // } break; } otherPlanesIt++; } // if we did not find a dataNode for the inputPlaneGeometry there is nothing we can do from here if ( dataNodeOfInputPlaneGeometry == NULL ) return; // Determine if we should draw the area covered by the thick slicing, default is false. // This will also show the area of slices that do not have thick slice mode enabled bool showAreaOfThickSlicing = false; dataNodeOfInputPlaneGeometry->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing ); // get the normal of the inputPlaneGeometry Vector3D normal = inputPlaneGeometry->GetNormal(); // determine the pixelSpacing in that direction double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); // As the inputPlaneGeometry cuts through the center of the slice in the middle // we have to add 0.5 pixel in order to compensate. thickSliceDistance *= mainLineThickSlicesNum+0.5; // not the nicest place to do it, but we have the width of the visible bloc in MM here // so we store it in this fancy property dataNodeOfInputPlaneGeometry->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 ); if ( showAreaOfThickSlicing ) { // vectorToHelperLine defines how to reach the helperLine from the mainLine Vector2D vectorToHelperLine; vectorToHelperLine = mainLineDirectionOrthogonal; vectorToHelperLine.Normalize(); // got the right direction, so we multiply the width vectorToHelperLine *= thickSliceDistance; // and create the corresponding points primaryHelperLine.SetPoints( primaryHelperLine.GetPoint1() - vectorToHelperLine, primaryHelperLine.GetPoint2() - vectorToHelperLine ); secondaryHelperLine.SetPoints( secondaryHelperLine.GetPoint1() + vectorToHelperLine, secondaryHelperLine.GetPoint2() + vectorToHelperLine ); } //int otherLineThickSlicesMode = 0; int otherLineThickSlicesNum = 1; // by default, there is no gap for the helper lines ScalarType gapSize = 0.0; otherPlanesIt = m_OtherGeometry2Ds.begin(); while ( otherPlanesIt != otherPlanesEnd ) { PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >( static_cast< Geometry2DData * >( (*otherPlanesIt)->GetData() )->GetGeometry2D() ); // Just as with the original line, calculate the intersection with // the world geometry... if ( (otherPlane != inputPlaneGeometry) && worldPlaneGeometry->IntersectionLine( otherPlane, otherCrossLine ) ) { //otherLineThickSlicesMode = this->DetermineThickSliceMode((*otherPlanesIt), otherLineThickSlicesNum); Vector3D normal = otherPlane->GetNormal(); double otherLineThickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal ); otherLineThickSliceDistance *= (otherLineThickSlicesNum+0.5)*2; Point2D otherLineFrom, otherLineTo; // ... and clip the resulting line segment with the reference // geometry bounding box. otherCrossLine.Transform( *inverseTransform ); if ( otherCrossLine.BoxLineIntersection( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2], boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2], otherCrossLine.GetPoint(), otherCrossLine.GetDirection(), point1, point2 ) == 2 ) { worldPlaneGeometry->Map( transform->TransformPoint( point1 ), otherLineFrom ); worldPlaneGeometry->Map( transform->TransformPoint( point2 ), otherLineTo ); otherLine.SetPoints( otherLineFrom, otherLineTo ); // then we have to determine the gap position of the main line // by finding the position at which the two lines cross this->DetermineParametricCrossPositions( mainLine, otherLine, mainLineParams ); // if the other line is also in thick slice mode, we have to determine the // gapsize considering the width of that other line and the spacing in its direction if ( showAreaOfThickSlicing ) { Vector2D otherLineDirection = otherLine.GetDirection(); otherLineDirection.Normalize(); mainLineDirectionOrthogonal.Normalize(); // determine the gapsize gapSize = fabs( otherLineThickSliceDistance / ( otherLineDirection*mainLineDirectionOrthogonal ) ); gapSize = gapSize / displayGeometry->GetScaleFactorMMPerDisplayUnit(); // determine the gap positions for the helper lines as well this->DetermineParametricCrossPositions( primaryHelperLine, otherLine, primaryHelperLineParams ); this->DetermineParametricCrossPositions( secondaryHelperLine, otherLine, secondaryHelperLineParams ); } } } ++otherPlanesIt; } // If we have to draw the helperlines, the mainline will be drawn as a dashed line // with a fixed gapsize of 10 pixels this->DrawLine(renderer, lengthInDisplayUnits, mainLine, mainLineParams, inputPlaneGeometry, showAreaOfThickSlicing, 10.0 ); // If drawn, the helperlines are drawn as a solid line. The gapsize depends on the // width of the crossed line. if ( showAreaOfThickSlicing ) { this->DrawLine(renderer, lengthInDisplayUnits, primaryHelperLine, primaryHelperLineParams, inputPlaneGeometry, false, gapSize ); this->DrawLine(renderer, lengthInDisplayUnits, secondaryHelperLine, secondaryHelperLineParams, inputPlaneGeometry, false, gapSize ); } } } } else { Geometry2DDataToSurfaceFilter::Pointer surfaceCreator; SmartPointerProperty::Pointer surfacecreatorprop; surfacecreatorprop = dynamic_cast< SmartPointerProperty * >( GetDataNode()->GetProperty( "surfacegeometry", renderer)); if( (surfacecreatorprop.IsNull()) || (surfacecreatorprop->GetSmartPointer().IsNull()) || ((surfaceCreator = dynamic_cast< Geometry2DDataToSurfaceFilter * >( surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull()) ) { surfaceCreator = Geometry2DDataToSurfaceFilter::New(); surfacecreatorprop = SmartPointerProperty::New(surfaceCreator); surfaceCreator->PlaceByGeometryOn(); GetDataNode()->SetProperty( "surfacegeometry", surfacecreatorprop ); } surfaceCreator->SetInput( input ); // Clip the Geometry2D with the reference geometry bounds (if available) if ( input->GetGeometry2D()->HasReferenceGeometry() ) { surfaceCreator->SetBoundingBox( input->GetGeometry2D()->GetReferenceGeometry()->GetBoundingBox() ); } int res; bool usegeometryparametricbounds = true; if ( GetDataNode()->GetIntProperty("xresolution", res, renderer)) { surfaceCreator->SetXResolution(res); usegeometryparametricbounds=false; } if (GetDataNode()->GetIntProperty("yresolution", res, renderer)) { surfaceCreator->SetYResolution(res); usegeometryparametricbounds=false; } surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds); // Calculate the surface of the Geometry2D surfaceCreator->Update(); if (m_SurfaceMapper.IsNull()) { m_SurfaceMapper=SurfaceGLMapper2D::New(); } m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput()); m_SurfaceMapper->SetDataNode(GetDataNode()); m_SurfaceMapper->Paint(renderer); } } void mitk::Geometry2DDataMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint, const mitk::PlaneGeometry *planeGeometry, const mitk::PlaneGeometry *rendererPlaneGeometry, const mitk::DisplayGeometry *displayGeometry, bool positiveOrientation ) { // Draw arrows to indicate plane orientation // Vector along line Vector2D v1 = innerPoint - outerPoint; v1.Normalize(); v1 *= 7.0; // Orthogonal vector Vector2D v2; v2[0] = v1[1]; v2[1] = -v1[0]; // Calculate triangle tip for one side and project it back into world // coordinates to determine whether it is above or below the plane Point2D worldPoint2D; Point3D worldPoint; displayGeometry->DisplayToWorld( outerPoint + v1 + v2, worldPoint2D ); rendererPlaneGeometry->Map( worldPoint2D, worldPoint ); // Initialize remaining triangle coordinates accordingly // (above/below state is XOR'ed with orientation flag) Point2D p1 = outerPoint + v1 * 2.0; Point2D p2 = outerPoint + v1 + ((positiveOrientation ^ planeGeometry->IsAbove( worldPoint )) ? v2 : -v2); // Draw the arrow (triangle) glBegin( GL_TRIANGLES ); glVertex2f( outerPoint[0], outerPoint[1] ); glVertex2f( p1[0], p1[1] ); glVertex2f( p2[0], p2[1] ); glEnd(); } -void mitk::Geometry2DDataMapper2D::ApplyProperties( BaseRenderer *renderer ) +void mitk::Geometry2DDataMapper2D::ApplyAllProperties( BaseRenderer *renderer ) { - Superclass::ApplyProperties(renderer); + Superclass::ApplyColorAndOpacityProperties(renderer); PlaneOrientationProperty* decorationProperty; this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer ); if ( decorationProperty != NULL ) { if ( decorationProperty->GetPlaneDecoration() == PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION ) { m_RenderOrientationArrows = true; m_ArrowOrientationPositive = true; } else if ( decorationProperty->GetPlaneDecoration() == PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION ) { m_RenderOrientationArrows = true; m_ArrowOrientationPositive = false; } else { m_RenderOrientationArrows = false; } } } void mitk::Geometry2DDataMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent ) { if (ds.IsNotNull()) { m_DataStorage = ds; } if (parent.IsNotNull()) { m_ParentNode = parent; } } void mitk::Geometry2DDataMapper2D::DrawLine( BaseRenderer* renderer, ScalarType lengthInDisplayUnits, Line &line, std::vector &gapPositions, const PlaneGeometry* inputPlaneGeometry, bool drawDashed, ScalarType gapSizeInPixel ) { DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry(); const PlaneGeometry *worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldGeometry2D() ); // Apply color and opacity read from the PropertyList. - this->ApplyProperties( renderer ); + this->ApplyAllProperties( renderer ); ScalarType gapSizeInParamUnits = 1.0 / lengthInDisplayUnits * gapSizeInPixel; std::sort( gapPositions.begin(), gapPositions.end() ); Point2D p1, p2; ScalarType p1Param, p2Param; p1Param = gapPositions[0]; p1 = line.GetPoint( p1Param ); displayGeometry->WorldToDisplay( p1, p1 ); //Workaround to show the crosshair always on top of a 2D render window //The image is usually located at depth = 0 or negative depth values, and thus, //the crosshair with depth = 1 is always on top. float depthPosition = 1.0f; if ( drawDashed ) { glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xF0F0); } glEnable(GL_DEPTH_TEST); // Iterate over all line segments and display each, with a gap // in between. unsigned int i, preLastLineParam = gapPositions.size() - 1; for ( i = 1; i < preLastLineParam; ++i ) { p2Param = gapPositions[i] - gapSizeInParamUnits * 0.5; p2 = line.GetPoint( p2Param ); if ( p2Param > p1Param ) { // Convert intersection points (until now mm) to display // coordinates (units). displayGeometry->WorldToDisplay( p2, p2 ); // draw glBegin (GL_LINES); glVertex3f(p1[0],p1[1], depthPosition); glVertex3f(p2[0],p2[1], depthPosition); glEnd (); if ( (i == 1) && (m_RenderOrientationArrows) ) { // Draw orientation arrow for first line segment this->DrawOrientationArrow( p1, p2, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); } } p1Param = p2Param + gapSizeInParamUnits; p1 = line.GetPoint( p1Param ); displayGeometry->WorldToDisplay( p1, p1 ); } // Draw last line segment p2Param = gapPositions[i]; p2 = line.GetPoint( p2Param ); displayGeometry->WorldToDisplay( p2, p2 ); glBegin( GL_LINES ); glVertex3f( p1[0], p1[1], depthPosition); glVertex3f( p2[0], p2[1], depthPosition); glEnd(); if ( drawDashed ) { glDisable(GL_LINE_STIPPLE); } // Draw orientation arrows if ( m_RenderOrientationArrows ) { this->DrawOrientationArrow( p2, p1, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); if ( preLastLineParam < 2 ) { // If we only have one line segment, draw other arrow, too this->DrawOrientationArrow( p1, p2, inputPlaneGeometry, worldPlaneGeometry, displayGeometry, m_ArrowOrientationPositive ); } } } int mitk::Geometry2DDataMapper2D::DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ) { int thickSlicesMode = 0; // determine the state and the extend of the thick-slice mode mitk::ResliceMethodProperty *resliceMethodEnumProperty=0; if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty ) thickSlicesMode = resliceMethodEnumProperty->GetValueAsId(); IntProperty *intProperty=0; if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) { thickSlicesNum = intProperty->GetValue(); if(thickSlicesNum < 1) thickSlicesNum=0; if(thickSlicesNum > 10) thickSlicesNum=10; } if ( thickSlicesMode == 0 ) thickSlicesNum = 0; return thickSlicesMode; } void mitk::Geometry2DDataMapper2D::DetermineParametricCrossPositions( Line< mitk::ScalarType, 2 > &mainLine, Line< mitk::ScalarType, 2 > &otherLine, std::vector< mitk::ScalarType > &crossPositions ) { Vector2D direction, dOrth; // By means of the dot product, calculate the gap position as // parametric value in the range [0, 1] direction = otherLine.GetDirection(); dOrth[0] = -direction[1]; dOrth[1] = direction[0]; ScalarType gapPosition = ( otherLine.GetPoint1() - mainLine.GetPoint1() ) * dOrth; ScalarType norm = mainLine.GetDirection() * dOrth; if ( fabs( norm ) > eps ) { gapPosition /= norm; if ( (gapPosition > 0.0) && (gapPosition < 1.0) ) { crossPositions.push_back(gapPosition); } } } diff --git a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h index e39c0891b4..ff6e8a26ec 100644 --- a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h +++ b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h @@ -1,122 +1,121 @@ /*=================================================================== 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 MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB #define MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB #include -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkDataStorage.h" #include "mitkDataNode.h" #include "mitkWeakPointer.h" namespace mitk { class BaseRenderer; /** * \brief OpenGL-based mapper to display a Geometry2D in a 2D window * * Currently implemented for mapping on PlaneGeometry. * The result is normally a line. An important usage of this class is to show * the orientation of the slices displayed in other 2D windows. * * * Properties that can be set and influence the Geometry2DDataMapper2D are: * * - \b "PlaneOrientationProperty": (PlaneOrientationProperty) * \todo implement for AbstractTransformGeometry. * \ingroup Mapper */ -class MITK_CORE_EXPORT Geometry2DDataMapper2D : public GLMapper2D +class MITK_CORE_EXPORT Geometry2DDataMapper2D : public GLMapper { public: - mitkClassMacro(Geometry2DDataMapper2D, GLMapper2D); + mitkClassMacro(Geometry2DDataMapper2D, GLMapper); itkNewMacro(Self); /** * \brief Get the Geometry2DData to map */ const Geometry2DData *GetInput(); virtual void Paint( BaseRenderer *renderer ); virtual void SetDatastorageAndGeometryBaseNode(mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent); /** Applies properties specific to this mapper */ - virtual void ApplyProperties( BaseRenderer *renderer ); + virtual void ApplyAllProperties( BaseRenderer *renderer ); protected: Geometry2DDataMapper2D(); virtual ~Geometry2DDataMapper2D(); - virtual void GenerateData(); - + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); /** * \brief Returns the thick slice mode for the given datanode. * * This method returns the value of the 'reslice.thickslices' property for * the given datanode. * '0': thick slice mode disabled * '1': thick slice mode enabled * * The variable 'thickSlicesNum' contains the value of the 'reslice.thickslices.num' * property that defines how many slices are shown at once. */ int DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum ); /** * \brief Determines the cross position of two lines and stores them as parametric coordinates * * This method determines the parametric position at which a line 'otherLine' crosses another line * 'mainLine'. The result is stored in 'crossPositions'. */ void DetermineParametricCrossPositions( Line &mainLine, Line &otherLine, std::vector &crossPositions ); void DrawLine( BaseRenderer * renderer, ScalarType lengthInDisplayUnits, Line< ScalarType, 2 > &line, std::vector< ScalarType > &gapPositions, const PlaneGeometry * inputPlaneGeometry, bool drawDashed, ScalarType gapSizeInPixel ); void DrawOrientationArrow( Point2D &outerPoint, Point2D &innerPoint, const PlaneGeometry *planeGeometry, const PlaneGeometry *rendererPlaneGeometry, const DisplayGeometry *displayGeometry, bool positiveOrientation = true ); SurfaceGLMapper2D::Pointer m_SurfaceMapper; mitk::WeakPointer m_DataStorage; ///< DataStorage that will be searched for sub nodes DataNode::Pointer m_ParentNode; ///< parent node that will be used to search for sub nodes typedef std::vector NodesVectorType; NodesVectorType m_OtherGeometry2Ds; bool m_RenderOrientationArrows; bool m_ArrowOrientationPositive; }; } // namespace mitk #endif /* MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB */ diff --git a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp index 04ebb884e5..514fa1ac41 100644 --- a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp @@ -1,578 +1,581 @@ /*=================================================================== 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 "mitkGeometry2DDataVtkMapper3D.h" #include "mitkImageVtkMapper2D.h" #include "mitkSmartPointerProperty.h" #include "mitkSurface.h" #include "mitkVtkRepresentationProperty.h" #include "mitkWeakPointerProperty.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateOr.h" #include "vtkNeverTranslucentTexture.h" #include "vtkMitkLevelWindowFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace mitk { Geometry2DDataVtkMapper3D::Geometry2DDataVtkMapper3D() : m_NormalsActorAdded(false), m_DataStorage(NULL) { m_EdgeTuber = vtkTubeFilter::New(); m_EdgeMapper = vtkPolyDataMapper::New(); m_SurfaceCreator = Geometry2DDataToSurfaceFilter::New(); m_SurfaceCreatorBoundingBox = BoundingBox::New(); m_SurfaceCreatorPointsContainer = BoundingBox::PointsContainer::New(); m_Edges = vtkFeatureEdges::New(); m_Edges->BoundaryEdgesOn(); m_Edges->FeatureEdgesOff(); m_Edges->NonManifoldEdgesOff(); m_Edges->ManifoldEdgesOff(); m_EdgeTransformer = vtkTransformPolyDataFilter::New(); m_NormalsTransformer = vtkTransformPolyDataFilter::New(); m_EdgeActor = vtkActor::New(); m_BackgroundMapper = vtkPolyDataMapper::New(); m_BackgroundActor = vtkActor::New(); m_Prop3DAssembly = vtkAssembly::New(); m_ImageAssembly = vtkAssembly::New(); m_SurfaceCreatorBoundingBox->SetPoints( m_SurfaceCreatorPointsContainer ); m_Cleaner = vtkCleanPolyData::New(); m_Cleaner->PieceInvariantOn(); m_Cleaner->ConvertLinesToPointsOn(); m_Cleaner->ConvertPolysToLinesOn(); m_Cleaner->ConvertStripsToPolysOn(); m_Cleaner->PointMergingOn(); // Make sure that the FeatureEdge algorithm is initialized with a "valid" // (though empty) input vtkPolyData *emptyPolyData = vtkPolyData::New(); m_Cleaner->SetInput( emptyPolyData ); emptyPolyData->Delete(); m_Edges->SetInput(m_Cleaner->GetOutput()); m_EdgeTransformer->SetInput( m_Edges->GetOutput() ); m_EdgeTuber->SetInput( m_EdgeTransformer->GetOutput() ); m_EdgeTuber->SetVaryRadiusToVaryRadiusOff(); m_EdgeTuber->SetNumberOfSides( 12 ); m_EdgeTuber->CappingOn(); m_EdgeMapper->SetInput( m_EdgeTuber->GetOutput() ); m_EdgeMapper->ScalarVisibilityOff(); m_BackgroundMapper->SetInput(emptyPolyData); m_EdgeActor->SetMapper( m_EdgeMapper ); m_BackgroundActor->GetProperty()->SetAmbient( 0.5 ); m_BackgroundActor->GetProperty()->SetColor( 0.0, 0.0, 0.0 ); m_BackgroundActor->GetProperty()->SetOpacity( 0.0 ); m_BackgroundActor->SetMapper( m_BackgroundMapper ); vtkProperty * backfaceProperty = m_BackgroundActor->MakeProperty(); backfaceProperty->SetColor( 0.0, 0.0, 0.0 ); m_BackgroundActor->SetBackfaceProperty( backfaceProperty ); backfaceProperty->Delete(); m_FrontHedgeHog = vtkHedgeHog::New(); m_BackHedgeHog = vtkHedgeHog::New(); m_FrontNormalsMapper = vtkPolyDataMapper::New(); m_FrontNormalsMapper->SetInput( m_FrontHedgeHog->GetOutput() ); m_BackNormalsMapper = vtkPolyDataMapper::New(); m_Prop3DAssembly->AddPart( m_EdgeActor ); m_Prop3DAssembly->AddPart( m_ImageAssembly ); m_FrontNormalsActor = vtkActor::New(); m_FrontNormalsActor->SetMapper(m_FrontNormalsMapper); m_BackNormalsActor = vtkActor::New(); m_BackNormalsActor->SetMapper(m_BackNormalsMapper); m_ImageMapperDeletedCommand = MemberCommandType::New(); m_ImageMapperDeletedCommand->SetCallbackFunction( this, &Geometry2DDataVtkMapper3D::ImageMapperDeletedCallback ); } Geometry2DDataVtkMapper3D::~Geometry2DDataVtkMapper3D() { m_ImageAssembly->Delete(); m_Prop3DAssembly->Delete(); m_EdgeTuber->Delete(); m_EdgeMapper->Delete(); m_EdgeTransformer->Delete(); m_Cleaner->Delete(); m_Edges->Delete(); m_NormalsTransformer->Delete(); m_EdgeActor->Delete(); m_BackgroundMapper->Delete(); m_BackgroundActor->Delete(); m_FrontNormalsMapper->Delete(); m_FrontNormalsActor->Delete(); m_FrontHedgeHog->Delete(); m_BackNormalsMapper->Delete(); m_BackNormalsActor->Delete(); m_BackHedgeHog->Delete(); // Delete entries in m_ImageActors list one by one m_ImageActors.clear(); m_DataStorage = NULL; } vtkProp* Geometry2DDataVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { if ( (this->GetDataNode() != NULL ) && (m_ImageAssembly != NULL) ) { // Do not transform the entire Prop3D assembly, but only the image part // here. The colored frame is transformed elsewhere (via m_EdgeTransformer), // since only vertices should be transformed there, not the poly data // itself, to avoid distortion for anisotropic datasets. m_ImageAssembly->SetUserTransform( this->GetDataNode()->GetVtkTransform() ); } return m_Prop3DAssembly; } void Geometry2DDataVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { m_ImageAssembly->SetUserTransform( this->GetDataNode()->GetVtkTransform(this->GetTimestep()) ); } const Geometry2DData* Geometry2DDataVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } void Geometry2DDataVtkMapper3D::SetDataStorageForTexture(mitk::DataStorage* storage) { if(storage != NULL && m_DataStorage != storage ) { m_DataStorage = storage; this->Modified(); } } void Geometry2DDataVtkMapper3D::ImageMapperDeletedCallback( itk::Object *caller, const itk::EventObject& /*event*/ ) { ImageVtkMapper2D *imageMapper = dynamic_cast< ImageVtkMapper2D * >( caller ); if ( (imageMapper != NULL) ) { if ( m_ImageActors.count( imageMapper ) > 0) { m_ImageActors[imageMapper].m_Sender = NULL; // sender is already destroying itself m_ImageActors.erase( imageMapper ); } } } void Geometry2DDataVtkMapper3D::GenerateDataForRenderer(BaseRenderer* renderer) { SetVtkMapperImmediateModeRendering(m_EdgeMapper); SetVtkMapperImmediateModeRendering(m_BackgroundMapper); // Remove all actors from the assembly, and re-initialize it with the // edge actor m_ImageAssembly->GetParts()->RemoveAllItems(); - if ( !this->IsVisible(renderer) ) + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) { // visibility has explicitly to be set in the single actors // due to problems when using cell picking: // even if the assembly is invisible, the renderer contains // references to the assemblies parts. During picking the // visibility of each part is checked, and not only for the // whole assembly. m_ImageAssembly->VisibilityOff(); m_EdgeActor->VisibilityOff(); return; } // visibility has explicitly to be set in the single actors // due to problems when using cell picking: // even if the assembly is invisible, the renderer contains // references to the assemblies parts. During picking the // visibility of each part is checked, and not only for the // whole assembly. m_ImageAssembly->VisibilityOn(); m_EdgeActor->VisibilityOn(); Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput()); if (input.IsNotNull() && (input->GetGeometry2D() != NULL)) { SmartPointerProperty::Pointer surfacecreatorprop; surfacecreatorprop = dynamic_cast< SmartPointerProperty * >(GetDataNode()->GetProperty("surfacegeometry", renderer)); if ( (surfacecreatorprop.IsNull()) || (surfacecreatorprop->GetSmartPointer().IsNull()) || ((m_SurfaceCreator = dynamic_cast (surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull() ) ) { m_SurfaceCreator->PlaceByGeometryOn(); surfacecreatorprop = SmartPointerProperty::New( m_SurfaceCreator ); GetDataNode()->SetProperty("surfacegeometry", surfacecreatorprop); } m_SurfaceCreator->SetInput(input); int res; if (GetDataNode()->GetIntProperty("xresolution", res, renderer)) { m_SurfaceCreator->SetXResolution(res); } if (GetDataNode()->GetIntProperty("yresolution", res, renderer)) { m_SurfaceCreator->SetYResolution(res); } double tubeRadius = 1.0; // Radius of tubular edge surrounding plane // Clip the Geometry2D with the reference geometry bounds (if available) if ( input->GetGeometry2D()->HasReferenceGeometry() ) { Geometry3D *referenceGeometry = input->GetGeometry2D()->GetReferenceGeometry(); BoundingBox::PointType boundingBoxMin, boundingBoxMax; boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum(); boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum(); if ( referenceGeometry->GetImageGeometry() ) { for ( unsigned int i = 0; i < 3; ++i ) { boundingBoxMin[i] -= 0.5; boundingBoxMax[i] -= 0.5; } } m_SurfaceCreatorPointsContainer->CreateElementAt( 0 ) = boundingBoxMin; m_SurfaceCreatorPointsContainer->CreateElementAt( 1 ) = boundingBoxMax; m_SurfaceCreatorBoundingBox->ComputeBoundingBox(); m_SurfaceCreator->SetBoundingBox( m_SurfaceCreatorBoundingBox ); tubeRadius = referenceGeometry->GetDiagonalLength() / 450.0; } // If no reference geometry is available, clip with the current global // bounds else if (m_DataStorage.IsNotNull()) { m_SurfaceCreator->SetBoundingBox(m_DataStorage->ComputeVisibleBoundingBox(NULL, "includeInBoundingBox")); tubeRadius = sqrt( m_SurfaceCreator->GetBoundingBox()->GetDiagonalLength2() ) / 450.0; } // Calculate the surface of the Geometry2D m_SurfaceCreator->Update(); Surface *surface = m_SurfaceCreator->GetOutput(); // Check if there's something to display, otherwise return if ( (surface->GetVtkPolyData() == 0 ) || (surface->GetVtkPolyData()->GetNumberOfCells() == 0) ) { m_ImageAssembly->VisibilityOff(); return; } // add a graphical representation of the surface normals if requested DataNode* node = this->GetDataNode(); bool displayNormals = false; bool colorTwoSides = false; bool invertNormals = false; node->GetBoolProperty("draw normals 3D", displayNormals, renderer); node->GetBoolProperty("color two sides", colorTwoSides, renderer); node->GetBoolProperty("invert normals", invertNormals, renderer); //if we want to draw the display normals or render two sides we have to get the colors if( displayNormals || colorTwoSides ) { //get colors float frontColor[3] = { 0.0, 0.0, 1.0 }; node->GetColor( frontColor, renderer, "front color" ); float backColor[3] = { 1.0, 0.0, 0.0 }; node->GetColor( backColor, renderer, "back color" ); if ( displayNormals ) { m_NormalsTransformer->SetInput( surface->GetVtkPolyData() ); m_NormalsTransformer->SetTransform(node->GetVtkTransform(this->GetTimestep()) ); m_FrontHedgeHog->SetInput( m_NormalsTransformer->GetOutput() ); m_FrontHedgeHog->SetVectorModeToUseNormal(); m_FrontHedgeHog->SetScaleFactor( invertNormals ? 1.0 : -1.0 ); m_FrontNormalsActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] ); m_BackHedgeHog->SetInput( m_NormalsTransformer->GetOutput() ); m_BackHedgeHog->SetVectorModeToUseNormal(); m_BackHedgeHog->SetScaleFactor( invertNormals ? -1.0 : 1.0 ); m_BackNormalsActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] ); //if there is no actor added yet, add one if ( !m_NormalsActorAdded ) { m_Prop3DAssembly->AddPart( m_FrontNormalsActor ); m_Prop3DAssembly->AddPart( m_BackNormalsActor ); m_NormalsActorAdded = true; } } //if we don't want to display normals AND there is an actor added remove the actor else if ( m_NormalsActorAdded ) { m_Prop3DAssembly->RemovePart( m_FrontNormalsActor ); m_Prop3DAssembly->RemovePart( m_BackNormalsActor ); m_NormalsActorAdded = false; } if ( colorTwoSides ) { if ( !invertNormals ) { m_BackgroundActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] ); m_BackgroundActor->GetBackfaceProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] ); } else { m_BackgroundActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] ); m_BackgroundActor->GetBackfaceProperty()->SetColor( backColor[0], backColor[1], backColor[2] ); } } } // Add black background for all images (which may be transparent) m_BackgroundMapper->SetInput( surface->GetVtkPolyData() ); m_ImageAssembly->AddPart( m_BackgroundActor ); LayerSortedActorList layerSortedActors; // Traverse the data tree to find nodes resliced by ImageMapperGL2D mitk::NodePredicateOr::Pointer p = mitk::NodePredicateOr::New(); //use a predicate to get all data nodes which are "images" or inherit from mitk::Image mitk::TNodePredicateDataType< mitk::Image >::Pointer predicateAllImages = mitk::TNodePredicateDataType< mitk::Image >::New(); mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetSubset(predicateAllImages); //process all found images for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { DataNode *node = it->Value(); if (node != NULL) this->ProcessNode(node, renderer, surface, layerSortedActors); } // Add all image actors to the assembly, sorted according to // layer property LayerSortedActorList::iterator actorIt; for ( actorIt = layerSortedActors.begin(); actorIt != layerSortedActors.end(); ++actorIt ) { m_ImageAssembly->AddPart( actorIt->second ); } // Configurate the tube-shaped frame: size according to the surface // bounds, color as specified in the plane's properties vtkPolyData *surfacePolyData = surface->GetVtkPolyData(); m_Cleaner->SetInput(surfacePolyData); m_EdgeTransformer->SetTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) ); // Adjust the radius according to extent m_EdgeTuber->SetRadius( tubeRadius ); // Get the plane's color and set the tube properties accordingly ColorProperty::Pointer colorProperty; colorProperty = dynamic_cast(this->GetDataNode()->GetProperty( "color" )); if ( colorProperty.IsNotNull() ) { const Color& color = colorProperty->GetColor(); m_EdgeActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue()); } else { m_EdgeActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 ); } m_ImageAssembly->SetUserTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) ); } VtkRepresentationProperty* representationProperty; this->GetDataNode()->GetProperty(representationProperty, "material.representation", renderer); if ( representationProperty != NULL ) m_BackgroundActor->GetProperty()->SetRepresentation( representationProperty->GetVtkRepresentation() ); } void Geometry2DDataVtkMapper3D::ProcessNode( DataNode * node, BaseRenderer* renderer, Surface * surface, LayerSortedActorList &layerSortedActors ) { if ( node != NULL ) { //we need to get the information from the 2D mapper to render the texture on the 3D plane ImageVtkMapper2D *imageMapper = dynamic_cast< ImageVtkMapper2D * >( node->GetMapper(1) ); //GetMapper(1) provides the 2D mapper for the data node //if there is a 2D mapper, which is not the standard image mapper... if(!imageMapper && node->GetMapper(1)) { //... check if it is the composite mapper std::string cname(node->GetMapper(1)->GetNameOfClass()); if(!cname.compare("CompositeMapper")) //string.compare returns 0 if the two strings are equal. { //get the standard image mapper. //This is a special case in MITK and does only work for the CompositeMapper. imageMapper = dynamic_cast( node->GetMapper(3) ); } } if ( (node->IsVisible(renderer)) && imageMapper ) { WeakPointerProperty::Pointer rendererProp = dynamic_cast< WeakPointerProperty * >(GetDataNode()->GetPropertyList()->GetProperty("renderer")); if ( rendererProp.IsNotNull() ) { BaseRenderer::Pointer planeRenderer = dynamic_cast< BaseRenderer * >(rendererProp->GetWeakPointer().GetPointer()); // Retrieve and update image to be mapped const ImageVtkMapper2D::LocalStorage* localStorage = imageMapper->GetLocalStorage(planeRenderer); if ( planeRenderer.IsNotNull() ) { // perform update of imagemapper if needed (maybe the respective 2D renderwindow is not rendered/update before) imageMapper->Update(planeRenderer); // If it has not been initialized already in a previous pass, // generate an actor and a texture object to // render the image associated with the ImageVtkMapper2D. vtkActor *imageActor; vtkDataSetMapper *dataSetMapper = NULL; vtkTexture *texture; if ( m_ImageActors.count( imageMapper ) == 0 ) { dataSetMapper = vtkDataSetMapper::New(); //Enable rendering without copying the image. dataSetMapper->ImmediateModeRenderingOn(); texture = vtkNeverTranslucentTexture::New(); texture->RepeatOff(); imageActor = vtkActor::New(); imageActor->SetMapper( dataSetMapper ); imageActor->SetTexture( texture ); imageActor->GetProperty()->SetOpacity(0.999); // HACK! otherwise VTK wouldn't recognize this as translucent surface (if LUT values map to alpha < 255 // improvement: apply "opacity" property onle HERE and also in 2D image mapper. DO NOT change LUT to achieve translucent images (see method ChangeOpacity in image mapper 2D) // Make imageActor the sole owner of the mapper and texture // objects dataSetMapper->UnRegister( NULL ); texture->UnRegister( NULL ); // Store the actor so that it may be accessed in following // passes. m_ImageActors[imageMapper].Initialize(imageActor, imageMapper, m_ImageMapperDeletedCommand); } else { // Else, retrieve the actor and associated objects from the // previous pass. imageActor = m_ImageActors[imageMapper].m_Actor; dataSetMapper = (vtkDataSetMapper *)imageActor->GetMapper(); texture = imageActor->GetTexture(); } // Set poly data new each time its object changes (e.g. when // switching between planar and curved geometries) if ( (dataSetMapper != NULL) && (dataSetMapper->GetInput() != surface->GetVtkPolyData()) ) { dataSetMapper->SetInput( surface->GetVtkPolyData() ); } //Check if the m_ReslicedImage is NULL. //This is the case when no image geometry is met by //the reslicer. In that case, the texture has to be //empty (black) and we don't have to do anything. //See fixed bug #13275 if(localStorage->m_ReslicedImage != NULL) { texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort()); // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter) texture->MapColorScalarsThroughLookupTableOff(); //re-use properties from the 2D image mapper imageActor->SetProperty( localStorage->m_Actor->GetProperty() ); imageActor->GetProperty()->SetAmbient(0.5); // Set texture interpolation on/off bool textureInterpolation = node->IsOn( "texture interpolation", renderer ); texture->SetInterpolate( textureInterpolation ); // Store this actor to be added to the actor assembly, sort // by layer int layer = 1; node->GetIntProperty( "layer", layer ); layerSortedActors.insert(std::pair< int, vtkActor * >( layer, imageActor ) ); } } } } } } void Geometry2DDataVtkMapper3D::ActorInfo::Initialize(vtkActor* actor, itk::Object* sender, itk::Command* command) { m_Actor = actor; m_Sender = sender; // Get informed when ImageMapper object is deleted, so that // the data structures built here can be deleted as well m_ObserverID = sender->AddObserver( itk::DeleteEvent(), command ); } Geometry2DDataVtkMapper3D::ActorInfo::ActorInfo() : m_Actor(NULL), m_Sender(NULL), m_ObserverID(0) { } Geometry2DDataVtkMapper3D::ActorInfo::~ActorInfo() { if(m_Sender != NULL) { m_Sender->RemoveObserver(m_ObserverID); } if(m_Actor != NULL) { m_Actor->Delete(); } } } // namespace mitk diff --git a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h index f952d71697..9a6604ec63 100644 --- a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h +++ b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h @@ -1,210 +1,210 @@ /*=================================================================== 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 MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F #define MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F #include -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkDataStorage.h" #include "mitkGeometry2DDataToSurfaceFilter.h" #include "mitkWeakPointer.h" #include #include class vtkActor; class vtkPolyDataMapper; class vtkAssembly; class vtkFeatureEdges; class vtkTubeFilter; class vtkTransformPolyDataFilter; class vtkHedgeHog; namespace mitk { class Geometry2DData; class BaseRenderer; class ImageVtkMapper2D; class DataStorage; /** * \brief Vtk-based mapper to display a Geometry2D in a 3D window * \ingroup Mapper * * Uses a Geometry2DDataToSurfaceFilter object to create a vtkPolyData representation of a given Geometry2D instance. * Geometry2D may either contain a common flat plane or a curved plane (ThinPlateSplineCurvedGeometry). * * The vtkPolyData object is then decorated by a colored tube on the edges and by image textures if possible * (currently this requires that there is a 2D render window rendering the same geometry as this mapper). * * Properties that influence rendering are: * * - \b "color": (ColorProperty) Color of the tubed frame. * - \b "xresolution": (FloatProperty) Resolution (=number of tiles) in x direction. Only relevant for ThinPlateSplineCurvedGeometry * - \b "yresolution": (FloatProperty) Resolution (=number of tiles) in y direction. Only relevant for ThinPlateSplineCurvedGeometry * - \b "draw normals 3D": (BoolProperty) If true, a vtkHedgeHog is used to display normals for the generated surface object. Useful to distinguish front and back of a plane. Hedgehogs are colored according to "front color" and "back color" * - \b "color two sides": (BoolProperty) If true, front and back side of the plane are colored differently ("front color" and "back color") * - \b "invert normals": (BoolProperty) Inverts front/back for display. * - \b "front color": (ColorProperty) Color for front side of the plane * - \b "back color": (ColorProperty) Color for back side of the plane * - \b "material.representation": (BoolProperty) Choose the representation to draw the mesh in (Surface, Wireframe, Point Cloud) * - \b "surfacegeometry": TODO: Add documentation * - \b "LookupTable": (LookupTableProperty) Set the lookuptable to render with. * * Note: The following properties are set for each image individually, and thus, also influence the rendering of this mapper: * * - \b "texture interpolation": (BoolProperty) Turn on/off the texture interpolation of each image * - \b "use color": (BoolProperty) Decide whether we want to use the color property or a lookuptable. * - \b "binary": (BoolProperty) Binary image handling: Color the value=1.0 with the color property and make the background (value=0.0) of the image translucent. * - \b "layer": (IntProperty) Controls what image is considered "on top" of another. In the case that two should inhabit the same space, higher layer occludes lower layer. * - \b "opacity": (FloatProperty) Set the opacity for each rendered image. * - \b "color": (FloatProperty) Set the color for each rendered image. * * The internal filter pipeline which combines a (sometimes deformed) 2D surface * with a nice frame and image textures is illustrated in the following sketch: * * \image html mitkGeometry2DDataVtkMapper3D.png "Internal filter pipeline" * */ -class MITK_CORE_EXPORT Geometry2DDataVtkMapper3D : public VtkMapper3D +class MITK_CORE_EXPORT Geometry2DDataVtkMapper3D : public VtkMapper { public: - mitkClassMacro(Geometry2DDataVtkMapper3D, VtkMapper3D); + mitkClassMacro(Geometry2DDataVtkMapper3D, VtkMapper); itkNewMacro(Geometry2DDataVtkMapper3D); /** * Overloaded since the displayed color-frame of the image mustn't be * transformed after generation of poly data, but before (vertex coordinates * only) */ virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); /** * \brief Get the Geometry2DData to map */ virtual const Geometry2DData *GetInput(); /** * \brief All images found when traversing the (sub-) tree starting at * \a iterator which are resliced by an ImageVtkMapper2D will be mapped. * This method is used to set the data storage to traverse. This offers * the possibility to use this mapper for other data storages (not only * the default data storage). */ virtual void SetDataStorageForTexture(mitk::DataStorage* storage); protected: typedef std::multimap< int, vtkActor * > LayerSortedActorList; Geometry2DDataVtkMapper3D(); virtual ~Geometry2DDataVtkMapper3D(); virtual void GenerateDataForRenderer(BaseRenderer* renderer); void ProcessNode( DataNode * node, BaseRenderer* renderer, Surface * surface, LayerSortedActorList &layerSortedActors ); void ImageMapperDeletedCallback( itk::Object *caller, const itk::EventObject &event ); /** \brief general PropAssembly to hold the entire scene */ vtkAssembly *m_Prop3DAssembly; /** \brief PropAssembly to hold the planes */ vtkAssembly *m_ImageAssembly; Geometry2DDataToSurfaceFilter::Pointer m_SurfaceCreator; BoundingBox::Pointer m_SurfaceCreatorBoundingBox; BoundingBox::PointsContainer::Pointer m_SurfaceCreatorPointsContainer; /** \brief Edge extractor for tube-shaped frame */ vtkFeatureEdges *m_Edges; /** \brief Filter to apply object transform to the extracted edges */ vtkTransformPolyDataFilter *m_EdgeTransformer; /** \brief Source to create the tube-shaped frame */ vtkTubeFilter *m_EdgeTuber; /** \brief Mapper for the tube-shaped frame */ vtkPolyDataMapper *m_EdgeMapper; /** \brief Actor for the tube-shaped frame */ vtkActor *m_EdgeActor; /** \brief Mapper for black plane background */ vtkPolyDataMapper *m_BackgroundMapper; /** \brief Actor for black plane background */ vtkActor *m_BackgroundActor; /** \brief Transforms the suface before applying the glyph filter */ vtkTransformPolyDataFilter* m_NormalsTransformer; /** \brief Mapper for normals representation (thin lines) */ vtkPolyDataMapper* m_FrontNormalsMapper; vtkPolyDataMapper* m_BackNormalsMapper; /** \brief Generates lines for surface normals */ vtkHedgeHog* m_FrontHedgeHog; vtkHedgeHog* m_BackHedgeHog; /** \brief Actor to hold the normals arrows */ vtkActor* m_FrontNormalsActor; vtkActor* m_BackNormalsActor; /** Cleans the polyline in order to avoid phantom boundaries */ vtkCleanPolyData *m_Cleaner; /** Internal flag, if actors for normals are already added to m_Prop3DAssembly*/ bool m_NormalsActorAdded; /** \brief The DataStorage defines which part of the data tree is traversed for renderering. */ mitk::WeakPointer m_DataStorage; class MITK_CORE_EXPORT ActorInfo { public: vtkActor * m_Actor; // we do not need a smart-pointer, because we delete our // connection, when the referenced mapper is destroyed itk::Object* m_Sender; unsigned long m_ObserverID; void Initialize(vtkActor* actor, itk::Object* sender, itk::Command* command); ActorInfo(); ~ActorInfo(); }; /** \brief List holding the vtkActor to map the image into 3D for each * ImageMapper */ typedef std::map< ImageVtkMapper2D *, ActorInfo > ActorList; ActorList m_ImageActors; // responsiblity to remove the observer upon its destruction typedef itk::MemberCommand< Geometry2DDataVtkMapper3D > MemberCommandType; MemberCommandType::Pointer m_ImageMapperDeletedCommand; }; } // namespace mitk #endif /* MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F */ diff --git a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp index c726e4c435..fb8e8e770d 100644 --- a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp +++ b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp @@ -1,1059 +1,1024 @@ /*=================================================================== 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. ===================================================================*/ //MITK #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include "mitkImageStatisticsHolder.h" #include "mitkPlaneClipping.h" //MITK Rendering #include "mitkImageVtkMapper2D.h" #include "vtkMitkThickSlicesFilter.h" #include "vtkMitkLevelWindowFilter.h" #include "vtkNeverTranslucentTexture.h" //VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include //ITK #include mitk::ImageVtkMapper2D::ImageVtkMapper2D() { } mitk::ImageVtkMapper2D::~ImageVtkMapper2D() { //The 3D RW Mapper (Geometry2DDataVtkMapper3D) is listening to this event, //in order to delete the images from the 3D RW. this->InvokeEvent( itk::DeleteEvent() ); } //set the two points defining the textured plane according to the dimension and spacing void mitk::ImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, vtkFloatingPointType planeBounds[6]) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); float depth = this->CalculateLayerDepth(renderer); //Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct //plane size in crosshair rotation and swivel mode. localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth); //These two points define the axes of the plane in combination with the origin. //Point 1 is the x-axis and point 2 the y-axis. //Each plane is transformed according to the view (axial, coronal and saggital) afterwards. localStorage->m_Plane->SetPoint1(planeBounds[1] , planeBounds[2], depth); //P1: (xMax, yMin, depth) localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); //P2: (xMin, yMax, depth) } float mitk::ImageVtkMapper2D::CalculateLayerDepth(mitk::BaseRenderer* renderer) { //get the clipping range to check how deep into z direction we can render images double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1]; //Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined float depth = -maxRange*0.01; // divide by 100 int layer = 0; GetDataNode()->GetIntProperty( "layer", layer, renderer); //add the layer property for each image to render images with a higher layer on top of the others depth += layer*10; //*10: keep some room for each image (e.g. for QBalls in between) if(depth > 0.0f) { depth = 0.0f; MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead."; } return depth; } const mitk::Image* mitk::ImageVtkMapper2D::GetInput( void ) { - return static_cast< const mitk::Image * >( this->GetData() ); + return static_cast< const mitk::Image * >( GetDataNode()->GetData() ); } vtkProp* mitk::ImageVtkMapper2D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Actors; } -void mitk::ImageVtkMapper2D::MitkRenderOverlay(BaseRenderer* renderer) -{ - if ( this->IsVisible(renderer)==false ) - return; - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); - } -} - -void mitk::ImageVtkMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer) -{ - if ( this->IsVisible( renderer )==false ) - return; - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); - } -} - -void mitk::ImageVtkMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer) -{ - if ( this->IsVisible(renderer)==false ) - return; - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); - } -} - -void mitk::ImageVtkMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer) -{ - if(IsVisible(renderer)==false) - return; - if ( GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); - } -} void mitk::ImageVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); mitk::DataNode* datanode = this->GetDataNode(); if ( input == NULL || input->IsInitialized() == false ) { return; } //check if there is a valid worldGeometry const Geometry2D *worldGeometry = renderer->GetCurrentWorldGeometry2D(); if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() )) { return; } input->Update(); // early out if there is no intersection of the current rendering geometry // and the geometry of the image that is to be rendered. if ( !RenderingGeometryIntersectsImage( worldGeometry, input->GetSlicedGeometry() ) ) { // set image to NULL, to clear the texture in 3D, because // the latest image is used there if the plane is out of the geometry // see bug-13275 localStorage->m_ReslicedImage = NULL; localStorage->m_Mapper->SetInput( localStorage->m_EmptyPolyData ); return; } //set main input for ExtractSliceFilter localStorage->m_Reslicer->SetInput(input); localStorage->m_Reslicer->SetWorldGeometry(worldGeometry); localStorage->m_Reslicer->SetTimeStep( this->GetTimestep() ); //set the transformation of the image to adapt reslice axis localStorage->m_Reslicer->SetResliceTransformByGeometry( input->GetTimeSlicedGeometry()->GetGeometry3D( this->GetTimestep() ) ); //is the geometry of the slice based on the input image or the worldgeometry? bool inPlaneResampleExtentByGeometry = false; datanode->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer); localStorage->m_Reslicer->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry); // Initialize the interpolation mode for resampling; switch to nearest // neighbor if the input image is too small. if ( (input->GetDimension() >= 3) && (input->GetDimension(2) > 1) ) { VtkResliceInterpolationProperty *resliceInterpolationProperty; datanode->GetProperty( resliceInterpolationProperty, "reslice interpolation" ); int interpolationMode = VTK_RESLICE_NEAREST; if ( resliceInterpolationProperty != NULL ) { interpolationMode = resliceInterpolationProperty->GetInterpolation(); } switch ( interpolationMode ) { case VTK_RESLICE_NEAREST: localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST); break; case VTK_RESLICE_LINEAR: localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_LINEAR); break; case VTK_RESLICE_CUBIC: localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_CUBIC); break; } } else { localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST); } //set the vtk output property to true, makes sure that no unneeded mitk image convertion //is done. localStorage->m_Reslicer->SetVtkOutputRequest(true); //Thickslicing int thickSlicesMode = 0; int thickSlicesNum = 1; // Thick slices parameters if( input->GetPixelType().GetNumberOfComponents() == 1 ) // for now only single component are allowed { DataNode *dn=renderer->GetCurrentWorldGeometry2DNode(); if(dn) { ResliceMethodProperty *resliceMethodEnumProperty=0; if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty ) thickSlicesMode = resliceMethodEnumProperty->GetValueAsId(); IntProperty *intProperty=0; if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty ) { thickSlicesNum = intProperty->GetValue(); if(thickSlicesNum < 1) thickSlicesNum=1; if(thickSlicesNum > 10) thickSlicesNum=10; } } else { MITK_WARN << "no associated widget plane data tree node found"; } } const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( worldGeometry ); if(thickSlicesMode > 0) { double dataZSpacing = 1.0; Vector3D normInIndex, normal; if ( planeGeometry != NULL ){ normal = planeGeometry->GetNormal(); }else{ const mitk::AbstractTransformGeometry* abstractGeometry = dynamic_cast< const AbstractTransformGeometry * >(worldGeometry); if(abstractGeometry != NULL) normal = abstractGeometry->GetPlane()->GetNormal(); else return; //no fitting geometry set } normal.Normalize(); input->GetTimeSlicedGeometry()->GetGeometry3D( this->GetTimestep() )->WorldToIndex( normal, normInIndex ); dataZSpacing = 1.0 / normInIndex.GetNorm(); localStorage->m_Reslicer->SetOutputDimensionality( 3 ); localStorage->m_Reslicer->SetOutputSpacingZDirection(dataZSpacing); localStorage->m_Reslicer->SetOutputExtentZDirection( -thickSlicesNum, 0+thickSlicesNum ); // Do the reslicing. Modified() is called to make sure that the reslicer is // executed even though the input geometry information did not change; this // is necessary when the input /em data, but not the /em geometry changes. localStorage->m_TSFilter->SetThickSliceMode( thickSlicesMode-1 ); localStorage->m_TSFilter->SetInput( localStorage->m_Reslicer->GetVtkOutput() ); //vtkFilter=>mitkFilter=>vtkFilter update mechanism will fail without calling manually localStorage->m_Reslicer->Modified(); localStorage->m_Reslicer->Update(); localStorage->m_TSFilter->Modified(); localStorage->m_TSFilter->Update(); localStorage->m_ReslicedImage = localStorage->m_TSFilter->GetOutput(); } else { //this is needed when thick mode was enable bevore. These variable have to be reset to default values localStorage->m_Reslicer->SetOutputDimensionality( 2 ); localStorage->m_Reslicer->SetOutputSpacingZDirection(1.0); localStorage->m_Reslicer->SetOutputExtentZDirection( 0, 0 ); localStorage->m_Reslicer->Modified(); //start the pipeline with updating the largest possible, needed if the geometry of the input has changed localStorage->m_Reslicer->UpdateLargestPossibleRegion(); localStorage->m_ReslicedImage = localStorage->m_Reslicer->GetVtkOutput(); } // Bounds information for reslicing (only reuqired if reference geometry // is present) //this used for generating a vtkPLaneSource with the right size vtkFloatingPointType sliceBounds[6]; for ( int i = 0; i < 6; ++i ) { sliceBounds[i] = 0.0; } localStorage->m_Reslicer->GetClippedPlaneBounds(sliceBounds); //get the spacing of the slice localStorage->m_mmPerPixel = localStorage->m_Reslicer->GetOutputSpacing(); // calculate minimum bounding rect of IMAGE in texture vtkFloatingPointType textureClippingBounds[6]; for ( int i = 0; i < 6; ++i ) { textureClippingBounds[i] = 0.0; } // Calculate the actual bounds of the transformed plane clipped by the // dataset bounding box; this is required for drawing the texture at the // correct position during 3D mapping. mitk::PlaneClipping::CalculateClippedPlaneBounds( input->GetGeometry(), planeGeometry, textureClippingBounds ); textureClippingBounds[0] = static_cast< int >( textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5 ); textureClippingBounds[1] = static_cast< int >( textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5 ); textureClippingBounds[2] = static_cast< int >( textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5 ); textureClippingBounds[3] = static_cast< int >( textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5 ); //get the number of scalar components to distinguish between different image types int numberOfComponents = localStorage->m_ReslicedImage->GetNumberOfScalarComponents(); //get the binary property bool binary = false; bool binaryOutline = false; datanode->GetBoolProperty( "binary", binary, renderer ); if(binary) //binary image { datanode->GetBoolProperty( "outline binary", binaryOutline, renderer ); if(binaryOutline) //contour rendering { if ( input->GetPixelType().GetBpe() <= 8 ) { //generate contours/outlines localStorage->m_OutlinePolyData = CreateOutlinePolyData(renderer); float binaryOutlineWidth(1.0); if ( datanode->GetFloatProperty( "outline width", binaryOutlineWidth, renderer ) ) { if ( localStorage->m_Actors->GetNumberOfPaths() > 1 ) { float binaryOutlineShadowWidth(1.5); datanode->GetFloatProperty( "outline shadow width", binaryOutlineShadowWidth, renderer ); dynamic_cast(localStorage->m_Actors->GetParts()->GetItemAsObject(0)) ->GetProperty()->SetLineWidth( binaryOutlineWidth * binaryOutlineShadowWidth ); } localStorage->m_Actor->GetProperty()->SetLineWidth( binaryOutlineWidth ); } } else { binaryOutline = false; this->ApplyLookuptable(renderer, textureClippingBounds); MITK_WARN << "Type of all binary images should be (un)signed char. Outline does not work on other pixel types!"; } } else //standard binary image { if(numberOfComponents != 1) { MITK_ERROR << "Rendering Error: Binary Images with more then 1 component are not supported!"; } } } if (!(numberOfComponents == 1 || numberOfComponents == 3 || numberOfComponents == 4)) { MITK_WARN << "Unknown number of components!"; } this->ApplyLookuptable(renderer, textureClippingBounds); // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter) localStorage->m_Texture->MapColorScalarsThroughLookupTableOff(); this->ApplyColor( renderer ); this->ApplyOpacity( renderer ); this->TransformActor( renderer ); vtkActor* contourShadowActor = dynamic_cast (localStorage->m_Actors->GetParts()->GetItemAsObject(0)); if(binary && binaryOutline) //connect the mapper with the polyData which contains the lines { //We need the contour for the binary outline property as actor localStorage->m_Mapper->SetInput(localStorage->m_OutlinePolyData); localStorage->m_Actor->SetTexture(NULL); //no texture for contours bool binaryOutlineShadow( false ); datanode->GetBoolProperty( "outline binary shadow", binaryOutlineShadow, renderer ); if ( binaryOutlineShadow ) contourShadowActor->SetVisibility( true ); else contourShadowActor->SetVisibility( false ); } else { //Connect the mapper with the input texture. This is the standard case. //setup the textured plane this->GeneratePlane( renderer, sliceBounds ); //set the plane as input for the mapper localStorage->m_Mapper->SetInputConnection(localStorage->m_Plane->GetOutputPort()); //set the texture for the actor localStorage->m_Actor->SetTexture(localStorage->m_Texture); contourShadowActor->SetVisibility( false ); } // We have been modified => save this for next Update() localStorage->m_LastUpdateTime.Modified(); } void mitk::ImageVtkMapper2D::ApplyColor( mitk::BaseRenderer* renderer ) { LocalStorage *localStorage = this->GetLocalStorage( renderer ); float rgb[3]= { 1.0f, 1.0f, 1.0f }; // check for color prop and use it for rendering if it exists // binary image hovering & binary image selection bool hover = false; bool selected = false; GetDataNode()->GetBoolProperty("binaryimage.ishovering", hover, renderer); GetDataNode()->GetBoolProperty("selected", selected, renderer); if(hover && !selected) { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty ("binaryimage.hoveringcolor", renderer)); if(colorprop.IsNotNull()) { memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); } else { - GetColor( rgb, renderer ); + GetDataNode()->GetColor( rgb, renderer, "color" ); } } if(selected) { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty ("binaryimage.selectedcolor", renderer)); if(colorprop.IsNotNull()) { memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); } else { - GetColor( rgb, renderer ); + GetDataNode()->GetColor(rgb, renderer, "color"); } } if(!hover && !selected) { - GetColor( rgb, renderer ); + GetDataNode()->GetColor( rgb, renderer, "color" ); } double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK dynamic_cast (localStorage->m_Actors->GetParts()->GetItemAsObject(0))->GetProperty()->SetColor(rgbConv); localStorage->m_Actor->GetProperty()->SetColor(rgbConv); if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 ) { float rgb[3]= { 1.0f, 1.0f, 1.0f }; mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty ("outline binary shadow color", renderer)); if(colorprop.IsNotNull()) { memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); } double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetColor(rgbConv); } } void mitk::ImageVtkMapper2D::ApplyOpacity( mitk::BaseRenderer* renderer ) { LocalStorage* localStorage = this->GetLocalStorage( renderer ); float opacity = 1.0f; // check for opacity prop and use it for rendering if it exists - GetOpacity( opacity, renderer ); + GetDataNode()->GetOpacity( opacity, renderer, "opacity" ); //set the opacity according to the properties localStorage->m_Actor->GetProperty()->SetOpacity(opacity); if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 ) { dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetOpacity(opacity); } } void mitk::ImageVtkMapper2D::ApplyLookuptable( mitk::BaseRenderer* renderer, vtkFloatingPointType* bounds ) { //Have the following 4 different use cases how to generate the lookuptable: //1. We have a binary image -> The lut range is set to 0.0, 1.0 //2. The user sets a lut we can use //3. The user sets a transfer function we can use //4. Nothing defined: The default color lookuptable is used //@Warning: If the user sets a lut and a transfer function the lut will be used! LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer); bool binary = false; this->GetDataNode()->GetBoolProperty( "binary", binary, renderer ); vtkLookupTable *usedLookupTable = localStorage->m_DefaultLookupTable; vtkScalarsToColors *usedScalarsToColors = localStorage->m_DefaultLookupTable; // If lookup table or transferfunction use is requested... mitk::LookupTableProperty::Pointer lookupTableProp = dynamic_cast(this->GetDataNode()->GetProperty("LookupTable")); mitk::TransferFunctionProperty::Pointer transferFunctionProp = dynamic_cast(this->GetDataNode()->GetProperty("Image Rendering.Transfer Function",renderer )); if(binary) // is it a binary image? { usedScalarsToColors = usedLookupTable = localStorage->m_BinaryLookupTable; } else if( lookupTableProp.IsNotNull() ) // is a lookuptable set? { if( transferFunctionProp.IsNotNull() ) { MITK_WARN << "A LookupTable and a transfer function TransferFunction property is set! Only the Image Rendering.Transfer Function will be used. If you want to use the color transfer function, remove or rename the LookupTable property."; } //If a lookup table is supplied by the user: //only update the lut, when the properties have changed... if( lookupTableProp->GetLookupTable()->GetMTime() <= this->GetDataNode()->GetPropertyList()->GetMTime() ) { lookupTableProp->GetLookupTable()->ChangeOpacityForAll( lookupTableProp->GetLookupTable()->GetVtkLookupTable()->GetAlpha()*localStorage->m_Actor->GetProperty()->GetOpacity() ); lookupTableProp->GetLookupTable()->ChangeOpacity(0, 0.0); } //If the user defines a lut, we dont want to use the color and take white instead. dynamic_cast (localStorage->m_Actors->GetParts()->GetItemAsObject(0))->GetProperty()->SetColor(1.0, 1.0, 1.0); localStorage->m_Actor->GetProperty()->SetColor(1.0, 1.0, 1.0); usedScalarsToColors = usedLookupTable = lookupTableProp->GetLookupTable()->GetVtkLookupTable(); } else if(transferFunctionProp.IsNotNull()) // is a color transfer function set? { usedScalarsToColors = transferFunctionProp->GetValue()->GetColorTransferFunction(); usedLookupTable = 0; } else { //default lookuptable LevelWindow levelWindow; - this->GetLevelWindow( levelWindow, renderer ); + GetDataNode()->GetLevelWindow( levelWindow, renderer, "levelwindow" ); usedLookupTable->SetRange( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() ); } this->ApplyColor( renderer ); // check for texture interpolation property bool textureInterpolation = false; GetDataNode()->GetBoolProperty( "texture interpolation", textureInterpolation, renderer ); //set the interpolation modus according to the property localStorage->m_Texture->SetInterpolate(textureInterpolation); mitk::LevelWindow opacLevelWindow; - if( this->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) ) + if( GetDataNode()->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) ) { //pass the opaque level window to the filter localStorage->m_LevelWindowFilter->SetMinOpacity(opacLevelWindow.GetLowerWindowBound()); localStorage->m_LevelWindowFilter->SetMaxOpacity(opacLevelWindow.GetUpperWindowBound()); } else { //no opaque level window localStorage->m_LevelWindowFilter->SetMinOpacity(0.0); localStorage->m_LevelWindowFilter->SetMaxOpacity(255.0); } localStorage->m_LevelWindowFilter->SetLookupTable(usedScalarsToColors); localStorage->m_LevelWindowFilter->SetInput(localStorage->m_ReslicedImage); localStorage->m_LevelWindowFilter->SetClippingBounds(bounds); //connect the texture with the output of the levelwindow filter localStorage->m_Texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort()); } void mitk::ImageVtkMapper2D::Update(mitk::BaseRenderer* renderer) { - if ( !this->IsVisible( renderer ) ) + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) { return; } mitk::Image* data = const_cast( this->GetInput() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); // Check if time step is valid const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->GetTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTime( this->GetTimestep() ) ) ) { return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } void mitk::ImageVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { mitk::Image::Pointer image = dynamic_cast(node->GetData()); // Properties common for both images and segmentations node->AddProperty( "depthOffset", mitk::FloatProperty::New( 0.0 ), renderer, overwrite ); node->AddProperty( "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "outline width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite ); node->AddProperty( "outline binary shadow", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "outline binary shadow color", ColorProperty::New(0.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "outline shadow width", mitk::FloatProperty::New( 1.5 ), renderer, overwrite ); if(image->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) ); else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() ); node->AddProperty( "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) ); // set to user configurable default value (see global options) node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) ); node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) ); std::string photometricInterpretation; // DICOM tag telling us how pixel values should be displayed if ( node->GetStringProperty( "dicom.pixel.PhotometricInterpretation", photometricInterpretation ) ) { // modality provided by DICOM or other reader if ( photometricInterpretation.find("MONOCHROME1") != std::string::npos ) // meaning: display MINIMUM pixels as WHITE { // generate LUT (white to black) mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); vtkLookupTable* bwLut = mitkLut->GetVtkLookupTable(); bwLut->SetTableRange (0, 1); bwLut->SetSaturationRange (0, 0); bwLut->SetHueRange (0, 0); bwLut->SetValueRange (1, 0); bwLut->SetAlphaRange (1, 1); bwLut->SetRampToLinear(); bwLut->Build(); mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); mitkLutProp->SetLookupTable(mitkLut); node->SetProperty( "LookupTable", mitkLutProp ); } else if ( photometricInterpretation.find("MONOCHROME2") != std::string::npos ) // meaning: display MINIMUM pixels as BLACK { // apply default LUT (black to white) node->SetProperty( "color", mitk::ColorProperty::New( 1,1,1 ), renderer ); } // PALETTE interpretation should be handled ok by RGB loading } bool isBinaryImage(false); if ( ! node->GetBoolProperty("binary", isBinaryImage) ) { // ok, property is not set, use heuristic to determine if this // is a binary image mitk::Image::Pointer centralSliceImage; ScalarType minValue = 0.0; ScalarType maxValue = 0.0; ScalarType min2ndValue = 0.0; ScalarType max2ndValue = 0.0; mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New(); sliceSelector->SetInput(image); sliceSelector->SetSliceNr(image->GetDimension(2)/2); sliceSelector->SetTimeNr(image->GetDimension(3)/2); sliceSelector->SetChannelNr(image->GetDimension(4)/2); sliceSelector->Update(); centralSliceImage = sliceSelector->GetOutput(); if ( centralSliceImage.IsNotNull() && centralSliceImage->IsInitialized() ) { minValue = centralSliceImage->GetStatistics()->GetScalarValueMin(); maxValue = centralSliceImage->GetStatistics()->GetScalarValueMax(); min2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMin(); max2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMax(); } if ((maxValue == min2ndValue && minValue == max2ndValue) || minValue == maxValue) { // centralSlice is strange, lets look at all data minValue = image->GetStatistics()->GetScalarValueMin(); maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute(); min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(); max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(); } isBinaryImage = ( maxValue == min2ndValue && minValue == max2ndValue ); } // some more properties specific for a binary... if (isBinaryImage) { node->AddProperty( "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite ); node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "binaryimage.selectedcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "binaryimage.selectedannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "binaryimage.hoveringcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "binaryimage.hoveringannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "binary", mitk::BoolProperty::New( true ), renderer, overwrite ); node->AddProperty("layer", mitk::IntProperty::New(10), renderer, overwrite); } else //...or image type object { node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite ); node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite); } if(image.IsNotNull() && image->IsInitialized()) { if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL)) { /* initialize level/window from DICOM tags */ std::string sLevel; std::string sWindow; if ( image->GetPropertyList()->GetStringProperty( "dicom.voilut.WindowCenter", sLevel ) && image->GetPropertyList()->GetStringProperty( "dicom.voilut.WindowWidth", sWindow ) ) { float level = atof( sLevel.c_str() ); float window = atof( sWindow.c_str() ); mitk::LevelWindow contrast; std::string sSmallestPixelValueInSeries; std::string sLargestPixelValueInSeries; if ( image->GetPropertyList()->GetStringProperty( "dicom.series.SmallestPixelValueInSeries", sSmallestPixelValueInSeries ) && image->GetPropertyList()->GetStringProperty( "dicom.series.LargestPixelValueInSeries", sLargestPixelValueInSeries ) ) { float smallestPixelValueInSeries = atof( sSmallestPixelValueInSeries.c_str() ); float largestPixelValueInSeries = atof( sLargestPixelValueInSeries.c_str() ); contrast.SetRangeMinMax( smallestPixelValueInSeries-1, largestPixelValueInSeries+1 ); // why not a little buffer? // might remedy some l/w widget challenges } else { contrast.SetAuto( static_cast(node->GetData()), false, true ); // we need this as a fallback } contrast.SetLevelWindow( level, window, true ); node->SetProperty( "levelwindow", LevelWindowProperty::New( contrast ), renderer ); } } if(((overwrite) || (node->GetProperty("opaclevelwindow", renderer)==NULL)) && (image->GetPixelType().GetPixelTypeId() == itk::ImageIOBase::RGBA) && (image->GetPixelType().GetTypeId() == typeid( unsigned char)) ) { mitk::LevelWindow opaclevwin; opaclevwin.SetRangeMinMax(0,255); opaclevwin.SetWindowBounds(0,255); mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin); node->SetProperty( "opaclevelwindow", prop, renderer ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } mitk::ImageVtkMapper2D::LocalStorage* mitk::ImageVtkMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } vtkSmartPointer mitk::ImageVtkMapper2D::CreateOutlinePolyData(mitk::BaseRenderer* renderer ){ LocalStorage* localStorage = this->GetLocalStorage(renderer); //get the min and max index values of each direction int* extent = localStorage->m_ReslicedImage->GetExtent(); int xMin = extent[0]; int xMax = extent[1]; int yMin = extent[2]; int yMax = extent[3]; int* dims = localStorage->m_ReslicedImage->GetDimensions(); //dimensions of the image int line = dims[0]; //how many pixels per line? int x = xMin; //pixel index x int y = yMin; //pixel index y char* currentPixel; //get the depth for each contour float depth = CalculateLayerDepth(renderer); vtkSmartPointer points = vtkSmartPointer::New(); //the points to draw vtkSmartPointer lines = vtkSmartPointer::New(); //the lines to connect the points // We take the pointer to the first pixel of the image currentPixel = static_cast(localStorage->m_ReslicedImage->GetScalarPointer() ); while (y <= yMax) { //if the current pixel value is set to something if ((currentPixel) && (*currentPixel != 0)) { //check in which direction a line is necessary //a line is added if the neighbor of the current pixel has the value 0 //and if the pixel is located at the edge of the image //if vvvvv not the first line vvvvv if (y > yMin && *(currentPixel-line) == 0) { //x direction - bottom edge of the pixel //add the 2 points vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); //add the line between both points lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv not the last line vvvvv if (y < yMax && *(currentPixel+line) == 0) { //x direction - top edge of the pixel vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv not the first pixel vvvvv if ( (x > xMin || y > yMin) && *(currentPixel-1) == 0) { //y direction - left edge of the pixel vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv not the last pixel vvvvv if ( (y < yMax || (x < xMax) ) && *(currentPixel+1) == 0) { //y direction - right edge of the pixel vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } /* now consider pixels at the edge of the image */ //if vvvvv left edge of image vvvvv if (x == xMin) { //draw left edge of the pixel vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv right edge of image vvvvv if (x == xMax) { //draw right edge of the pixel vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv bottom edge of image vvvvv if (y == yMin) { //draw bottom edge of the pixel vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } //if vvvvv top edge of image vvvvv if (y == yMax) { //draw top edge of the pixel vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth); lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } }//end if currentpixel is set x++; if (x > xMax) { //reached end of line x = xMin; y++; } // Increase the pointer-position to the next pixel. // This is safe, as the while-loop and the x-reset logic above makes // sure we do not exceed the bounds of the image currentPixel++; }//end of while // Create a polydata to store everything in vtkSmartPointer polyData = vtkSmartPointer::New(); // Add the points to the dataset polyData->SetPoints(points); // Add the lines to the dataset polyData->SetLines(lines); return polyData; } void mitk::ImageVtkMapper2D::TransformActor(mitk::BaseRenderer* renderer) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital vtkSmartPointer trans = vtkSmartPointer::New(); vtkSmartPointer matrix = localStorage->m_Reslicer->GetResliceAxes(); trans->SetMatrix(matrix); //transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital) localStorage->m_Actor->SetUserTransform(trans); //transform the origin to center based coordinates, because MITK is center based. localStorage->m_Actor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0); if ( localStorage->m_Actors->GetNumberOfPaths() > 1 ) { vtkActor* secondaryActor = dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) ); secondaryActor->SetUserTransform(trans); secondaryActor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0); } } bool mitk::ImageVtkMapper2D::RenderingGeometryIntersectsImage( const Geometry2D* renderingGeometry, SlicedGeometry3D* imageGeometry ) { // if either one of the two geometries is NULL we return true // for safety reasons if ( renderingGeometry == NULL || imageGeometry == NULL ) return true; // get the distance for the first cornerpoint ScalarType initialDistance = renderingGeometry->SignedDistance( imageGeometry->GetCornerPoint( 0 ) ); for( int i=1; i<8; i++ ) { mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint( i ); // get the distance to the other cornerpoints ScalarType distance = renderingGeometry->SignedDistance( cornerPoint ); // if it has not the same signing as the distance of the first point if ( initialDistance * distance < 0 ) { // we have an intersection and return true return true; } } // all distances have the same sign, no intersection and we return false return false; } mitk::ImageVtkMapper2D::LocalStorage::LocalStorage() { //Do as much actions as possible in here to avoid double executions. m_Plane = vtkSmartPointer::New(); m_Texture = vtkSmartPointer::New().GetPointer(); m_DefaultLookupTable = vtkSmartPointer::New(); m_BinaryLookupTable = vtkSmartPointer::New(); m_Mapper = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_Actors = vtkSmartPointer::New(); m_Reslicer = mitk::ExtractSliceFilter::New(); m_TSFilter = vtkSmartPointer::New(); m_OutlinePolyData = vtkSmartPointer::New(); m_ReslicedImage = vtkSmartPointer::New(); m_EmptyPolyData = vtkSmartPointer::New(); //the following actions are always the same and thus can be performed //in the constructor for each image (i.e. the image-corresponding local storage) m_TSFilter->ReleaseDataFlagOn(); //built a default lookuptable m_DefaultLookupTable->SetRampToLinear(); m_DefaultLookupTable->SetSaturationRange( 0.0, 0.0 ); m_DefaultLookupTable->SetHueRange( 0.0, 0.0 ); m_DefaultLookupTable->SetValueRange( 0.0, 1.0 ); m_DefaultLookupTable->Build(); m_BinaryLookupTable->SetRampToLinear(); m_BinaryLookupTable->SetSaturationRange( 0.0, 0.0 ); m_BinaryLookupTable->SetHueRange( 0.0, 0.0 ); m_BinaryLookupTable->SetValueRange( 0.0, 1.0 ); m_BinaryLookupTable->SetRange(0.0, 1.0); m_BinaryLookupTable->Build(); // make first value transparent { double rgba[4]; m_BinaryLookupTable->GetTableValue(0, rgba); m_BinaryLookupTable->SetTableValue(0, rgba[0], rgba[1], rgba[2], 0); // background to 0 } //do not repeat the texture (the image) m_Texture->RepeatOff(); //set the mapper for the actor m_Actor->SetMapper( m_Mapper ); vtkSmartPointer outlineShadowActor = vtkSmartPointer::New(); outlineShadowActor->SetMapper( m_Mapper ); m_Actors->AddPart( outlineShadowActor ); m_Actors->AddPart( m_Actor ); //level window filter m_LevelWindowFilter = new vtkMitkLevelWindowFilter(); } diff --git a/Core/Code/Rendering/mitkImageVtkMapper2D.h b/Core/Code/Rendering/mitkImageVtkMapper2D.h index d214fa45ec..c435536fb9 100644 --- a/Core/Code/Rendering/mitkImageVtkMapper2D.h +++ b/Core/Code/Rendering/mitkImageVtkMapper2D.h @@ -1,295 +1,290 @@ /*=================================================================== 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 MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E #define MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E //MITK #include //MITK Rendering #include "mitkBaseRenderer.h" -#include "mitkVtkMapper2D.h" +#include "mitkVtkMapper.h" #include "mitkExtractSliceFilter.h" //VTK #include #include class vtkActor; class vtkPolyDataMapper; class vtkPlaneSource; class vtkImageData; class vtkLookupTable; class vtkImageReslice; class vtkImageChangeInformation; class vtkPoints; class vtkMitkThickSlicesFilter; class vtkPolyData; class vtkMitkApplyLevelWindowToRGBFilter; class vtkMitkLevelWindowFilter; namespace mitk { /** \brief Mapper to resample and display 2D slices of a 3D image. * * The following image gives a brief overview of the mapping and the involved parts. * * \image html imageVtkMapper2Darchitecture.png * * First, the image is resliced by means of vtkImageReslice. The volume image * serves as input to the mapper in addition to spatial placement of the slice and a few other * properties such as thick slices. This code was already present in the old version * (mitkImageMapperGL2D). * * Next, the obtained slice (m_ReslicedImage) is put into a vtkMitkLevelWindowFilter * and the scalar levelwindow, opacity levelwindow and optional clipping to * local image bounds are applied * * Next, the output of the vtkMitkLevelWindowFilter is used to create a texture * (m_Texture) and a plane onto which the texture is rendered (m_Plane). For * mapping purposes, a vtkPolyDataMapper (m_Mapper) is utilized. Orthographic * projection is applied to create the effect of a 2D image. The mapper and the * texture are assigned to the actor (m_Actor) which is passed to the VTK rendering * pipeline via the method GetVtkProp(). * * In order to transform the textured plane to the correct position in space, the * same transformation as used for reslicing is applied to both the camera and the * vtkActor. All important steps are explained in more detail below. The resulting * 2D image (by reslicing the underlying 3D input image appropriately) can either * be directly rendered in a 2D view or just be calculated to be used later by another * rendering entity, e.g. in texture mapping in a 3D view. * * Properties that can be set for images and influence the imageMapper2D are: * * - \b "opacity": (FloatProperty) Opacity of the image * - \b "color": (ColorProperty) Color of the image * - \b "LookupTable": (mitkLookupTableProperty) If this property is set, * the default lookuptable will be ignored and the "LookupTable" value * will be used instead. * - \b "Image Rendering.Transfer Function": (mitkTransferFunctionProperty) If this * property is set, a color transferfunction will be used to color the image. * \warning This property will not have any effect if, the "LookupTable" property * is set. * - \b "binary": (BoolProperty) is the image a binary image or not * - \b "outline binary": (BoolProperty) show outline of the image or not * - \b "texture interpolation": (BoolProperty) texture interpolation of the image * - \b "reslice interpolation": (VtkResliceInterpolationProperty) reslice interpolation of the image * - \b "in plane resample extent by geometry": (BoolProperty) Do it or not * - \b "bounding box": (BoolProperty) Is the Bounding Box of the image shown or not * - \b "layer": (IntProperty) Layer of the image * - \b "volume annotation color": (ColorProperty) color of the volume annotation, TODO has to be reimplemented * - \b "volume annotation unit": (StringProperty) annotation unit as string (does not implicit convert the unit!) unit is ml or cm3, TODO has to be reimplemented * The default properties are: * - \b "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite ) * - \b "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ) * - \b "binary", mitk::BoolProperty::New( true ), renderer, overwrite ) * - \b "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite ) * - \b "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) ) * - \b "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() ) * - \b "in plane resample extent by geometry", mitk::BoolProperty::New( false ) ) * - \b "bounding box", mitk::BoolProperty::New( false ) ) * - \b "layer", mitk::IntProperty::New(10), renderer, overwrite) * - \b "Image Rendering.Transfer Function": Default color transfer function for CTs * - \b "LookupTable": Undefined. Must be set by the user. * If the modality-property is set for an image, the mapper uses modality-specific default properties, * e.g. color maps, if they are defined. * \ingroup Mapper */ -class MITK_CORE_EXPORT ImageVtkMapper2D : public VtkMapper2D -{ + class MITK_CORE_EXPORT ImageVtkMapper2D : public VtkMapper + { -public: - /** Standard class typedefs. */ - mitkClassMacro( ImageVtkMapper2D,VtkMapper2D ); + public: + /** Standard class typedefs. */ + mitkClassMacro( ImageVtkMapper2D,VtkMapper ); /** Method for creation through the object factory. */ itkNewMacro(Self); /** \brief Get the Image to map */ const mitk::Image *GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); - //### methods of MITK-VTK rendering pipeline - virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); - - virtual void MitkRenderOverlay(BaseRenderer* renderer); - virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); - virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); - virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); - //### end of methods of MITK-VTK rendering pipeline + //### methods of MITK-VTK rendering pipeline + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + //### end of methods of MITK-VTK rendering pipeline /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ /** * To render transveral, coronal, and sagittal, the mapper is called three times. * For performance reasons, the corresponding data for each view is saved in the * internal helper class LocalStorage. This allows rendering n views with just * 1 mitkMapper using n vtkMapper. * */ class MITK_CORE_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Actor of a 2D render window. */ vtkSmartPointer m_Actor; vtkSmartPointer m_Actors; /** \brief Mapper of a 2D render window. */ vtkSmartPointer m_Mapper; /** \brief Current slice of a 2D render window.*/ vtkSmartPointer m_ReslicedImage; /** \brief Empty vtkPolyData that is set when rendering geometry does not * intersect the image geometry. * \warning This member variable is set to NULL, * if no image geometry is inside the plane geometry * of the respective render window. Any user of this * slice has to check whether it is set to NULL! */ vtkSmartPointer m_EmptyPolyData; /** \brief Plane on which the slice is rendered as texture. */ vtkSmartPointer m_Plane; /** \brief The texture which is used to render the current slice. */ vtkSmartPointer m_Texture; /** \brief The lookuptable for colors and level window */ vtkSmartPointer m_DefaultLookupTable; vtkSmartPointer m_BinaryLookupTable; /** \brief The actual reslicer (one per renderer) */ mitk::ExtractSliceFilter::Pointer m_Reslicer; /** \brief Filter for thick slices */ vtkSmartPointer m_TSFilter; /** \brief PolyData object containg all lines/points needed for outlining the contour. This container is used to save a computed contour for the next rendering execution. For instance, if you zoom or pann, there is no need to recompute the contour. */ vtkSmartPointer m_OutlinePolyData; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief mmPerPixel relation between pixel and mm. (World spacing).*/ mitk::ScalarType* m_mmPerPixel; /** \brief This filter is used to apply the level window to Grayvalue and RBG(A) images. */ vtkMitkLevelWindowFilter* m_LevelWindowFilter; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage() { } }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::Mapper::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: /** \brief Transforms the actor to the actual position in 3D. * \param renderer The current renderer corresponding to the render window. */ void TransformActor(mitk::BaseRenderer* renderer); /** \brief Generates a plane according to the size of the resliced image in milimeters. * * \image html texturedPlane.png * * In VTK a vtkPlaneSource is defined through three points. The origin and two * points defining the axes of the plane (see VTK documentation). The origin is * set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the * resliced image in space. Z is relevant for blending and the layer property. * The center of the plane (C) is also the center of the view plane (cf. the image above). * * \note For the standard MITK view with three 2D render windows showing three * different slices, three such planes are generated. All these planes are generated * in the XY-plane (even if they depict a YZ-slice of the volume). * */ void GeneratePlane(mitk::BaseRenderer* renderer, vtkFloatingPointType planeBounds[6]); /** \brief Generates a vtkPolyData object containing the outline of a given binary slice. \param renderer: Pointer to the renderer containing the needed information \note This code is based on code from the iil library. */ vtkSmartPointer CreateOutlinePolyData(mitk::BaseRenderer* renderer); /** Default constructor */ ImageVtkMapper2D(); /** Default deconstructor */ virtual ~ImageVtkMapper2D(); /** \brief Does the actual resampling, without rendering the image yet. * All the data is generated inside this method. The vtkProp (or Actor) * is filled with content (i.e. the resliced image). * * After generation, a 4x4 transformation matrix(t) of the current slice is obtained * from the vtkResliceImage object via GetReslicesAxis(). This matrix is * applied to each textured plane (actor->SetUserTransform(t)) to transform everything * to the actual 3D position (cf. the following image). * * \image html cameraPositioning3D.png * */ virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer); /** \brief This method uses the vtkCamera clipping range and the layer property * to calcualte the depth of the object (e.g. image or contour). The depth is used * to keep the correct order for the final VTK rendering.*/ float CalculateLayerDepth(mitk::BaseRenderer* renderer); /** \brief This method applies (or modifies) the lookuptable for all types of images. */ void ApplyLookuptable( mitk::BaseRenderer* renderer, vtkFloatingPointType* bounds ); /** \brief This method applies a color transfer function, if no LookuptableProperty is set. Internally, a vtkColorTransferFunction is used. This is usefull for coloring continous images (e.g. float) */ void ApplyColorTransferFunction(mitk::BaseRenderer* renderer); /** \brief Set the color of the image/polydata */ void ApplyColor( mitk::BaseRenderer* renderer ); /** \brief Set the opacity of the actor. */ void ApplyOpacity( mitk::BaseRenderer* renderer ); /** * \brief Calculates whether the given rendering geometry intersects the * given SlicedGeometry3D. * * This method checks if the given Geometry2D intersects the given * SlicedGeometry3D. It calculates the distance of the Geometry2D to all * 8 cornerpoints of the SlicedGeometry3D. If all distances have the same * sign (all positive or all negative) there is no intersection. * If the distances have different sign, there is an intersection. **/ bool RenderingGeometryIntersectsImage( const Geometry2D* renderingGeometry, SlicedGeometry3D* imageGeometry ); }; } // namespace mitk #endif /* MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E */ diff --git a/Core/Code/Rendering/mitkMapper.cpp b/Core/Code/Rendering/mitkMapper.cpp index a03c64a96e..6a2e00d78c 100644 --- a/Core/Code/Rendering/mitkMapper.cpp +++ b/Core/Code/Rendering/mitkMapper.cpp @@ -1,157 +1,149 @@ /*=================================================================== 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 "mitkMapper.h" #include "mitkDataNode.h" #include "mitkBaseRenderer.h" #include "mitkProperties.h" mitk::Mapper::Mapper() :m_TimeStep( 0 ) { - } mitk::Mapper::~Mapper() { } + mitk::BaseData* mitk::Mapper::GetData() const { - return m_DataNode->GetData(); +return m_DataNode->GetData(); } mitk::DataNode* mitk::Mapper::GetDataNode() const { - itkDebugMacro("returning DataNode address " << this->m_DataNode ); return this->m_DataNode.GetPointer(); } bool mitk::Mapper::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetColor(rgb, renderer, name); } bool mitk::Mapper::GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetVisibility(visible, renderer, name); } bool mitk::Mapper::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetOpacity(opacity, renderer, name); } bool mitk::Mapper::GetLevelWindow(mitk::LevelWindow& levelWindow, mitk::BaseRenderer* renderer, const char* name) const { const mitk::DataNode* node=GetDataNode(); if(node==NULL) return false; return node->GetLevelWindow(levelWindow, renderer, name); } + bool mitk::Mapper::IsVisible(mitk::BaseRenderer* renderer, const char* name) const { - bool visible=true; - GetVisibility(visible, renderer, name); + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, name); return visible; } -void mitk::Mapper::GenerateData() -{ -} - -void mitk::Mapper::GenerateDataForRenderer(mitk::BaseRenderer* /*renderer*/) -{ -} void mitk::Mapper::CalculateTimeStep( mitk::BaseRenderer *renderer ) { if ( ( renderer != NULL ) && ( m_DataNode.GetPointer() != NULL ) ) { m_TimeStep = renderer->GetTimeStep(m_DataNode->GetData()); } else { m_TimeStep = 0; } } void mitk::Mapper::Update(mitk::BaseRenderer *renderer) { const DataNode* node = GetDataNode(); assert(node!=NULL); //safety cause there are datatreenodes that have no defined data (video-nodes and root) unsigned int dataMTime = 0; mitk::BaseData::Pointer data = static_cast(node->GetData()); if (data.IsNotNull()) { dataMTime = data->GetMTime(); } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); // Check if time step is valid const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->GetTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTime( m_TimeStep ) ) ) { // TimeSlicedGeometry or time step is not valid for this data: // reset mapper so that nothing is displayed this->ResetMapper( renderer ); return; } if( (m_LastUpdateTime < GetMTime()) || (m_LastUpdateTime < node->GetDataReferenceChangedTime()) || (m_LastUpdateTime < dataMTime) || (renderer && (m_LastUpdateTime < renderer->GetTimeStepUpdateTime())) ) { - this->GenerateData(); m_LastUpdateTime.Modified(); } this->GenerateDataForRenderer(renderer); } void mitk::Mapper::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "layer", mitk::IntProperty::New(0), renderer, overwrite); node->AddProperty( "name", mitk::StringProperty::New("No Name!"), renderer, overwrite ); } diff --git a/Core/Code/Rendering/mitkMapper.h b/Core/Code/Rendering/mitkMapper.h index cb7fc53ba3..74154a7fc6 100644 --- a/Core/Code/Rendering/mitkMapper.h +++ b/Core/Code/Rendering/mitkMapper.h @@ -1,282 +1,298 @@ /*=================================================================== 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 MAPPER_H_HEADER_INCLUDED_C1E6EA08 #define MAPPER_H_HEADER_INCLUDED_C1E6EA08 #include #include "mitkBaseRenderer.h" +#include "mitkVtkPropRenderer.h" #include "mitkLevelWindow.h" +#include "mitkCommon.h" #include #include //Just included to get VTK version #include class vtkWindow; class vtkProp; namespace mitk { class BaseRenderer; class BaseData; class DataNode; /** \brief Interface for accessing (templated) LocalStorageHandler instances. */ class BaseLocalStorageHandler { public: virtual ~BaseLocalStorageHandler() {} virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true )=0; }; - //##Documentation - //## @brief Base class of all mappers, 2D as well as 3D - //## - //## Base class of all Mappers, 2D as well as 3D. - //## Subclasses of mitk::Mapper control the creation of rendering primitives - //## that interface to the graphics library (e.g., OpenGL, vtk). - //## @todo Should Mapper be a subclass of ImageSource? - //## @ingroup Mapper + /** \brief Base class of all mappers, Vtk as well as OpenGL mappers + * + * By the help of mappers, the input data is transformed to tangible primitives, + * such as surfaces, points, lines, etc. + * This is the base class of all mappers, Vtk as well as OpenGL mappers. + * Subclasses of mitk::Mapper control the creation of rendering primitives + * that interface to the graphics library (e.g., OpenGL, vtk). + * + * \todo Should Mapper be a subclass of ImageSource? + * \ingroup Mapper + */ class MITK_CORE_EXPORT Mapper : public itk::Object { public: mitkClassMacro(Mapper, itk::Object); - //##Documentation - //## @brief Set the DataNode containing the data to map + /** \brief Set the DataNode containing the data to map */ itkSetObjectMacro(DataNode, DataNode); - //##Documentation - //## @brief Get the data to map - //## - //## Returns the mitk::BaseData object associated with this mapper. - //## @returns the mitk::BaseData associated with this mapper. - BaseData* GetData() const; - //##Documentation - //## @brief Get the DataNode containing the data to map + /** \brief Get the DataNode containing the data to map */ virtual DataNode* GetDataNode() const; - //##Documentation - //## @brief Convenience access method for color properties (instances of - //## ColorProperty) - //## @return @a true property was found - virtual bool GetColor(float rgb[3], BaseRenderer* renderer, const char* name = "color") const; - - //##Documentation - //## @brief Convenience access method for visibility properties (instances - //## of BoolProperty) - //## @return @a true property was found - //## @sa IsVisible - virtual bool GetVisibility(bool &visible, BaseRenderer* renderer, const char* name = "visible") const; - - //##Documentation - //## @brief Convenience access method for opacity properties (instances of - //## FloatProperty) - //## @return @a true property was found - virtual bool GetOpacity(float &opacity, BaseRenderer* renderer, const char* name = "opacity") const; - - //##Documentation - //## @brief Convenience access method for color properties (instances of - //## LevelWindoProperty) - //## @return @a true property was found - virtual bool GetLevelWindow(LevelWindow &levelWindow, BaseRenderer* renderer, const char* name = "levelwindow") const; - - //##Documentation - //## @brief Convenience access method for visibility properties (instances - //## of BoolProperty). Return value is the visibility. Default is - //## visible==true, i.e., true is returned even if the property (@a - //## propertyKey) is not found. - //## - //## Thus, the return value has a different meaning than in the - //## GetVisibility method! - //## @sa GetVisibility - virtual bool IsVisible(BaseRenderer* renderer, const char* name = "visible") const; - virtual void Update(BaseRenderer* renderer); + /**\brief Get the data to map + * + * Returns the mitk::BaseData object associated with this mapper. + * \return the mitk::BaseData associated with this mapper. + * @deprecated Use GetDataNode()->GetData() instead to access the data + */ + DEPRECATED(BaseData* GetData() const); - virtual void MitkRenderOverlay(BaseRenderer* renderer) = 0; - virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer) = 0; - virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer) = 0; + /** \brief Convenience access method for color properties (instances of + * ColorProperty) + * \return \a true property was found + * @deprecated Use GetDataNode()->GetColor(...) instead to get the color + */ + DEPRECATED(virtual bool GetColor(float rgb[3], BaseRenderer* renderer, const char* name = "color") const); - virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer) = 0; + /** \brief Convenience access method for visibility properties (instances + * of BoolProperty) + * \return \a true property was found + * \sa IsVisible + * @deprecated Use GetDataNode()->GetVisibility(...) instead to get the visibility + */ + DEPRECATED(virtual bool GetVisibility(bool &visible, BaseRenderer* renderer, const char* name = "visible") const); - /** - * \brief Returns whether this is an vtk-based mapper + /** \brief Convenience access method for opacity properties (instances of + * FloatProperty) + * \return \a true property was found + * @deprecated Use GetDataNode()->GetOpacity(...) instead to get the opacity */ - virtual bool IsVtkBased() const = 0; + DEPRECATED(virtual bool GetOpacity(float &opacity, BaseRenderer* renderer, const char* name = "opacity") const); - /** \brief Returns true if this mapper owns the specified vtkProp for - * the given BaseRenderer. - * - * Note: returns false by default; should be implemented for VTK-based - * Mapper subclasses. */ - virtual bool HasVtkProp( const vtkProp* /*prop*/, BaseRenderer* /*renderer*/ ) - { - return false; - } + /** \brief Convenience access method for color properties (instances of + * LevelWindoProperty) + * \return \a true property was found + * @deprecated Use GetDataNode->GetLevelWindow(...) instead to get the levelwindow + */ + DEPRECATED(virtual bool GetLevelWindow(LevelWindow &levelWindow, BaseRenderer* renderer, const char* name = "levelwindow") const); + + + /** \brief Convenience access method for visibility properties (instances + * of BoolProperty). Return value is the visibility. Default is + * visible==true, i.e., true is returned even if the property (\a + * propertyKey) is not found. + * + * Thus, the return value has a different meaning than in the + * GetVisibility method! + * \sa GetVisibility + * @deprecated Use GetDataNode()->GetVisibility(...) instead + */ + DEPRECATED(virtual bool IsVisible(BaseRenderer* renderer, const char* name = "visible") const); + + + /** \brief Returns whether this is an vtk-based mapper + * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead + */ + virtual bool IsVtkBased() const = 0; + + + /** \brief Calls the time step of the input data for the specified renderer and checks + * whether the time step is valid and calls method GenerateDataForRenderer() + */ + virtual void Update(BaseRenderer* renderer); + + /** \brief Responsible for calling the appropriate render functions. + * To be implemented in sub-classes. + */ + virtual void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type) = 0; /** - * \brief Release vtk-based graphics resources. Must be overwritten in - * subclasses if vtkProps are used. + * \brief Apply specific color and opacity properties read from the PropertyList. + * Reimplemented in GLmapper (does not use the actor) and the VtkMapper class. + * The function is called by the individual mapper (mostly in the ApplyProperties() or ApplyAllProperties() + * method). */ - virtual void ReleaseGraphicsResources(vtkWindow*) { }; + virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL) = 0; + /** \brief Set default values of properties used by this mapper * to \a node * * \param node The node for which the properties are set * \param overwrite overwrite existing properties (default: \a false) * \param renderer defines which property list of node is used * (default: \a NULL, i.e. default property list) */ static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); /** \brief Returns the current time step as calculated from the renderer */ - int GetTimestep() const {return m_TimeStep;}; - + int GetTimestep() const { return m_TimeStep; }; /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer * /*renderer*/ ) const { return false; } protected: - Mapper(); + /** \brief explicit constructor which disallows implicit conversions */ + explicit Mapper(); + /** \brief virtual destructor in order to derive from this class */ virtual ~Mapper(); - //##Documentation - //## @brief Generate the data needed for rendering (independent of a specific renderer) - virtual void GenerateData(); - //##Documentation - //## @brief Generate the data needed for rendering into @a renderer - virtual void GenerateDataForRenderer(BaseRenderer* renderer); - //## Updates the time step, which is sometimes needed in subclasses + /** \brief Generate the data needed for rendering (independent of a specific renderer) */ + // @deprecated Use GenerateDataForRenderer(BaseRenderer* renderer) instead. + DEPRECATED( virtual void GenerateData() { }); + + /** \brief Generate the data needed for rendering into \a renderer */ + virtual void GenerateDataForRenderer(BaseRenderer* /* renderer */) { }; + + /** \brief Updates the time step, which is sometimes needed in subclasses */ virtual void CalculateTimeStep( BaseRenderer* renderer ); - //## Reset the mapper (i.e., make sure that nothing is displayed) if no - //## valid data is present. - //## - //## To be implemented in sub-classes. + /** \brief Reset the mapper (i.e., make sure that nothing is displayed) if no + * valid data is present. In most cases the reimplemented function + * disables the according actors (toggling visibility off) + * + * To be implemented in sub-classes. + */ virtual void ResetMapper( BaseRenderer* /*renderer*/ ) { }; - + //\brief not thread-safe itk::WeakPointer m_DataNode; - //##Documentation - //## @brief timestamp of last update of stored data + /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastUpdateTime; private: - - //## The current time step of the dataset to be rendered, for use in subclasses - //## The momentary timestep can be accessed via the GetTimestep() method. + /** \brief The current time step of the dataset to be rendered, + * for use in subclasses. + * The current timestep can be accessed via the GetTimestep() method. + */ int m_TimeStep; + /** \brief copy constructor */ + Mapper( const Mapper &); + + /** \brief assignment operator */ + Mapper &operator=(const Mapper &); + public: /** \brief Base class for mapper specific rendering ressources. */ class BaseLocalStorage { }; /** \brief Templated class for management of LocalStorage implementations in Mappers. * * The LocalStorageHandler is responsible for providing a LocalStorage to a * concrete mitk::Mapper subclass. Each RenderWindow / mitk::BaseRenderer is * assigned its own LocalStorage instance so that all contained ressources * (actors, shaders, textures, ...) are provided individually per window. * */ template class LocalStorageHandler : public mitk::BaseLocalStorageHandler { protected: std::map m_BaseRenderer2LS; public: /** \brief deallocates a local storage for a specifc BaseRenderer (if the * BaseRenderer is itself deallocating it in its destructor, it has to set * unregisterFromBaseRenderer=false) */ virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true ) { //MITK_INFO << "deleting a localstorage on a mapper request"; if(unregisterFromBaseRenderer) renderer->UnregisterLocalStorageHandler( this ); L *l = m_BaseRenderer2LS[renderer]; m_BaseRenderer2LS.erase( renderer ); delete l; } /** \brief Retrieves a LocalStorage for a specific BaseRenderer. * - * Should be used by mappers in GenerateData() and ApplyProperties() + * Should be used by mappers in GenerateDataForRenderer() */ L *GetLocalStorage(mitk::BaseRenderer *forRenderer) { L *l = m_BaseRenderer2LS[ forRenderer ]; if(!l) { //MITK_INFO << "creating new localstorage"; l = new L; m_BaseRenderer2LS[ forRenderer ] = l; forRenderer->RegisterLocalStorageHandler( this ); } return l; } ~LocalStorageHandler() { typename std::map::iterator it; for ( it=m_BaseRenderer2LS.begin() ; it != m_BaseRenderer2LS.end(); it++ ) { (*it).first->UnregisterLocalStorageHandler(this); delete (*it).second; } m_BaseRenderer2LS.clear(); } }; - - - }; } // namespace mitk #endif /* MAPPER_H_HEADER_INCLUDED_C1E6EA08 */ diff --git a/Core/Code/Rendering/mitkMapper2D.cpp b/Core/Code/Rendering/mitkMapper2D.cpp deleted file mode 100644 index 0c8454bdc5..0000000000 --- a/Core/Code/Rendering/mitkMapper2D.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*=================================================================== - -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 "mitkMapper2D.h" - -mitk::Mapper2D::Mapper2D() -{ -} - -mitk::Mapper2D::~Mapper2D() -{ -} - -void mitk::Mapper2D::SetGeometry3D(const mitk::Geometry3D* aGeometry3D) -{ - m_Geometry3D = aGeometry3D; - Modified(); -} diff --git a/Core/Code/Rendering/mitkMapper2D.h b/Core/Code/Rendering/mitkMapper2D.h deleted file mode 100644 index f0ef27834d..0000000000 --- a/Core/Code/Rendering/mitkMapper2D.h +++ /dev/null @@ -1,63 +0,0 @@ -/*=================================================================== - -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 MAPPER2D_H_HEADER_INCLUDED_C1C5453B -#define MAPPER2D_H_HEADER_INCLUDED_C1C5453B - -#include "mitkMapper.h" -#include "mitkGeometry3D.h" - -namespace mitk { - -//##Documentation -//## @brief Base class of all Mappers for 2D display -//## -//## Base class of all Mappers for 2D display, i.e., a frontal view on a plane -//## display area, so nothing rotated in 3D space as, e.g., a plane in 3D space -//## (such things are done by subclasses of Mapper3D). -//## @note [not yet used:] SetGeometry3D() tells the Mapper2D which slices will -//## potentially be requested. -//## @ingroup Mapper -class MITK_CORE_EXPORT Mapper2D : public Mapper -{ - public: - mitkClassMacro(Mapper2D,Mapper); - - //##Documentation - //## @brief Set Geometry3D containing the all possible Geometry2D that may be requested for mapping - //## @sa m_Geometry3D - virtual void SetGeometry3D(const mitk::Geometry3D* aGeometry3D); - - protected: - Mapper2D(); - - virtual ~Mapper2D(); - - //##Documentation - //## @brief Set Geometry3D containing the all possible Geometry2D that may be requested for mapping - //## @note not yet implemented - //## The idea was that this allows storing/pre-fetching of data required for mapping. - //## Should be called by SliceNavigationController. - //## @todo check design and implement when implementing (sub-)classes of SliceNavigationController - Geometry3D::ConstPointer m_Geometry3D; -}; - -} // namespace mitk - - - -#endif /* MAPPER2D_H_HEADER_INCLUDED_C1C5453B */ diff --git a/Core/Code/Rendering/mitkMapper3D.cpp b/Core/Code/Rendering/mitkMapper3D.cpp deleted file mode 100644 index dc2eb48284..0000000000 --- a/Core/Code/Rendering/mitkMapper3D.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*=================================================================== - -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 "mitkMapper3D.h" - -mitk::Mapper3D::Mapper3D() -{ -} - -mitk::Mapper3D::~Mapper3D() -{ -} - diff --git a/Core/Code/Rendering/mitkMapper3D.h b/Core/Code/Rendering/mitkMapper3D.h deleted file mode 100644 index a4e4737467..0000000000 --- a/Core/Code/Rendering/mitkMapper3D.h +++ /dev/null @@ -1,44 +0,0 @@ -/*=================================================================== - -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 MAPPER3D_H_HEADER_INCLUDED_C1C517B9 -#define MAPPER3D_H_HEADER_INCLUDED_C1C517B9 - -#include "mitkMapper.h" - -namespace mitk { - -//##Documentation -//## @brief Base class of all mappers for 3D display -//## @ingroup Mapper -class MITK_CORE_EXPORT Mapper3D : public Mapper -{ - public: - mitkClassMacro(Mapper3D,Mapper); - - protected: - Mapper3D(); - - virtual ~Mapper3D(); - -}; - -} // namespace mitk - - - -#endif /* MAPPER3D_H_HEADER_INCLUDED_C1C517B9 */ diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp index 956d7ac6d3..3fe64931e5 100644 --- a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp +++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp @@ -1,521 +1,523 @@ /*=================================================================== 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 "mitkPointSetGLMapper2D.h" #include "mitkPointSet.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "vtkLinearTransform.h" #include "mitkStringProperty.h" #include "mitkPointSet.h" #include "mitkVtkPropRenderer.h" #include "mitkGL.h" //const float selectedColor[]={1.0,0.0,0.6}; //for selected! mitk::PointSetGLMapper2D::PointSetGLMapper2D() : m_Polygon(false), m_ShowPoints(true), m_ShowDistances(false), m_DistancesDecimalDigits(1), m_ShowAngles(false), m_ShowDistantLines(true), m_LineWidth(1) { } mitk::PointSetGLMapper2D::~PointSetGLMapper2D() { } const mitk::PointSet *mitk::PointSetGLMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } -void mitk::PointSetGLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer) +void mitk::PointSetGLMapper2D::ApplyAllProperties(mitk::BaseRenderer* renderer) { - GLMapper2D::ApplyProperties( renderer ); + GLMapper::ApplyColorAndOpacityProperties( renderer ); const mitk::DataNode* node=GetDataNode(); if( node == NULL ) return; node->GetBoolProperty("show contour", m_Polygon); node->GetBoolProperty("close contour", m_PolygonClosed); node->GetBoolProperty("show points", m_ShowPoints); node->GetBoolProperty("show distances", m_ShowDistances); node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits); node->GetBoolProperty("show angles", m_ShowAngles); node->GetBoolProperty("show distant lines", m_ShowDistantLines); node->GetIntProperty("line width", m_LineWidth); node->GetIntProperty("point line width", m_PointLineWidth); node->GetIntProperty("point 2D size", m_Point2DSize); } static bool makePerpendicularVector2D(const mitk::Vector2D& in, mitk::Vector2D& out) { if((fabs(in[0])>0) && ( (fabs(in[0])>fabs(in[1])) || (in[1] == 0) ) ) { out[0]=-in[1]/in[0]; out[1]=1; out.Normalize(); return true; } else if(fabs(in[1])>0) { out[0]=1; out[1]=-in[0]/in[1]; out.Normalize(); return true; } else return false; } void mitk::PointSetGLMapper2D::Paint( mitk::BaseRenderer *renderer ) { const mitk::DataNode* node=GetDataNode(); if( node == NULL ) return; const int text2dDistance = 10; - if(IsVisible(renderer)==false) return; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if ( !visible) return; // @FIXME: Logik fuer update bool updateNeccesary=true; if (updateNeccesary) { // ok, das ist aus GenerateData kopiert mitk::PointSet::Pointer input = const_cast(this->GetInput()); // Get the TimeSlicedGeometry of the input object const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry(); if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) { return; } // // get the world time // const Geometry2D* worldGeometry = renderer->GetCurrentWorldGeometry2D(); assert( worldGeometry != NULL ); ScalarType time = worldGeometry->GetTimeBounds()[ 0 ]; // // convert the world time in time steps of the input object // int timeStep=0; if ( time > ScalarTypeNumericTraits::NonpositiveMin() ) timeStep = inputTimeGeometry->MSToTimeStep( time ); if ( inputTimeGeometry->IsValidTime( timeStep ) == false ) { return; } mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timeStep ); if ( itkPointSet.GetPointer() == NULL) { return; } mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + this->ApplyAllProperties(renderer); vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); //List of the Points PointSet::DataType::PointsContainerConstIterator it, end; it = itkPointSet->GetPoints()->Begin(); end = itkPointSet->GetPoints()->End(); //iterator on the additional data of each point PointSet::DataType::PointDataContainerIterator selIt, selEnd; bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); selIt = itkPointSet->GetPointData()->Begin(); selEnd = itkPointSet->GetPointData()->End(); int counter = 0; //for writing text int j = 0; //for switching back to old color after using selected color float recallColor[4]; glGetFloatv(GL_CURRENT_COLOR,recallColor); //get the properties for coloring the points float unselectedColor[4] = {1.0, 1.0, 0.0, 1.0};//yellow //check if there is an unselected property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { //get the color from the dataNode node->GetColor(unselectedColor, NULL); } //get selected property float selectedColor[4] = {1.0, 0.0, 0.6, 1.0}; if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } //check if there is an pointLineWidth property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("point line width")) != NULL) { m_PointLineWidth = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point line width"))->GetValue(); } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("point line width")) != NULL) { m_PointLineWidth = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point line width"))->GetValue(); } //check if there is an point 2D size property if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("point 2D size")) != NULL) { m_Point2DSize = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point 2D size"))->GetValue(); } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("point 2D size")) != NULL) { m_Point2DSize = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point 2D size"))->GetValue(); } Point3D p; // currently visited point Point3D lastP; // last visited point Vector3D vec; // p - lastP Vector3D lastVec; // lastP - point before lastP vec.Fill(0); mitk::Point3D projected_p; // p projected on viewplane Point2D pt2d; // projected_p in display coordinates Point2D lastPt2d; // last projected_p in display coordinates Point2D preLastPt2d;// projected_p in display coordinates before lastPt2d Point2D lastPt2DInPointSet; // The last point in the pointset in display coordinates mitk::PointSet::DataType::PointType plob; plob.Fill(0); itkPointSet->GetPoint( itkPointSet->GetNumberOfPoints()-1, &plob); //map lastPt2DInPointSet to display coordinates float vtkp[3]; itk2vtk(plob, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, lastPt2DInPointSet); displayGeometry->WorldToDisplay(lastPt2DInPointSet, lastPt2DInPointSet); while(it!=end) // iterate over all points { lastP = p; // valid only for counter > 0 lastVec = vec; // valid only for counter > 1 preLastPt2d = lastPt2d; // valid only for counter > 1 lastPt2d = pt2d; // valid only for counter > 0 itk2vtk(it->Value(), vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); vec = p-lastP; // valid only for counter > 0 displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetSquaredNorm(); //MouseOrientation bool isInputDevice=false; bool isRendererSlice = scalardiff < 0.00001; //cause roundoff error if(this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice && !isRendererSlice ) { displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); //Point size depending of distance to slice /*float p_size = (1/scalardiff)*10*m_Point2DSize; if(p_size < m_Point2DSize * 0.6 ) p_size = m_Point2DSize * 0.6 ; else if ( p_size > m_Point2DSize ) p_size = m_Point2DSize;*/ float p_size = (1/scalardiff)*100.0; if(p_size < 6.0 ) p_size = 6.0 ; else if ( p_size > 10.0 ) p_size = 10.0; //draw Point float opacity = (p_size<8)?0.3:1.0;//don't get the opacity from the node? Feature not a bug! Otehrwise the 2D cross is hardly seen. glColor4f(unselectedColor[0],unselectedColor[1],unselectedColor[2],opacity); glPointSize(p_size); //glShadeModel(GL_FLAT); glBegin (GL_POINTS); glVertex2fv(&pt2d[0]); glEnd (); } //for point set if(!isInputDevice && ( (scalardiff<4.0) || (m_Polygon))) { Point2D tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector2D horz,vert; horz[0]=(float)m_Point2DSize-scalardiff*2; horz[1]=0; vert[0]=0; vert[1]=(float)m_Point2DSize-scalardiff*2; // now paint text if available if (dynamic_cast(this->GetDataNode() ->GetProperty("label")) != NULL) { const char * pointLabel = dynamic_cast( this->GetDataNode()->GetProperty("label"))->GetValue(); std::string l = pointLabel; if (input->GetSize()>1) { // char buffer[20]; // sprintf(buffer,"%d",it->Index()); std::stringstream ss; ss << it->Index(); l.append(ss.str()); } if (unselectedColor != NULL) { mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3];//yellow rgb[0] = unselectedColor[0]; rgb[1] = unselectedColor[1]; rgb[2] = unselectedColor[2]; OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,rgb[0], rgb[1],rgb[2]); } else { mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,0.0,1.0,0.0); } } if((m_ShowPoints) && (scalardiff<4.0)) { //check if the point is to be marked as selected if(selIt != selEnd || pointDataBroken) { bool addAsSelected = false; if (pointDataBroken) addAsSelected = false; else if (selIt->Value().selected) addAsSelected = true; else addAsSelected = false; if (addAsSelected) { horz[0]=(float)m_Point2DSize; vert[1]=(float)m_Point2DSize; glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]); glLineWidth(m_PointLineWidth); //a diamond around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); glEnd (); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2fv(&tmp[0]); glEnd (); } else //if not selected { glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); glLineWidth(m_PointLineWidth); //drawing crosses glBegin (GL_LINES); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); glEnd (); glLineWidth(1); } } } bool drawLinesEtc = true; if (!m_ShowDistantLines && counter > 0) // check, whether this line should be drawn { ScalarType currentDistance = displayGeometry->GetWorldGeometry()->SignedDistance(p); ScalarType lastDistance = displayGeometry->GetWorldGeometry()->SignedDistance(lastP); if ( currentDistance * lastDistance > 0.5 ) // points on same side of plane drawLinesEtc = false; } // draw a line if ((m_Polygon && counter>0 && drawLinesEtc) || (m_Polygon && m_PolygonClosed && drawLinesEtc)) { if ((counter == 0) && ( m_PolygonClosed)) { lastPt2d = lastPt2DInPointSet; } //get contour color property float contourColor[4] = {unselectedColor[0], unselectedColor[1], unselectedColor[2], unselectedColor[3]};//so if no property set, then use unselected color if (dynamic_cast(node->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(node->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } //set this color glColor3f(contourColor[0],contourColor[1],contourColor[2]); glLineWidth( m_LineWidth ); glBegin (GL_LINES); glVertex2fv(&pt2d[0]); glVertex2fv(&lastPt2d[0]); glEnd (); glLineWidth(1.0); if(m_ShowDistances) // calculate and print a distance { std::stringstream buffer; float distance = vec.GetNorm(); buffer<( renderer ); OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]); //this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer); } if(m_ShowAngles && counter > 1 ) // calculate and print the angle btw. two lines { std::stringstream buffer; //buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << "�"; buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << (char)176; Vector2D vec2d = pt2d-lastPt2d; vec2d.Normalize(); Vector2D lastVec2d = lastPt2d-preLastPt2d; lastVec2d.Normalize(); vec2d=vec2d-lastVec2d; vec2d.Normalize(); Vector2D pos2d = lastPt2d.GetVectorFromOrigin()+vec2d*text2dDistance*text2dDistance; mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]); //this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer); } } counter++; } ++it; if(selIt != selEnd && !pointDataBroken) ++selIt; j++; } //recall the color to the same color before this drawing glColor3f(recallColor[0],recallColor[1],recallColor[2]); } } void mitk::PointSetGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); // width of the line from one point to another node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); //width of the cross marking a point node->AddProperty( "point 2D size", mitk::IntProperty::New(8), renderer, overwrite ); // length of the cross marking a point // length of an edge of the box marking a point node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); // contour of the line between points node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); //show or hide points node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide distance measure (not always available) node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); //set the number of decimal digits to be shown node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide angle measurement (not always available) node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); //show the line between to points from a distant view (equals "always on top" option) node->AddProperty( "layer", mitk::IntProperty::New(1), renderer, overwrite ); // default to draw pointset above images (they have a default layer of 0) Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.h b/Core/Code/Rendering/mitkPointSetGLMapper2D.h index 67185b0e04..bf192147af 100644 --- a/Core/Code/Rendering/mitkPointSetGLMapper2D.h +++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.h @@ -1,94 +1,94 @@ /*=================================================================== 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 MITKPointSetMAPPER2D_H_HEADER_INCLUDED #define MITKPointSetMAPPER2D_H_HEADER_INCLUDED #include -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class PointSet; /** * @brief OpenGL-based mapper to display a mitk::PointSet in a 2D window. * * This mapper can actually more than just draw a number of points of a * mitk::PointSet. If you set the right properties of the mitk::DataNode, * which contains the point set, then this mapper will also draw lines * connecting the points, and calculate and display distances and angles * between adjacent points. Here is a complete list of boolean properties, * which might be of interest: * * - \b "show contour": Draw not only the points but also the connections between * them (default false) * - \b "line width": IntProperty which gives the width of the contour lines * - \b "show points": Wheter or not to draw the actual points (default true) * - \b "show distances": Wheter or not to calculate and print the distance * between adjacent points (default false) * - \b "show angles": Wheter or not to calculate and print the angle between * adjacent points (default false) * - \b "show distant lines": When true, the mapper will also draw contour * lines that are far away form the current slice (default true) * - \b "label": StringProperty with a label for this point set * * BUG 1321 - possible new features: * point-2d-size (length of lines in cross/diamond) * point-linewidth * * @ingroup Mapper */ -class MITK_CORE_EXPORT PointSetGLMapper2D : public GLMapper2D +class MITK_CORE_EXPORT PointSetGLMapper2D : public GLMapper { public: - mitkClassMacro(PointSetGLMapper2D, GLMapper2D); + mitkClassMacro(PointSetGLMapper2D, GLMapper); itkNewMacro(Self); /** @brief Get the PointDataList to map */ virtual const mitk::PointSet * GetInput(void); virtual void Paint(mitk::BaseRenderer * renderer); - virtual void ApplyProperties(mitk::BaseRenderer* renderer); + virtual void ApplyAllProperties(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: PointSetGLMapper2D(); virtual ~PointSetGLMapper2D(); bool m_Polygon; bool m_PolygonClosed; bool m_ShowPoints; bool m_ShowDistances; int m_DistancesDecimalDigits; bool m_ShowAngles; bool m_ShowDistantLines; int m_LineWidth; int m_PointLineWidth; int m_Point2DSize; }; } // namespace mitk #endif /* MITKPointSetMapper2D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp index 1760f2ad58..4e8f3b8c3d 100644 --- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp @@ -1,629 +1,624 @@ /*=================================================================== 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 "mitkPointSetVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkPointSet.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const mitk::PointSet* mitk::PointSetVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } mitk::PointSetVtkMapper3D::PointSetVtkMapper3D() : m_vtkSelectedPointList(NULL), m_vtkUnselectedPointList(NULL), m_VtkSelectedPolyDataMapper(NULL), m_VtkUnselectedPolyDataMapper(NULL), m_vtkTextList(NULL), m_NumberOfSelectedAdded(0), m_NumberOfUnselectedAdded(0), m_PointSize(1.0), m_ContourRadius(0.5) { //propassembly m_PointsAssembly = vtkSmartPointer::New(); //creating actors to be able to set transform m_SelectedActor = vtkSmartPointer::New(); m_UnselectedActor = vtkSmartPointer::New(); m_ContourActor = vtkSmartPointer::New(); } mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D() { } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin) { m_PointsAssembly->ReleaseGraphicsResources(renWin); m_SelectedActor->ReleaseGraphicsResources(renWin); m_UnselectedActor->ReleaseGraphicsResources(renWin); m_ContourActor->ReleaseGraphicsResources(renWin); } + void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects() { m_vtkSelectedPointList = vtkSmartPointer::New(); m_vtkUnselectedPointList = vtkSmartPointer::New(); m_PointsAssembly->VisibilityOn(); if(m_PointsAssembly->GetParts()->IsItemPresent(m_SelectedActor)) m_PointsAssembly->RemovePart(m_SelectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_UnselectedActor)) m_PointsAssembly->RemovePart(m_UnselectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_ContourActor)) m_PointsAssembly->RemovePart(m_ContourActor); // exceptional displaying for PositionTracker -> MouseOrientationTool int mapperID; bool isInputDevice=false; if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice ) { if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2) return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed } // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { m_PointsAssembly->VisibilityOff(); return; } mitk::PointSet::PointsContainer::Iterator pointsIter; mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; m_NumberOfSelectedAdded = 0; m_NumberOfUnselectedAdded = 0; //create contour bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { this->CreateContour(); } //now fill selected and unselected pointList //get size of Points in Property m_PointSize = 2; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if ( pointSizeProp.IsNotNull() ) m_PointSize = pointSizeProp->GetValue(); //get the property for creating a label onto every point only once bool showLabel = true; this->GetDataNode()->GetBoolProperty("show label", showLabel); const char * pointLabel=NULL; if(showLabel) { if(dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != NULL) pointLabel =dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue(); else showLabel = false; } //check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected) bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); //now add an object for each point in data pointDataIter = itkPointSet->GetPointData()->Begin(); for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End(); pointsIter++, j++) { //check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected list int pointType; if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken) pointType = mitk::PTUNDEFINED; else pointType = pointDataIter.Value().pointSpec; vtkSmartPointer source; switch (pointType) { case mitk::PTUNDEFINED: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); //sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]); //MouseOrientation Tool (PositionTracker) if(isInputDevice) { sphere->SetThetaResolution(10); sphere->SetPhiResolution(10); } else { sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); } source = sphere; } break; case mitk::PTSTART: { vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetXLength(m_PointSize/2); cube->SetYLength(m_PointSize/2); cube->SetZLength(m_PointSize/2); itk::Point point1 = pointsIter->Value(); cube->SetCenter(point1[0],point1[1],point1[2]); source = cube; } break; case mitk::PTCORNER: { vtkSmartPointer cone = vtkSmartPointer::New(); cone->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cone->SetCenter(point1[0],point1[1],point1[2]); cone->SetResolution(20); source = cone; } break; case mitk::PTEDGE: { vtkSmartPointer cylinder = vtkSmartPointer::New(); cylinder->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cylinder->SetCenter(point1[0],point1[1],point1[2]); cylinder->SetResolution(20); source = cylinder; } break; case mitk::PTEND: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); //itk::Point point1 = pointsIter->Value(); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; default: { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; } if (!pointDataBroken) { if (pointDataIter.Value().selected) { m_vtkSelectedPointList->AddInput(source->GetOutput()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInput(source->GetOutput()); ++m_NumberOfUnselectedAdded; } } else { m_vtkUnselectedPointList->AddInput(source->GetOutput()); ++m_NumberOfUnselectedAdded; } if (showLabel) { char buffer[20]; std::string l = pointLabel; if ( input->GetSize()>1 ) { sprintf(buffer,"%d",j+1); l.append(buffer); } // Define the text for the label vtkSmartPointer label = vtkSmartPointer::New(); label->SetText(l.c_str()); //# Set up a transform to move the label to a new position. vtkSmartPointer aLabelTransform = vtkSmartPointer::New(); aLabelTransform->Identity(); itk::Point point1 = pointsIter->Value(); aLabelTransform->Translate(point1[0]+2,point1[1]+2,point1[2]); aLabelTransform->Scale(5.7,5.7,5.7); //# Move the label to a new position. vtkSmartPointer labelTransform = vtkSmartPointer::New(); labelTransform->SetTransform(aLabelTransform); labelTransform->SetInput(label->GetOutput()); //add it to the wright PointList if (pointType) { m_vtkSelectedPointList->AddInput(labelTransform->GetOutput()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInput(labelTransform->GetOutput()); ++m_NumberOfUnselectedAdded; } } if(pointDataIter != itkPointSet->GetPointData()->End()) pointDataIter++; } // end FOR //now according to number of elements added to selected or unselected, build up the rendering pipeline if (m_NumberOfSelectedAdded > 0) { m_VtkSelectedPolyDataMapper = vtkSmartPointer::New(); m_VtkSelectedPolyDataMapper->SetInput(m_vtkSelectedPointList->GetOutput()); //create a new instance of the actor m_SelectedActor = vtkSmartPointer::New(); m_SelectedActor->SetMapper(m_VtkSelectedPolyDataMapper); m_PointsAssembly->AddPart(m_SelectedActor); } if (m_NumberOfUnselectedAdded > 0) { m_VtkUnselectedPolyDataMapper = vtkSmartPointer::New(); m_VtkUnselectedPolyDataMapper->SetInput(m_vtkUnselectedPointList->GetOutput()); //create a new instance of the actor m_UnselectedActor = vtkSmartPointer::New(); m_UnselectedActor->SetMapper(m_VtkUnselectedPolyDataMapper); m_PointsAssembly->AddPart(m_UnselectedActor); } } -void mitk::PointSetVtkMapper3D::GenerateData() +void mitk::PointSetVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { - //create new vtk render objects (e.g. sphere for a point) + // create new vtk render objects (e.g. sphere for a point) this->CreateVTKRenderObjects(); - //apply props - this->ApplyProperties(m_ContourActor,NULL); - -} - - -void mitk::PointSetVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) -{ SetVtkMapperImmediateModeRendering(m_VtkSelectedPolyDataMapper); SetVtkMapperImmediateModeRendering(m_VtkUnselectedPolyDataMapper); mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize")); // only create new vtk render objects if property values were changed if ( pointSizeProp.IsNotNull() && contourSizeProp.IsNotNull() ) { if (m_PointSize!=pointSizeProp->GetValue() || m_ContourRadius!= contourSizeProp->GetValue()) { this->CreateVTKRenderObjects(); } } - this->ApplyProperties(m_ContourActor,renderer); + this->ApplyAllProperties(renderer, m_ContourActor); - if(IsVisible(renderer)==false) + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if(!visible) { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); m_ContourActor->VisibilityOff(); return; } bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); if(showPoints) { m_UnselectedActor->VisibilityOn(); m_SelectedActor->VisibilityOn(); } else { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); } if(dynamic_cast(this->GetDataNode()->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetProperty("opacity")); float opacity = pointOpacity->GetValue(); m_ContourActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetOpacity(opacity); m_SelectedActor->GetProperty()->SetOpacity(opacity); } bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { m_ContourActor->VisibilityOn(); } else { m_ContourActor->VisibilityOff(); } } void mitk::PointSetVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_PointsAssembly->VisibilityOff(); } vtkProp* mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_PointsAssembly; } void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { vtkSmartPointer vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); m_SelectedActor->SetUserTransform(vtktransform); m_UnselectedActor->SetUserTransform(vtktransform); m_ContourActor->SetUserTransform(vtktransform); } -void mitk::PointSetVtkMapper3D::ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer) +void mitk::PointSetVtkMapper3D::ApplyAllProperties(mitk::BaseRenderer* renderer, vtkActor* actor) { - Superclass::ApplyProperties(actor,renderer); + Superclass::ApplyColorAndOpacityProperties(renderer, actor); //check for color props and use it for rendering of selected/unselected points and contour //due to different params in VTK (double/float) we have to convert! //vars to convert to vtkFloatingPointType unselectedColor[4]={1.0f,1.0f,0.0f,1.0f};//yellow vtkFloatingPointType selectedColor[4]={1.0f,0.0f,0.0f,1.0f};//red vtkFloatingPointType contourColor[4]={1.0f,0.0f,0.0f,1.0f};//red //different types for color!!! mitk::Color tmpColor; double opacity = 1.0; //check if there is an unselected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { //check if the node has a color float unselectedColorTMP[4]={1.0f,1.0f,0.0f,1.0f};//yellow m_DataNode->GetColor(unselectedColorTMP, NULL); unselectedColor[0] = unselectedColorTMP[0]; unselectedColor[1] = unselectedColorTMP[1]; unselectedColor[2] = unselectedColorTMP[2]; //unselectedColor[3] stays 1.0f } //get selected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } //get contour property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } if(dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } else if(dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } //finished color / opacity fishing! //check if a contour shall be drawn bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour, renderer); if(makeContour && (m_ContourActor != NULL) ) { this->CreateContour(); m_ContourActor->GetProperty()->SetColor(contourColor); m_ContourActor->GetProperty()->SetOpacity(opacity); } m_SelectedActor->GetProperty()->SetColor(selectedColor); m_SelectedActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetColor(unselectedColor); m_UnselectedActor->GetProperty()->SetOpacity(opacity); } void mitk::PointSetVtkMapper3D::CreateContour() { vtkSmartPointer vtkContourPolyData = vtkSmartPointer::New(); vtkSmartPointer vtkContourPolyDataMapper = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polys = vtkSmartPointer::New(); mitk::PointSet::PointsContainer::Iterator pointsIter; // mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { return; } for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End() ; pointsIter++,j++) { vtkIdType cell[2] = {j-1,j}; itk::Point point1 = pointsIter->Value(); points->InsertPoint(j,point1[0],point1[1],point1[2]); if (j>0) polys->InsertNextCell(2,cell); } bool close = false; this->GetDataNode()->GetBoolProperty("close contour", close); if (close) { vtkIdType cell[2] = {j-1,0}; polys->InsertNextCell(2,cell); } vtkSmartPointer contour = vtkSmartPointer::New(); contour->SetPoints(points); contour->SetLines(polys); contour->Update(); vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetNumberOfSides( 12 ); tubeFilter->SetInput(contour); //check for property contoursize. m_ContourRadius = 0.5; mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize") ); if (contourSizeProp.IsNotNull()) m_ContourRadius = contourSizeProp->GetValue(); tubeFilter->SetRadius( m_ContourRadius ); tubeFilter->Update(); //add to pipeline vtkContourPolyData->AddInput(tubeFilter->GetOutput()); vtkContourPolyDataMapper->SetInput(vtkContourPolyData->GetOutput()); m_ContourActor->SetMapper(vtkContourPolyDataMapper); m_PointsAssembly->AddPart(m_ContourActor); } void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); //red node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h index 1202fa2632..ffca0102c2 100644 --- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h +++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h @@ -1,152 +1,151 @@ /*=================================================================== 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 MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 #define MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 #include -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkBaseRenderer.h" #include class vtkActor; class vtkPropAssembly; class vtkAppendPolyData; class vtkPolyData; class vtkTubeFilter; class vtkPolyDataMapper; namespace mitk { class PointSet; /** * @brief Vtk-based mapper for PointSet * * Due to the need of different colors for selected * and unselected points and the facts, that we also have a contour and * labels for the points, the vtk structure is build up the following way: * * We have two AppendPolyData, one selected, and one unselected and one * for a contour between the points. Each one is connected to an own * PolyDaraMapper and an Actor. The different color for the unselected and * selected state and for the contour is read from properties. * * "unselectedcolor", "selectedcolor" and "contourcolor" are the strings, * that are looked for. Pointlabels are added besides the selected or the * deselected points. * * Then the three Actors are combined inside a vtkPropAssembly and this * object is returned in GetProp() and so hooked up into the rendering * pipeline. * Properties that can be set for point sets and influence the PointSetVTKMapper3D are: * * - \b "color": (ColorProperty*) Color of the point set * - \b "Opacity": (FloatProperty) Opacity of the point set * - \b "show contour": (BoolProperty) If the contour of the points are visible * - \b "contourSizeProp":(FloatProperty) Contour size of the points The default properties are: * - \b "line width": (IntProperty::New(2), renderer, overwrite ) * - \b "pointsize": (FloatProperty::New(1.0), renderer, overwrite) * - \b "selectedcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite) //red * - \b "color": (ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite) //yellow * - \b "show contour": (BoolProperty::New(false), renderer, overwrite ) * - \b "contourcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite) * - \b "contoursize": (FloatProperty::New(0.5), renderer, overwrite ) * - \b "close contour": (BoolProperty::New(false), renderer, overwrite ) * - \b "show points": (BoolProperty::New(true), renderer, overwrite ) * - \b "updateDataOnRender": (BoolProperty::New(true), renderer, overwrite ) *Other properties looked for are: * * - \b "show contour": if set to on, lines between the points are shown * - \b "close contour": if set to on, the open strip is closed (first point * connected with last point) * - \b "pointsize": size of the points mapped * - \b "label": text of the Points to show besides points * - \b "contoursize": size of the contour drawn between the points * (if not set, the pointsize is taken) * * @ingroup Mapper */ - class MITK_CORE_EXPORT PointSetVtkMapper3D : public VtkMapper3D + class MITK_CORE_EXPORT PointSetVtkMapper3D : public VtkMapper { public: - mitkClassMacro(PointSetVtkMapper3D, VtkMapper3D); + mitkClassMacro(PointSetVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::PointSet* GetInput(); //overwritten from VtkMapper3D to be able to return a //m_PointsAssembly which is much faster than a vtkAssembly virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void ReleaseGraphicsResources(vtkWindow *renWin); protected: PointSetVtkMapper3D(); virtual ~PointSetVtkMapper3D(); - virtual void GenerateData(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( BaseRenderer* renderer ); - virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); + virtual void ApplyAllProperties(mitk::BaseRenderer* renderer, vtkActor* actor); virtual void CreateContour(); virtual void CreateVTKRenderObjects(); vtkSmartPointer m_vtkSelectedPointList; vtkSmartPointer m_vtkUnselectedPointList; vtkSmartPointer m_VtkSelectedPolyDataMapper; vtkSmartPointer m_VtkUnselectedPolyDataMapper; vtkSmartPointer m_SelectedActor; vtkSmartPointer m_UnselectedActor; vtkSmartPointer m_ContourActor; vtkSmartPointer m_PointsAssembly; //help for contour between points vtkSmartPointer m_vtkTextList; //variables to be able to log, how many inputs have been added to PolyDatas unsigned int m_NumberOfSelectedAdded; unsigned int m_NumberOfUnselectedAdded; //variables to check if an update of the vtk objects is needed ScalarType m_PointSize; ScalarType m_ContourRadius; }; } // namespace mitk #endif /* MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 */ diff --git a/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp b/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp index caadd84073..920d51fec2 100644 --- a/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp +++ b/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp @@ -1,274 +1,276 @@ /*=================================================================== 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 #include "mitkPolyDataGLMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkSurface.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkAbstractTransformGeometry.h" #include "mitkVtkMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer ) { - if ( IsVisible( renderer ) == false ) - return ; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) return; // ok, das ist aus GenerateData kopiert - mitk::BaseData::Pointer input = const_cast( GetData() ); + mitk::BaseData::Pointer input = const_cast( GetDataNode()->GetData() ); assert( input ); input->Update(); vtkPolyData * vtkpolydata = this->GetVtkPolyData(); assert( vtkpolydata ); vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform(); if (vtktransform) { vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); if ( vtkpolydata != NULL ) { Point3D point; Vector3D normal; if(worldPlaneGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldPlaneGeometry->GetOrigin(); normal=worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"? return; AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast(renderer->GetCurrentWorldGeometry2D()); if(worldAbstractGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=const_cast(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } else return; } vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; vnl2vtk(point.Get_vnl_vector(), vp); vnl2vtk(normal.Get_vnl_vector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. inversetransform->TransformPoint( vp, vp ); inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal ); m_Plane->SetOrigin( vp ); m_Plane->SetNormal( vnormal ); // set data into cutter m_Cutter->SetInput( vtkpolydata ); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); // calculate the cut m_Cutter->Update(); // fetch geometry mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); // float toGL=displayGeometry->GetSizeInDisplayUnits()[1]; //apply color and opacity read from the PropertyList - ApplyProperties( renderer ); + ApplyColorAndOpacityProperties( renderer ); // traverse the cut contour vtkPolyData * contour = m_Cutter->GetOutput(); vtkPoints *vpoints = contour->GetPoints(); vtkCellArray *vpolys = contour->GetLines(); vtkPointData *vpointdata = contour->GetPointData(); vtkDataArray* vscalars = vpointdata->GetScalars(); vtkCellData *vcelldata = contour->GetCellData(); vtkDataArray* vcellscalars = vcelldata->GetScalars(); int i, numberOfCells = vpolys->GetNumberOfCells(); Point3D p; Point2D p2d, last, first; vpolys->InitTraversal(); vtkScalarsToColors* lut = GetVtkLUT(); assert ( lut != NULL ); for ( i = 0;i < numberOfCells;++i ) { vtkIdType *cell(NULL); vtkIdType cellSize(0); vpolys->GetNextCell( cellSize, cell ); if ( m_ColorByCellData ) { // color each cell according to cell data vtkFloatingPointType* color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) ); glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] ); } if ( m_ColorByPointData ) { vtkFloatingPointType* color = lut->GetColor( vscalars->GetComponent( cell[0], 0 ) ); glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] ); } glBegin ( GL_LINE_LOOP ); for ( int j = 0;j < cellSize;++j ) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd (); } } } } vtkPolyDataMapper* mitk::PolyDataGLMapper2D::GetVtkPolyDataMapper() { return NULL; /* mitk::DataNode::ConstPointer node = this->GetDataNode(); if ( node.IsNull() ) return NULL; mitk::VtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper3D* > ( node->GetMapper( 2 ) ); if ( mitkMapper.IsNull() ) return NULL; mitkMapper->Update(NULL); vtkActor* actor = dynamic_cast( mitkMapper->GetVtkProp(0) ); if ( actor == NULL ) return NULL; return dynamic_cast( actor->GetMapper() ); */ } vtkPolyData* mitk::PolyDataGLMapper2D::GetVtkPolyData( ) { vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper(); if ( polyDataMapper == NULL ) return NULL; else return polyDataMapper->GetInput(); } vtkScalarsToColors* mitk::PolyDataGLMapper2D::GetVtkLUT( ) { vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper(); if ( polyDataMapper == NULL ) return NULL; else return polyDataMapper->GetLookupTable(); } bool mitk::PolyDataGLMapper2D::IsConvertibleToVtkPolyData() { return ( GetVtkPolyDataMapper() != NULL ); } mitk::PolyDataGLMapper2D::PolyDataGLMapper2D() { m_Plane = vtkPlane::New(); m_Cutter = vtkCutter::New(); m_Cutter->SetCutFunction( m_Plane ); m_Cutter->GenerateValues( 1, 0, 1 ); m_ColorByCellData = false; m_ColorByPointData = false; //m_LUT = vtkLookupTable::New(); //m_LUT->SetTableRange( 0, 255 ); //m_LUT->SetNumberOfColors( 255 ); //m_LUT->SetRampToLinear (); //m_LUT->Build(); } mitk::PolyDataGLMapper2D::~PolyDataGLMapper2D() {} diff --git a/Core/Code/Rendering/mitkPolyDataGLMapper2D.h b/Core/Code/Rendering/mitkPolyDataGLMapper2D.h index b68f386cd3..15307b96d3 100644 --- a/Core/Code/Rendering/mitkPolyDataGLMapper2D.h +++ b/Core/Code/Rendering/mitkPolyDataGLMapper2D.h @@ -1,109 +1,109 @@ /*=================================================================== 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 MitkPolyDataGLMapper2D_H #define MitkPolyDataGLMapper2D_H #include -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" class vtkCutter; class vtkPlane; class vtkLookupTable; class vtkPolyData; class vtkScalarsToColors; class vtkPolyDataMapper; namespace mitk { class BaseRenderer; /** * @brief OpenGL-based mapper to display a 2d cut through a poly data * OpenGL-based mapper to display a 2D cut through a poly data. The result is * normally a line. This class can be added to any data object, which is * rendered in 3D via a vtkPolyData. */ -class MITK_CORE_EXPORT PolyDataGLMapper2D : public GLMapper2D +class MITK_CORE_EXPORT PolyDataGLMapper2D : public GLMapper { public: - mitkClassMacro( PolyDataGLMapper2D, GLMapper2D ); + mitkClassMacro( PolyDataGLMapper2D, GLMapper ); itkNewMacro( Self ); /** * Sets if the cut lines are colored by mapping cell data */ itkSetMacro( ColorByCellData, bool ); /** * Sets if the cut lines are colored by mapping point data */ itkSetMacro( ColorByPointData, bool ); /** * Renders a cut through a poly-data by lines. * @param renderer the render to render in. */ virtual void Paint( mitk::BaseRenderer * renderer ); protected: PolyDataGLMapper2D(); virtual ~PolyDataGLMapper2D(); /** * Determines, if the associated BaseData is mapped three-dimensionally (mapper-slot id 2) * with a class convertable to vtkPolyDataMapper(). * @returns NULL if it is not convertable or the appropriate PolyDataMapper otherwise */ virtual vtkPolyDataMapper* GetVtkPolyDataMapper(); /** * Determines the poly data object to be cut. * returns the poly data if possible, otherwise NULL. */ virtual vtkPolyData* GetVtkPolyData( ); /** * Determines the LookupTable used by the associated vtkMapper. * returns the LUT if possible, otherwise NULL. */ virtual vtkScalarsToColors* GetVtkLUT( ); /** * Checks if this mapper can be used to generate cuts through the associated * base data. * @return true if yes or false if not. */ virtual bool IsConvertibleToVtkPolyData(); vtkPlane* m_Plane; vtkCutter* m_Cutter; bool m_ColorByCellData; bool m_ColorByPointData; }; } // namespace mitk #endif /* MitkPolyDataGLMapper2D_H */ diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp index 7a40fdbde9..06cac2223f 100644 --- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp +++ b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp @@ -1,542 +1,544 @@ /*=================================================================== 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 #include "mitkSurfaceGLMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkSurface.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkVtkScalarModeProperty.h" #include "mitkAbstractTransformGeometry.h" #include "mitkLookupTableProperty.h" #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::SurfaceGLMapper2D::SurfaceGLMapper2D() : m_Plane( vtkPlane::New() ), m_Cutter( vtkCutter::New() ), m_LUT( vtkLookupTable::New() ), m_PointLocator( vtkPKdTree::New() ), m_Stripper( vtkStripper::New() ), m_DrawNormals(false), m_FrontNormalLengthInPixels(10.0), m_BackNormalLengthInPixels(10.0) { // default for normals on front side = green m_FrontSideColor[0] = 0.0; m_FrontSideColor[1] = 1.0; m_FrontSideColor[2] = 0.0; m_FrontSideColor[3] = 1.0; // default for normals on back side = red m_BackSideColor[0] = 1.0; m_BackSideColor[1] = 0.0; m_BackSideColor[2] = 0.0; m_BackSideColor[3] = 1.0; // default for line color = yellow m_LineColor[0] = 1.0; m_LineColor[1] = 1.0; m_LineColor[2] = 0.0; m_LineColor[3] = 1.0; m_Cutter->SetCutFunction(m_Plane); m_Cutter->GenerateValues(1,0,1); m_LUT->SetTableRange(0,255); m_LUT->SetNumberOfColors(255); m_LUT->SetRampToLinear(); m_LUT->Build(); } mitk::SurfaceGLMapper2D::~SurfaceGLMapper2D() { m_Plane->Delete(); m_Cutter->Delete(); m_LUT->Delete(); m_PointLocator->Delete(); m_Stripper->Delete(); } const mitk::Surface *mitk::SurfaceGLMapper2D::GetInput(void) { if(m_Surface.IsNotNull()) return m_Surface; - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } void mitk::SurfaceGLMapper2D::SetDataNode( mitk::DataNode* node ) { Superclass::SetDataNode( node ); bool useCellData; if (dynamic_cast(node->GetProperty("deprecated useCellDataForColouring")) == NULL) useCellData = false; else useCellData = dynamic_cast(node->GetProperty("deprecated useCellDataForColouring"))->GetValue(); if (!useCellData) { // search min/max point scalars over all time steps vtkFloatingPointType dataRange[2] = {0,0}; vtkFloatingPointType range[2]; Surface::Pointer input = const_cast< Surface* >(dynamic_cast( this->GetDataNode()->GetData() )); if(input.IsNull()) return; const TimeSlicedGeometry::Pointer inputTimeGeometry = input->GetTimeSlicedGeometry(); if(( inputTimeGeometry.IsNull() ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) return; for (unsigned int timestep=0; timestepGetTimeSteps(); timestep++) { vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep ); if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) continue; vtkDataArray *vpointscalars = vtkpolydata->GetPointData()->GetScalars(); if (vpointscalars) { vpointscalars->GetRange( range, 0 ); if (dataRange[0]==0 && dataRange[1]==0) { dataRange[0] = range[0]; dataRange[1] = range[1]; } else { if (range[0] < dataRange[0]) dataRange[0] = range[0]; if (range[1] > dataRange[1]) dataRange[1] = range[1]; } } } if (dataRange[1] - dataRange[0] > 0) { m_LUT->SetTableRange( dataRange ); m_LUT->Build(); } } } void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer) { - if(IsVisible(renderer)==false) return; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if(!visible) return; Surface::Pointer input = const_cast(this->GetInput()); if(input.IsNull()) return; // // get the TimeSlicedGeometry of the input object // const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry(); if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) return; if (dynamic_cast(this->GetDataNode()->GetProperty("line width")) == NULL) m_LineWidth = 1; else m_LineWidth = dynamic_cast(this->GetDataNode()->GetProperty("line width"))->GetValue(); // // get the world time // Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); assert( worldGeometry.IsNotNull() ); ScalarType time = worldGeometry->GetTimeBounds()[ 0 ]; int timestep=0; if( time > ScalarTypeNumericTraits::NonpositiveMin() ) timestep = inputTimeGeometry->MSToTimeStep( time ); // int timestep = this->GetTimestep(); if( inputTimeGeometry->IsValidTime( timestep ) == false ) return; vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep ); if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) return; PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast(worldGeometry.GetPointer()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + this->ApplyAllProperties(renderer); if (m_DrawNormals) { m_PointLocator->SetDataSet( vtkpolydata ); m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() ); } if(vtkpolydata!=NULL) { Point3D point; Vector3D normal; //Check if Lookup-Table is already given, else use standard one. vtkFloatingPointType* scalarLimits = m_LUT->GetTableRange(); vtkFloatingPointType scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1]; vtkLookupTable *lut;// = vtkLookupTable::New(); LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable(); if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); // check if the scalar range has been changed, e.g. manually, for the data tree node, and rebuild the LUT if necessary. double* oldRange = lut->GetTableRange(); if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax ) { lut->SetTableRange(scalarsMin, scalarsMax); lut->Build(); } } else { lut = m_LUT; } vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep); if(worldPlaneGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldPlaneGeometry->GetOrigin(); normal=worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast(renderer->GetCurrentWorldGeometry2D()); if(worldAbstractGeometry.IsNotNull()) { AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast(input->GetTimeSlicedGeometry()->GetGeometry3D(0)); if(surfaceAbstractGeometry.IsNotNull()) //@todo substitude by operator== after implementation, see bug id 28 { PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut); return; } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "flat plane" into a "curved plane"? return; // set up vtkPlane according to worldGeometry point=const_cast(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } } else return; } vtkFloatingPointType vp[3], vnormal[3]; vnl2vtk(point.Get_vnl_vector(), vp); vnl2vtk(normal.Get_vnl_vector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); inversetransform->TransformPoint(vp, vp); inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal); m_Plane->SetOrigin(vp); m_Plane->SetNormal(vnormal); //set data into cutter m_Cutter->SetInput(vtkpolydata); m_Cutter->Update(); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); if (m_DrawNormals) { m_Stripper->SetInput( m_Cutter->GetOutput() ); // calculate the cut m_Stripper->Update(); PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata); } else { PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata); } } } void mitk::SurfaceGLMapper2D::PaintCells(mitk::BaseRenderer* renderer, vtkPolyData* contour, const Geometry2D* worldGeometry, const DisplayGeometry* displayGeometry, vtkLinearTransform * vtktransform, vtkLookupTable *lut, vtkPolyData* original3DObject) { // deprecated settings bool usePointData = false; bool useCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", useCellData); bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); if(scalarVisibility) { VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { if( (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA) || (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT) ) { usePointData = true; } if(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA) { useCellData = true; } } else { usePointData = true; } } vtkPoints *vpoints = contour->GetPoints(); vtkDataArray *vpointscalars = contour->GetPointData()->GetScalars(); vtkCellArray *vlines = contour->GetLines(); vtkDataArray* vcellscalars = contour->GetCellData()->GetScalars(); Point3D p; Point2D p2d, last; int i, j; int numberOfLines = vlines->GetNumberOfCells(); glLineWidth( m_LineWidth ); glBegin (GL_LINES); glColor4fv(m_LineColor); double distanceSinceLastNormal(0.0); vlines->InitTraversal(); for(i=0;iGetNextCell(cellSize, cell); vpoints->GetPoint(cell[0], vp); //take transformation via vtktransform into account vtktransform->TransformPoint(vp, vp); vtk2itk(vp, p); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map(p, p2d); //convert point (until now mm and in world coordinates) to display coordinates (units ) displayGeometry->WorldToDisplay(p2d, p2d); last=p2d; for(j=1; jGetPoint(cell[j], vp); Point3D originalPoint; vtk2itk(vp, originalPoint); //take transformation via vtktransform into account vtktransform->TransformPoint(vp, vp); vtk2itk(vp, p); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map(p, p2d); //convert point (until now mm and in world coordinates) to display coordinates (units ) displayGeometry->WorldToDisplay(p2d, p2d); vtkFloatingPointType color[3]; if (useCellData && vcellscalars != NULL ) { // color each cell according to cell data lut->GetColor( vcellscalars->GetComponent(i,0),color); glColor3f(color[0],color[1],color[2]); glVertex2f(last[0], last[1]); glVertex2f(p2d[0], p2d[1]); } else if (usePointData && vpointscalars != NULL ) { lut->GetColor( vpointscalars->GetComponent(cell[j-1],0),color); glColor3f(color[0],color[1],color[2]); glVertex2f(last[0], last[1]); lut->GetColor( vpointscalars->GetComponent(cell[j],0),color); glColor3f(color[0],color[1],color[2]); glVertex2f(p2d[0], p2d[1]); } else { glVertex2f(last[0], last[1]); glVertex2f(p2d[0], p2d[1]); // draw normals ? if (m_DrawNormals && original3DObject) { distanceSinceLastNormal += sqrt((p2d[0]-last[0])*(p2d[0]-last[0]) + (p2d[1]-last[1])*(p2d[1]-last[1])); if (distanceSinceLastNormal >= 5.0) { distanceSinceLastNormal = 0.0; vtkPointData* pointData = original3DObject->GetPointData(); if (!pointData) break; vtkDataArray* normalsArray = pointData->GetNormals(); if (!normalsArray) break; // find 3D point closest to the currently drawn point double distance(0.0); vtkIdType closestPointId = m_PointLocator->FindClosestPoint(originalPoint[0], originalPoint[1], originalPoint[2], distance); if (closestPointId >= 0) { // find normal of 3D object at this 3D point double* normal = normalsArray->GetTuple3(closestPointId); double transformedNormal[3]; vtktransform->TransformNormal(normal, transformedNormal); Vector3D normalITK; vtk2itk(transformedNormal, normalITK); normalITK.Normalize(); // calculate a point (point from the cut 3D object) + (normal vector of closest point) Point3D tip3D = p + normalITK; // map this point into our 2D coordinate system Point2D tip2D; worldGeometry->Map(tip3D, tip2D); displayGeometry->WorldToDisplay(tip2D, tip2D); // calculate 2D vector from point to point+normal, normalize it to standard length Vector2D tipVectorGLFront = tip2D - p2d; tipVectorGLFront.Normalize(); tipVectorGLFront *= m_FrontNormalLengthInPixels; Vector2D tipVectorGLBack = p2d - tip2D; tipVectorGLBack.Normalize(); tipVectorGLBack *= m_BackNormalLengthInPixels; Point2D tipPoint2D = p2d + tipVectorGLFront; Point2D backTipPoint2D = p2d + tipVectorGLBack; // draw normalized mapped normal vector glColor4f(m_BackSideColor[0], m_BackSideColor[1], m_BackSideColor[2], m_BackSideColor[3]); // red backside glVertex2f(p2d[0], p2d[1]); glVertex2f(tipPoint2D[0], tipPoint2D[1]); glColor4f(m_FrontSideColor[0], m_FrontSideColor[1], m_FrontSideColor[2], m_FrontSideColor[3]); // green backside glVertex2f(p2d[0], p2d[1]); glVertex2f(backTipPoint2D[0], backTipPoint2D[1]); glColor4fv(m_LineColor); // back to line color } } } } last=p2d; } } glEnd(); glLineWidth(1.0); } void mitk::SurfaceGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", IntProperty::New(2), renderer, overwrite ); node->AddProperty( "scalar mode", VtkScalarModeProperty::New(), renderer, overwrite ); node->AddProperty( "draw normals 2D", BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "invert normals", BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "front color", ColorProperty::New(0.0, 1.0, 0.0), renderer, overwrite ); node->AddProperty( "back color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite ); node->AddProperty( "front normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite ); node->AddProperty( "back normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite ); node->AddProperty( "layer", mitk::IntProperty::New(100), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } -void mitk::SurfaceGLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer) +void mitk::SurfaceGLMapper2D::ApplyAllProperties(mitk::BaseRenderer* renderer) { - Superclass::ApplyProperties(renderer); + ApplyColorAndOpacityProperties(renderer); - GetDataNode()->GetBoolProperty("draw normals 2D", m_DrawNormals, renderer); + DataNode * node = GetDataNode(); + + if(node == NULL) + { + return; + } + + node->GetBoolProperty("draw normals 2D", m_DrawNormals, renderer); // check for color and opacity properties, use it for rendering if they exists - GetColor(m_LineColor, renderer /*, "color" */); - GetOpacity(m_LineColor[3], renderer /*, "color" */); + node->GetColor(m_LineColor, renderer, "color"); + node->GetOpacity(m_LineColor[3], renderer, "opacity"); bool invertNormals(false); - if (DataNode* node = GetDataNode()) - { - node->GetBoolProperty("invert normals", invertNormals, renderer); - } + node->GetBoolProperty("invert normals", invertNormals, renderer); if (!invertNormals) { - GetColor(m_FrontSideColor, renderer, "front color"); - GetOpacity(m_FrontSideColor[3], renderer); + node->GetColor(m_FrontSideColor, renderer, "front color"); + node->GetOpacity(m_FrontSideColor[3], renderer, "opacity"); - GetColor(m_BackSideColor, renderer, "back color"); - GetOpacity(m_BackSideColor[3], renderer); + node->GetColor(m_BackSideColor, renderer, "back color"); + node->GetOpacity(m_BackSideColor[3], renderer, "opacity"); + + node->GetFloatProperty( "front normal lenth (px)", m_FrontNormalLengthInPixels, renderer ); + node->GetFloatProperty( "back normal lenth (px)", m_BackNormalLengthInPixels, renderer ); - if (DataNode* node = GetDataNode()) - { - node->GetFloatProperty( "front normal lenth (px)", m_FrontNormalLengthInPixels, renderer ); - node->GetFloatProperty( "back normal lenth (px)", m_BackNormalLengthInPixels, renderer ); - } } else { - GetColor(m_FrontSideColor, renderer, "back color"); - GetOpacity(m_FrontSideColor[3], renderer); + node->GetColor(m_FrontSideColor, renderer, "back color"); + node->GetOpacity(m_FrontSideColor[3], renderer, "opacity"); - GetColor(m_BackSideColor, renderer, "front color"); - GetOpacity(m_BackSideColor[3], renderer); + node->GetColor(m_BackSideColor, renderer, "front color"); + node->GetOpacity(m_BackSideColor[3], renderer, "opacity"); + + node->GetFloatProperty( "back normal lenth (px)", m_FrontNormalLengthInPixels, renderer ); + node->GetFloatProperty( "front normal lenth (px)", m_BackNormalLengthInPixels, renderer ); - if (DataNode* node = GetDataNode()) - { - node->GetFloatProperty( "back normal lenth (px)", m_FrontNormalLengthInPixels, renderer ); - node->GetFloatProperty( "front normal lenth (px)", m_BackNormalLengthInPixels, renderer ); - } } } diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h b/Core/Code/Rendering/mitkSurfaceGLMapper2D.h index bab8373dfb..04630969d1 100644 --- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h +++ b/Core/Code/Rendering/mitkSurfaceGLMapper2D.h @@ -1,155 +1,155 @@ /*=================================================================== 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 MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 #define MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 #include -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" #include "mitkSurface.h" class vtkCutter; class vtkPlane; class vtkLookupTable; class vtkLinearTransform; class vtkPKdTree; class vtkStripper; namespace mitk { class BaseRenderer; class Geometry2D; class DisplayGeometry; /** * @brief OpenGL-based mapper to display a Surface in a 2D window. * * Displays a 2D cut through a Surface object (vtkPolyData). This * is basically done in two steps: * * 1. Cut a slice out of a (input) vtkPolyData object. The slice may be a flat plane (PlaneGeometry) * or a curved plane (ThinPlateSplineCurvedGeometry). The actual cutting is done by a vtkCutter. * The result of cutting is a (3D) vtkPolyData object, which contains only points and lines * describing the cut. * * 2. Paint the cut out slice by means of OpenGL. To do this, all lines of the cut object are traversed. * For each line segment, both end points are transformed from 3D into the 2D system of the associated * renderer and then drawn by OpenGL. * * There is a mode to display normals of the input surface object (see properties below). If this mode * is on, then the drawing of the 2D cut is slightly more complicated. For each line segment of the cut, * we take the end point (p2d) of this line and search the input vtkPolyData object for the closest point to p2d (p3D-input). * We then read out the surface normal for p3D-input. We map this normal into our 2D coordinate system and * then draw a line from p2d to (p2d+mapped normal). This drawing of surface normals will only work if the * input vtkPolyData actually HAS normals. If you have a vtkPolyData without normals, use the vtkPolyDataNormals * filter to generate normals. * * Properties that influence rendering are: * * - \b "color": (ColorProperty) Color of surface object * - \b "line width": (IntProperty) Width in pixels of the lines drawn. * - \b "scalar visibility": (BoolProperty) Whether point/cell data values (from vtkPolyData) should be used to influence colors * - \b "scalar mode": (BoolProperty) If "scalar visibility" is on, whether to use point data or cell data for coloring. * - \b "LookupTable": (LookupTableProperty) A lookup table to translate point/cell data values (from vtkPolyData) to colors * - \b "ScalarsRangeMinimum": (FloatProperty) Range of the lookup table * - \b "ScalarsRangeMaximum": (FloatProperty) Range of the lookup table * - \b "draw normals 2D": (BoolProperty) If true, normals are drawn (if present in vtkPolyData) * - \b "invert normals": (BoolProperty) Inverts front/back for display. * - \b "front color": (ColorProperty) Color for normals display on front side of the plane * - \b "front normal length (px)": (FloatProperty) Length of the front side normals in pixels. * - \b "back color": (ColorProperty) Color for normals display on back side of the plane * - \b "back normal length (px)": (FloatProperty) Length of the back side normals in pixels. * */ -class MITK_CORE_EXPORT SurfaceGLMapper2D : public GLMapper2D +class MITK_CORE_EXPORT SurfaceGLMapper2D : public GLMapper { public: - mitkClassMacro(SurfaceGLMapper2D, GLMapper2D); + mitkClassMacro(SurfaceGLMapper2D, GLMapper); itkNewMacro(Self); const Surface* GetInput(void); virtual void Paint(BaseRenderer* renderer); /** * @brief The Surface to map can be explicitly set by this method. * * If it is set, it is used instead of the data stored in the DataNode. * This enables to use the mapper also internally from other mappers. */ itkSetConstObjectMacro(Surface, Surface); /** * @brief Get the Surface set explicitly. * * @return NULL is returned if no Surface is set to be used instead of DataNode::GetData(). * @sa SetSurface */ itkGetConstObjectMacro(Surface, Surface); /** *\brief Overwritten to initialize lookup table for point scalar data */ void SetDataNode( DataNode* node ); /** * \brief Generate OpenGL primitives for the VTK contour held in contour. */ void PaintCells(BaseRenderer* renderer, vtkPolyData* contour, const Geometry2D* worldGeometry, const DisplayGeometry* displayGeometry, vtkLinearTransform* vtktransform, vtkLookupTable* lut = NULL, vtkPolyData* original3DObject = NULL); static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); - virtual void ApplyProperties(BaseRenderer* renderer); + virtual void ApplyAllProperties(BaseRenderer* renderer); protected: SurfaceGLMapper2D(); virtual ~SurfaceGLMapper2D(); vtkPlane* m_Plane; vtkCutter* m_Cutter; Surface::ConstPointer m_Surface; vtkLookupTable* m_LUT; int m_LineWidth; vtkPKdTree* m_PointLocator; vtkStripper* m_Stripper; bool m_DrawNormals; float m_FrontSideColor[4]; float m_BackSideColor[4]; float m_LineColor[4]; float m_FrontNormalLengthInPixels; float m_BackNormalLengthInPixels; }; } // namespace mitk #endif /* MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 */ diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp index 5eb7fb4246..8f67ca1d98 100644 --- a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp @@ -1,503 +1,504 @@ /*=================================================================== 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 "mitkSurfaceVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkLookupTableProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkClippingProperty.h" #include "mitkSmartPointerProperty.h" #include "mitkShaderProperty.h" #include "mitkShaderRepository.h" #include #include //VTK #include #include #include #include #include #include #include #include const mitk::Surface* mitk::SurfaceVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } mitk::SurfaceVtkMapper3D::SurfaceVtkMapper3D() { // m_Prop3D = vtkActor::New(); m_GenerateNormals = false; } mitk::SurfaceVtkMapper3D::~SurfaceVtkMapper3D() { // m_Prop3D->Delete(); } void mitk::SurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - bool visible = IsVisible(renderer); + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); - if(visible==false) - { - ls->m_Actor->VisibilityOff(); - return; - } - - // - // set the input-object at time t for the mapper - // - mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); - vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); - if(polydata == NULL) - { - ls->m_Actor->VisibilityOff(); - return; - } - - if ( m_GenerateNormals ) - { - ls->m_VtkPolyDataNormals->SetInput( polydata ); - ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); - } - else - { - ls->m_VtkPolyDataMapper->SetInput( polydata ); - } - - // - // apply properties read from the PropertyList - // - ApplyProperties(ls->m_Actor, renderer); - - if(visible) - ls->m_Actor->VisibilityOn(); + if(!visible) + { + ls->m_Actor->VisibilityOff(); + return; + } + + // + // set the input-object at time t for the mapper + // + mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); + vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); + if(polydata == NULL) + { + ls->m_Actor->VisibilityOff(); + return; + } + + if ( m_GenerateNormals ) + { + ls->m_VtkPolyDataNormals->SetInput( polydata ); + ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); + } + else + { + ls->m_VtkPolyDataMapper->SetInput( polydata ); + } + + // + // apply properties read from the PropertyList + // + ApplyAllProperties(renderer, ls->m_Actor); + + if(visible) + ls->m_Actor->VisibilityOn(); } void mitk::SurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } void mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer) { // Backface culling { mitk::BoolProperty::Pointer p; node->GetProperty(p, "Backface Culling", renderer); bool useCulling = false; if(p.IsNotNull()) useCulling = p->GetValue(); property->SetBackfaceCulling(useCulling); } // Colors { double ambient [3] = { 0.5,0.5,0.0 }; double diffuse [3] = { 0.5,0.5,0.0 }; double specular[3] = { 1.0,1.0,1.0 }; float coeff_ambient = 0.5f; float coeff_diffuse = 0.5f; float coeff_specular= 0.5f; float power_specular=10.0f; // Color { mitk::ColorProperty::Pointer p; node->GetProperty(p, "color", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); // Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different. specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.ambientColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); } } // Diffuse { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.diffuseColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); } } // Specular { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.specularColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient coeff { node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer); } // Diffuse coeff { node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer); } // Specular coeff { node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer); } // Specular power { node->GetFloatProperty("material.specularPower", power_specular, renderer); } property->SetAmbient( coeff_ambient ); property->SetDiffuse( coeff_diffuse ); property->SetSpecular( coeff_specular ); property->SetSpecularPower( power_specular ); property->SetAmbientColor( ambient ); property->SetDiffuseColor( diffuse ); property->SetSpecularColor( specular ); } // Render mode { // Opacity { float opacity = 1.0f; if( node->GetOpacity(opacity,renderer) ) property->SetOpacity( opacity ); } // Wireframe line width { float lineWidth = 1; node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer); property->SetLineWidth( lineWidth ); } // Representation { mitk::VtkRepresentationProperty::Pointer p; node->GetProperty(p, "material.representation", renderer); if(p.IsNotNull()) property->SetRepresentation( p->GetVtkRepresentation() ); } // Interpolation { mitk::VtkInterpolationProperty::Pointer p; node->GetProperty(p, "material.interpolation", renderer); if(p.IsNotNull()) property->SetInterpolation( p->GetVtkInterpolation() ); } } } -void mitk::SurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) +void mitk::SurfaceVtkMapper3D::ApplyAllProperties( mitk::BaseRenderer* renderer, vtkActor* actor) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Applying shading properties { - Superclass::ApplyProperties( ls->m_Actor, renderer ) ; + Superclass::ApplyColorAndOpacityProperties( renderer, ls->m_Actor ) ; // VTK Properties ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer ); // Shaders mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate); } mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } mitk::LevelWindow levelWindow; if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow")) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } else if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer)) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) ); if(scalarVisibility) { mitk::VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); } else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) ); float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 1.0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); } mitk::SmartPointerProperty::Pointer imagetextureProp; imagetextureProp = dynamic_cast< mitk::SmartPointerProperty * >( GetDataNode()->GetProperty("Surface.Texture", renderer)); if(imagetextureProp.IsNotNull()) { mitk::Image* miktTexture = dynamic_cast< mitk::Image* >( imagetextureProp->GetSmartPointer().GetPointer() ); vtkSmartPointer vtkTxture = vtkSmartPointer::New(); //Either select the first slice of a volume if(miktTexture->GetDimension(2) > 1) { MITK_WARN << "3D Textures are not supported by VTK and MITK. The first slice of the volume will be used instead!"; mitk::ImageSliceSelector::Pointer sliceselector = mitk::ImageSliceSelector::New(); sliceselector->SetSliceNr(0); sliceselector->SetChannelNr(0); sliceselector->SetTimeNr(0); sliceselector->SetInput(miktTexture); sliceselector->Update(); vtkTxture->SetInput(sliceselector->GetOutput()->GetVtkImageData()); } else //or just use the 2D image { vtkTxture->SetInput(miktTexture->GetVtkImageData()); } //pass the texture to the actor ls->m_Actor->SetTexture(vtkTxture); if(ls->m_VtkPolyDataMapper->GetInput()->GetPointData()->GetTCoords() == NULL) { MITK_ERROR << "Surface.Texture property was set, but there are no texture coordinates. Please provide texture coordinates for the vtkPolyData via vtkPolyData->GetPointData()->SetTCoords()."; } } // deprecated settings bool deprecatedUseCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData); bool deprecatedUsePointData = false; this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData); if (deprecatedUseCellData) { ls->m_VtkPolyDataMapper->SetColorModeToDefault(); ls->m_VtkPolyDataMapper->SetScalarRange(0,255); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } else if (deprecatedUsePointData) { float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 0.1; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); ls->m_VtkPolyDataMapper->SetColorModeToMapScalars(); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT; if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); //m_Actor->GetProperty()->SetInterpolationToPhong(); } // Check whether one or more ClippingProperty objects have been defined for // this node. Check both renderer specific and global property lists, since // properties in both should be considered. const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); // Add clipping planes (if any) ls->m_ClippingPlaneCollection->RemoveAllItems(); PropertyList::PropertyMap::const_iterator it; for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 ) { ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection ); } else { ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes(); } } vtkProp *mitk::SurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_Actor; } void mitk::SurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // m_Prop3D = ls->m_Actor; ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property ); if ( (clippingProperty != NULL) && (clippingProperty->GetClippingEnabled()) ) { const Point3D &origin = clippingProperty->GetOrigin(); const Vector3D &normal = clippingProperty->GetNormal(); vtkPlane *clippingPlane = vtkPlane::New(); clippingPlane->SetOrigin( origin[0], origin[1], origin[2] ); clippingPlane->SetNormal( normal[0], normal[1], normal[2] ); ls->m_ClippingPlaneCollection->AddItem( clippingPlane ); clippingPlane->UnRegister( NULL ); } } void mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // Shading { node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite ); node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite ); node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite ); //node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite ); node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite ); } // Shaders { mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite); } } void mitk::SurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite ); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0)) { node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite ); } } // Backface culling node->AddProperty( "Backface Culling", mitk::BoolProperty::New(false), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::SurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/) { /* if (m_VtkPolyDataMapper != NULL) m_VtkPolyDataMapper->SetImmediateModeRendering(on); */ } diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h index 2e55f800e5..b460eae2f8 100644 --- a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h +++ b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h @@ -1,162 +1,162 @@ /*=================================================================== 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 MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #define MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #include -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkSurface.h" #include "mitkBaseRenderer.h" #include #include #include #include #include #include namespace mitk { //##Documentation //## @brief Vtk-based mapper for Surface //## //## @ingroup Mapper /** * @brief Vtk-based mapper for Surface * * Properties that can be set for surfaces and influence the surfaceVTKMapper3D are: * * - \b "Backface Culling": True enables backface culling, which means only front-facing polygons will be visualized. False/disabled by default. * - \b "color": (ColorProperty) Diffuse color of the surface object (this property will be read when material.diffuseColor is not defined) * - \b "Opacity": (FloatProperty) Opacity of the surface object * - \b "material.ambientColor": (ColorProperty) Ambient color of the surface object * - \b "material.ambientCoefficient": ( FloatProperty) Ambient coefficient of the surface object * - \b "material.diffuseColor": ( ColorProperty) Diffuse color of the surface object * - \b "material.diffuseCoefficient": (FloatProperty) Diffuse coefficient of the surface object * - \b "material.specularColor": (ColorProperty) Specular Color of the surface object * - \b "material.specularCoefficient": (FloatProperty) Specular coefficient of the surface object * - \b "material.specularPower": (FloatProperty) Specular power of the surface object * - \b "material.interpolation": (VtkInterpolationProperty) Interpolation * - \b "material.representation": (VtkRepresentationProperty*) Representation * - \b "material.wireframeLineWidth": (FloatProperty) Width in pixels of the lines drawn. * - \b "scalar visibility": (BoolProperty) If the scarlars of the surface are visible * Properties to look for are: * * - \b "scalar visibility": if set to on, scalars assigned to the data are shown * Turn this on if using a lookup table. * - \b "ScalarsRangeMinimum": Optional. Can be used to store the scalar min, e.g. * for the level window settings. * - \b "ScalarsRangeMaximum": Optional. See above. * * There might be still some other, deprecated properties. These will not be documented anymore. * Please check the source if you really need them. * * @ingroup Mapper */ -class MITK_CORE_EXPORT SurfaceVtkMapper3D : public VtkMapper3D +class MITK_CORE_EXPORT SurfaceVtkMapper3D : public VtkMapper { public: - mitkClassMacro(SurfaceVtkMapper3D, VtkMapper3D); + mitkClassMacro(SurfaceVtkMapper3D, VtkMapper); itkNewMacro(Self); itkSetMacro(GenerateNormals, bool); itkGetMacro(GenerateNormals, bool); //enable ImmediateModeRendering for vtkMapping //yet to solve bug 1398 void SetImmediateModeRenderingOn(int on = 1); itkGetMacro(ImmediateModeRenderingOn, int); virtual const mitk::Surface* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); - virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); + virtual void ApplyAllProperties(mitk::BaseRenderer* renderer, vtkActor* actor); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: SurfaceVtkMapper3D(); virtual ~SurfaceVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( mitk::BaseRenderer* renderer ); /** Checks whether the specified property is a ClippingProperty and if yes, * adds it to m_ClippingPlaneCollection (internal method). */ virtual void CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ); bool m_GenerateNormals; //enable ImmediateModeRendering for the vtkMapper int m_ImmediateModeRenderingOn; public: class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: vtkActor* m_Actor; vtkPolyDataMapper *m_VtkPolyDataMapper; vtkPolyDataNormals *m_VtkPolyDataNormals; vtkPlaneCollection *m_ClippingPlaneCollection; itk::TimeStamp m_ShaderTimestampUpdate; LocalStorage() { m_VtkPolyDataMapper = vtkOpenGLPolyDataMapper::New(); m_VtkPolyDataNormals = vtkPolyDataNormals::New(); m_Actor = vtkActor::New(); m_ClippingPlaneCollection = vtkPlaneCollection::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); } ~LocalStorage() { m_VtkPolyDataMapper->Delete(); m_VtkPolyDataNormals->Delete(); m_Actor->Delete(); m_ClippingPlaneCollection->Delete(); } }; mitk::Mapper::LocalStorageHandler m_LSH; static void ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer); static void SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite); }; } // namespace mitk #endif /* MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 */ diff --git a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp index b21d338bf5..a99ea97659 100644 --- a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp @@ -1,707 +1,707 @@ /*=================================================================== 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 "mitkVolumeDataVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkLevelWindow.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunctionProperty.h" #include "mitkTransferFunctionInitializer.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkVtkVolumeRenderingProperty.h" #include const mitk::Image* mitk::VolumeDataVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } mitk::VolumeDataVtkMapper3D::VolumeDataVtkMapper3D() : m_Mask( NULL ) { m_PlaneSet = false; m_ClippingPlane = vtkPlane::New(); m_PlaneWidget = vtkImplicitPlaneWidget::New(); /* m_T2DMapper = vtkVolumeTextureMapper2D::New(); m_T2DMapper->SetMaximumNumberOfPlanes( 100 ); */ m_HiResMapper = vtkVolumeRayCastMapper::New(); m_HiResMapper->SetSampleDistance(1.0); // 4 rays for every pixel m_HiResMapper->IntermixIntersectingGeometryOn(); m_HiResMapper->SetNumberOfThreads( itk::MultiThreader::GetGlobalDefaultNumberOfThreads() ); /* vtkVolumeRayCastCompositeFunction* compositeFunction = vtkVolumeRayCastCompositeFunction::New(); compositeFunction->SetCompositeMethodToClassifyFirst(); m_HiResMapper->SetVolumeRayCastFunction(compositeFunction); compositeFunction->Delete(); vtkVolumeRayCastMIPFunction* mipFunction = vtkVolumeRayCastMIPFunction::New(); m_HiResMapper->SetVolumeRayCastFunction(mipFunction); mipFunction->Delete(); */ vtkFiniteDifferenceGradientEstimator* gradientEstimator = vtkFiniteDifferenceGradientEstimator::New(); m_HiResMapper->SetGradientEstimator(gradientEstimator); gradientEstimator->Delete(); m_VolumePropertyLow = vtkVolumeProperty::New(); m_VolumePropertyMed = vtkVolumeProperty::New(); m_VolumePropertyHigh = vtkVolumeProperty::New(); m_VolumeLOD = vtkLODProp3D::New(); m_VolumeLOD->VisibilityOff(); m_HiResID = m_VolumeLOD->AddLOD(m_HiResMapper,m_VolumePropertyHigh,0.0); // RayCast // m_LowResID = m_VolumeLOD->AddLOD(m_T2DMapper,m_VolumePropertyLow,0.0); // TextureMapper2D m_MedResID = m_VolumeLOD->AddLOD(m_HiResMapper,m_VolumePropertyMed,0.0); // RayCast m_Resampler = vtkImageResample::New(); m_Resampler->SetAxisMagnificationFactor(0,0.25); m_Resampler->SetAxisMagnificationFactor(1,0.25); m_Resampler->SetAxisMagnificationFactor(2,0.25); // For abort rendering mechanism m_VolumeLOD->AutomaticLODSelectionOff(); m_BoundingBox = vtkCubeSource::New(); m_BoundingBox->SetXLength( 0.0 ); m_BoundingBox->SetYLength( 0.0 ); m_BoundingBox->SetZLength( 0.0 ); m_BoundingBoxMapper = vtkPolyDataMapper::New(); m_BoundingBoxMapper->SetInput( m_BoundingBox->GetOutput() ); m_BoundingBoxActor = vtkActor::New(); m_BoundingBoxActor->SetMapper( m_BoundingBoxMapper ); m_BoundingBoxActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 ); m_BoundingBoxActor->GetProperty()->SetRepresentationToWireframe(); // BoundingBox rendering is not working due to problem with assembly // transformation; see bug #454 // If commenting in the following, do not forget to comment in the // m_Prop3DAssembly->Delete() line in the destructor. //m_Prop3DAssembly = vtkAssembly::New(); //m_Prop3DAssembly->AddPart( m_VolumeLOD ); //m_Prop3DAssembly->AddPart( m_BoundingBoxActor ); //m_Prop3D = m_Prop3DAssembly; m_ImageCast = vtkImageShiftScale::New(); m_ImageCast->SetOutputScalarTypeToUnsignedShort(); m_ImageCast->ClampOverflowOn(); m_UnitSpacingImageFilter = vtkImageChangeInformation::New(); m_UnitSpacingImageFilter->SetInput(m_ImageCast->GetOutput()); m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 ); m_ImageMaskFilter = vtkImageMask::New(); m_ImageMaskFilter->SetMaskedOutputValue(0xffff); this->m_Resampler->SetInput( this->m_UnitSpacingImageFilter->GetOutput() ); this->m_HiResMapper->SetInput( this->m_UnitSpacingImageFilter->GetOutput() ); // m_T2DMapper->SetInput(m_Resampler->GetOutput()); this->CreateDefaultTransferFunctions(); } vtkProp *mitk::VolumeDataVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_VolumeLOD; } mitk::VolumeDataVtkMapper3D::~VolumeDataVtkMapper3D() { m_UnitSpacingImageFilter->Delete(); m_ImageCast->Delete(); // m_T2DMapper->Delete(); m_HiResMapper->Delete(); m_Resampler->Delete(); m_VolumePropertyLow->Delete(); m_VolumePropertyMed->Delete(); m_VolumePropertyHigh->Delete(); m_VolumeLOD->Delete(); m_ClippingPlane->Delete(); m_PlaneWidget->Delete(); // m_Prop3DAssembly->Delete(); m_BoundingBox->Delete(); m_BoundingBoxMapper->Delete(); m_BoundingBoxActor->Delete(); m_ImageMaskFilter->Delete(); m_DefaultColorTransferFunction->Delete(); m_DefaultOpacityTransferFunction->Delete(); m_DefaultGradientTransferFunction->Delete(); if (m_Mask) { m_Mask->Delete(); } } void mitk::VolumeDataVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { SetVtkMapperImmediateModeRendering(m_BoundingBoxMapper); mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); if ( !input || !input->IsInitialized() ) return; vtkRenderWindow* renderWindow = renderer->GetRenderWindow(); bool volumeRenderingEnabled = true; - if (this->IsVisible(renderer)==false || + bool visible = true; + + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible || this->GetDataNode() == NULL || dynamic_cast(GetDataNode()->GetProperty("volumerendering",renderer))==NULL || dynamic_cast(GetDataNode()->GetProperty("volumerendering",renderer))->GetValue() == false ) { volumeRenderingEnabled = false; // Check if a bounding box should be displayed around the dataset // (even if volume rendering is disabled) bool hasBoundingBox = false; this->GetDataNode()->GetBoolProperty( "bounding box", hasBoundingBox ); if ( !hasBoundingBox ) { m_BoundingBoxActor->VisibilityOff(); } else { m_BoundingBoxActor->VisibilityOn(); const BoundingBox::BoundsArrayType &bounds = input->GetTimeSlicedGeometry()->GetBounds(); m_BoundingBox->SetBounds( bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5] ); ColorProperty *colorProperty; if ( this->GetDataNode()->GetProperty( colorProperty, "color" ) ) { const mitk::Color &color = colorProperty->GetColor(); m_BoundingBoxActor->GetProperty()->SetColor( color[0], color[1], color[2] ); } else { m_BoundingBoxActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 ); } } } // Don't do anything if VR is disabled if ( !volumeRenderingEnabled ) { m_VolumeLOD->VisibilityOff(); return; } else { mitk::VtkVolumeRenderingProperty* vrp=dynamic_cast(GetDataNode()->GetProperty("volumerendering configuration",renderer)); if(vrp) { int renderingValue = vrp->GetValueAsId(); switch(renderingValue) { case VTK_VOLUME_RAY_CAST_MIP_FUNCTION: { vtkVolumeRayCastMIPFunction* mipFunction = vtkVolumeRayCastMIPFunction::New(); m_HiResMapper->SetVolumeRayCastFunction(mipFunction); mipFunction->Delete(); MITK_INFO <<"in switch" <SetCompositeMethodToClassifyFirst(); m_HiResMapper->SetVolumeRayCastFunction(compositeFunction); compositeFunction->Delete(); break; } default: MITK_ERROR <<"Warning: invalid volume rendering option. " << std::endl; } } m_VolumeLOD->VisibilityOn(); } this->SetPreferences(); /* switch ( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) ) { case 0: m_VolumeLOD->SetSelectedLODID(m_MedResID); m_LowResID ); break; default: case 1: m_VolumeLOD->SetSelectedLODID( m_HiResID ); break; } */ m_VolumeLOD->SetSelectedLODID( m_HiResID ); assert(input->GetTimeSlicedGeometry()); const Geometry3D* worldgeometry = renderer->GetCurrentWorldGeometry(); if(worldgeometry==NULL) { GetDataNode()->SetProperty("volumerendering",mitk::BoolProperty::New(false)); return; } vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() ); if(inputData==NULL) return; m_ImageCast->SetInput( inputData ); //If mask exists, process mask before resampling. if (this->m_Mask) { this->m_ImageMaskFilter->SetImageInput(this->m_UnitSpacingImageFilter->GetOutput()); this->m_Resampler->SetInput(this->m_ImageMaskFilter->GetOutput()); this->m_HiResMapper->SetInput(this->m_ImageMaskFilter->GetOutput()); } else { this->m_Resampler->SetInput(this->m_UnitSpacingImageFilter->GetOutput()); this->m_HiResMapper->SetInput(this->m_UnitSpacingImageFilter->GetOutput()); } this->UpdateTransferFunctions( renderer ); vtkRenderWindowInteractor *interactor = renderWindow->GetInteractor(); float frameRate; if( this->GetDataNode()->GetFloatProperty( "framerate", frameRate ) && frameRate > 0 && frameRate <= 60) { interactor->SetDesiredUpdateRate( frameRate ); interactor->SetStillUpdateRate( frameRate ); } else if( frameRate > 60 ) { this->GetDataNode()->SetProperty( "framerate",mitk::FloatProperty::New(60)); interactor->SetDesiredUpdateRate( 60 ); interactor->SetStillUpdateRate( 60 ); } else { this->GetDataNode()->SetProperty( "framerate",mitk::FloatProperty::New(0.00001)); interactor->SetDesiredUpdateRate( 0.00001 ); interactor->SetStillUpdateRate( 0.00001 ); } if ( m_RenderWindowInitialized.find( renderWindow ) == m_RenderWindowInitialized.end() ) { m_RenderWindowInitialized.insert( renderWindow ); // mitk::RenderingManager::GetInstance()->SetNextLOD( 0, renderer ); mitk::RenderingManager::GetInstance()->SetShading( true, 0 ); mitk::RenderingManager::GetInstance()->SetShading( true, 1 ); //mitk::RenderingManager::GetInstance()->SetShading( true, 2 ); mitk::RenderingManager::GetInstance()->SetShadingValues( m_VolumePropertyHigh->GetAmbient(), m_VolumePropertyHigh->GetDiffuse(), m_VolumePropertyHigh->GetSpecular(), m_VolumePropertyHigh->GetSpecularPower()); mitk::RenderingManager::GetInstance()->SetClippingPlaneStatus(false); } this->SetClippingPlane( interactor ); } void mitk::VolumeDataVtkMapper3D::CreateDefaultTransferFunctions() { m_DefaultOpacityTransferFunction = vtkPiecewiseFunction::New(); m_DefaultOpacityTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultOpacityTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultOpacityTransferFunction->ClampingOn(); m_DefaultGradientTransferFunction = vtkPiecewiseFunction::New(); m_DefaultGradientTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultGradientTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultGradientTransferFunction->ClampingOn(); m_DefaultColorTransferFunction = vtkColorTransferFunction::New(); m_DefaultColorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 127.5, 1, 1, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 255.0, 0.8, 0.2, 0 ); m_DefaultColorTransferFunction->ClampingOn(); } void mitk::VolumeDataVtkMapper3D::UpdateTransferFunctions( mitk::BaseRenderer *renderer ) { vtkPiecewiseFunction *opacityTransferFunction = NULL; vtkPiecewiseFunction *gradientTransferFunction = NULL; vtkColorTransferFunction *colorTransferFunction = NULL; mitk::LookupTableProperty::Pointer lookupTableProp; lookupTableProp = dynamic_cast(this->GetDataNode()->GetProperty("LookupTable")); mitk::TransferFunctionProperty::Pointer transferFunctionProp = dynamic_cast(this->GetDataNode()->GetProperty("TransferFunction")); if ( transferFunctionProp.IsNotNull() ) { opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction(); gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction(); colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction(); } else if (lookupTableProp.IsNotNull() ) { lookupTableProp->GetLookupTable()->CreateOpacityTransferFunction(opacityTransferFunction); opacityTransferFunction->ClampingOn(); lookupTableProp->GetLookupTable()->CreateGradientTransferFunction(gradientTransferFunction); gradientTransferFunction->ClampingOn(); lookupTableProp->GetLookupTable()->CreateColorTransferFunction(colorTransferFunction); colorTransferFunction->ClampingOn(); } else { opacityTransferFunction = m_DefaultOpacityTransferFunction; gradientTransferFunction = m_DefaultGradientTransferFunction; colorTransferFunction = m_DefaultColorTransferFunction; float rgb[3]={1.0f,1.0f,1.0f}; // check for color prop and use it for rendering if it exists - if(GetColor(rgb, renderer)) + if(GetDataNode()->GetColor(rgb, renderer, "color")) { colorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); colorTransferFunction->AddRGBPoint( 127.5, rgb[0], rgb[1], rgb[2] ); colorTransferFunction->AddRGBPoint( 255.0, rgb[0], rgb[1], rgb[2] ); } } if (this->m_Mask) { opacityTransferFunction->AddPoint(0xffff, 0.0); } m_VolumePropertyLow->SetColor( colorTransferFunction ); m_VolumePropertyLow->SetScalarOpacity( opacityTransferFunction ); m_VolumePropertyLow->SetGradientOpacity( gradientTransferFunction ); m_VolumePropertyLow->SetInterpolationTypeToNearest(); m_VolumePropertyMed->SetColor( colorTransferFunction ); m_VolumePropertyMed->SetScalarOpacity( opacityTransferFunction ); m_VolumePropertyMed->SetGradientOpacity( gradientTransferFunction ); m_VolumePropertyMed->SetInterpolationTypeToNearest(); m_VolumePropertyHigh->SetColor( colorTransferFunction ); m_VolumePropertyHigh->SetScalarOpacity( opacityTransferFunction ); m_VolumePropertyHigh->SetGradientOpacity( gradientTransferFunction ); m_VolumePropertyHigh->SetInterpolationTypeToLinear(); } /* Shading enabled / disabled */ void mitk::VolumeDataVtkMapper3D::SetPreferences() { //LOD 0 /*if(mitk::RenderingManager::GetInstance()->GetShading(0)) { m_VolumePropertyLow->ShadeOn(); m_VolumePropertyLow->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]); m_VolumePropertyLow->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]); m_VolumePropertyLow->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]); m_VolumePropertyLow->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]); } else*/ { m_VolumePropertyLow->ShadeOff(); } //LOD 1 /*if(mitk::RenderingManager::GetInstance()->GetShading(1)) { m_VolumePropertyMed->ShadeOn(); m_VolumePropertyMed->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]); m_VolumePropertyMed->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]); m_VolumePropertyMed->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]); m_VolumePropertyMed->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]); } else*/ { m_VolumePropertyMed->ShadeOff(); } //LOD 2 /* if(mitk::RenderingManager::GetInstance()->GetShading(2)) { m_VolumePropertyHigh->ShadeOn(); //Shading Properties m_VolumePropertyHigh->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]); m_VolumePropertyHigh->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]); m_VolumePropertyHigh->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]); m_VolumePropertyHigh->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]); } else { m_VolumePropertyHigh->ShadeOff(); } */ } /* Adds A Clipping Plane to the Mapper */ void mitk::VolumeDataVtkMapper3D::SetClippingPlane(vtkRenderWindowInteractor* interactor) { if(mitk::RenderingManager::GetInstance()->GetClippingPlaneStatus()) //if clipping plane is enabled { if(!m_PlaneSet) { m_PlaneWidget->SetInteractor(interactor); m_PlaneWidget->SetPlaceFactor(1.0); m_PlaneWidget->SetInput(m_UnitSpacingImageFilter->GetOutput()); m_PlaneWidget->OutlineTranslationOff(); //disables scaling of the bounding box m_PlaneWidget->ScaleEnabledOff(); //disables scaling of the bounding box m_PlaneWidget->DrawPlaneOff(); //clipping plane is transparent mitk::Image* input = const_cast(this->GetInput()); /*places the widget within the specified bounds*/ m_PlaneWidget->PlaceWidget( input->GetGeometry()->GetOrigin()[0],(input->GetGeometry()->GetOrigin()[0])+(input->GetDimension(0))*(input->GetVtkImageData()->GetSpacing()[0]), input->GetGeometry()->GetOrigin()[1],(input->GetGeometry()->GetOrigin()[1])+(input->GetDimension(1))*(input->GetVtkImageData()->GetSpacing()[1]), input->GetGeometry()->GetOrigin()[2],(input->GetGeometry()->GetOrigin()[2])+(input->GetDimension(2))*(input->GetVtkImageData()->GetSpacing()[2])); // m_T2DMapper->AddClippingPlane(m_ClippingPlane); m_HiResMapper->AddClippingPlane(m_ClippingPlane); } m_PlaneWidget->GetPlane(m_ClippingPlane); m_PlaneSet = true; } else //if clippingplane is disabled { if(m_PlaneSet) //if plane exists { DelClippingPlane(); } } } /* Removes the clipping plane */ void mitk::VolumeDataVtkMapper3D::DelClippingPlane() { // m_T2DMapper->RemoveAllClippingPlanes(); m_HiResMapper->RemoveAllClippingPlanes(); m_PlaneSet = false; } -void mitk::VolumeDataVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* /*renderer*/) -{ - -} void mitk::VolumeDataVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "volumerendering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering configuration", mitk::VtkVolumeRenderingProperty::New( 1 ), renderer, overwrite ); node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite ); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL)) { mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetAuto( image ); levWinProp->SetLevelWindow( levelwindow ); node->SetProperty( "levelwindow", levWinProp, renderer ); } //This mapper used to set a default lut "LookupTable" for images. However, this will //overwrite the default lut of the 2D image mapper. Thus, this property here is renamed. /* if((overwrite) || (node->GetProperty("Volume.LookupTable", renderer)==NULL)) { // add a default rainbow lookup table for color mapping mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable(); vtkLut->SetHueRange(0.6667, 0.0); vtkLut->SetTableRange(0.0, 20.0); vtkLut->Build(); mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); mitkLutProp->SetLookupTable(mitkLut); node->SetProperty( "Volume.LookupTable", mitkLutProp ); }*/ if((overwrite) || (node->GetProperty("TransferFunction", renderer)==NULL)) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf); tfInit->SetTransferFunctionMode(0); node->SetProperty ( "TransferFunction", mitk::TransferFunctionProperty::New ( tf.GetPointer() ) ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } bool mitk::VolumeDataVtkMapper3D::IsLODEnabled( mitk::BaseRenderer * /*renderer*/ ) const { return false; // Volume mapper is LOD enabled if volumerendering is enabled /* return dynamic_cast(GetDataNode()->GetProperty("volumerendering",renderer)) != NULL && dynamic_cast(GetDataNode()->GetProperty("volumerendering",renderer))->GetValue() == true; */ } void mitk::VolumeDataVtkMapper3D::EnableMask() { if (!this->m_Mask) { const Image *orig_image = this->GetInput(); unsigned int *dimensions = orig_image->GetDimensions(); this->m_Mask = vtkImageData::New(); this->m_Mask->SetDimensions(dimensions[0], dimensions[1], dimensions[2]); this->m_Mask->SetScalarTypeToUnsignedChar(); this->m_Mask->SetNumberOfScalarComponents(1); this->m_Mask->AllocateScalars(); unsigned char *mask_data = static_cast(this->m_Mask->GetScalarPointer()); unsigned int size = dimensions[0] * dimensions[1] * dimensions[2]; for (unsigned int i = 0u; i < size; ++i) { *mask_data++ = 1u; } this->m_ImageMaskFilter->SetMaskInput(this->m_Mask); this->m_ImageMaskFilter->Modified(); } } void mitk::VolumeDataVtkMapper3D::DisableMask() { if (this->m_Mask) { this->m_Mask->Delete(); this->m_Mask = 0; } } mitk::Image::Pointer mitk::VolumeDataVtkMapper3D::GetMask() { if (this->m_Mask) { Image::Pointer mask = Image::New(); mask->Initialize(this->m_Mask); mask->SetImportVolume(this->m_Mask->GetScalarPointer(), 0, 0, Image::ReferenceMemory); mask->SetGeometry(this->GetInput()->GetGeometry()); return mask; } return 0; } void mitk::VolumeDataVtkMapper3D::UpdateMask() { if (this->m_Mask) { this->m_ImageMaskFilter->Modified(); } } bool mitk::VolumeDataVtkMapper3D::SetMask(const mitk::Image* mask) { if (this->m_Mask) { if ( (mask->GetPixelType().GetTypeId() == typeid(unsigned char)) &&(mask->GetPixelType().GetPixelTypeId() == itk::ImageIOBase::SCALAR )) { Image *img = const_cast(mask); this->m_Mask->DeepCopy(img->GetVtkImageData()); this->m_ImageMaskFilter->Modified(); return true; } } return false; } diff --git a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h index 2ea5461dd1..4cf0ec6e99 100644 --- a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h +++ b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h @@ -1,150 +1,148 @@ /*=================================================================== 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 MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED #define MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED #include -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkBaseRenderer.h" #include "mitkImage.h" #include #include #include #include #include #include #include class vtkAssembly; class vtkVolumeRayCastMapper; class vtkFixedPointVolumeRayCastMapper; class vtkVolumeTextureMapper2D; class vtkVolumeMapper; class vtkVolume; class vtkObject; class vtkImageShiftScale; class vtkImageChangeInformation; class vtkLODProp3D; class vtkImageResample; class vtkCubeSource; class vtkPolyDataMapper; class vtkActor; namespace mitk { /************************************************************************/ /* Properties that influence the mapper are: * * - \b "level window": for the level window of the volume data * - \b "LookupTable" : for the lookup table of the volume data * - \b "TransferFunction" (mitk::TransferFunctionProperty): for the used transfer function of the volume data ************************************************************************/ //##Documentation //## @brief Vtk-based mapper for VolumeData //## //## @ingroup Mapper -class MITK_CORE_EXPORT VolumeDataVtkMapper3D : public VtkMapper3D +class MITK_CORE_EXPORT VolumeDataVtkMapper3D : public VtkMapper { public: - mitkClassMacro(VolumeDataVtkMapper3D, VtkMapper3D); + mitkClassMacro(VolumeDataVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::Image* GetInput(); - virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); - virtual void EnableMask(); virtual void DisableMask(); Image::Pointer GetMask(); bool SetMask(const Image* mask); virtual void UpdateMask(); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer *renderer = NULL ) const; virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); protected: VolumeDataVtkMapper3D(); virtual ~VolumeDataVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); void CreateDefaultTransferFunctions(); void UpdateTransferFunctions( mitk::BaseRenderer *renderer ); void SetPreferences(); void SetClippingPlane(vtkRenderWindowInteractor* interactor); void DelClippingPlane(); vtkImageShiftScale* m_ImageCast; vtkImageChangeInformation* m_UnitSpacingImageFilter; vtkVolumeProperty* m_VolumePropertyLow; vtkVolumeProperty* m_VolumePropertyMed; vtkVolumeProperty* m_VolumePropertyHigh; vtkVolumeTextureMapper2D* m_T2DMapper; vtkVolumeRayCastMapper* m_HiResMapper; vtkImageResample* m_Resampler; vtkLODProp3D* m_VolumeLOD; vtkCubeSource *m_BoundingBox; vtkPolyDataMapper *m_BoundingBoxMapper; vtkActor *m_BoundingBoxActor; vtkAssembly *m_Prop3DAssembly; vtkPlane* m_ClippingPlane; vtkImplicitPlaneWidget* m_PlaneWidget; vtkImageData *m_Mask; vtkImageMask *m_ImageMaskFilter; vtkPiecewiseFunction *m_DefaultOpacityTransferFunction; vtkPiecewiseFunction *m_DefaultGradientTransferFunction; vtkColorTransferFunction *m_DefaultColorTransferFunction; int m_LowResID; int m_MedResID; int m_HiResID; bool m_PlaneSet; double m_PlaneNormalA; double m_PlaneNormalB; double m_PlaneNormalC; std::set< vtkRenderWindow * > m_RenderWindowInitialized; }; } // namespace mitk #endif /* MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkVtkMapper.cpp b/Core/Code/Rendering/mitkVtkMapper.cpp new file mode 100644 index 0000000000..a272fba01e --- /dev/null +++ b/Core/Code/Rendering/mitkVtkMapper.cpp @@ -0,0 +1,129 @@ +/*=================================================================== + +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 "mitkVtkMapper.h" + +mitk::VtkMapper::VtkMapper() +{ +} + +mitk::VtkMapper::~VtkMapper() +{ +} + +void mitk::VtkMapper::MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type){ + + switch(type) + { + case mitk::VtkPropRenderer::Opaque: this->MitkRenderOpaqueGeometry(renderer); break; + case mitk::VtkPropRenderer::Translucent: this->MitkRenderTranslucentGeometry(renderer); break; + case mitk::VtkPropRenderer::Overlay: this->MitkRenderOverlay(renderer); break; + case mitk::VtkPropRenderer::Volumetric: this->MitkRenderVolumetricGeometry(renderer); break; + } +} + +bool mitk::VtkMapper::IsVtkBased() const +{ + return true; +} + +void mitk::VtkMapper::MitkRenderOverlay(BaseRenderer* renderer) +{ + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if ( !visible) return; + + if ( this->GetVtkProp(renderer)->GetVisibility() ) + { + GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); + } +} + +void mitk::VtkMapper::MitkRenderOpaqueGeometry(BaseRenderer* renderer) +{ + bool visible = true; + + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if ( !visible) return; + + if ( this->GetVtkProp(renderer)->GetVisibility() ) + { + GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); + } +} + +void mitk::VtkMapper::MitkRenderTranslucentGeometry(BaseRenderer* renderer) +{ + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if ( !visible) return; + + if ( this->GetVtkProp(renderer)->GetVisibility() ) + { + GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); + } +} + +void mitk::VtkMapper::MitkRenderVolumetricGeometry(BaseRenderer* renderer) +{ + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if ( !visible) return; + + if ( GetVtkProp(renderer)->GetVisibility() ) + { + GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); + } +} + +bool mitk::VtkMapper::HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ) +{ + vtkProp *myProp = this->GetVtkProp( renderer ); + + // TODO: check if myProp is a vtkAssembly and if so, check if prop is contained in its leafs + return ( prop == myProp ); +} + +void mitk::VtkMapper::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) +{ + if(mapper) + mapper->SetImmediateModeRendering(mitk::VtkPropRenderer::useImmediateModeRendering()); +} + +void mitk::VtkMapper::UpdateVtkTransform(mitk::BaseRenderer *renderer) +{ + vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(this->GetTimestep()); + + vtkProp3D *prop = dynamic_cast( GetVtkProp(renderer) ); + if(prop) + prop->SetUserTransform(vtktransform); +} + +void mitk::VtkMapper::ApplyColorAndOpacityProperties(BaseRenderer* renderer, vtkActor* actor) +{ + float rgba[4]={1.0f,1.0f,1.0f,1.0f}; + DataNode * node = GetDataNode(); + + // check for color prop and use it for rendering if it exists + node->GetColor(rgba, renderer, "color"); + // check for opacity prop and use it for rendering if it exists + node->GetOpacity(rgba[3], renderer, "opacity"); + + double drgba[4]={rgba[0],rgba[1],rgba[2],rgba[3]}; + actor->GetProperty()->SetColor(drgba); + actor->GetProperty()->SetOpacity(drgba[3]); +} diff --git a/Core/Code/Rendering/mitkVtkMapper.h b/Core/Code/Rendering/mitkVtkMapper.h new file mode 100644 index 0000000000..5d6f24a6f2 --- /dev/null +++ b/Core/Code/Rendering/mitkVtkMapper.h @@ -0,0 +1,145 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// change number +#ifndef VTKMAPPER_H_HEADER_INCLUDED_C1C5453B +#define VTKMAPPER_H_HEADER_INCLUDED_C1C5453B + +#include +#include "mitkMapper.h" +#include "mitkBaseRenderer.h" +#include "mitkDataNode.h" +#include "mitkVtkPropRenderer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +class vtkProp; +class vtkProp3D; +class vtkActor; + +namespace mitk { + +/** \brief Base class of all Vtk Mappers in order to display primitives +* by exploiting Vtk functionality. +* +* Rendering of opaque, translucent or volumetric geometry and overlays +* is done in consecutive render passes. +* +* \ingroup Mapper +*/ +class MITK_CORE_EXPORT VtkMapper : public Mapper +{ + public: + mitkClassMacro(VtkMapper,Mapper); + + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) = 0; + + /** \brief Re-issues all drawing commands required to describe + * the entire scene each time a new frame is required, + * regardless of actual changes. + */ + static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); + + /** + * \brief Returns whether this is an vtk-based mapper + * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead + */ + DEPRECATED( virtual bool IsVtkBased() const ); + + + /** \brief Determines which geometry should be rendered + * (opaque, translucent, volumetric, overlay) + * and calls the appropriate function. + * + * Called by mitk::VtkPropRenderer::Render + */ + void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); + + /** \brief Checks visibility and renders the overlay */ + virtual void MitkRenderOverlay(BaseRenderer* renderer); + + /** \brief Checks visibility and renders untransparent geometry */ + virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); + + /** \brief Checks visiblity and renders transparent geometry */ + virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); + + /** \brief Checks visibility and renders volumes */ + virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); + + /** \brief Returns true if this mapper owns the specified vtkProp for + * the given BaseRenderer. + * + * Note: returns false by default; should be implemented for VTK-based + * Mapper subclasses. */ + virtual bool HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ); + + /** \brief Set the vtkTransform of the m_Prop3D for + * the current time step of \a renderer + * + * Called by mitk::VtkPropRenderer::Update before rendering + */ + virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); + + /** + * \brief Apply color and opacity properties read from the PropertyList + * @deprecated Use ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor) instead + */ + DEPRECATED(inline virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer) + { + ApplyColorAndOpacityProperties(renderer, actor); + }); + + /** + * \brief Apply color and opacity properties read from the PropertyList. + * Called by mapper subclasses. + */ + virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor); + + /** + * \brief Release vtk-based graphics resources that are being consumed by this mapper. + * The parameter window could be used to determine which graphic + * resources to releases. Must be overwritten in individual subclasses + * if vtkProps are used. + */ + virtual void ReleaseGraphicsResources(vtkWindow *renWin) { }; + + protected: + + /** constructor */ + VtkMapper(); + + /** virtual destructor in order to derive from this class */ + virtual ~VtkMapper(); + + private: + + /** copy constructor */ + VtkMapper( const VtkMapper &); + + /** assignment operator */ + VtkMapper & operator=(const VtkMapper &); + +}; +} // namespace mitk +#endif /* VTKMAPPER_H_HEADER_INCLUDED_C1C5453B */ diff --git a/Core/Code/Rendering/mitkVtkMapper2D.cpp b/Core/Code/Rendering/mitkVtkMapper2D.cpp deleted file mode 100644 index 61761927b9..0000000000 --- a/Core/Code/Rendering/mitkVtkMapper2D.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*=================================================================== - -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 "mitkVtkMapper2D.h" - -mitk::VtkMapper2D::VtkMapper2D() -{ - -} - - -mitk::VtkMapper2D::~VtkMapper2D() -{ -} - diff --git a/Core/Code/Rendering/mitkVtkMapper2D.h b/Core/Code/Rendering/mitkVtkMapper2D.h index 90134f196d..f9db3be352 100644 --- a/Core/Code/Rendering/mitkVtkMapper2D.h +++ b/Core/Code/Rendering/mitkVtkMapper2D.h @@ -1,55 +1,32 @@ /*=================================================================== 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 BASEVTKMAPPER2D_H_HEADER_INCLUDED #define BASEVTKMAPPER2D_H_HEADER_INCLUDED -#include "mitkMapper2D.h" - -class vtkProp; +#include "mitkVtkMapper.h" namespace mitk { - //##Documentation - //## @brief Base class of all vtk-based 2D-Mappers - //## - //## Those must implement the abstract - //## method vtkProp* GetProp(). - //## @ingroup Mapper - class MITK_CORE_EXPORT VtkMapper2D : public Mapper2D - { - public: - mitkClassMacro(VtkMapper2D,Mapper2D); - virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) = 0; - - /** - * \brief Returns whether this is an vtk-based mapper - */ - virtual bool IsVtkBased() const { return true; } - - protected: - VtkMapper2D(); - - virtual ~VtkMapper2D(); - - }; + // typedef allows integration of mappers into the new mapper architecture + // @deprecated Use VtkMapper instead. + DEPRECATED(typedef VtkMapper VtkMapper2D); } // namespace mitk - #endif /* BASEVTKMAPPER2D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkVtkMapper3D.cpp b/Core/Code/Rendering/mitkVtkMapper3D.cpp deleted file mode 100644 index 8c6bb0ddb5..0000000000 --- a/Core/Code/Rendering/mitkVtkMapper3D.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/*=================================================================== - -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 "mitkVtkMapper3D.h" -#include "mitkDataNode.h" -#include "mitkProperties.h" -#include "mitkAnnotationProperty.h" -#include "mitkVtkPropRenderer.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace mitk -{ - -VtkMapper3D::VtkMapper3D() -{ -} - - -VtkMapper3D::~VtkMapper3D() -{ -} - -void VtkMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) -{ - if(mapper) - mapper->SetImmediateModeRendering(mitk::VtkPropRenderer::useImmediateModeRendering()); -} - - -void VtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer *renderer) -{ - vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(this->GetTimestep()); - - vtkProp3D *prop = dynamic_cast( GetVtkProp(renderer) ); - if(prop) - prop->SetUserTransform(vtktransform); -} - - -void VtkMapper3D::MitkRenderOpaqueGeometry(BaseRenderer* renderer) -{ - if ( this->IsVisible( renderer )==false ) - return; - - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); - } -} - -void VtkMapper3D::MitkRenderTranslucentGeometry(BaseRenderer* renderer) -{ - if ( this->IsVisible(renderer)==false ) - return; - - /* if(dynamic_cast(m_Prop3D) != NULL) - { - if( dynamic_cast(GetDataNode()-> - GetProperty("volumerendering",renderer).GetPointer())==NULL || - dynamic_cast(GetDataNode()-> - GetProperty("volumerendering",renderer).GetPointer())->GetValue() == false) - return; - }*/ - - if ( this->GetVtkProp(renderer)->GetVisibility() ) - this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); - -} - - -void VtkMapper3D::MitkRenderVolumetricGeometry(BaseRenderer* renderer) -{ - if(IsVisible(renderer)==false) - return; - - /* if(dynamic_cast(m_Prop3D) != NULL) - { - if( dynamic_cast(GetDataNode()-> - GetProperty("volumerendering",renderer).GetPointer())==NULL || - dynamic_cast(GetDataNode()-> - GetProperty("volumerendering",renderer).GetPointer())->GetValue() == false) - return; - }*/ - - if ( GetVtkProp(renderer)->GetVisibility() ) - GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); - -} - - -void VtkMapper3D::MitkRenderOverlay(BaseRenderer* renderer) -{ - if ( this->IsVisible(renderer)==false ) - return; - - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); - } - - // Render annotations as overlay -/* - m_LabelActorCollection->InitTraversal(); - vtkProp3D *labelActor; - for ( m_LabelActorCollection->InitTraversal(); - (labelActor = m_LabelActorCollection->GetNextProp3D()); ) - { - if ( labelActor->GetVisibility() ) - labelActor->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); - } - */ -} - - -void VtkMapper3D::ApplyProperties(vtkActor* actor, BaseRenderer* renderer) -{ - float rgba[4]={1.0f,1.0f,1.0f,1.0f}; - // check for color prop and use it for rendering if it exists - this->GetColor(rgba, renderer); - // check for opacity prop and use it for rendering if it exists - this->GetOpacity(rgba[3], renderer); - - double drgba[4]={rgba[0],rgba[1],rgba[2],rgba[3]}; - actor->GetProperty()->SetColor(drgba); - actor->GetProperty()->SetOpacity(drgba[3]); - - // Add annotations to assembly, if any (camera (renderer) must be present) - if ( renderer != NULL ) - { - // Check whether one or more AnnotationProperty objects have been defined for - // this node. Check both renderer specific and global property lists, since - // properties in both should be considered. - //const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); - //const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); - - // Add clipping planes (if any) -/* - m_LabelActorCollection->RemoveAllItems(); - - PropertyList::PropertyMap::const_iterator it; - for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) - { - this->CheckForAnnotationProperty( (*it).second.first.GetPointer(), renderer ); - } - - for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) - { - this->CheckForAnnotationProperty( (*it).second.first.GetPointer(), renderer ); - } - */ - } -} - -/* -void VtkMapper3D::CheckForAnnotationProperty( mitk::BaseProperty *property, BaseRenderer *renderer ) -{ - AnnotationProperty *annotationProperty = - dynamic_cast< AnnotationProperty * >( property ); - - if ( annotationProperty != NULL ) - { - vtkVectorText *labelText = vtkVectorText::New(); - vtkPolyDataMapper *labelMapper = vtkPolyDataMapper::New(); - labelMapper->SetInput( labelText->GetOutput() ); - - vtkFollower *labelFollower = vtkFollower::New(); - labelFollower->SetMapper( labelMapper ); - labelFollower->SetCamera( renderer->GetVtkRenderer()->GetActiveCamera() ); - - labelFollower->SetScale( 2.5, 2.5, 2.5 ); - labelFollower->GetProperty()->SetColor( 1.0, 0.2, 0.1 ); - - labelText->SetText( annotationProperty->GetLabel() ); - - const Point3D &pos = annotationProperty->GetPosition(); - - Geometry3D *geometry = m_DataNode->GetData()->GetGeometry(); - - Point3D transformedPos; - geometry->IndexToWorld( pos, transformedPos ); - - labelFollower->SetPosition( transformedPos[0], transformedPos[1], transformedPos[2] ); - - //labelFollower->SetUserTransform( - // m_DataNode->GetData()->GetGeometry()->GetVtkTransform() ); - - m_LabelActorCollection->AddItem( labelFollower ); - } -} -*/ - -void VtkMapper3D::ReleaseGraphicsResources(vtkWindow * /*renWin*/) -{ -/* - if(m_Prop3D) - m_Prop3D->ReleaseGraphicsResources(renWin); -*/ -} - - -bool VtkMapper3D::HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ) -{ - vtkProp *myProp = this->GetVtkProp( renderer ); - - // TODO: check if myProp is a vtkAssembly and if so, check if prop is contained in its leafs - return ( prop == myProp ); -} - - - -} // namespace - diff --git a/Core/Code/Rendering/mitkVtkMapper3D.h b/Core/Code/Rendering/mitkVtkMapper3D.h index 3c691709ed..f31560ec0f 100644 --- a/Core/Code/Rendering/mitkVtkMapper3D.h +++ b/Core/Code/Rendering/mitkVtkMapper3D.h @@ -1,112 +1,31 @@ /*=================================================================== 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 BASEVTKMAPPER3D_H_HEADER_INCLUDED #define BASEVTKMAPPER3D_H_HEADER_INCLUDED -#include -#include "mitkMapper.h" -#include "mitkMapper3D.h" -#include "mitkBaseRenderer.h" -#include "vtkMapper.h" - -class vtkProp; -class vtkProp3D; -class vtkActor; -class vtkProp3DCollection; +#include "mitkVtkMapper.h" namespace mitk { -//##Documentation -//## @brief Base class of all vtk-based 3D-Mappers -//## -//## GetProp() returns m_Prop3D, which should be -//## initialized by sub-classes (e.g., by setting -//## it to an vtkActor). -//## @ingroup Mapper -class MITK_CORE_EXPORT VtkMapper3D : public Mapper3D -{ -public: - mitkClassMacro(VtkMapper3D, Mapper3D); - - virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) = 0; - - static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); - - virtual void MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer); - virtual void MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer); - virtual void MitkRenderOverlay(mitk::BaseRenderer* renderer); - - - virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer); - - //##Documentation - //## @brief Set the vtkTransform of the m_Prop3D for - //## the current time step of \a renderer - //## - //## Called by mitk::VtkPropRenderer::Update before rendering - //## - virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); - - //##Documentation - //## @brief Apply color and opacity read from the PropertyList - virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); - - /** - * \brief Release vtk-based graphics resources. Must be overwritten in - * subclasses if vtkProps additional to m_Prop3D are used. - */ - virtual void ReleaseGraphicsResources(vtkWindow *renWin); - - - /** \brief Returns true if this mapper owns the specified vtkProp for - * the given BaseRenderer. - * - * Note: returns false by default; should be implemented for VTK-based - * Mapper subclasses. */ - virtual bool HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ); - - /** - * \brief Returns whether this is an vtk-based mapper - */ - virtual bool IsVtkBased() const { return true; } - -protected: - VtkMapper3D(); - - virtual ~VtkMapper3D(); - - /** Checks whether the specified property is a AnnotationProperty and if yes, - * adds it to m_LabelActorCollection (internal method). */ - // virtual void CheckForAnnotationProperty( mitk::BaseProperty *property, BaseRenderer *renderer ); - -public: - - itkGetObjectMacro(Geometry,Geometry3D); - itkSetObjectMacro(Geometry,Geometry3D); - -protected: - Geometry3D::Pointer m_Geometry; - LevelWindow m_LevelWindow; - - //vtkProp3D *m_Prop3D; - //vtkProp3DCollection *m_LabelActorCollection; -}; + // typedef allows integration of mappers into the new mapper architecture + // @deprecated Use VtkMapper instead + DEPRECATED(typedef VtkMapper VtkMapper3D); } // namespace mitk #endif /* BASEVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp index 185ef02450..af3f9d444e 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp +++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp @@ -1,926 +1,927 @@ /*=================================================================== 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 "mitkVtkPropRenderer.h" // MAPPERS #include "mitkMapper.h" #include "mitkImageVtkMapper2D.h" -#include "mitkVtkMapper2D.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" +#include "mitkGLMapper.h" #include "mitkGeometry2DDataVtkMapper3D.h" #include "mitkPointSetGLMapper2D.h" #include "mitkImageSliceSelector.h" #include "mitkRenderingManager.h" #include "mitkGL.h" #include "mitkGeometry3D.h" #include "mitkDisplayGeometry.h" #include "mitkLevelWindow.h" #include "mitkCameraController.h" #include "mitkVtkInteractorCameraController.h" #include "mitkPlaneGeometry.h" #include "mitkProperties.h" #include "mitkSurface.h" #include "mitkNodePredicateDataType.h" #include "mitkVtkInteractorStyle.h" // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm ) : BaseRenderer(name,renWin, rm), m_VtkMapperPresent(false), m_NewRenderer(true), m_CameraInitializedForMapperID(0) { didCount=false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance( 0.0025 ); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance( 0.0025 ); mitk::Geometry2DDataVtkMapper3D::Pointer geometryMapper = mitk::Geometry2DDataVtkMapper3D::New(); m_CurrentWorldGeometry2DMapper = geometryMapper; m_CurrentWorldGeometry2DNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID=0; checkState(); } if (m_LightKit != NULL) m_LightKit->Delete(); if (m_VtkRenderer!=NULL) { m_CameraController = NULL; m_VtkRenderer->Delete(); m_VtkRenderer = NULL; } else m_CameraController = NULL; if (m_WorldPointPicker != NULL) m_WorldPointPicker->Delete(); if (m_PointPicker != NULL) m_PointPicker->Delete(); if (m_CellPicker != NULL) m_CellPicker->Delete(); if (m_TextRenderer != NULL) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage ) { if ( storage == NULL ) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldGeometry2DMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() ); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if ( m_DataStorage.IsNull() ) return false; //initialize world geometry mitk::TimeSlicedGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" ); if ( geometry.IsNull() ) return false; this->SetWorldGeometry(geometry); //this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] ); this->GetDisplayGeometry()->Fit(); this->GetVtkRenderer()->ResetCamera(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { // Do we have objects to render? if ( this->GetEmptyWorldGeometry()) return 0; if ( m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) this->PrepareMapperQueue(); //go through the generated list and let the sorted mappers paint bool lastVtkBased = true; //bool sthVtkBased = false; for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++) { Mapper * mapper = (*it).second; - if((mapper->IsVtkBased() == true) ) + + VtkMapper* vtkmapper = dynamic_cast(mapper); + + if(vtkmapper) { //sthVtkBased = true; - mitk::VtkMapper3D::Pointer vtkMapper = dynamic_cast(mapper); - if(vtkMapper) - { - vtkMapper->GetVtkProp(this)->SetAllocatedRenderTime(5000,GetVtkRenderer()); //B/ ToDo: rendering time calculation - //vtkMapper->GetVtkProp(this)->PokeMatrix(NULL); //B/ ToDo ??: VtkUserTransform - } - if(lastVtkBased == false) + if(!lastVtkBased) { Disable2DOpenGL(); lastVtkBased = true; } } else - if((mapper->IsVtkBased() == false) && (lastVtkBased == true)) + if(lastVtkBased) { Enable2DOpenGL(); lastVtkBased = false; } - switch(type) - { - case mitk::VtkPropRenderer::Opaque: mapper->MitkRenderOpaqueGeometry(this); break; - case mitk::VtkPropRenderer::Translucent: mapper->MitkRenderTranslucentGeometry(this); break; - case mitk::VtkPropRenderer::Overlay: mapper->MitkRenderOverlay(this); break; - case mitk::VtkPropRenderer::Volumetric: mapper->MitkRenderVolumetricGeometry(this); break; - } + mapper->MitkRender(this, type); + } if (lastVtkBased == false) Disable2DOpenGL(); // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) { Update(); } else if (m_MapperID>=1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for ( unsigned int i=0; iDelete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; //DataStorage if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if ( mapper.IsNull() ) continue; + bool visible = true; + node->GetVisibility(visible, this, "visible"); + // The information about LOD-enabled mappers is required by RenderingManager - if ( mapper->IsLODEnabled( this ) && mapper->IsVisible( this ) ) + if ( mapper->IsLODEnabled( this ) && visible ) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer<<16) + mapperNo; m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) ); mapperNo++; } } /*! \brief Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Enable2DOpenGL() { GLint iViewport[4]; // Get a copy of the viewport glGetIntegerv( GL_VIEWPORT, iViewport ); // Save a copy of the projection matrix so that we can restore it // when it's time to do 3D rendering again. glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); // Set up the orthographic projection glOrtho( iViewport[0], iViewport[0]+iViewport[2], iViewport[1], iViewport[1]+iViewport[3], -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); // Make sure depth testing and lighting are disabled for 2D rendering until // we are finished rendering in 2D glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); // disable the texturing here so crosshair is painted in the correct colors // vtk will reenable texturing every time it is needed glDisable( GL_TEXTURE_1D ); glDisable( GL_TEXTURE_2D ); } /*! \brief Initialize the VtkPropRenderer Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Disable2DOpenGL() { glPopAttrib(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } + void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode) { if(datatreenode!=NULL) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if(mapper.IsNotNull()) { - Mapper2D* mapper2d=dynamic_cast(mapper.GetPointer()); - if(mapper2d != NULL) + GLMapper* glmapper=dynamic_cast(mapper.GetPointer()); + + if(GetDisplayGeometry()->IsValid()) { - if(GetDisplayGeometry()->IsValid()) + if(glmapper != NULL) { - VtkMapper2D* vtkmapper2d=dynamic_cast(mapper.GetPointer()); - if(vtkmapper2d != NULL) + glmapper->Update(this); + m_VtkMapperPresent=false; + } + else + { + VtkMapper* vtkmapper=dynamic_cast(mapper.GetPointer()); + if(vtkmapper != NULL) { - vtkmapper2d->Update(this); + vtkmapper->Update(this); + vtkmapper->UpdateVtkTransform(this); m_VtkMapperPresent=true; } - else - mapper2d->Update(this); - } - } - else - { - VtkMapper3D* vtkmapper3d=dynamic_cast(mapper.GetPointer()); - if(vtkmapper3d != NULL) - { - vtkmapper3d->Update(this); - vtkmapper3d->UpdateVtkTransform(this); - m_VtkMapperPresent=true; } } } } } void mitk::VtkPropRenderer::Update() { if( m_DataStorage.IsNull() ) return; m_VtkMapperPresent = false; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow) { BaseRenderer::InitRenderer(renderWindow); if(renderWindow == NULL) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w,h); Superclass::InitSize(w, h); Modified(); Update(); if(m_VtkRenderer!=NULL) { int w=vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if(m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if(m_RenderWindow!=NULL) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const { if(m_VtkMapperPresent) { //m_WorldPointPicker->SetTolerance (0.0001); switch ( m_PickingMode ) { case (WorldPointPicking) : { m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); break; } case (PointPicking) : { // create a new vtkRenderer // give it all necessary information (camera position, etc.) // get all surfaces from datastorage, get actors from them // add all those actors to the new renderer // give this new renderer to pointpicker /* vtkRenderer* pickingRenderer = vtkRenderer::New(); pickingRenderer->SetActiveCamera( ); DataStorage* dataStorage = m_DataStorage; TNodePredicateDataType isSurface; DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface ); MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl; for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin(); iter != allSurfaces->end(); ++iter) { const DataNode* currentNode = *iter; VtkMapper3D* baseVtkMapper3D = dynamic_cast( currentNode->GetMapper( BaseRenderer::Standard3D ) ); if ( baseVtkMapper3D ) { vtkActor* actor = dynamic_cast( baseVtkMapper3D->GetViewProp() ); if (actor) { MITK_INFO << "a" << std::flush; pickingRenderer->AddActor( actor ); } } } MITK_INFO << ";" << std::endl; */ m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); break; } } } else { Superclass::PickWorldPoint(displayPoint, worldPoint); } } mitk::DataNode * mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const { if ( m_VtkMapperPresent ) { m_CellPicker->InitializePickList(); // Iterate over all DataStorage objects to determine all vtkProps intended // for picking DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it ) { DataNode *node = it->Value(); if ( node == NULL ) continue; bool pickable = false; node->GetBoolProperty( "pickable", pickable ); if ( !pickable ) continue; - VtkMapper3D *mapper = dynamic_cast< VtkMapper3D * > - ( node->GetMapper( m_MapperID ) ); + VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) ); if ( mapper == NULL ) continue; vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this ); if ( prop == NULL ) continue; m_CellPicker->AddPickList( prop ); } // Do the picking and retrieve the picked vtkProp (if any) m_CellPicker->PickFromListOn(); m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer ); m_CellPicker->PickFromListOff(); vtk2itk( m_CellPicker->GetPickPosition(), worldPosition ); vtkProp *prop = m_CellPicker->GetViewProp(); if ( prop == NULL ) { return NULL; } // Iterate over all DataStorage objects to determine if the retrieved // vtkProp is owned by any associated mapper. for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; - mitk::Mapper::Pointer mapper = node->GetMapper( m_MapperID ); - if ( mapper.IsNull() ) + mitk::Mapper * mapper = node->GetMapper( m_MapperID ); + if ( mapper == NULL) continue; - if ( mapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) - { - return node; + mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper); + + if(vtkmapper){ + //if vtk-based, then ... + if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) + { + return node; + } } } return NULL; } else { return Superclass::PickObject( displayPosition, worldPosition ); } }; /*! \brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. */ int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { if(text.size() > 0) { vtkTextActor* textActor = vtkTextActor::New(); textActor->SetPosition(posX,posY); textActor->SetInput(text.c_str()); textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property textActor->GetTextProperty()->SetOpacity( opacity ); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id,textActor)); return text_id; } return -1; } /*! \brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc. */ vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { m_PickingObjects = m_DataStorage->GetAll(); m_PickingObjectsIterator = m_PickingObjects->begin(); } } vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath() { if (m_DataStorage.IsNull() ) { return NULL; } if ( m_PickingObjectsIterator == m_PickingObjects->end() ) { return NULL; } vtkAssemblyPath* returnPath = vtkAssemblyPath::New(); //returnPath->Register(NULL); bool success = false; while (!success) { // loop until AddNode can be called successfully const DataNode* node = *m_PickingObjectsIterator; if (node) { Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D ); if (mapper) { - VtkMapper3D* vtkmapper = dynamic_cast( mapper ); + VtkMapper* vtkmapper = dynamic_cast( mapper ); if (vtkmapper) { vtkProp* prop = vtkmapper->GetVtkProp(this); if ( prop && prop->GetVisibility() ) { // add to assembly path returnPath->AddNode( prop, prop->GetMatrix() ); success = true; } } } } ++m_PickingObjectsIterator; if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break; } if ( success ) { return returnPath; } else { return NULL; } } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow *renWin) { if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if ( node.IsNull() ) continue; - Mapper::Pointer mapper = node->GetMapper(m_MapperID); - if(mapper.IsNotNull()) - mapper->ReleaseGraphicsResources(renWin); - } + Mapper * mapper = node->GetMapper(m_MapperID); + + if (mapper) + { + VtkMapper* vtkmapper = dynamic_cast( mapper ); + + if(vtkmapper) + vtkmapper->ReleaseGraphicsResources(renWin); + } + } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount>1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } //MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n"; } } else { if(didCount) { didCount=false; glWorkAroundGlobalCount--; if(glWorkAroundGlobalCount==1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } //MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n"; } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if ( this->GetMapperID() != m_CameraInitializedForMapperID ) { Initialize2DvtkCamera(); //Set parallel projection etc. } AdjustCameraToScene(); //Prepare camera for 2D render windows } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if ( this->GetMapperID() == Standard3D ) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( vtkInteractorStyleTrackballCamera::New() ); m_CameraInitializedForMapperID = Standard3D; } else if( this->GetMapperID() == Standard2D) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); //turn the light out in the scene in order to render correct grey values. //TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( mitkVtkInteractorStyle::New() ); m_CameraInitializedForMapperID = Standard2D; } return true; } void mitk::VtkPropRenderer::AdjustCameraToScene(){ if(this->GetMapperID() == Standard2D) { const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); double objectHeightInMM = this->GetCurrentWorldGeometry2D()->GetExtentInMM(1);//the height of the current object slice in mm double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in) double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit() //determine how much of the object can be displayed Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin) Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2) //Scale the rendered object: //The image is scaled by a single factor, because in an orthographic projection sizes //are preserved (so you cannot scale X and Y axis with different parameters). The //parameter sets the size of the total display-volume. If you set this to the image //height, the image plus a border with the size of the image will be rendered. //Therefore, the size is imageHeightInMM / 2. this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 ); //zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely. this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor); //the center of the view-plane double viewPlaneCenter[3]; viewPlaneCenter[0] = displayGeometryCenterInMM[0]; viewPlaneCenter[1] = displayGeometryCenterInMM[1]; viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0 //define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0) double cameraUp[3]; cameraUp[0] = 0.0; cameraUp[1] = 1.0; cameraUp[2] = 0.0; //the position of the camera (center[0], center[1], 900000) double cameraPosition[3]; cameraPosition[0] = viewPlaneCenter[0]; cameraPosition[1] = viewPlaneCenter[1]; cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. //set the camera corresponding to the textured plane vtkSmartPointer camera = this->GetVtkRenderer()->GetActiveCamera(); if (camera) { camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal) camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane camera->SetViewUp( cameraUp ); //set the view-up for the camera // double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2])); // camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. } const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldGeometry2D() ); if ( planeGeometry != NULL ) { //Transform the camera to the current position (transveral, coronal and saggital plane). //This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera. //(Without not all three planes would be visible). vtkSmartPointer trans = vtkSmartPointer::New(); vtkSmartPointer matrix = vtkSmartPointer::New(); Point3D origin; Vector3D right, bottom, normal; origin = planeGeometry->GetOrigin(); right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace) bottom = planeGeometry->GetAxisVector( 1 ); normal = planeGeometry->GetNormal(); right.Normalize(); bottom.Normalize(); normal.Normalize(); matrix->SetElement(0, 0, right[0]); matrix->SetElement(1, 0, right[1]); matrix->SetElement(2, 0, right[2]); matrix->SetElement(0, 1, bottom[0]); matrix->SetElement(1, 1, bottom[1]); matrix->SetElement(2, 1, bottom[2]); matrix->SetElement(0, 2, normal[0]); matrix->SetElement(1, 2, normal[1]); matrix->SetElement(2, 2, normal[2]); matrix->SetElement(0, 3, origin[0]); matrix->SetElement(1, 3, origin[1]); matrix->SetElement(2, 3, origin[2]); matrix->SetElement(3, 0, 0.0); matrix->SetElement(3, 1, 0.0); matrix->SetElement(3, 2, 0.0); matrix->SetElement(3, 3, 1.0); trans->SetMatrix(matrix); //Transform the camera to the current position (transveral, coronal and saggital plane). this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans); } } } diff --git a/Core/Code/Rendering/vtkMitkRenderProp.cpp b/Core/Code/Rendering/vtkMitkRenderProp.cpp index f1839cf303..59d4c6bf9d 100644 --- a/Core/Code/Rendering/vtkMitkRenderProp.cpp +++ b/Core/Code/Rendering/vtkMitkRenderProp.cpp @@ -1,125 +1,107 @@ /*=================================================================== 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 "vtkMitkRenderProp.h" #include #include #include -#include "mitkVtkMapper3D.h" -#include "mitkVtkMapper2D.h" +#include "mitkVtkMapper.h" +#include "mitkGLMapper.h" vtkStandardNewMacro(vtkMitkRenderProp); vtkMitkRenderProp::vtkMitkRenderProp() { } vtkMitkRenderProp::~vtkMitkRenderProp() { } double *vtkMitkRenderProp::GetBounds() { return const_cast(m_VtkPropRenderer->GetBounds()); } void vtkMitkRenderProp::SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer) { this->m_VtkPropRenderer = propRenderer; } int vtkMitkRenderProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Opaque); } int vtkMitkRenderProp::RenderOverlay(vtkViewport* /*viewport*/) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Overlay); } void vtkMitkRenderProp::ReleaseGraphicsResources(vtkWindow* window) { m_VtkPropRenderer->ReleaseGraphicsResources(window); } void vtkMitkRenderProp::InitPathTraversal() { m_VtkPropRenderer->InitPathTraversal(); } vtkAssemblyPath* vtkMitkRenderProp::GetNextPath() { return m_VtkPropRenderer->GetNextPath(); } //BUG (#1551) added method depth peeling int vtkMitkRenderProp::HasTranslucentPolygonalGeometry() { typedef std::map MappersMapType; MappersMapType mappersMap = m_VtkPropRenderer->GetMappersMap(); for(MappersMapType::iterator it = mappersMap.begin(); it != mappersMap.end(); it++) { mitk::Mapper * mapper = (*it).second; - mitk::VtkMapper3D::Pointer vtkMapper3D = dynamic_cast(mapper); - if(vtkMapper3D) - { - // Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly - // manually (see issue #8186 committed to VTK's Mantis issue tracker) - // --> VTK bug resolved on 2008-12-01 - vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >( - vtkMapper3D->GetVtkProp(m_VtkPropRenderer) ); - if ( propAssembly ) - { - propAssembly->InitPathTraversal(); - } - if (vtkMapper3D->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1) - return 1; - } - - //TODO bad solution. - mitk::VtkMapper2D::Pointer vtkMapper2D = dynamic_cast(mapper); - if(vtkMapper2D) + mitk::VtkMapper::Pointer vtkMapper = dynamic_cast(mapper); + if(vtkMapper) { // Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly // manually (see issue #8186 committed to VTK's Mantis issue tracker) // --> VTK bug resolved on 2008-12-01 vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >( - vtkMapper2D->GetVtkProp(m_VtkPropRenderer) ); + vtkMapper->GetVtkProp(m_VtkPropRenderer) ); if ( propAssembly ) { - propAssembly->InitPathTraversal(); //TODO why is this called here??? + propAssembly->InitPathTraversal(); } - if (vtkMapper2D->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1) { + if (vtkMapper->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1) return 1; - } } } return 0; } int vtkMitkRenderProp::RenderTranslucentPolygonalGeometry( vtkViewport * ) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Translucent); } int vtkMitkRenderProp::RenderVolumetricGeometry( vtkViewport * ) { return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Volumetric); } diff --git a/Core/Code/Rendering/vtkMitkRenderProp.h b/Core/Code/Rendering/vtkMitkRenderProp.h index 9be98656c0..4ac689567c 100644 --- a/Core/Code/Rendering/vtkMitkRenderProp.h +++ b/Core/Code/Rendering/vtkMitkRenderProp.h @@ -1,79 +1,75 @@ /*=================================================================== 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 VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723 #define VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723 #include "vtkProp.h" #include "mitkVtkPropRenderer.h" - - /*! \brief vtkMitkRenderProp The MITK rendering process is completely integrated into the VTK rendering pipeline. The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes. \sa rendering \ingroup rendering */ class MITK_CORE_EXPORT vtkMitkRenderProp : public vtkProp { public: static vtkMitkRenderProp *New(); vtkTypeMacro(vtkMitkRenderProp,vtkProp); void SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer); int RenderOpaqueGeometry(vtkViewport* viewport); int RenderOverlay(vtkViewport* viewport); double *GetBounds(); void ReleaseGraphicsResources(vtkWindow* window); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ virtual void InitPathTraversal(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ virtual vtkAssemblyPath* GetNextPath(); //BUG (#1551) added method for depth peeling support virtual int HasTranslucentPolygonalGeometry(); virtual int RenderTranslucentPolygonalGeometry( vtkViewport *); virtual int RenderVolumetricGeometry( vtkViewport *); protected: vtkMitkRenderProp(); ~vtkMitkRenderProp(); mitk::VtkPropRenderer::Pointer m_VtkPropRenderer; }; #endif /* VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723 */ - - diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 10cafd5bc7..5ca0ce8172 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,358 +1,355 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkLocalVariationImageFilter.h Algorithms/itkLocalVariationImageFilter.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/itkTotalVariationDenoisingImageFilter.h Algorithms/itkTotalVariationDenoisingImageFilter.txx Algorithms/itkTotalVariationSingleIterationImageFilter.h Algorithms/itkTotalVariationSingleIterationImageFilter.txx Algorithms/mitkBilateralFilter.h Algorithms/mitkBilateralFilter.cpp Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h # Preprocessor macros taken from Boost Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkExceptionMacro.h Common/mitkServiceBaseObject.h Common/mitkTestingMacros.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkImageToItk.txx Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkBaseProcess.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp #DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp #DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeSlicedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interfaces/mitkInteractionEventObserver.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp #IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp #IO/mitkPicFileIOFactory.cpp #IO/mitkPicFileReader.cpp #IO/mitkPicFileWriter.cpp #IO/mitkPicHelper.cpp #IO/mitkPicVolumeTimeSeriesIOFactory.cpp #IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp - Rendering/mitkVtkMapper2D.cpp - Rendering/mitkVtkMapper3D.cpp + Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp - Rendering/mitkGLMapper2D.cpp + Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp - Rendering/mitkMapper2D.cpp - Rendering/mitkMapper3D.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkShaderRepository.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkRenderingTestHelper.cpp Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp ) list(APPEND CPP_FILES ${CppMicroServices_SOURCES}) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/PointSetConfig.xml Interactions/Tests/AddAndRemovePoints.xml Interactions/Tests/globalConfig.xml Interactions/Tests/StatemachineTest.xml Interactions/Tests/StatemachineConfigTest.xml ) diff --git a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp index a857776901..92d0e23579 100644 --- a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp +++ b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.cpp @@ -1,760 +1,756 @@ /*=================================================================== 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 "mitkConnectomicsNetworkMapper3D.h" #include #include "vtkGraphLayout.h" #include #include "vtkGraphToPolyData.h" #include #include "vtkGlyph3D.h" #include "vtkGlyphSource2D.h" #include "mitkConnectomicsRenderingProperties.h" #include "mitkConnectomicsRenderingSchemeProperty.h" #include "mitkConnectomicsRenderingEdgeFilteringProperty.h" #include "mitkConnectomicsRenderingNodeFilteringProperty.h" #include "mitkConnectomicsRenderingNodeColorParameterProperty.h" #include "mitkConnectomicsRenderingNodeRadiusParameterProperty.h" #include "mitkConnectomicsRenderingEdgeColorParameterProperty.h" #include "mitkConnectomicsRenderingEdgeRadiusParameterProperty.h" #include "mitkConnectomicsRenderingNodeThresholdParameterProperty.h" #include "mitkConnectomicsRenderingEdgeThresholdParameterProperty.h" #include mitk::ConnectomicsNetworkMapper3D::ConnectomicsNetworkMapper3D() { m_NetworkAssembly = vtkPropAssembly::New(); } mitk::ConnectomicsNetworkMapper3D:: ~ConnectomicsNetworkMapper3D() { m_NetworkAssembly->Delete(); } void mitk::ConnectomicsNetworkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { if( this->GetInput() == NULL ) { return; } bool propertiesHaveChanged = this->PropertiesChanged(); if( this->GetInput()->GetIsModified( ) || propertiesHaveChanged ) { - GenerateData(); - } -} -void mitk::ConnectomicsNetworkMapper3D::GenerateData() -{ m_NetworkAssembly->Delete(); m_NetworkAssembly = vtkPropAssembly::New(); // Here is the part where a graph is given and converted to points and connections between points... std::vector< mitk::ConnectomicsNetwork::NetworkNode > vectorOfNodes = this->GetInput()->GetVectorOfAllNodes(); std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); // Decide on the style of rendering due to property if( m_ChosenRenderingScheme == connectomicsRenderingMITKScheme ) { mitk::Point3D tempWorldPoint, tempCNFGeometryPoint; //////////////////////Prepare coloring and radius//////////// std::vector< double > vectorOfNodeRadiusParameterValues; vectorOfNodeRadiusParameterValues.resize( vectorOfNodes.size() ); double maxNodeRadiusParameterValue( FillNodeParameterVector( &vectorOfNodeRadiusParameterValues, m_NodeRadiusParameter ) ); std::vector< double > vectorOfNodeColorParameterValues; vectorOfNodeColorParameterValues.resize( vectorOfNodes.size() ); double maxNodeColorParameterValue( FillNodeParameterVector( &vectorOfNodeColorParameterValues, m_NodeColorParameter ) ); std::vector< double > vectorOfEdgeRadiusParameterValues; vectorOfEdgeRadiusParameterValues.resize( vectorOfEdges.size() ); double maxEdgeRadiusParameterValue( FillEdgeParameterVector( &vectorOfEdgeRadiusParameterValues, m_EdgeRadiusParameter ) ); std::vector< double > vectorOfEdgeColorParameterValues; vectorOfEdgeColorParameterValues.resize( vectorOfEdges.size() ); double maxEdgeColorParameterValue( FillEdgeParameterVector( &vectorOfEdgeColorParameterValues, m_EdgeColorParameter ) ); //////////////////////Prepare Filtering////////////////////// // true will be rendered std::vector< bool > vectorOfNodeFilterBools( vectorOfNodes.size(), true ); if( m_ChosenNodeFilter == connectomicsRenderingNodeThresholdingFilter ) { FillNodeFilterBoolVector( &vectorOfNodeFilterBools, m_NodeThresholdParameter ); } std::vector< bool > vectorOfEdgeFilterBools( vectorOfEdges.size(), true ); if( m_ChosenEdgeFilter == connectomicsRenderingEdgeThresholdFilter ) { FillEdgeFilterBoolVector( &vectorOfEdgeFilterBools, m_EdgeThresholdParameter ); } //////////////////////Create Spheres///////////////////////// for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { vtkSmartPointer sphereSource = vtkSmartPointer::New(); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint.SetElement( dimension , vectorOfNodes[i].coordinates[dimension] ); } this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); sphereSource->SetCenter( tempWorldPoint[0] , tempWorldPoint[1], tempWorldPoint[2] ); // determine radius double radiusFactor = vectorOfNodeRadiusParameterValues[i] / maxNodeRadiusParameterValue; double radius = m_NodeRadiusStart + ( m_NodeRadiusEnd - m_NodeRadiusStart) * radiusFactor; sphereSource->SetRadius( radius ); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(sphereSource->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); // determine color double colorFactor = vectorOfNodeColorParameterValues[i] / maxNodeColorParameterValue; double redStart = m_NodeColorStart.GetElement( 0 ); double greenStart = m_NodeColorStart.GetElement( 1 ); double blueStart = m_NodeColorStart.GetElement( 2 ); double redEnd = m_NodeColorEnd.GetElement( 0 ); double greenEnd = m_NodeColorEnd.GetElement( 1 ); double blueEnd = m_NodeColorEnd.GetElement( 2 ); double red = redStart + ( redEnd - redStart ) * colorFactor; double green = greenStart + ( greenEnd - greenStart ) * colorFactor; double blue = blueStart + ( blueEnd - blueStart ) * colorFactor; actor->GetProperty()->SetColor( red, green, blue); if( vectorOfNodeFilterBools[i] ) { m_NetworkAssembly->AddPart(actor); } } //////////////////////Create Tubes///////////////////////// double maxWeight = (double) this->GetInput()->GetMaximumWeight(); for(unsigned int i = 0; i < vectorOfEdges.size(); i++) { vtkSmartPointer lineSource = vtkSmartPointer::New(); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.first.coordinates[dimension]; } this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); lineSource->SetPoint1(tempWorldPoint[0], tempWorldPoint[1],tempWorldPoint[2] ); for(unsigned int dimension = 0; dimension < 3; dimension++) { tempCNFGeometryPoint[ dimension ] = vectorOfEdges[i].first.second.coordinates[dimension]; } this->GetData()->GetGeometry()->IndexToWorld( tempCNFGeometryPoint, tempWorldPoint ); lineSource->SetPoint2(tempWorldPoint[0], tempWorldPoint[1], tempWorldPoint[2] ); vtkSmartPointer tubes = vtkSmartPointer::New(); tubes->SetInput( lineSource->GetOutput() ); tubes->SetNumberOfSides( 12 ); // determine radius double radiusFactor = vectorOfEdgeRadiusParameterValues[i] / maxEdgeRadiusParameterValue; double radius = m_EdgeRadiusStart + ( m_EdgeRadiusEnd - m_EdgeRadiusStart) * radiusFactor; tubes->SetRadius( radius ); // originally we used a logarithmic scaling, // double radiusFactor = 1.0 + ((double) vectorOfEdges[i].second.weight) / 10.0 ; // tubes->SetRadius( std::log10( radiusFactor ) ); vtkSmartPointer mapper2 = vtkSmartPointer::New(); mapper2->SetInput( tubes->GetOutput() ); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper2); // determine color double colorFactor = vectorOfEdgeColorParameterValues[i] / maxEdgeColorParameterValue; double redStart = m_EdgeColorStart.GetElement( 0 ); double greenStart = m_EdgeColorStart.GetElement( 1 ); double blueStart = m_EdgeColorStart.GetElement( 2 ); double redEnd = m_EdgeColorEnd.GetElement( 0 ); double greenEnd = m_EdgeColorEnd.GetElement( 1 ); double blueEnd = m_EdgeColorEnd.GetElement( 2 ); double red = redStart + ( redEnd - redStart ) * colorFactor; double green = greenStart + ( greenEnd - greenStart ) * colorFactor; double blue = blueStart + ( blueEnd - blueStart ) * colorFactor; actor->GetProperty()->SetColor( red, green, blue); if( vectorOfEdgeFilterBools[i] ) { m_NetworkAssembly->AddPart(actor); } } } else if( m_ChosenRenderingScheme == connectomicsRenderingVTKScheme ) { vtkSmartPointer graph = vtkSmartPointer::New(); std::vector< vtkIdType > networkToVTKvector; networkToVTKvector.resize(vectorOfNodes.size()); for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { networkToVTKvector[vectorOfNodes[i].id] = graph->AddVertex(); } for(unsigned int i = 0; i < vectorOfEdges.size(); i++) { graph->AddEdge(networkToVTKvector[vectorOfEdges[i].first.first.id], networkToVTKvector[vectorOfEdges[i].first.second.id]); } vtkSmartPointer points = vtkSmartPointer::New(); for(unsigned int i = 0; i < vectorOfNodes.size(); i++) { double x = vectorOfNodes[i].coordinates[0]; double y = vectorOfNodes[i].coordinates[1]; double z = vectorOfNodes[i].coordinates[2]; points->InsertNextPoint( x, y, z); } graph->SetPoints(points); vtkGraphLayout* layout = vtkGraphLayout::New(); layout->SetInput(graph); layout->SetLayoutStrategy(vtkPassThroughLayoutStrategy::New()); vtkGraphToPolyData* graphToPoly = vtkGraphToPolyData::New(); graphToPoly->SetInputConnection(layout->GetOutputPort()); // Create the standard VTK polydata mapper and actor // for the connections (edges) in the tree. vtkPolyDataMapper* edgeMapper = vtkPolyDataMapper::New(); edgeMapper->SetInputConnection(graphToPoly->GetOutputPort()); vtkActor* edgeActor = vtkActor::New(); edgeActor->SetMapper(edgeMapper); edgeActor->GetProperty()->SetColor(0.0, 0.5, 1.0); // Glyph the points of the tree polydata to create // VTK_VERTEX cells at each vertex in the tree. vtkGlyph3D* vertGlyph = vtkGlyph3D::New(); vertGlyph->SetInputConnection(0, graphToPoly->GetOutputPort()); vtkGlyphSource2D* glyphSource = vtkGlyphSource2D::New(); glyphSource->SetGlyphTypeToVertex(); vertGlyph->SetInputConnection(1, glyphSource->GetOutputPort()); // Create a mapper for the vertices, and tell the mapper // to use the specified color array. vtkPolyDataMapper* vertMapper = vtkPolyDataMapper::New(); vertMapper->SetInputConnection(vertGlyph->GetOutputPort()); /*if (colorArray) { vertMapper->SetScalarModeToUsePointFieldData(); vertMapper->SelectColorArray(colorArray); vertMapper->SetScalarRange(colorRange); }*/ // Create an actor for the vertices. Move the actor forward // in the z direction so it is drawn on top of the edge actor. vtkActor* vertActor = vtkActor::New(); vertActor->SetMapper(vertMapper); vertActor->GetProperty()->SetPointSize(5); vertActor->SetPosition(0, 0, 0.001); m_NetworkAssembly->AddPart(edgeActor); m_NetworkAssembly->AddPart(vertActor); } (static_cast ( GetData() ) )->SetIsModified( false ); + } } const mitk::ConnectomicsNetwork* mitk::ConnectomicsNetworkMapper3D::GetInput() { return static_cast ( GetData() ); } void mitk::ConnectomicsNetworkMapper3D::SetDefaultProperties(DataNode* node, BaseRenderer* renderer , bool overwrite) { // Initialize enumeration properties mitk::ConnectomicsRenderingSchemeProperty::Pointer connectomicsRenderingScheme = mitk::ConnectomicsRenderingSchemeProperty::New(); mitk::ConnectomicsRenderingEdgeFilteringProperty::Pointer connectomicsRenderingEdgeFiltering = mitk::ConnectomicsRenderingEdgeFilteringProperty::New(); mitk::ConnectomicsRenderingNodeFilteringProperty::Pointer connectomicsRenderingNodeFiltering = mitk::ConnectomicsRenderingNodeFilteringProperty::New(); mitk::ConnectomicsRenderingNodeColorParameterProperty::Pointer connectomicsRenderingNodeGradientColorParameter = mitk::ConnectomicsRenderingNodeColorParameterProperty::New(); mitk::ConnectomicsRenderingNodeRadiusParameterProperty::Pointer connectomicsRenderingNodeRadiusParameter = mitk::ConnectomicsRenderingNodeRadiusParameterProperty::New(); mitk::ConnectomicsRenderingEdgeColorParameterProperty::Pointer connectomicsRenderingEdgeGradientColorParameter = mitk::ConnectomicsRenderingEdgeColorParameterProperty::New(); mitk::ConnectomicsRenderingEdgeRadiusParameterProperty::Pointer connectomicsRenderingEdgeRadiusParameter = mitk::ConnectomicsRenderingEdgeRadiusParameterProperty::New(); mitk::ConnectomicsRenderingNodeThresholdParameterProperty::Pointer connectomicsRenderingNodeThresholdParameter = mitk::ConnectomicsRenderingNodeThresholdParameterProperty::New(); mitk::ConnectomicsRenderingEdgeThresholdParameterProperty::Pointer connectomicsRenderingEdgeThresholdParameter = mitk::ConnectomicsRenderingEdgeThresholdParameterProperty::New(); // set the properties node->AddProperty( connectomicsRenderingSchemePropertyName.c_str(), connectomicsRenderingScheme, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeFilteringPropertyName.c_str(), connectomicsRenderingEdgeFiltering, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeThresholdFilterParameterName.c_str(), connectomicsRenderingEdgeThresholdParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeThresholdFilterThresholdName.c_str(), connectomicsRenderingEdgeThresholdFilterThresholdDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeFilteringPropertyName.c_str(), connectomicsRenderingNodeFiltering, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeThresholdFilterParameterName.c_str(), connectomicsRenderingNodeThresholdParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeThresholdFilterThresholdName.c_str(), connectomicsRenderingNodeThresholdFilterThresholdDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientStartColorName.c_str(), connectomicsRenderingNodeGradientStartColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientEndColorName.c_str(), connectomicsRenderingNodeGradientEndColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeGradientColorParameterName.c_str(), connectomicsRenderingNodeGradientColorParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusStartName.c_str(), connectomicsRenderingNodeRadiusStartDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusEndName.c_str(), connectomicsRenderingNodeRadiusEndDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeRadiusParameterName.c_str(), connectomicsRenderingNodeRadiusParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingNodeChosenNodeName.c_str(), connectomicsRenderingNodeChosenNodeDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientStartColorName.c_str(), connectomicsRenderingEdgeGradientStartColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientEndColorName.c_str(), connectomicsRenderingEdgeGradientEndColorDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeGradientColorParameterName.c_str(), connectomicsRenderingEdgeGradientColorParameter, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusStartName.c_str(), connectomicsRenderingEdgeRadiusStartDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusEndName.c_str(), connectomicsRenderingEdgeRadiusEndDefault, renderer, overwrite ); node->AddProperty( connectomicsRenderingEdgeRadiusParameterName.c_str(), connectomicsRenderingEdgeRadiusParameter, renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::ConnectomicsNetworkMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { //TODO: implement } void mitk::ConnectomicsNetworkMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) { //TODO: implement } void mitk::ConnectomicsNetworkMapper3D::UpdateVtkObjects() { //TODO: implement } vtkProp* mitk::ConnectomicsNetworkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_NetworkAssembly; } bool mitk::ConnectomicsNetworkMapper3D::PropertiesChanged() { mitk::ConnectomicsRenderingSchemeProperty * renderingScheme = static_cast< mitk::ConnectomicsRenderingSchemeProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingSchemePropertyName.c_str() ) ); mitk::ConnectomicsRenderingEdgeFilteringProperty * edgeFilter = static_cast< mitk::ConnectomicsRenderingEdgeFilteringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeFilteringPropertyName.c_str() ) ); mitk::FloatProperty * edgeThreshold = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeThresholdFilterThresholdName.c_str() ) ); mitk::ConnectomicsRenderingNodeFilteringProperty * nodeFilter = static_cast< mitk::ConnectomicsRenderingNodeFilteringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeFilteringPropertyName.c_str() ) ); mitk::ConnectomicsRenderingNodeThresholdParameterProperty * nodeThresholdParameter = static_cast< mitk::ConnectomicsRenderingNodeThresholdParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeThresholdFilterParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeThresholdParameterProperty * edgeThresholdParameter = static_cast< mitk::ConnectomicsRenderingEdgeThresholdParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeThresholdFilterParameterName.c_str() ) ); mitk::FloatProperty * nodeThreshold = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeThresholdFilterThresholdName.c_str() ) ); mitk::ColorProperty * nodeColorStart = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientStartColorName.c_str() ) ); mitk::ColorProperty * nodeColorEnd = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientEndColorName.c_str() ) ); mitk::FloatProperty * nodeRadiusStart = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusStartName.c_str() ) ); mitk::FloatProperty * nodeRadiusEnd = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusEndName.c_str() ) ); mitk::StringProperty * chosenNode = static_cast< mitk::StringProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeChosenNodeName.c_str() ) ); mitk::ColorProperty * edgeColorStart = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientStartColorName.c_str() ) ); mitk::ColorProperty * edgeColorEnd = static_cast< mitk::ColorProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientEndColorName.c_str() ) ); mitk::FloatProperty * edgeRadiusStart = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusStartName.c_str() ) ); mitk::FloatProperty * edgeRadiusEnd = static_cast< mitk::FloatProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusEndName.c_str() ) ); mitk::ConnectomicsRenderingNodeColorParameterProperty * nodeColorParameter = static_cast< mitk::ConnectomicsRenderingNodeColorParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeGradientColorParameterName.c_str() ) ); mitk::ConnectomicsRenderingNodeRadiusParameterProperty * nodeRadiusParameter = static_cast< mitk::ConnectomicsRenderingNodeRadiusParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingNodeRadiusParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeColorParameterProperty * edgeColorParameter = static_cast< mitk::ConnectomicsRenderingEdgeColorParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeGradientColorParameterName.c_str() ) ); mitk::ConnectomicsRenderingEdgeRadiusParameterProperty * edgeRadiusParameter = static_cast< mitk::ConnectomicsRenderingEdgeRadiusParameterProperty * > ( this->GetDataNode()->GetProperty( connectomicsRenderingEdgeRadiusParameterName.c_str() ) ); if( m_ChosenRenderingScheme != renderingScheme->GetValueAsString() || m_ChosenEdgeFilter != edgeFilter->GetValueAsString() || m_EdgeThreshold != edgeThreshold->GetValue() || m_EdgeThresholdParameter != edgeThresholdParameter->GetValueAsString() || m_ChosenNodeFilter != nodeFilter->GetValueAsString() || m_NodeThreshold != nodeThreshold->GetValue() || m_NodeThresholdParameter != nodeThresholdParameter->GetValueAsString() || m_NodeColorStart != nodeColorStart->GetValue() || m_NodeColorEnd != nodeColorEnd->GetValue() || m_NodeRadiusStart != nodeRadiusStart->GetValue() || m_NodeRadiusEnd != nodeRadiusEnd->GetValue() || m_ChosenNodeLabel != chosenNode->GetValueAsString() || m_EdgeColorStart != edgeColorStart->GetValue() || m_EdgeColorEnd != edgeColorEnd->GetValue() || m_EdgeRadiusStart != edgeRadiusStart->GetValue() || m_EdgeRadiusEnd != edgeRadiusEnd->GetValue() || m_NodeColorParameter != nodeColorParameter->GetValueAsString() || m_NodeRadiusParameter != nodeRadiusParameter->GetValueAsString() || m_EdgeColorParameter != edgeColorParameter->GetValueAsString() || m_EdgeRadiusParameter != edgeRadiusParameter->GetValueAsString() ) { m_ChosenRenderingScheme = renderingScheme->GetValueAsString(); m_ChosenEdgeFilter = edgeFilter->GetValueAsString(); m_EdgeThreshold = edgeThreshold->GetValue(); m_EdgeThresholdParameter = edgeThresholdParameter->GetValueAsString(); m_ChosenNodeFilter = nodeFilter->GetValueAsString(); m_NodeThreshold = nodeThreshold->GetValue(); m_NodeThresholdParameter = nodeThresholdParameter->GetValueAsString(); m_NodeColorStart = nodeColorStart->GetValue(); m_NodeColorEnd = nodeColorEnd->GetValue(); m_NodeRadiusStart = nodeRadiusStart->GetValue(); m_NodeRadiusEnd = nodeRadiusEnd->GetValue(); m_ChosenNodeLabel = chosenNode->GetValueAsString(); m_EdgeColorStart = edgeColorStart->GetValue(); m_EdgeColorEnd = edgeColorEnd->GetValue(); m_EdgeRadiusStart = edgeRadiusStart->GetValue(); m_EdgeRadiusEnd = edgeRadiusEnd->GetValue(); m_NodeColorParameter = nodeColorParameter->GetValueAsString(); m_NodeRadiusParameter = nodeRadiusParameter->GetValueAsString(); m_EdgeColorParameter = edgeColorParameter->GetValueAsString(); m_EdgeRadiusParameter = edgeRadiusParameter->GetValueAsString(); return true; } return false; } double mitk::ConnectomicsNetworkMapper3D::FillNodeParameterVector( std::vector< double > * parameterVector, std::string parameterName ) { int end( parameterVector->size() ); // constant parameter - uniform style if( parameterName == connectomicsRenderingNodeParameterConstant ) { for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } double maximum( 0.0 ); // using the degree as parameter if( parameterName == connectomicsRenderingNodeParameterDegree ) { std::vector< int > vectorOfDegree = this->GetInput()->GetDegreeOfNodes(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfDegree[ index ]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using betweenness centrality as parameter if( parameterName == connectomicsRenderingNodeParameterBetweenness ) { std::vector< double > vectorOfBetweenness = this->GetInput()->GetNodeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfBetweenness[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using clustering coefficient as parameter if( parameterName == connectomicsRenderingNodeParameterClustering ) { const std::vector< double > vectorOfClustering = this->GetInput()->GetLocalClusteringCoefficients(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfClustering[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using distance to a specific node as parameter if( parameterName == connectomicsRenderingNodeParameterColoringShortestPath ) { bool labelFound( this->GetInput()->CheckForLabel( m_ChosenNodeLabel ) ); // check whether the chosen node is valid if( !labelFound ) { MITK_WARN << "Node chosen for rendering is not valid."; for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } else { const std::vector< double > distanceVector = this->GetInput()->GetShortestDistanceVectorFromLabel( m_ChosenNodeLabel ); for(int index(0); index < end; index++) { parameterVector->at( index ) = distanceVector[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } } // if the maximum is nearly zero if( std::abs( maximum ) < mitk::eps ) { maximum = 1.0; } return maximum; } double mitk::ConnectomicsNetworkMapper3D::FillEdgeParameterVector( std::vector< double > * parameterVector, std::string parameterName ) { int end( parameterVector->size() ); // constant parameter - uniform style if( parameterName == connectomicsRenderingEdgeParameterConstant ) { for(int index(0); index < end; index++) { parameterVector->at( index ) = 1.0; } return 1.0; } double maximum( 0.0 ); // using the weight as parameter if( parameterName == connectomicsRenderingEdgeParameterWeight ) { std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfEdges[ index ].second.weight; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // using the edge centrality as parameter if( parameterName == connectomicsRenderingEdgeParameterCentrality ) { const std::vector< double > vectorOfCentrality = this->GetInput()->GetEdgeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector->at( index ) = vectorOfCentrality[index]; } maximum = *std::max_element( parameterVector->begin(), parameterVector->end() ); } // if the maximum is nearly zero if( std::abs( maximum ) < mitk::eps ) { maximum = 1.0; } return maximum; } void mitk::ConnectomicsNetworkMapper3D::FillNodeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ) { std::vector< double > parameterVector; parameterVector.resize( boolVector->size() ); int end( parameterVector.size() ); // using the degree as parameter if( parameterName == connectomicsRenderingNodeParameterDegree ) { std::vector< int > vectorOfDegree = this->GetInput()->GetDegreeOfNodes(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfDegree[ index ]; } } // using betweenness centrality as parameter if( parameterName == connectomicsRenderingNodeParameterBetweenness ) { std::vector< double > vectorOfBetweenness = this->GetInput()->GetNodeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfBetweenness[index]; } } // using clustering coefficient as parameter if( parameterName == connectomicsRenderingNodeParameterClustering ) { const std::vector< double > vectorOfClustering = this->GetInput()->GetLocalClusteringCoefficients(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfClustering[index]; } } for( int index( 0 ), end( boolVector->size() ); index < end; index++ ) { if( parameterVector.at( index ) >= m_NodeThreshold ) { boolVector->at( index ) = true; } else { boolVector->at( index ) = false; } } return; } void mitk::ConnectomicsNetworkMapper3D::FillEdgeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ) { std::vector< double > parameterVector; parameterVector.resize( boolVector->size() ); int end( parameterVector.size() ); // using the weight as parameter if( parameterName == connectomicsRenderingEdgeParameterWeight ) { std::vector< std::pair< std::pair< mitk::ConnectomicsNetwork::NetworkNode, mitk::ConnectomicsNetwork::NetworkNode > , mitk::ConnectomicsNetwork::NetworkEdge > > vectorOfEdges = this->GetInput()->GetVectorOfAllEdges(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfEdges[ index ].second.weight; } } // using the edge centrality as parameter if( parameterName == connectomicsRenderingEdgeParameterCentrality ) { const std::vector< double > vectorOfCentrality = this->GetInput()->GetEdgeBetweennessVector(); for(int index(0); index < end; index++) { parameterVector.at( index ) = vectorOfCentrality[index]; } } for( int index( 0 ), end( boolVector->size() ); index < end; index++ ) { if( parameterVector.at( index ) >= m_EdgeThreshold ) { boolVector->at( index ) = true; } else { boolVector->at( index ) = false; } } return; } diff --git a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.h b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.h index b596449f0f..391c32906d 100644 --- a/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.h +++ b/Modules/DiffusionImaging/Connectomics/Rendering/mitkConnectomicsNetworkMapper3D.h @@ -1,136 +1,135 @@ /*=================================================================== 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 ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED #define ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED // VTK includes #include #include "vtkPropAssembly.h" // MITK includes // base class -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" // data type #include "mitkConnectomicsNetwork.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ConnectomicsExports.h" namespace mitk { /** * \brief Mapper for Networks * \ingroup Mapper */ - class Connectomics_EXPORT ConnectomicsNetworkMapper3D : public VtkMapper3D + class Connectomics_EXPORT ConnectomicsNetworkMapper3D : public VtkMapper { public: - mitkClassMacro(ConnectomicsNetworkMapper3D, VtkMapper3D); + mitkClassMacro(ConnectomicsNetworkMapper3D, VtkMapper); itkNewMacro(Self); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like deprecated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); virtual void ApplyProperties(mitk::BaseRenderer* renderer); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); - virtual void GenerateData(); virtual const mitk::ConnectomicsNetwork* GetInput(); protected: ConnectomicsNetworkMapper3D(); virtual ~ConnectomicsNetworkMapper3D(); void UpdateVtkObjects(); vtkPropAssembly *m_NetworkAssembly; /** * \brief Returns true if the properties have changed since the last data generation */ bool PropertiesChanged(); // Create vectors for customizing color and radius and return maximum double FillNodeParameterVector( std::vector< double > * parameterVector, std::string parameterName ); double FillEdgeParameterVector( std::vector< double > * parameterVector, std::string parameterName ); void FillNodeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ); void FillEdgeFilterBoolVector( std::vector< bool > * boolVector, std::string parameterName ); // Property storing members std::string m_ChosenRenderingScheme; std::string m_ChosenEdgeFilter; std::string m_EdgeThresholdParameter; double m_EdgeThreshold; std::string m_ChosenNodeFilter; std::string m_NodeThresholdParameter; double m_NodeThreshold; mitk::Color m_NodeColorStart; mitk::Color m_NodeColorEnd; double m_NodeRadiusStart; double m_NodeRadiusEnd; std::string m_ChosenNodeLabel; mitk::Color m_EdgeColorStart; mitk::Color m_EdgeColorEnd; double m_EdgeRadiusStart; double m_EdgeRadiusEnd; std::string m_NodeRadiusParameter; std::string m_NodeColorParameter; std::string m_EdgeRadiusParameter; std::string m_EdgeColorParameter; }; } // namespace mitk #endif /* ConnectomicsNetworkMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkCompositeMapper.h b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkCompositeMapper.h index acd8ef65be..b587249019 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkCompositeMapper.h +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkCompositeMapper.h @@ -1,170 +1,159 @@ /*=================================================================== 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 COMPOSITEMAPPER_H_HEADER_INCLUDED #define COMPOSITEMAPPER_H_HEADER_INCLUDED -#include "mitkGLMapper2D.h" -#include "mitkVtkMapper2D.h" +#include "mitkGLMapper.h" +#include "mitkVtkMapper.h" #include "mitkQBallImage.h" #include "mitkImageVtkMapper2D.h" #include "mitkOdfVtkMapper2D.h" #include "mitkLevelWindowProperty.h" namespace mitk { class CopyImageMapper2D : public ImageVtkMapper2D { public: mitkClassMacro(CopyImageMapper2D,ImageVtkMapper2D); itkNewMacro(Self); friend class CompositeMapper; }; //##Documentation //## @brief Composite pattern for combination of different mappers //## @ingroup Mapper - class CompositeMapper : public VtkMapper2D + class CompositeMapper : public VtkMapper { public: - mitkClassMacro(CompositeMapper,VtkMapper2D) - itkNewMacro(Self) + mitkClassMacro(CompositeMapper,VtkMapper); + itkNewMacro(Self); virtual void MitkRenderOverlay(BaseRenderer* renderer) { m_ImgMapper->MitkRenderOverlay(renderer); m_OdfMapper->MitkRenderOverlay(renderer); } virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer) { m_ImgMapper->MitkRenderOpaqueGeometry(renderer); m_OdfMapper->MitkRenderOpaqueGeometry(renderer); if( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) { renderer->Modified(); } } virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer) { m_ImgMapper->MitkRenderTranslucentGeometry(renderer); m_OdfMapper->MitkRenderTranslucentGeometry(renderer); } virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer) { m_ImgMapper->MitkRenderVolumetricGeometry(renderer); m_OdfMapper->MitkRenderVolumetricGeometry(renderer); } void SetDataNode(DataNode* node) { m_DataNode = node; m_ImgMapper->SetDataNode(node); m_OdfMapper->SetDataNode(node); } mitk::ImageVtkMapper2D::Pointer GetImageMapper() { ImageVtkMapper2D* retval = m_ImgMapper; return retval; } - bool IsVtkBased() const - { - return m_OdfMapper->IsVtkBased(); - } - bool HasVtkProp( const vtkProp* prop, BaseRenderer* renderer ) { return m_OdfMapper->HasVtkProp(prop, renderer); } void ReleaseGraphicsResources(vtkWindow* window) { m_ImgMapper->ReleaseGraphicsResources(window); m_OdfMapper->ReleaseGraphicsResources(window); } static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ) { mitk::OdfVtkMapper2D::SetDefaultProperties(node, renderer, overwrite); mitk::CopyImageMapper2D::SetDefaultProperties(node, renderer, overwrite); mitk::LevelWindow opaclevwin; opaclevwin.SetRangeMinMax(0,255); opaclevwin.SetWindowBounds(0,0); mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin); node->AddProperty( "opaclevelwindow", prop ); } bool IsLODEnabled( BaseRenderer * renderer ) const { return m_ImgMapper->IsLODEnabled(renderer) || m_OdfMapper->IsLODEnabled(renderer); } vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) { vtkPropAssembly* assembly = vtkPropAssembly::New(); assembly->AddPart( m_OdfMapper->GetVtkProp(renderer)); assembly->AddPart( m_ImgMapper->GetVtkProp(renderer)); return assembly; } - void SetGeometry3D(const mitk::Geometry3D* aGeometry3D) - { - m_ImgMapper->SetGeometry3D(aGeometry3D); - m_OdfMapper->SetGeometry3D(aGeometry3D); - } + protected: virtual void Update(mitk::BaseRenderer* renderer) { m_OdfMapper->Update(renderer); GenerateDataForRenderer(renderer); } - protected: - virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer) { m_ImgMapper->GenerateDataForRenderer(renderer); // if( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) > 0 ) // { // m_OdfMapper->GenerateDataForRenderer(renderer); // } } CompositeMapper(); virtual ~CompositeMapper(); private: mitk::OdfVtkMapper2D::Pointer m_OdfMapper; mitk::CopyImageMapper2D::Pointer m_ImgMapper; }; } // namespace mitk #endif /* COMPOSITEMAPPER_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp index ac70a28948..825d657a22 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.cpp @@ -1,161 +1,121 @@ /*=================================================================== 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 "mitkPlanarFigureMapper3D.h" #include #include #include #include mitk::PlanarFigureMapper3D::PlanarFigureMapper3D() : m_points(vtkPoints::New()) , m_polygon(vtkPolygon::New()) , m_polygonPolyData(vtkPolyData::New()) , m_polygonsCell(vtkCellArray::New()) , m_VtkPolygonDataMapperGL(vtkOpenGLPolyDataMapper::New()) , m_PolygonActor(vtkOpenGLActor::New()) , m_PolygonAssembly(vtkPropAssembly::New()) { } //template mitk::PlanarFigureMapper3D::~PlanarFigureMapper3D() { } const mitk::PlanarFigure* mitk::PlanarFigureMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } -/* - This method is called once the mapper gets new input, - for UI rotation or changes in colorcoding this method is NOT called - */ -void mitk::PlanarFigureMapper3D::GenerateData() + +void mitk::PlanarFigureMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { try { - mitk::PlanarFigure* pf = dynamic_cast< mitk::PlanarFigure* > (this->GetData()); + mitk::PlanarFigure* pf = dynamic_cast< mitk::PlanarFigure* > (GetDataNode()->GetData()); const mitk::Geometry2D* pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeo = dynamic_cast(pfgeometry); mitk::Point3D wp; - mitk::PlanarFigure::PolyLineType line = pf->GetPolyLine(0); if (line.size() <= 2) return; m_points->SetNumberOfPoints(line.size()); m_polygon->GetPointIds()->SetNumberOfIds(line.size()); int i=0; for (mitk::PlanarFigure::PolyLineType::iterator it = line.begin(); it!=line.end(); ++it) { mitk::PlanarFigure::PolyLineElement elem = *it; planeGeo->Map(elem.Point, wp); m_points->InsertPoint(i,(double)wp[0], (double)wp[1], (double)wp[2] ); m_polygon->GetPointIds()->SetId(i, i); i++; } m_polygonsCell->Reset(); m_polygonsCell->InsertNextCell(m_polygon); m_polygonPolyData->SetPoints(m_points); m_polygonPolyData->SetPolys(m_polygonsCell); m_VtkPolygonDataMapperGL->SetInput(m_polygonPolyData); m_PolygonActor->SetMapper(m_VtkPolygonDataMapperGL); m_PolygonAssembly->AddPart(m_PolygonActor); - m_VtkPolygonDataMapperGL->Modified(); - } - catch(...) - { - - } -} - -void mitk::PlanarFigureMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) -{ - try - { - mitk::PlanarFigure* pf = dynamic_cast< mitk::PlanarFigure* > (this->GetData()); - - const mitk::Geometry2D* pfgeometry = pf->GetGeometry2D(); - const mitk::PlaneGeometry* planeGeo = dynamic_cast(pfgeometry); - mitk::Point3D wp; - mitk::PlanarFigure::PolyLineType line = pf->GetPolyLine(0); - - if (line.size() <= 2) - return; - - m_points->SetNumberOfPoints(line.size()); - m_polygon->GetPointIds()->SetNumberOfIds(line.size()); - - int i=0; - for (mitk::PlanarFigure::PolyLineType::iterator it = line.begin(); it!=line.end(); ++it) - { - mitk::PlanarFigure::PolyLineElement elem = *it; - planeGeo->Map(elem.Point, wp); - - m_points->InsertPoint(i,(double)wp[0], (double)wp[1], (double)wp[2] ); - m_polygon->GetPointIds()->SetId(i, i); - i++; - } - //updates all polygon pipeline m_VtkPolygonDataMapperGL->Modified(); float polyOpaq; this->GetDataNode()->GetOpacity(polyOpaq, NULL); m_PolygonActor->GetProperty()->SetOpacity((double) polyOpaq); float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; m_PolygonActor->GetProperty()->SetColor(trgb); } catch (...) { } } void mitk::PlanarFigureMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::PlanarFigureMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_PolygonAssembly; } void mitk::PlanarFigureMapper3D::UpdateVtkObjects() { } void mitk::PlanarFigureMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.h b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.h index e6a21daed5..334e883b6d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.h +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkPlanarFigureMapper3D.h @@ -1,76 +1,75 @@ /*=================================================================== 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 PlanarFigureMapper3D_H #define PlanarFigureMapper3D_H #include -#include +#include #include #include #include #include #include #include #include #include #include namespace mitk { //##Documentation //## @brief 3D mapper for planar figures //## @ingroup Mapper // template - class PlanarFigureMapper3D : public VtkMapper3D + class PlanarFigureMapper3D : public VtkMapper { public: - mitkClassMacro(PlanarFigureMapper3D, VtkMapper3D) + mitkClassMacro(PlanarFigureMapper3D, VtkMapper) itkNewMacro(Self) const mitk::PlanarFigure* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like depricated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); - virtual void GenerateData(); protected: PlanarFigureMapper3D(); virtual ~PlanarFigureMapper3D(); void UpdateVtkObjects(); vtkSmartPointer m_points; vtkSmartPointer m_polygon; vtkSmartPointer m_polygonPolyData; vtkSmartPointer m_polygonsCell; vtkSmartPointer m_VtkPolygonDataMapperGL; vtkSmartPointer m_PolygonActor; vtkSmartPointer m_PolygonAssembly; }; } // namespace mitk #endif /* FiberBundleMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp index 6c82f14860..1e45c857ac 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.cpp @@ -1,211 +1,207 @@ /*=================================================================== 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 "mitkVectorImageVtkGlyphMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include /* * Constructor. Doesn't do anything... */ mitk::VectorImageVtkGlyphMapper3D::VectorImageVtkGlyphMapper3D() { m_RandomMode = true; m_UseMaskPoints = true; m_MaximumNumberOfPoints = 5000; m_GlyphType = ArrowGlyph; m_Glyph3DGenerator = vtkMaskedGlyph3D::New(); m_Glyph3DMapper = vtkPolyDataMapper::New(); m_Glyph3DActor = vtkActor::New(); } vtkProp* mitk::VectorImageVtkGlyphMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Glyph3DActor; } /* * Destructor */ mitk::VectorImageVtkGlyphMapper3D::~VectorImageVtkGlyphMapper3D() { if ( m_Glyph3DMapper != NULL ) m_Glyph3DMapper->Delete(); if ( m_Glyph3DGenerator != NULL ) m_Glyph3DGenerator->Delete(); } - /* * Generate a vtkPolyData by creating vectors as glyphs +* This method is called, each time a specific renderer is updated. */ -void mitk::VectorImageVtkGlyphMapper3D::GenerateData() +void mitk::VectorImageVtkGlyphMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) { // // get the input image... // mitk::Image::Pointer mitkImage = this->GetInput(); if ( mitkImage.GetPointer() == NULL ) { itkWarningMacro( << "VectorImage is null !" ); return ; } // // make sure, that the input image is an vector image // if ( mitkImage->GetPixelType().GetNumberOfComponents() <= 1 ) { itkWarningMacro( << "VectorImage has only one scalar component!" ); return ; } vtkImageData* vtkImage = mitkImage->GetVtkImageData(); // // make sure, that we have point data with more than 1 component (as vectors) // vtkPointData* pointData = vtkImage->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "vtkImage->GetPointData() returns NULL!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "vtkImage->GetPointData()->GetNumberOfArrays() is 0!" ); return ; } else if ( pointData->GetArrayName( 0 ) == NULL ) { vtkImage->GetPointData() ->GetArray( 0 ) ->SetName( "vector" ); } if ( vtkImage->GetNumberOfPoints() != 0 ) { // // create the glyph, which has to be shown at each point // of the masked image // vtkPolyData* glyph; if ( m_GlyphType == LineGlyph ) { vtkLineSource * lineSource = vtkLineSource::New(); lineSource->Update(); glyph = lineSource->GetOutput(); } else if ( m_GlyphType == ArrowGlyph ) { vtkArrowSource * arrowSource = vtkArrowSource::New(); arrowSource->Update(); glyph = arrowSource->GetOutput(); } else { // Use a vtkLineSource as default, if the GlyphType is // unknown itkWarningMacro( << "unknown glyph type!" ); vtkLineSource * lineSource = vtkLineSource::New(); lineSource->Update(); glyph = lineSource->GetOutput(); } m_RandomMode = false; m_UseMaskPoints = false; m_MaximumNumberOfPoints = 80*80*80; // // set up the actual glyphing filter // m_Glyph3DGenerator->SetSource( glyph ); m_Glyph3DGenerator->SetInput( vtkImage ); //m_Glyph3DGenerator->SetInputConnection(m_Cutter->GetOutputPort()); m_Glyph3DGenerator->SetInputArrayToProcess (1, 0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); //m_Glyph3DGenerator->SelectInputVectors( vtkImage->GetPointData() ->GetArray( 0 ) ->GetName() ); m_Glyph3DGenerator->OrientOn(); m_Glyph3DGenerator->SetVectorModeToUseVector(); m_Glyph3DGenerator->SetScaleFactor( 0.00392156862745 ); m_Glyph3DGenerator->SetScaleModeToScaleByVector(); m_Glyph3DGenerator->SetUseMaskPoints( m_UseMaskPoints ); m_Glyph3DGenerator->SetRandomMode( m_RandomMode ); m_Glyph3DGenerator->SetMaximumNumberOfPoints( m_MaximumNumberOfPoints ); m_Glyph3DGenerator->Update(); m_Glyph3DMapper->SetInput( m_Glyph3DGenerator->GetOutput() ); m_Glyph3DActor->SetMapper( m_Glyph3DMapper ); if (GetDataNode()->GetProperty("LookupTable")) { mitk::LookupTable::Pointer mitkLookupTable = mitk::LookupTable::New(); m_Glyph3DMapper->Update(); mitkLookupTable->SetVtkLookupTable(dynamic_cast(m_Glyph3DMapper->GetLookupTable())); mitk::LookupTableProperty::Pointer LookupTableProp = mitk::LookupTableProperty::New( mitkLookupTable ); GetDataNode()->SetProperty( "LookupTable", LookupTableProp ); } else { mitk::LookupTableProperty::Pointer mitkLutProp = dynamic_cast(GetDataNode()->GetProperty("LookupTable")); if (mitkLutProp.IsNotNull()) m_Glyph3DMapper->SetLookupTable( mitkLutProp->GetLookupTable()->GetVtkLookupTable() ); } //vtkDataSetWriter* writer = vtkDataSetWriter::New(); //writer->SetInput( vtkImage ); //writer->SetFileName( "out.vtk" ); //writer->Update(); } -} + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); -/* -* This method is called, each time a specific renderer is updated. -*/ -void mitk::VectorImageVtkGlyphMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) -{ - if ( IsVisible( renderer ) == false ) + if ( !visible ) { if ( m_Glyph3DActor != NULL ) m_Glyph3DActor->VisibilityOff(); return ; } else { if ( m_Glyph3DActor != NULL ) m_Glyph3DActor->VisibilityOn(); } } /* * Returns the input data object of the given filter. In this * case, a mitk::Image is returned. */ mitk::Image* mitk::VectorImageVtkGlyphMapper3D::GetInput() { - return const_cast( dynamic_cast( this->GetData() ) ); + return const_cast( dynamic_cast( GetDataNode()->GetData() ) ); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.h b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.h index f75dd01ea8..3c96509165 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.h +++ b/Modules/DiffusionImaging/DiffusionCore/Rendering/mitkVectorImageVtkGlyphMapper3D.h @@ -1,100 +1,96 @@ /*=================================================================== 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_VECTOR_IMAGE_VTK_MAPPER_3D__H #define _MITK_VECTOR_IMAGE_VTK_MAPPER_3D__H #include "DiffusionCoreExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkImage.h" class vtkMaskedGlyph3D; class vtkActor; class vtkPolyDataMapper; class vtkMaskPoints; namespace mitk { -class DiffusionCore_EXPORT VectorImageVtkGlyphMapper3D : public VtkMapper3D +class DiffusionCore_EXPORT VectorImageVtkGlyphMapper3D : public VtkMapper { public: - mitkClassMacro( VectorImageVtkGlyphMapper3D, VtkMapper3D ); + mitkClassMacro( VectorImageVtkGlyphMapper3D, VtkMapper ); itkNewMacro( Self ); enum GlyphType {LineGlyph, ArrowGlyph}; itkSetMacro(MaximumNumberOfPoints, unsigned int); itkGetMacro(MaximumNumberOfPoints, unsigned int); itkSetMacro(UseMaskPoints, bool); itkGetMacro(UseMaskPoints, bool); itkBooleanMacro(UseMaskPoints); itkSetMacro(RandomMode, bool); itkGetMacro(RandomMode, bool); itkBooleanMacro(RandomMode); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); protected: /** * Constructor. Doesn't do anything... */ VectorImageVtkGlyphMapper3D(); /** * Destructor */ virtual ~VectorImageVtkGlyphMapper3D(); /** * Generate a vtkPolyData by creating vectors as glyphs - */ - virtual void GenerateData(); - - /** * This method is called, each time a specific renderer is updated. */ virtual void GenerateDataForRenderer( mitk::BaseRenderer* renderer ); /** * Returns the input data object of the given filter. In this * case, a mitk::Image is returned. */ Image* GetInput(); vtkMaskedGlyph3D* m_Glyph3DGenerator; vtkActor* m_Glyph3DActor; vtkPolyDataMapper* m_Glyph3DMapper; GlyphType m_GlyphType; unsigned int m_MaximumNumberOfPoints; bool m_UseMaskPoints; bool m_RandomMode; }; } //end of namespace mitk #endif diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp index ce6bb4268c..02046959d5 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.cpp @@ -1,336 +1,288 @@ /*=================================================================== 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. ===================================================================*/ /* * mitkFiberBundleMapper2D.cpp * mitk-all * * Created by HAL9000 on 1/17/11. * Copyright 2011 __MyCompanyName__. All rights reserved. * */ #include "mitkFiberBundleXMapper2D.h" #include #include #include #include #include //#include //#include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include mitk::FiberBundleXMapper2D::FiberBundleXMapper2D() { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::FiberBundleXMapper2D::~FiberBundleXMapper2D() { } mitk::FiberBundleX* mitk::FiberBundleXMapper2D::GetInput() { - return dynamic_cast< mitk::FiberBundleX * > ( GetData() ); + return dynamic_cast< mitk::FiberBundleX * > ( GetDataNode()->GetData() ); } void mitk::FiberBundleXMapper2D::Update(mitk::BaseRenderer * renderer) { - if ( !this->IsVisible( renderer ) ) - { - return; - } + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) return; + MITK_DEBUG << "MapperFBX 2D update: "; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper this->CalculateTimeStep( renderer ); //check if updates occured in the node or on the display FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); const DataNode *node = this->GetDataNode(); if ( (localStorage->m_LastUpdateTime < node->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { // MITK_INFO << "UPDATE NEEDED FOR _ " << renderer->GetName(); this->GenerateDataForRenderer( renderer ); } if ((localStorage->m_LastUpdateTime < renderer->GetDisplayGeometry()->GetMTime()) ) //was the display geometry modified? e.g. zooming, panning) { this->UpdateShaderParameter(renderer); } } void mitk::FiberBundleXMapper2D::UpdateShaderParameter(mitk::BaseRenderer * renderer) { FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //get information about current position of views mitk::SliceNavigationController::Pointer sliceContr = renderer->GetSliceNavigationController(); mitk::PlaneGeometry::ConstPointer planeGeo = sliceContr->GetCurrentPlaneGeometry(); //generate according cutting planes based on the view position float sliceN[3], planeOrigin[3]; // since shader uses camera coordinates, transform origin and normal from worldcoordinates to cameracoordinates planeOrigin[0] = (float) planeGeo->GetOrigin()[0]; planeOrigin[1] = (float) planeGeo->GetOrigin()[1]; planeOrigin[2] = (float) planeGeo->GetOrigin()[2]; sliceN[0] = planeGeo->GetNormal()[0]; sliceN[1] = planeGeo->GetNormal()[1]; sliceN[2] = planeGeo->GetNormal()[2]; float tmp1 = planeOrigin[0] * sliceN[0]; float tmp2 = planeOrigin[1] * sliceN[1]; float tmp3 = planeOrigin[2] * sliceN[2]; float d1 = tmp1 + tmp2 + tmp3; //attention, correct normalvector float plane1[4]; plane1[0] = sliceN[0]; plane1[1] = sliceN[1]; plane1[2] = sliceN[2]; plane1[3] = d1; float thickness = 2.0; if(!this->GetDataNode()->GetPropertyValue("Fiber2DSliceThickness",thickness)) MITK_INFO << "FIBER2D SLICE THICKNESS PROPERTY ERROR"; bool fiberfading = false; if(!this->GetDataNode()->GetPropertyValue("Fiber2DfadeEFX",fiberfading)) MITK_INFO << "FIBER2D SLICE FADE EFX PROPERTY ERROR"; int fiberfading_i = 1; if (!fiberfading) fiberfading_i = 0; // set Opacity float fiberOpacity; this->GetDataNode()->GetOpacity(fiberOpacity, NULL); localStorage->m_PointActor->GetProperty()->AddShaderVariable("slicingPlane",4, plane1); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberThickness",1, &thickness); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberFadingON",1, &fiberfading_i); localStorage->m_PointActor->GetProperty()->AddShaderVariable("fiberOpacity", 1, &fiberOpacity); } // ALL RAW DATA FOR VISUALIZATION IS GENERATED HERE. // vtkActors and Mappers are feeded here void mitk::FiberBundleXMapper2D::GenerateDataForRenderer(mitk::BaseRenderer *renderer) { //the handler of local storage gets feeded in this method with requested data for related renderwindow FBXLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); //this procedure is depricated, //not needed after initializaton anymore mitk::DataNode* node = this->GetDataNode(); if ( node == NULL ) { MITK_INFO << "check DATANODE: ....[Fail] "; return; } /////////////////////////////////// ///THIS GET INPUT mitk::FiberBundleX* fbx = this->GetInput(); localStorage->m_PointMapper->ScalarVisibilityOn(); localStorage->m_PointMapper->SetScalarModeToUsePointFieldData(); localStorage->m_PointMapper->SetLookupTable(m_lut); //apply the properties after the slice was set localStorage->m_PointActor->GetProperty()->SetOpacity(0.999); // set color if (fbx->GetCurrentColorCoding() != NULL){ // localStorage->m_PointMapper->SelectColorArray(""); localStorage->m_PointMapper->SelectColorArray(fbx->GetCurrentColorCoding()); MITK_DEBUG << "MapperFBX 2D: " << fbx->GetCurrentColorCoding(); if(fbx->GetCurrentColorCoding() == fbx->COLORCODING_CUSTOM){ float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; localStorage->m_PointActor->GetProperty()->SetColor(trgb); } } localStorage->m_PointMapper->SetInput(fbx->GetFiberPolyData()); localStorage->m_PointActor->SetMapper(localStorage->m_PointMapper); localStorage->m_PointActor->GetProperty()->ShadingOn(); // Applying shading properties { mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),localStorage->m_PointActor,renderer, localStorage->m_LastUpdateTime); } this->UpdateShaderParameter(renderer); // We have been modified => save this for next Update() localStorage->m_LastUpdateTime.Modified(); } vtkProp* mitk::FiberBundleXMapper2D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleMapper2D GetVtkProp(renderer)"; this->Update(renderer); return m_LSH.GetLocalStorage(renderer)->m_PointActor; } void mitk::FiberBundleXMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { //add shader to datano //####### load shader from file ######### QString applicationDir = QCoreApplication::applicationDirPath(); if (applicationDir.endsWith("bin")) applicationDir.append("/"); else if (applicationDir.endsWith("MacOS")) { //on osx, check if path for installer or MITK development is needed applicationDir.append("/"); QFile f( applicationDir+"FiberTrackingLUTBaryCoords.bin" ); if( !f.exists() ) // if file does not exist, then look in MITK development build directory applicationDir.append("../../../"); }else applicationDir.append("\\..\\"); mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( applicationDir.toStdString().c_str(), false ); mitk::ShaderRepository::Pointer shaderRepository = mitk::ShaderRepository::GetGlobalShaderRepository(); shaderRepository->LoadShader(mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderFiberClipping.xml")); //#################################################################### node->SetProperty("shader",mitk::ShaderProperty::New("mitkShaderFiberClipping")); mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite); //add other parameters to propertylist node->AddProperty( "Fiber2DSliceThickness", mitk::FloatProperty::New(2.0f), renderer, overwrite ); node->AddProperty( "Fiber2DfadeEFX", mitk::BoolProperty::New(true), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } - - - -// following methods are essential, they actually call the GetVtkProp() method -// which returns the desired actors -void mitk::FiberBundleXMapper2D::MitkRenderOverlay(BaseRenderer* renderer) -{ - // MITK_INFO << "FiberBundleMapper2D MitkRenderOVerlay(renderer)"; - if ( this->IsVisible(renderer)==false ) - return; - - if ( this->GetVtkProp(renderer)->GetVisibility() ) - { - this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); - } -} - -void mitk::FiberBundleXMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer) -{ - // MITK_INFO << "FiberBundleMapper2D MitkRenderOpaqueGeometry(renderer)"; - if ( this->IsVisible( renderer )==false ) - return; - - if ( this->GetVtkProp(renderer)->GetVisibility() ) - this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); -} -void mitk::FiberBundleXMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer) -{ - // MITK_INFO << "FiberBundleMapper2D MitkRenderTranslucentGeometry(renderer)"; - if ( this->IsVisible(renderer)==false ) - return; - - //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer??? - if ( this->GetVtkProp(renderer)->GetVisibility() ) - this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); - -} -void mitk::FiberBundleXMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer) -{ - // MITK_INFO << "FiberBundleMapper2D MitkRenderVolumentricGeometry(renderer)"; - if(IsVisible(renderer)==false) - return; - - //TODO is it possible to have a visible BaseRenderer AND an invisible VtkRenderer??? - if ( GetVtkProp(renderer)->GetVisibility() ) - this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); - -} - mitk::FiberBundleXMapper2D::FBXLocalStorage::FBXLocalStorage() { m_PointActor = vtkSmartPointer::New(); m_PointMapper = vtkSmartPointer::New(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.h b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.h index 40a4110f13..6381cb381d 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.h +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper2D.h @@ -1,111 +1,107 @@ /*=================================================================== 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 FIBERBUNDLEXMAPPER2D_H_HEADER_INCLUDED #define FIBERBUNDLEXMAPPER2D_H_HEADER_INCLUDED //MITK Rendering #include #include //#include "FiberTrackingExports.h" -#include +#include #include #include class vtkActor; //class vtkPropAssembly; //lets see if we need it class mitkBaseRenderer; class vtkPolyDataMapper; class vtkCutter; class vtkPlane; class vtkPolyData; namespace mitk { - class FiberBundleXMapper2D : public VtkMapper2D + class FiberBundleXMapper2D : public VtkMapper { public: - mitkClassMacro(FiberBundleXMapper2D, VtkMapper2D); + mitkClassMacro(FiberBundleXMapper2D, VtkMapper); itkNewMacro(Self); mitk::FiberBundleX* GetInput(); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); //### methods of MITK-VTK rendering pipeline virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); - virtual void MitkRenderOverlay(BaseRenderer* renderer); - virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); - virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); - virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); //### end of methods of MITK-VTK rendering pipeline class FBXLocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Point Actor of a 2D render window. */ vtkSmartPointer m_PointActor; /** \brief Point Mapper of a 2D render window. */ vtkSmartPointer m_PointMapper; vtkSmartPointer m_SlicingPlane; //needed later when optimized 2D mapper vtkSmartPointer m_SlicedResult; //might be depricated in optimized 2D mapper /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief Constructor of the local storage. Do as much actions as possible in here to avoid double executions. */ FBXLocalStorage(); //if u copy&paste from this 2Dmapper, be aware that the implementation of this constructor is in the cpp file ~FBXLocalStorage() { } }; /** \brief This member holds all three LocalStorages for the three 2D render windows. */ mitk::Mapper::LocalStorageHandler m_LSH; protected: FiberBundleXMapper2D(); virtual ~FiberBundleXMapper2D(); /** Does the actual resampling, without rendering. */ virtual void GenerateDataForRenderer(mitk::BaseRenderer*); void UpdateShaderParameter(mitk::BaseRenderer*); private: vtkSmartPointer m_lut; }; }//end namespace #endif diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp index 51fa92e13c..75c540a01e 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.cpp @@ -1,200 +1,202 @@ /*=================================================================== 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 "mitkFiberBundleXMapper3D.h" #include //#include //#include #include #include #include #include //not essential for mapper #include mitk::FiberBundleXMapper3D::FiberBundleXMapper3D() { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::FiberBundleXMapper3D::~FiberBundleXMapper3D() { } const mitk::FiberBundleX* mitk::FiberBundleXMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ void mitk::FiberBundleXMapper3D::GenerateData(mitk::BaseRenderer *renderer) { //MITK_INFO << "GENERATE DATA FOR FBX :)"; //=====timer measurement==== QTime myTimer; myTimer.start(); //========================== - mitk::FiberBundleX* FBX = dynamic_cast (this->GetData()); + mitk::FiberBundleX* FBX = dynamic_cast (GetDataNode()->GetData()); if (FBX == NULL) return; vtkSmartPointer FiberData = FBX->GetFiberPolyData(); if (FiberData == NULL) return; FBXLocalStorage3D *localStorage = m_LSH.GetLocalStorage(renderer); localStorage->m_FiberMapper->SetInput(FiberData); if ( FiberData->GetPointData()->GetNumberOfArrays() > 0 ) localStorage->m_FiberMapper->SelectColorArray( FBX->GetCurrentColorCoding() ); localStorage->m_FiberMapper->ScalarVisibilityOn(); localStorage->m_FiberMapper->SetScalarModeToUsePointFieldData(); localStorage->m_FiberActor->SetMapper(localStorage->m_FiberMapper); localStorage->m_FiberMapper->SetLookupTable(m_lut); // set Opacity float tmpopa; this->GetDataNode()->GetOpacity(tmpopa, NULL); localStorage->m_FiberActor->GetProperty()->SetOpacity((double) tmpopa); // set color if (FBX->GetCurrentColorCoding() != NULL){ // localStorage->m_FiberMapper->SelectColorArray(""); localStorage->m_FiberMapper->SelectColorArray(FBX->GetCurrentColorCoding()); MITK_DEBUG << "MapperFBX: " << FBX->GetCurrentColorCoding(); if(FBX->GetCurrentColorCoding() == FBX->COLORCODING_CUSTOM) { float temprgb[3]; this->GetDataNode()->GetColor( temprgb, NULL ); double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; localStorage->m_FiberActor->GetProperty()->SetColor(trgb); } } localStorage->m_FiberAssembly->AddPart(localStorage->m_FiberActor); localStorage->m_LastUpdateTime.Modified(); //since this method is called after generating all necessary data for fiber visualization, all modifications are represented so far. } void mitk::FiberBundleXMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { - if ( !this->IsVisible( renderer ) ) - return; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) return; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper this->CalculateTimeStep( renderer ); //check if updates occured in the node or on the display FBXLocalStorage3D *localStorage = m_LSH.GetLocalStorage(renderer); const DataNode *node = this->GetDataNode(); if ( (localStorage->m_LastUpdateTime < node->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { MITK_DEBUG << "UPDATE NEEDED FOR _ " << renderer->GetName(); this->GenerateData(renderer); } } void mitk::FiberBundleXMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // MITK_INFO << "FiberBundleXxXXMapper3D()SetDefaultProperties"; //MITK_INFO << "FiberBundleMapperX3D SetDefault Properties(...)"; // node->AddProperty( "DisplayChannel", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "LineWidth", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); // node->AddProperty( "VertexOpacity_1", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "Set_FA_VertexAlpha", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "pointSize", mitk::FloatProperty::New(0.5), renderer, overwrite); // node->AddProperty( "setShading", mitk::IntProperty::New(1), renderer, overwrite); // node->AddProperty( "Xmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Ymove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "Zmove", mitk::IntProperty::New( 0 ), renderer, overwrite); // node->AddProperty( "RepPoints", mitk::BoolProperty::New( false ), renderer, overwrite); // node->AddProperty( "TubeSides", mitk::IntProperty::New( 8 ), renderer, overwrite); // node->AddProperty( "TubeRadius", mitk::FloatProperty::New( 0.15 ), renderer, overwrite); // node->AddProperty( "TubeOpacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); node->AddProperty( "pickable", mitk::BoolProperty::New( true ), renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::FiberBundleXMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleXxXXMapper3D()GetVTKProp"; //this->GenerateData(); return m_LSH.GetLocalStorage(renderer)->m_FiberAssembly; } void mitk::FiberBundleXMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { } void mitk::FiberBundleXMapper3D::UpdateVtkObjects() { } void mitk::FiberBundleXMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } mitk::FiberBundleXMapper3D::FBXLocalStorage3D::FBXLocalStorage3D() { m_FiberActor = vtkSmartPointer::New(); m_FiberMapper = vtkSmartPointer::New(); m_FiberAssembly = vtkSmartPointer::New(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.h b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.h index 6d238416cc..f4e73c98e4 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.h +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXMapper3D.h @@ -1,104 +1,104 @@ /*=================================================================== 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 FiberBundleXMapper3D_H_HEADER_INCLUDED #define FiberBundleXMapper3D_H_HEADER_INCLUDED //#include //?? necessary #include -#include +#include #include #include #include #include #include class vtkPropAssembly; namespace mitk { //##Documentation //## @brief Mapper for FiberBundleX //## @ingroup Mapper -class FiberTracking_EXPORT FiberBundleXMapper3D : public VtkMapper3D +class FiberTracking_EXPORT FiberBundleXMapper3D : public VtkMapper { public: - mitkClassMacro(FiberBundleXMapper3D, VtkMapper3D); + mitkClassMacro(FiberBundleXMapper3D, VtkMapper); itkNewMacro(Self); //========== essential implementation for 3D mapper ======== const FiberBundleX* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like depricated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); virtual void ApplyProperties(mitk::BaseRenderer* renderer); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); //========================================================= virtual void GenerateData(mitk::BaseRenderer *renderer); class FBXLocalStorage3D : public mitk::Mapper::BaseLocalStorage { public: /** \brief Point Actor of a 3D render window. */ vtkSmartPointer m_FiberActor; /** \brief Point Mapper of a 3D render window. */ vtkSmartPointer m_FiberMapper; vtkSmartPointer m_FiberAssembly; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief Constructor of the local storage. Do as much actions as possible in here to avoid double executions. */ FBXLocalStorage3D(); //if u copy&paste from this 2Dmapper, be aware that the implementation of this constructor is in the cpp file ~FBXLocalStorage3D() { } }; /** \brief This member holds all three LocalStorages for the 3D render window(s). */ mitk::Mapper::LocalStorageHandler m_LSH; protected: FiberBundleXMapper3D(); virtual ~FiberBundleXMapper3D(); void UpdateVtkObjects(); //?? private: vtkSmartPointer m_lut; }; } // end namespace mitk #endif /* FiberBundleXMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp index b26341abea..281db2efb0 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.cpp @@ -1,213 +1,206 @@ /*=================================================================== 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 "mitkFiberBundleXThreadMonitorMapper3D.h" #include #include //#include #include mitk::FiberBundleXThreadMonitorMapper3D::FiberBundleXThreadMonitorMapper3D() : m_FiberMonitorMapper(vtkSmartPointer::New()) , m_TextActorClose(vtkSmartPointer::New()) , m_TextActorOpen(vtkSmartPointer::New()) , m_TextActorHeading(vtkSmartPointer::New()) , m_TextActorMask(vtkSmartPointer::New()) , m_TextActorStatus(vtkSmartPointer::New()) , m_TextActorStarted(vtkSmartPointer::New()) , m_TextActorFinished(vtkSmartPointer::New()) , m_TextActorTerminated(vtkSmartPointer::New()) , m_FiberAssembly(vtkPropAssembly::New()) , m_lastModifiedMonitorNodeTime(-1) { m_FiberAssembly->AddPart(m_TextActorClose); m_FiberAssembly->AddPart(m_TextActorOpen); m_FiberAssembly->AddPart(m_TextActorHeading); m_FiberAssembly->AddPart(m_TextActorMask); m_FiberAssembly->AddPart(m_TextActorStatus); m_FiberAssembly->AddPart(m_TextActorStarted); m_FiberAssembly->AddPart(m_TextActorFinished); m_FiberAssembly->AddPart(m_TextActorTerminated); } mitk::FiberBundleXThreadMonitorMapper3D::~FiberBundleXThreadMonitorMapper3D() { m_FiberAssembly->Delete(); } const mitk::FiberBundleXThreadMonitor* mitk::FiberBundleXThreadMonitorMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ -void mitk::FiberBundleXThreadMonitorMapper3D::GenerateData() +void mitk::FiberBundleXThreadMonitorMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { -// MITK_INFO << m_LastUpdateTime; - FiberBundleXThreadMonitor* monitor = dynamic_cast ( GetData() ); + + // MITK_INFO << m_LastUpdateTime; + FiberBundleXThreadMonitor* monitor = dynamic_cast ( GetDataNode()->GetData() ); // m_TextActor->SetInput( monitor->getTextL1().toStdString().c_str() ); m_TextActorClose->SetInput( monitor->getBracketClose().toStdString().c_str() ); vtkTextProperty* tpropClose = m_TextActorClose->GetTextProperty(); //tprop->SetFontFamilyToArial (); //tprop->SetLineSpacing(1.0); tpropClose->SetFontSize(16); tpropClose->SetColor(0.85,0.8,0.8); m_TextActorClose->SetDisplayPosition( monitor->getBracketClosePosition()[0], monitor->getBracketClosePosition()[1] ); //m_TextActorClose->Modified(); m_TextActorOpen->SetInput( monitor->getBracketOpen().toStdString().c_str() ); vtkTextProperty* tpropOpen = m_TextActorOpen->GetTextProperty(); //tprop->SetFontFamilyToArial (); //tprop->SetLineSpacing(1.0); tpropOpen->SetFontSize(16); tpropOpen->SetColor(0.85,0.8,0.8); m_TextActorOpen->SetDisplayPosition( monitor->getBracketOpenPosition()[0], monitor->getBracketOpenPosition()[1] ); //m_TextActorOpen->Modified(); - m_TextActorHeading->SetInput( monitor->getHeading().toStdString().c_str() ); vtkTextProperty* tpropHeading = m_TextActorHeading->GetTextProperty(); tpropHeading->SetFontSize(12); tpropHeading->SetOpacity( monitor->getHeadingOpacity() * 0.1 ); tpropHeading->SetColor(0.85,0.8,0.8); m_TextActorHeading->SetDisplayPosition( monitor->getHeadingPosition()[0], monitor->getHeadingPosition()[1] ); //m_TextActorHeading->Modified(); m_TextActorMask->SetInput( monitor->getMask().toStdString().c_str() ); vtkTextProperty* tpropMask = m_TextActorMask->GetTextProperty(); tpropMask->SetFontSize(12); tpropMask->SetOpacity( monitor->getMaskOpacity() * 0.1 ); tpropMask->SetColor(1.0,1.0,1.0); m_TextActorMask->SetDisplayPosition( monitor->getMaskPosition()[0], monitor->getMaskPosition()[1] ); //m_TextActorHeading->Modified(); m_TextActorStatus->SetInput(monitor->getStatus().toStdString().c_str()); vtkTextProperty* tpropStatus = m_TextActorStatus->GetTextProperty(); tpropStatus->SetFontSize(10); tpropStatus->SetOpacity( monitor->getStatusOpacity() * 0.1 ); tpropStatus->SetColor(0.85,0.8,0.8); m_TextActorStatus->SetDisplayPosition( monitor->getStatusPosition()[0], monitor->getStatusPosition()[1] ); //m_TextActorStatus->Modified(); m_TextActorStarted->SetInput(QString::number(monitor->getStarted()).toStdString().c_str()); vtkTextProperty* tpropStarted = m_TextActorStarted->GetTextProperty(); tpropStarted->SetFontSize(12); tpropStarted->SetOpacity( monitor->getStartedOpacity() * 0.1 ); tpropStarted->SetColor(0.0,1.0,0.0); m_TextActorStarted->SetDisplayPosition( monitor->getStartedPosition()[0], monitor->getStartedPosition()[1] ); //m_TextActorStarted->Modified(); m_TextActorFinished->SetInput(QString::number(monitor->getFinished()).toStdString().c_str()); vtkTextProperty* tpropFinished = m_TextActorFinished->GetTextProperty(); tpropFinished->SetFontSize(12); tpropFinished->SetOpacity( monitor->getFinishedOpacity() * 0.1 ); tpropFinished->SetColor(1.0,1.0,1.0); m_TextActorFinished->SetDisplayPosition( monitor->getFinishedPosition()[0], monitor->getFinishedPosition()[1] ); //m_TextActorFinished->Modified(); m_TextActorTerminated->SetInput(QString::number(monitor->getTerminated()).toStdString().c_str()); vtkTextProperty* tpropTerminated = m_TextActorTerminated->GetTextProperty(); tpropTerminated->SetFontSize(12); tpropTerminated->SetOpacity( monitor->getTerminatedOpacity() * 0.1 ); tpropTerminated->SetColor(1.0,1.0,1.0); m_TextActorTerminated->SetDisplayPosition( monitor->getTerminatedPosition()[0], monitor->getTerminatedPosition()[1] ); //m_TextActorTerminated->Modified(); + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); -} - - - -void mitk::FiberBundleXThreadMonitorMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) -{ - if ( !this->IsVisible( renderer ) ) - { - return; - } + if ( !visible ) return; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper // this->CalculateTimeStep( renderer ); const DataNode *node = this->GetDataNode(); if (m_lastModifiedMonitorNodeTime < node->GetMTime()) { this->GenerateData(); m_lastModifiedMonitorNodeTime = node->GetMTime(); } } void mitk::FiberBundleXThreadMonitorMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // MITK_INFO << "FiberBundleXxXXMapper3D()SetDefaultProperties"; Superclass::SetDefaultProperties(node, renderer, overwrite); } vtkProp* mitk::FiberBundleXThreadMonitorMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { //MITK_INFO << "FiberBundleXxXXMapper3D()GetVTKProp"; //this->GenerateData(); return m_FiberAssembly; } void mitk::FiberBundleXThreadMonitorMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { // MITK_INFO << "FiberBundleXXXXMapper3D ApplyProperties(renderer)"; } void mitk::FiberBundleXThreadMonitorMapper3D::UpdateVtkObjects() { // MITK_INFO << "FiberBundleXxxXMapper3D UpdateVtkObjects()"; } void mitk::FiberBundleXThreadMonitorMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } diff --git a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.h b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.h index dbff4caf6c..45c259fd93 100644 --- a/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.h +++ b/Modules/DiffusionImaging/FiberTracking/Rendering/mitkFiberBundleXThreadMonitorMapper3D.h @@ -1,90 +1,89 @@ /*=================================================================== 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 FiberBundleXThreadMonitorMapper3D_H_HEADER_INCLUDED #define FiberBundleXThreadMonitorMapper3D_H_HEADER_INCLUDED //#include //?? necessary #include -#include +#include #include #include #include #include class vtkPropAssembly; namespace mitk { //##Documentation //## @brief Mapper for FiberBundleX //## @ingroup Mapper - class FiberTracking_EXPORT FiberBundleXThreadMonitorMapper3D : public VtkMapper3D + class FiberTracking_EXPORT FiberBundleXThreadMonitorMapper3D : public VtkMapper { public: - mitkClassMacro(FiberBundleXThreadMonitorMapper3D, VtkMapper3D); + mitkClassMacro(FiberBundleXThreadMonitorMapper3D, VtkMapper); itkNewMacro(Self); //========== essential implementation for 3D mapper ======== const FiberBundleXThreadMonitor* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like depricated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); virtual void ApplyProperties(mitk::BaseRenderer* renderer); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); - virtual void GenerateData(); //========================================================= protected: FiberBundleXThreadMonitorMapper3D(); virtual ~FiberBundleXThreadMonitorMapper3D(); void UpdateVtkObjects(); //?? vtkSmartPointer m_FiberMonitorMapper; vtkSmartPointer m_TextActorClose; vtkSmartPointer m_TextActorOpen; vtkSmartPointer m_TextActorHeading; vtkSmartPointer m_TextActorMask; vtkSmartPointer m_TextActorStatus; vtkSmartPointer m_TextActorStarted; vtkSmartPointer m_TextActorFinished; vtkSmartPointer m_TextActorTerminated; vtkPropAssembly* m_FiberAssembly; private: double m_lastModifiedMonitorNodeTime; }; } // end namespace mitk #endif /* FiberBundleXMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp index 1a2cf91fad..cde313ed90 100644 --- a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp @@ -1,437 +1,434 @@ /*=================================================================== 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 "mitkEnhancedPointSetVtkMapper3D.h" //#include #include #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkLookupTables.h" #include "mitkColorProperty.h" //#include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include const mitk::PointSet* mitk::EnhancedPointSetVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } mitk::EnhancedPointSetVtkMapper3D::EnhancedPointSetVtkMapper3D() { m_Contour = vtkActor::New(); m_ContourSource = vtkTubeFilter::New(); m_PropAssembly = vtkAssembly::New(); } vtkProp* mitk::EnhancedPointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_PropAssembly; } mitk::EnhancedPointSetVtkMapper3D::~EnhancedPointSetVtkMapper3D() { m_Contour->Delete(); m_ContourSource->Delete(); m_PropAssembly->Delete(); // TODO: do cleanup correctly // Clean up all remaining actors and poly-data sources //std::for_each(m_PointActors.begin(), m_PointActors.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_SphereSources.begin(), m_SphereSources.end(), &mitk::EnhancedPointSetVtgkMapper3D::DeleteVtkObject); // std::for_each(m_CubeSources.begin(), m_CubeSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_ConeSources.begin(), m_ConeSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_CylinderSources.begin(), m_CylinderSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // } void mitk::EnhancedPointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow * /*renWin*/) { // TODO: Do we have to call this for all actors?? //m_Actor->ReleaseGraphicsResources(renWin); } void mitk::EnhancedPointSetVtkMapper3D::UpdateVtkObjects() { // get and update the PointSet const mitk::PointSet* pointset = this->GetInput(); //pointset->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType* itkPointSet = pointset->GetPointSet( timestep ); mitk::PointSet::PointsContainer* points = itkPointSet->GetPoints(); mitk::PointSet::PointDataContainer* pointData = itkPointSet->GetPointData(); assert(points->Size() == pointData->Size()); mitk::PointSet::PointsIterator pIt; mitk::PointSet::PointDataIterator pdIt; /* search removed points and delete the corresponding source/actor/mapper objects */ for (ActorMap::iterator it = m_PointActors.begin(); it != m_PointActors.end(); ) { PointIdentifier id = it->first; if (!points->IndexExists(id)) { this->RemoveEntryFromSourceMaps(id); m_PropAssembly->GetParts()->RemoveItem(it->second.first); // remove from prop assembly if (it->second.first != NULL) it->second.first->Delete(); // Delete actor, which deletes mapper too (reference count) ActorMap::iterator er = it; // save iterator for deleting ++it; // advance iterator to next object m_PointActors.erase(er); // erase element from map. This invalidates er, therefore we had to advance it before deletion. } else ++it; } /* iterate over each point in the pointset and create corresponding vtk objects */ for (pIt = points->Begin(), pdIt = pointData->Begin(); pIt != itkPointSet->GetPoints()->End(); ++pIt, ++pdIt) { PointIdentifier pointID = pIt->Index(); assert (pointID == pdIt->Index()); mitk::PointSet::PointType point = pIt->Value(); mitk::PointSet::PointDataType data = pdIt->Value(); ActorMap::iterator aIt = m_PointActors.find(pointID); // Does an actor exist for the point? /* Create/Update sources for the point */ vtkActor* a = NULL; bool newPoint = (aIt == m_PointActors.end()); // current point is new bool specChanged = (!newPoint && data.pointSpec != aIt->second.second); // point spec of current point has changed if (newPoint) // point did not exist before, we have to create vtk objects for it { // create actor and mapper for the new point a = vtkActor::New(); vtkPolyDataMapper* m = vtkPolyDataMapper::New(); a->SetMapper(m); m->UnRegister( NULL ); aIt = m_PointActors.insert(std::make_pair(pointID, std::make_pair(a, data.pointSpec))).first; // insert element and update actormap iterator to point to new element m_PropAssembly->AddPart(a); } else { a = aIt->second.first; if (specChanged) // point exists, but point spec has changed { this->RemoveEntryFromSourceMaps( pointID ); } } if ( newPoint || specChanged ) // new point OR existing point but point spec changed { vtkPolyDataAlgorithm* source = NULL; // works only in VTK 5+ switch (data.pointSpec) // add to new map { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID] = vtkCubeSource::New(); source = m_CubeSources[pointID]; break; case PTCORNER: //cone m_ConeSources[pointID] = vtkConeSource::New(); source = m_ConeSources[pointID]; break; case PTEDGE: // cylinder m_CylinderSources[pointID] = vtkCylinderSource::New(); source = m_CylinderSources[pointID]; break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID] = vtkSphereSource::New(); source = m_SphereSources[pointID]; break; } vtkPolyDataMapper* m = dynamic_cast(a->GetMapper()); assert(m != NULL); m->SetInput(source->GetOutput()); aIt->second.second = data.pointSpec; // update point spec in actormap } } // for each point } -void mitk::EnhancedPointSetVtkMapper3D::GenerateData() +void mitk::EnhancedPointSetVtkMapper3D::ApplyProperties( mitk::BaseRenderer * renderer ) { - this->UpdateVtkObjects(); -} + this->UpdateVtkObjects(); -void mitk::EnhancedPointSetVtkMapper3D::ApplyProperties( mitk::BaseRenderer * renderer ) -{ /* iterate over all points in pointset and apply properties to corresponding vtk objects */ // get and update the PointSet const mitk::PointSet* pointset = this->GetInput(); int timestep = this->GetTimestep(); mitk::PointSet::DataType* itkPointSet = pointset->GetPointSet( timestep ); mitk::PointSet::PointsContainer* points = itkPointSet->GetPoints(); mitk::PointSet::PointDataContainer* pointData = itkPointSet->GetPointData(); assert(points->Size() == pointData->Size()); mitk::PointSet::PointsIterator pIt; mitk::PointSet::PointDataIterator pdIt; mitk::DataNode* n = this->GetDataNode(); assert(n != NULL); for (pIt = points->Begin(), pdIt = pointData->Begin(); pIt != itkPointSet->GetPoints()->End(); ++pIt, ++pdIt) // for each point in the pointset { PointIdentifier pointID = pIt->Index(); assert (pointID == pdIt->Index()); mitk::PointSet::PointType point = pIt->Value(); mitk::PointSet::PointDataType data = pdIt->Value(); ActorMap::iterator aIt = m_PointActors.find(pointID); // Does an actor exist for the point? assert(aIt != m_PointActors.end()); // UpdateVtkObjects() must ensure that actor exists vtkActor* a = aIt->second.first; assert(a != NULL); SetVtkMapperImmediateModeRendering(a->GetMapper()); /* update properties */ // visibility bool pointVisibility = true; bool visValueFound = false; mitk::BaseProperty* visProp = n->GetProperty("visibility", renderer); mitk::BoolLookupTableProperty* visLTProp = dynamic_cast(visProp); if (visLTProp != NULL) { mitk::BoolLookupTable visLookupTable = visLTProp->GetValue(); //if (visLookupTable != NULL) //{ try { pointVisibility = visLookupTable.GetTableValue(pointID); visValueFound = true; } catch (...) { } //} } if (visValueFound == false) { pointVisibility = n->IsVisible(renderer, "show points"); // use BoolProperty instead } a->SetVisibility(pointVisibility); // opacity float opacity = 1.0; bool opValueFound = false; mitk::BaseProperty* opProp = n->GetProperty("opacity", renderer); mitk::FloatLookupTableProperty* opLTProp = dynamic_cast(opProp); if (opLTProp != NULL) { mitk::FloatLookupTable opLookupTable = opLTProp->GetValue(); //if (opLookupTable != NULL) //{ try { opacity = opLookupTable.GetTableValue(pointID); opValueFound = true; } catch (...) { } //} } if (opValueFound == false) { n->GetOpacity(opacity, renderer); } a->GetProperty()->SetOpacity(opacity); ////////////////////// continue here /////////////////// // pointsize & point position float pointSize = 1.0; n->GetFloatProperty( "pointsize", pointSize, renderer); switch (data.pointSpec) { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID]->SetXLength(pointSize); m_CubeSources[pointID]->SetYLength(pointSize); m_CubeSources[pointID]->SetZLength(pointSize); //m_CubeSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTCORNER: //cone m_ConeSources[pointID]->SetRadius(pointSize/2); m_ConeSources[pointID]->SetHeight(pointSize); m_ConeSources[pointID]->SetResolution(2); // two crossed triangles. Maybe introduce an extra property for //m_ConeSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTEDGE: // cylinder m_CylinderSources[pointID]->SetRadius(pointSize/2); m_CylinderSources[pointID]->SetHeight(pointSize); m_CylinderSources[pointID]->CappingOn(); m_CylinderSources[pointID]->SetResolution(6); //m_CylinderSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID]->SetRadius(pointSize/2); m_SphereSources[pointID]->SetThetaResolution(10); m_SphereSources[pointID]->SetPhiResolution(10); //m_SphereSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; } // set position mitk::Point3D pos = pIt->Value(); aIt->second.first->SetPosition(pos[0], pos[1], pos[2]); // selectedcolor & color float color[3]; if (data.selected) { if(!n->GetColor(color, renderer, "selectedcolor")) n->GetColor(color, renderer); } else { mitk::BaseProperty* a = n->GetProperty("colorLookupTable", renderer); mitk::LookupTableProperty* b = dynamic_cast(a); if (b != NULL) { mitk::LookupTable::Pointer c = b->GetLookupTable(); vtkLookupTable *d = c->GetVtkLookupTable(); double *e=d->GetTableValue(pointID); color[0]=e[0]; color[1]=e[1]; color[2]=e[2]; } else { if(!n->GetColor(color, renderer, "unselectedcolor")) n->GetColor(color, renderer); } } // TODO: What about "color" property? 2D Mapper only uses unselected and selected color properties a->GetProperty()->SetColor(color[0], color[1], color[2]); // TODO: label property } //TODO test different pointSpec // TODO "line width" "show contour" "contourcolor" "contoursize" "close contour" "show label", "label" // TODO "show points" vs "visibility" - is visibility evaluated at all? in a superclass maybe? // TODO create lookup tables for all properties that should be evaluated per point. also create editor widgets for these lookup tables! // TODO check if property changes and pointset changes are reflected in the render window immediately. // TODO check behavior with large PointSets // TODO check for memory leaks on adding/deleting points } void mitk::EnhancedPointSetVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer * renderer ) { ApplyProperties(renderer); } void mitk::EnhancedPointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { // TODO: apply new transform if time step changed //vtkLinearTransform * vtktransform = // this->GetDataNode()->GetVtkTransform(this->GetTimestep()); //m_SelectedActor->SetUserTransform(vtktransform); //m_UnselectedActor->SetUserTransform(vtktransform); //m_ContourActor->SetUserTransform(vtktransform); } void mitk::EnhancedPointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow for selected node->AddProperty( "unselectedcolor", mitk::ColorProperty::New(0.5f, 1.0f, 0.5f), renderer, overwrite); // middle green for unselected node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); // red as standard node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "show label", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "label", mitk::StringProperty::New("P"), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject( vtkObject* o) { if (o != NULL) o->Delete(); } void mitk::EnhancedPointSetVtkMapper3D::RemoveEntryFromSourceMaps( mitk::PointSet::PointIdentifier pointID ) { ActorMap::iterator aIt = m_PointActors.find(pointID); if (aIt == m_PointActors.end()) return; switch (aIt->second.second) // erase in old map { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID]->Delete(); m_CubeSources.erase(pointID); break; case PTCORNER: //cone m_ConeSources[pointID]->Delete(); m_ConeSources.erase(pointID); break; case PTEDGE: // cylinder m_CylinderSources[pointID]->Delete(); m_CylinderSources.erase(pointID); break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID]->Delete(); m_SphereSources.erase(pointID); break; } } diff --git a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.h b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.h index 445bac2205..84ebcf36c2 100644 --- a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.h @@ -1,124 +1,123 @@ /*=================================================================== 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 MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 #define MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkBaseRenderer.h" #include "mitkPointSet.h" #include "mitkVector.h" class vtkActor; class vtkAssembly; class vtkSphereSource; class vtkCubeSource; class vtkConeSource; class vtkCylinderSource; class vtkTubeFilter; class vtkProp; namespace mitk { /** * \brief Alternative Vtk-based 3D mapper for mitk::PointSet * * This class renders mitk::PointSet objects in 3D views. It resembles the * standard mitk::PointSetVtkMapper3D, but is designed to enable single * points to be rendered with individual appearances. * * Instead of assembling one vtkPolyData object containing all points, * a list of VTK source objects (spheres, cubes, cones, ...) is maintained. * Therefore, the application can change the appearance and/or type of a * specific point at runtime, without having to rebuild the * * You should use this class instead of the standard mapper if you * * - change the PointSet very often (by adding or removing points) * - need different representations for points (+++) * - want to change the point representation frequently (+++) * * Note: the class is still in experimental stage, and the points above * marked with (+++) are not yet working correctly. Also, drawing lines * between points (contour mode) is not yet supported. The class will be * extended so that point representations are stored in a lookup table, * which is indexed by point data from the rendered PointSet. * * \warn This mapper requires the PointData container to be the same size * as the point container. * * \sa PointSetVtkMapper3D */ - class MitkExt_EXPORT EnhancedPointSetVtkMapper3D : public VtkMapper3D + class MitkExt_EXPORT EnhancedPointSetVtkMapper3D : public VtkMapper { public: - mitkClassMacro(EnhancedPointSetVtkMapper3D, VtkMapper3D); + mitkClassMacro(EnhancedPointSetVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::PointSet* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void ReleaseGraphicsResources(vtkWindow *renWin); protected: EnhancedPointSetVtkMapper3D(); virtual ~EnhancedPointSetVtkMapper3D(); void RemoveEntryFromSourceMaps( mitk::PointSet::PointIdentifier pointID ); void DeleteVtkObject(vtkObject* o); // functor for stl_each in destructor // update all vtk sources, mappers, actors with current data and properties void UpdateVtkObjects(); - virtual void GenerateData(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ApplyProperties(mitk::BaseRenderer* renderer); typedef mitk::PointSet::PointIdentifier PointIdentifier; typedef std::map SphereSourceMap; typedef std::map CubeSourceMap; typedef std::map ConeSourceMap; typedef std::map CylinderSourceMap; typedef std::pair ActorAndPointType; typedef std::map ActorMap; SphereSourceMap m_SphereSources; // stores all sphere sources CubeSourceMap m_CubeSources; // stores all cube sources ConeSourceMap m_ConeSources; // stores all cone sources CylinderSourceMap m_CylinderSources; // stores all cylinder sources ActorMap m_PointActors; // stores an actor for each point(referenced by its ID) and the currently used pointspec = which source type is generating the polydata vtkActor* m_Contour; vtkTubeFilter* m_ContourSource; vtkAssembly* m_PropAssembly; // this contains everything, this will be returned by GetVtkProp() }; } // namespace mitk #endif /* MITKEnhancedPointSetVtkMapper3D_H_HEADER_INCLUDED_C1907273 */ diff --git a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp index 5265b2e98b..2d66b1637b 100644 --- a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp @@ -1,704 +1,708 @@ /*=================================================================== 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. ===================================================================*/ #define GPU_INFO MITK_INFO("mapper.vr") #define GPU_WARN MITK_WARN("mapper.vr") #define GPU_ERROR MITK_ERROR("mapper.vr") #include "mitkGPUVolumeMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkLevelWindow.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunctionProperty.h" #include "mitkTransferFunctionInitializer.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) #include "vtkMitkGPUVolumeRayCastMapper.h" #endif #include "vtkOpenGLGPUVolumeRayCastMapper.h" #include "vtkMitkOpenGLVolumeTextureMapper3D.h" const mitk::Image* mitk::GPUVolumeMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } void mitk::GPUVolumeMapper3D::MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); - VtkMapper3D::MitkRenderVolumetricGeometry(renderer); + VtkMapper::MitkRenderVolumetricGeometry(renderer); if(ls->m_gpuInitialized) ls->m_MapperGPU->UpdateMTime(); } bool mitk::GPUVolumeMapper3D::InitGPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_gpuInitialized) return ls->m_gpuSupported; GPU_INFO << "initializing gpu-slicing-vr (vtkMitkOpenGLVolumeTextureMapper3D)"; ls->m_MapperGPU = vtkSmartPointer::New(); ls->m_MapperGPU->SetUseCompressedTexture(false); ls->m_MapperGPU->SetSampleDistance(1.0); ls->m_VolumePropertyGPU = vtkSmartPointer::New(); ls->m_VolumePropertyGPU->ShadeOn(); ls->m_VolumePropertyGPU->SetAmbient (0.25f); //0.05f ls->m_VolumePropertyGPU->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyGPU->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyGPU->SetSpecularPower(16.0f); ls->m_VolumePropertyGPU->SetInterpolationTypeToLinear(); ls->m_VolumeGPU = vtkSmartPointer::New(); ls->m_VolumeGPU->SetMapper( ls->m_MapperGPU ); ls->m_VolumeGPU->SetProperty( ls->m_VolumePropertyGPU ); ls->m_VolumeGPU->VisibilityOn(); ls->m_MapperGPU->SetInput( this->m_UnitSpacingImageFilter->GetOutput() ); ls->m_gpuSupported = ls->m_MapperGPU->IsRenderSupported(renderer->GetVtkRenderer(),ls->m_VolumePropertyGPU); ls->m_gpuInitialized = true; return ls->m_gpuSupported; } void mitk::GPUVolumeMapper3D::InitCPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_cpuInitialized) return; int numThreads = itk::MultiThreader::GetGlobalDefaultNumberOfThreads(); GPU_INFO << "initializing cpu-raycast-vr (vtkFixedPointVolumeRayCastMapper) (" << numThreads << " threads)"; ls->m_MapperCPU = vtkSmartPointer::New(); ls->m_MapperCPU->SetSampleDistance(1.0); // ls->m_MapperCPU->LockSampleDistanceToInputSpacingOn(); ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->IntermixIntersectingGeometryOn(); ls->m_MapperCPU->SetAutoAdjustSampleDistances(0); ls->m_MapperCPU->SetNumberOfThreads( numThreads ); ls->m_VolumePropertyCPU = vtkSmartPointer::New(); ls->m_VolumePropertyCPU->ShadeOn(); ls->m_VolumePropertyCPU->SetAmbient (0.10f); //0.05f ls->m_VolumePropertyCPU->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyCPU->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyCPU->SetSpecularPower(16.0f); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); ls->m_VolumeCPU = vtkSmartPointer::New(); ls->m_VolumeCPU->SetMapper( ls->m_MapperCPU ); ls->m_VolumeCPU->SetProperty( ls->m_VolumePropertyCPU ); ls->m_VolumeCPU->VisibilityOn(); ls->m_MapperCPU->SetInput( m_UnitSpacingImageFilter->GetOutput() );//m_Resampler->GetOutput()); ls->m_cpuInitialized=true; } void mitk::GPUVolumeMapper3D::DeinitGPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_gpuInitialized) { GPU_INFO << "deinitializing gpu-slicing-vr"; ls->m_VolumePropertyGPU = NULL; ls->m_MapperGPU = NULL; ls->m_VolumeGPU = NULL; ls->m_gpuInitialized=false; } } void mitk::GPUVolumeMapper3D::DeinitCPU(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(!ls->m_cpuInitialized) return; GPU_INFO << "deinitializing cpu-raycast-vr"; ls->m_VolumePropertyCPU = NULL; ls->m_MapperCPU = NULL; ls->m_VolumeCPU = NULL; ls->m_cpuInitialized=false; } mitk::GPUVolumeMapper3D::GPUVolumeMapper3D() { m_VolumeNULL=0; m_commonInitialized=false; } mitk::GPUVolumeMapper3D::~GPUVolumeMapper3D() { DeinitCommon(); } void mitk::GPUVolumeMapper3D::InitCommon() { if(m_commonInitialized) return; m_UnitSpacingImageFilter = vtkSmartPointer::New(); m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 ); CreateDefaultTransferFunctions(); m_commonInitialized=true; } void mitk::GPUVolumeMapper3D::DeinitCommon() { if(!m_commonInitialized) return; m_commonInitialized=false; } bool mitk::GPUVolumeMapper3D::IsRenderable(mitk::BaseRenderer* renderer) { - if(!IsVisible(renderer)) - return false; if(!GetDataNode()) return false; - bool value = false; + DataNode* node = GetDataNode(); + + bool visible = true; + node->GetVisibility(visible, renderer, "visible"); - if(!GetDataNode()->GetBoolProperty("volumerendering",value,renderer)) + if(!visible) return false; + + bool value = false; + if(!node->GetBoolProperty("volumerendering",value,renderer)); return false; if(!value) return false; mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); if ( !input || !input->IsInitialized() ) return false; vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() ); if(inputData==NULL) return false; return true; } void mitk::GPUVolumeMapper3D::InitVtkMapper(mitk::BaseRenderer* renderer) { // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(IsRAYEnabled(renderer)) { DeinitCPU(renderer); DeinitGPU(renderer); if(!InitRAY(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } else #endif if(IsGPUEnabled(renderer)) { DeinitCPU(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) DeinitRAY(renderer); #endif if(!InitGPU(renderer)) { GPU_WARN << "hardware renderer can't initialize ... falling back to software renderer"; goto fallback; } } else { fallback: DeinitGPU(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) DeinitRAY(renderer); #endif InitCPU(renderer); } } vtkProp *mitk::GPUVolumeMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { if(!IsRenderable(renderer)) { if(!m_VolumeNULL) { m_VolumeNULL = vtkSmartPointer::New(); m_VolumeNULL->VisibilityOff(); } return m_VolumeNULL; } InitCommon(); InitVtkMapper( renderer ); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) return ls->m_VolumeRAY; #endif if(ls->m_gpuInitialized) return ls->m_VolumeGPU; return ls->m_VolumeCPU; } void mitk::GPUVolumeMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { if(!IsRenderable(renderer)) return; InitCommon(); InitVtkMapper( renderer ); mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() ); vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() ); m_UnitSpacingImageFilter->SetInput( inputData ); LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) { GenerateDataRAY(renderer); } else #endif if(ls->m_gpuInitialized) { GenerateDataGPU(renderer); } else { GenerateDataCPU(renderer); } // UpdateTransferFunctions UpdateTransferFunctions( renderer ); } void mitk::GPUVolumeMapper3D::GenerateDataGPU( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool useCompression = false; GetDataNode()->GetBoolProperty("volumerendering.gpu.usetexturecompression",useCompression,renderer); ls->m_MapperGPU->SetUseCompressedTexture(useCompression); if( IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) ls->m_MapperGPU->SetSampleDistance(2.0); else ls->m_MapperGPU->SetSampleDistance(1.0); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.gpu.ambient",value,renderer)) ls->m_VolumePropertyGPU->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.diffuse",value,renderer)) ls->m_VolumePropertyGPU->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.specular",value,renderer)) ls->m_VolumePropertyGPU->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.gpu.specular.power",value,renderer)) ls->m_VolumePropertyGPU->SetSpecularPower(value); } } void mitk::GPUVolumeMapper3D::GenerateDataCPU( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); int nextLod = mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ); if( IsLODEnabled(renderer) && nextLod == 0 ) { ls->m_MapperCPU->SetImageSampleDistance(3.5); ls->m_MapperCPU->SetSampleDistance(1.25); ls->m_VolumePropertyCPU->SetInterpolationTypeToNearest(); } else { ls->m_MapperCPU->SetImageSampleDistance(1.0); ls->m_MapperCPU->SetSampleDistance(1.0); ls->m_VolumePropertyCPU->SetInterpolationTypeToLinear(); } // Check raycasting mode if(IsMIPEnabled(renderer)) ls->m_MapperCPU->SetBlendModeToMaximumIntensity(); else ls->m_MapperCPU->SetBlendModeToComposite(); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.cpu.ambient",value,renderer)) ls->m_VolumePropertyCPU->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.diffuse",value,renderer)) ls->m_VolumePropertyCPU->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.specular",value,renderer)) ls->m_VolumePropertyCPU->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.cpu.specular.power",value,renderer)) ls->m_VolumePropertyCPU->SetSpecularPower(value); } } void mitk::GPUVolumeMapper3D::CreateDefaultTransferFunctions() { m_DefaultOpacityTransferFunction = vtkSmartPointer::New(); m_DefaultOpacityTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultOpacityTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultOpacityTransferFunction->ClampingOn(); m_DefaultGradientTransferFunction = vtkSmartPointer::New(); m_DefaultGradientTransferFunction->AddPoint( 0.0, 0.0 ); m_DefaultGradientTransferFunction->AddPoint( 255.0, 0.8 ); m_DefaultGradientTransferFunction->ClampingOn(); m_DefaultColorTransferFunction = vtkSmartPointer::New(); m_DefaultColorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 127.5, 1, 1, 0.0 ); m_DefaultColorTransferFunction->AddRGBPoint( 255.0, 0.8, 0.2, 0 ); m_DefaultColorTransferFunction->ClampingOn(); m_BinaryOpacityTransferFunction = vtkSmartPointer::New(); m_BinaryOpacityTransferFunction->AddPoint( 0, 0.0 ); m_BinaryOpacityTransferFunction->AddPoint( 1, 1.0 ); m_BinaryGradientTransferFunction = vtkSmartPointer::New(); m_BinaryGradientTransferFunction->AddPoint( 0.0, 1.0 ); m_BinaryColorTransferFunction = vtkSmartPointer::New(); } void mitk::GPUVolumeMapper3D::UpdateTransferFunctions( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); vtkPiecewiseFunction *opacityTransferFunction = m_DefaultOpacityTransferFunction; vtkPiecewiseFunction *gradientTransferFunction = m_DefaultGradientTransferFunction; vtkColorTransferFunction *colorTransferFunction = m_DefaultColorTransferFunction; bool isBinary = false; GetDataNode()->GetBoolProperty("binary", isBinary, renderer); if(isBinary) { opacityTransferFunction = m_BinaryOpacityTransferFunction; gradientTransferFunction = m_BinaryGradientTransferFunction; colorTransferFunction = m_BinaryColorTransferFunction; colorTransferFunction->RemoveAllPoints(); float rgb[3]; if( !GetDataNode()->GetColor( rgb,renderer ) ) rgb[0]=rgb[1]=rgb[2]=1; colorTransferFunction->AddRGBPoint( 0,rgb[0],rgb[1],rgb[2] ); colorTransferFunction->Modified(); } else { mitk::TransferFunctionProperty *transferFunctionProp = dynamic_cast(this->GetDataNode()->GetProperty("TransferFunction",renderer)); if( transferFunctionProp ) { opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction(); gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction(); colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction(); } } if(ls->m_gpuInitialized) { ls->m_VolumePropertyGPU->SetColor( colorTransferFunction ); ls->m_VolumePropertyGPU->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyGPU->SetGradientOpacity( gradientTransferFunction ); } // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(ls->m_rayInitialized) { ls->m_VolumePropertyRAY->SetColor( colorTransferFunction ); ls->m_VolumePropertyRAY->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyRAY->SetGradientOpacity( gradientTransferFunction ); } #endif if(ls->m_cpuInitialized) { ls->m_VolumePropertyCPU->SetColor( colorTransferFunction ); ls->m_VolumePropertyCPU->SetScalarOpacity( opacityTransferFunction ); ls->m_VolumePropertyCPU->SetGradientOpacity( gradientTransferFunction ); } } void mitk::GPUVolumeMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* /*renderer*/) { //GPU_INFO << "ApplyProperties"; } void mitk::GPUVolumeMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { //GPU_INFO << "SetDefaultProperties"; node->AddProperty( "volumerendering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.usemip", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.uselod", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.ambient", mitk::FloatProperty::New( 0.10f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.cpu.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); bool usegpu = true; #ifdef __APPLE__ usegpu = false; node->AddProperty( "volumerendering.uselod", mitk::BoolProperty::New( true ), renderer, overwrite ); #endif node->AddProperty( "volumerendering.usegpu", mitk::BoolProperty::New( usegpu ), renderer, overwrite ); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) node->AddProperty( "volumerendering.useray", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.ambient", mitk::FloatProperty::New( 0.25f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.ray.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); #endif node->AddProperty( "volumerendering.gpu.ambient", mitk::FloatProperty::New( 0.25f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.diffuse", mitk::FloatProperty::New( 0.50f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.specular", mitk::FloatProperty::New( 0.40f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.specular.power", mitk::FloatProperty::New( 16.0f ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.usetexturecompression", mitk::BoolProperty ::New( false ), renderer, overwrite ); node->AddProperty( "volumerendering.gpu.reducesliceartifacts" , mitk::BoolProperty ::New( false ), renderer, overwrite ); node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite ); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL)) { mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetAuto( image ); levWinProp->SetLevelWindow( levelwindow ); node->SetProperty( "levelwindow", levWinProp, renderer ); } if((overwrite) || (node->GetProperty("TransferFunction", renderer)==NULL)) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf); tfInit->SetTransferFunctionMode(0); node->SetProperty ( "TransferFunction", mitk::TransferFunctionProperty::New ( tf.GetPointer() ) ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } bool mitk::GPUVolumeMapper3D::IsLODEnabled( mitk::BaseRenderer * renderer ) const { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.uselod",value,renderer) && value; } bool mitk::GPUVolumeMapper3D::IsMIPEnabled( mitk::BaseRenderer * renderer ) { bool value = false; return GetDataNode()->GetBoolProperty("volumerendering.usemip",value,renderer) && value; } bool mitk::GPUVolumeMapper3D::IsGPUEnabled( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_gpuSupported && GetDataNode()->GetBoolProperty("volumerendering.usegpu",value,renderer) && value; } // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool mitk::GPUVolumeMapper3D::InitRAY(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_rayInitialized) return ls->m_raySupported; GPU_INFO << "initializing gpu-raycast-vr (vtkOpenGLGPUVolumeRayCastMapper)"; ls->m_MapperRAY = vtkSmartPointer::New(); ls->m_MapperRAY->SetAutoAdjustSampleDistances(0); ls->m_MapperRAY->SetSampleDistance(1.0); ls->m_VolumePropertyRAY = vtkSmartPointer::New(); ls->m_VolumePropertyRAY->ShadeOn(); ls->m_VolumePropertyRAY->SetAmbient (0.25f); //0.05f ls->m_VolumePropertyRAY->SetDiffuse (0.50f); //0.45f ls->m_VolumePropertyRAY->SetSpecular(0.40f); //0.50f ls->m_VolumePropertyRAY->SetSpecularPower(16.0f); ls->m_VolumePropertyRAY->SetInterpolationTypeToLinear(); ls->m_VolumeRAY = vtkSmartPointer::New(); ls->m_VolumeRAY->SetMapper( ls->m_MapperRAY ); ls->m_VolumeRAY->SetProperty( ls->m_VolumePropertyRAY ); ls->m_VolumeRAY->VisibilityOn(); ls->m_MapperRAY->SetInput( this->m_UnitSpacingImageFilter->GetOutput() ); ls->m_raySupported = ls->m_MapperRAY->IsRenderSupported(renderer->GetRenderWindow(),ls->m_VolumePropertyRAY); ls->m_rayInitialized = true; return ls->m_raySupported; } void mitk::GPUVolumeMapper3D::DeinitRAY(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_rayInitialized) { GPU_INFO << "deinitializing gpu-raycast-vr"; ls->m_MapperRAY = NULL; ls->m_VolumePropertyRAY = NULL; //Here ReleaseGraphicsResources has to be called to avoid VTK error messages. //This seems like a VTK bug, because ReleaseGraphicsResources() is ment for internal use, //but you cannot just delete the object (last smartpointer reference) without getting the //VTK error. ls->m_VolumeRAY->ReleaseGraphicsResources(renderer->GetVtkRenderer()->GetRenderWindow()); ls->m_VolumeRAY = NULL; ls->m_rayInitialized=false; } } void mitk::GPUVolumeMapper3D::GenerateDataRAY( mitk::BaseRenderer *renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if( IsLODEnabled(renderer) && mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) == 0 ) ls->m_MapperRAY->SetImageSampleDistance(4.0); else ls->m_MapperRAY->SetImageSampleDistance(1.0); // Check raycasting mode if(IsMIPEnabled(renderer)) ls->m_MapperRAY->SetBlendModeToMaximumIntensity(); else ls->m_MapperRAY->SetBlendModeToComposite(); // Updating shadings { float value=0; if(GetDataNode()->GetFloatProperty("volumerendering.ray.ambient",value,renderer)) ls->m_VolumePropertyRAY->SetAmbient(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.diffuse",value,renderer)) ls->m_VolumePropertyRAY->SetDiffuse(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.specular",value,renderer)) ls->m_VolumePropertyRAY->SetSpecular(value); if(GetDataNode()->GetFloatProperty("volumerendering.ray.specular.power",value,renderer)) ls->m_VolumePropertyRAY->SetSpecularPower(value); } } bool mitk::GPUVolumeMapper3D::IsRAYEnabled( mitk::BaseRenderer * renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool value = false; return ls->m_raySupported && GetDataNode()->GetBoolProperty("volumerendering.useray",value,renderer) && value; } #endif diff --git a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h index 49ff32f358..7622549925 100644 --- a/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h @@ -1,197 +1,197 @@ /*=================================================================== 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 MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED #define MITKGPUVOLUMEMAPPER3D_H_HEADER_INCLUDED //MITK #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkBaseRenderer.h" #include "mitkImage.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "vtkMitkVolumeTextureMapper3D.h" //VTK #include #include #include #include #include // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) #include "vtkMitkGPUVolumeRayCastMapper.h" #endif namespace mitk { /************************************************************************/ /* Properties that influence the mapper are: * * - \b "level window": for the level window of the volume data * - \b "LookupTable" : for the lookup table of the volume data * - \b "TransferFunction" (mitk::TransferFunctionProperty): for the used transfer function of the volume data ************************************************************************/ //##Documentation //## @brief Vtk-based mapper for VolumeData //## //## @ingroup Mapper -class MitkExt_EXPORT GPUVolumeMapper3D : public VtkMapper3D +class MitkExt_EXPORT GPUVolumeMapper3D : public VtkMapper { public: - mitkClassMacro(GPUVolumeMapper3D, VtkMapper3D); + mitkClassMacro(GPUVolumeMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::Image* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer *renderer = NULL ) const; bool IsMIPEnabled( BaseRenderer *renderer = NULL ); bool IsGPUEnabled( BaseRenderer *renderer = NULL ); bool IsRAYEnabled( BaseRenderer *renderer = NULL ); virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer); protected: GPUVolumeMapper3D(); virtual ~GPUVolumeMapper3D(); bool IsRenderable(mitk::BaseRenderer* renderer); void InitCommon(); void DeinitCommon(); void InitCPU(mitk::BaseRenderer* renderer); void DeinitCPU(mitk::BaseRenderer* renderer); void GenerateDataCPU(mitk::BaseRenderer* renderer); bool InitGPU(mitk::BaseRenderer* renderer); void DeinitGPU(mitk::BaseRenderer* renderer); void GenerateDataGPU(mitk::BaseRenderer* renderer); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool InitRAY(mitk::BaseRenderer* renderer); void DeinitRAY(mitk::BaseRenderer* renderer); void GenerateDataRAY(mitk::BaseRenderer* renderer); #endif void InitVtkMapper(mitk::BaseRenderer* renderer); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); void CreateDefaultTransferFunctions(); void UpdateTransferFunctions( mitk::BaseRenderer *renderer ); vtkSmartPointer m_VolumeNULL; bool m_commonInitialized; vtkSmartPointer m_UnitSpacingImageFilter; vtkSmartPointer m_DefaultOpacityTransferFunction; vtkSmartPointer m_DefaultGradientTransferFunction; vtkSmartPointer m_DefaultColorTransferFunction; vtkSmartPointer m_BinaryOpacityTransferFunction; vtkSmartPointer m_BinaryGradientTransferFunction; vtkSmartPointer m_BinaryColorTransferFunction; class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: bool m_cpuInitialized; vtkSmartPointer m_VolumeCPU; vtkSmartPointer m_MapperCPU; vtkSmartPointer m_VolumePropertyCPU; bool m_gpuSupported; bool m_gpuInitialized; vtkSmartPointer m_VolumeGPU; vtkSmartPointer m_MapperGPU; vtkSmartPointer m_VolumePropertyGPU; // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool m_raySupported; bool m_rayInitialized; vtkSmartPointer m_VolumeRAY; vtkSmartPointer m_MapperRAY; vtkSmartPointer m_VolumePropertyRAY; #endif LocalStorage() { m_cpuInitialized = false; m_gpuInitialized = false; m_gpuSupported = true; // assume initially gpu slicing is supported // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_rayInitialized = false; m_raySupported = true; // assume initially gpu raycasting is supported #endif } ~LocalStorage() { if(m_cpuInitialized) { m_cpuInitialized=false; } if(m_gpuInitialized) { m_gpuInitialized=false; } // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) if(m_rayInitialized) { m_rayInitialized=false; } #endif } }; mitk::Mapper::LocalStorageHandler m_LSH; }; } // namespace mitk #endif /* MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Rendering/mitkLineMapper2D.cpp b/Modules/MitkExt/Rendering/mitkLineMapper2D.cpp index 432b016abc..19560e23ca 100644 --- a/Modules/MitkExt/Rendering/mitkLineMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkLineMapper2D.cpp @@ -1,138 +1,140 @@ /*=================================================================== 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 "mitkLineMapper2D.h" #include "mitkPointSet.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include #include "mitkPointSet.h" #include "mitkGL.h" mitk::LineMapper2D::LineMapper2D() : mitk::PointSetGLMapper2D() { } mitk::LineMapper2D::~LineMapper2D() { } const mitk::PointSet *mitk::LineMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } void mitk::LineMapper2D::Paint(mitk::BaseRenderer * renderer) { - if(IsVisible(renderer)==false) - return; + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if(!visible) return; bool updateNeccesary = true;//!!!! @TODO !??!! if (updateNeccesary) { mitk::PointSet::Pointer input = const_cast(this->GetInput()); mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + ApplyColorAndOpacityProperties(renderer); vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); //List of the Points PointSet::DataType::PointsContainerConstIterator it, end; it = input->GetPointSet()->GetPoints()->Begin(); end = input->GetPointSet()->GetPoints()->End();//the last before end, because lines from n to n+1 if (end!=it) // otherwise PointSet is empty end--; //bool list for the selection of the points PointSet::DataType::PointDataContainerIterator selIt, selItNext; selIt=input->GetPointSet()->GetPointData()->Begin(); int j=0; while(it!=end) { mitk::Point3D p, q, projected_p, projected_q; float vtkp[3]; itk2vtk(it->Value(), vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); //next point n+1 it++; itk2vtk(it->Value(), vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,q); it--; displayGeometry->Project(p, projected_p); displayGeometry->Project(q, projected_q); Vector3D diffp=p-projected_p, diffq=q-projected_q; if((diffp.GetSquaredNorm()<4.0) && (diffq.GetSquaredNorm()<4.0)) { Point2D p2d, q2d, tmp; displayGeometry->Map(projected_p, p2d); displayGeometry->WorldToDisplay(p2d, p2d); displayGeometry->Map(projected_q, q2d); displayGeometry->WorldToDisplay(q2d, q2d); //outlined, cause iterators behave strange and multiple points can't be selected anyway by now! //selItNext = selIt++;//Iterator to the next Element, cause only when the two points ar selected, then the Line is Selected //if (selIt->Value() && selItNext->Value())//selected //{ // float colorSel[]={1.0,0.0,0.6}; //for selected! // //current color for changing to a diferent color if selected // float currCol[4]; // glGetFloatv(GL_CURRENT_COLOR,currCol); // glColor3f(colorSel[0],colorSel[1],colorSel[2]);//red // glBegin (GL_LINES); // glVertex2f(p2d[0], p2d[1]); // glVertex2f(q2d[0], q2d[1]); // glEnd (); // glColor3f(currCol[0],currCol[1],currCol[2]);//the color before changing to select! //} //else //{ glBegin (GL_LINES); glVertex2f(p2d[0], p2d[1]); glVertex2f(q2d[0], q2d[1]); glEnd (); //} } ++it; ++selIt; j++; } //drawing the points PointSetGLMapper2D::Paint(renderer); } } diff --git a/Modules/MitkExt/Rendering/mitkMeshMapper2D.cpp b/Modules/MitkExt/Rendering/mitkMeshMapper2D.cpp index 17c010635e..4b29bdf907 100644 --- a/Modules/MitkExt/Rendering/mitkMeshMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkMeshMapper2D.cpp @@ -1,476 +1,481 @@ /*=================================================================== 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 "mitkMeshMapper2D.h" #include "mitkMesh.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkLine.h" #include "mitkGL.h" #include #include const float selectedColor[]={1.0,0.0,0.6}; //for selected! mitk::MeshMapper2D::MeshMapper2D() { } mitk::MeshMapper2D::~MeshMapper2D() { } const mitk::Mesh *mitk::MeshMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } // Return whether a point is "smaller" than the second static bool point3DSmaller( const mitk::Point3D& elem1, const mitk::Point3D& elem2 ) { if(elem1[0]!=elem2[0]) return elem1[0] < elem2[0]; if(elem1[1]!=elem2[1]) return elem1[1] < elem2[1]; return elem1[2] < elem2[2]; } void mitk::MeshMapper2D::Paint( mitk::BaseRenderer *renderer ) { - if ( !this->IsVisible(renderer) ) return; + + bool visible = true; + + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) return; // @FIXME: Logik fuer update bool updateNeccesary = true; if (updateNeccesary) { //aus GenerateData mitk::Mesh::Pointer input = const_cast(this->GetInput()); // Get the TimeSlicedGeometry of the input object const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry(); if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) { return; } // // get the world time // const Geometry2D* worldGeometry = renderer->GetCurrentWorldGeometry2D(); assert( worldGeometry != NULL ); ScalarType time = worldGeometry->GetTimeBounds()[ 0 ]; // // convert the world time in time steps of the input object // int timeStep=0; if ( time > ScalarTypeNumericTraits::NonpositiveMin() ) timeStep = inputTimeGeometry->MSToTimeStep( time ); if ( inputTimeGeometry->IsValidTime( timeStep ) == false ) { return; } mitk::Mesh::MeshType::Pointer itkMesh = input->GetMesh( timeStep ); if ( itkMesh.GetPointer() == NULL) { return; } mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); const PlaneGeometry* worldplanegeometry = dynamic_cast(renderer->GetCurrentWorldGeometry2D()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + ApplyColorAndOpacityProperties(renderer); vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); //List of the Points Mesh::DataType::PointsContainerConstIterator it, end; it=itkMesh->GetPoints()->Begin(); end=itkMesh ->GetPoints()->End(); //iterator on the additional data of each point Mesh::PointDataIterator dataIt;//, dataEnd; dataIt=itkMesh->GetPointData()->Begin(); //for switching back to old color after using selected color float unselectedColor[4]; glGetFloatv(GL_CURRENT_COLOR,unselectedColor); while(it!=end) { mitk::Point3D p, projected_p; float vtkp[3]; itk2vtk(it->Value(), vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; if(diff.GetSquaredNorm()<4.0) { Point2D pt2d, tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector2D horz,vert; horz[0]=5; horz[1]=0; vert[0]=0; vert[1]=5; //check if the point is to be marked as selected if (dataIt->Value().selected) { horz[0]=8; vert[1]=8; glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]);//red switch (dataIt->Value().pointSpec) { case PTSTART: { //a quad glBegin (GL_LINE_LOOP); tmp=pt2d-horz+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz-vert; glVertex2fv(&tmp[0]); tmp=pt2d-horz-vert; glVertex2fv(&tmp[0]); glEnd (); } break; case PTUNDEFINED: { //a diamond around the point glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); glEnd (); } break; default: break; }//switch //the actual point glBegin (GL_POINTS); tmp=pt2d; glVertex2fv(&tmp[0]); glEnd (); } else //if not selected { glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); switch (dataIt->Value().pointSpec) { case PTSTART: { //a quad glBegin (GL_LINE_LOOP); tmp=pt2d-horz+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz+vert; glVertex2fv(&tmp[0]); tmp=pt2d+horz-vert; glVertex2fv(&tmp[0]); tmp=pt2d-horz-vert; glVertex2fv(&tmp[0]); glEnd (); } case PTUNDEFINED: { //drawing crosses glBegin (GL_LINES); tmp=pt2d-horz; glVertex2fv(&tmp[0]); tmp=pt2d+horz; glVertex2fv(&tmp[0]); tmp=pt2d-vert; glVertex2fv(&tmp[0]); tmp=pt2d+vert; glVertex2fv(&tmp[0]); glEnd (); } default: { break; } }//switch }//else } ++it; ++dataIt; } //now connect the lines inbetween mitk::Mesh::PointType thisPoint; thisPoint.Fill(0); Point2D *firstOfCell = NULL; Point2D *lastPoint = NULL; unsigned int lastPointId = 0; bool lineSelected = false; Point3D firstOfCell3D; Point3D lastPoint3D; bool first; mitk::Line line; std::vector intersectionPoints; double t; //iterate through all cells and then iterate through all indexes of points in that cell Mesh::CellIterator cellIt, cellEnd; Mesh::CellDataIterator cellDataIt;//, cellDataEnd; Mesh::PointIdIterator cellIdIt, cellIdEnd; cellIt = itkMesh->GetCells()->Begin(); cellEnd = itkMesh->GetCells()->End(); cellDataIt = itkMesh->GetCellData()->Begin(); while (cellIt != cellEnd) { unsigned int numOfPointsInCell = cellIt->Value()->GetNumberOfPoints(); if (numOfPointsInCell>1) { //iterate through all id's in the cell cellIdIt = cellIt->Value()->PointIdsBegin(); cellIdEnd = cellIt->Value()->PointIdsEnd(); firstOfCell3D = input->GetPoint(*cellIdIt); intersectionPoints.clear(); intersectionPoints.reserve(numOfPointsInCell); first = true; while(cellIdIt != cellIdEnd) { lastPoint3D = thisPoint; thisPoint = input->GetPoint(*cellIdIt); //search in data (vector<> selectedLines) if the index of the point is set. if so, then the line is selected. lineSelected = false; Mesh::SelectedLinesType selectedLines = cellDataIt->Value().selectedLines; //a line between 1(lastPoint) and 2(pt2d) has the Id 1, so look for the Id of lastPoint //since we only start, if we have more than one point in the cell, lastPointId is initiated with 0 Mesh::SelectedLinesIter position = std::find(selectedLines.begin(), selectedLines.end(), lastPointId); if (position != selectedLines.end()) { lineSelected = true; } mitk::Point3D p, projected_p; float vtkp[3]; itk2vtk(thisPoint, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; if(diff.GetSquaredNorm()<4.0) { Point2D pt2d, tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); if (lastPoint == NULL) { //set the first point in the cell. This point in needed to close the polygon firstOfCell = new Point2D; *firstOfCell = pt2d; lastPoint = new Point2D; *lastPoint = pt2d; lastPointId = *cellIdIt; } else { if (lineSelected) { glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]);//red //a line from lastPoint to thisPoint glBegin (GL_LINES); glVertex2fv(&(*lastPoint)[0]); glVertex2fv(&pt2d[0]); glEnd (); } else //if not selected { glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); //drawing crosses glBegin (GL_LINES); glVertex2fv(&(*lastPoint)[0]); glVertex2fv(&pt2d[0]); glEnd (); } //to draw the line to the next in iteration step *lastPoint = pt2d; //and to search for the selection state of the line lastPointId = *cellIdIt; }//if..else }//if <4.0 //fill off-plane polygon part 1 if((!first) && (worldplanegeometry!=NULL)) { line.SetPoints(lastPoint3D, thisPoint); if(worldplanegeometry->IntersectionPointParam(line, t) && ((t>=0) && (t<=1)) ) { intersectionPoints.push_back(line.GetPoint(t)); } } ++cellIdIt; first=false; }//while cellIdIter //closed polygon? if ( cellDataIt->Value().closed ) { //close the polygon if needed if( firstOfCell != NULL ) { lineSelected = false; Mesh::SelectedLinesType selectedLines = cellDataIt->Value().selectedLines; Mesh::SelectedLinesIter position = std::find(selectedLines.begin(), selectedLines.end(), lastPointId); if (position != selectedLines.end())//found the index { glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]);//red //a line from lastPoint to firstPoint glBegin (GL_LINES); glVertex2fv(&(*lastPoint)[0]); glVertex2fv(&(*firstOfCell)[0]); glEnd (); } else { glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]); glBegin (GL_LINES); glVertex2fv(&(*lastPoint)[0]); glVertex2fv(&(*firstOfCell)[0]); glEnd (); } } }//if closed //Axis-aligned bounding box(AABB) around the cell if selected and set in Property bool showBoundingBox; if (dynamic_cast(this->GetDataNode()->GetProperty("showBoundingBox")) == NULL) showBoundingBox = false; else showBoundingBox = dynamic_cast(this->GetDataNode()->GetProperty("showBoundingBox"))->GetValue(); if(showBoundingBox) { if (cellDataIt->Value().selected) { mitk::Mesh::DataType::BoundingBoxPointer aABB = input->GetBoundingBoxFromCell(cellIt->Index()); if (aABB.IsNotNull()) { mitk::Mesh::PointType min, max; min = aABB->GetMinimum(); max = aABB->GetMaximum(); //project to the displayed geometry Point2D min2D, max2D; Point3D p, projected_p; float vtkp[3]; itk2vtk(min, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, min2D); displayGeometry->WorldToDisplay(min2D, min2D); itk2vtk(max, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; if(diff.GetSquaredNorm()<4.0) { displayGeometry->Map(projected_p, max2D); displayGeometry->WorldToDisplay(max2D, max2D); //draw the BoundingBox glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]);//red //a line from lastPoint to firstPoint glBegin(GL_LINE_LOOP); glVertex2f(min2D[0], min2D[1]); glVertex2f(min2D[0], max2D[1]); glVertex2f(max2D[0], max2D[1]); glVertex2f(max2D[0], min2D[1]); glEnd(); }//draw bounding-box }//bounding-box exists }//cell selected }//show bounding-box //fill off-plane polygon part 2 if(worldplanegeometry!=NULL) { //consider line from last to first line.SetPoints(thisPoint, firstOfCell3D); if(worldplanegeometry->IntersectionPointParam(line, t) && ((t>=0) && (t<=1)) ) { intersectionPoints.push_back(line.GetPoint(t)); } std::sort(intersectionPoints.begin(), intersectionPoints.end(), point3DSmaller); std::vector::iterator it, end; end=intersectionPoints.end(); if((intersectionPoints.size()%2)!=0) { --end; //ensure even number of intersection-points } float p[2]; Point3D pt3d; Point2D pt2d; for ( it = intersectionPoints.begin( ); it != end; ++it ) { glBegin (GL_LINES); displayGeometry->Map(*it, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); p[0] = pt2d[0]; p[1] = pt2d[1]; glVertex2fv(p); ++it; displayGeometry->Map(*it, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); p[0] = pt2d[0]; p[1] = pt2d[1]; glVertex2fv(p); glEnd (); } if(it!=intersectionPoints.end()) { glBegin (GL_LINES); displayGeometry->Map(*it, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); p[0] = pt2d[0]; p[1] = pt2d[1]; glVertex2fv(p); p[0] = pt2d[0]; p[1] = pt2d[1]; glVertex2fv(p); glEnd (); } }//fill off-plane polygon part 2 }//if numOfPointsInCell>1 delete firstOfCell; delete lastPoint; lastPoint = NULL; firstOfCell = NULL; lastPointId = 0; ++cellIt; ++cellDataIt; } } } diff --git a/Modules/MitkExt/Rendering/mitkMeshMapper2D.h b/Modules/MitkExt/Rendering/mitkMeshMapper2D.h index 202c6bbbfe..df6ad8b4e6 100644 --- a/Modules/MitkExt/Rendering/mitkMeshMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkMeshMapper2D.h @@ -1,58 +1,58 @@ /*=================================================================== 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 MITKMESHMAPPER2D_H_HEADER_INCLUDED #define MITKMESHMAPPER2D_H_HEADER_INCLUDED #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class Mesh; /** * \brief OpenGL-based mapper to display a mesh in a 2D window * * \todo implement for AbstractTransformGeometry. * \ingroup Mapper */ -class MitkExt_EXPORT MeshMapper2D : public GLMapper2D +class MitkExt_EXPORT MeshMapper2D : public GLMapper { public: - mitkClassMacro(MeshMapper2D, Mapper2D); + mitkClassMacro(MeshMapper2D, GLMapper); itkNewMacro(Self); /** @brief Get the Mesh to map */ const mitk::Mesh *GetInput(void); virtual void Paint( mitk::BaseRenderer *renderer ); protected: MeshMapper2D(); virtual ~MeshMapper2D(); }; } // namespace mitk #endif /* MITKMESHMapper2D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.cpp index f8b09edf76..b1cfd0a309 100644 --- a/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.cpp @@ -1,227 +1,228 @@ /*=================================================================== 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 "mitkMeshVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkVtkPropRenderer.h" #ifndef VCL_VC60 #include "mitkMeshUtil.h" #endif #include #include #include #include #include #include #include #include #include const mitk::Mesh* mitk::MeshVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } vtkProp* mitk::MeshVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_PropAssembly; } void mitk::MeshVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); m_SpheresActor->SetUserTransform(vtktransform); m_ContourActor->SetUserTransform(vtktransform); } mitk::MeshVtkMapper3D::MeshVtkMapper3D() : m_PropAssembly(NULL) { m_Spheres = vtkAppendPolyData::New(); m_Contour = vtkPolyData::New(); m_SpheresActor = vtkActor::New(); m_SpheresMapper = vtkPolyDataMapper::New(); m_SpheresActor->SetMapper(m_SpheresMapper); m_ContourActor = vtkActor::New(); m_ContourMapper = vtkPolyDataMapper::New(); m_ContourActor->SetMapper(m_ContourMapper); m_ContourActor->GetProperty()->SetAmbient(1.0); m_PropAssembly = vtkPropAssembly::New(); // a vtkPropAssembly is not a sub-class of vtkProp3D, so // we cannot use m_Prop3D. } mitk::MeshVtkMapper3D::~MeshVtkMapper3D() { m_ContourActor->Delete(); m_SpheresActor->Delete(); m_ContourMapper->Delete(); m_SpheresMapper->Delete(); m_PropAssembly->Delete(); m_Spheres->Delete(); m_Contour->Delete(); } -void mitk::MeshVtkMapper3D::GenerateData() + +void mitk::MeshVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) { + m_PropAssembly->VisibilityOn(); if(m_PropAssembly->GetParts()->IsItemPresent(m_SpheresActor)) m_PropAssembly->RemovePart(m_SpheresActor); if(m_PropAssembly->GetParts()->IsItemPresent(m_ContourActor)) m_PropAssembly->RemovePart(m_ContourActor); m_Spheres->RemoveAllInputs(); m_Contour->Initialize(); mitk::Mesh::Pointer input = const_cast(this->GetInput()); input->Update(); mitk::Mesh::DataType::Pointer itkMesh = input->GetMesh( this->GetTimestep() ); if ( itkMesh.GetPointer() == NULL) { m_PropAssembly->VisibilityOff(); return; } mitk::Mesh::PointsContainer::Iterator i; int j; float floatRgba[4] = {1.0f,1.0f,1.0f,1.0f}; vtkFloatingPointType doubleRgba[4]={1.0f,1.0f,1.0f,1.0f}; mitk::Color tmpColor; // check for color prop and use it for rendering if it exists m_DataNode->GetColor(floatRgba, NULL); if (dynamic_cast(this->GetDataNode()->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetProperty("unselectedcolor"))->GetValue(); floatRgba[0] = tmpColor[0]; floatRgba[1] = tmpColor[1]; floatRgba[2] = tmpColor[2]; floatRgba[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value doubleRgba[0] = floatRgba[0]; doubleRgba[1] = floatRgba[1]; doubleRgba[2] = floatRgba[2]; doubleRgba[3] = floatRgba[3]; } if(itkMesh->GetNumberOfPoints()>0) { // build m_Spheres->GetOutput() vtkPolyData float pointSize = 2.0; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if (pointSizeProp.IsNotNull()) pointSize = pointSizeProp->GetValue(); for (j=0, i=itkMesh->GetPoints()->Begin(); i!=itkMesh->GetPoints()->End() ; i++,j++) { vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(pointSize); sphere->SetCenter(i.Value()[0],i.Value()[1],i.Value()[2]); m_Spheres->AddInput(sphere->GetOutput()); sphere->Delete(); } // setup mapper, actor and add to assembly m_SpheresMapper->SetInput(m_Spheres->GetOutput()); m_SpheresActor->GetProperty()->SetColor(doubleRgba); m_PropAssembly->AddPart(m_SpheresActor); } if(itkMesh->GetNumberOfCells()>0) { // build m_Contour vtkPolyData #ifdef VCL_VC60 itkExceptionMacro(<<"MeshVtkMapper3D currently not working for MS Visual C++ 6.0, because MeshUtils are currently not supported."); #else m_Contour = MeshUtil::MeshToPolyData(itkMesh.GetPointer(), false, false, 0, NULL, m_Contour); #endif if(m_Contour->GetNumberOfCells()>0) { // setup mapper, actor and add to assembly m_ContourMapper->SetInput(m_Contour); bool wireframe=true; GetDataNode()->GetVisibility(wireframe, NULL, "wireframe"); if(wireframe) m_ContourActor->GetProperty()->SetRepresentationToWireframe(); else m_ContourActor->GetProperty()->SetRepresentationToSurface(); m_ContourActor->GetProperty()->SetColor(doubleRgba); m_PropAssembly->AddPart(m_ContourActor); } } -} - -void mitk::MeshVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) -{ SetVtkMapperImmediateModeRendering(m_ContourMapper); SetVtkMapperImmediateModeRendering(m_SpheresMapper); - if(IsVisible(renderer)==false) + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) { m_SpheresActor->VisibilityOff(); m_ContourActor->VisibilityOff(); return; } bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { m_ContourActor->VisibilityOn(); } else { m_ContourActor->VisibilityOff(); } bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); if(showPoints) { m_SpheresActor->VisibilityOn(); } else { m_SpheresActor->VisibilityOff(); } } void mitk::MeshVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_PropAssembly->VisibilityOff(); } diff --git a/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.h b/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.h index 59a0af9697..3d1d18bd77 100644 --- a/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkMeshVtkMapper3D.h @@ -1,92 +1,90 @@ /*=================================================================== 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 MITKMESHVTKMAPPER3D_H_HEADER_INCLUDED #define MITKMESHVTKMAPPER3D_H_HEADER_INCLUDED #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkMesh.h" #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include class vtkActor; class vtkAssembly; class vtkFollower; class vtkPolyDataMapper; class vtkPropAssembly; namespace mitk { /** * \brief Vtk-based mapper for PointList * \ingroup Mapper */ -class MitkExt_EXPORT MeshVtkMapper3D : public VtkMapper3D +class MitkExt_EXPORT MeshVtkMapper3D : public VtkMapper { public: - mitkClassMacro(MeshVtkMapper3D, VtkMapper3D); + mitkClassMacro(MeshVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::Mesh* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer *renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); protected: MeshVtkMapper3D(); virtual ~MeshVtkMapper3D(); - virtual void GenerateData(); - virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( BaseRenderer* renderer ); vtkPropAssembly* m_PropAssembly; vtkActor *m_SpheresActor; vtkActor *m_ContourActor; vtkPolyDataMapper* m_ContourMapper; vtkPolyDataMapper* m_SpheresMapper; vtkPolyDataMapper* m_TextVtkPolyDataMapper; vtkAppendPolyData *m_Spheres; vtkPolyData *m_Contour; }; } // namespace mitk #endif /* MITKMESHVTKMAPPER3D_H_HEADER_INCLUDED*/ diff --git a/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp b/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp index 81597d00f6..f81f3c4a35 100755 --- a/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkSplineMapper2D.cpp @@ -1,189 +1,193 @@ /*=================================================================== 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 "mitkSplineMapper2D.h" #include "mitkSplineVtkMapper3D.h" #include #include #include #include #include #include #include #include void mitk::SplineMapper2D::Paint ( mitk::BaseRenderer * renderer ) { Superclass::Paint ( renderer ); - if ( IsVisible ( renderer ) == false ) + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) return; // // get the poly data of the splines in 3D // mitk::SplineVtkMapper3D::Pointer mapper3D = dynamic_cast ( this->GetDataNode()->GetMapper ( 2 ) ); if ( mapper3D.IsNull() ) { itkWarningMacro ( "Mapper used for 3D mapping is not a mitk::SplineVtkMapper3D!" ); return; } // // update the 3D spline, if the accoring mapper has not been updated yet // if ( mapper3D->GetLastUpdateTime() < GetDataNode()->GetData()->GetMTime() ) mapper3D->UpdateSpline(); vtkPolyData* spline3D = NULL; if ( mapper3D->SplinesAreAvailable() ) spline3D = mapper3D->GetSplinesPolyData(); else return; if ( spline3D == NULL ) { itkWarningMacro ( "3D spline is not available!" ); return; } // // get the transform associated with the data tree node // vtkLinearTransform* transform = this->GetDataNode()->GetVtkTransform(); if ( transform == NULL ) { itkWarningMacro("transfrom is NULL"); } // // get the plane geometry of the current renderer // mitk::Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); if ( worldGeometry.IsNull() ) { itkWarningMacro("worldGeometry is NULL!"); return; } PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast ( worldGeometry.GetPointer() ); if ( worldPlaneGeometry.IsNull() ) { itkWarningMacro("worldPlaneGeometry is NULL!"); return; } // // determine color of the spline // float color[3]; this->GetDataNode()->GetColor ( color, renderer ); // // iterate over the points // vtkPoints *vpoints = spline3D->GetPoints(); vtkCellArray *vlines = spline3D->GetLines(); if (vpoints == NULL) { itkWarningMacro("points are NULL!"); return; } if (vlines == NULL) { itkWarningMacro("lines are NULL!"); return; } mitk::Point3D currentPoint3D; mitk::Point2D currentPoint2D; vtkFloatingPointType currentPoint3DVtk[3]; vlines->InitTraversal(); int numberOfLines = vlines->GetNumberOfCells(); vtkFloatingPointType currentPointDistance; for ( int i = 0;i < numberOfLines; ++i ) { bool previousPointOnPlane = false; bool currentPointOnPlane = false; vtkIdType* cell ( NULL ); vtkIdType cellSize ( 0 ); vlines->GetNextCell ( cellSize, cell ); for ( int j = 0 ; j < cellSize; ++j ) { vpoints->GetPoint ( cell[j], currentPoint3DVtk ); // take transformation via vtktransform into account transform->TransformPoint ( currentPoint3DVtk, currentPoint3DVtk ); vtk2itk ( currentPoint3DVtk, currentPoint3D ); // check if the point has a distance to the plane // which is smaller than m_MaxProjectionDistance currentPointDistance = worldPlaneGeometry->DistanceFromPlane ( currentPoint3D ); if ( currentPointDistance < m_MaxProjectionDistance ) { currentPointOnPlane = true; //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map ( currentPoint3D, currentPoint2D ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) renderer->GetDisplayGeometry()->WorldToDisplay ( currentPoint2D, currentPoint2D ); } else currentPointOnPlane = false; // // check if we have to begin or end a GL_LINE // if ( ( previousPointOnPlane == false ) && ( currentPointOnPlane == true ) ) { glLineWidth ( m_LineWidth ); glColor3f ( color[0], color[1], color[2] ); glBegin ( GL_LINE_STRIP ); } else if ( ( previousPointOnPlane == true ) && ( currentPointOnPlane == false ) ) { glEnd (); glLineWidth ( 1.0 ); } // the current ponit is on the plane, add it as point to the // line segment if ( currentPointOnPlane == true ) { glVertex2f ( currentPoint2D[0], currentPoint2D[1] ); } previousPointOnPlane = currentPointOnPlane; } // the last point of the spline segment is on the plane, thus we have to // close the GL_LINE if ( previousPointOnPlane == true ) { glEnd (); glLineWidth ( 1.0 ); } previousPointOnPlane = false; } } void mitk::SplineMapper2D::ApplyProperties ( mitk::BaseRenderer* renderer ) { - Superclass::ApplyProperties ( renderer ); + ApplyColorAndOpacityProperties ( renderer ); } mitk::SplineMapper2D::SplineMapper2D() { m_MaxProjectionDistance = 1; m_ShowDistantLines = false ; m_LineWidth = 1; } mitk::SplineMapper2D::~SplineMapper2D() {} diff --git a/Modules/MitkExt/Rendering/mitkSplineMapper2D.h b/Modules/MitkExt/Rendering/mitkSplineMapper2D.h index 668ba0e99a..30c6d704fa 100755 --- a/Modules/MitkExt/Rendering/mitkSplineMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkSplineMapper2D.h @@ -1,83 +1,83 @@ /*=================================================================== 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 MITKSplineMapper2D_H_HEADER_INCLUDED #define MITKSplineMapper2D_H_HEADER_INCLUDED #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" #include "mitkPointSetGLMapper2D.h" #include namespace mitk { class BaseRenderer; class PointSet; //##Documentation //## @brief OpenGL-based mapper to display a spline based on a mitk::PointSet in a 2D window. //## /** This mapper can actually more than just draw a number of points of a * mitk::PointSet. If you set the right properties of the mitk::DataNode, * which contains the point set, then this mapper will also draw lines * connecting the points, and calculate and display distances and angles * between adjacent points. Here is a complete list of boolean properties, * which might be of interest: * * - \b "show contour": Draw not only the points but also the connections between * them (default false) * - \b "line width": IntProperty which gives the width of the contour lines * - \b "show points": Wheter or not to draw the actual points (default true) * - \b "show distances": Wheter or not to calculate and print the distance * between adjacent points (default false) * - \b "show angles": Wheter or not to calculate and print the angle between * adjacent points (default false) * - \b "show distant lines": When true, the mapper will also draw contour * lines that are far away form the current slice (default true) * - \b "label": StringProperty with a label for this point set */ //## @ingroup Mapper class MitkExt_EXPORT SplineMapper2D : public PointSetGLMapper2D { public: mitkClassMacro ( SplineMapper2D, PointSetGLMapper2D ); itkNewMacro ( Self ); virtual void Paint ( mitk::BaseRenderer * renderer ); virtual void ApplyProperties ( mitk::BaseRenderer* renderer ); itkSetMacro ( MaxProjectionDistance, vtkFloatingPointType ); itkGetMacro ( MaxProjectionDistance, vtkFloatingPointType ); protected: SplineMapper2D(); virtual ~SplineMapper2D(); vtkFloatingPointType m_MaxProjectionDistance; }; } // namespace mitk #endif /* MITKSplineMapper2D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.cpp index 07f55a227c..9c311a3227 100644 --- a/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.cpp @@ -1,236 +1,234 @@ /*=================================================================== 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 "mitkSplineVtkMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::SplineVtkMapper3D::SplineVtkMapper3D() : m_SplinesAvailable (false), m_SplinesAddedToAssembly(false) { m_SplinesActor = vtkActor::New(); m_SplineAssembly = vtkPropAssembly::New(); m_SplineResolution = 500; } mitk::SplineVtkMapper3D::~SplineVtkMapper3D() { m_SplinesActor->Delete(); m_SplineAssembly->Delete(); } vtkProp* mitk::SplineVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_SplineAssembly; } void mitk::SplineVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); m_SplinesActor->SetUserTransform(vtktransform); } -void -mitk::SplineVtkMapper3D::GenerateData() + +void mitk::SplineVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) { - Superclass::GenerateData(); // only update spline if UpdateSpline has not been called from // external, e.g. by the SplineMapper2D. But call it the first time when m_SplineUpdateTime = 0 and m_LastUpdateTime = 0. if ( m_SplineUpdateTime < m_LastUpdateTime || m_SplineUpdateTime == 0) { this->UpdateSpline(); - this->ApplyProperties(m_SplinesActor, NULL); + this->ApplyAllProperties(renderer, m_SplinesActor); } if ( m_SplinesAvailable ) { if ( ! m_SplinesAddedToAssembly ) { m_SplineAssembly->AddPart( m_SplinesActor ); m_SplinesAddedToAssembly = true; } } else { if ( m_SplinesAddedToAssembly ) { m_SplineAssembly->RemovePart( m_SplinesActor ); m_SplinesAddedToAssembly = false; } } -} + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); -void mitk::SplineVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) -{ - if ( IsVisible( renderer ) == false ) + if(!visible) { m_SplinesActor->VisibilityOff(); m_SplineAssembly->VisibilityOff(); } else { m_SplinesActor->VisibilityOn(); m_SplineAssembly->VisibilityOn(); //remove the PointsAssembly if it was added in superclass. No need to display points and spline! if(m_SplineAssembly->GetParts()->IsItemPresent(m_PointsAssembly)) m_SplineAssembly->RemovePart(m_PointsAssembly); } //if the properties have been changed, then refresh the properties if ( (m_SplineUpdateTime < this->m_DataNode->GetPropertyList()->GetMTime() ) || (m_SplineUpdateTime < this->m_DataNode->GetPropertyList(renderer)->GetMTime() ) ) - this->ApplyProperties(m_SplinesActor, NULL); + this->ApplyAllProperties(renderer, m_SplinesActor); } -void mitk::SplineVtkMapper3D::ApplyProperties(vtkActor *actor, BaseRenderer *renderer) +void mitk::SplineVtkMapper3D::ApplyAllProperties(BaseRenderer *renderer, vtkActor *actor) { - Superclass::ApplyProperties(actor, renderer); + Superclass::ApplyColorAndOpacityProperties(renderer, actor); //vtk changed the type of rgba during releases. Due to that, the following convert is done vtkFloatingPointType rgba[ 4 ] = {1.0f, 1.0f, 1.0f, 1.0f};//white //getting the color from DataNode float temprgba[4]; this->GetDataNode()->GetColor( &temprgba[0], NULL ); //convert to rgba, what ever type it has! rgba[0] = temprgba[0]; rgba[1] = temprgba[1]; rgba[2] = temprgba[2]; rgba[3] = temprgba[3]; //finaly set the color inside the actor m_SplinesActor->GetProperty()->SetColor( rgba ); float lineWidth; if (dynamic_cast(this->GetDataNode()->GetProperty("line width")) == NULL) lineWidth = 1.0; else lineWidth = dynamic_cast(this->GetDataNode()->GetProperty("line width"))->GetValue(); m_SplinesActor->GetProperty()->SetLineWidth(lineWidth); m_SplineUpdateTime.Modified(); } bool mitk::SplineVtkMapper3D::SplinesAreAvailable() { return m_SplinesAvailable; } vtkPolyData* mitk::SplineVtkMapper3D::GetSplinesPolyData() { if ( m_SplinesAvailable ) return ( dynamic_cast( m_SplinesActor->GetMapper() ) )->GetInput(); else return NULL; } vtkActor* mitk::SplineVtkMapper3D::GetSplinesActor() { if ( m_SplinesAvailable ) return m_SplinesActor; else return vtkActor::New(); } unsigned long mitk::SplineVtkMapper3D::GetLastUpdateTime() const { return m_LastUpdateTime.GetMTime(); } void mitk::SplineVtkMapper3D::UpdateSpline() { mitk::PointSet::Pointer input = const_cast( this->GetInput( ) ); // input->Update();//already done in superclass // Number of points on the spline unsigned int numberOfOutputPoints = m_SplineResolution; unsigned int numberOfInputPoints = input->GetSize(); if ( numberOfInputPoints >= 2 ) { m_SplinesAvailable = true; vtkCardinalSpline* splineX = vtkCardinalSpline::New(); vtkCardinalSpline* splineY = vtkCardinalSpline::New(); vtkCardinalSpline* splineZ = vtkCardinalSpline::New(); unsigned int index = 0; mitk::PointSet::DataType::PointsContainer::Pointer pointsContainer = input->GetPointSet()->GetPoints(); for ( mitk::PointSet::DataType::PointsContainer::Iterator it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++index ) //for ( unsigned int i = 0 ; i < numberOfInputPoints; ++i ) { mitk::PointSet::PointType point = it->Value(); splineX->AddPoint( index, point[ 0 ] ); splineY->AddPoint( index, point[ 1 ] ); splineZ->AddPoint( index, point[ 2 ] ); } vtkPoints* points = vtkPoints::New(); vtkPolyData* profileData = vtkPolyData::New(); // Interpolate x, y and z by using the three spline filters and // create new points double t = 0.0f; for ( unsigned int i = 0; i < numberOfOutputPoints; ++i ) { t = ( ( ( ( double ) numberOfInputPoints ) - 1.0f ) / ( ( ( double ) numberOfOutputPoints ) - 1.0f ) ) * ( ( double ) i ); points->InsertPoint( i, splineX->Evaluate( t ), splineY->Evaluate( t ), splineZ->Evaluate( t ) ) ; } // Create the polyline. vtkCellArray* lines = vtkCellArray::New(); lines->InsertNextCell( numberOfOutputPoints ); for ( unsigned int i = 0; i < numberOfOutputPoints; ++i ) lines->InsertCellPoint( i ); profileData->SetPoints( points ); profileData->SetLines( lines ); // Add thickness to the resulting line. //vtkTubeFilter* profileTubes = vtkTubeFilter::New(); //profileTubes->SetNumberOfSides(8); //profileTubes->SetInput(profileData); //profileTubes->SetRadius(.005); vtkPolyDataMapper* profileMapper = vtkPolyDataMapper::New(); profileMapper->SetInput( profileData ); m_SplinesActor->SetMapper( profileMapper ); } else { m_SplinesAvailable = false; } m_SplineUpdateTime.Modified(); } diff --git a/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.h b/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.h index 0a03a5a0fd..dd9a41691b 100644 --- a/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkSplineVtkMapper3D.h @@ -1,98 +1,96 @@ /*=================================================================== 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_SPLINE_VTK_MAPPER_3D__H #define _MITK_SPLINE_VTK_MAPPER_3D__H #include "mitkPointSetVtkMapper3D.h" #include "MitkExtExports.h" class vtkActor; class vtkAssembly; namespace mitk { //##Documentation //## @brief Vtk-based mapper for Splines //## //## properties looked for: //## "line width" = with of the spline //## @ingroup Mapper /************************************************************************/ /* * - \b "line width": (FloatProperty) line width of the spline */ /************************************************************************/ class MitkExt_EXPORT SplineVtkMapper3D : public PointSetVtkMapper3D { public: mitkClassMacro( SplineVtkMapper3D, PointSetVtkMapper3D ); itkNewMacro( Self ); virtual vtkProp* GetVtkProp(mitk::BaseRenderer *renderer); virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); bool SplinesAreAvailable(); vtkPolyData* GetSplinesPolyData(); vtkActor* GetSplinesActor(); unsigned long GetLastUpdateTime() const; virtual void UpdateSpline(); itkSetMacro( SplineResolution, unsigned int ); itkGetMacro( SplineResolution, unsigned int ); protected: SplineVtkMapper3D(); virtual ~SplineVtkMapper3D(); - virtual void GenerateData(); - virtual void GenerateDataForRenderer(mitk::BaseRenderer * renderer); - virtual void ApplyProperties(vtkActor *actor, BaseRenderer *renderer); + virtual void ApplyAllProperties(BaseRenderer *renderer, vtkActor *actor); vtkActor* m_SplinesActor; vtkPropAssembly* m_SplineAssembly; bool m_SplinesAvailable; bool m_SplinesAddedToAssembly; unsigned int m_SplineResolution; itk::TimeStamp m_SplineUpdateTime; }; } //namespace mitk #endif diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.cpp b/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.cpp index d67ae504ed..8ce7980bee 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.cpp @@ -1,570 +1,567 @@ /*=================================================================== 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 #include "mitkUnstructuredGridMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkUnstructuredGrid.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkColorProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkProperties.h" #include "mitkAbstractTransformGeometry.h" #include "mitkVtkMapper3D.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -void mitk::UnstructuredGridMapper2D::GenerateData() +void mitk::UnstructuredGridMapper2D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) { - mitk::DataNode::ConstPointer node = this->GetDataNode(); + + mitk::DataNode::ConstPointer node = this->GetDataNode(); if ( node.IsNull() ) return; - if (!node->GetProperty(m_ScalarMode, "scalar mode")) { m_ScalarMode = mitk::VtkScalarModeProperty::New(0); } if (!node->GetProperty(m_ScalarVisibility, "scalar visibility")) { m_ScalarVisibility = mitk::BoolProperty::New(true); } if (!node->GetProperty(m_Outline, "outline polygons")) { m_Outline = mitk::BoolProperty::New(false); } if (!node->GetProperty(m_Color, "color")) { m_Color = mitk::ColorProperty::New(1.0f, 1.0f, 1.0f); } if (!node->GetProperty(m_LineWidth, "line width")) { m_LineWidth = mitk::IntProperty::New(1); } -} - -void mitk::UnstructuredGridMapper2D::GenerateDataForRenderer( mitk::BaseRenderer* renderer ) -{ - mitk::BaseData::Pointer input = const_cast( this->GetData() ); + mitk::BaseData::Pointer input = const_cast( GetDataNode()->GetData() ); assert( input ); input->Update(); if (m_VtkPointSet) m_VtkPointSet->UnRegister(0); m_VtkPointSet = this->GetVtkPointSet(renderer); assert(m_VtkPointSet); m_VtkPointSet->Register(0); if (m_ScalarVisibility->GetValue()) { mitk::DataNode::ConstPointer node = this->GetDataNode(); mitk::TransferFunctionProperty::Pointer transferFuncProp; node->GetProperty(transferFuncProp, "TransferFunction", renderer); if (transferFuncProp.IsNotNull()) { mitk::TransferFunction::Pointer tf = transferFuncProp->GetValue(); if (m_ScalarsToColors) m_ScalarsToColors->UnRegister(0); m_ScalarsToColors = static_cast(tf->GetColorTransferFunction()); m_ScalarsToColors->Register(0); if (m_ScalarsToOpacity) m_ScalarsToOpacity->UnRegister(0); m_ScalarsToOpacity = tf->GetScalarOpacityFunction(); m_ScalarsToOpacity->Register(0); } else { if (m_ScalarsToColors) m_ScalarsToColors->UnRegister(0); m_ScalarsToColors = this->GetVtkLUT(renderer); assert(m_ScalarsToColors); m_ScalarsToColors->Register(0); float opacity; node->GetOpacity(opacity, renderer); if (m_ScalarsToOpacity) m_ScalarsToOpacity->UnRegister(0); m_ScalarsToOpacity = vtkPiecewiseFunction::New(); double range[2]; m_VtkPointSet->GetScalarRange(range); m_ScalarsToOpacity->AddSegment(range[0], opacity, range[1], opacity); } } } void mitk::UnstructuredGridMapper2D::Paint( mitk::BaseRenderer* renderer ) { - if ( IsVisible( renderer ) == false ) - return ; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + if(!visible) return; vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(); vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse(); Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); Point3D point; Vector3D normal; if(worldPlaneGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=worldPlaneGeometry->GetOrigin(); normal=worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform((vtkAbstractTransform*)NULL); } else { //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"? return; AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast(renderer->GetCurrentWorldGeometry2D()); if(worldAbstractGeometry.IsNotNull()) { // set up vtkPlane according to worldGeometry point=const_cast(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum(); FillVector3D(normal, 0, 0, 1); m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse()); } else return; } vtkFloatingPointType vp[ 3 ], vnormal[ 3 ]; vnl2vtk(point.Get_vnl_vector(), vp); vnl2vtk(normal.Get_vnl_vector(), vnormal); //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. inversetransform->TransformPoint( vp, vp ); inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal ); m_Plane->SetOrigin( vp ); m_Plane->SetNormal( vnormal ); // set data into cutter m_Slicer->SetInput( m_VtkPointSet ); // m_Cutter->GenerateCutScalarsOff(); // m_Cutter->SetSortByToSortByCell(); // calculate the cut m_Slicer->Update(); // fetch geometry mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert( displayGeometry ); // float toGL=displayGeometry->GetSizeInDisplayUnits()[1]; //apply color and opacity read from the PropertyList - ApplyProperties( renderer ); + ApplyColorAndOpacityProperties( renderer ); // traverse the cut contour vtkPolyData * contour = m_Slicer->GetOutput(); vtkPoints *vpoints = contour->GetPoints(); vtkCellArray *vlines = contour->GetLines(); vtkCellArray *vpolys = contour->GetPolys(); vtkPointData *vpointdata = contour->GetPointData(); vtkDataArray* vscalars = vpointdata->GetScalars(); vtkCellData *vcelldata = contour->GetCellData(); vtkDataArray* vcellscalars = vcelldata->GetScalars(); const int numberOfLines = contour->GetNumberOfLines(); const int numberOfPolys = contour->GetNumberOfPolys(); const bool useCellData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT || m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA; const bool usePointData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA; Point3D p; Point2D p2d; vlines->InitTraversal(); vpolys->InitTraversal(); mitk::Color outlineColor = m_Color->GetColor(); glLineWidth((float)m_LineWidth->GetValue()); for (int i = 0;i < numberOfLines;++i ) { vtkIdType *cell(0); vtkIdType cellSize(0); vlines->GetNextCell( cellSize, cell ); float rgba[4] = {outlineColor[0], outlineColor[1], outlineColor[2], 1.0f}; if (m_ScalarVisibility->GetValue() && vcellscalars) { if ( useCellData ) { // color each cell according to cell data double scalar = vcellscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } else if ( usePointData ) { double scalar = vscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } } glColor4fv( rgba ); glBegin ( GL_LINE_LOOP ); for ( int j = 0;j < cellSize;++j ) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd (); } bool polyOutline = m_Outline->GetValue(); bool scalarVisibility = m_ScalarVisibility->GetValue(); // cache the transformed points // a fixed size array is way faster than 'new' // slices through 3d cells usually do not generated // polygons with more than 6 vertices const int maxPolySize = 10; Point2D* cachedPoints = new Point2D[maxPolySize*numberOfPolys]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only draw polygons if there are cell scalars // or the outline property is set to true if (scalarVisibility && vcellscalars) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); for (int i = 0;i < numberOfPolys;++i ) { vtkIdType *cell(0); vtkIdType cellSize(0); vpolys->GetNextCell( cellSize, cell ); float rgba[4] = {1.0f, 1.0f, 1.0f, 0}; if (scalarVisibility && vcellscalars) { if ( useCellData ) { // color each cell according to cell data double scalar = vcellscalars->GetComponent( i+numberOfLines, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } else if ( usePointData ) { double scalar = vscalars->GetComponent( i, 0 ); double rgb[3] = { 1.0f, 1.0f, 1.0f }; m_ScalarsToColors->GetColor(scalar, rgb); rgba[0] = (float)rgb[0]; rgba[1] = (float)rgb[1]; rgba[2] = (float)rgb[2]; rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar); } } glColor4fv( rgba ); glBegin( GL_POLYGON ); for (int j = 0; j < cellSize; ++j) { vpoints->GetPoint( cell[ j ], vp ); //take transformation via vtktransform into account vtktransform->TransformPoint( vp, vp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left ) //p2d[1]=toGL-p2d[1]; cachedPoints[i*10+j][0] = p2d[0]; cachedPoints[i*10+j][1] = p2d[1]; //add the current vertex to the line glVertex2f( p2d[0], p2d[1] ); } glEnd(); } if (polyOutline) { vpolys->InitTraversal(); glColor4f(outlineColor[0], outlineColor[1], outlineColor[2], 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for (int i = 0;i < numberOfPolys;++i) { vtkIdType *cell(0); vtkIdType cellSize(0); vpolys->GetNextCell( cellSize, cell ); glBegin( GL_POLYGON ); //glPolygonOffset(1.0, 1.0); for (int j = 0; j < cellSize; ++j) { //add the current vertex to the line glVertex2f( cachedPoints[i*10+j][0], cachedPoints[i*10+j][1] ); } glEnd(); } } } glDisable(GL_BLEND); delete cachedPoints; } vtkAbstractMapper3D* mitk::UnstructuredGridMapper2D ::GetVtkAbstractMapper3D(mitk::BaseRenderer * renderer) { //MITK_INFO << "GETVTKABSTRACTMAPPER3D\n"; mitk::DataNode::ConstPointer node = this->GetDataNode(); if ( node.IsNull() ) return 0; - mitk::VtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper3D* > ( node->GetMapper( 2 ) ); + mitk::VtkMapper::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper* > ( node->GetMapper( 2 ) ); if ( mitkMapper.IsNull() ) { return 0; } mitkMapper->Update(renderer); vtkAssembly* assembly = dynamic_cast(mitkMapper->GetVtkProp(renderer)); if (assembly) { vtkProp3DCollection* collection = assembly->GetParts(); collection->InitTraversal(); vtkProp3D* prop3d = 0; do { prop3d = collection->GetNextProp3D(); vtkActor* actor = dynamic_cast( prop3d ); if (actor) { return dynamic_cast( actor->GetMapper() ); } vtkVolume* volume = dynamic_cast( prop3d ); if (volume) { return dynamic_cast( volume->GetMapper() ); } } while (prop3d != collection->GetLastProp3D()); } else { vtkActor* actor = dynamic_cast( mitkMapper->GetVtkProp(renderer) ); if (actor) { return dynamic_cast( actor->GetMapper() ); } vtkVolume* volume = dynamic_cast( mitkMapper->GetVtkProp(renderer) ); if (volume) { return dynamic_cast( volume->GetMapper() ); } } return 0; } vtkPointSet* mitk::UnstructuredGridMapper2D ::GetVtkPointSet(mitk::BaseRenderer* renderer) { //MITK_INFO << "GETVTKPOINTSET\n"; vtkAbstractMapper3D * abstractMapper = GetVtkAbstractMapper3D(renderer); if ( abstractMapper == 0 ) { // try to get data from the node mitk::DataNode::ConstPointer node = this->GetDataNode(); if ( node.IsNull() ) return 0; mitk::BaseData::Pointer data = node->GetData(); mitk::UnstructuredGrid::Pointer grid = dynamic_cast(data.GetPointer()); if (!grid.IsNull()) return static_cast(grid->GetVtkUnstructuredGrid()); return 0; } else { vtkMapper* mapper = dynamic_cast(abstractMapper); if (mapper) { return dynamic_cast(mapper->GetInput()); } vtkAbstractVolumeMapper* volMapper = dynamic_cast(abstractMapper); if (volMapper) { return dynamic_cast(volMapper->GetDataSetInput()); } } return 0; } vtkScalarsToColors* mitk::UnstructuredGridMapper2D::GetVtkLUT(mitk::BaseRenderer* renderer) { //MITK_INFO << "GETVTKLUT\n"; vtkMapper * mapper = dynamic_cast(GetVtkAbstractMapper3D(renderer)); if (mapper) return mapper->GetLookupTable(); else { mitk::DataNode::ConstPointer node = this->GetDataNode(); if ( node.IsNull() ) return 0; - mitk::VtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper3D* > ( node->GetMapper( 2 ) ); + mitk::VtkMapper::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper* > ( node->GetMapper( 2 ) ); if ( mitkMapper.IsNull() ) { //MITK_INFO << "mitkMapper is null\n"; return 0; } mitkMapper->Update(renderer); vtkVolume* volume = dynamic_cast( mitkMapper->GetVtkProp(renderer) ); if (volume) { //MITK_INFO << "found volume prop\n"; return static_cast(volume->GetProperty()->GetRGBTransferFunction()); } vtkAssembly* assembly = dynamic_cast(mitkMapper->GetVtkProp(renderer)); if (assembly) { //MITK_INFO << "found assembly prop\n"; mitk::TransferFunctionProperty::Pointer transferFuncProp; node->GetProperty(transferFuncProp, "TransferFunction", 0); if (transferFuncProp.IsNotNull()) { MITK_INFO << "return colortransferfunction\n"; return static_cast(transferFuncProp->GetValue()->GetColorTransferFunction()); } } return 0; } } bool mitk::UnstructuredGridMapper2D::IsConvertibleToVtkPointSet(mitk::BaseRenderer * renderer) { return ( GetVtkPointSet(renderer) != 0 ); } mitk::UnstructuredGridMapper2D::UnstructuredGridMapper2D() { m_Plane = vtkPlane::New(); m_Slicer = vtkPointSetSlicer::New(); m_Slicer->SetSlicePlane( m_Plane ); m_ScalarsToColors = 0; m_ScalarsToOpacity = 0; m_VtkPointSet = 0; //m_LUT = vtkLookupTable::New(); //m_LUT->SetTableRange( 0, 255 ); //m_LUT->SetNumberOfColors( 255 ); //m_LUT->SetRampToLinear (); //m_LUT->Build(); } mitk::UnstructuredGridMapper2D::~UnstructuredGridMapper2D() { m_Slicer->Delete(); m_Plane->Delete(); if (m_ScalarsToOpacity != 0) m_ScalarsToOpacity->UnRegister(0); if (m_ScalarsToColors != 0) m_ScalarsToColors->UnRegister(0); if (m_VtkPointSet != 0) m_VtkPointSet->UnRegister(0); } diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.h b/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.h index 83c4b45e78..6e8dd546b3 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridMapper2D.h @@ -1,112 +1,111 @@ /*=================================================================== 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 MitkPointSetSliceLMapper2D_H #define MitkPointSetSliceLMapper2D_H #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" #include "mitkTransferFunction.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkScalarModeProperty.h" class vtkPointSetSlicer; class vtkPlane; class vtkLookupTable; class vtkPointSet; class vtkScalarsToColors; class vtkPiecewiseFunction; class vtkAbstractMapper3D; namespace mitk { class BaseRenderer; /** * @brief OpenGL-based mapper to display a 2d cut through a poly data * OpenGL-based mapper to display a 2D cut through a poly data. The result is * normally a line. This class can be added to any data object, which is * rendered in 3D via a vtkPolyData. */ -class MitkExt_EXPORT UnstructuredGridMapper2D : public GLMapper2D +class MitkExt_EXPORT UnstructuredGridMapper2D : public GLMapper { public: - mitkClassMacro( UnstructuredGridMapper2D, GLMapper2D ); + mitkClassMacro( UnstructuredGridMapper2D, GLMapper ); itkNewMacro( Self ); /** * Renders a cut through a pointset by cutting trough the n-cells, * producing (n-1)-cells. * @param renderer the render to render in. */ virtual void Paint( mitk::BaseRenderer* renderer ); protected: UnstructuredGridMapper2D(); virtual ~UnstructuredGridMapper2D(); - virtual void GenerateData(); virtual void GenerateDataForRenderer(BaseRenderer*); /** * Determines, if the associated BaseData is mapped three-dimensionally (mapper-slot id 2) * with a class convertable to vtkAbstractMapper3D(). * @returns NULL if it is not convertable or the appropriate Mapper otherwise */ virtual vtkAbstractMapper3D* GetVtkAbstractMapper3D(BaseRenderer* renderer); /** * Determines the pointset object to be cut. * returns the pointset if possible, otherwise NULL. */ virtual vtkPointSet* GetVtkPointSet(BaseRenderer* renderer ); /** * Determines the LookupTable used by the associated vtkMapper. * returns the LUT if possible, otherwise NULL. */ virtual vtkScalarsToColors* GetVtkLUT(BaseRenderer* renderer ); /** * Checks if this mapper can be used to generate cuts through the associated * base data. * @return true if yes or false if not. */ virtual bool IsConvertibleToVtkPointSet(BaseRenderer* renderer); vtkPlane* m_Plane; vtkPointSetSlicer* m_Slicer; vtkPointSet* m_VtkPointSet; vtkScalarsToColors* m_ScalarsToColors; vtkPiecewiseFunction* m_ScalarsToOpacity; mitk::ColorProperty::Pointer m_Color; mitk::IntProperty::Pointer m_LineWidth; mitk::BoolProperty::Pointer m_Outline; mitk::BoolProperty::Pointer m_ScalarVisibility; mitk::VtkScalarModeProperty::Pointer m_ScalarMode; }; } // namespace mitk #endif /* MitkPointSetSliceLMapper2D_H */ diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp index fecc620e54..1a955caeb7 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.cpp @@ -1,416 +1,416 @@ /*=================================================================== 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 "mitkUnstructuredGridVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkTransferFunctionProperty.h" #include "mitkColorProperty.h" //#include "mitkLookupTableProperty.h" #include "mitkGridRepresentationProperty.h" #include "mitkGridVolumeMapperProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkDataStorage.h" #include "mitkSurfaceVtkMapper3D.h" #include #include #include #include #include const mitk::UnstructuredGrid* mitk::UnstructuredGridVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } mitk::UnstructuredGridVtkMapper3D::UnstructuredGridVtkMapper3D() { m_VtkTriangleFilter = vtkDataSetTriangleFilter::New(); m_Assembly = vtkAssembly::New(); m_Volume = vtkVolume::New(); m_Actor = vtkActor::New(); m_ActorWireframe = vtkActor::New(); m_VtkDataSetMapper = vtkUnstructuredGridMapper::New(); m_VtkDataSetMapper->SetResolveCoincidentTopologyToPolygonOffset(); m_VtkDataSetMapper->SetResolveCoincidentTopologyPolygonOffsetParameters(0,1); m_Actor->SetMapper(m_VtkDataSetMapper); m_VtkDataSetMapper2 = vtkUnstructuredGridMapper::New(); m_VtkDataSetMapper2->SetResolveCoincidentTopologyToPolygonOffset(); m_VtkDataSetMapper2->SetResolveCoincidentTopologyPolygonOffsetParameters(1,1); m_ActorWireframe->SetMapper(m_VtkDataSetMapper2); m_ActorWireframe->GetProperty()->SetRepresentationToWireframe(); m_Assembly->AddPart(m_Actor); m_Assembly->AddPart(m_ActorWireframe); m_Assembly->AddPart(m_Volume); m_VtkVolumeRayCastMapper = 0; m_VtkPTMapper = 0; m_VtkVolumeZSweepMapper = 0; //m_GenerateNormals = false; } mitk::UnstructuredGridVtkMapper3D::~UnstructuredGridVtkMapper3D() { if (m_VtkTriangleFilter != 0) m_VtkTriangleFilter->Delete(); if (m_VtkVolumeRayCastMapper != 0) m_VtkVolumeRayCastMapper->Delete(); if (m_VtkVolumeZSweepMapper != 0) m_VtkVolumeZSweepMapper->Delete(); if (m_VtkPTMapper != 0) m_VtkPTMapper->Delete(); if (m_VtkDataSetMapper != 0) m_VtkDataSetMapper->Delete(); if (m_VtkDataSetMapper2 != 0) m_VtkDataSetMapper2->Delete(); if (m_Assembly != 0) m_Assembly->Delete(); if (m_Actor != 0) m_Actor->Delete(); if (m_ActorWireframe != 0) m_ActorWireframe->Delete(); if (m_Volume != 0) m_Volume->Delete(); } vtkProp* mitk::UnstructuredGridVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Assembly; } -void mitk::UnstructuredGridVtkMapper3D::GenerateData() + +void mitk::UnstructuredGridVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { + m_Assembly->VisibilityOn(); m_ActorWireframe->GetProperty()->SetAmbient(1.0); m_ActorWireframe->GetProperty()->SetDiffuse(0.0); m_ActorWireframe->GetProperty()->SetSpecular(0.0); mitk::DataNode::ConstPointer node = this->GetDataNode(); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction")) { mitk::TransferFunction::Pointer transferFunction = transferFuncProp->GetValue(); if (transferFunction->GetColorTransferFunction()->GetSize() < 2) { mitk::UnstructuredGrid::Pointer input = const_cast< mitk::UnstructuredGrid* >(this->GetInput()); if (input.IsNull()) return; vtkUnstructuredGrid * grid = input->GetVtkUnstructuredGrid(this->GetTimestep()); if (grid == 0) return; double* scalarRange = grid->GetScalarRange(); vtkColorTransferFunction* colorFunc = transferFunction->GetColorTransferFunction(); colorFunc->RemoveAllPoints(); colorFunc->AddRGBPoint(scalarRange[0], 1, 0, 0); colorFunc->AddRGBPoint((scalarRange[0] + scalarRange[1])/2.0, 0, 1, 0); colorFunc->AddRGBPoint(scalarRange[1], 0, 0, 1); } } -} -void mitk::UnstructuredGridVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) -{ + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); - if(!IsVisible(renderer)) + if(!visible) { m_Assembly->VisibilityOff(); return; } // // get the TimeSlicedGeometry of the input object // mitk::UnstructuredGrid::Pointer input = const_cast< mitk::UnstructuredGrid* >( this->GetInput() ); // // set the input-object at time t for the mapper // vtkUnstructuredGrid * grid = input->GetVtkUnstructuredGrid( this->GetTimestep() ); if(grid == 0) { m_Assembly->VisibilityOff(); return; } m_Assembly->VisibilityOn(); m_VtkTriangleFilter->SetInput(grid); m_VtkDataSetMapper->SetInput(grid); m_VtkDataSetMapper2->SetInput(grid); - mitk::DataNode::ConstPointer node = this->GetDataNode(); bool clip = false; node->GetBoolProperty("enable clipping", clip); mitk::DataNode::Pointer bbNode = renderer->GetDataStorage()->GetNamedDerivedNode("Clipping Bounding Object", node); if (clip && bbNode.IsNotNull()) { m_VtkDataSetMapper->SetBoundingObject(dynamic_cast(bbNode->GetData())); m_VtkDataSetMapper2->SetBoundingObject(dynamic_cast(bbNode->GetData())); } else { m_VtkDataSetMapper->SetBoundingObject(0); m_VtkDataSetMapper2->SetBoundingObject(0); } // // apply properties read from the PropertyList // ApplyProperties(0, renderer); } void mitk::UnstructuredGridVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_Assembly->VisibilityOff(); } void mitk::UnstructuredGridVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { mitk::DataNode::Pointer node = this->GetDataNode(); - Superclass::ApplyProperties(m_Actor, renderer); - Superclass::ApplyProperties(m_ActorWireframe, renderer); + ApplyColorAndOpacityProperties(renderer, m_Actor); + ApplyColorAndOpacityProperties(renderer, m_ActorWireframe); vtkVolumeProperty* volProp = m_Volume->GetProperty(); vtkProperty* property = m_Actor->GetProperty(); vtkProperty* wireframeProp = m_ActorWireframe->GetProperty(); mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(node,property,renderer); mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(node,wireframeProp,renderer); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction", renderer)) { mitk::TransferFunction::Pointer transferFunction = transferFuncProp->GetValue(); volProp->SetColor(transferFunction->GetColorTransferFunction()); volProp->SetScalarOpacity(transferFunction->GetScalarOpacityFunction()); volProp->SetGradientOpacity(transferFunction->GetGradientOpacityFunction()); m_VtkDataSetMapper->SetLookupTable(transferFunction->GetColorTransferFunction()); m_VtkDataSetMapper2->SetLookupTable(transferFunction->GetColorTransferFunction()); } bool isVolumeRenderingOn = false; node->GetBoolProperty("volumerendering", isVolumeRenderingOn, renderer); if (isVolumeRenderingOn) { m_Assembly->RemovePart(m_Actor); m_Assembly->RemovePart(m_ActorWireframe); m_Assembly->AddPart(m_Volume); mitk::GridVolumeMapperProperty::Pointer mapperProp; if (node->GetProperty(mapperProp, "volumerendering.mapper", renderer)) { mitk::GridVolumeMapperProperty::IdType type = mapperProp->GetValueAsId(); switch (type) { case mitk::GridVolumeMapperProperty::RAYCAST: if (m_VtkVolumeRayCastMapper == 0) { m_VtkVolumeRayCastMapper = vtkUnstructuredGridVolumeRayCastMapper::New(); m_VtkVolumeRayCastMapper->SetInput(m_VtkTriangleFilter->GetOutput()); } m_Volume->SetMapper(m_VtkVolumeRayCastMapper); break; case mitk::GridVolumeMapperProperty::PT: if (m_VtkPTMapper == 0) { m_VtkPTMapper = vtkProjectedTetrahedraMapper::New(); m_VtkPTMapper->SetInputConnection(m_VtkTriangleFilter->GetOutputPort()); } m_Volume->SetMapper(m_VtkPTMapper); break; case mitk::GridVolumeMapperProperty::ZSWEEP: if (m_VtkVolumeZSweepMapper == 0) { m_VtkVolumeZSweepMapper = vtkUnstructuredGridVolumeZSweepMapper::New(); m_VtkVolumeZSweepMapper->SetInputConnection(m_VtkTriangleFilter->GetOutputPort()); } m_Volume->SetMapper(m_VtkVolumeZSweepMapper); break; } } } else { m_Assembly->RemovePart(m_Volume); m_Assembly->AddPart(m_Actor); m_Assembly->RemovePart(m_ActorWireframe); mitk::GridRepresentationProperty::Pointer gridRepProp; if (node->GetProperty(gridRepProp, "grid representation", renderer)) { mitk::GridRepresentationProperty::IdType type = gridRepProp->GetValueAsId(); switch (type) { case mitk::GridRepresentationProperty::POINTS: property->SetRepresentationToPoints(); break; case mitk::GridRepresentationProperty::WIREFRAME: property->SetRepresentationToWireframe(); break; case mitk::GridRepresentationProperty::SURFACE: property->SetRepresentationToSurface(); break; } // if (type == mitk::GridRepresentationProperty::WIREFRAME_SURFACE) // { // m_Assembly->AddPart(m_ActorWireframe); // } } } // mitk::LevelWindow levelWindow; // if(node->GetLevelWindow(levelWindow, renderer, "levelWindow")) // { // m_VtkVolumeRayCastMapper->SetScalarRange(levelWindow.GetMin(),levelWindow.GetMax()); // } // else // if(node->GetLevelWindow(levelWindow, renderer)) // { // m_VtkVolumeRayCastMapper->SetScalarRange(levelWindow.GetMin(),levelWindow.GetMax()); // } // // mitk::VtkRepresentationProperty* representationProperty; // node->GetProperty(representationProperty, "material.representation", renderer); // if ( representationProperty != NULL ) // m_Volume->GetProperty()->SetRepresentation( representationProperty->GetVtkRepresentation() ); // // mitk::VtkInterpolationProperty* interpolationProperty; // node->GetProperty(interpolationProperty, "material.interpolation", renderer); // if ( interpolationProperty != NULL ) // m_Volume->GetProperty()->SetInterpolation( interpolationProperty->GetVtkInterpolation() ); // mitk::VtkScalarModeProperty* scalarMode = 0; if(node->GetProperty(scalarMode, "scalar mode", renderer)) { if (m_VtkVolumeRayCastMapper) m_VtkVolumeRayCastMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); if (m_VtkPTMapper) m_VtkPTMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); if (m_VtkVolumeZSweepMapper) m_VtkVolumeZSweepMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); m_VtkDataSetMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); m_VtkDataSetMapper2->SetScalarMode(scalarMode->GetVtkScalarMode()); } else { if (m_VtkVolumeRayCastMapper) m_VtkVolumeRayCastMapper->SetScalarModeToDefault(); if (m_VtkPTMapper) m_VtkPTMapper->SetScalarModeToDefault(); if (m_VtkVolumeZSweepMapper) m_VtkVolumeZSweepMapper->SetScalarModeToDefault(); m_VtkDataSetMapper->SetScalarModeToDefault(); m_VtkDataSetMapper2->SetScalarModeToDefault(); } bool scalarVisibility = true; node->GetBoolProperty("scalar visibility", scalarVisibility, renderer); m_VtkDataSetMapper->SetScalarVisibility(scalarVisibility ? 1 : 0); m_VtkDataSetMapper2->SetScalarVisibility(scalarVisibility ? 1 : 0); // double scalarRangeLower = std::numeric_limits::min(); // double scalarRangeUpper = std::numeric_limits::max(); // mitk::DoubleProperty* lowerRange = 0; // if (node->GetProperty(lowerRange, "scalar range min", renderer)) // { // scalarRangeLower = lowerRange->GetValue(); // } // mitk::DoubleProperty* upperRange = 0; // if (node->GetProperty(upperRange, "scalar range max", renderer)) // { // scalarRangeUpper = upperRange->GetValue(); // } // m_VtkDataSetMapper->SetScalarRange(scalarRangeLower, scalarRangeUpper); // m_VtkDataSetMapper2->SetScalarRange(scalarRangeLower, scalarRangeUpper); // bool colorMode = false; // node->GetBoolProperty("color mode", colorMode); // m_VtkVolumeRayCastMapper->SetColorMode( (colorMode ? 1 : 0) ); // float scalarsMin = 0; // if (dynamic_cast(node->GetProperty("ScalarsRangeMinimum").GetPointer()) != NULL) // scalarsMin = dynamic_cast(node->GetProperty("ScalarsRangeMinimum").GetPointer())->GetValue(); // float scalarsMax = 1.0; // if (dynamic_cast(node->GetProperty("ScalarsRangeMaximum").GetPointer()) != NULL) // scalarsMax = dynamic_cast(node->GetProperty("ScalarsRangeMaximum").GetPointer())->GetValue(); // m_VtkVolumeRayCastMapper->SetScalarRange(scalarsMin,scalarsMax); } void mitk::UnstructuredGridVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node, renderer, overwrite); node->AddProperty("grid representation", GridRepresentationProperty::New(), renderer, overwrite); node->AddProperty("volumerendering", BoolProperty::New(false), renderer, overwrite); node->AddProperty("volumerendering.mapper", GridVolumeMapperProperty::New(), renderer, overwrite); node->AddProperty("scalar mode", VtkScalarModeProperty::New(0), renderer, overwrite); node->AddProperty("scalar visibility", BoolProperty::New(true), renderer, overwrite); //node->AddProperty("scalar range min", DoubleProperty::New(std::numeric_limits::min()), renderer, overwrite); //node->AddProperty("scalar range max", DoubleProperty::New(std::numeric_limits::max()), renderer, overwrite); node->AddProperty("outline polygons", BoolProperty::New(false), renderer, overwrite); node->AddProperty("color", ColorProperty::New(1.0f, 1.0f, 1.0f), renderer, overwrite); node->AddProperty("line width", IntProperty::New(1), renderer, overwrite); if(overwrite || node->GetProperty("TransferFunction", renderer) == 0) { // add a default transfer function mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); //tf->GetColorTransferFunction()->RemoveAllPoints(); node->SetProperty ("TransferFunction", mitk::TransferFunctionProperty::New(tf.GetPointer())); } Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h index 37e3828e52..52f208b015 100644 --- a/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h +++ b/Modules/MitkExt/Rendering/mitkUnstructuredGridVtkMapper3D.h @@ -1,91 +1,90 @@ /*=================================================================== 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_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ #define _MITK_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ #include "mitkCommon.h" #include "MitkExtExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkUnstructuredGrid.h" #include "mitkBaseRenderer.h" #include #include #include #include #include "vtkUnstructuredGridMapper.h" #include #include #include namespace mitk { //##Documentation //## @brief Vtk-based mapper for UnstructuredGrid //## //## @ingroup Mapper -class MitkExt_EXPORT UnstructuredGridVtkMapper3D : public VtkMapper3D +class MitkExt_EXPORT UnstructuredGridVtkMapper3D : public VtkMapper { public: - mitkClassMacro(UnstructuredGridVtkMapper3D, VtkMapper3D); + mitkClassMacro(UnstructuredGridVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::UnstructuredGrid* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer); protected: UnstructuredGridVtkMapper3D(); virtual ~UnstructuredGridVtkMapper3D(); - virtual void GenerateData(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( BaseRenderer* /*renderer*/ ); void SetProperties(mitk::BaseRenderer* renderer); vtkAssembly* m_Assembly; vtkActor* m_Actor; vtkActor* m_ActorWireframe; vtkVolume* m_Volume; vtkDataSetTriangleFilter* m_VtkTriangleFilter; vtkUnstructuredGridMapper* m_VtkDataSetMapper; vtkUnstructuredGridMapper* m_VtkDataSetMapper2; vtkUnstructuredGridVolumeRayCastMapper* m_VtkVolumeRayCastMapper; vtkProjectedTetrahedraMapper* m_VtkPTMapper; vtkUnstructuredGridVolumeZSweepMapper* m_VtkVolumeZSweepMapper; }; } // namespace mitk #endif /* _MITK_UNSTRUCTURED_GRID_VTK_MAPPER_3D_H_ */ diff --git a/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.cpp b/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.cpp index 9570c948e0..e4764abbd4 100644 --- a/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.cpp +++ b/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.cpp @@ -1,534 +1,538 @@ /*=================================================================== 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 "mitkVectorImageMapper2D.h" //vtk related includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //mitk related includes #include "mitkGL.h" #include "mitkBaseRenderer.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkAbstractTransformGeometry.h" #include const mitk::Image * mitk::VectorImageMapper2D::GetInput( void ) { if ( m_Image.IsNotNull() ) return m_Image; else - return dynamic_cast( this->GetData() ); + return dynamic_cast( GetDataNode()->GetData() ); } void mitk::VectorImageMapper2D::Paint( mitk::BaseRenderer * renderer ) { //std::cout << "2d vector mapping..." << std::endl; - if ( IsVisible( renderer ) == false ) + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) return ; mitk::Image::Pointer input = const_cast( this->GetInput() ); if ( input.IsNull() ) return ; mitk::PlaneGeometry::Pointer worldPlaneGeometry2D = dynamic_cast< mitk::PlaneGeometry*>( const_cast( renderer->GetCurrentWorldGeometry2D() ) ); assert( worldPlaneGeometry2D.IsNotNull() ); vtkImageData* vtkImage = input->GetVtkImageData( this->GetCurrentTimeStep( input, renderer ) ); // // set up the cutter orientation according to the current geometry of // the renderers plane // Point3D point; Vector3D normal; Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast( worldGeometry.GetPointer() ); if ( worldPlaneGeometry.IsNotNull() ) { // set up vtkPlane according to worldGeometry point = worldPlaneGeometry->GetOrigin(); normal = worldPlaneGeometry->GetNormal(); normal.Normalize(); m_Plane->SetTransform( (vtkAbstractTransform*)NULL ); } else { itkWarningMacro( << "worldPlaneGeometry is NULL!" ); return ; } vtkFloatingPointType vp[ 3 ], vp_slice[ 3 ], vnormal[ 3 ]; vnl2vtk( point.Get_vnl_vector(), vp ); vnl2vtk( normal.Get_vnl_vector(), vnormal ); //std::cout << "Origin: " << vp[0] <<" "<< vp[1] <<" "<< vp[2] << std::endl; //std::cout << "Normal: " << vnormal[0] <<" "<< vnormal[1] <<" "<< vnormal[2] << std::endl; //normally, we would need to transform the surface and cut the transformed surface with the cutter. //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead. //@todo It probably does not work for scaling operations yet:scaling operations have to be //dealed with after the cut is performed by scaling the contour. vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform(); vtkTransform* world2vtk = vtkTransform::New(); world2vtk->Identity(); world2vtk->Concatenate(vtktransform->GetLinearInverse()); double myscale[3]; world2vtk->GetScale(myscale); world2vtk->PostMultiply(); world2vtk->Scale(1/myscale[0],1/myscale[1],1/myscale[2]); world2vtk->TransformPoint( vp, vp ); world2vtk->TransformNormalAtPoint( vp, vnormal, vnormal ); world2vtk->Delete(); // vtk works in axis align coords // thus the normal also must be axis align, since // we do not allow arbitrary cutting through volume // // vnormal should already be axis align, but in order // to get rid of precision effects, we set the two smaller // components to zero here int dims[3]; vtkImage->GetDimensions(dims); double spac[3]; vtkImage->GetSpacing(spac); vp_slice[0] = vp[0]; vp_slice[1] = vp[1]; vp_slice[2] = vp[2]; if(fabs(vnormal[0]) > fabs(vnormal[1]) && fabs(vnormal[0]) > fabs(vnormal[2]) ) { if(fabs(vp_slice[0]/spac[0]) < 0.4) vp_slice[0] = 0.4*spac[0]; if(fabs(vp_slice[0]/spac[0]) > (dims[0]-1)-0.4) vp_slice[0] = ((dims[0]-1)-0.4)*spac[0]; vnormal[1] = 0; vnormal[2] = 0; } if(fabs(vnormal[1]) > fabs(vnormal[0]) && fabs(vnormal[1]) > fabs(vnormal[2]) ) { if(fabs(vp_slice[1]/spac[1]) < 0.4) vp_slice[1] = 0.4*spac[1]; if(fabs(vp_slice[1]/spac[1]) > (dims[1]-1)-0.4) vp_slice[1] = ((dims[1]-1)-0.4)*spac[1]; vnormal[0] = 0; vnormal[2] = 0; } if(fabs(vnormal[2]) > fabs(vnormal[1]) && fabs(vnormal[2]) > fabs(vnormal[0]) ) { if(fabs(vp_slice[2]/spac[2]) < 0.4) vp_slice[2] = 0.4*spac[2]; if(fabs(vp_slice[2]/spac[2]) > (dims[2]-1)-0.4) vp_slice[2] = ((dims[2]-1)-0.4)*spac[2]; vnormal[0] = 0; vnormal[1] = 0; } m_Plane->SetOrigin( vp_slice ); m_Plane->SetNormal( vnormal ); vtkPolyData* cuttedPlane; if(!( (dims[0] == 1 && vnormal[0] != 0) || (dims[1] == 1 && vnormal[1] != 0) || (dims[2] == 1 && vnormal[2] != 0) )) { m_Cutter->SetCutFunction( m_Plane ); m_Cutter->SetInput( vtkImage ); m_Cutter->GenerateCutScalarsOff();//! m_Cutter->Update(); cuttedPlane = m_Cutter->GetOutput(); } else { // cutting of a 2D-Volume does not work, // so we have to build up our own polydata object cuttedPlane = vtkPolyData::New(); vtkPoints* points = vtkPoints::New(); points->SetNumberOfPoints(vtkImage->GetNumberOfPoints()); for(int i=0; iGetNumberOfPoints(); i++) points->SetPoint(i, vtkImage->GetPoint(i)); cuttedPlane->SetPoints(points); vtkFloatArray* pointdata = vtkFloatArray::New(); int comps = vtkImage->GetPointData()->GetScalars()->GetNumberOfComponents(); pointdata->SetNumberOfComponents(comps); int tuples = vtkImage->GetPointData()->GetScalars()->GetNumberOfTuples(); pointdata->SetNumberOfTuples(tuples); for(int i=0; iSetTuple(i,vtkImage->GetPointData()->GetScalars()->GetTuple(i)); pointdata->SetName( "vector" ); cuttedPlane->GetPointData()->AddArray(pointdata); } if ( cuttedPlane->GetNumberOfPoints() != 0) { // // make sure, that we have point data with more than 1 component (as vectors) // vtkPointData * pointData = cuttedPlane->GetPointData(); if ( pointData == NULL ) { itkWarningMacro( << "no point data associated with cutters result!" ); return ; } if ( pointData->GetNumberOfArrays() == 0 ) { itkWarningMacro( << "point data returned by cutter doesn't have any arrays associated!" ); return ; } else if ( pointData->GetArray(0)->GetNumberOfComponents() <= 1) { itkWarningMacro( << "number of components <= 1!" ); return; } else if ( pointData->GetArrayName( 0 ) == NULL ) { pointData->GetArray( 0 ) ->SetName( "vector" ); //std::cout << "array name = vectors now" << std::endl; } //std::cout << " projecting..."<< std::endl; // // constrain the vectors to lie on the plane, which means to remove the vector component, // which is orthogonal to the plane. // vtkIdType numPoints, pointId; numPoints = cuttedPlane->GetNumberOfPoints(); vtkDataArray* inVectors = cuttedPlane->GetPointData()->GetVectors( "vector" ); assert( inVectors != NULL ); vtkFloatArray* vectorMagnitudes = vtkFloatArray::New(); vectorMagnitudes->SetName("vectorMagnitudes"); vectorMagnitudes->SetNumberOfComponents(1); vectorMagnitudes->SetNumberOfValues(numPoints); vectorMagnitudes->SetNumberOfTuples(numPoints); vtkFloatingPointType inVector[ 3 ], outVector[3], wnormal[3]; //, tmpVector[ 3 ], outVector[ 3 ]; vtkFloatingPointType k = 0.0; vnl2vtk( normal.Get_vnl_vector(), wnormal ); vtkMath::Normalize( wnormal ); bool normalizeVecs; m_DataNode->GetBoolProperty( "NormalizeVecs", normalizeVecs ); for ( pointId = 0; pointId < numPoints; ++pointId ) { inVectors->GetTuple( pointId, inVector ); if(normalizeVecs) { vnl_vector tmp(3); vtk2vnl(inVector, tmp); tmp.normalize(); vnl2vtk(tmp, inVector); } k = vtkMath::Dot( wnormal, inVector ); // Remove non orthogonal component. outVector[ 0 ] = inVector[ 0 ] - ( wnormal[ 0 ] * k ); outVector[ 1 ] = inVector[ 1 ] - ( wnormal[ 1 ] * k ); outVector[ 2 ] = inVector[ 2 ] - ( wnormal[ 2 ] * k ); inVectors->SetTuple( pointId, outVector ); // ?? this was set to norm(inVector) before, but outVector made more sense to me vectorMagnitudes->SetValue( pointId, vtkMath::Norm( outVector ) ); //std::cout << "method old: " << inVector[0] <<", " << inVector[1] << ", "<AddArray(vectorMagnitudes); pointData->CopyAllOn(); //pointData->PrintSelf(std::cout, vtkIndent(4)); //std::cout << " ...done!"<< std::endl; //std::cout << " glyphing..."<< std::endl; // call glyph2D to generate 2D glyphs for each of the // vectors vtkGlyphSource2D* glyphSource = vtkGlyphSource2D::New(); //glyphSource->SetGlyphTypeToDash(); glyphSource->DashOn(); //glyphSource->SetScale( 0.1 ); //glyphSource->SetScale2( .5 ); //glyphSource->SetCenter( 0.5, 0.5, 0.5 ); glyphSource->CrossOff(); //glyphSource->FilledOff(); //glyphSource->Update(); double spacing[3]; vtkImage->GetSpacing(spacing); double min = spacing[0]; min = min > spacing[1] ? spacing[1] : min; min = min > spacing[2] ? spacing[2] : min; float scale = 1; mitk::FloatProperty::Pointer mitkScaleProp = dynamic_cast(GetDataNode()->GetProperty("Scale")); if (mitkScaleProp.IsNotNull()) { scale = mitkScaleProp->GetValue(); } vtkMaskedGlyph3D* glyphGenerator = vtkMaskedGlyph3D::New(); glyphGenerator->SetSource( glyphSource->GetOutput() ); glyphGenerator->SetInputConnection(cuttedPlane->GetProducerPort()); glyphGenerator->SetInputArrayToProcess (1, 0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector"); glyphGenerator->SetVectorModeToUseVector(); glyphGenerator->OrientOn(); glyphGenerator->SetScaleFactor( min*scale ); glyphGenerator->SetUseMaskPoints( true ); glyphGenerator->SetRandomMode( true ); glyphGenerator->SetMaximumNumberOfPoints( 128*128 ); glyphGenerator->Update(); vtkLookupTable* vtkLut = NULL; mitk::LookupTableProperty::Pointer mitkLutProp = dynamic_cast(GetDataNode()->GetProperty("LookupTable")); if (mitkLutProp.IsNotNull()) { vtkLut = mitkLutProp->GetLookupTable()->GetVtkLookupTable(); } mitk::Color color; mitk::ColorProperty::Pointer mitkColorProp = dynamic_cast(GetDataNode()->GetProperty("color")); if (mitkColorProp.IsNotNull()) { color = mitkColorProp->GetColor(); } else { color.SetRed(0); color.SetBlue(1); color.SetGreen(0); } float lwidth = 1; mitk::FloatProperty::Pointer mitkLWidthProp = dynamic_cast(GetDataNode()->GetProperty("LineWidth")); if (mitkLWidthProp.IsNotNull()) { lwidth = mitkLWidthProp->GetValue(); } vtkTransform* trafo = vtkTransform::New(); trafo->Identity(); trafo->Concatenate(vtktransform); trafo->PreMultiply(); double myscale[3]; trafo->GetScale(myscale); trafo->Scale(1/myscale[0],1/myscale[1],1/myscale[2]); this->PaintCells( glyphGenerator->GetOutput(), renderer->GetCurrentWorldGeometry2D(), renderer->GetDisplayGeometry(), trafo, renderer, NULL/*vtkLut*/, color, lwidth, spacing ); vectorMagnitudes->Delete(); glyphSource->Delete(); glyphGenerator->Delete(); trafo->Delete(); } else { std::cout << " no points cutted!"<< std::endl; } //std::cout << "...done!" << std::endl; } void mitk::VectorImageMapper2D::PaintCells( vtkPolyData* glyphs, const Geometry2D* worldGeometry, const DisplayGeometry* displayGeometry, vtkLinearTransform* vtktransform, mitk::BaseRenderer* /*renderer*/, vtkScalarsToColors *lut, mitk::Color color, float lwidth, vtkFloatingPointType *spacing ) { vtkPoints * points = glyphs->GetPoints(); vtkPointData * vpointdata = glyphs->GetPointData(); vtkDataArray* vpointscalars = vpointdata->GetArray("vectorMagnitudes"); //vtkDataArray* vpointpositions = vpointdata->GetArray("pointPositions"); assert(vpointscalars != NULL); //std::cout << " Scalars range 2d:" << vpointscalars->GetRange()[0] << " " << vpointscalars->GetRange()[0] << std::endl; Point3D p; Point2D p2d; vtkIdList* idList; vtkCell* cell; vtkFloatingPointType offset[3]; for (unsigned int i = 0; i < 3; ++i) { offset[i] = 0; } vtkIdType numCells = glyphs->GetNumberOfCells(); for ( vtkIdType cellId = 0; cellId < numCells; ++cellId ) { vtkFloatingPointType vp[ 3 ]; cell = glyphs->GetCell( cellId ); idList = cell->GetPointIds(); int numPoints = idList->GetNumberOfIds(); if(numPoints == 1) { //take transformation via vtktransform into account vtkFloatingPointType pos[ 3 ],vp_raster[3]; points->GetPoint( idList->GetId( 0 ), vp ); vp_raster[0] = vtkMath::Round(vp[0]/spacing[0])*spacing[0]; vp_raster[1] = vtkMath::Round(vp[1]/spacing[1])*spacing[1]; vp_raster[2] = vtkMath::Round(vp[2]/spacing[2])*spacing[2]; vtktransform->TransformPoint( vp_raster, pos ); offset[0] = pos[0] - vp[0]; offset[1] = pos[1] - vp[1]; offset[2] = pos[2] - vp[2]; } else { glLineWidth(lwidth); glBegin ( GL_LINE_LOOP ); for ( int pointNr = 0; pointNr < numPoints ;++pointNr ) { points->GetPoint( idList->GetId( pointNr ), vp ); vp[0] = vp[0] + offset[0]; vp[1] = vp[1] + offset[1]; vp[2] = vp[2] + offset[2]; vtkFloatingPointType tmp[ 3 ]; vtktransform->TransformPoint( vp,tmp ); vtk2itk( vp, p ); //convert 3D point (in mm) to 2D point on slice (also in mm) worldGeometry->Map( p, p2d ); //convert point (until now mm and in worldcoordinates) to display coordinates (units ) displayGeometry->WorldToDisplay( p2d, p2d ); if ( lut != NULL ) { // color each point according to point data vtkFloatingPointType * color; if ( vpointscalars != NULL ) { vpointscalars->GetComponent( pointNr, 0 ); color = lut->GetColor( vpointscalars->GetComponent( idList->GetId( pointNr ), 0 ) ); glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] ); } } else { glColor3f( color.GetRed(), color.GetGreen(), color.GetBlue() ); } //std::cout << idList->GetId( pointNr )<< ": " << p2d[0]<< " "<< p2d[1] << std::endl; //draw the line glVertex2f( p2d[ 0 ], p2d[ 1 ] ); } glEnd (); } } } mitk::VectorImageMapper2D::VectorImageMapper2D() { m_LUT = NULL; m_Plane = vtkPlane::New(); m_Cutter = vtkCutter::New(); m_Cutter->SetCutFunction( m_Plane ); m_Cutter->GenerateValues( 1, 0, 1 ); } mitk::VectorImageMapper2D::~VectorImageMapper2D() { if ( m_LUT != NULL ) m_LUT->Delete(); if ( m_Plane != NULL ) m_Plane->Delete(); if ( m_Cutter != NULL ) m_Cutter->Delete(); } int mitk::VectorImageMapper2D::GetCurrentTimeStep( mitk::BaseData* data, mitk::BaseRenderer* renderer ) { // // get the TimeSlicedGeometry of the input object // const TimeSlicedGeometry * dataTimeGeometry = data->GetUpdatedTimeSlicedGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->GetTimeSteps() == 0 ) ) { itkWarningMacro( << "geometry of the given data object isn't a mitk::TimeSlicedGeometry, or the number of time steps is 0!" ); return 0; } // // get the world time // Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D(); assert( worldGeometry.IsNotNull() ); ScalarType time = worldGeometry->GetTimeBounds() [ 0 ]; // // convert the world time to time steps of the input object // int timestep = 0; if ( time > ScalarTypeNumericTraits::NonpositiveMin() ) timestep = dataTimeGeometry->MSToTimeStep( time ); if ( dataTimeGeometry->IsValidTime( timestep ) == false ) { itkWarningMacro( << timestep << " is not a valid time of the given data object!" ); return 0; } return timestep; } diff --git a/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.h b/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.h index 5f41732e67..28013b1380 100644 --- a/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.h +++ b/Modules/MitkExt/Rendering/mitkVectorImageMapper2D.h @@ -1,93 +1,93 @@ /*=================================================================== 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_VECTOR_IMAGE_MAPPER_2D__H_ #define _MITK_VECTOR_IMAGE_MAPPER_2D__H_ #include "MitkExtExports.h" #include "mitkCommon.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" #include "mitkImage.h" class vtkLookupTable; class vtkScalarsToColors; class vtkImageReslice; class vtkPolyData; class vtkGlyph2D; class vtkPlane; class vtkCutter; namespace mitk { class BaseRenderer; class Geometry2D; class DisplayGeometry; -class MitkExt_EXPORT VectorImageMapper2D : public GLMapper2D +class MitkExt_EXPORT VectorImageMapper2D : public GLMapper { public: - mitkClassMacro( VectorImageMapper2D, GLMapper2D ); + mitkClassMacro( VectorImageMapper2D, GLMapper ); itkNewMacro( Self ); typedef vtkFloatingPointType vtkScalarType; /** * @returns the image held by the associated with the mapper or the image * which has been explicitly set by SetImage(...) */ const mitk::Image * GetInput( void ); virtual void Paint( mitk::BaseRenderer * renderer ); /** * Explicitly set an vector image. This image will be used for * rendering instead of the image returned by GetData() */ itkSetConstObjectMacro( Image, mitk::Image ); /** * Get the explicitly set image * @returns NULL if no Image has been set instead of GetData(); */ itkGetConstObjectMacro( Image, mitk::Image ); virtual void PaintCells( vtkPolyData* contour, const Geometry2D* worldGeometry, const DisplayGeometry* displayGeometry, vtkLinearTransform* vtktransform, BaseRenderer* renderer, vtkScalarsToColors *lut, mitk::Color color, float lwidth, vtkFloatingPointType *spacing ); protected: int GetCurrentTimeStep( mitk::BaseData* data, mitk::BaseRenderer* renderer ); VectorImageMapper2D(); virtual ~VectorImageMapper2D(); mitk::Image::ConstPointer m_Image; vtkLookupTable *m_LUT; vtkPlane* m_Plane; vtkCutter* m_Cutter; }; } // namespace mitk #endif diff --git a/Modules/MitkExt/Testing/mitkDataNodeExtTest.cpp b/Modules/MitkExt/Testing/mitkDataNodeExtTest.cpp index 7cd3a45f9c..5b9dfd95b8 100644 --- a/Modules/MitkExt/Testing/mitkDataNodeExtTest.cpp +++ b/Modules/MitkExt/Testing/mitkDataNodeExtTest.cpp @@ -1,213 +1,213 @@ /*=================================================================== 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 "mitkDataNode.h" #include #include "mitkVtkPropRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" #include //Basedata Test #include #include #include #include #include //Mapper Test #include -#include -#include +#include +#include #include #include #include #include #include #include #include #include //Interactors #include #include #include #include #include //Propertylist Test #include #include #include #include #include #include #include #include #include #include #include /** * Extended test for mitk::DataNode. A number of tests from the core test * mitkDataNodeTest are assumed to pass! */ class mitkDataNodeExtTestClass { public: static void TestDataSetting(mitk::DataNode::Pointer dataNode) { mitk::BaseData::Pointer baseData; //NULL pointer Test dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" ) baseData = mitk::ItkBaseDataAdapter::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ItkBaseDataAdapter object was set correctly" ) baseData = mitk::Mesh::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Mesh object was set correctly" ) baseData = mitk::SeedsImage::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a SeedsImage object was set correctly" ) baseData = mitk::BoundingObject::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a BoundingObject object was set correctly" ) baseData = mitk::UnstructuredGrid::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a UnstructuredGrid object was set correctly" ) } static void TestMapperSetting(mitk::DataNode::Pointer dataNode) { //tests the SetMapper() method //in dataNode is a mapper vector which can be accessed by index //in this test method we use only slot 0 (filled with null) and slot 1 //so we also test the destructor of the mapper classes mitk::Mapper::Pointer mapper; dataNode->SetMapper(0,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" ) mapper = mitk::MeshMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a MeshMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::UnstructuredGridMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a UnstructuredGridMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::LineMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SplineMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SplineMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::MeshVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a MeshVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::UnstructuredGridVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a UnstructuredGridVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) //linker error //mapper = mitk::LineVtkMapper3D::New(); //dataNode->SetMapper(1,mapper); //MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" ) //MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::SplineVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SplineVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) } static void TestInteractorSetting(mitk::DataNode::Pointer dataNode) { //this method tests the SetInteractor() and GetInteractor methods //the Interactor base class calls the DataNode->SetInteractor method mitk::Interactor::Pointer interactor; MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" ) interactor = mitk::ConnectPointsInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a ConnectPointsInteractor was set correctly" ) interactor = mitk::PointInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointInteractor was set correctly" ) interactor = mitk::PointSelectorInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointSelectorInteractor was set correctly" ) interactor = mitk::SeedsInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a SeedsInteractor was set correctly" ) interactor = mitk::DisplayPointSetInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a DisplayPointSetInteractor was set correctly" ) } }; int mitkDataNodeExtTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("DataNode") // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); // let's create an object of our class mitk::DataNode::Pointer myDataNode = mitk::DataNode::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation") //test setData() Method mitkDataNodeExtTestClass::TestDataSetting(myDataNode); mitkDataNodeExtTestClass::TestMapperSetting(myDataNode); //note, that no data is set to the dataNode mitkDataNodeExtTestClass::TestInteractorSetting(myDataNode); // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // always end with this! MITK_TEST_END() } diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp index 6f225b3812..9f77172bcf 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp @@ -1,753 +1,754 @@ /*=================================================================== 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 ) { - if ( !this->IsVisible( renderer ) ) - { - return; - } + + 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 * >( this->GetData() ) ); + 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 - this->ApplyProperties( renderer ); + 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 ); 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) { // 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) { 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 ); } } 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_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->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.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 e7fbe6f388..cac9489522 100644 --- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h +++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.h @@ -1,244 +1,244 @@ /*=================================================================== 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 "mitkGLMapper2D.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 GLMapper2D +class PlanarFigure_EXPORT PlanarFigureMapper2D : public GLMapper { public: - mitkClassMacro(PlanarFigureMapper2D, Mapper2D); + 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; // 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_ */ diff --git a/Modules/Segmentation/Rendering/mitkContourMapper2D.cpp b/Modules/Segmentation/Rendering/mitkContourMapper2D.cpp index 24487e999e..5419d13d24 100644 --- a/Modules/Segmentation/Rendering/mitkContourMapper2D.cpp +++ b/Modules/Segmentation/Rendering/mitkContourMapper2D.cpp @@ -1,129 +1,132 @@ /*=================================================================== 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 "mitkContourMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkContour.h" #include #include "mitkGL.h" mitk::ContourMapper2D::ContourMapper2D() { } mitk::ContourMapper2D::~ContourMapper2D() { } void mitk::ContourMapper2D::Paint(mitk::BaseRenderer * renderer) { - if(IsVisible(renderer)==false) return; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) return; //// @FIXME: Logik fuer update bool updateNeccesary=true; if (updateNeccesary) { mitk::Contour::Pointer input = const_cast(this->GetInput()); // ok, das ist aus GenerateData kopiert mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + ApplyColorAndOpacityProperties(renderer); vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); // Contour::OutputType point; Contour::BoundingBoxType::PointType point; mitk::Point3D p, projected_p; float vtkp[3]; float lineWidth = 3.0; if (dynamic_cast(this->GetDataNode()->GetProperty("Width")) != NULL) lineWidth = dynamic_cast(this->GetDataNode()->GetProperty("Width"))->GetValue(); glLineWidth(lineWidth); if (input->GetClosed()) { glBegin (GL_LINE_LOOP); } else { glBegin (GL_LINE_STRIP); } //Contour::InputType end = input->GetContourPath()->EndOfInput(); //if (end > 50000) end = 0; mitk::Contour::PointsContainerPointer points = input->GetPoints(); mitk::Contour::PointsContainerIterator pointsIt = points->Begin(); while ( pointsIt != points->End() ) { //while ( idx != end ) //{ // point = input->GetContourPath()->Evaluate(idx); point = pointsIt.Value(); itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); bool projectmode=false; GetDataNode()->GetVisibility(projectmode, renderer, "project"); bool drawit=false; if(projectmode) drawit=true; else { Vector3D diff=p-projected_p; if(diff.GetSquaredNorm()<1.0) drawit=true; } if(drawit) { Point2D pt2d, tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); glVertex2f(pt2d[0], pt2d[1]); } pointsIt++; // idx += 1; } glEnd (); glLineWidth(1.0); } } const mitk::Contour* mitk::ContourMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } diff --git a/Modules/Segmentation/Rendering/mitkContourMapper2D.h b/Modules/Segmentation/Rendering/mitkContourMapper2D.h index 82a336128b..66b7875c03 100644 --- a/Modules/Segmentation/Rendering/mitkContourMapper2D.h +++ b/Modules/Segmentation/Rendering/mitkContourMapper2D.h @@ -1,65 +1,65 @@ /*=================================================================== 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_CONTOUR_MAPPER_2D_H_ #define MITK_CONTOUR_MAPPER_2D_H_ #include "mitkCommon.h" #include "SegmentationExports.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class Contour; /** * @brief OpenGL-based mapper to display a mitk::Contour object in a 2D render window * * * @ingroup Mapper */ -class Segmentation_EXPORT ContourMapper2D : public GLMapper2D +class Segmentation_EXPORT ContourMapper2D : public GLMapper { public: - mitkClassMacro(ContourMapper2D, Mapper2D); + mitkClassMacro(ContourMapper2D, GLMapper); itkNewMacro(Self); /** * reimplemented from Baseclass */ virtual void Paint(BaseRenderer * renderer); /** * return a refernce of the rendered data object */ const Contour* GetInput(void); protected: ContourMapper2D(); virtual ~ContourMapper2D(); }; } // namespace mitk #endif /* MITKContourMapper2D_H_HEADER_INCLUDED */ diff --git a/Modules/Segmentation/Rendering/mitkContourSetMapper2D.cpp b/Modules/Segmentation/Rendering/mitkContourSetMapper2D.cpp index 176fed49af..5d6b7abe3d 100644 --- a/Modules/Segmentation/Rendering/mitkContourSetMapper2D.cpp +++ b/Modules/Segmentation/Rendering/mitkContourSetMapper2D.cpp @@ -1,127 +1,130 @@ /*=================================================================== 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 "mitkContourSetMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkContourSet.h" #include "mitkProperties.h" #include #include "mitkGL.h" mitk::ContourSetMapper2D::ContourSetMapper2D() { } mitk::ContourSetMapper2D::~ContourSetMapper2D() { } void mitk::ContourSetMapper2D::Paint(mitk::BaseRenderer * renderer) { - if(IsVisible(renderer)==false) return; + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) return; //// @FIXME: Logik fuer update bool updateNeccesary=true; if (updateNeccesary) { // ok, das ist aus GenerateData kopiert mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList - ApplyProperties(renderer); + ApplyColorAndOpacityProperties(renderer); mitk::ContourSet::Pointer input = const_cast(this->GetInput()); mitk::ContourSet::ContourVectorType contourVec = input->GetContours(); mitk::ContourSet::ContourIterator contourIt = contourVec.begin(); while ( contourIt != contourVec.end() ) { mitk::Contour::Pointer nextContour = (mitk::Contour::Pointer) (*contourIt).second; vtkLinearTransform* transform = GetDataNode()->GetVtkTransform(); // Contour::OutputType point; Contour::BoundingBoxType::PointType point; mitk::Point3D p, projected_p; float vtkp[3]; glLineWidth( nextContour->GetWidth() ); if (nextContour->GetClosed()) { glBegin (GL_LINE_LOOP); } else { glBegin (GL_LINE_STRIP); } //float rgba[4]={1.0f,1.0f,1.0f,1.0f}; //if ( nextContour->GetSelected() ) //{ // rgba[0] = 1.0; // rgba[1] = 0.0; // rgba[2] = 0.0; //} //glColor4fv(rgba); mitk::Contour::PointsContainerPointer points = nextContour->GetPoints(); mitk::Contour::PointsContainerIterator pointsIt = points->Begin(); while ( pointsIt != points->End() ) { point = pointsIt.Value(); itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); Vector3D diff=p-projected_p; if(diff.GetSquaredNorm()<1.0) { Point2D pt2d, tmp; displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); glVertex2f(pt2d[0], pt2d[1]); } pointsIt++; // idx += 1; } glEnd (); glLineWidth(1.0); contourIt++; } } } const mitk::ContourSet* mitk::ContourSetMapper2D::GetInput(void) { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } diff --git a/Modules/Segmentation/Rendering/mitkContourSetMapper2D.h b/Modules/Segmentation/Rendering/mitkContourSetMapper2D.h index ddb0b571da..4088433bee 100644 --- a/Modules/Segmentation/Rendering/mitkContourSetMapper2D.h +++ b/Modules/Segmentation/Rendering/mitkContourSetMapper2D.h @@ -1,65 +1,64 @@ /*=================================================================== 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_CONTOUR_SET_MAPPER_2D_H_ #define MITK_CONTOUR_SET_MAPPER_2D_H_ #include "mitkCommon.h" #include "SegmentationExports.h" -#include "mitkGLMapper2D.h" +#include "mitkGLMapper.h" namespace mitk { class BaseRenderer; class ContourSet; -class BaseRenderer; /** * @brief OpenGL-based mapper to display a mitk::Contour object in a 2D render window * * * @ingroup Mapper */ -class Segmentation_EXPORT ContourSetMapper2D : public GLMapper2D +class Segmentation_EXPORT ContourSetMapper2D : public GLMapper { public: - mitkClassMacro(ContourSetMapper2D, Mapper2D); + mitkClassMacro(ContourSetMapper2D, GLMapper); itkNewMacro(Self); /** * reimplemented from Baseclass */ virtual void Paint(mitk::BaseRenderer * renderer); /** * return a refernce of the rendered data object */ const mitk::ContourSet * GetInput(void); protected: ContourSetMapper2D(); virtual ~ContourSetMapper2D(); }; } // namespace mitk #endif /* MITK_CONTOUR_SET_MAPPER_2D_H_ */ diff --git a/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.cpp b/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.cpp index e618b7e8e8..df216bafa7 100644 --- a/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.cpp +++ b/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.cpp @@ -1,162 +1,166 @@ /*=================================================================== 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 "mitkContourSetVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::ContourSetVtkMapper3D::ContourSetVtkMapper3D() { m_VtkPolyDataMapper = vtkPolyDataMapper::New(); m_Actor = vtkActor::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); m_ContourSet = vtkPolyData::New(); m_TubeFilter = vtkTubeFilter::New(); } mitk::ContourSetVtkMapper3D::~ContourSetVtkMapper3D() { if( m_VtkPolyDataMapper ) m_VtkPolyDataMapper->Delete();; if( m_TubeFilter ) m_TubeFilter->Delete();; if( m_ContourSet ) m_ContourSet->Delete();; if( m_Actor ) m_Actor->Delete();; } vtkProp* mitk::ContourSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Actor; } void mitk::ContourSetVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { - if(IsVisible(renderer)==false) + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if(!visible) { m_Actor->VisibilityOff(); return; } + m_Actor->VisibilityOn(); mitk::ContourSet::Pointer input = const_cast(this->GetInput()); if ( renderer->GetDisplayGeometryUpdateTime() > this->GetInput()->GetMTime() ) { m_ContourSet = vtkPolyData::New(); vtkPoints *points = vtkPoints::New(); vtkCellArray *lines = vtkCellArray::New(); mitk::ContourSet::Pointer input = const_cast(this->GetInput()); mitk::ContourSet::ContourVectorType contourVec = input->GetContours(); mitk::ContourSet::ContourIterator contourIt = contourVec.begin(); vtkIdType firstPointIndex= 0, lastPointIndex=0; vtkIdType ptIndex = 0; while ( contourIt != contourVec.end() ) { mitk::Contour* nextContour = (mitk::Contour*) (*contourIt).second; Contour::InputType idx = nextContour->GetContourPath()->StartOfInput(); Contour::InputType end = nextContour->GetContourPath()->EndOfInput(); if (end > 50000) end = 0; mitk::Contour::PointsContainerPointer contourPoints = nextContour->GetPoints(); mitk::Contour::PointsContainerIterator pointsIt = contourPoints->Begin(); unsigned int counter = 0; firstPointIndex=ptIndex; while ( pointsIt != contourPoints->End() ) { if (counter %2 == 0) { Contour::BoundingBoxType::PointType point; point = pointsIt.Value(); points->InsertPoint(ptIndex, point[0],point[1],point[2]); if (ptIndex > firstPointIndex) { int cell[2] = {ptIndex-1,ptIndex}; lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell); } lastPointIndex=ptIndex; ptIndex++; } pointsIt++; idx+=1; } if (nextContour->GetClosed()) { int cell[2] = {lastPointIndex,firstPointIndex}; lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell); } contourIt++; } m_ContourSet->SetPoints(points); m_ContourSet->SetLines(lines); m_ContourSet->Update(); m_TubeFilter->SetInput(m_ContourSet); m_TubeFilter->SetRadius(1); m_TubeFilter->Update(); m_VtkPolyDataMapper->SetInput(m_TubeFilter->GetOutput()); vtkFloatingPointType rgba[4]={0.0f,1.0f,0.0f,0.6f}; m_Actor->GetProperty()->SetColor(rgba); m_Actor->SetMapper(m_VtkPolyDataMapper); } SetVtkMapperImmediateModeRendering(m_VtkPolyDataMapper); } const mitk::ContourSet* mitk::ContourSetVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } diff --git a/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.h b/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.h index 67b0c7993f..7d83a0ea07 100644 --- a/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.h +++ b/Modules/Segmentation/Rendering/mitkContourSetVtkMapper3D.h @@ -1,69 +1,69 @@ /*=================================================================== 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_CONTOUR_SET_VTK_MAPPER_3D_H #define MITK_CONTOUR_SET_VTK_MAPPER_3D_H #include "mitkCommon.h" #include "SegmentationExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkContourSet.h" #include "mitkBaseRenderer.h" #include class vtkPolyDataMapper; class vtkAppendPolyData; class vtkActor; class vtkTubeFilter; namespace mitk { //##Documentation //## @brief Vtk-based mapper for mitk::Contour //## @ingroup Mapper -class Segmentation_EXPORT ContourSetVtkMapper3D : public VtkMapper3D +class Segmentation_EXPORT ContourSetVtkMapper3D : public VtkMapper { public: - mitkClassMacro(ContourSetVtkMapper3D, VtkMapper3D); + mitkClassMacro(ContourSetVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::ContourSet* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); protected: ContourSetVtkMapper3D(); virtual ~ContourSetVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); vtkPolyDataMapper* m_VtkPolyDataMapper; vtkTubeFilter* m_TubeFilter; vtkPolyData *m_ContourSet; vtkActor *m_Actor; }; } // namespace mitk #endif // MITK_CONTOUR_VTK_MAPPER_3D_H diff --git a/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.cpp b/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.cpp index 482b8be4b5..4a4c5be811 100644 --- a/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.cpp +++ b/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.cpp @@ -1,180 +1,183 @@ /*=================================================================== 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 "mitkContourVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkContour.h" #include #include #include #pragma GCC diagnostic ignored "-Wstrict-aliasing" #include #pragma GCC diagnostic warning "-Wstrict-aliasing" #include #include #include #include #include #include #include #include #include #include mitk::ContourVtkMapper3D::ContourVtkMapper3D() { m_VtkPolyDataMapper = vtkPolyDataMapper::New(); m_VtkPointList = vtkAppendPolyData::New(); m_Actor = vtkActor::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); m_TubeFilter = vtkTubeFilter::New(); } mitk::ContourVtkMapper3D::~ContourVtkMapper3D() { if(m_VtkPolyDataMapper) m_VtkPolyDataMapper->Delete(); if(m_TubeFilter) m_TubeFilter->Delete(); if(m_VtkPointList) m_VtkPointList->Delete(); if(m_Contour) m_Contour->Delete(); if(m_Actor) m_Actor->Delete(); } vtkProp* mitk::ContourVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_Actor; } void mitk::ContourVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { - if ( IsVisible(renderer)==false ) + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) { m_Actor->VisibilityOff(); return; } m_Actor->VisibilityOn(); m_Contour = vtkPolyData::New(); mitk::Contour::Pointer input = const_cast(this->GetInput()); bool makeContour = true; if ( makeContour ) { vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer lines = vtkSmartPointer::New(); int numPts=input->GetNumberOfPoints(); if ( numPts > 200000 ) numPts = 200000; mitk::Contour::PathPointer path = input->GetContourPath(); mitk::Contour::PathType::InputType cstart = path->StartOfInput(); mitk::Contour::PathType::InputType cend = path->EndOfInput(); mitk::Contour::PathType::InputType cstep = (cend-cstart+1)/numPts; mitk::Contour::PathType::InputType ccur; vtkIdType ptIndex = 0; vtkIdType lastPointIndex = 0; mitk::Contour::PointsContainerPointer contourPoints = input->GetPoints(); mitk::Contour::PointsContainerIterator pointsIt = contourPoints->Begin(); vtkFloatingPointType vtkpoint[3]; int i; float pointSize = 2; this->GetDataNode()->GetFloatProperty("spheres size", pointSize); bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); if ( showPoints ) { m_VtkPointList = vtkAppendPolyData::New(); } for ( i=0, ccur=cstart; iEvaluate(ccur), vtkpoint); points->InsertPoint(ptIndex, vtkpoint); if ( ptIndex > 0 ) { int cell[2] = {ptIndex-1,ptIndex}; lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell); } lastPointIndex = ptIndex; ++ptIndex; if ( showPoints ) { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(pointSize); sphere->SetCenter(vtkpoint); m_VtkPointList->AddInput(sphere->GetOutput()); sphere->Update(); } } if ( input->GetClosed() ) { int cell[2] = {lastPointIndex,0}; lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell); } m_Contour->SetPoints(points); m_Contour->SetLines(lines); m_Contour->Update(); m_TubeFilter->SetInput(m_Contour); m_TubeFilter->SetRadius(pointSize / 2.0f); m_TubeFilter->SetNumberOfSides(8); m_TubeFilter->Update(); if ( showPoints ) { m_VtkPointList->AddInput(m_TubeFilter->GetOutput()); m_VtkPolyDataMapper->SetInput(m_VtkPointList->GetOutput()); } else { m_VtkPolyDataMapper->SetInput(m_TubeFilter->GetOutput()); } vtkFloatingPointType rgba[4]={0.0f,1.0f,0.0f,0.6f}; m_Actor->GetProperty()->SetColor(rgba); m_Actor->SetMapper(m_VtkPolyDataMapper); } SetVtkMapperImmediateModeRendering(m_VtkPolyDataMapper); } const mitk::Contour* mitk::ContourVtkMapper3D::GetInput() { - return static_cast ( GetData() ); + return static_cast ( GetDataNode()->GetData() ); } diff --git a/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.h b/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.h index 5e97c98651..5d14be787c 100644 --- a/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.h +++ b/Modules/Segmentation/Rendering/mitkContourVtkMapper3D.h @@ -1,68 +1,68 @@ /*=================================================================== 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_CONTOUR_VTK_MAPPER_3D_H #define MITK_CONTOUR_VTK_MAPPER_3D_H #include "SegmentationExports.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include #include class vtkPolyDataMapper; class vtkAppendPolyData; class vtkActor; class vtkTubeFilter; namespace mitk { class BaseRenderer; class Contour; /** @brief Vtk-based mapper for mitk::Contour @ingroup Mapper */ -class Segmentation_EXPORT ContourVtkMapper3D : public VtkMapper3D +class Segmentation_EXPORT ContourVtkMapper3D : public VtkMapper { public: - mitkClassMacro(ContourVtkMapper3D, VtkMapper3D); + mitkClassMacro(ContourVtkMapper3D, VtkMapper); itkNewMacro(Self); virtual const mitk::Contour* GetInput(); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); protected: ContourVtkMapper3D(); virtual ~ContourVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); vtkSmartPointer m_VtkPolyDataMapper; vtkSmartPointer m_TubeFilter; vtkSmartPointer m_VtkPointList; vtkSmartPointer m_Contour; vtkSmartPointer m_Actor; }; } // namespace mitk #endif // MITK_CONTOUR_VTK_MAPPER_3D_H diff --git a/Modules/Segmentation/Testing/mitkDataNodeSegmentationTest.cpp b/Modules/Segmentation/Testing/mitkDataNodeSegmentationTest.cpp index ce31fb59ab..f4a654d6f6 100644 --- a/Modules/Segmentation/Testing/mitkDataNodeSegmentationTest.cpp +++ b/Modules/Segmentation/Testing/mitkDataNodeSegmentationTest.cpp @@ -1,164 +1,164 @@ /*=================================================================== 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 "mitkDataNode.h" #include #include "mitkVtkPropRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" #include //Basedata Test #include #include #include //Mapper Test #include -#include -#include +#include +#include #include #include #include #include //Interactors #include #include #include //Propertylist Test #include #include #include #include #include #include #include #include #include #include #include /** * Extended test for mitk::DataNode. A number of tests from the core test * mitkDataNodeTest are assumed to pass! */ class mitkDataNodeSegmentationTestClass { public: static void TestDataSetting(mitk::DataNode::Pointer dataNode) { mitk::BaseData::Pointer baseData; //NULL pointer Test dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" ) baseData = mitk::Contour::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Contour object was set correctly" ) baseData = mitk::ContourSet::New(); dataNode->SetData(baseData); MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ContourSet object was set correctly" ) } static void TestMapperSetting(mitk::DataNode::Pointer dataNode) { //tests the SetMapper() method //in dataNode is a mapper vector which can be accessed by index //in this test method we use only slot 0 (filled with null) and slot 1 //so we also test the destructor of the mapper classes mitk::Mapper::Pointer mapper; dataNode->SetMapper(0,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" ) mapper = mitk::ContourMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ContourMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::ContourSetMapper2D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ContourSetMapper2D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) //3D Mappers mapper = mitk::ContourSetVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ContourSetVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) mapper = mitk::ContourVtkMapper3D::New(); dataNode->SetMapper(1,mapper); MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ContourVtkMapper3D was set correctly" ) MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" ) } static void TestInteractorSetting(mitk::DataNode::Pointer dataNode) { //this method tests the SetInteractor() and GetInteractor methods //the Interactor base class calls the DataNode->SetInteractor method mitk::Interactor::Pointer interactor; MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" ) interactor = mitk::ContourInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a ContourInteractor was set correctly" ) interactor = mitk::ExtrudedContourInteractor::New("AffineInteractions click to select", dataNode); MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a ExtrudedContourInteractor was set correctly" ) } }; int mitkDataNodeSegmentationTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("DataNode") // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); // let's create an object of our class mitk::DataNode::Pointer myDataNode = mitk::DataNode::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation") //test setData() Method mitkDataNodeSegmentationTestClass::TestDataSetting(myDataNode); mitkDataNodeSegmentationTestClass::TestMapperSetting(myDataNode); //note, that no data is set to the dataNode mitkDataNodeSegmentationTestClass::TestInteractorSetting(myDataNode); // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // always end with this! MITK_TEST_END() } diff --git a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp index 15d1ef52a7..016e4cbfa2 100644 --- a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp +++ b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.cpp @@ -1,506 +1,506 @@ /*=================================================================== 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 "mitkToFSurfaceVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkLookupTableProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkClippingProperty.h" #include "mitkShaderProperty.h" #include "mitkShaderRepository.h" #include #include #include #include #include #include #include #include #include #include #include //const mitk::ToFSurface* mitk::ToFSurfaceVtkMapper3D::GetInput() const mitk::Surface* mitk::ToFSurfaceVtkMapper3D::GetInput() { //return static_cast ( GetData() ); return static_cast ( GetData() ); } mitk::ToFSurfaceVtkMapper3D::ToFSurfaceVtkMapper3D() { // m_Prop3D = vtkActor::New(); m_GenerateNormals = false; this->m_Texture = NULL; this->m_TextureWidth = 0; this->m_TextureHeight = 0; this->m_VtkScalarsToColors = NULL; } mitk::ToFSurfaceVtkMapper3D::~ToFSurfaceVtkMapper3D() { // m_Prop3D->Delete(); } void mitk::ToFSurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool visible = IsVisible(renderer); if(visible==false) { ls->m_Actor->VisibilityOff(); return; } // // set the input-object at time t for the mapper // //mitk::ToFSurface::Pointer input = const_cast< mitk::ToFSurface* >( this->GetInput() ); mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); if(polydata == NULL) { ls->m_Actor->VisibilityOff(); return; } if ( m_GenerateNormals ) { ls->m_VtkPolyDataNormals->SetInput( polydata ); ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); } else { ls->m_VtkPolyDataMapper->SetInput( polydata ); } // // apply properties read from the PropertyList // ApplyProperties(ls->m_Actor, renderer); if(visible) ls->m_Actor->VisibilityOn(); // // TOF extension for visualization (color/texture mapping) // if (this->m_VtkScalarsToColors) { // set the color transfer funtion if applied ls->m_VtkPolyDataMapper->SetLookupTable(this->m_VtkScalarsToColors); } if (this->m_Texture) { ls->m_Actor->SetTexture(this->m_Texture); } else { // remove the texture ls->m_Actor->SetTexture(0); } } void mitk::ToFSurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } void mitk::ToFSurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer) { // Colors { double ambient [3] = { 0.5,0.5,0.0 }; double diffuse [3] = { 0.5,0.5,0.0 }; double specular[3] = { 1.0,1.0,1.0 }; float coeff_ambient = 0.5f; float coeff_diffuse = 0.5f; float coeff_specular= 0.5f; float power_specular=10.0f; // Color { mitk::ColorProperty::Pointer p; node->GetProperty(p, "color", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); // Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different. specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.ambientColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); } } // Diffuse { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.diffuseColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); } } // Specular { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.specularColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient coeff { node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer); } // Diffuse coeff { node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer); } // Specular coeff { node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer); } // Specular power { node->GetFloatProperty("material.specularPower", power_specular, renderer); } property->SetAmbient( coeff_ambient ); property->SetDiffuse( coeff_diffuse ); property->SetSpecular( coeff_specular ); property->SetSpecularPower( power_specular ); property->SetAmbientColor( ambient ); property->SetDiffuseColor( diffuse ); property->SetSpecularColor( specular ); } // Render mode { // Opacity { float opacity = 1.0f; if( node->GetOpacity(opacity,renderer) ) property->SetOpacity( opacity ); } // Wireframe line width { float lineWidth = 1; node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer); property->SetLineWidth( lineWidth ); } // Representation { mitk::VtkRepresentationProperty::Pointer p; node->GetProperty(p, "material.representation", renderer); if(p.IsNotNull()) property->SetRepresentation( p->GetVtkRepresentation() ); } // Interpolation { mitk::VtkInterpolationProperty::Pointer p; node->GetProperty(p, "material.interpolation", renderer); if(p.IsNotNull()) property->SetInterpolation( p->GetVtkInterpolation() ); } } } void mitk::ToFSurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Applying shading properties { - Superclass::ApplyProperties( ls->m_Actor, renderer ) ; + ApplyColorAndOpacityProperties( ls->m_Actor, renderer ) ; // VTK Properties ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer ); // Shaders mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate); } mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } mitk::LevelWindow levelWindow; if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow")) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } else if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer)) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) ); if(scalarVisibility) { mitk::VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); } else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) ); float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 1.0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); } // deprecated settings bool deprecatedUseCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData); bool deprecatedUsePointData = false; this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData); if (deprecatedUseCellData) { ls->m_VtkPolyDataMapper->SetColorModeToDefault(); ls->m_VtkPolyDataMapper->SetScalarRange(0,255); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } else if (deprecatedUsePointData) { float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 0.1; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); ls->m_VtkPolyDataMapper->SetColorModeToMapScalars(); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT; if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); //m_Actor->GetProperty()->SetInterpolationToPhong(); } // Check whether one or more ClippingProperty objects have been defined for // this node. Check both renderer specific and global property lists, since // properties in both should be considered. const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); // Add clipping planes (if any) ls->m_ClippingPlaneCollection->RemoveAllItems(); PropertyList::PropertyMap::const_iterator it; for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) { this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 ) { ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection ); } else { ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes(); } } vtkProp *mitk::ToFSurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_Actor; } void mitk::ToFSurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // m_Prop3D = ls->m_Actor; ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property ); if ( (clippingProperty != NULL) && (clippingProperty->GetClippingEnabled()) ) { const Point3D &origin = clippingProperty->GetOrigin(); const Vector3D &normal = clippingProperty->GetNormal(); vtkPlane *clippingPlane = vtkPlane::New(); clippingPlane->SetOrigin( origin[0], origin[1], origin[2] ); clippingPlane->SetNormal( normal[0], normal[1], normal[2] ); ls->m_ClippingPlaneCollection->AddItem( clippingPlane ); clippingPlane->UnRegister( NULL ); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // Shading { node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite ); node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite ); node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite ); //node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite ); node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite ); } // Shaders { mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite); } } void mitk::ToFSurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); mitk::ToFSurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite ); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0)) { node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::ToFSurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/) { /* if (m_VtkPolyDataMapper != NULL) m_VtkPolyDataMapper->SetImmediateModeRendering(on); */ } void mitk::ToFSurfaceVtkMapper3D::SetTexture(vtkImageData *img) { this->m_Texture = vtkSmartPointer::New(); this->m_Texture->SetInput(img); // MITK_INFO << "Neuer Code"; } vtkSmartPointer mitk::ToFSurfaceVtkMapper3D::GetTexture() { return this->m_Texture; } void mitk::ToFSurfaceVtkMapper3D::SetVtkScalarsToColors(vtkScalarsToColors* vtkScalarsToColors) { this->m_VtkScalarsToColors = vtkScalarsToColors; } vtkScalarsToColors* mitk::ToFSurfaceVtkMapper3D::GetVtkScalarsToColors() { return this->m_VtkScalarsToColors; } diff --git a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h index e237607cd9..960833158f 100644 --- a/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h +++ b/Modules/ToFProcessing/mitkToFSurfaceVtkMapper3D.h @@ -1,186 +1,186 @@ /*=================================================================== 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 MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #define MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 #include "mitkCommon.h" -#include "mitkVtkMapper3D.h" +#include "mitkVtkMapper.h" #include "mitkSurface.h" #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include #include #include "mitkToFProcessingExports.h" namespace mitk { //##Documentation //## @brief Vtk-based mapper for Surface //## //## @ingroup Mapper /** * @brief Vtk-based mapper for Surface * * Properties that can be set for surfaces and influence the surfaceVTKMapper3D are: * * - \b "color": (ColorProperty) Diffuse color of the surface object (this property will be read when material.diffuseColor is not defined) * - \b "Opacity": (FloatProperty) Opacity of the surface object * - \b "material.ambientColor": (ColorProperty) Ambient color of the surface object * - \b "material.ambientCoefficient": ( FloatProperty) Ambient coefficient of the surface object * - \b "material.diffuseColor": ( ColorProperty) Diffuse color of the surface object * - \b "material.diffuseCoefficient": (FloatProperty) Diffuse coefficient of the surface object * - \b "material.specularColor": (ColorProperty) Specular Color of the surface object * - \b "material.specularCoefficient": (FloatProperty) Specular coefficient of the surface object * - \b "material.specularPower": (FloatProperty) Specular power of the surface object * - \b "material.interpolation": (VtkInterpolationProperty) Interpolation * - \b "material.representation": (VtkRepresentationProperty*) Representation * - \b "material.wireframeLineWidth": (FloatProperty) Width in pixels of the lines drawn. * - \b "scalar visibility": (BoolProperty) If the scarlars of the surface are visible * Properties to look for are: * * - \b "scalar visibility": if set to on, scalars assigned to the data are shown * Turn this on if using a lookup table. * - \b "ScalarsRangeMinimum": Optional. Can be used to store the scalar min, e.g. * for the level window settings. * - \b "ScalarsRangeMaximum": Optional. See above. * * There might be still some other, deprecated properties. These will not be documented anymore. * Please check the source if you really need them. * * @ingroup Mapper */ -class mitkToFProcessing_EXPORT ToFSurfaceVtkMapper3D : public VtkMapper3D +class mitkToFProcessing_EXPORT ToFSurfaceVtkMapper3D : public VtkMapper { public: - mitkClassMacro(ToFSurfaceVtkMapper3D, VtkMapper3D); + mitkClassMacro(ToFSurfaceVtkMapper3D, VtkMapper); itkNewMacro(Self); itkSetMacro(GenerateNormals, bool); itkGetMacro(GenerateNormals, bool); //enable ImmediateModeRendering for vtkMapping //yet to solve bug 1398 void SetImmediateModeRenderingOn(int on = 1); itkGetMacro(ImmediateModeRenderingOn, int); //virtual const mitk::ToFSurface* GetInput(); virtual const mitk::Surface* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer); static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); void SetTexture(vtkImageData *img); vtkSmartPointer GetTexture(); itkSetMacro(TextureWidth, int); itkSetMacro(TextureHeight, int); void SetVtkScalarsToColors(vtkScalarsToColors* vtkScalarsToColors); vtkScalarsToColors* GetVtkScalarsToColors(); protected: ToFSurfaceVtkMapper3D(); virtual ~ToFSurfaceVtkMapper3D(); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void ResetMapper( mitk::BaseRenderer* renderer ); /** Checks whether the specified property is a ClippingProperty and if yes, * adds it to m_ClippingPlaneCollection (internal method). */ virtual void CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ); bool m_GenerateNormals; //enable ImmediateModeRendering for the vtkMapper int m_ImmediateModeRenderingOn; vtkSmartPointer m_Texture; // pointer to the texture/video image int m_TextureWidth; // width of the texture/video image int m_TextureHeight; // height of the texture/video image vtkScalarsToColors* m_VtkScalarsToColors; // vtk color transfer funtion public: class LocalStorage : public mitk::Mapper::BaseLocalStorage { public: vtkActor* m_Actor; vtkPolyDataMapper *m_VtkPolyDataMapper; vtkPolyDataNormals *m_VtkPolyDataNormals; vtkPlaneCollection *m_ClippingPlaneCollection; itk::TimeStamp m_ShaderTimestampUpdate; LocalStorage() { m_VtkPolyDataMapper = vtkOpenGLPolyDataMapper::New(); m_VtkPolyDataNormals = vtkPolyDataNormals::New(); m_Actor = vtkActor::New(); m_ClippingPlaneCollection = vtkPlaneCollection::New(); m_Actor->SetMapper(m_VtkPolyDataMapper); } ~LocalStorage() { m_VtkPolyDataMapper->Delete(); m_VtkPolyDataNormals->Delete(); m_Actor->Delete(); m_ClippingPlaneCollection->Delete(); } }; mitk::Mapper::LocalStorageHandler m_LSH; static void ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer); static void SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite); }; } // namespace mitk #endif /* MITKTOFSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 */