diff --git a/CMakeExternals/ACVD.cmake b/CMakeExternals/ACVD.cmake index 9b59889482..787b50a8c1 100644 --- a/CMakeExternals/ACVD.cmake +++ b/CMakeExternals/ACVD.cmake @@ -1,42 +1,42 @@ #----------------------------------------------------------------------------- # ACVD #----------------------------------------------------------------------------- if(MITK_USE_ACVD) # Sanity checks if(DEFINED ACVD_DIR AND NOT EXISTS ${ACVD_DIR}) message(FATAL_ERROR "ACVD_DIR variable is defined but corresponds to non-existing directory") endif() set(proj ACVD) set(proj_DEPENDENCIES VTK) set(ACVD_DEPENDS ${proj}) set(additional_cmake_args -DUSE_MULTITHREADING:BOOL=ON -DVTK_DIR:PATH=${VTK_DIR} ) set(ACVD_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchACVD.cmake) if(NOT DEFINED ACVD_DIR) ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake - URL http://mitk.org/download/thirdparty/ACVD_8bbb6da1.tar.gz - URL_MD5 9cbce5e05e288982e05a95cda780fe64 + URL http://mitk.org/download/thirdparty/ACVD_VTK6.tar.gz + URL_MD5 e99d1cb7d264d421074d5346f1d3ce82 PATCH_COMMAND ${ACVD_PATCH_COMMAND} INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_cmake_args} DEPENDS ${proj_DEPENDENCIES} ) set(ACVD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj}_DEPENDENCIES}") endif() endif() diff --git a/CMakeExternals/PatchACVD.cmake b/CMakeExternals/PatchACVD.cmake index aaa47c6a8e..062adbb8d0 100644 --- a/CMakeExternals/PatchACVD.cmake +++ b/CMakeExternals/PatchACVD.cmake @@ -1,47 +1,63 @@ # Create Config.cmake file to make ACVD findable through config mode of find_package() file(WRITE "ACVDConfig.cmake.in" "set(ACVD_INCLUDE_DIRS \"@VTKSURFACE_INCLUDE_DIR@;@VTKDISCRETEREMESHING_INCLUDE_DIR@;@VTKVOLUMEPROCESSING_INCLUDE_DIR@\") -set(ACVD_LIBRARY_DIRS \"@VTKSURFACE_BINARY_DIR@/bin\") +set(ACVD_LIBRARY_DIRS \"@PROJECT_BINARY_DIR@/bin\") set(ACVD_LIBRARIES vtkSurface vtkDiscreteRemeshing vtkVolumeProcessing) add_definitions(-DDOmultithread)") file(APPEND "CMakeLists.txt" "CONFIGURE_FILE(ACVDConfig.cmake.in ACVDConfig.cmake @ONLY)") +# Add vtkVersionMacros.h header file + +set(path "Common/vtkCurvatureMeasure.h") +file(STRINGS ${path} contents NEWLINE_CONSUME) +string(REPLACE "w.h\"" "w.h\"\n#include " contents ${contents}) +set(CONTENTS ${contents}) +configure_file(${TEMPLATE_FILE} ${path} @ONLY) + # Replace VTK_COMMON_EXPORT by VTK_EXPORT in class declarations set(path "Common/vtkMyMinimalStandardRandomSequence.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "COMMON_" "" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) set(path "DiscreteRemeshing/vtkThreadedClustering.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "COMMON_" "" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) # Add missing VTK_EXPORT to class declaration set(path "VolumeProcessing/vtkImageDataCleanLabels.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "ss" "ss VTK_EXPORT" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) # Replace int by vtkIdType, which are types of different size (x64) set(path "DiscreteRemeshing/vtkVerticesProcessing.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "int N" "vtkIdType N" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) +# Replace VTK 5 module names by VTK 6 module names # Link to POSIX thread library set(path "DiscreteRemeshing/CMakeLists.txt") file(STRINGS ${path} contents NEWLINE_CONSUME) +string(REPLACE "vtkCommon" "vtkCommonCore" contents ${contents}) +string(REPLACE "vtkFiltering" "vtkFiltersCore" contents ${contents}) +string(REPLACE "vtkImaging" "vtkImagingCore" contents ${contents}) +string(REPLACE "vtkIO" "vtkIOCore" contents ${contents}) +string(REPLACE "vtkRendering" "vtkRenderingCore" contents ${contents}) +string(REPLACE "vtkHybrid" "vtkFiltersHybrid vtkImagingHybrid" contents ${contents}) +string(REPLACE "vtkGraphics" "" contents ${contents}) string(REPLACE "TARGET_LINK_LIBRARIES(v" "IF(UNIX AND NOT APPLE)\n LIST(APPEND LIB_ADDED pthread)\nENDIF(UNIX AND NOT APPLE)\n\nTARGET_LINK_LIBRARIES(v" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) diff --git a/Modules/Remeshing/mitkACVD.cpp b/Modules/Remeshing/mitkACVD.cpp index 74939ebe0d..3ea3e3ffd2 100644 --- a/Modules/Remeshing/mitkACVD.cpp +++ b/Modules/Remeshing/mitkACVD.cpp @@ -1,209 +1,209 @@ /*=================================================================== 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 "mitkACVD.h" #include #include #include #include #include #include #include #include #include struct ClustersQuadrics { explicit ClustersQuadrics(int size) : Elements(new double*[size]), Size(size) { for (int i = 0; i < size; ++i) { Elements[i] = new double[9]; for (int j = 0; j < 9; ++j) Elements[i][j] = 0.0; } } ~ClustersQuadrics() { for (int i = 0; i < Size; ++i) delete[] Elements[i]; delete Elements; } double** Elements; int Size; private: ClustersQuadrics(const ClustersQuadrics&); ClustersQuadrics& operator=(const ClustersQuadrics&); }; static void ValidateSurface(mitk::Surface::ConstPointer surface, unsigned int t) { if (surface.IsNull()) mitkThrow() << "Input surface is NULL!"; if (t >= surface->GetSizeOfPolyDataSeries()) mitkThrow() << "Input surface doesn't have data at time step " << t << "!"; vtkPolyData* polyData = const_cast(surface.GetPointer())->GetVtkPolyData(t); if (polyData == NULL) mitkThrow() << "PolyData of input surface at time step " << t << " is NULL!"; if (polyData->GetNumberOfPolys() == 0) mitkThrow() << "Input surface has no polygons at time step " << t << "!"; } mitk::Surface::Pointer mitk::ACVD::Remesh(mitk::Surface::ConstPointer surface, unsigned int t, int numVertices, double gradation, int subsampling, double edgeSplitting, int optimizationLevel, bool forceManifold, bool boundaryFixing) { ValidateSurface(surface, t); MITK_INFO << "Start remeshing..."; vtkSmartPointer surfacePolyData = vtkSmartPointer::New(); surfacePolyData->DeepCopy(const_cast(surface.GetPointer())->GetVtkPolyData(t)); vtkSmartPointer mesh = vtkSmartPointer::New(); mesh->CreateFromPolyData(surfacePolyData); mesh->GetCellData()->Initialize(); mesh->GetPointData()->Initialize(); mesh->DisplayMeshProperties(); if (numVertices == 0) numVertices = surfacePolyData->GetNumberOfPoints(); if (edgeSplitting != 0.0) mesh->SplitLongEdges(edgeSplitting); vtkSmartPointer remesher = vtkSmartPointer::New(); remesher->GetMetric()->SetGradation(gradation); remesher->SetBoundaryFixing(boundaryFixing); remesher->SetConsoleOutput(1); remesher->SetForceManifold(forceManifold); remesher->SetInput(mesh); remesher->SetNumberOfClusters(numVertices); remesher->SetNumberOfThreads(vtkMultiThreader::GetGlobalDefaultNumberOfThreads()); remesher->SetSubsamplingThreshold(subsampling); remesher->Remesh(); // Optimization: Minimize distance between input surface and remeshed surface if (optimizationLevel != 0) { ClustersQuadrics clustersQuadrics(numVertices); vtkSmartPointer faceList = vtkSmartPointer::New(); vtkSmartPointer clustering = remesher->GetClustering(); vtkSmartPointer remesherInput = remesher->GetInput(); int clusteringType = remesher->GetClusteringType(); int numItems = remesher->GetNumberOfItems(); int numMisclassifiedItems = 0; for (int i = 0; i < numItems; ++i) { int cluster = clustering->GetValue(i); if (cluster >= 0 && cluster < numVertices) { if (clusteringType != 0) { remesherInput->GetVertexNeighbourFaces(i, faceList); int numIds = static_cast(faceList->GetNumberOfIds()); for (int j = 0; j < numIds; ++j) vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, faceList->GetId(j), false); } else { vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, i, false); } } else { ++numMisclassifiedItems; } } if (numMisclassifiedItems != 0) std::cout << numMisclassifiedItems << " items with wrong cluster association" << std::endl; vtkSmartPointer remesherOutput = remesher->GetOutput(); double point[3]; for (int i = 0; i < numVertices; ++i) { remesherOutput->GetPoint(i, point); vtkQuadricTools::ComputeRepresentativePoint(clustersQuadrics.Elements[i], point, optimizationLevel); remesherOutput->SetPointCoordinates(i, point); } std::cout << "After quadrics post-processing:" << std::endl; remesherOutput->DisplayMeshProperties(); } vtkSmartPointer normals = vtkSmartPointer::New(); - normals->SetInput(remesher->GetOutput()); + normals->SetInputData(remesher->GetOutput()); normals->AutoOrientNormalsOn(); normals->ComputeCellNormalsOff(); normals->ComputePointNormalsOn(); normals->ConsistencyOff(); normals->FlipNormalsOff(); normals->NonManifoldTraversalOff(); normals->SplittingOff(); normals->Update(); Surface::Pointer remeshedSurface = Surface::New(); remeshedSurface->SetVtkPolyData(normals->GetOutput()); MITK_INFO << "Finished remeshing"; return remeshedSurface; } mitk::ACVD::RemeshFilter::RemeshFilter() : m_TimeStep(0), m_NumVertices(0), m_Gradation(1.0), m_Subsampling(10), m_EdgeSplitting(0.0), m_OptimizationLevel(1), m_ForceManifold(false), m_BoundaryFixing(false) { Surface::Pointer output = Surface::New(); this->SetNthOutput(0, output); } mitk::ACVD::RemeshFilter::~RemeshFilter() { } void mitk::ACVD::RemeshFilter::GenerateData() { Surface::Pointer output = Remesh(this->GetInput(), m_TimeStep, m_NumVertices, m_Gradation, m_Subsampling, m_EdgeSplitting, m_OptimizationLevel, m_ForceManifold, m_BoundaryFixing); this->SetNthOutput(0, output); }