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
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.