19 : m_SegmentationBinaryImage(nullptr),
21 m_NegativeNormalCounter(0),
22 m_PositiveNormalCounter(0),
23 m_UseProgressBar(false),
27 this->SetNthOutput(0, output.GetPointer());
36 unsigned int numberOfInputs = this->GetNumberOfIndexedInputs();
39 for (
unsigned int i = 0; i < numberOfInputs; i++)
42 auto *currentSurface = this->
GetInput(i);
43 vtkPolyData *polyData = currentSurface->GetVtkPolyData();
45 vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();
47 vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();
49 existingPolys->InitTraversal();
51 vtkIdType *cell(
nullptr);
52 vtkIdType cellSize(0);
55 vtkSmartPointer<vtkDoubleArray> normals = vtkSmartPointer<vtkDoubleArray>::New();
56 normals->SetNumberOfComponents(3);
57 normals->SetNumberOfTuples(polyData->GetNumberOfPoints());
61 m_NegativeNormalCounter = 0;
62 m_PositiveNormalCounter = 0;
66 for (existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
72 double polygonNormal[3] = {0.0};
80 existingPoints->GetPoint(cell[0], p1);
81 unsigned int index = cellSize * 0.5;
82 existingPoints->GetPoint(cell[index], p2);
84 v1[0] = p2[0] - p1[0];
85 v1[1] = p2[1] - p1[1];
86 v1[2] = p2[2] - p1[2];
88 for (vtkIdType
k = 2;
k < cellSize;
k++)
90 index = cellSize * 0.25;
91 existingPoints->GetPoint(cell[index], p1);
92 index = cellSize * 0.75;
93 existingPoints->GetPoint(cell[index], p2);
95 v2[0] = p2[0] - p1[0];
96 v2[1] = p2[1] - p1[1];
97 v2[2] = p2[2] - p1[2];
99 vtkMath::Cross(v1, v2, polygonNormal);
100 if (vtkMath::Norm(polygonNormal) != 0)
108 double vertexNormalTemp[3];
109 existingPoints->GetPoint(cell[0], p1);
110 existingPoints->GetPoint(cell[1], p2);
112 v1[0] = p2[0] - p1[0];
113 v1[1] = p2[1] - p1[1];
114 v1[2] = p2[2] - p1[2];
116 vtkMath::Cross(v1, polygonNormal, vertexNormalTemp);
120 double vertexNormal[3];
122 for (vtkIdType j = 0; j < cellSize - 2; j++)
124 existingPoints->GetPoint(cell[j + 1], p1);
125 existingPoints->GetPoint(cell[j + 2], p2);
127 v1[0] = p2[0] - p1[0];
128 v1[1] = p2[1] - p1[1];
129 v1[2] = p2[2] - p1[2];
131 vtkMath::Cross(v1, polygonNormal, vertexNormal);
135 double finalNormal[3];
137 finalNormal[0] = (vertexNormal[0] + vertexNormalTemp[0]) * 0.5;
138 finalNormal[1] = (vertexNormal[1] + vertexNormalTemp[1]) * 0.5;
139 finalNormal[2] = (vertexNormal[2] + vertexNormalTemp[2]) * 0.5;
143 if (m_SegmentationBinaryImage)
146 worldCoord[0] = p1[0] + finalNormal[0] * m_MaxSpacing;
147 worldCoord[1] = p1[1] + finalNormal[1] * m_MaxSpacing;
148 worldCoord[2] = p1[2] + finalNormal[2] * m_MaxSpacing;
153 m_SegmentationBinaryImage->GetGeometry()->WorldToIndex(worldCoord, idx);
156 if (m_SegmentationBinaryImage->GetImageDescriptor()
157 ->GetChannelDescriptor()
159 .GetComponentType() == itk::ImageIOBase::UCHAR)
164 else if (m_SegmentationBinaryImage->GetImageDescriptor()
165 ->GetChannelDescriptor()
167 .GetComponentType() == itk::ImageIOBase::USHORT)
182 ++m_PositiveNormalCounter;
187 ++m_NegativeNormalCounter;
191 vertexNormalTemp[0] = vertexNormal[0];
192 vertexNormalTemp[1] = vertexNormal[1];
193 vertexNormalTemp[2] = vertexNormal[2];
195 vtkIdType
id = cell[j + 1];
196 normals->SetTuple(
id, finalNormal);
199 existingPoints->GetPoint(cell[0], p1);
200 existingPoints->GetPoint(cell[1], p2);
202 v1[0] = p2[0] - p1[0];
203 v1[1] = p2[1] - p1[1];
204 v1[2] = p2[2] - p1[2];
206 vtkMath::Cross(v1, polygonNormal, vertexNormal);
210 vertexNormal[0] = (vertexNormal[0] + vertexNormalTemp[0]) * 0.5;
211 vertexNormal[1] = (vertexNormal[1] + vertexNormalTemp[1]) * 0.5;
212 vertexNormal[2] = (vertexNormal[2] + vertexNormalTemp[2]) * 0.5;
215 vtkIdType
id = cell[0];
216 normals->SetTuple(
id, vertexNormal);
217 id = cell[cellSize - 1];
218 normals->SetTuple(
id, vertexNormal);
220 if (m_NegativeNormalCounter > m_PositiveNormalCounter)
222 for (vtkIdType n = 0; n < cellSize; n++)
225 normals->GetTuple(offSet + n, normal);
226 normal[0] = (-1) * normal[0];
227 normal[1] = (-1) * normal[1];
228 normal[2] = (-1) * normal[2];
229 normals->SetTuple(offSet + n, normal);
233 m_NegativeNormalCounter = 0;
234 m_PositiveNormalCounter = 0;
240 surface->GetVtkPolyData()->GetCellData()->SetNormals(normals);
244 if (this->m_UseProgressBar)
251 vtkSmartPointer<vtkPolyData> newPolyData = vtkSmartPointer<vtkPolyData>::New();
252 vtkSmartPointer<vtkCellArray> newLines = vtkSmartPointer<vtkCellArray>::New();
253 vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
254 unsigned int idCounter(0);
257 for (
unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); i++)
259 auto *currentSurface = this->
GetOutput(i);
260 vtkPolyData *polyData = currentSurface->GetVtkPolyData();
262 vtkSmartPointer<vtkDoubleArray> currentCellNormals =
263 vtkDoubleArray::SafeDownCast(polyData->GetCellData()->GetNormals());
265 vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();
267 vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();
269 existingPolys->InitTraversal();
271 vtkIdType *cell(
nullptr);
272 vtkIdType cellSize(0);
274 for (existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
276 for (vtkIdType j = 0; j < cellSize; j++)
278 double currentNormal[3];
279 currentCellNormals->GetTuple(cell[j], currentNormal);
280 vtkSmartPointer<vtkLine>
line = vtkSmartPointer<vtkLine>::New();
281 line->GetPointIds()->SetNumberOfIds(2);
284 existingPoints->GetPoint(cell[j], p0);
285 newPoint[0] = p0[0] + currentNormal[0];
286 newPoint[1] = p0[1] + currentNormal[1];
287 newPoint[2] = p0[2] + currentNormal[2];
289 line->GetPointIds()->SetId(0, idCounter);
290 newPoints->InsertPoint(idCounter, p0);
293 line->GetPointIds()->SetId(1, idCounter);
294 newPoints->InsertPoint(idCounter, newPoint);
297 newLines->InsertNextCell(line);
302 newPolyData->SetPoints(newPoints);
303 newPolyData->SetLines(newLines);
304 newPolyData->BuildCells();
307 surface->SetVtkPolyData(newPolyData);
314 m_MaxSpacing = maxSpacing;
319 Superclass::GenerateOutputInformation();
324 for (
unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++)
326 this->PopBackInput();
328 this->SetNumberOfIndexedInputs(0);
329 this->SetNumberOfIndexedOutputs(0);
332 this->SetNthOutput(0, output.GetPointer());
337 this->m_UseProgressBar = status;
342 this->m_ProgressStepSize = stepSize;
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
Gives locked and index-based read access for a particular image part. The class provides several set-...
mitk::Surface::Pointer GetNormalsAsSurface()
void GenerateOutputInformation() override
~ComputeContourSetNormalsFilter() 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...
const TPixel & GetPixelByIndexSafe(const itk::Index< VDimension > &idx) const
void SetUseProgressBar(bool)
Set whether the mitkProgressBar should be used.
ComputeContourSetNormalsFilter()
void GenerateData() override
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
void SetMaxSpacing(double)
void Normalize(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output)