Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkBoundingObjectGroup.cpp
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 
18 #include "mitkBaseProcess.h"
20 #include <vtkLinearTransform.h>
21 
23  : m_BoundingObjects(0), m_Counter(0), m_CSGMode(Union) // m_CSGMode(Difference) //m_CSGMode(Intersection)
24 {
26  timeGeometry->Initialize(1);
27  SetTimeGeometry(timeGeometry);
28 
29  SetVtkPolyData(nullptr);
30 }
31 
33 {
34 }
35 
37 {
38  if (this->GetSource())
39  {
40  this->GetSource()->UpdateOutputInformation();
41  }
42 
43  // calculate global bounding box
44  if (m_BoundingObjects.size() < 1) // if there is no BoundingObject, the bounding box is zero
45  {
47  boundsArray.Fill(0);
49  timeGeometry->Initialize(1);
50  SetTimeGeometry(timeGeometry);
51  GetGeometry()->SetBounds(boundsArray);
52  GetTimeGeometry()->Update();
53  return;
54  }
55 
56  // initialize container
58 
59  mitk::BoundingBox::PointIdentifier pointid = 0;
60  mitk::Point3D point;
61 
62  mitk::AffineTransform3D *transform = GetGeometry()->GetIndexToWorldTransform();
64  transform->GetInverse(inverse);
65 
66  // calculate a bounding box that includes all BoundingObjects
67  // \todo probably we should do this additionally for each time-step
68  // while (boundingObjectsIterator != boundingObjectsIteratorEnd)
69  for (unsigned int j = 0; j < m_BoundingObjects.size(); j++)
70  {
71  const TimeGeometry *geometry = m_BoundingObjects.at(j)->GetUpdatedTimeGeometry();
72  unsigned char i;
73  for (i = 0; i < 8; ++i)
74  {
75  point = inverse->TransformPoint(geometry->GetCornerPointInWorld(i));
76  if (point[0] * point[0] + point[1] * point[1] + point[2] * point[2] < mitk::large)
77  pointscontainer->InsertElement(pointid++, point);
78  else
79  {
80  itkGenericOutputMacro(<< "Unrealistically distant corner point encountered. Ignored. BoundingObject: "
81  << m_BoundingObjects.at(j));
82  }
83  }
84  }
85 
87  boundingBox->SetPoints(pointscontainer);
88  boundingBox->ComputeBoundingBox();
89 
90  BaseGeometry *geometry3d = GetGeometry(0);
91  geometry3d->SetIndexToWorldTransform(transform);
92  geometry3d->SetBounds(boundingBox->GetBounds());
93  /* the objects position is the center of all sub bounding objects */
94  // geometry3d->SetOrigin(center);
95 
97  timeGeometry->Initialize(geometry3d, GetTimeGeometry()->CountTimeSteps());
98  SetTimeGeometry(timeGeometry);
99 }
100 
102 {
103  if (boundingObject->GetPositive())
104  m_BoundingObjects.push_front(boundingObject);
105  else
106  m_BoundingObjects.push_back(boundingObject);
107  ++m_Counter;
108  UpdateOutputInformation();
109 }
110 
112 {
113  auto it = m_BoundingObjects.begin();
114  for (unsigned int i = 0; i < m_BoundingObjects.size(); i++)
115  {
116  if (m_BoundingObjects.at(i) == boundingObject)
117  m_BoundingObjects.erase(it);
118  ++it;
119  }
120  --m_Counter;
121  UpdateOutputInformation();
122 }
123 
125 {
126  bool inside = false; // initialize with true for intersection, with false for union
127  bool posInside = false;
128  bool negInside = false;
129 
130  for (unsigned int i = 0; i < m_BoundingObjects.size(); i++)
131  {
132  switch (m_CSGMode)
133  {
134  case Intersection:
135  inside = true;
136  // calculate intersection: each point, that is inside each BoundingObject is considered inside the group
137  inside = m_BoundingObjects.at(i)->IsInside(p) && inside;
138  if (!inside) // shortcut, it is enough to find one object that does not contain the point
139  i = m_BoundingObjects.size();
140  break;
141 
142  case Union:
143  case Difference:
144  posInside = false;
145  negInside = false;
146  // calculate union: each point, that is inside least one BoundingObject is considered inside the group
147  if (m_BoundingObjects.at(i)->GetPositive())
148  posInside = m_BoundingObjects.at(i)->IsInside(p) || posInside;
149  else
150  negInside = m_BoundingObjects.at(i)->IsInside(p) || negInside;
151 
152  if (posInside && !negInside)
153  inside = true;
154  else
155  inside = false;
156  break;
157 
158  default:
159  inside = false;
160  // calculate union: each point, that is inside least one BoundingObject is considered inside the group
161  inside = m_BoundingObjects.at(i)->IsInside(p) || inside;
162  if (inside) // shortcut, it is enough to find one object that contains the point
163  i = m_BoundingObjects.size();
164  break;
165  }
166  }
167  return inside;
168 }
169 
171 {
172  return m_Counter;
173 }
174 
176 {
177  return m_Counter > 0;
178 }
179 
181 {
182  // if ( m_BoundingObjects == NULL )
183  return Superclass::GetGeometry(t);
184 
185  // mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boI = m_BoundingObjects->Begin();
186  // const mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boIEnd = m_BoundingObjects->End();
187  // mitk::Geometry3D* currentGeometry = NULL;
188 
189  // while ( boI != boIEnd )
190  //{
191  // currentGeometry = boI.Value()->GetGeometry( t );
192  // boI++;
193  //}
194 
195  // return currentGeometry;
196 }
197 
198 void mitk::BoundingObjectGroup::SetBoundingObjects(const std::deque<mitk::BoundingObject::Pointer> boundingObjects)
199 {
200  m_BoundingObjects = boundingObjects;
201 }
202 
203 std::deque<mitk::BoundingObject::Pointer> mitk::BoundingObjectGroup::GetBoundingObjects()
204 {
205  return m_BoundingObjects;
206 }
itk::SmartPointer< Self > Pointer
void SetIndexToWorldTransform(mitk::AffineTransform3D *transform)
mitk::BaseGeometry * GetGeometry(int t=0) const
virtual void SetTimeGeometry(TimeGeometry *geometry)
Set the TimeGeometry of the data, which will be referenced (not copied!).
void RemoveBoundingObject(mitk::BoundingObject::Pointer boundingObject)
void AddBoundingObject(mitk::BoundingObject::Pointer boundingObject)
Point3D GetCornerPointInWorld(int id) const
Get the position of the corner number id (in world coordinates)
virtual bool IsInside(const mitk::Point3D &p) const override
std::deque< mitk::BoundingObject::Pointer > GetBoundingObjects()
virtual void UpdateOutputInformation() override
itk::AffineGeometryFrame< ScalarType, 3 >::TransformType AffineTransform3D
virtual void SetVtkPolyData(vtkPolyData *polydata, unsigned int t=0)
MITKCORE_EXPORT const double large
void SetBounds(const BoundsArrayType &bounds)
Set the bounding box (in index/unit coordinates)
virtual bool VerifyRequestedRegion() override
Verify that the RequestedRegion is within the LargestPossibleRegion.
void SetBoundingObjects(const std::deque< mitk::BoundingObject::Pointer > boundingObjects)
BaseGeometry Describes the geometry of a data object.
BoundingBoxType::BoundsArrayType BoundsArrayType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.