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