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
mitkContourModelSubDivisionFilter.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 <mitkInteractionConst.h>
19 #include <mitkPointOperation.h>
20 
22 {
23  OutputType::Pointer output = dynamic_cast<OutputType *>(this->MakeOutput(0).GetPointer());
24  this->SetNumberOfRequiredInputs(1);
25  this->SetNumberOfIndexedOutputs(1);
26  this->SetNthOutput(0, output.GetPointer());
27  this->m_InterpolationIterations = 4;
28 }
30 {
31 }
32 
34 {
35  this->SetInput(0, input);
36 }
37 
40 {
41  if (idx + 1 > this->GetNumberOfInputs())
42  {
43  this->SetNumberOfRequiredInputs(idx + 1);
44  }
45  if (input != static_cast<InputType *>(this->ProcessObject::GetInput(idx)))
46  {
47  this->ProcessObject::SetNthInput(idx, const_cast<InputType *>(input));
48  this->Modified();
49  }
50 }
51 
53 {
54  if (this->GetNumberOfInputs() < 1)
55  return nullptr;
56  return static_cast<const mitk::ContourModelSubDivisionFilter::InputType *>(this->ProcessObject::GetInput(0));
57 }
58 
60 {
61  if (this->GetNumberOfInputs() < 1)
62  return nullptr;
63  return static_cast<const mitk::ContourModelSubDivisionFilter::InputType *>(this->ProcessObject::GetInput(idx));
64 }
65 
67 {
68  mitk::ContourModel::Pointer input = const_cast<mitk::ContourModel *>(this->GetInput(0));
69 
70  // mitk::ContourModelSubDivisionFilter::OutputType::Pointer outputContour = this->GetOutput();
71 
72  mitk::ContourModel::Pointer contour(input);
73 
74  int timestep = static_cast<int>(input->GetTimeSteps());
75 
76  for (int currentTimestep = 0; currentTimestep < timestep; currentTimestep++)
77  {
78  if (input->GetNumberOfVertices(currentTimestep) >= 4)
79  {
80  for (int iterations = 0; iterations < this->m_InterpolationIterations; iterations++)
81  {
82  auto it = contour->IteratorBegin();
83  auto end = contour->IteratorEnd();
84 
85  auto first = contour->IteratorBegin();
86  auto last = contour->IteratorEnd() - 1;
87 
88  // tempory contour to store result of a subdivision iteration
90 
91  // insert subpoints
92  while (it != end)
93  {
94  // add the current point to the temp contour
95  tempContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, currentTimestep);
96 
97  // control points for interpolation
98  auto Ci = it;
101  InputType::VertexIterator CiMinus1;
102 
103  // consider all possible cases
104  if (it == first)
105  {
106  if (input->IsClosed(currentTimestep))
107  {
108  CiPlus1 = it + 1;
109  CiPlus2 = it + 2;
110  CiMinus1 = last;
111  }
112  else
113  {
114  CiPlus1 = it + 1;
115  CiPlus2 = it + 2;
116  CiMinus1 = it;
117  }
118  }
119  else if (it == last)
120  {
121  if (input->IsClosed(currentTimestep))
122  {
123  CiPlus1 = first;
124  CiPlus2 = first + 1;
125  CiMinus1 = it - 1;
126  }
127  else
128  {
129  // don't add point after last
130  break;
131  }
132  }
133  else if (it == (last - 1))
134  {
135  if (input->IsClosed(currentTimestep))
136  {
137  CiPlus1 = it + 1;
138  CiPlus2 = first;
139  CiMinus1 = it - 1;
140  }
141  else
142  {
143  CiPlus1 = it + 1;
144  CiPlus2 = it + 1;
145  CiMinus1 = it - 1;
146  }
147  }
148  else
149  {
150  CiPlus1 = it + 1;
151  CiPlus2 = it + 2;
152  CiMinus1 = it - 1;
153  }
154 
155  /* F2i = Ci
156  * F2i+1 = -1/16Ci-1 + 9/16Ci + 9/16Ci+1 - 1/16Ci+2
157  */
158  mitk::Point3D subpoint;
159 
160  mitk::Point3D a;
161  a[0] = (-1.0 / 16.0) * (*CiMinus1)->Coordinates[0];
162  a[1] = (-1.0 / 16.0) * (*CiMinus1)->Coordinates[1];
163  a[2] = (-1.0 / 16.0) * (*CiMinus1)->Coordinates[2];
164 
165  mitk::Point3D b;
166  b[0] = (9.0 / 16.0) * (*Ci)->Coordinates[0];
167  b[1] = (9.0 / 16.0) * (*Ci)->Coordinates[1];
168  b[2] = (9.0 / 16.0) * (*Ci)->Coordinates[2];
169 
170  mitk::Point3D c;
171  c[0] = (9.0 / 16.0) * (*CiPlus1)->Coordinates[0];
172  c[1] = (9.0 / 16.0) * (*CiPlus1)->Coordinates[1];
173  c[2] = (9.0 / 16.0) * (*CiPlus1)->Coordinates[2];
174 
175  mitk::Point3D d;
176  d[0] = (-1.0 / 16.0) * (*CiPlus2)->Coordinates[0];
177  d[1] = (-1.0 / 16.0) * (*CiPlus2)->Coordinates[1];
178  d[2] = (-1.0 / 16.0) * (*CiPlus2)->Coordinates[2];
179 
180  subpoint[0] = a[0] + b[0] + c[0] + d[0];
181  subpoint[1] = a[1] + b[1] + c[1] + d[1];
182  subpoint[2] = a[2] + b[2] + c[2] + d[2];
183  InputType::VertexType subdivisionPoint(subpoint, false);
184 
185  // add the new subdivision point to our tempContour
186  tempContour->AddVertex(subdivisionPoint.Coordinates, currentTimestep);
187 
188  it++;
189  }
190 
191  // set the interpolated contour as the contour for the next iteration
192  contour = tempContour;
193  }
194  }
195  else
196  {
197  // filter not executeable - set input to output
198  contour = input;
199  }
200  }
201 
202  // somehow the isClosed property is not set via copy constructor
203  contour->SetClosed(input->IsClosed());
204 
205  this->SetNthOutput(0, contour);
206 }
ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are store...
mitk::Point3D Coordinates
Coordinates in 3D space.
mitk::ContourElement::VertexIterator VertexIterator
Constants for most interaction classes, due to the generic StateMachines.
virtual mitkBaseDataSourceGetOutputDeclarations itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) override
virtual void SetInput(const InputType *input)
static Pointer New()
Represents a single vertex of contour.