Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef MITKPLANECLIPPING_H_HEADER_INCLUDED
18 #define MITKPLANECLIPPING_H_HEADER_INCLUDED
19 
20 #include <mitkGeometry3D.h>
21 #include <mitkPlaneGeometry.h>
22 #include <vtkPoints.h>
23 #include <vtkTransform.h>
24 
25 namespace mitk
26 {
27  namespace PlaneClipping
28  {
30  static bool LineIntersectZero(vtkPoints *points, int p1, int p2, double *bounds)
31  {
32  double point1[3];
33  double point2[3];
34  points->GetPoint(p1, point1);
35  points->GetPoint(p2, point2);
36 
37  if ((point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]))
38  {
39  double x, y;
40  x = (point1[0] * point2[2] - point1[2] * point2[0]) / (point2[2] - point1[2]);
41  y = (point1[1] * point2[2] - point1[2] * point2[1]) / (point2[2] - point1[2]);
42 
43  if (x < bounds[0])
44  {
45  bounds[0] = x;
46  }
47  if (x > bounds[1])
48  {
49  bounds[1] = x;
50  }
51  if (y < bounds[2])
52  {
53  bounds[2] = y;
54  }
55  if (y > bounds[3])
56  {
57  bounds[3] = y;
58  }
59  bounds[4] = bounds[5] = 0.0;
60  return true;
61  }
62  return false;
63  }
64 
68  static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry,
69  const PlaneGeometry *planeGeometry,
70  double *bounds)
71  {
72  // Clip the plane with the bounding geometry. To do so, the corner points
73  // of the bounding box are transformed by the inverse transformation
74  // matrix, and the transformed bounding box edges derived therefrom are
75  // clipped with the plane z=0. The resulting min/max values are taken as
76  // bounds for the image reslicer.
77  const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox();
78 
79  mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum();
80  mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum();
81 
82  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
83  if (boundingGeometry->GetImageGeometry())
84  {
85  points->InsertPoint(0, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
86  points->InsertPoint(1, bbMin[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
87  points->InsertPoint(2, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
88  points->InsertPoint(3, bbMin[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
89  points->InsertPoint(4, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMin[2] - 0.5);
90  points->InsertPoint(5, bbMax[0] - 0.5, bbMin[1] - 0.5, bbMax[2] - 0.5);
91  points->InsertPoint(6, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMax[2] - 0.5);
92  points->InsertPoint(7, bbMax[0] - 0.5, bbMax[1] - 0.5, bbMin[2] - 0.5);
93  }
94  else
95  {
96  points->InsertPoint(0, bbMin[0], bbMin[1], bbMin[2]);
97  points->InsertPoint(1, bbMin[0], bbMin[1], bbMax[2]);
98  points->InsertPoint(2, bbMin[0], bbMax[1], bbMax[2]);
99  points->InsertPoint(3, bbMin[0], bbMax[1], bbMin[2]);
100  points->InsertPoint(4, bbMax[0], bbMin[1], bbMin[2]);
101  points->InsertPoint(5, bbMax[0], bbMin[1], bbMax[2]);
102  points->InsertPoint(6, bbMax[0], bbMax[1], bbMax[2]);
103  points->InsertPoint(7, bbMax[0], bbMax[1], bbMin[2]);
104  }
105 
106  vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
107 
108  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
109  transform->Identity();
110  transform->Concatenate(planeGeometry->GetVtkTransform()->GetLinearInverse());
111 
112  transform->Concatenate(boundingGeometry->GetVtkTransform());
113 
114  transform->TransformPoints(points, newPoints);
115 
116  bounds[0] = bounds[2] = 10000000.0;
117  bounds[1] = bounds[3] = -10000000.0;
118  bounds[4] = bounds[5] = 0.0;
119 
120  LineIntersectZero(newPoints, 0, 1, bounds);
121  LineIntersectZero(newPoints, 1, 2, bounds);
122  LineIntersectZero(newPoints, 2, 3, bounds);
123  LineIntersectZero(newPoints, 3, 0, bounds);
124  LineIntersectZero(newPoints, 0, 4, bounds);
125  LineIntersectZero(newPoints, 1, 5, bounds);
126  LineIntersectZero(newPoints, 2, 6, bounds);
127  LineIntersectZero(newPoints, 3, 7, bounds);
128  LineIntersectZero(newPoints, 4, 5, bounds);
129  LineIntersectZero(newPoints, 5, 6, bounds);
130  LineIntersectZero(newPoints, 6, 7, bounds);
131  LineIntersectZero(newPoints, 7, 4, bounds);
132 
133  if ((bounds[0] > 9999999.0) || (bounds[2] > 9999999.0) || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0))
134  {
135  return false;
136  }
137  else
138  {
139  // The resulting bounds must be adjusted by the plane spacing, since we
140  // we have so far dealt with index coordinates
141  const mitk::Vector3D planeSpacing = planeGeometry->GetSpacing();
142  bounds[0] *= planeSpacing[0];
143  bounds[1] *= planeSpacing[0];
144  bounds[2] *= planeSpacing[1];
145  bounds[3] *= planeSpacing[1];
146  bounds[4] *= planeSpacing[2];
147  bounds[5] *= planeSpacing[2];
148  return true;
149  }
150  }
151  }
152 }
153 
154 #endif
mitk::Point3D PointType
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D-BoundingBox typedef.
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...
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.
vtkLinearTransform * GetVtkTransform() const
Get the m_IndexToWorldTransform as a vtkLinearTransform.
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
BaseGeometry Describes the geometry of a data object.
virtual const BoundingBoxType * GetBoundingBox()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.