17 m_MaxSegmentLenght = 0;
23 this->m_UseProgressBar =
false;
24 this->m_ProgressStepSize = 1;
25 m_NumberOfPointsAfterReduction = 0;
28 this->SetNthOutput(0, output.GetPointer());
37 this->SetNthInput(idx, const_cast<mitk::Surface *>(surface));
48 unsigned int numberOfInputs = this->GetNumberOfIndexedInputs();
49 unsigned int numberOfOutputs(0);
51 vtkSmartPointer<vtkPolyData> newPolyData;
52 vtkSmartPointer<vtkCellArray> newPolygons;
53 vtkSmartPointer<vtkPoints> newPoints;
57 m_NumberOfPointsAfterReduction = 0;
59 for (
unsigned int i = 0; i < numberOfInputs; i++)
61 auto *currentSurface = this->
GetInput(i);
62 vtkSmartPointer<vtkPolyData> polyData = currentSurface->GetVtkPolyData();
64 newPolyData = vtkSmartPointer<vtkPolyData>::New();
65 newPolygons = vtkSmartPointer<vtkCellArray>::New();
66 newPoints = vtkSmartPointer<vtkPoints>::New();
68 vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();
70 vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();
72 existingPolys->InitTraversal();
74 vtkIdType *cell(
nullptr);
75 vtkIdType cellSize(0);
77 for (existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
79 bool incorporatePolygon =
80 this->CheckForIntersection(cell, cellSize, existingPoints, i);
81 if (!incorporatePolygon)
84 vtkSmartPointer<vtkPolygon> newPolygon = vtkSmartPointer<vtkPolygon>::New();
88 this->ReduceNumberOfPointsByNthPoint(cellSize, cell, existingPoints, newPolygon, newPoints);
89 if (newPolygon->GetPointIds()->GetNumberOfIds() != 0)
91 newPolygons->InsertNextCell(newPolygon);
96 this->ReduceNumberOfPointsByDouglasPeucker(cellSize, cell, existingPoints, newPolygon, newPoints);
97 if (newPolygon->GetPointIds()->GetNumberOfIds() > 3)
99 newPolygons->InsertNextCell(newPolygon);
105 m_NumberOfPointsAfterReduction += newPolygon->GetPointIds()->GetNumberOfIds();
108 if (newPolygons->GetNumberOfCells() != 0)
110 newPolyData->SetPolys(newPolygons);
111 newPolyData->SetPoints(newPoints);
112 newPolyData->BuildLinks();
114 this->SetNumberOfIndexedOutputs(numberOfOutputs + 1);
116 this->SetNthOutput(numberOfOutputs, surface.GetPointer());
117 surface->SetVtkPolyData(newPolyData);
123 this->SetNumberOfIndexedOutputs(numberOfOutputs);
125 if (numberOfOutputs == 0)
128 tmp_output->SetVtkPolyData(vtkPolyData::New());
129 this->SetNthOutput(0, tmp_output.GetPointer());
132 if (this->m_UseProgressBar)
136 void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByNthPoint(
137 vtkIdType cellSize, vtkIdType *cell, vtkPoints *points, vtkPolygon *reducedPolygon, vtkPoints *reducedPoints)
139 unsigned int newNumberOfPoints(0);
140 unsigned int mod = cellSize % m_StepSize;
144 newNumberOfPoints = cellSize / m_StepSize;
148 newNumberOfPoints = ((cellSize - mod) / m_StepSize) + 1;
151 if (newNumberOfPoints <= 3)
155 reducedPolygon->GetPointIds()->SetNumberOfIds(newNumberOfPoints);
156 reducedPolygon->GetPoints()->SetNumberOfPoints(newNumberOfPoints);
158 for (vtkIdType i = 0; i < cellSize; i++)
160 if (i % m_StepSize == 0)
163 points->GetPoint(cell[i], point);
164 vtkIdType
id = reducedPoints->InsertNextPoint(point);
165 reducedPolygon->GetPointIds()->SetId(i / m_StepSize,
id);
168 vtkIdType
id = cell[0];
170 points->GetPoint(
id, point);
171 id = reducedPoints->InsertNextPoint(point);
172 reducedPolygon->GetPointIds()->SetId(newNumberOfPoints - 1,
id);
175 void mitk::ReduceContourSetFilter::ReduceNumberOfPointsByDouglasPeucker(
176 vtkIdType cellSize, vtkIdType *cell, vtkPoints *points, vtkPolygon *reducedPolygon, vtkPoints *reducedPoints)
179 if (cellSize <= static_cast<vtkIdType>(m_StepSize * 3))
214 if (m_MaxSpacing > 0)
216 m_Tolerance = m_MinSpacing;
224 std::stack<LineSegment> lineSegments;
231 lineSegments.push(ls2);
236 lineSegments.push(ls1);
244 double currentMaxDistance(0);
245 vtkIdType currentMaxDistanceIndex(0);
250 vtkIdType pointId(0);
252 pointId = reducedPoints->InsertNextPoint(points->GetPoint(cell[0]));
253 reducedPolygon->GetPointIds()->InsertNextId(pointId);
255 while (!lineSegments.empty())
257 currentSegment = lineSegments.top();
262 points->GetPoint(currentSegment.
EndIndex, tempV);
263 points->GetPoint(currentSegment.
StartIndex, v1);
265 v1[0] = tempV[0] - v1[0];
266 v1[1] = tempV[1] - v1[1];
267 v1[2] = tempV[2] - v1[2];
269 lenghtV1 = vtkMath::Norm(v1);
273 for (
int i = 1; i < abs(range); ++i)
275 points->GetPoint(currentSegment.
StartIndex + i, tempV);
276 points->GetPoint(currentSegment.
StartIndex, v2);
278 v2[0] = tempV[0] - v2[0];
279 v2[1] = tempV[1] - v2[1];
280 v2[2] = tempV[2] - v2[2];
284 l = vtkMath::Dot(v2, v1);
286 d = vtkMath::Norm(v2);
288 if (l > 0 && l < lenghtV1)
290 d = sqrt((d * d - l * l));
292 else if (l > 0 && l > lenghtV1)
294 tempV[0] = lenghtV1 * v1[0] - v2[0];
295 tempV[1] = lenghtV1 * v1[1] - v2[1];
296 tempV[2] = lenghtV1 * v1[2] - v2[2];
297 d = vtkMath::Norm(tempV);
301 if (d > currentMaxDistance)
303 currentMaxDistance = d;
304 currentMaxDistanceIndex = currentSegment.
StartIndex + i;
309 if (currentMaxDistance <= m_Tolerance)
313 if (segmentLenght > (
int)m_MaxSegmentLenght)
315 m_MaxSegmentLenght = (
unsigned int)segmentLenght;
319 if (abs(segmentLenght) > 25)
321 unsigned int newLenght(segmentLenght);
322 while (newLenght > 25)
324 newLenght = newLenght * 0.5;
326 unsigned int divisions = abs(segmentLenght) / newLenght;
329 for (
unsigned int i = 1; i <= divisions; ++i)
332 pointId = reducedPoints->InsertNextPoint(points->GetPoint(currentSegment.
StartIndex + newLenght * i));
333 reducedPolygon->GetPointIds()->InsertNextId(pointId);
337 pointId = reducedPoints->InsertNextPoint(points->GetPoint(currentSegment.
EndIndex));
338 reducedPolygon->GetPointIds()->InsertNextId(pointId);
344 lineSegments.push(ls2);
347 ls1.
EndIndex = currentMaxDistanceIndex;
348 lineSegments.push(ls1);
350 currentMaxDistance = 0;
354 bool mitk::ReduceContourSetFilter::CheckForIntersection(
355 vtkIdType *currentCell,
356 vtkIdType currentCellSize,
357 vtkPoints *currentPoints,
358 unsigned int currentInputIndex)
371 for (
unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++)
374 if (i == currentInputIndex)
379 vtkSmartPointer<vtkCellArray> polygonArray = poly->GetPolys();
380 polygonArray->InitTraversal();
381 vtkIdType anotherInputPolygonSize(0);
382 vtkIdType *anotherInputPolygonIDs(
nullptr);
392 for (polygonArray->InitTraversal(); polygonArray->GetNextCell(anotherInputPolygonSize, anotherInputPolygonIDs);)
406 poly->GetPoint(anotherInputPolygonIDs[0], p1);
407 poly->GetPoint(anotherInputPolygonIDs[1], p2);
409 v1[0] = p2[0] - p1[0];
410 v1[1] = p2[1] - p1[1];
411 v1[2] = p2[2] - p1[2];
415 double maxDistance(0);
416 double minDistance(10000);
418 for (vtkIdType j = 2; j < anotherInputPolygonSize; j++)
420 poly->GetPoint(anotherInputPolygonIDs[j], p3);
422 v2[0] = p3[0] - p1[0];
423 v2[1] = p3[1] - p1[1];
424 v2[2] = p3[2] - p1[2];
427 double dotV1V2 = vtkMath::Dot(v1, v2);
428 double absV1 = sqrt(vtkMath::Dot(v1, v1));
429 double absV2 = sqrt(vtkMath::Dot(v2, v2));
430 double cosV1V2 = dotV1V2 / (absV1 * absV2);
432 double arccos = acos(cosV1V2);
433 double degree = vtkMath::DegreesFromRadians(arccos);
442 vtkMath::Cross(v1, v2, normal);
446 double lambda = vtkMath::Dot(normal, p1);
452 for (vtkIdType
k = 0;
k < currentCellSize;
k++)
454 double currentPoint[3];
455 currentPoints->GetPoint(currentCell[
k], currentPoint);
458 tempPoint[0] = normal[0] * currentPoint[0];
459 tempPoint[1] = normal[1] * currentPoint[1];
460 tempPoint[2] = normal[2] * currentPoint[2];
462 double temp = tempPoint[0] + tempPoint[1] + tempPoint[2] - lambda;
463 double distance = fabs(temp);
465 if (distance > maxDistance)
467 maxDistance = distance;
469 if (distance < minDistance)
471 minDistance = distance;
475 if (maxDistance < 1.5 * m_MaxSpacing && minDistance < 0.5 * m_MinSpacing)
492 Superclass::GenerateOutputInformation();
497 for (
unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++)
499 this->PopBackInput();
501 this->SetNumberOfIndexedInputs(0);
502 this->SetNumberOfIndexedOutputs(0);
506 this->SetNthOutput(0, output.GetPointer());
508 m_NumberOfPointsAfterReduction = 0;
513 this->m_UseProgressBar = status;
518 this->m_ProgressStepSize = stepSize;
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
Class for storing surfaces (vtkPolyData).
virtual vtkPolyData * GetVtkPolyData(unsigned int t=0) const
void SetUseProgressBar(bool)
Set whether the mitkProgressBar should be used.
void SetInput(const mitk::Surface *surface) override
virtual const mitk::Surface * GetInput()
void SetProgressStepSize(unsigned int stepSize)
Set the stepsize which the progress bar should proceed.
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
~ReduceContourSetFilter() override
void Normalize(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output)
void GenerateOutputInformation() override
void GenerateData() override