diff --git a/Modules/Segmentation/Testing/files.cmake b/Modules/Segmentation/Testing/files.cmake index 5fe0287ffc..253dd2e6ef 100644 --- a/Modules/Segmentation/Testing/files.cmake +++ b/Modules/Segmentation/Testing/files.cmake @@ -1,40 +1,41 @@ set(MODULE_TESTS + mitkComputeContourSetNormalsFilterTest.cpp mitkContourMapper2DTest.cpp mitkContourTest.cpp mitkDataNodeSegmentationTest.cpp mitkImageToContourFilterTest.cpp # mitkSegmentationInterpolationTest.cpp mitkOverwriteSliceFilterTest.cpp mitkOverwriteSliceFilterObliquePlaneTest.cpp # mitkToolManagerTest.cpp mitkReduceContourSetFilterTest.cpp mitkToolManagerProviderTest.cpp ) set(MODULE_IMAGE_TESTS mitkManualSegmentationToSurfaceFilterTest.cpp #only runs on images mitkOverwriteSliceImageFilterTest.cpp #only runs on images ) set(MODULE_CUSTOM_TESTS ) set(MODULE_TESTIMAGES US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png Sigmoid.nrrd Sigmoid-2D-as-3D.nrrd ) # Create an artificial module initializing class for # usServices set(testdriver_init_file ) usFunctionGenerateModuleInit(testdriver_init_file NAME SegmentationTestDriver DEPENDS "Segmentation" VERSION "0.1.0" ) set(TEST_CPP_FILES ${testdriver_init_file}) diff --git a/Modules/Segmentation/Testing/mitkComputeContourSetNormalsFilterTest.cpp b/Modules/Segmentation/Testing/mitkComputeContourSetNormalsFilterTest.cpp new file mode 100644 index 0000000000..90a4e72630 --- /dev/null +++ b/Modules/Segmentation/Testing/mitkComputeContourSetNormalsFilterTest.cpp @@ -0,0 +1,89 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class mitkComputeContourSetNormalsFilterTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkComputeContourSetNormalsFilterTestSuite); + MITK_TEST(TestComputeNormals); + MITK_TEST(TestComputeNormalsWithHole); + CPPUNIT_TEST_SUITE_END(); + +private: + + mitk::ComputeContourSetNormalsFilter::Pointer m_ContourNormalsFilter; + +public: + + void setUp() + { + m_ContourNormalsFilter = mitk::ComputeContourSetNormalsFilter::New(); + CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourNormalsFilter.IsNotNull()); + } + + // Compute the normals for a regular contour + void TestComputeNormals() + { + mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); + m_ContourNormalsFilter->SetInput(contour); + m_ContourNormalsFilter->Update(); + // Get the computed normals (basically lines) + mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); + // Get the actual surface object which has the contours stored as normals internally + mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); + + mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithNormals.vtk")); + mitk::Surface::Pointer referenceNormals = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourNormals.vtk")); + + CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(contourWithNormals->GetVtkPolyData(), referenceContour->GetVtkPolyData(), 0.000001, true)); + CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(normals->GetVtkPolyData(), referenceNormals->GetVtkPolyData(), 0.000001, true)); + } + + + + // Reduce contours with Douglas Peucker + void TestComputeNormalsWithHole() + { + mitk::Image::Pointer segmentationImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/LiverSegmentation.nrrd")); + + mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/ComputeNormals/ContourWithHoles.vtk")); + m_ContourNormalsFilter->SetInput(contour); + m_ContourNormalsFilter->SetSegmentationBinaryImage(segmentationImage); + m_ContourNormalsFilter->Update(); + mitk::Surface::Pointer contourWithNormals = m_ContourNormalsFilter->GetOutput(); + mitk::Surface::Pointer normals = m_ContourNormalsFilter->GetNormalsAsSurface(); + + mitk::Surface::Pointer contourReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ContourWithHolesWithNormals.vtk")); + mitk::Surface::Pointer normalsReference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/NormalsWithHoles.vtk")); + + CPPUNIT_ASSERT_MESSAGE("Error computing normals", mitk::Equal(normals->GetVtkPolyData(), normalsReference->GetVtkPolyData(), 0.000001, true)); + CPPUNIT_ASSERT_MESSAGE("Error computing normals", + contourWithNormals->GetVtkPolyData()->GetCellData()->GetNormals()->GetNumberOfTuples() == contourReference->GetVtkPolyData()->GetNumberOfPoints()); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkComputeContourSetNormalsFilter) diff --git a/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp b/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp index d661026551..91102af916 100644 --- a/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkImageToContourFilterTest.cpp @@ -1,107 +1,109 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include class mitkImageToContourFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkImageToContourFilterTestSuite); MITK_TEST(TestExtractContoursFromAnEmptySlice); MITK_TEST(TestExtractASingleContourFromASlice); MITK_TEST(TestExtractTwoContoursFromASingleSlice); CPPUNIT_TEST_SUITE_END(); private: mitk::Image::Pointer m_EmptySlice; mitk::Image::Pointer m_SliceWithSingleContour; mitk::Image::Pointer m_SliceWithTwoContours; mitk::ImageToContourFilter::Pointer m_ContourExtractor; public: void setUp() { //Load the image //TODO Move/create segmentation subfolder - m_EmptySlice = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/EmptySlice.nrrd")); + m_EmptySlice = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/EmptySlice.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [EmptySlice.nrrd]", m_EmptySlice.IsNotNull()); - m_SliceWithSingleContour = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/SliceWithSingleContour.nrrd")); + m_SliceWithSingleContour = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithSingleContour.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [SliceWithSingleContour.nrrd]", m_SliceWithSingleContour.IsNotNull()); - m_SliceWithTwoContours = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/SliceWithTwoContours.nrrd")); + m_SliceWithTwoContours = mitk::IOUtil::LoadImage(GetTestDataFilePath("SurfaceInterpolation/ImageToContour/SliceWithTwoContours.nrrd")); CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [SliceWithTwoContours.nrrd]", m_SliceWithTwoContours.IsNotNull()); m_ContourExtractor = mitk::ImageToContourFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ImageToContourFilter", m_ContourExtractor.IsNotNull()); } // Extract contours from an empty slice void TestExtractContoursFromAnEmptySlice() { m_ContourExtractor->SetInput(m_EmptySlice); m_ContourExtractor->Update(); mitk::Surface::Pointer emptyContour = m_ContourExtractor->GetOutput(); CPPUNIT_ASSERT_MESSAGE("Extracted contour is not empty", emptyContour->GetVtkPolyData()->GetNumberOfPoints() == 0); } // Extract a single contour from a slice void TestExtractASingleContourFromASlice() { m_ContourExtractor->SetInput(m_SliceWithSingleContour); m_ContourExtractor->Update(); CPPUNIT_ASSERT_MESSAGE("ImageToContourFilter has wrong number of outputs!", m_ContourExtractor->GetNumberOfOutputs() == 1); mitk::Surface::Pointer contour = m_ContourExtractor->GetOutput(); - mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/SingleContour_Reference.vtk")); + + mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); CPPUNIT_ASSERT_MESSAGE("Extracted contour has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPoints() == referenceContour->GetVtkPolyData()->GetNumberOfPoints()); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(contour->GetVtkPolyData(), referenceContour->GetVtkPolyData(), 0.000001, true)); } // Extract multiple contours from a single slice void TestExtractTwoContoursFromASingleSlice() { m_ContourExtractor->SetInput(m_SliceWithTwoContours); m_ContourExtractor->Update(); CPPUNIT_ASSERT_MESSAGE("ImageToContourFilter has wrong number of outputs!", m_ContourExtractor->GetNumberOfOutputs() == 1); mitk::Surface::Pointer contour = m_ContourExtractor->GetOutput(0); - mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/TwoContours_Reference.vtk")); + + mitk::Surface::Pointer referenceContour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk")); CPPUNIT_ASSERT_MESSAGE("Extracted contour1 has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPoints() == referenceContour->GetVtkPolyData()->GetNumberOfPoints()); CPPUNIT_ASSERT_MESSAGE("Extracted contour1 has wrong number of points!", contour->GetVtkPolyData()->GetNumberOfPolys() == referenceContour->GetVtkPolyData()->GetNumberOfPolys()); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(contour->GetVtkPolyData(), referenceContour->GetVtkPolyData(), 0.000001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkImageToContourFilter) diff --git a/Modules/Segmentation/Testing/mitkReduceContourSetFilterTest.cpp b/Modules/Segmentation/Testing/mitkReduceContourSetFilterTest.cpp index 1fe0b0a7ea..6ead064e22 100644 --- a/Modules/Segmentation/Testing/mitkReduceContourSetFilterTest.cpp +++ b/Modules/Segmentation/Testing/mitkReduceContourSetFilterTest.cpp @@ -1,74 +1,74 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include class mitkReduceContourSetFilterTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkReduceContourSetFilterTestSuite); MITK_TEST(TestReduceContourWithNthPoint); MITK_TEST(TestReduceContourWithDouglasPeuker); CPPUNIT_TEST_SUITE_END(); private: mitk::ReduceContourSetFilter::Pointer m_ContourReducer; public: void setUp() { m_ContourReducer = mitk::ReduceContourSetFilter::New(); CPPUNIT_ASSERT_MESSAGE("Failed to initialize ReduceContourSetFilter", m_ContourReducer.IsNotNull()); } // Reduce contours with nth point void TestReduceContourWithNthPoint() { - mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/SingleContour_Reference.vtk")); + mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/SingleContour.vtk")); m_ContourReducer->SetInput(contour); m_ContourReducer->SetReductionType(mitk::ReduceContourSetFilter::NTH_POINT); m_ContourReducer->SetStepSize(20); m_ContourReducer->Update(); mitk::Surface::Pointer reducedContour = m_ContourReducer->GetOutput(); - mitk::Surface::Pointer reference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/ReducedContourNthPoint_20_Reference.vtk")); + mitk::Surface::Pointer reference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourNthPoint_20.vtk")); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(reducedContour->GetVtkPolyData(), reference->GetVtkPolyData(), 0.000001, true)); } // Reduce contours with Douglas Peucker void TestReduceContourWithDouglasPeuker() { - mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/TwoContours_Reference.vtk")); + mitk::Surface::Pointer contour = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/TwoContours.vtk")); m_ContourReducer->SetInput(contour); m_ContourReducer->SetReductionType(mitk::ReduceContourSetFilter::DOUGLAS_PEUCKER); m_ContourReducer->Update(); mitk::Surface::Pointer reducedContour = m_ContourReducer->GetOutput(); - mitk::Surface::Pointer reference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/ReducedContourDouglasPeucker_Reference.vtk")); + mitk::Surface::Pointer reference = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SurfaceInterpolation/Reference/ReducedContourDouglasPeucker.vtk")); CPPUNIT_ASSERT_MESSAGE("Unequal contours", mitk::Equal(reducedContour->GetVtkPolyData(), reference->GetVtkPolyData(), 0.000001, true)); } }; MITK_TEST_SUITE_REGISTRATION(mitkReduceContourSetFilter) diff --git a/Modules/SurfaceInterpolation/mitkComputeContourSetNormalsFilter.cpp b/Modules/SurfaceInterpolation/mitkComputeContourSetNormalsFilter.cpp index 7589adbeae..9c6ab2bdbd 100644 --- a/Modules/SurfaceInterpolation/mitkComputeContourSetNormalsFilter.cpp +++ b/Modules/SurfaceInterpolation/mitkComputeContourSetNormalsFilter.cpp @@ -1,319 +1,321 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkComputeContourSetNormalsFilter.h" #include "mitkImagePixelReadAccessor.h" mitk::ComputeContourSetNormalsFilter::ComputeContourSetNormalsFilter() { m_MaxSpacing = 5; this->m_UseProgressBar = false; this->m_ProgressStepSize = 1; mitk::Surface::Pointer output = mitk::Surface::New(); this->SetNthOutput(0, output.GetPointer()); } mitk::ComputeContourSetNormalsFilter::~ComputeContourSetNormalsFilter() { } void mitk::ComputeContourSetNormalsFilter::GenerateData() { unsigned int numberOfInputs = this->GetNumberOfIndexedInputs(); this->CreateOutputsForAllInputs(numberOfInputs); //Iterating over each input for(unsigned int i = 0; i < numberOfInputs; i++) { //Getting the inputs polydata and polygons Surface* currentSurface = const_cast( this->GetInput(i) ); vtkPolyData* polyData = currentSurface->GetVtkPolyData(); vtkSmartPointer existingPolys = polyData->GetPolys(); vtkSmartPointer existingPoints = polyData->GetPoints(); existingPolys->InitTraversal(); vtkIdType* cell (NULL); vtkIdType cellSize (0); //The array that contains all the vertex normals of the current polygon vtkSmartPointer normals = vtkSmartPointer::New(); normals->SetNumberOfComponents(3); normals->SetNumberOfTuples(polyData->GetNumberOfPoints()); //If the current contour is an inner contour then the direction is -1 //A contour lies inside another one if the pixel values in the direction of the normal is 1 m_NegativeNormalCounter = 0; m_PositiveNormalCounter = 0; + vtkIdType offSet (0); //Iterating over each polygon for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);) { if(cellSize < 3)continue; //First we calculate the current polygon's normal double polygonNormal[3] = {0.0}; double p1[3]; double p2[3]; double v1[3]; double v2[3]; existingPoints->GetPoint(cell[0], p1); unsigned int index = cellSize*0.5; existingPoints->GetPoint(cell[index], p2); v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; for (unsigned int k = 2; k < cellSize; k++) { index = cellSize*0.25; existingPoints->GetPoint(cell[index], p1); index = cellSize*0.75; existingPoints->GetPoint(cell[index], p2); v2[0] = p2[0]-p1[0]; v2[1] = p2[1]-p1[1]; v2[2] = p2[2]-p1[2]; vtkMath::Cross(v1,v2,polygonNormal); if (vtkMath::Norm(polygonNormal) != 0) break; } vtkMath::Normalize(polygonNormal); //Now we start computing the normal for each vertex double vertexNormalTemp[3]; existingPoints->GetPoint(cell[0], p1); existingPoints->GetPoint(cell[1], p2); v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; vtkMath::Cross(v1,polygonNormal,vertexNormalTemp); vtkMath::Normalize(vertexNormalTemp); double vertexNormal[3]; for (unsigned j = 0; j < cellSize-2; j++) { existingPoints->GetPoint(cell[j+1], p1); existingPoints->GetPoint(cell[j+2], p2); v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; vtkMath::Cross(v1,polygonNormal,vertexNormal); vtkMath::Normalize(vertexNormal); double finalNormal[3]; finalNormal[0] = (vertexNormal[0] + vertexNormalTemp[0])*0.5; finalNormal[1] = (vertexNormal[1] + vertexNormalTemp[1])*0.5; finalNormal[2] = (vertexNormal[2] + vertexNormalTemp[2])*0.5; //Here we determine the direction of the normal - if (j == 0 && m_SegmentationBinaryImage) + if (m_SegmentationBinaryImage) { Point3D worldCoord; worldCoord[0] = p1[0]+finalNormal[0]*m_MaxSpacing; worldCoord[1] = p1[1]+finalNormal[1]*m_MaxSpacing; worldCoord[2] = p1[2]+finalNormal[2]*m_MaxSpacing; double val = 0.0; mitk::ImagePixelReadAccessor readAccess(m_SegmentationBinaryImage); mitk::Index3D idx; m_SegmentationBinaryImage->GetGeometry()->WorldToIndex(worldCoord, idx); val = readAccess.GetPixelByIndexSafe(idx); - if (val == 1.0) + if (val == 0.0) { ++m_PositiveNormalCounter; } else { ++m_NegativeNormalCounter; } } vertexNormalTemp[0] = vertexNormal[0]; vertexNormalTemp[1] = vertexNormal[1]; vertexNormalTemp[2] = vertexNormal[2]; vtkIdType id = cell[j+1]; normals->SetTuple(id,finalNormal); } existingPoints->GetPoint(cell[0], p1); existingPoints->GetPoint(cell[1], p2); v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; vtkMath::Cross(v1,polygonNormal,vertexNormal); vtkMath::Normalize(vertexNormal); vertexNormal[0] = (vertexNormal[0] + vertexNormalTemp[0])*0.5; vertexNormal[1] = (vertexNormal[1] + vertexNormalTemp[1])*0.5; vertexNormal[2] = (vertexNormal[2] + vertexNormalTemp[2])*0.5; vtkIdType id = cell[0]; normals->SetTuple(id,vertexNormal); id = cell[cellSize-1]; normals->SetTuple(id,vertexNormal); - int normalDirection(-1); - - if(m_NegativeNormalCounter < m_PositiveNormalCounter) + if(m_NegativeNormalCounter > m_PositiveNormalCounter) { - normalDirection = 1; + for(vtkIdType n = 0; n < cellSize; n++) + { + double normal[3]; + normals->GetTuple(offSet+n, normal); + normal[0] = (-1)*normal[0]; + normal[1] = (-1)*normal[1]; + normal[2] = (-1)*normal[2]; + normals->SetTuple(offSet+n, normal); + } } - for(unsigned int n = 0; n < normals->GetNumberOfTuples(); n++) - { - double normal[3]; - normals->GetTuple(n,normal); - normal[0] = normalDirection*normal[0]; - normal[1] = normalDirection*normal[1]; - normal[2] = normalDirection*normal[2]; - } + m_NegativeNormalCounter = 0; + m_PositiveNormalCounter = 0; + offSet += cellSize; }//end for all cells Surface::Pointer surface = this->GetOutput(i); surface->GetVtkPolyData()->GetCellData()->SetNormals(normals); }//end for all inputs //Setting progressbar if (this->m_UseProgressBar) mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize); } mitk::Surface::Pointer mitk::ComputeContourSetNormalsFilter::GetNormalsAsSurface() { //Just for debugging: vtkSmartPointer newPolyData = vtkSmartPointer::New(); vtkSmartPointer newLines = vtkSmartPointer::New(); vtkSmartPointer newPoints = vtkSmartPointer::New(); unsigned int idCounter (0); //Debug end for (unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); i++) { Surface* currentSurface = const_cast( this->GetOutput(i) ); vtkPolyData* polyData = currentSurface->GetVtkPolyData(); vtkSmartPointer currentCellNormals = vtkDoubleArray::SafeDownCast(polyData->GetCellData()->GetNormals()); vtkSmartPointer existingPolys = polyData->GetPolys(); vtkSmartPointer existingPoints = polyData->GetPoints(); existingPolys->InitTraversal(); vtkIdType* cell (NULL); vtkIdType cellSize (0); for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);) { for ( unsigned int j = 0; j < cellSize; j++ ) { double currentNormal[3]; currentCellNormals->GetTuple(cell[j], currentNormal); vtkSmartPointer line = vtkSmartPointer::New(); line->GetPointIds()->SetNumberOfIds(2); double newPoint[3]; double p0[3]; existingPoints->GetPoint(cell[j], p0); newPoint[0] = p0[0] + currentNormal[0]; newPoint[1] = p0[1] + currentNormal[1]; newPoint[2] = p0[2] + currentNormal[2]; line->GetPointIds()->SetId(0, idCounter); newPoints->InsertPoint(idCounter, p0); idCounter++; line->GetPointIds()->SetId(1, idCounter); newPoints->InsertPoint(idCounter, newPoint); idCounter++; newLines->InsertNextCell(line); }//end for all points }//end for all cells }//end for all outputs newPolyData->SetPoints(newPoints); newPolyData->SetLines(newLines); newPolyData->BuildCells(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(newPolyData); return surface; } void mitk::ComputeContourSetNormalsFilter::SetMaxSpacing(double maxSpacing) { m_MaxSpacing = maxSpacing; } void mitk::ComputeContourSetNormalsFilter::GenerateOutputInformation() { Superclass::GenerateOutputInformation(); } void mitk::ComputeContourSetNormalsFilter::Reset() { for (unsigned int i = 0; i < this->GetNumberOfIndexedInputs(); i++) { this->PopBackInput(); } this->SetNumberOfIndexedInputs(0); this->SetNumberOfIndexedOutputs(0); mitk::Surface::Pointer output = mitk::Surface::New(); this->SetNthOutput(0, output.GetPointer()); } void mitk::ComputeContourSetNormalsFilter::SetUseProgressBar(bool status) { this->m_UseProgressBar = status; } void mitk::ComputeContourSetNormalsFilter::SetProgressStepSize(unsigned int stepSize) { this->m_ProgressStepSize = stepSize; }