diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp index cca9836a7f..63b8c33045 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp @@ -1,150 +1,191 @@ #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) { this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::~ClippedSurfaceBoundsCalculator() { } void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image) { if(geometry != NULL && image.IsNotNull()) { - this->m_Geometry2D = geometry; + this->m_PlaneGeometry = geometry; this->m_Image = image; - 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() )); - } } } -void mitk::ClippedSurfaceBoundsCalculator::CalculateSurfaceBounds() +mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() { + return this->m_MinMaxOutput[0]; +} - //Get the corner points of the geometry3D - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, false, false) - , m_Image->GetGeometry()->GetCornerPoint(true, false, false)); +mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() +{ + return this->m_MinMaxOutput[1]; +} - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, false, false) - , m_Image->GetGeometry()->GetCornerPoint(false, true, false)); +mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() +{ + return this->m_MinMaxOutput[2]; +} - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, false, false) - , m_Image->GetGeometry()->GetCornerPoint(false, false, true)); +void mitk::ClippedSurfaceBoundsCalculator::Update() +{ + typedef std::vector< std::pair > EdgesVector; - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, true, false) - , m_Image->GetGeometry()->GetCornerPoint(true, true, false)); + 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() )); + } - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, true, false) - , m_Image->GetGeometry()->GetCornerPoint(false, true, true)); + Point3D origin; + Vector3D xDirection, yDirection, zDirection; + const Vector3D spacing = m_Image->GetGeometry()->GetSpacing(); - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, false, true) - , m_Image->GetGeometry()->GetCornerPoint(true, false, true)); + origin = m_Image->GetGeometry()->GetOrigin(); //Left, bottom, front - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, false, true) - , m_Image->GetGeometry()->GetCornerPoint(false, true, true)); + //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); - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(false, true, true) - , m_Image->GetGeometry()->GetCornerPoint(true, true, true)); + /* 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]; + } - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(true, false, true) - , m_Image->GetGeometry()->GetCornerPoint(true, true, true)); + if(yDirection[i] < 0) + { + yDirection[i] += spacing[i]; + } + else if( yDirection[i] > 0 ) + { + yDirection[i] -= spacing[i]; + } - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(true, false, false) - , m_Image->GetGeometry()->GetCornerPoint(true, false, true)); + if(zDirection[i] < 0) + { + zDirection[i] += spacing[i]; + } + else if( zDirection[i] > 0 ) + { + zDirection[i] -= spacing[i]; + } + } - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(true, false, false) - , m_Image->GetGeometry()->GetCornerPoint(true, true, false)); + Point3D LeftTopFront, LeftBottomBack, LeftTopBack; + Point3D RightBottomFront, RightTopFront, RightBottomBack, RightTopBack; - CalculateSurfaceBounds( m_Image->GetGeometry()->GetCornerPoint(true, true, false) - , m_Image->GetGeometry()->GetCornerPoint(true, true, true)); -} + 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; -void mitk::ClippedSurfaceBoundsCalculator::CalculateSurfaceBounds(Point3D startPoint, Point3D endPoint) -{ - if(this->GetIntersectionPoint(startPoint, endPoint) != NULL) - { - mitk::Point3D* point3D = this->GetIntersectionPoint(startPoint, endPoint); - mitk::Point3D indexPoint3D; - m_Image->GetGeometry()->WorldToIndex(*point3D, indexPoint3D); + EdgesVector edgesOf3DBox; - for(int dim = 0; dim < 3; dim++) - { - // minimum - if(this->m_MinMaxOutput[dim].first > ROUND_P(indexPoint3D[dim])) - { - this->m_MinMaxOutput[dim].first = ROUND_P(indexPoint3D[dim]); - } + // connections/edges from origin + edgesOf3DBox.push_back(std::make_pair(origin, // x = left=xfront, y=bottom=yfront, z=front=zfront + LeftTopFront)); // left, top, front - // maximum - if(this->m_MinMaxOutput[dim].second < ROUND_P(indexPoint3D[dim])) - { - this->m_MinMaxOutput[dim].second = ROUND_P(indexPoint3D[dim]); - } - } - delete point3D; - } + edgesOf3DBox.push_back(std::make_pair(origin, // left, bottom, front + LeftBottomBack)); // left, bottom, back -// } -} + edgesOf3DBox.push_back(std::make_pair(origin, // left, bottom, front + RightBottomFront)); // right, bottom, front -mitk::Point3D* mitk::ClippedSurfaceBoundsCalculator::GetIntersectionPoint(Point3D startPoint, Point3D endPoint) -{ - Point3D* intersectionPoint = new Point3D(); - vtkSmartPointer points = vtkPoints::New(); - points->SetNumberOfPoints(1); + edgesOf3DBox.push_back(std::make_pair(LeftTopFront, // left, top, front + RightTopFront)); // right, top, front - endPoint[0] =- startPoint[0]; - endPoint[1] =- startPoint[1]; - endPoint[2] =- startPoint[2]; + edgesOf3DBox.push_back(std::make_pair(LeftTopFront, // left, top, front + LeftTopBack)); // left, top, back - Vector3D bottomVec; + edgesOf3DBox.push_back(std::make_pair(RightTopFront, // right, top, front + RightTopBack)); // right, top, back - FillVector3D(bottomVec, endPoint[0], endPoint[1], endPoint[2]); + edgesOf3DBox.push_back(std::make_pair(RightTopFront, // right, top, front + RightBottomFront)); // right, bottom, front - mitk::Line3D line(startPoint, bottomVec); + edgesOf3DBox.push_back(std::make_pair(RightBottomFront, // right, bottom, front + RightBottomBack)); // right, bottom, back - m_Geometry2D->IntersectionPoint(line, *intersectionPoint); + edgesOf3DBox.push_back(std::make_pair(RightBottomBack, // right, bottom, back + LeftBottomBack)); // left, bottom, back - if(m_Image->GetGeometry()->IsInside(*intersectionPoint)) - { - return intersectionPoint; - } - else + 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(LeftTopBack, // left, top, back + LeftBottomBack)); // left, bottom, back + + + + for (EdgesVector::iterator iterator = edgesOf3DBox.begin(); iterator != edgesOf3DBox.end();iterator++) { - return NULL; - } -} + Point3D startPoint = (*iterator).first; // start point of the line + Point3D endPoint = (*iterator).second; // end point of the line + Vector3D lineDirection = endPoint - startPoint; -mitk::ClippedSurfaceBoundsCalculator::outputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() -{ - return this->m_MinMaxOutput[0]; -} + mitk::Line3D line(startPoint, lineDirection); -mitk::ClippedSurfaceBoundsCalculator::outputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() -{ - return this->m_MinMaxOutput[1]; -} + Point3D intersectionWorldPoint; + intersectionWorldPoint.Fill(std::numeric_limits::min()); -mitk::ClippedSurfaceBoundsCalculator::outputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() -{ - return this->m_MinMaxOutput[2]; -} + m_PlaneGeometry->IntersectionPoint(line, intersectionWorldPoint); // Get intersection point of line and plane geometry -void mitk::ClippedSurfaceBoundsCalculator::Update() -{ - this->CalculateSurfaceBounds(); + double t = -1.0; + bool isIntersectionPointOnLine; + isIntersectionPointOnLine = m_PlaneGeometry->IntersectionPointParam(line, t); + + mitk::Point3D intersectionIndexPoint; + m_Image->GetGeometry()->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); //Get index point + + 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 + { + 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 + { + 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 fb30fef899..83098c127b 100644 --- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h +++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h @@ -1,53 +1,49 @@ #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" /** * \brief Class to find * */ namespace mitk { class MITK_CORE_EXPORT ClippedSurfaceBoundsCalculator { public: ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry = NULL, mitk::Image::Pointer image = NULL); virtual ~ClippedSurfaceBoundsCalculator(); void SetInput(const mitk::PlaneGeometry* geometry, mitk::Image::Pointer image); void Update(); - typedef std::pair outputType; + typedef std::pair OutputType; - outputType GetMinMaxSpatialDirectionX(); - outputType GetMinMaxSpatialDirectionY(); - outputType GetMinMaxSpatialDirectionZ(); + OutputType GetMinMaxSpatialDirectionX(); + OutputType GetMinMaxSpatialDirectionY(); + OutputType GetMinMaxSpatialDirectionZ(); protected: - void CalculateSurfaceBounds(); - void CalculateSurfaceBounds(Point3D right, Point3D bottom); - mitk::Point3D* GetIntersectionPoint(Point3D right, Point3D bottom); - - const mitk::PlaneGeometry* m_Geometry2D; + const mitk::PlaneGeometry* m_PlaneGeometry; mitk::Image::Pointer m_Image; - std::vector< outputType > m_MinMaxOutput; + std::vector< OutputType > m_MinMaxOutput; }; } //namespace mitk #endif