Medical Imaging Interaction Toolkit  2026.06.00
Medical Imaging Interaction Toolkit
mitkPlaneClipping.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef mitkPlaneClipping_h
14 #define mitkPlaneClipping_h
15 
16 #include <mitkGeometry3D.h>
17 #include <mitkPlaneGeometry.h>
18 #include <vtkPoints.h>
19 #include <vtkSmartPointer.h>
20 #include <vtkTransform.h>
21 
22 namespace mitk
23 {
25  namespace PlaneClipping
26  {
39  static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
40  {
41  double point1[3];
42  double point2[3];
43  points->GetPoint(p1, point1);
44  points->GetPoint(p2, point2);
45 
46  if ((point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]))
47  {
48  double x, y;
49  x = (point1[0] * point2[2] - point1[2] * point2[0]) / (point2[2] - point1[2]);
50  y = (point1[1] * point2[2] - point1[2] * point2[1]) / (point2[2] - point1[2]);
51 
52  if (x < bounds[0])
53  {
54  bounds[0] = x;
55  }
56  if (x > bounds[1])
57  {
58  bounds[1] = x;
59  }
60  if (y < bounds[2])
61  {
62  bounds[2] = y;
63  }
64  if (y > bounds[3])
65  {
66  bounds[3] = y;
67  }
68  bounds[4] = bounds[5] = 0.0;
69  return true;
70  }
71  return false;
72  }
73 
87  static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry,
88  const PlaneGeometry *planeGeometry,
89  double *bounds)
90  {
91  // Clip the plane with the bounding geometry. To do so, the corner points
92  // of the bounding box are transformed by the inverse transformation
93  // matrix, and the transformed bounding box edges derived therefrom are
94  // clipped with the plane z=0. The resulting min/max values are taken as
95  // bounds for the image reslicer.
96  const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox();
97 
98  mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum();
99  mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum();
100 
102  if (boundingGeometry->GetImageGeometry())
103  {
104  points->InsertPoint(0, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
105  points->InsertPoint(1, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
106  points->InsertPoint(2, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
107  points->InsertPoint(3, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
108  points->InsertPoint(4, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
109  points->InsertPoint(5, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
110  points->InsertPoint(6, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
111  points->InsertPoint(7, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
112  }
113  else
114  {
115  points->InsertPoint(0, bbMin[0], bbMin[1], bbMin[2]);
116  points->InsertPoint(1, bbMin[0], bbMin[1], bbMax[2]);
117  points->InsertPoint(2, bbMin[0], bbMax[1], bbMax[2]);
118  points->InsertPoint(3, bbMin[0], bbMax[1], bbMin[2]);
119  points->InsertPoint(4, bbMax[0], bbMin[1], bbMin[2]);
120  points->InsertPoint(5, bbMax[0], bbMin[1], bbMax[2]);
121  points->InsertPoint(6, bbMax[0], bbMax[1], bbMax[2]);
122  points->InsertPoint(7, bbMax[0], bbMax[1], bbMin[2]);
123  }
124 
126 
128  transform->Identity();
129  transform->Concatenate(planeGeometry->GetVtkTransform()->GetLinearInverse());
130 
131  transform->Concatenate(boundingGeometry->GetVtkTransform());
132 
133  transform->TransformPoints(points, newPoints);
134 
135  bounds[0] = bounds[2] = 10000000.0;
136  bounds[1] = bounds[3] = -10000000.0;
137  bounds[4] = bounds[5] = 0.0;
138 
139  LineIntersectZero(newPoints, 0, 1, bounds);
140  LineIntersectZero(newPoints, 1, 2, bounds);
141  LineIntersectZero(newPoints, 2, 3, bounds);
142  LineIntersectZero(newPoints, 3, 0, bounds);
143  LineIntersectZero(newPoints, 0, 4, bounds);
144  LineIntersectZero(newPoints, 1, 5, bounds);
145  LineIntersectZero(newPoints, 2, 6, bounds);
146  LineIntersectZero(newPoints, 3, 7, bounds);
147  LineIntersectZero(newPoints, 4, 5, bounds);
148  LineIntersectZero(newPoints, 5, 6, bounds);
149  LineIntersectZero(newPoints, 6, 7, bounds);
150  LineIntersectZero(newPoints, 7, 4, bounds);
151 
152  if ((bounds[0] > 9999999.0) || (bounds[2] > 9999999.0) || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0))
153  {
154  return false;
155  }
156  else
157  {
158  // The resulting bounds must be adjusted by the plane spacing, since we
159  // we have so far dealt with index coordinates
160  const mitk::Vector3D planeSpacing = planeGeometry->GetSpacing();
161  bounds[0] *= planeSpacing[0];
162  bounds[1] *= planeSpacing[0];
163  bounds[2] *= planeSpacing[1];
164  bounds[3] *= planeSpacing[1];
165  bounds[4] *= planeSpacing[2];
166  bounds[5] *= planeSpacing[2];
167  return true;
168  }
169  }
170  }
171 }
172 
173 #endif
Abstract base class describing the geometry of a data object.
virtual const BoundingBoxType * GetBoundingBox()
Get the bounding box in index/unit coordinates.
mitk::Vector3D GetSpacing() const
Get the spacing (voxel size) in mm per unit for each axis.
vtkLinearTransform * GetVtkTransform() const
Get the IndexToWorldTransform as a vtkLinearTransform.
virtual bool GetImageGeometry() const
Query whether this geometry refers to an image.
Describes the geometry of a plane object.
static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry, const PlaneGeometry *planeGeometry, double *bounds)
Calculate the bounding box of the resliced image.
static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
Internal helper method for intersection testing used only in CalculateClippedPlaneBounds().
Find image slices visible on a given plane.
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D bounding box type.