Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.