diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp index 63b8c33045..1b8f763fab 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp @@ -1,191 +1,211 @@ #include "mitkClippedSurfaceBoundsCalculator.h" -#include "vtkPolyData.h" -#include "vtkPlaneSource.h" -#include "vtkPPolyDataNormals.h" -#include "mitkGeometry2D.h" -#include "mitkSliceNavigationController.h" #include "mitkLine.h" -#include "vtkSmartPointer.h" #define ROUND_P(x) ((int)((x)+0.5)) -mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image) +mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator( + const mitk::PlaneGeometry* geometry, + mitk::Image::Pointer image) { + // initialize with meaningless slice indices + m_MinMaxOutput.clear(); + for(int i = 0; i < 3; i++) + { + m_MinMaxOutput.push_back( + OutputType( std::numeric_limits::max() , + std::numeric_limits::min() )); + } + + this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::~ClippedSurfaceBoundsCalculator() { } -void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image) +void +mitk::ClippedSurfaceBoundsCalculator::SetInput( + const mitk::PlaneGeometry* geometry, + mitk::Image* image) { - if(geometry != NULL && image.IsNotNull()) + if(geometry && image) { this->m_PlaneGeometry = geometry; this->m_Image = image; } } -mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() +mitk::ClippedSurfaceBoundsCalculator::OutputType +mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() { return this->m_MinMaxOutput[0]; } -mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() +mitk::ClippedSurfaceBoundsCalculator::OutputType +mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() { return this->m_MinMaxOutput[1]; } -mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() +mitk::ClippedSurfaceBoundsCalculator::OutputType +mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() { return this->m_MinMaxOutput[2]; } void mitk::ClippedSurfaceBoundsCalculator::Update() { + // SEE HEADER DOCUMENTATION for explanation + typedef std::vector< std::pair > EdgesVector; this->m_MinMaxOutput.clear(); for(int i = 0; i < 3; i++) { this->m_MinMaxOutput.push_back(OutputType( std::numeric_limits::max() , std::numeric_limits::min() )); } Point3D origin; Vector3D xDirection, yDirection, zDirection; const Vector3D spacing = m_Image->GetGeometry()->GetSpacing(); origin = m_Image->GetGeometry()->GetOrigin(); //Left, bottom, front //Get axis vector for the spatial directions xDirection = m_Image->GetGeometry()->GetAxisVector(1); yDirection = m_Image->GetGeometry()->GetAxisVector(0); zDirection = m_Image->GetGeometry()->GetAxisVector(2); - /* For the calculation of the intersection points we need as corner points the center-based image coordinates. + /* + * For the calculation of the intersection points we need as corner points the center-based image coordinates. * With the method GetCornerPoint() of the class Geometry3D we only get the corner-based coordinates. * Therefore we need to calculate the center-based corner points here. For that we add/substract the corner- * based coordinates with the spacing of the geometry3D. */ for( int i = 0; i < 3; i++ ) { if(xDirection[i] < 0) { xDirection[i] += spacing[i]; } else if( xDirection[i] > 0 ) { xDirection[i] -= spacing[i]; } if(yDirection[i] < 0) { yDirection[i] += spacing[i]; } else if( yDirection[i] > 0 ) { yDirection[i] -= spacing[i]; } if(zDirection[i] < 0) { zDirection[i] += spacing[i]; } else if( zDirection[i] > 0 ) { zDirection[i] -= spacing[i]; } } - Point3D LeftTopFront, LeftBottomBack, LeftTopBack; - Point3D RightBottomFront, RightTopFront, RightBottomBack, RightTopBack; + Point3D leftBottomFront, leftTopFront, leftBottomBack, leftTopBack; + Point3D rightBottomFront, rightTopFront, rightBottomBack, rightTopBack; - LeftTopFront = origin + yDirection; - LeftBottomBack = origin + zDirection; - LeftTopBack = origin + yDirection + zDirection; - RightBottomFront = origin + xDirection; - RightTopFront = origin + xDirection + yDirection; - RightBottomBack = origin + xDirection + zDirection; - RightTopBack = origin + xDirection + yDirection + zDirection; + leftBottomFront = origin; + leftTopFront = origin + yDirection; + leftBottomBack = origin + zDirection; + leftTopBack = origin + yDirection + zDirection; + rightBottomFront = origin + xDirection; + rightTopFront = origin + xDirection + yDirection; + rightBottomBack = origin + xDirection + zDirection; + rightTopBack = origin + xDirection + yDirection + zDirection; EdgesVector edgesOf3DBox; - // connections/edges from origin - edgesOf3DBox.push_back(std::make_pair(origin, // x = left=xfront, y=bottom=yfront, z=front=zfront - LeftTopFront)); // left, top, front + edgesOf3DBox.push_back(std::make_pair(leftBottomBack, // x = left=xfront, y=bottom=yfront, z=front=zfront + leftTopFront)); // left, top, front - edgesOf3DBox.push_back(std::make_pair(origin, // left, bottom, front - LeftBottomBack)); // left, bottom, back + edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front + leftBottomBack)); // left, bottom, back - edgesOf3DBox.push_back(std::make_pair(origin, // left, bottom, front - RightBottomFront)); // right, bottom, front + edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front + rightBottomFront)); // right, bottom, front - edgesOf3DBox.push_back(std::make_pair(LeftTopFront, // left, top, front - RightTopFront)); // right, top, front + edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front + rightTopFront)); // right, top, front - edgesOf3DBox.push_back(std::make_pair(LeftTopFront, // left, top, front - LeftTopBack)); // left, top, back + edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front + leftTopBack)); // left, top, back - edgesOf3DBox.push_back(std::make_pair(RightTopFront, // right, top, front - RightTopBack)); // right, top, back + edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front + rightTopBack)); // right, top, back - edgesOf3DBox.push_back(std::make_pair(RightTopFront, // right, top, front - RightBottomFront)); // right, bottom, front + edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front + rightBottomFront)); // right, bottom, front - edgesOf3DBox.push_back(std::make_pair(RightBottomFront, // right, bottom, front - RightBottomBack)); // right, bottom, back + edgesOf3DBox.push_back(std::make_pair(rightBottomFront, // right, bottom, front + rightBottomBack)); // right, bottom, back - edgesOf3DBox.push_back(std::make_pair(RightBottomBack, // right, bottom, back - LeftBottomBack)); // left, bottom, back + edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back + leftBottomBack)); // left, bottom, back - edgesOf3DBox.push_back(std::make_pair(RightBottomBack, // right, bottom, back - RightTopBack)); // right, top, back + edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back + rightTopBack)); // right, top, back - edgesOf3DBox.push_back(std::make_pair(RightTopBack, // right, top, back - LeftTopBack)); // left, top, back + edgesOf3DBox.push_back(std::make_pair(rightTopBack, // right, top, back + leftTopBack)); // left, top, back - edgesOf3DBox.push_back(std::make_pair(LeftTopBack, // left, top, back - LeftBottomBack)); // left, bottom, back + edgesOf3DBox.push_back(std::make_pair(leftTopBack, // left, top, back + leftBottomBack)); // left, bottom, back for (EdgesVector::iterator iterator = edgesOf3DBox.begin(); iterator != edgesOf3DBox.end();iterator++) { Point3D startPoint = (*iterator).first; // start point of the line Point3D endPoint = (*iterator).second; // end point of the line Vector3D lineDirection = endPoint - startPoint; mitk::Line3D line(startPoint, lineDirection); Point3D intersectionWorldPoint; intersectionWorldPoint.Fill(std::numeric_limits::min()); - m_PlaneGeometry->IntersectionPoint(line, intersectionWorldPoint); // Get intersection point of line and plane geometry + // Get intersection point of line and plane geometry + m_PlaneGeometry->IntersectionPoint(line, intersectionWorldPoint); double t = -1.0; bool isIntersectionPointOnLine; isIntersectionPointOnLine = m_PlaneGeometry->IntersectionPointParam(line, t); mitk::Point3D intersectionIndexPoint; - m_Image->GetGeometry()->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); //Get index point + //Get index point + m_Image->GetGeometry()->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); if(0.0 <= t && t <= 1.0 && isIntersectionPointOnLine) { for(int dim = 0; dim < 3; dim++) { // minimum - if( this->m_MinMaxOutput[dim].first > ROUND_P(intersectionIndexPoint[dim]) ) //If new point value is lower than old + //If new point value is lower than old + if( this->m_MinMaxOutput[dim].first > ROUND_P(intersectionIndexPoint[dim]) ) { this->m_MinMaxOutput[dim].first = ROUND_P(intersectionIndexPoint[dim]); //set new value } // maximum - if( this->m_MinMaxOutput[dim].second < ROUND_P(intersectionIndexPoint[dim]) ) //If new point value is higher than old + //If new point value is higher than old + if( this->m_MinMaxOutput[dim].second < ROUND_P(intersectionIndexPoint[dim]) ) { this->m_MinMaxOutput[dim].second = ROUND_P(intersectionIndexPoint[dim]); //set new value } } } } } + diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h index 83098c127b..89201b1520 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h @@ -1,49 +1,102 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Module: $RCSfile: mitkPropertyManager.cpp,v $ +Language: C++ +Date: $Date: 2005/06/28 12:37:25 $ +Version: $Revision: 1.12 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + #ifndef ClippedSurfaceBoundsCalculator_h_included #define ClippedSurfaceBoundsCalculator_h_included -#include "mitkGeometry2DData.h" #include "mitkImage.h" -#include "mitkGeometry2DDataToSurfaceFilter.h" -#include "mitkSlicedGeometry3D.h" -#include "mitkSliceNavigationController.h" -#include "mitkCommon.h" -#include "vtkPoints.h" -#include "mitkVector.h" - +#include "mitkPlaneGeometry.h" +#include /** - * \brief Class to find + * \brief Find image slices visible on a given plane. + * + * The class name is not helpful in finding this class. Good suggestions welcome. * -*/ + * Given a PlaneGeometry (e.g. the 2D plane of a render window), this class + * calculates which slices of an mitk::Image are visible on this plane. + * Calculation is done for X, Y, and Z direction, the result is available in + * form of a pair (minimum,maximum) slice index. + * + * Such calculations are useful if you want to display information about the + * currently visible slice (overlays, statistics, ...) and you don't want to + * depend on any prior information about hat the renderwindow is currently showing. + * + * \warning The interface attempts to look like an ITK filter but it is far from being one. + */ namespace mitk { class MITK_CORE_EXPORT ClippedSurfaceBoundsCalculator { public: - ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry = NULL, mitk::Image::Pointer image = NULL); + + ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry = NULL, + mitk::Image::Pointer image = NULL); virtual ~ClippedSurfaceBoundsCalculator(); - void SetInput(const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image); + void SetInput(const mitk::PlaneGeometry* geometry, mitk::Image* image); + + /** + \brief Request calculation. + + How cut/visible slice indices are determined: + 1. construct a bounding box of the image. This is the box that connect the outer voxel centers(!). + 2. check the edges of this box. + 3. intersect each edge with the plane geometry + - if the intersection point is within the image box, + we update the visible/cut slice indices for all dimensions. + - else we ignore the cut + */ void Update(); + /** + \brief Minimum (first) and maximum (second) slice index. + */ typedef std::pair OutputType; + /** + \brief What X coordinates (slice indices) are cut/visible in given plane. + */ OutputType GetMinMaxSpatialDirectionX(); + + /** + \brief What Y coordinates (slice indices) are cut/visible in given plane. + */ OutputType GetMinMaxSpatialDirectionY(); + + /** + \brief What Z coordinates (slice indices) are cut/visible in given plane. + */ OutputType GetMinMaxSpatialDirectionZ(); protected: - const mitk::PlaneGeometry* m_PlaneGeometry; + + mitk::PlaneGeometry::ConstPointer m_PlaneGeometry; mitk::Image::Pointer m_Image; std::vector< OutputType > m_MinMaxOutput; }; } //namespace mitk -#endif +#endif