19 #define ROUND_P(x) ((x) >= 0 ? (int)((x) + 0.5) : (int)((x)-0.5))
23 : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr)
32 : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr)
41 : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(image)
51 m_MinMaxOutput.clear();
52 m_MinMaxOutput.reserve(3);
53 for (
int i = 0; i < 3; i++)
65 if (geometry && image)
67 this->m_PlaneGeometry = geometry;
68 this->m_Image = image;
69 this->m_Geometry3D =
nullptr;
70 m_ObjectPointsInWorldCoordinates.clear();
76 if (geometry && image)
78 this->m_Geometry3D = geometry;
79 this->m_Image = image;
80 this->m_PlaneGeometry =
nullptr;
81 m_ObjectPointsInWorldCoordinates.clear();
87 if (!pointlist.empty() && image)
89 m_Geometry3D =
nullptr;
90 m_PlaneGeometry =
nullptr;
92 m_ObjectPointsInWorldCoordinates = pointlist;
98 return this->m_MinMaxOutput[0];
103 return this->m_MinMaxOutput[1];
108 return this->m_MinMaxOutput[2];
113 this->m_MinMaxOutput.clear();
114 m_MinMaxOutput.reserve(3);
115 for (
int i = 0; i < 3; i++)
120 if (m_PlaneGeometry.IsNotNull())
122 this->CalculateIntersectionPoints(m_PlaneGeometry);
124 else if (m_Geometry3D.IsNotNull())
129 int allSlices = slicedGeometry3D->
GetSlices();
130 this->CalculateIntersectionPoints(dynamic_cast<mitk::PlaneGeometry *>(slicedGeometry3D->
GetPlaneGeometry(0)));
131 this->CalculateIntersectionPoints(
132 dynamic_cast<mitk::PlaneGeometry *>(slicedGeometry3D->
GetPlaneGeometry(allSlices - 1)));
134 else if (!m_ObjectPointsInWorldCoordinates.empty())
136 this->CalculateIntersectionPoints(m_ObjectPointsInWorldCoordinates);
137 this->EnforceImageBounds();
148 Point3D origin = imageGeometry->GetCornerPoint(0);
151 const Vector3D xDirection = imageGeometry->GetAxisVector(0);
152 const Vector3D yDirection = imageGeometry->GetAxisVector(1);
153 const Vector3D zDirection = imageGeometry->GetAxisVector(2);
155 const Point3D leftBottomFront = origin;
156 const Point3D leftTopFront = origin + yDirection;
157 const Point3D leftBottomBack = origin + zDirection;
158 const Point3D leftTopBack = origin + yDirection + zDirection;
159 const Point3D rightBottomFront = origin + xDirection;
160 const Point3D rightTopFront = origin + xDirection + yDirection;
161 const Point3D rightBottomBack = origin + xDirection + zDirection;
162 const Point3D rightTopBack = origin + xDirection + yDirection + zDirection;
164 typedef std::vector<std::pair<mitk::Point3D, mitk::Point3D>> EdgesVector;
165 EdgesVector edgesOf3DBox;
166 edgesOf3DBox.reserve(12);
168 edgesOf3DBox.push_back(std::make_pair(leftBottomFront,
171 edgesOf3DBox.push_back(std::make_pair(leftBottomFront,
174 edgesOf3DBox.push_back(std::make_pair(leftBottomFront,
177 edgesOf3DBox.push_back(std::make_pair(leftTopFront,
180 edgesOf3DBox.push_back(std::make_pair(leftTopFront,
183 edgesOf3DBox.push_back(std::make_pair(rightTopFront,
186 edgesOf3DBox.push_back(std::make_pair(rightTopFront,
189 edgesOf3DBox.push_back(std::make_pair(rightBottomFront,
192 edgesOf3DBox.push_back(std::make_pair(rightBottomBack,
195 edgesOf3DBox.push_back(std::make_pair(rightBottomBack,
198 edgesOf3DBox.push_back(std::make_pair(rightTopBack,
201 edgesOf3DBox.push_back(std::make_pair(leftTopBack,
204 for (
auto iterator = edgesOf3DBox.cbegin(); iterator != edgesOf3DBox.cend(); ++iterator)
206 const Point3D startPoint = (*iterator).first;
207 const Point3D endPoint = (*iterator).second;
208 const Vector3D lineDirection = endPoint - startPoint;
216 bool doesLineIntersectWithPlane(
false);
223 doesLineIntersectWithPlane =
true;
224 intersectionWorldPoint = line.
GetPoint1();
234 imageGeometry->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint);
238 if (doesLineIntersectWithPlane && lowerBoundGood && upperBoundGood)
240 for (
int dim = 0; dim < 3; ++dim)
242 m_MinMaxOutput[dim].first =
std::min(m_MinMaxOutput[dim].first,
ROUND_P(intersectionIndexPoint[dim]));
243 m_MinMaxOutput[dim].second =
std::max(m_MinMaxOutput[dim].second,
ROUND_P(intersectionIndexPoint[dim]));
245 this->EnforceImageBounds();
252 PointListType::const_iterator pointIterator;
255 for (pointIterator = pointList.cbegin(); pointIterator != pointList.cend(); ++pointIterator)
258 imageGeometry->WorldToIndex((*pointIterator), pntInIndexCoordinates);
260 m_MinMaxOutput[0].first =
261 pntInIndexCoordinates[0] < m_MinMaxOutput[0].first ?
ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].first;
262 m_MinMaxOutput[0].second = pntInIndexCoordinates[0] > m_MinMaxOutput[0].second ?
ROUND_P(pntInIndexCoordinates[0]) :
263 m_MinMaxOutput[0].second;
265 m_MinMaxOutput[1].first =
266 pntInIndexCoordinates[1] < m_MinMaxOutput[1].first ?
ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].first;
267 m_MinMaxOutput[1].second = pntInIndexCoordinates[1] > m_MinMaxOutput[1].second ?
ROUND_P(pntInIndexCoordinates[1]) :
268 m_MinMaxOutput[1].second;
270 m_MinMaxOutput[2].first =
271 pntInIndexCoordinates[2] < m_MinMaxOutput[2].first ?
ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].first;
272 m_MinMaxOutput[2].second = pntInIndexCoordinates[2] > m_MinMaxOutput[2].second ?
ROUND_P(pntInIndexCoordinates[2]) :
273 m_MinMaxOutput[2].second;
281 m_MinMaxOutput[0].first =
std::max(m_MinMaxOutput[0].first, 0);
282 m_MinMaxOutput[1].first =
std::max(m_MinMaxOutput[1].first, 0);
283 m_MinMaxOutput[2].first =
std::max(m_MinMaxOutput[2].first, 0);
285 m_MinMaxOutput[0].first =
std::min(m_MinMaxOutput[0].first, (
int)m_Image->GetDimension(0) - 1);
286 m_MinMaxOutput[1].first =
std::min(m_MinMaxOutput[1].first, (
int)m_Image->GetDimension(1) - 1);
287 m_MinMaxOutput[2].first =
std::min(m_MinMaxOutput[2].first, (
int)m_Image->GetDimension(2) - 1);
289 m_MinMaxOutput[0].second =
std::min(m_MinMaxOutput[0].second, (
int)m_Image->GetDimension(0) - 1);
290 m_MinMaxOutput[1].second =
std::min(m_MinMaxOutput[1].second, (
int)m_Image->GetDimension(1) - 1);
291 m_MinMaxOutput[2].second =
std::min(m_MinMaxOutput[2].second, (
int)m_Image->GetDimension(2) - 1);
293 m_MinMaxOutput[0].second =
std::max(m_MinMaxOutput[0].second, 0);
294 m_MinMaxOutput[1].second =
std::max(m_MinMaxOutput[1].second, 0);
295 m_MinMaxOutput[2].second =
std::max(m_MinMaxOutput[2].second, 0);
OutputType GetMinMaxSpatialDirectionZ()
What Z coordinates (slice indices) are cut/visible in given plane.
bool IntersectionPointParam(const Line3D &line, double &t) const
Calculate line parameter of intersection point between the plane and a line.
void CalculateIntersectionPoints(const mitk::PlaneGeometry *geometry)
const itk::Point< TCoordRep, NPointDimension > & GetPoint1() const
Get start point of the line.
bool IntersectionPoint(const Line3D &line, Point3D &intersectionPoint) const
Calculate intersection point between the plane and a line.
void SetInput(const mitk::PlaneGeometry *geometry, mitk::Image *image)
void Update()
Request calculation.
virtual ~ClippedSurfaceBoundsCalculator()
ScalarType Distance(const Point3D &pt3d_mm) const
Distance of the point from the geometry (bounding-box not considered)
const itk::Vector< TCoordRep, NPointDimension > & GetDirection() const
Get the direction vector of the line.
void EnforceImageBounds()
Clips the resulting index-coordinates to make sure they do not exceed the imagebounds.
Image class for storing images.
virtual mitk::PlaneGeometry * GetPlaneGeometry(int s) const
Returns the PlaneGeometry of the slice (s).
ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry *geometry=nullptr, mitk::Image::Pointer image=nullptr)
std::vector< mitk::Point3D > m_ObjectPointsInWorldCoordinates
std::vector< mitk::Point3D > PointListType
virtual unsigned int GetSlices() const
Get the number of slices.
Describes the geometry of a data object consisting of slices.
MITKCORE_EXPORT const ScalarType sqrteps
MITKCORE_EXPORT const ScalarType eps
OutputType GetMinMaxSpatialDirectionY()
What Y coordinates (slice indices) are cut/visible in given plane.
Describes a two-dimensional, rectangular plane.
OutputType GetMinMaxSpatialDirectionX()
What X coordinates (slice indices) are cut/visible in given plane.
std::pair< int, int > OutputType
Minimum (first) and maximum (second) slice index.
BaseGeometry Describes the geometry of a data object.