Medical Imaging Interaction Toolkit  2018.4.99-6a3ea89d
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_HEADER_INCLUDED
14 #define MITKPLANECLIPPING_H_HEADER_INCLUDED
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 {
24  namespace PlaneClipping
25  {
27  static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
28  {
29  double point1[3];
30  double point2[3];
31  points->GetPoint(p1, point1);
32  points->GetPoint(p2, point2);
33 
34  if ((point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]))
35  {
36  double x, y;
37  x = (point1[0] * point2[2] - point1[2] * point2[0]) / (point2[2] - point1[2]);
38  y = (point1[1] * point2[2] - point1[2] * point2[1]) / (point2[2] - point1[2]);
39 
40  if (x < bounds[0])
41  {
42  bounds[0] = x;
43  }
44  if (x > bounds[1])
45  {
46  bounds[1] = x;
47  }
48  if (y < bounds[2])
49  {
50  bounds[2] = y;
51  }
52  if (y > bounds[3])
53  {
54  bounds[3] = y;
55  }
56  bounds[4] = bounds[5] = 0.0;
57  return true;
58  }
59  return false;
60  }
61 
65  static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry,
66  const PlaneGeometry *planeGeometry,
67  double *bounds)
68  {
69  // Clip the plane with the bounding geometry. To do so, the corner points
70  // of the bounding box are transformed by the inverse transformation
71  // matrix, and the transformed bounding box edges derived therefrom are
72  // clipped with the plane z=0. The resulting min/max values are taken as
73  // bounds for the image reslicer.
74  const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox();
75 
76  mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum();
77  mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum();
78 
79  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
80  if (boundingGeometry->GetImageGeometry())
81  {
82  points->InsertPoint(0, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
83  points->InsertPoint(1, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
84  points->InsertPoint(2, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
85  points->InsertPoint(3, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
86  points->InsertPoint(4, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
87  points->InsertPoint(5, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
88  points->InsertPoint(6, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
89  points->InsertPoint(7, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
90  }
91  else
92  {
93  points->InsertPoint(0, bbMin[0], bbMin[1], bbMin[2]);
94  points->InsertPoint(1, bbMin[0], bbMin[1], bbMax[2]);
95  points->InsertPoint(2, bbMin[0], bbMax[1], bbMax[2]);
96  points->InsertPoint(3, bbMin[0], bbMax[1], bbMin[2]);
97  points->InsertPoint(4, bbMax[0], bbMin[1], bbMin[2]);
98  points->InsertPoint(5, bbMax[0], bbMin[1], bbMax[2]);
99  points->InsertPoint(6, bbMax[0], bbMax[1], bbMax[2]);
100  points->InsertPoint(7, bbMax[0], bbMax[1], bbMin[2]);
101  }
102 
103  vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
104 
105  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
106  transform->Identity();
107  transform->Concatenate(planeGeometry->GetVtkTransform()->GetLinearInverse());
108 
109  transform->Concatenate(boundingGeometry->GetVtkTransform());
110 
111  transform->TransformPoints(points, newPoints);
112 
113  bounds[0] = bounds[2] = 10000000.0;
114  bounds[1] = bounds[3] = -10000000.0;
115  bounds[4] = bounds[5] = 0.0;
116 
117  LineIntersectZero(newPoints, 0, 1, bounds);
118  LineIntersectZero(newPoints, 1, 2, bounds);
119  LineIntersectZero(newPoints, 2, 3, bounds);
120  LineIntersectZero(newPoints, 3, 0, bounds);
121  LineIntersectZero(newPoints, 0, 4, bounds);
122  LineIntersectZero(newPoints, 1, 5, bounds);
123  LineIntersectZero(newPoints, 2, 6, bounds);
124  LineIntersectZero(newPoints, 3, 7, bounds);
125  LineIntersectZero(newPoints, 4, 5, bounds);
126  LineIntersectZero(newPoints, 5, 6, bounds);
127  LineIntersectZero(newPoints, 6, 7, bounds);
128  LineIntersectZero(newPoints, 7, 4, bounds);
129 
130  if ((bounds[0] > 9999999.0) || (bounds[2] > 9999999.0) || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0))
131  {
132  return false;
133  }
134  else
135  {
136  // The resulting bounds must be adjusted by the plane spacing, since we
137  // we have so far dealt with index coordinates
138  const mitk::Vector3D planeSpacing = planeGeometry->GetSpacing();
139  bounds[0] *= planeSpacing[0];
140  bounds[1] *= planeSpacing[0];
141  bounds[2] *= planeSpacing[1];
142  bounds[3] *= planeSpacing[1];
143  bounds[4] *= planeSpacing[2];
144  bounds[5] *= planeSpacing[2];
145  return true;
146  }
147  }
148  }
149 }
150 
151 #endif
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D-BoundingBox typedef.
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry, const PlaneGeometry *planeGeometry, double *bounds)
Calculate the bounding box of the resliced image. This is necessary for arbitrarily rotated planes in...
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
DataCollection - Class to facilitate loading/accessing structured data.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
Internal helper method for intersection testing used only in CalculateClippedPlaneBounds() ...
Describes a two-dimensional, rectangular plane.
BaseGeometry Describes the geometry of a data object.
virtual const BoundingBoxType * GetBoundingBox()