diff --git a/.gitignore b/.gitignore index d33c4cdb..109312e9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ qtcreator-build/ #OSX specifics .DS_Store + +*.orig + diff --git a/CMake/ConfigBoost.cmake b/CMake/ConfigBoost.cmake index a79298c8..2d79cab9 100644 --- a/CMake/ConfigBoost.cmake +++ b/CMake/ConfigBoost.cmake @@ -3,5 +3,5 @@ FIND_PACKAGE( Boost REQUIRED ) IF( Boost_FOUND ) INCLUDE_DIRECTORIES( BEFORE ${Boost_INCLUDE_DIRS} ) ELSE( Boost_FOUND ) - MESSAGE( SEND_ERROR "BOOST NOT FOUND, CMAKE WILL STOP NOW") + MESSAGE( SEND_ERROR "BOOST NOT FOUND, CMAKE WILL STOP NOW") ENDIF( Boost_FOUND ) diff --git a/CMake/ConfigITK.cmake b/CMake/ConfigITK.cmake index 7e1c48d7..ae9fa659 100644 --- a/CMake/ConfigITK.cmake +++ b/CMake/ConfigITK.cmake @@ -1,36 +1,66 @@ #---------------------------------------------------------- FIND_PACKAGE( ITK REQUIRED ) -IF( ITK_FOUND ) - + IF( ITK_FOUND ) #---------------------------------------------------------- INCLUDE( ${ITK_USE_FILE} ) #---------------------------------------------------------- # Check the version of ITK - IF( ( ${ITK_VERSION_MAJOR} LESS 3 ) OR - ( ( ${ITK_VERSION_MAJOR} EQUAL 3 ) AND - ( ${ITK_VERSION_MINOR} LESS 18 ) ) ) - MESSAGE( SEND_ERROR - "GoFigure2 requires ITK 3.18 or newer version (your version of ITK is ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH})" ) - ENDIF( ( ${ITK_VERSION_MAJOR} LESS 3 ) OR - ( ( ${ITK_VERSION_MAJOR} EQUAL 3 ) AND - ( ${ITK_VERSION_MINOR} LESS 18 ) ) ) - + # ( by checking the existence of a variable + # can't check version: 4.0.0 is modularized and old style...) #---------------------------------------------------------- - # Check if "REVIEW" is "ON" - IF( ${ITK_VERSION_MAJOR} EQUAL 3 ) - IF( ( ${ITK_USE_REVIEW} MATCHES "OFF" ) OR - ( ${ITK_USE_REVIEW_STATISTICS} MATCHES "OFF" ) ) - MESSAGE( SEND_ERROR - "GoFigure2 requires ITK to be compiled with USE_REVIEW and USE_REVIEW_STATISTICS turned ON" ) - ENDIF( ( ${ITK_USE_REVIEW} MATCHES "OFF" ) OR - ( ${ITK_USE_REVIEW_STATISTICS} MATCHES "OFF" ) ) - ELSE( ${ITK_VERSION_MAJOR} EQUAL 3 ) - IF( ${ITK_USE_REVIEW} MATCHES "OFF" ) + IF( ITK_VERSION_MAJOR EQUAL "4" ) + + ADD_DEFINITIONS( -DITKv4 ) + + IF( NOT DEFINED ITK_MODULES_ENABLED ) MESSAGE( SEND_ERROR - "GoFigure2 requires ITK to be compiled with USE_REVIEW turned ON" ) - ENDIF( ${ITK_USE_REVIEW} MATCHES "OFF" ) - ENDIF( ${ITK_VERSION_MAJOR} EQUAL 3 ) + "WRONG VERSION OF ITK, REQUIERES MODULARIZED ITK, CMAKE WILL STOP NOW") + ENDIF ( NOT DEFINED ITK_MODULES_ENABLED ) + + # check if requiered modules are enabled + # note that ITK-Review requires all modules to be turned ON... + list(FIND ITK_MODULES_ENABLED ITK-Review ITK-Review_FOUND) + IF( ITK-Review_FOUND LESS 0 ) + MESSAGE( SEND_ERROR "GoFigure2 requires ITK to be compiled with ITK-Review turned ON") + ENDIF( ITK-Review_FOUND LESS 0 ) + + ELSE( ITK_VERSION_MAJOR EQUAL "4" ) + + REMOVE_DEFINITIONS( -DITKv4 ) + # Make sure it is at least ITK 3 + IF( ITK_VERSION_MAJOR EQUAL "3" ) + + # Make sure it is ITK 3.20 + IF( ITK_VERSION_MINOR EQUAL "20" ) + + # Make sure it is ITK 3.20.1 + IF( ITK_VERSION_PATCH EQUAL "1" ) + + IF( ( ${ITK_USE_REVIEW} MATCHES "OFF" ) OR + ( ${ITK_USE_REVIEW_STATISTICS} MATCHES "OFF" ) ) + MESSAGE( SEND_ERROR + "GoFigure2 requires ITK to be compiled with USE_REVIEW" + " and USE_REVIEW_STATISTICS turned ON" ) + ENDIF() + + ELSE( ITK_VERSION_PATCH EQUAL "1" ) + MESSAGE( SEND_ERROR "GoFigure2 requires at ITK 3.20.1" ) + ENDIF( ITK_VERSION_PATCH EQUAL "1" ) + + ELSE( ITK_VERSION_MINOR EQUAL "20" ) + + MESSAGE( SEND_ERROR "GoFigure2 requires at ITK 3.20.1" ) + + ENDIF( ITK_VERSION_MINOR EQUAL "20" ) + + ELSE( ITK_VERSION_MAJOR EQUAL "3" ) + + MESSAGE( SEND_ERROR "GoFigure2 requires at ITK 3.20.1" ) + + ENDIF( ITK_VERSION_MAJOR EQUAL "3" ) + + ENDIF( ITK_VERSION_MAJOR EQUAL "4" ) ELSE( ITK_FOUND ) MESSAGE( SEND_ERROR "ITK NOT FOUND, CMAKE WILL STOP NOW") diff --git a/CMake/SuperBuild/External-Boost.cmake b/CMake/SuperBuild/External-Boost.cmake index 2a37cff6..b2cee511 100644 --- a/CMake/SuperBuild/External-Boost.cmake +++ b/CMake/SuperBuild/External-Boost.cmake @@ -2,10 +2,10 @@ # Get and build boost set( proj Boost ) -set( version 1.45.0 ) +set( version 1.46.1 ) ExternalProject_Add(${proj} - GIT_REPOSITORY "${git_protocol}://github.com/boost-lib/boost-cmake.git" + GIT_REPOSITORY "${git_protocol}://github.com/pocb/boost.git" GIT_TAG "origin/cmake-${version}" SOURCE_DIR ${proj} BINARY_DIR ${proj}-build diff --git a/CMake/SuperBuild/External-FFMPEG.cmake b/CMake/SuperBuild/External-FFMPEG.cmake index 33615e93..b57b85d1 100644 --- a/CMake/SuperBuild/External-FFMPEG.cmake +++ b/CMake/SuperBuild/External-FFMPEG.cmake @@ -9,6 +9,18 @@ IF( SUPER_SHARED_LIBS ) set( SHARED_FFMPEG --enable-shared ) ENDIF( SUPER_SHARED_LIBS ) +OPTION( FFMPEG_GPL "Use a GPL version of FFMPEG" OFF ) + +SET(FFMPEG_GPL_FLAG "") + +IF( FFMPEG_GPL ) + SET(FFMPEG_GPL_FLAG "--enable-gpl") + SET(msg "ATTENTION: You have enabled the use of GPL components of FFMPEG.") + SET(msg "${msg} By enabling this option, the binary of GoFigure2") + SET(msg "${msg} that you are going to build will be covered by a GPL license.") + MESSAGE("${msg}") +ENDIF( FFMPEG_GPL ) + SET(FFMPEG_INSTALL_DIR ${CMAKE_BINARY_DIR}/${proj}-install) ExternalProject_Add(${proj} @@ -16,14 +28,15 @@ ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} INSTALL_DIR ${FFMPEG_INSTALL_DIR} # get the project - GIT_REPOSITORY "${git_protocol}://git.ffmpeg.org/ffmpeg.git" + GIT_REPOSITORY "${git_protocol}://git.videolan.org/ffmpeg.git" + GIT_TAG "ffmpeg-0.6.3" # Build the project BUILD_IN_SOURCE 1 - + # Configure step # DO STH FOR THE ARCHITECTURE... - CONFIGURE_COMMAND /configure --prefix=${FFMPEG_INSTALL_DIR} ${SHARED_FFMPEG} --enable-gpl --enable-avfilter --disable-yasm --disable-decoders --disable-zlib --disable-demuxer=matroska + CONFIGURE_COMMAND /configure --prefix=${FFMPEG_INSTALL_DIR} ${SHARED_FFMPEG} ${FFMPEG_GPL_FLAG} --enable-avfilter --disable-yasm --disable-decoders --disable-zlib --disable-demuxer=matroska ) # define the library suffix diff --git a/CMake/SuperBuild/External-ITK.cmake b/CMake/SuperBuild/External-ITK.cmake index 3735ed7b..22b706c6 100644 --- a/CMake/SuperBuild/External-ITK.cmake +++ b/CMake/SuperBuild/External-ITK.cmake @@ -3,9 +3,15 @@ set(proj ITK) +if( WIN32 ) + set( ITK_TAG "release" ) +else() + set( ITK_TAG "2260c095f5809045a10d76cca0acee326502ac53" ) +endif() + ExternalProject_Add(${proj} GIT_REPOSITORY "${git_protocol}://itk.org/ITK.git" - GIT_TAG "v4.0a06" + GIT_TAG "${ITK_TAG}" UPDATE_COMMAND "" SOURCE_DIR ${proj} BINARY_DIR ${proj}-build @@ -13,7 +19,8 @@ ExternalProject_Add(${proj} CMAKE_ARGS ${ep_common_args} -DITK_INSTALL_LIB_DIR:PATH=${GOFIGURE2_INSTALL_LIB_DIR} - -DITK_USE_REVIEW:BOOL=ON + # should change soon + -DITK_USE_REVIEW:INTERNAL=ON INSTALL_COMMAND "" DEPENDS ${ITK_DEPENDENCIES} diff --git a/CMakeLists.txt b/CMakeLists.txt index b4c9061b..9b133038 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,6 @@ ELSE( SUPERBUILD ) #---------------------------------------------------------- # Then find ITK #### ITK #### - INCLUDE( "${GOFIGURE2_SOURCE_DIR}/CMake/ConfigITK.cmake" ) #---------------------------------------------------------- @@ -203,8 +202,15 @@ ELSE( SUPERBUILD ) ${GOFIGURE2_BINARY_DIR}/Code/ ${GOFIGURE2_SOURCE_DIR}/Code/IO/ ${GOFIGURE2_BINARY_DIR}/Code/IO/ + ${GOFIGURE2_SOURCE_DIR}/Code/IO/GoImage/ + ${GOFIGURE2_BINARY_DIR}/Code/IO/GoImage/ ${GOFIGURE2_SOURCE_DIR}/Code/Filters/ ${GOFIGURE2_BINARY_DIR}/Code/Filters/ + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Contour/ + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/ + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Attributes/ + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Split/ + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/Merge/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/ @@ -218,6 +224,10 @@ ELSE( SUPERBUILD ) ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/Video/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/Wizard/ ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/Wizard/ + ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/TraceEditing/ + ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/TraceEditing/ + ${GOFIGURE2_SOURCE_DIR}/Code/GUI/lib/TransferFunctionEditor/ + ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/TransferFunctionEditor/ ${GOFIGURE2_SOURCE_DIR}/Interfaces/ ${GOFIGURE2_BINARY_DIR}/Interfaces/ ${GOFIGURE2_SOURCE_DIR}/Code/GUI/src/ @@ -323,6 +333,4 @@ ELSE( SUPERBUILD ) "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/GOFIGURE2Uninstall.cmake" ) - INCLUDE( GOFIGURE2CPack.cmake ) - ENDIF( SUPERBUILD ) diff --git a/Code/GUI/lib/QGoTabImageView4D.cxx b/Code/Attic/QGoTabImageView4D.cxx similarity index 100% rename from Code/GUI/lib/QGoTabImageView4D.cxx rename to Code/Attic/QGoTabImageView4D.cxx diff --git a/Code/GUI/lib/QGoTabImageView4D.h b/Code/Attic/QGoTabImageView4D.h similarity index 100% rename from Code/GUI/lib/QGoTabImageView4D.h rename to Code/Attic/QGoTabImageView4D.h diff --git a/Code/GUI/lib/Resources/SegmentationSeedBaseWidget.ui b/Code/Attic/SegmentationSeedBaseWidget.ui similarity index 100% rename from Code/GUI/lib/Resources/SegmentationSeedBaseWidget.ui rename to Code/Attic/SegmentationSeedBaseWidget.ui diff --git a/Code/CMakeLists.txt b/Code/CMakeLists.txt index f238e1fa..ab86bb85 100644 --- a/Code/CMakeLists.txt +++ b/Code/CMakeLists.txt @@ -1,8 +1,10 @@ +# add subdirectories ADD_SUBDIRECTORY( ExternalCode ) ADD_SUBDIRECTORY( Database ) ADD_SUBDIRECTORY( IO ) -ADD_SUBDIRECTORY( GUI ) ADD_SUBDIRECTORY( Filters ) +ADD_SUBDIRECTORY( GUI ) + FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) diff --git a/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.txx b/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.txx index 76b3148e..21b3b8c5 100644 --- a/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.txx +++ b/Code/ExternalCode/MegaVTK/vtkItk/itkImageToVTKImageFilter.txx @@ -153,4 +153,4 @@ ImageToVTKImageFilter< TInputImage > } // end namespace itk -#endif \ No newline at end of file +#endif diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.cxx b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.cxx index 4c5d9e6f..65127dd5 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.cxx +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkFillImageWithPolyData.cxx @@ -133,22 +133,21 @@ void vtkFillImageWithPolyDataExecuteZ(vtkFillImageWithPolyData *self, unsigned char *outPtr, int id, int slice, double bbox[6]) { - int num0, num1, num2, numC, pixSize; int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; - numC = outData->GetNumberOfScalarComponents(); - pixSize = numC * static_cast< int >( sizeof( T ) ); +// numC = outData->GetNumberOfScalarComponents(); +// pixSize = numC * static_cast< int >( sizeof( T ) ); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); - num0 = ext[1] - ext[0] + 1; - num1 = ext[3] - ext[2] + 1; - num2 = ext[5] - ext[4] + 1; + int num0 = ext[1] - ext[0] + 1; + int num1 = ext[3] - ext[2] + 1; + int num2 = ext[5] - ext[4] + 1; double outVal = self->GetInsidePixelValue(); @@ -226,22 +225,21 @@ void vtkFillImageWithPolyDataExecuteY(vtkFillImageWithPolyData *self, int ext[6] vtkImageData *outData, unsigned char *outPtr, int id, int slice, double bbox[6]) { - int num0, num1, num2, numC; int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; - numC = outData->GetNumberOfScalarComponents(); +// numC = outData->GetNumberOfScalarComponents(); // int pixSize = numC * static_cast(sizeof(T)); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); outData->GetContinuousIncrements(ext, outInc0, outInc1, outInc2); - num0 = ext[1] - ext[0] + 1; - num1 = ext[3] - ext[2] + 1; - num2 = ext[5] - ext[4] + 1; + int num0 = ext[1] - ext[0] + 1; + int num1 = ext[3] - ext[2] + 1; + int num2 = ext[5] - ext[4] + 1; vtkPoints *points = self->GetPolyData()->GetPoints(); vtkIdType numP = self->GetPolyData()->GetNumberOfPoints(); @@ -319,15 +317,15 @@ void vtkFillImageWithPolyDataExecuteX(vtkFillImageWithPolyData *self, int ext[6] vtkImageData *outData, unsigned char *outPtr, int id, int slice, double bbox[6]) { - int num0, num1, num2, numC, pixSize; + int num0, num1, num2; int idx0, idx1, idx2; vtkIdType in1Inc0, in1Inc1, in1Inc2; vtkIdType outInc0, outInc1, outInc2; unsigned long count = 0; unsigned long target; - numC = outData->GetNumberOfScalarComponents(); - pixSize = numC * static_cast< int >( sizeof( T ) ); +// numC = outData->GetNumberOfScalarComponents(); +// pixSize = numC * static_cast< int >( sizeof( T ) ); // Get information to march through data inData->GetContinuousIncrements(ext, in1Inc0, in1Inc1, in1Inc2); @@ -520,4 +518,4 @@ double vtkFillImageWithPolyData::Angle2D(const double dp1[2], const double dp2[2 } return dt; -} \ No newline at end of file +} diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.cxx b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.cxx index dbc18d53..84989751 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.cxx +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.cxx @@ -92,7 +92,6 @@ #include "vtkProperty.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" -#include "vtkProp3DCollection.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" @@ -117,7 +116,6 @@ vtkViewImage::vtkViewImage() this->TextProperty = vtkTextProperty::New(); this->LookupTable = vtkLookupTable::New(); this->ScalarBarActor = vtkScalarBarActor::New(); - this->Prop3DCollection = vtkProp3DCollection::New(); this->OrientationTransform = vtkMatrixToLinearTransform::New(); this->OrientationMatrix->Identity(); @@ -171,13 +169,20 @@ void vtkViewImage::SetInput(vtkImageData *in) if ( this->IsColor ) { + this->ImageActor->SetInput(this->WindowLevel->GetOutput()); this->WindowLevel->SetLookupTable(NULL); + // image is unsigned char () + this->WindowLevel->SetWindow(255); + this->WindowLevel->SetLevel(127.5); this->ShowScalarBar = false; this->ScalarBarActor->SetVisibility(this->ShowScalarBar); } else { + this->ImageActor->SetInput(this->WindowLevel->GetOutput()); this->WindowLevel->SetLookupTable(this->LookupTable); + this->WindowLevel->SetWindow(in->GetScalarRange()[1]-in->GetScalarRange()[0]); + this->WindowLevel->SetLevel(in->GetScalarRange()[0]+(in->GetScalarRange()[1]-in->GetScalarRange()[0])/2); } } } @@ -197,9 +202,6 @@ vtkViewImage::~vtkViewImage() this->CornerAnnotation->Delete(); this->LookupTable->Delete(); this->ScalarBarActor->Delete(); - - // delete the collection - this->Prop3DCollection->Delete(); } //---------------------------------------------------------------------------- @@ -215,7 +217,7 @@ void vtkViewImage::SetOrientationMatrix(vtkMatrix4x4 *matrix) //---------------------------------------------------------------------------- void vtkViewImage::SetLookupTable(vtkLookupTable *lookuptable) { - if ( !this->IsColor ) + if ( lookuptable ) { vtkSetObjectMacro2Body(LookupTable, vtkLookupTable, lookuptable); this->WindowLevel->SetLookupTable(this->LookupTable); @@ -321,20 +323,8 @@ double vtkViewImage::GetValueAtPosition(double worldcoordinates[3], return value; } - //---------------------------------------------------------------------------- -void vtkViewImage::RemoveProp(vtkProp *prop) -{ - this->Renderer->RemoveViewProp(prop); - - int index = this->Prop3DCollection->IsItemPresent(prop); - if( index ) - { - this->Prop3DCollection->RemoveItem(index); - } -} - //---------------------------------------------------------------------------- double * vtkViewImage::GetWorldCoordinatesFromImageCoordinates(int indices[3]) { @@ -456,7 +446,7 @@ void vtkViewImage::ResetWindowLevel(void) return; } - if ( !this->IsColor ) + if ( !this->IsColor ) { double *range = input->GetScalarRange(); double window = range[1] - range[0]; diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.h b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.h index 907ae55e..cc1018b8 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.h +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage.h @@ -76,7 +76,6 @@ #include #include #include -#include #include @@ -129,7 +128,6 @@ class vtkActor; class vtkDataSet; class vtkPolyData; class vtkProperty; -class vtkProp3DCollection; class vtkMatrixToLinearTransform; class vtkRenderWindowInteractor; @@ -249,14 +247,6 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage:public vtkImageViewer2 vtkGetObjectMacro(TextProperty, vtkTextProperty); virtual void SetTextProperty(vtkTextProperty *textproperty); - /** - * \brief Get a pointer to the current vtkProp3DCollection - * - * All displayed dataset generates an actor which is added to the renderer. - * These actors are gathered in this vtkProp3DCollection for easier access. - */ - vtkGetObjectMacro (Prop3DCollection, vtkProp3DCollection); - /** * \brief Set the world coordinates * \param[in] x x value @@ -274,8 +264,6 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage:public vtkImageViewer2 virtual void SetWorldCoordinates(double pos[3]) = 0; - virtual void RemoveProp(vtkProp *iProp); - /** \brief Set/Get the current slice to display (depending on the orientation this can be in X, Y or Z). @@ -547,11 +535,6 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage:public vtkImageViewer2 of the viewer. */ vtkScalarBarActor *ScalarBarActor; - /** - All displayed dataset generates an actor which is added to the renderer. (See AddDataSet()). - These actors are gathered in this vtkProp3DCollection for easier access. - */ - vtkProp3DCollection *Prop3DCollection; /** This vtkTransform instance carries the OrientationMatrix (see GetOrientationMatrix()) and is used to quickly transform the slice plane in vtkViewImage2D. diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.cxx b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.cxx index e4eb4ede..f57c3078 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.cxx +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.cxx @@ -893,14 +893,14 @@ vtkViewImage2D::AddDataSet(vtkPolyData *dataset, const bool & intersection, const bool & iDataVisibility) { - vtkCamera *cam = NULL; +// vtkCamera *cam = NULL; - if ( this->Renderer ) - { - cam = this->Renderer->GetActiveCamera(); - } - else + if ( !this->Renderer ) { +// cam = this->Renderer->GetActiveCamera(); +// } +// else +// { return NULL; } @@ -912,6 +912,7 @@ vtkViewImage2D::AddDataSet(vtkPolyData *dataset, vtkSmartPointer< vtkPolyDataMapper > mapper = vtkSmartPointer< vtkPolyDataMapper >::New(); mapper->SetScalarVisibility(iDataVisibility); + mapper->ImmediateModeRenderingOn(); vtkActor * actor = vtkActor::New(); vtkSmartPointer< vtkCutter > cutter = vtkSmartPointer< vtkCutter >::New(); @@ -929,7 +930,6 @@ vtkViewImage2D::AddDataSet(vtkPolyData *dataset, || ( ( bounds[2] == bounds[3] ) && ( normal[2] == 0 ) && ( normal[0] == 0 ) ) || ( ( bounds[4] == bounds[5] ) && ( normal[0] == 0 ) && ( normal[1] == 0 ) ) ) { - //std::cout << "extract 2d" << std::endl; extracter->SetInput(dataset); extracter->SetImplicitFunction(this->SliceImplicitPlane); extracter->Update(); @@ -964,8 +964,115 @@ vtkViewImage2D::AddDataSet(vtkPolyData *dataset, this->Renderer->AddViewProp(actor); + /*if( ( bounds[0] != bounds[1] ) + && ( bounds[2] != bounds[3] ) + && ( bounds[4] != bounds[5] )) + { + // std::cout << "extract actors..." << std::endl; + ExtractActors(dataset, XY); + ExtractActors(dataset, XZ); + ExtractActors(dataset, YZ); + }*/ + + return actor; } +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +std::map +vtkViewImage2D:: +ExtractActors(vtkPolyData *iDataSet, ORIENTATION iOrientation) +{ + std::map contours; + + // create plane to extract contours (based on orientation) + double normal[3] = {0., 0., 0.}; + + switch (iOrientation) + { + case XY: + { + normal[2] = 1; + break; + } + case XZ: + { + normal[1] = 1; + break; + } + case YZ: + { + normal[0] = 1; + break; + } + default: + { + break; + } + } + + double origin[3] = {0., 0., 0.}; + origin[0] = iDataSet->GetCenter()[0]; + origin[1] = iDataSet->GetCenter()[1]; + origin[2] = iDataSet->GetCenter()[2]; + + double position = iDataSet->GetBounds()[4 - 2*iOrientation]; + double maxPosition = iDataSet->GetBounds()[5 - 2*iOrientation]; + + /*std::cout << "position: " + << position << "-" + << maxPosition << std::endl;*/ + + // get information about image (spacing) + double spacing = this->GetInput()->GetSpacing()[2-iOrientation]; + + while( position < maxPosition) + { + origin[2-iOrientation] = position; + +/* + std::cout << "origin: " + << origin[0] << "-" + << origin[1] << "-" + << origin[2] << std::endl; + + std::cout << "normal: " + << normal[0] << "-" + << normal[1] << "-" + << normal[2] << std::endl; + */ + + vtkPlane* plane = vtkPlane::New(); + plane->SetNormal(normal); + plane->SetOrigin(origin); + + // cut + vtkCutter* cutter = vtkCutter::New(); + cutter->SetInput(iDataSet); + cutter->SetCutFunction(plane); + cutter->Update(); + plane->Delete(); + + vtkPolyDataMapper* mapper = vtkPolyDataMapper::New(); + mapper->SetInput( cutter->GetOutput() ); + cutter->Delete(); + + vtkActor* actor = vtkActor::New(); + actor->SetMapper(mapper); + actor->VisibilityOn(); + mapper->Delete(); + + contours[position] = actor; + + // increase position + position += spacing; + } + + return contours; +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- void vtkViewImage2D::UpdateCenter(void) @@ -974,15 +1081,15 @@ vtkViewImage2D::UpdateCenter(void) { return; } - vtkCamera *cam = NULL; +// vtkCamera *cam = NULL; - if ( this->Renderer ) - { - cam = this->Renderer->GetActiveCamera(); - } - else + if ( !this->Renderer ) { - return; +// cam = this->Renderer->GetActiveCamera(); +// } +// else +// { +// return; } int *dimensions = this->GetInput()->GetDimensions(); diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.h b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.h index 24d790dd..f8c2e14f 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.h +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2D.h @@ -71,6 +71,7 @@ #include "vtkViewImage.h" #include "MegaVTK2Configure.h" +#include #include #include "vtkTransform.h" @@ -155,6 +156,12 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2D:public vtkViewImage }; //ETX + enum ORIENTATION { + XY = 0, + XZ = 1, + YZ = 2 + }; + /** * \brief Get the polydata representing the Slice Plane * @@ -489,6 +496,8 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage2D:public vtkViewImage } } */ + std::map ExtractActors( + vtkPolyData *iDataSet, ORIENTATION iOrientation); protected: diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.cxx b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.cxx index a48cf361..2b172d43 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.cxx +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage2DCommand.cxx @@ -207,6 +207,7 @@ vtkViewImage2DCommand::Windowing(vtkInteractorStyleImage2D *isi) } int * size = this->Viewer->GetRenderWindow()->GetSize(); + double window = this->InitialWindow; double level = this->InitialLevel; @@ -288,7 +289,11 @@ void vtkViewImage2DCommand::PrintInformation() { os2 << "Value : " << this->Viewer->GetValueAtPosition (pos); } - else + // one display value for single channel images + /* + * \todo Nicolas- show channel value if we look at a multi channel image + */ + /*else { os2 << "Value : ["; for ( int i = 0; i < 3; i++ ) @@ -296,7 +301,8 @@ void vtkViewImage2DCommand::PrintInformation() os2 << this->Viewer->GetValueAtPosition (pos, i) << ", "; } os2 << "]"; - } + }*/ + this->Viewer->GetCornerAnnotation()->SetText ( 3, os2.str().c_str() ); this->Viewer->Render(); diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.cxx b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.cxx index 793c677e..45368b95 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.cxx +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.cxx @@ -97,7 +97,6 @@ // #include "vtkQuadricLODActor.h" #include "vtkActor.h" #include "vtkPolyDataMapper.h" -#include "vtkProp3DCollection.h" #include "vtkPoints.h" #include "vtkIdList.h" #include "vtkOutlineSource.h" @@ -114,8 +113,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -131,7 +130,6 @@ #include #include #include -#include #include #include "vtkRenderWindow.h" #include "vtkScalarsToColors.h" @@ -204,16 +202,8 @@ vtkViewImage3D::vtkViewImage3D() { this->VolumeProperty = vtkVolumeProperty::New(); this->VolumeActor = vtkVolume::New(); - this->VolumeRayCastMapper = vtkVolumeRayCastMapper::New(); - this->VolumeRayCastMIPFunction = vtkVolumeRayCastMIPFunction::New(); - this->VolumeRayCastCompositeFunction = - vtkVolumeRayCastCompositeFunction::New(); - this->VolumeRayCastIsosurfaceFunction = - vtkVolumeRayCastIsosurfaceFunction::New(); - this->OpacityFunction = vtkPiecewiseFunction::New(); this->Callback = vtkImage3DCroppingBoxCallback::New(); - this->Blender = vtkImageBlend::New(); - this->VolumeMapper3D = vtkVolumeTextureMapper3D::New(); + this->SmartVolumeMapper3D = vtkSmartVolumeMapper::New(); this->Phantom.push_back( vtkImageActor::New() ); this->Phantom.push_back( vtkImageActor::New() ); @@ -232,7 +222,6 @@ vtkViewImage3D::vtkViewImage3D() // the new interactor style this->InteractorStyle3D = vtkInteractorStyleImage3D::New(); -// this->SetupVolumeRendering(); this->SetupWidgets(); } @@ -243,19 +232,12 @@ vtkViewImage3D::vtkViewImage3D() vtkViewImage3D::~vtkViewImage3D() { // delete all vtk objetcts: - this->VolumeMapper3D->Delete(); + this->SmartVolumeMapper3D->Delete(); this->VolumeProperty->Delete(); this->VolumeActor->Delete(); - this->OpacityFunction->Delete(); this->Callback->Delete(); this->Cube->Delete(); this->Marker->Delete(); - this->Blender->Delete(); - //this->PlaneWidget->Delete(); - this->VolumeRayCastMapper->Delete(); - this->VolumeRayCastMIPFunction->Delete(); - this->VolumeRayCastCompositeFunction->Delete(); - this->VolumeRayCastIsosurfaceFunction->Delete(); this->Phantom[0]->Delete(); this->Phantom[1]->Delete(); this->Phantom[2]->Delete(); @@ -268,64 +250,11 @@ vtkViewImage3D::~vtkViewImage3D() this->Command->Delete(); this->InteractorStyle3D->Delete(); + + CleanVolumeRenderingVectors(); } //---------------------------------------------------------------------------- -/** - * - */ -void vtkViewImage3D::SetupVolumeRendering() -{ - this->Blender->SetBlendModeToNormal(); - this->Blender->SetOpacity (0, 0.25); - this->Blender->SetOpacity (1, 0.75); - vtkVolumeTextureMapper3D *texturemapper = - vtkVolumeTextureMapper3D::SafeDownCast ( this->VolumeActor->GetMapper() ); - if ( texturemapper ) - { - texturemapper->SetSampleDistance(0.5); - //texturemapper->SetPreferredMethodToNVidia(); - } - - this->VolumeMapper3D->CroppingOn(); - this->VolumeMapper3D->SetCroppingRegionFlagsToSubVolume(); - this->VolumeMapper3D->SetCroppingRegionFlags (0x7ffdfff); - this->VolumeRayCastMapper->SetSampleDistance(2.0); - this->VolumeRayCastMapper->CroppingOn(); - this->VolumeRayCastMapper->SetCroppingRegionFlags (0x7ffdfff); - vtkFiniteDifferenceGradientEstimator *gradest = - vtkFiniteDifferenceGradientEstimator::New(); - this->VolumeRayCastMapper->SetGradientEstimator(gradest); - gradest->Delete(); - this->VolumeRayCastMapper->SetVolumeRayCastFunction ( - this->VolumeRayCastCompositeFunction); - this->OpacityFunction->AddPoint (0, 0.0); - this->OpacityFunction->AddPoint (255, 1.0); - vtkColorTransferFunction *colorfunction = vtkColorTransferFunction::New(); - colorfunction->AddRGBPoint (0, 0.0, 0.0, 0.0); - colorfunction->AddRGBPoint (255, 1.0, 1.0, 1.0); - this->VolumeProperty->IndependentComponentsOff(); - this->VolumeProperty->SetColor (colorfunction); - colorfunction->Delete(); - this->VolumeProperty->SetScalarOpacity(this->OpacityFunction); - this->VolumeProperty->SetInterpolationTypeToLinear(); - this->VolumeProperty->ShadeOff(); - this->VolumeProperty->SetDiffuse (0.9); - this->VolumeProperty->SetAmbient (0.2); - this->VolumeProperty->SetSpecular (0.3); - this->VolumeProperty->SetSpecularPower (15.0); - // set up the vtk pipeline: volume rendering - this->VolumeActor->SetProperty (this->VolumeProperty); - this->VolumeActor->SetMapper (this->VolumeMapper3D); - this->VolumeActor->PickableOff(); - this->VolumeActor->DragableOff(); - this->VolumeActor->SetVisibility (0); - - // set up the boxwidget/ callback - this->Callback->SetVolumeMapper (this->VolumeMapper3D); - - this->Renderer->AddViewProp (this->VolumeActor); -} //---------------------------------------------------------------------------- /** @@ -406,89 +335,127 @@ void vtkViewImage3D::Render() */ void vtkViewImage3D::SetVolumeRenderingOff() { - this->VolumeActor->SetVisibility (false); + // triplanar rendering on + SetTriPlanarRenderingOn(); + + CleanVolumeRenderingVectors(); } +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void vtkViewImage3D::CleanVolumeRenderingVectors() +{ + //this->VolumeActor->SetVisibility (false); + for(unsigned int i=0; iSetVisibility(false); + this->Renderer->RemoveViewProp(m_VolumeActors[i]); + } + //delete everything... + for(unsigned int i=0; iDelete(); + m_VolumeMappers[i]->Delete(); + m_VolumeProperties[i]->Delete(); + } + + m_VolumeActors.clear(); + m_VolumeMappers.clear(); + m_VolumeProperties.clear(); +} //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * */ -void vtkViewImage3D::SetVolumeRenderingOn() +void vtkViewImage3D::SetVolumeRenderingOn(const std::vector& iImages, + const std::vector& iOpacities) { - if ( 1 ) // !this->IsColor ) + // triplanar rendering off + SetTriPlanarRenderingOff(); + + int *size = this->GetInput()->GetDimensions(); + + if ( ( size[0] < 2 ) + || ( size[1] < 2 ) + || ( size[2] < 2 ) ) { - vtkImageData *image = this->GetInput(); + vtkWarningMacro (<< "Cannot do volume rendering for a single slice, skipping" << endl); + return; + } - int *size = image->GetDimensions(); + CleanVolumeRenderingVectors(); - if ( ( size[0] < 2 ) - || ( size[1] < 2 ) - || ( size[2] < 2 ) ) - { - vtkWarningMacro (<< "Cannot do volume rendering for a single slice, skipping" << endl); - return; - } -/* - if (!this->IsColor) - { - vtkImageMapToWindowLevelColors* test = this->GetWindowLevel(); - test->SetInput(image); - vtkImageData* imagenew = vtkImageData::New(); - imagenew = test->GetOutput(); - image = imagenew; - }*/ - this->SetupVolumeRendering(); - - int NbOfComp = image->GetNumberOfScalarComponents(); - if ( NbOfComp > 1 && NbOfComp != 4 && NbOfComp < 5 ) - { - vtkSmartPointer< vtkImageExtractComponents > extComp = - vtkSmartPointer< vtkImageExtractComponents >::New(); - extComp->SetInput(image); - extComp->SetComponents(0); - extComp->Update(); - - vtkSmartPointer< vtkImageAppendComponents > addComp = - vtkSmartPointer< vtkImageAppendComponents >::New(); - addComp->AddInput(image); - addComp->AddInput( extComp->GetOutput() ); - addComp->Update(); - - if ( addComp->GetOutput()->GetNumberOfScalarComponents() == 4 ) - { - this->VolumeMapper3D->SetInput( addComp->GetOutput() ); - } - else - { - vtkSmartPointer< vtkImageData > temp = - vtkSmartPointer< vtkImageData >::New(); - temp->ShallowCopy( addComp->GetOutput() ); - addComp->SetInput(0, temp); - addComp->Update(); - this->VolumeMapper3D->SetInput( addComp->GetOutput() ); - } - } - else - { - if ( NbOfComp == 1 || NbOfComp == 4 ) - { - this->VolumeMapper3D->SetInput(image); - } - } - if ( !this->IsColor ) + for(unsigned int j=0; jCroppingOn(); + smartVolumeMapper3D->SetCroppingRegionFlagsToSubVolume(); + smartVolumeMapper3D->SetCroppingRegionFlags (0x7ffdfff); + m_VolumeMappers.push_back(smartVolumeMapper3D); + + // PROPERTY + vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New(); + volumeProperty->SetScalarOpacity(0, iOpacities[j]); + volumeProperty->SetScalarOpacity(1, iOpacities[j]); + volumeProperty->SetScalarOpacity(2, iOpacities[j]); + // one dataset-1 tf, not 1 tf for each component + volumeProperty->IndependentComponentsOff(); + volumeProperty->SetInterpolationTypeToLinear(); + //volumeProperty->SetScalarOpacityUnitDistance(1.0); + volumeProperty->ShadeOff(); + m_VolumeProperties.push_back(volumeProperty); + + // ACTOR + vtkVolume* volumeActor = vtkVolume::New(); + volumeActor->SetProperty (volumeProperty); + volumeActor->SetMapper (smartVolumeMapper3D); + volumeActor->PickableOff(); + volumeActor->DragableOff(); + volumeActor->SetVisibility (true); + m_VolumeActors.push_back(volumeActor); + + // get the index of the first non-NULL component + int i(0); + for(i=0; i<3;++i) + { + double range[2]; + iImages[j]->GetPointData()->GetScalars()->GetRange(range,i); + if(range[1]>0) { - this->VolumeRayCastMapper->SetInput(image); + break; } + } - this->SetupTextureMapper(); + // mix components + // dont't really get the point but has sth to do with the alpha component + // create a "FAKE" 4th alpha channel...?? + vtkImageExtractComponents* extComp = vtkImageExtractComponents::New(); + extComp->SetInput(iImages[j]); + extComp->SetComponents(i); + extComp->Update(); - //this->PlaneWidget->SetInput (this->GetInput()); - //this->PlaneWidget->PlaceWidget(); + vtkImageAppendComponents* addComp = vtkImageAppendComponents::New(); + addComp->AddInput(iImages[j]); + addComp->AddInput( extComp->GetOutput() ); + addComp->Update(); - this->VolumeActor->SetVisibility (true); - } + iImages[j]->Delete(); + extComp->Delete(); + + // add output to mapper + smartVolumeMapper3D->SetInput( addComp->GetOutput() ); + + addComp->Delete(); + + this->Renderer->AddViewProp (volumeActor); + } } //---------------------------------------------------------------------------- @@ -664,6 +631,7 @@ vtkViewImage3D::AddDataSet(vtkDataSet *dataset, mapper->SetInput( dynamic_cast< vtkPolyData * >( dataset ) ); mapper->SetScalarVisibility(iDataVisibility); mapper->StaticOn(); + mapper->ImmediateModeRenderingOn(); vtkActor *actor3d = vtkActor::New(); actor3d->SetMapper(mapper); @@ -679,16 +647,8 @@ vtkViewImage3D::AddDataSet(vtkDataSet *dataset, return actor3d; } - //---------------------------------------------------------------------------- -/* - * \todo Nicolas-Get rid of Prop3DCollection - */ -void vtkViewImage3D:: -AddActorToProp3DCollection( vtkActor * iActor) -{ - this->Prop3DCollection->AddItem(iActor); -} + //---------------------------------------------------------------------------- /** * @@ -704,70 +664,6 @@ void vtkViewImage3D::SetOrientationMatrix(vtkMatrix4x4 *matrix) } //---------------------------------------------------------------------------- -/** - * - */ -void vtkViewImage3D::SetupTextureMapper() -{ - if ( !this->GetInput() ) - { - return; - } - - vtkVolumeTextureMapper3D *mapper3D = - vtkVolumeTextureMapper3D::SafeDownCast( this->VolumeActor->GetMapper() ); - - if ( mapper3D && !this->GetRenderWindow()->GetNeverRendered() ) - { -#if VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION == 6 && VTK_BUILD_VERSION == 0 - if ( !mapper3D->IsRenderSupported (this->VolumeProperty) ) -#else - if ( !mapper3D->IsRenderSupported( this->VolumeProperty, - this->GetRenderer() ) ) -#endif - { - //try the ATI fragment program implementation - // mapper3D->SetPreferredMethodToFragmentProgram(); - -#if VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION == 6 && VTK_BUILD_VERSION == 0 - if ( !mapper3D->IsRenderSupported (this->VolumeProperty) ) -#else - if ( !mapper3D->IsRenderSupported( this->VolumeProperty, - this->GetRenderer() ) ) -#endif - { - vtkWarningMacro ( - << "Warning: 3D Texture volume rendering is not supported by your" - << " hardware, I switch to 2D Texture rendering." << endl); - - /// \todo FIX LEAK - vtkVolumeTextureMapper2D *newMapper = - vtkVolumeTextureMapper2D::New(); - newMapper->CroppingOn(); - newMapper->SetCroppingRegionFlags (0x7ffdfff); - - double *range = this->GetInput()->GetScalarRange(); - double shift = 0 - range[0]; - double scale = 65535.0 / ( range[1] - range[0] ); - - vtkSmartPointer< vtkImageShiftScale > scaler = - vtkSmartPointer< vtkImageShiftScale >::New(); - scaler->SetInput ( this->GetInput() ); - scaler->SetShift (shift); - scaler->SetScale (scale); - scaler->SetOutputScalarTypeToUnsignedShort(); - scaler->Update(); - newMapper->SetInput ( scaler->GetOutput() ); - scaler->Delete(); - this->Callback->SetVolumeMapper (newMapper); - - mapper3D->Delete(); - this->VolumeMapper3D = newMapper; - this->VolumeActor->SetMapper (this->VolumeMapper3D); - } - } - } -} //---------------------------------------------------------------------------- /** @@ -787,8 +683,9 @@ vtkViewImage3D::ComputeDistances(double *n, double *origin) { // go through all actors // relative distance from point to plane - Prop3DCollection->InitTraversal(); - vtkProp3D *prop_temp = Prop3DCollection->GetNextProp3D(); + vtkActorCollection *test = this->Renderer->GetActors(); + test->InitTraversal(); + vtkProp3D *prop_temp = test->GetNextActor(); while ( prop_temp ) { @@ -811,7 +708,7 @@ vtkViewImage3D::ComputeDistances(double *n, double *origin) this->GetInteractorStyle3D()->SetCurrentState(state); this->InvokeEvent(vtkViewImage3DCommand::VisibilityUpdatedEvent); - prop_temp = Prop3DCollection->GetNextProp3D(); + prop_temp = test->GetNextActor(); } // emit signal to say to render this->InvokeEvent(vtkViewImage3DCommand::UpdateRenderEvent); @@ -825,8 +722,9 @@ vtkViewImage3D::ComputeDistancesToSquare(vtkPlanes *planes) { // go through all actors // relative distance from point to plane - Prop3DCollection->InitTraversal(); - vtkProp3D *prop_temp = Prop3DCollection->GetNextProp3D(); + vtkActorCollection *test = this->Renderer->GetActors(); + test->InitTraversal(); + vtkProp3D *prop_temp = test->GetNextActor(); while ( prop_temp ) { @@ -852,7 +750,7 @@ vtkViewImage3D::ComputeDistancesToSquare(vtkPlanes *planes) this->GetInteractorStyle3D()->SetCurrentState(show); this->InvokeEvent(vtkViewImage3DCommand::VisibilityUpdatedEvent); - prop_temp = Prop3DCollection->GetNextProp3D(); + prop_temp = test->GetNextActor(); } planes->Delete(); diff --git a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.h b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.h index dd1474cf..8b4b9172 100644 --- a/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.h +++ b/Code/ExternalCode/MegaVTK/vtkRenderingAddOn/vtkViewImage3D.h @@ -80,10 +80,6 @@ #include "vtkOrientedBoxWidget.h" #include #include -#include -#include -#include -#include #include #include "vtkImage3DCroppingBoxCallback.h" #include @@ -95,11 +91,8 @@ #include "vtkProp3D.h" class vtkViewImage3DCommand; -class vtkVolumeTextureMapper3D; -class vtkVolumeMapper; -class vtkVolumeRayCastFunction; -class vtkPiecewiseFunction; -class vtkColorTransferFunction; +class vtkSmartVolumeMapper; +class vtkSmartVolumeMapper; class vtkVolume; class vtkImageActor; class vtkAxes; @@ -108,7 +101,6 @@ class vtkTubeFilter; class vtkAnnotatedCubeActor; class vtkOrientationMarkerWidget; class vtkAxesActor; -class vtkImageBlend; class vtkViewImage2D; class vtkScalarsToColors; class vtkColorTransferFunction; @@ -181,7 +173,8 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3D:public vtkViewImage /* * \brief Set volume rendering on */ - void SetVolumeRenderingOn(); + void SetVolumeRenderingOn(const std::vector& iImages, + const std::vector& iOpacities); /* * \brief Set volume rendering off @@ -198,73 +191,6 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3D:public vtkViewImage */ void SetTriPlanarRenderingOff(); - /* - * \brief Set the volume mapper to texture (for volume rendering purpose) - */ - void SetVolumeMapperToTexture(void) - { - this->VolumeActor->SetMapper (this->VolumeMapper3D); - this->Callback->SetVolumeMapper (this->VolumeMapper3D); - } - - /* - * \brief Set the volume mapper to ray cast (for volume rendering purpose) - */ - void SetVolumeMapperToRayCast(void) - { - this->VolumeActor->SetMapper (this->VolumeRayCastMapper); - this->Callback->SetVolumeMapper (this->VolumeRayCastMapper); - } - - /* - * \brief Set the volume ray cast function to composite - * (for volume rendering purpose) - */ - void SetVolumeRayCastFunctionToComposite(void) - { - this->VolumeRayCastMapper->SetVolumeRayCastFunction - (this->VolumeRayCastCompositeFunction); - } - - /* - * \brief Set the volume ray cast function to MIP - * (for volume rendering purpose) - */ - void SetVolumeRayCastFunctionToMIP(void) - { - this->VolumeRayCastMapper->SetVolumeRayCastFunction - (this->VolumeRayCastMIPFunction); - } - - void SetVolumeRayCastFunctionToIsosurface(void) - { - this->VolumeRayCastMapper->SetVolumeRayCastFunction - (this->VolumeRayCastIsosurfaceFunction); - } - - /** Set the box widget visibility */ - /*void SetBoxWidgetVisibility(const bool& a) - { - if (this->Interactor) this->BoxWidget->SetEnabled (a); - } - bool GetBoxWidgetVisibility(void) - { - return (this->BoxWidget->GetEnabled() == 1); - } - vtkBooleanMacro (BoxWidgetVisibility, int); -*/ - /** Set the plane widget on */ - /*void SetPlaneWidgetVisibility (const bool& a) - { - if (this->Interactor) - this->PlaneWidget->SetEnabled (a); - } - bool GetPlaneWidgetVisibility (void) - { - return ( this->PlaneWidget->GetEnabled() == 1 ); - } - vtkBooleanMacro (PlaneWidgetVisibility, int);*/ - /** * \brief Set the cube visibility * \param[in] a true: visible, false: not visible @@ -340,8 +266,6 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3D:public vtkViewImage * */ void ComputeDistancesToSquare(vtkPlanes *planes); - void AddActorToProp3DCollection( vtkActor * iActor); - protected: vtkViewImage3D(); @@ -352,30 +276,21 @@ class VTK_RENDERINGADDON2_EXPORT vtkViewImage3D:public vtkViewImage virtual void UpdateOrientation(){} - virtual void SetupVolumeRendering(); - virtual void SetupWidgets(); - virtual void SetupTextureMapper(); + void CleanVolumeRenderingVectors(); // texture mapper in 3D - vtkVolumeMapper *VolumeMapper3D; - // volume ray cast mapper - vtkVolumeRayCastMapper *VolumeRayCastMapper; - // ray cast function - vtkVolumeRayCastMIPFunction *VolumeRayCastMIPFunction; - // ray cast function - vtkVolumeRayCastCompositeFunction *VolumeRayCastCompositeFunction; - // ray cast function - vtkVolumeRayCastIsosurfaceFunction *VolumeRayCastIsosurfaceFunction; + vtkSmartVolumeMapper *SmartVolumeMapper3D; // volume property vtkVolumeProperty *VolumeProperty; // volume actor vtkVolume *VolumeActor; - // opacity transfer function - vtkPiecewiseFunction *OpacityFunction; - // blender - vtkImageBlend *Blender; + + std::vector m_VolumeActors; + std::vector m_VolumeMappers; + std::vector m_VolumeProperties; + // image 3D cropping box callback vtkImage3DCroppingBoxCallback *Callback; diff --git a/Code/ExternalCode/PoissonReconstruction/MultiGridOctest.cpp b/Code/ExternalCode/PoissonReconstruction/MultiGridOctest.cpp index 5ba6fece..bcd4a6b4 100644 --- a/Code/ExternalCode/PoissonReconstruction/MultiGridOctest.cpp +++ b/Code/ExternalCode/PoissonReconstruction/MultiGridOctest.cpp @@ -127,6 +127,11 @@ void ShowUsage(char* ex) printf("\t\t used as a confidence value, affecting the sample's\n"); printf("\t\t constribution to the reconstruction process.\n"); + printf("\t[--manifold]\n"); + printf("\t\t If this flag is enabled, the isosurface extraction is performed\n"); + printf("\t\t by adding a polygon's barycenter in order to ensure that the output\n"); + printf("\t\t mesh is manifold.\n"); + printf("\t[--verbose]\n"); } diff --git a/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.h b/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.h index 3a00d21d..4116e069 100644 --- a/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.h +++ b/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.h @@ -279,7 +279,8 @@ class Octree hash_map< long long, int > *interiorRoots, std::vector< Point3D< float > > *interiorPositions, const int & offSet, - const int & sDepth); + const int & sDepth, + bool addBarycenter); static int AddTriangles(CoredMeshData *mesh, std::vector< CoredPointIndex > edges[3], @@ -289,7 +290,8 @@ class Octree static int AddTriangles(CoredMeshData *mesh, std::vector< CoredPointIndex > & edges, std::vector< Point3D< float > > *interiorPositions, - const int & offSet); + const int & offSet, + bool addBarycenter); void GetMCIsoEdges(TreeOctNode *node, hash_map< long long, int > & boundaryRoots, @@ -401,13 +403,15 @@ class Octree void GetMCIsoTriangles(const Real & isoValue, CoredMeshData *mesh, const int & fullDepthIso = 0, - const int & nonLinearFit = 1); + const int & nonLinearFit = 1, + bool addBarycenter=false); void GetMCIsoTriangles(const Real & isoValue, const int & subdivideDepth, CoredMeshData *mesh, const int & fullDepthIso = 0, - const int & nonLinearFit = 1); + const int & nonLinearFit = 1, + bool addBarycenter=false); }; #include "MultiGridOctreeData.inl" diff --git a/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.inl b/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.inl index 4e28703c..2f76b0b3 100644 --- a/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.inl +++ b/Code/ExternalCode/PoissonReconstruction/MultiGridOctreeData.inl @@ -1368,7 +1368,7 @@ inline int Octree::RestrictedLaplacianMatrixFunction::Function(const Tre } template -inline void Octree::GetMCIsoTriangles(const Real& isoValue,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit) +inline void Octree::GetMCIsoTriangles(const Real& isoValue,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit, bool addBarycenter) { TreeOctNode* temp; @@ -1385,7 +1385,7 @@ inline void Octree::GetMCIsoTriangles(const Real& isoValue,CoredMeshData { SetMCRootPositions(temp,0,isoValue,roots,NULL,*normalHash,NULL,NULL,mesh,nonLinearFit); temp=tree.nextLeaf(temp); - } + } // MemoryUsage(); //DumpOutput("Normal Size: %.2f MB\n",double(sizeof(Point3D)*normalHash->size())/1000000); @@ -1402,15 +1402,15 @@ inline void Octree::GetMCIsoTriangles(const Real& isoValue,CoredMeshData temp=tree.nextLeaf(); while(temp) { - GetMCIsoTriangles(temp,mesh,roots,NULL,NULL,0,0); + GetMCIsoTriangles(temp,mesh,roots,NULL,NULL,0,0,addBarycenter); temp=tree.nextLeaf(temp); - } + } //DumpOutput("Added triangles in: %f\n",Time()-t); //DumpOutput("Memory Usage: %.3f MB\n",float(MemoryUsage())); } template -inline void Octree::GetMCIsoTriangles(const Real& isoValue,const int& subdivideDepth,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit) +inline void Octree::GetMCIsoTriangles(const Real& isoValue,const int& subdivideDepth,CoredMeshData* mesh,const int& fullDepthIso,const int& nonLinearFit, bool addBarycenter) { TreeOctNode* temp; hash_map boundaryRoots,*interiorRoots; @@ -1460,7 +1460,7 @@ inline void Octree::GetMCIsoTriangles(const Real& isoValue,const int& su temp=sNodes.treeNodes[i]->nextLeaf(); while(temp){ - GetMCIsoTriangles(temp,mesh,boundaryRoots,interiorRoots,interiorPoints,offSet,sDepth); + GetMCIsoTriangles(temp,mesh,boundaryRoots,interiorRoots,interiorPoints,offSet,sDepth,addBarycenter); temp=sNodes.treeNodes[i]->nextLeaf(temp); } delete interiorRoots; @@ -1471,7 +1471,7 @@ inline void Octree::GetMCIsoTriangles(const Real& isoValue,const int& su temp=tree.nextLeaf(); while(temp){ - if(temp->depth()depth()::SetIsoSurfaceCorners(const Real& isoValue,const int& // Start by setting the corner values of all the nodes cf.valueTables=fData.valueTables; cf.res2=fData.res2; - - int idx[3]; - int temp_N = sNodes->nodeCount[subdivideDepth]; - - int c, mcid; - - for(i=0;inodeCount[subdivideDepth];i++){ temp=sNodes->treeNodes[i]; if(!temp->children){ for(j=0;jwidth<=3){cornerValues[j]=getCornerValue(temp,j);} else{ cf.value=0; + int idx[3]; VertexData::CornerIndex(temp,j,fData.depth,idx); cf.index[0]=idx[0]*fData.res; cf.index[1]=idx[1]*fData.res; @@ -1724,8 +1719,8 @@ inline void Octree::SetIsoSurfaceCorners(const Real& isoValue,const int& if(temp->parent){ TreeOctNode* parent=temp->parent; - c=int(temp-temp->parent->children); - mcid=temp->nodeData.mcIndex&(1<parent->children); + int mcid=temp->nodeData.mcIndex&(1<nodeData.mcIndex|=mcid; @@ -1750,11 +1745,12 @@ inline void Octree::SetIsoSurfaceCorners(const Real& isoValue,const int& { for(j=0;j::SetIsoSurfaceCorners(const Real& isoValue,const int& if(temp->parent){ TreeOctNode* parent=temp->parent; - c=int(temp-temp->parent->children); - mcid=temp->nodeData.mcIndex&(1<parent->children); + int mcid=temp->nodeData.mcIndex&(1<nodeData.mcIndex|=mcid; @@ -2235,6 +2231,9 @@ inline int Octree::GetRoot(const RootInfo& ri,const Real& isoValue,Point if(rCount && nonLinearFit) {averageRoot/=rCount;} else {averageRoot=Real((x0-isoValue)/(x0-x1));} + if( averageRoot > 1 ) { averageRoot = 1;} + if( averageRoot < -1 ) { averageRoot = -1;} + position.coords[o]=Real(center-twidth/2+twidth*averageRoot); return 1; } @@ -2624,7 +2623,7 @@ inline void Octree::GetMCIsoEdges(TreeOctNode* node,hash_map inline int Octree::GetMCIsoTriangles(TreeOctNode* node,CoredMeshData* mesh,hash_map& boundaryRoots, - hash_map* interiorRoots,std::vector >* interiorPositions,const int& offSet,const int& sDepth) + hash_map* interiorRoots,std::vector >* interiorPositions,const int& offSet,const int& sDepth, bool addBarycenter) { int tris=0; std::vector > edges; @@ -2639,7 +2638,7 @@ inline int Octree::GetMCIsoTriangles(TreeOctNode* node,CoredMeshData* me if(!GetRootIndex(edgeLoops[i][j].first,boundaryRoots,interiorRoots,p)){printf("Bad Point Index\n");} else{edgeIndices.push_back(p);} } - tris+=AddTriangles(mesh,edgeIndices,interiorPositions,offSet); + tris+=AddTriangles(mesh,edgeIndices,interiorPositions,offSet,addBarycenter); } return tris; } @@ -2696,18 +2695,65 @@ inline int Octree::AddTriangles(CoredMeshData* mesh,std::vector -inline int Octree::AddTriangles(CoredMeshData* mesh,std::vector& edges,std::vector >* interiorPositions,const int& offSet) +inline int Octree::AddTriangles(CoredMeshData* mesh,std::vector& edges,std::vector >* interiorPositions,const int& offSet, bool addBarycenter ) { - if(edges.size()>3){ - Triangulation t; + if( edges.size()>3 ) + { +#if 1 + bool isCoplanar = false; - // Add the points to the triangulation - for(int i=0;i p; - if(edges[i].inCore) {for(int j=0;j<3;j++){p.coords[j]=mesh->inCorePoints[edges[i].index].coords[j];}} - else {for(int j=0;j<3;j++){p.coords[j]=(*interiorPositions)[edges[i].index-offSet].coords[j];}} - t.points.push_back(p); - } + for( size_t i=0 ; i v1 , v2; + if( edges[i].inCore ) for( int k=0 ; k<3 ; k++ ) v1.coords[k] = mesh->inCorePoints[ edges[i].index ].coords[k]; + else for( int k=0 ; k<3 ; k++ ) v1.coords[k] = (*interiorPositions)[ edges[i].index-offSet ].coords[k]; + if( edges[j].inCore ) for( int k=0 ; k<3 ; k++ ) v2.coords[k] = mesh->inCorePoints[ edges[j].index ].coords[k]; + else for( int k=0 ; k<3 ; k++ ) v2.coords[k] = (*interiorPositions)[ edges[j].index-offSet ].coords[k]; + for( int k=0 ; k<3 ; k++ ) if( v1.coords[k]==v2.coords[k] ) isCoplanar = true; + } + if( addBarycenter && isCoplanar ) +#else + if( addBarycenter ) +#endif + { + Point3D< Real > c; + c.coords[0] = c.coords[1] = c.coords[2] = 0; + for( int i=0 ; i p; + if(edges[i].inCore) for(int j=0 ; j<3 ; j++ ) p.coords[j] = mesh->inCorePoints[edges[i].index].coords[j]; + else for(int j=0 ; j<3 ; j++ ) p.coords[j] =(*interiorPositions)[edges[i].index-offSet].coords[j]; + c.coords[0] += p.coords[0] , c.coords[1] += p.coords[1] , c.coords[2] += p.coords[2]; + } + c.coords[0] /= edges.size() , c.coords[1] /= edges.size() , c.coords[2] /= edges.size(); + int cIdx = mesh->addOutOfCorePoint( c ); + for( int i=0 ; iaddTriangle( tri , inCoreFlag ); + } + return edges.size(); + } + else + { + Triangulation t; + + // Add the points to the triangulation + for(int i=0;i p; + if(edges[i].inCore) {for(int j=0;j<3;j++){p.coords[j]=mesh->inCorePoints[edges[i].index].coords[j];}} + else {for(int j=0;j<3;j++){p.coords[j]=(*interiorPositions)[edges[i].index-offSet].coords[j];}} + t.points.push_back(p); + } // Create a fan triangulation for(int i=1;i::AddTriangles(CoredMeshData* mesh,std::vectoraddTriangle(tri,inCoreFlag); } } - else if(edges.size()==3){ + } + else if(edges.size()==3) + { TriangleIndex tri; int inCoreFlag=0; for(int i=0;i<3;i++){ @@ -2742,7 +2790,7 @@ inline int Octree::AddTriangles(CoredMeshData* mesh,std::vectoraddTriangle(tri,inCoreFlag); - } + } return int(edges.size())-2; } //////////////// diff --git a/Code/ExternalCode/PoissonReconstruction/PPolynomial.inl b/Code/ExternalCode/PoissonReconstruction/PPolynomial.inl index e76c2eae..323feb62 100644 --- a/Code/ExternalCode/PoissonReconstruction/PPolynomial.inl +++ b/Code/ExternalCode/PoissonReconstruction/PPolynomial.inl @@ -475,7 +475,7 @@ inline PPolynomial PPolynomial::GaussianApproximation(const doub template inline PPolynomial PPolynomial::MovingAverage(const double& radius) { - const int UDegree = Degree+1; + const int UDegree = Degree+1; PPolynomial A; Polynomial p; StartingPolynomial* sps; diff --git a/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.cxx b/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.cxx index b41d8d3c..ec3a6de1 100644 --- a/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.cxx +++ b/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.cxx @@ -78,11 +78,7 @@ #include "MultiGridOctest.h" #include "MultiGridOctreeData.h" -//#include "MemoryUsage.h" -#include "vtkPolyDataWriter.h" - -vtkCxxRevisionMacro(vtkPoissonReconstruction, "$Revision: 1.70 $"); vtkStandardNewMacro(vtkPoissonReconstruction); vtkPoissonReconstruction::vtkPoissonReconstruction() @@ -193,11 +189,11 @@ int vtkPoissonReconstruction::RequestData(vtkInformation *vtkNotUsed(request), if ( this->IsoDivide ) { - tree.GetMCIsoTriangles(isoValue, this->IsoDivide, &mesh); + tree.GetMCIsoTriangles(isoValue, this->IsoDivide, &mesh, 0, 1, true); } else { - tree.GetMCIsoTriangles(isoValue, &mesh); + tree.GetMCIsoTriangles(isoValue, &mesh, 0, 1, true); } //PlyWriteTriangles(Out.value,&mesh,PLY_BINARY_NATIVE,center,scale,comments,commentNum); diff --git a/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.h b/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.h index 263e430d..a794e990 100644 --- a/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.h +++ b/Code/ExternalCode/PoissonReconstruction/vtkPoissonReconstruction.h @@ -45,7 +45,7 @@ class PoissonReconstruction_EXPORT vtkPoissonReconstruction:public vtkPolyDataAlgorithm { public: - vtkTypeRevisionMacro(vtkPoissonReconstruction, vtkPolyDataAlgorithm); + vtkTypeMacro(vtkPoissonReconstruction, vtkPolyDataAlgorithm); void PrintSelf(ostream & os, vtkIndent indent); static vtkPoissonReconstruction * New(); diff --git a/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.cpp b/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.cpp index aaac732e..55954acd 100644 --- a/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.cpp +++ b/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.cpp @@ -29,32 +29,6 @@ // CTK includes #include "ctkCollapsibleGroupBox.h" -#if QT_VERSION >= 0x040600 -#include - -//----------------------------------------------------------------------------- -class ctkCollapsibleGroupBoxStyle:public QProxyStyle -{ - public: - - virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption * opt, QPainter * p, const QWidget * widget = 0) const - { - if (pe == QStyle::PE_IndicatorCheckBox) - { - const QGroupBox* groupBox= qobject_cast(widget); - if (groupBox) - { - this->QProxyStyle::drawPrimitive(groupBox->isChecked() ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown, opt, p, widget); - return; - } - } - this->QProxyStyle::drawPrimitive(pe, opt, p, widget); - } -}; -#else - -#endif - //----------------------------------------------------------------------------- ctkCollapsibleGroupBox::ctkCollapsibleGroupBox(QWidget* _parent) :QGroupBox(_parent) @@ -72,7 +46,10 @@ ctkCollapsibleGroupBox::ctkCollapsibleGroupBox(const QString& _title, QWidget* _ //----------------------------------------------------------------------------- ctkCollapsibleGroupBox::~ctkCollapsibleGroupBox() { - + if(Style) + { + delete Style; + } } //----------------------------------------------------------------------------- @@ -82,8 +59,10 @@ void ctkCollapsibleGroupBox::init() connect(this, SIGNAL(toggled(bool)), this, SLOT(expand(bool))); this->MaxHeight = this->maximumHeight(); + #if QT_VERSION >= 0x040600 - this->setStyle(new ctkCollapsibleGroupBoxStyle); + Style = new ctkCollapsibleGroupBoxStyle; + this->setStyle(Style); #else this->setStyleSheet( "ctkCollapsibleGroupBox::indicator:checked{" diff --git a/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.h b/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.h index 9cc3f53d..06f84d1c 100644 --- a/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.h +++ b/Code/ExternalCode/ctk/ctkCollapsibleGroupBox.h @@ -27,6 +27,32 @@ // CTK includes #include "ctkConfigure.h" +#if QT_VERSION >= 0x040600 +#include + +//----------------------------------------------------------------------------- +class ctkCollapsibleGroupBoxStyle:public QProxyStyle +{ + public: + + virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption * opt, QPainter * p, const QWidget * widget = 0) const + { + if (pe == QStyle::PE_IndicatorCheckBox) + { + const QGroupBox* groupBox= qobject_cast(widget); + if (groupBox) + { + this->QProxyStyle::drawPrimitive(groupBox->isChecked() ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown, opt, p, widget); + return; + } + } + this->QProxyStyle::drawPrimitive(pe, opt, p, widget); + } +}; +#else + +#endif + /// A QGroupBox with an arrow indicator that shows/hides the groupbox contents /// when clicked. It responds to the slot QGroupBox::setChecked(bool) or /// ctkCollapsibleGroupBox::setCollapsed(bool) @@ -78,6 +104,7 @@ protected slots: QSize OldSize; /// Maximum allowed height int MaxHeight; + ctkCollapsibleGroupBoxStyle* Style; }; //---------------------------------------------------------------------------- diff --git a/Code/ExternalCode/ctk/ctkRangeSlider.cpp b/Code/ExternalCode/ctk/ctkRangeSlider.cpp index c81d4cdf..0764b3b8 100644 --- a/Code/ExternalCode/ctk/ctkRangeSlider.cpp +++ b/Code/ExternalCode/ctk/ctkRangeSlider.cpp @@ -518,8 +518,8 @@ void ctkRangeSlider::paintEvent( QPaintEvent* ) } // TODO: Set this based on the supplied transfer function - QColor l = Qt::darkGray; - QColor u = Qt::black; +// QColor l = Qt::darkGray; +// QColor u = Qt::black; gradient.setColorAt(0, highlight.darker(120)); gradient.setColorAt(1, highlight.lighter(160)); diff --git a/Code/ExternalCode/itkQt/CMakeLists.txt b/Code/ExternalCode/itkQt/CMakeLists.txt index 39607105..5ebce420 100644 --- a/Code/ExternalCode/itkQt/CMakeLists.txt +++ b/Code/ExternalCode/itkQt/CMakeLists.txt @@ -22,7 +22,7 @@ ADD_LIBRARY( itkQt ) TARGET_LINK_LIBRARIES( itkQt - ITKCommon + ${ITK_LIBRARIES} ${QT_LIBRARIES} ) diff --git a/Code/ExternalCode/vtkLSM/vtkLSMReader.cxx b/Code/ExternalCode/vtkLSM/vtkLSMReader.cxx index c731095a..277991f9 100644 --- a/Code/ExternalCode/vtkLSM/vtkLSMReader.cxx +++ b/Code/ExternalCode/vtkLSM/vtkLSMReader.cxx @@ -101,8 +101,8 @@ vtkLSMReader::vtkLSMReader() this->ChannelDataTypes = 0; this->TrackWavelengths = 0; this->ImageOffsets = 0; - this->ReadSizes = 0; - this->Description = 0; + this->ReadSizes = NULL; + this->Description = NULL; #ifdef VTK_WORDS_BIGENDIAN this->SwapBytes = true; @@ -142,18 +142,17 @@ vtkLSMReader::~vtkLSMReader() this->TimeStampInformation->Delete(); } -/// \todo Fix leaks -/* if(Description) { delete[] Description; + Description = NULL; } if(Objective) { delete[] Objective; + Objective = NULL; } -*/ } void vtkLSMReader::ClearFileName() @@ -719,18 +718,16 @@ int vtkLSMReader::ReadScanInformation(ifstream *f, unsigned long pos) switch ( entry ) { - double gain; - int mode; case DETCHANNEL_ENTRY_DETECTOR_GAIN_FIRST: - gain = this->ReadDouble(f, pos); + this->ReadDouble(f, pos); // double gain continue; break; case DETCHANNEL_ENTRY_DETECTOR_GAIN_LAST: - gain = this->ReadDouble(f, pos); + this->ReadDouble(f, pos); // double gain continue; break; case DETCHANNEL_ENTRY_INTEGRATION_MODE: - mode = this->ReadInt(f, pos); + this->ReadInt(f, pos); // int mode continue; break; case LASER_ENTRY_NAME: diff --git a/Code/Filters/CMakeLists.txt b/Code/Filters/CMakeLists.txt index 38620453..9abec12c 100644 --- a/Code/Filters/CMakeLists.txt +++ b/Code/Filters/CMakeLists.txt @@ -1,3 +1,116 @@ +# create library +IF( WIN32 ) + IF( NOT CYGWIN ) + IF( NOT MINGW ) + IF( BUILD_SHARED_LIBS ) + ADD_DEFINITIONS( -DGoFilters_EXPORTS ) + ENDIF( BUILD_SHARED_LIBS ) + ENDIF( NOT MINGW ) + ENDIF( NOT CYGWIN ) +ENDIF( WIN32 ) + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/GoFiltersConfigure.h.in + ${CMAKE_CURRENT_BINARY_DIR}/GoFiltersConfigure.h @ONLY IMMEDIATE) + +SET( GoFilters_SRC + itkCellFeatureGenerator.h + itkCellFeatureGenerator.txx + itkCellForegroundExtraction.h + itkCellForegroundExtraction.txx + itkChanAndVeseSegmentationFilter.h + itkGaussianProfileMatchingImageFilter.h + itkGaussianProfileMatchingImageFilter.txx + itkGradientWeightedDistanceImageFilter.h + itkGradientWeightedDistanceImageFilter.txx + itkGradientWeightedIntensityImageFilter.h + itkGradientWeightedIntensityImageFilter.txx + itkMorphologicalWatershedFromMarkersImageFilter2.h + itkMorphologicalWatershedFromMarkersImageFilter2.txx + itkMorphologicalWatershedImageFilter2.h + itkMorphologicalWatershedImageFilter2.txx + itkMultiScaleLoGDistanceImageFilter.h + itkMultiScaleLoGDistanceImageFilter.txx + itkMultiScaleLoGImageFilter.h + itkMultiScaleLoGImageFilter.txx + itkPreprocessImageFilter.h + itkPreprocessImageFilter.txx + itkViscousWatershedTransform.h + itkViscousWatershedTransform.txx + itkWatershedBasedCellSegmentation.h + itkWatershedBasedCellSegmentation.txx + +# +# Contour +# + Contour/ContourToMeshFilter.h + Contour/ContourToMeshFilter.txx + +# +# Mesh +# + Mesh/itkConvertMeshesToLabelImageFilter.h + Mesh/itkConvertMeshesToLabelImageFilter.txx + Mesh/itkExtractMeshesFromLabelImageFilter.h + Mesh/itkExtractMeshesFromLabelImageFilter.txx + Mesh/itkQuadEdgeMeshTovtkPolyData.h + Mesh/itkQuadEdgeMeshTovtkPolyData.txx + Mesh/itkvtkPolyDataToBinaryMaskImageFilter.h + Mesh/itkvtkPolyDataToBinaryMaskImageFilter.txx + + Mesh/itkvtkMeshFilterBase.txx + Mesh/itkvtkMeshFilterBase.h + + Mesh/MeshToContourFilter.h + Mesh/MeshToContourFilter.cxx + + # Attributes + Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.h + Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.txx + Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.h + Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.txx + + # Merge + Mesh/Merge/itkvtkMeshMergeFilterBase.h + Mesh/Merge/itkvtkMeshMergeFilterBase.txx + Mesh/Merge/itkvtkMeshMergeConvexHullFilter.h + Mesh/Merge/itkvtkMeshMergeConvexHullFilter.txx + + # Split + Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.h + Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.txx + Mesh/Split/itkvtkMeshSplitterFilterBase.txx + Mesh/Split/itkvtkMeshSplitterFilterBase.h + Mesh/Split/itkvtkMeshSplitterImageFilterBase.h + Mesh/Split/itkvtkMeshSplitterImageFilterBase.txx +) + +#--------------------------------------------------------------------------- +#--------------------------------------------------------------------------- + +ADD_LIBRARY( GoFilters + ${GoFilters_SRC} +) + + +SET_TARGET_PROPERTIES( GoFilters PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) + +# Runtime +INSTALL( TARGETS GoFilters + EXPORT GoFigure2Targets + RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime + ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries + LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} NAMELINK_SKIP COMPONENT Libraries + ) + +# Development +INSTALL( TARGETS GoFilters + EXPORT GoFigure2Targets + RUNTIME DESTINATION ${GOFIGURE2_INSTALL_BIN_DIR} COMPONENT Runtime + ARCHIVE DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries + LIBRARY DESTINATION ${GOFIGURE2_INSTALL_LIB_DIR} COMPONENT Libraries NAMELINK_ONLY + ) + +# for the installation FILE( GLOB __source_file_h "${CMAKE_CURRENT_SOURCE_DIR}/*.h" ) FILE( GLOB __source_file_txx "${CMAKE_CURRENT_SOURCE_DIR}/*.txx" ) diff --git a/Code/Filters/ContourToMeshFilter.h b/Code/Filters/Contour/ContourToMeshFilter.h similarity index 86% rename from Code/Filters/ContourToMeshFilter.h rename to Code/Filters/Contour/ContourToMeshFilter.h index 554f6b27..5d28f09c 100644 --- a/Code/Filters/ContourToMeshFilter.h +++ b/Code/Filters/Contour/ContourToMeshFilter.h @@ -1,8 +1,8 @@ /*========================================================================= Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + at Megason Lab, Systems biology, Harvard Medical school, 2009-10 - Copyright (c) 2009-11, President and Fellows of Harvard College. + Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -34,6 +34,8 @@ #ifndef __ContourToMeshFilter_h #define __ContourToMeshFilter_h +#include "GoFiltersConfigure.h" + #include "itkLightObject.h" #include "itkObjectFactory.h" @@ -41,12 +43,10 @@ namespace itk { /** * \class ContourToMeshFilter - * \brief Generate a mesh from a set of 2D contours - * \tparam TContainer Container of Contours (e.g. std::vector< vtkPolyData* >, - * std::list< vtkPolyData* >, etc. ) + * \brief */ template< class TContainer > -class ContourToMeshFilter:public LightObject +class GOFILTERS_EXPORT ContourToMeshFilter:public LightObject { public: typedef ContourToMeshFilter Self; @@ -63,17 +63,12 @@ class ContourToMeshFilter:public LightObject typedef TContainer ContainerType; typedef typename ContainerType::const_iterator ContainerConstIterator; - /** \brief Main method: where the mesh is actually calculated. */ void ProcessContours(const ContainerType & iContainer); - /** \brief Get the resulting mesh */ vtkPolyData * GetOutput(); protected: - /** \brief Constructor */ ContourToMeshFilter(); - - /** \brief Destructor */ ~ContourToMeshFilter(); vtkPolyData *m_Output; diff --git a/Code/Filters/ContourToMeshFilter.txx b/Code/Filters/Contour/ContourToMeshFilter.txx similarity index 99% rename from Code/Filters/ContourToMeshFilter.txx rename to Code/Filters/Contour/ContourToMeshFilter.txx index 90af1490..25cdd4c5 100644 --- a/Code/Filters/ContourToMeshFilter.txx +++ b/Code/Filters/Contour/ContourToMeshFilter.txx @@ -166,4 +166,4 @@ ContourToMeshFilter< TContainer >::GetOutput() } } -#endif \ No newline at end of file +#endif diff --git a/Code/Filters/GoFiltersConfigure.h.in b/Code/Filters/GoFiltersConfigure.h.in new file mode 100644 index 00000000..6add159e --- /dev/null +++ b/Code/Filters/GoFiltersConfigure.h.in @@ -0,0 +1,19 @@ +#ifndef __GoFiltersConfigure_h +#define __GoFiltersConfigure_h + +/* Whether we are building shared libraries. */ +#if defined ( WIN32 ) && defined ( GOFIGURE2_BUILD_SHARED_LIBS ) + +#if defined ( Filters_EXPORTS ) +#define GOFILTERS_EXPORT __declspec(dllexport) +#else +#define GOFILTERS_EXPORT __declspec(dllimport) +#endif + +#else + +#define GOFILTERS_EXPORT + +#endif + +#endif diff --git a/Code/Filters/itkBinaryMaskImageToGoFigureMeshAttributes.h b/Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.h similarity index 98% rename from Code/Filters/itkBinaryMaskImageToGoFigureMeshAttributes.h rename to Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.h index 680be48e..3e2ba8ce 100644 --- a/Code/Filters/itkBinaryMaskImageToGoFigureMeshAttributes.h +++ b/Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.h @@ -34,6 +34,8 @@ #ifndef __itkBinaryMaskImageToGoFigureMeshAttributes_h #define __itkBinaryMaskImageToGoFigureMeshAttributes_h +#include "GoFiltersConfigure.h" + #include "itkLightObject.h" #include "itkShapeLabelObject.h" #include "itkStatisticsLabelObject.h" @@ -50,7 +52,7 @@ namespace itk * \sa GoFigureMeshAttributes * */ template< class TInput, class TMask > -class BinaryMaskImageToGoFigureMeshAttributes:public LightObject +class GOFILTERS_EXPORT BinaryMaskImageToGoFigureMeshAttributes:public LightObject { public: typedef BinaryMaskImageToGoFigureMeshAttributes Self; diff --git a/Code/Filters/itkBinaryMaskImageToGoFigureMeshAttributes.txx b/Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.txx similarity index 100% rename from Code/Filters/itkBinaryMaskImageToGoFigureMeshAttributes.txx rename to Code/Filters/Mesh/Attributes/itkBinaryMaskImageToGoFigureMeshAttributes.txx diff --git a/Code/Filters/itkvtkPolyDataToGoFigureMeshAttributes.h b/Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.h similarity index 97% rename from Code/Filters/itkvtkPolyDataToGoFigureMeshAttributes.h rename to Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.h index 4c8fe248..b2f9e2ad 100644 --- a/Code/Filters/itkvtkPolyDataToGoFigureMeshAttributes.h +++ b/Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.h @@ -34,6 +34,8 @@ #ifndef __itkvtkPolyDataToGoFigureMeshAttributes_h #define __itkvtkPolyDataToGoFigureMeshAttributes_h +#include "GoFiltersConfigure.h" + #include "itkLightObject.h" #include "itkvtkPolyDataToBinaryMaskImageFilter.h" #include "itkBinaryMaskImageToGoFigureMeshAttributes.h" @@ -43,7 +45,7 @@ namespace itk { template< class TImage > -class vtkPolyDataToGoFigureMeshAttributes:public LightObject +class GOFILTERS_EXPORT vtkPolyDataToGoFigureMeshAttributes:public LightObject { public: typedef vtkPolyDataToGoFigureMeshAttributes Self; diff --git a/Code/Filters/itkvtkPolyDataToGoFigureMeshAttributes.txx b/Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.txx similarity index 100% rename from Code/Filters/itkvtkPolyDataToGoFigureMeshAttributes.txx rename to Code/Filters/Mesh/Attributes/itkvtkPolyDataToGoFigureMeshAttributes.txx diff --git a/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.h b/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.h new file mode 100644 index 00000000..c472e575 --- /dev/null +++ b/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.h @@ -0,0 +1,76 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshMergeConvexHullFilter_h +#define __itkvtkMeshMergeConvexHullFilter_h + +#include "GoFiltersConfigure.h" + +#include "itkvtkMeshMergeFilterBase.h" + +#include "itkObjectFactory.h" + +namespace itk +{ +template< class TFeatureImage > +class GOFILTERS_EXPORT vtkMeshMergeConvexHullFilter : + public vtkMeshMergeFilterBase< TFeatureImage > +{ +public: + typedef vtkMeshMergeFilterBase< TFeatureImage > Superclass; + typedef vtkMeshMergeConvexHullFilter Self; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro( vtkMeshMergeConvexHullFilter, + vtkMeshMergeFilterBase ); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + +protected: + vtkMeshMergeConvexHullFilter(); + ~vtkMeshMergeConvexHullFilter() {} + + void GenerateData(); + void SetRequiredAttributeComputationFlags(); + +private: + vtkMeshMergeConvexHullFilter( const Self& ); + void operator = ( const Self& ); +}; +} +#include "itkvtkMeshMergeConvexHullFilter.txx" +#endif // __itkvtkMeshMergeConvexHullFilter_h diff --git a/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.txx b/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.txx new file mode 100644 index 00000000..2b5a1794 --- /dev/null +++ b/Code/Filters/Mesh/Merge/itkvtkMeshMergeConvexHullFilter.txx @@ -0,0 +1,96 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshMergeConvexHullFilter_txx +#define __itkvtkMeshMergeConvexHullFilter_txx + +#include "itkvtkMeshMergeConvexHullFilter.h" + +#include "vtkSmartPointer.h" +#include "vtkAppendPolyData.h" +#include "vtkDelaunay3D.h" +#include "vtkDataSetSurfaceFilter.h" + +namespace itk +{ +template< class TFeatureImage > +vtkMeshMergeConvexHullFilter< TFeatureImage >:: +vtkMeshMergeConvexHullFilter() : Superclass() +{ + this->SetRequiredAttributeComputationFlags(); +} + +template< class TFeatureImage > +void +vtkMeshMergeConvexHullFilter< TFeatureImage >:: +GenerateData() +{ + vtkSmartPointer< vtkAppendPolyData > append = + vtkSmartPointer< vtkAppendPolyData >::New(); + + typename std::list< vtkPolyData* >::iterator it = this->m_Inputs.begin(); + typename std::list< vtkPolyData* >::iterator end = this->m_Inputs.end(); + + while( it != end ) + { + append->AddInput( *it ); + ++it; + } + + append->Update(); + + vtkSmartPointer< vtkDelaunay3D > delaunay = + vtkSmartPointer< vtkDelaunay3D >::New(); + delaunay->SetInputConnection( append->GetOutputPort() ); + delaunay->Update(); + + vtkSmartPointer surfaceFilter = + vtkSmartPointer::New(); + surfaceFilter->SetInputConnection(delaunay->GetOutputPort()); + surfaceFilter->Update(); + + this->m_Outputs.front()->DeepCopy( surfaceFilter->GetOutput() ); +} + +template< class TFeatureImage > +void +vtkMeshMergeConvexHullFilter< TFeatureImage >:: +SetRequiredAttributeComputationFlags() +{ + this->m_ShapeComputation = true; + this->m_IntensityComputation = true; +} + +} +#endif // __itkvtkMeshMergeConvexHullFilter_h diff --git a/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.h b/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.h new file mode 100644 index 00000000..a98bf908 --- /dev/null +++ b/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.h @@ -0,0 +1,79 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-10 + + Copyright (c) 2009-10, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshMergeFilterBase_h +#define __itkvtkMeshMergeFilterBase_h + +#include "GoFiltersConfigure.h" + +#include "itkvtkMeshFilterBase.h" +#include + +class vtkPolyData; + +namespace itk +{ +template< class TFeatureImage > +class GOFILTERS_EXPORT vtkMeshMergeFilterBase : + public vtkMeshFilterBase< TFeatureImage > +{ +public: + typedef vtkMeshFilterBase< TFeatureImage > Superclass; + typedef vtkMeshMergeFilterBase Self; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + itkTypeMacro( vtkMeshMergeFilterBase, vtkMeshFilterBase ); + + typedef typename Superclass::FeatureImageType FeatureImageType; + typedef typename Superclass::FeatureImagePointer FeatureImagePointer; + + void SetInputs( std::list< vtkPolyData* > iMeshes ); + + vtkPolyData* GetOutput(); + +protected: + vtkMeshMergeFilterBase(); + virtual ~vtkMeshMergeFilterBase() {} + + std::list< vtkPolyData* > m_Inputs; + +private: + vtkMeshMergeFilterBase( const Self& ); + void operator = ( const Self& ); +}; +} + +#include "itkvtkMeshMergeFilterBase.txx" +#endif // __itkvtkMeshMergeFilterBase_h diff --git a/Code/GUI/lib/QGoContourSemiAutoShapeWidget.h b/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.txx similarity index 71% rename from Code/GUI/lib/QGoContourSemiAutoShapeWidget.h rename to Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.txx index 8fba3560..6cf78dd3 100644 --- a/Code/GUI/lib/QGoContourSemiAutoShapeWidget.h +++ b/Code/Filters/Mesh/Merge/itkvtkMeshMergeFilterBase.txx @@ -1,8 +1,8 @@ /*========================================================================= Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + at Megason Lab, Systems biology, Harvard Medical school, 2009-10 - Copyright (c) 2009-11, President and Fellows of Harvard College. + Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,31 +32,38 @@ =========================================================================*/ -#ifndef __QGoContourSemiAutoShapeWidget_h -#define __QGoContourSemiAutoShapeWidget_h +#ifndef __itkvtkMeshMergeFilterBase_txx +#define __itkvtkMeshMergeFilterBase_txx -#include -#include "ui_ShapeWidget.h" +#include "itkvtkMeshMergeFilterBase.h" +#include "vtkPolyData.h" -/** - * \class QGoContourSemiAutoShapeWidget - * \ingroup QGoContourSeed - * \brief Widget suited for the shape segmentation. Shape can be a sphere, a cube, etc. -*/ +namespace itk +{ +template< class TFeature > +vtkMeshMergeFilterBase< TFeature >:: +vtkMeshMergeFilterBase() : Superclass() +{ + this->m_Outputs.resize( 1, NULL ); + this->m_Outputs[0] = vtkPolyData::New(); +} + +template< class TFeature > +void +vtkMeshMergeFilterBase< TFeature >:: +SetInputs( std::list< vtkPolyData* > iMeshes ) +{ + m_Inputs = iMeshes; + this->Modified(); +} -class QGoContourSemiAutoShapeWidget: - public QWidget, - protected Ui::ShapeWidget +template< class TFeature > +vtkPolyData* +vtkMeshMergeFilterBase< TFeature >:: +GetOutput() { - Q_OBJECT -public: - explicit QGoContourSemiAutoShapeWidget(QWidget *iParent = 0); - ~QGoContourSemiAutoShapeWidget(); -signals: - /* - * \brief Signal sent when the shape is modified - */ - void Shape(int); -}; + return this->m_Outputs.front(); +} +} #endif diff --git a/Code/Filters/Mesh/MeshToContourFilter.cxx b/Code/Filters/Mesh/MeshToContourFilter.cxx new file mode 100644 index 00000000..686dd535 --- /dev/null +++ b/Code/Filters/Mesh/MeshToContourFilter.cxx @@ -0,0 +1,146 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "MeshToContourFilter.h" + +#include "vtkPolyData.h" +#include "vtkPlane.h" +#include "vtkCutter.h" + +//----------------------------------------------------------------------------- +MeshToContourFilter:: +MeshToContourFilter() : + m_Input(NULL) +{ + SetSpacing(0., 0., 0.); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +MeshToContourFilter:: +~MeshToContourFilter() +{ +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +MeshToContourFilter:: +SetInput(vtkPolyData* iInput) +{ + m_Input = iInput; +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +MeshToContourFilter:: +SetSpacing(const double& iX, const double & iY, const double& iZ) +{ + m_Spacing[0] = iX; + m_Spacing[1] = iY; + m_Spacing[2] = iZ; +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +std::map +MeshToContourFilter:: +ExtractPolyData(ORIENTATION iOrientation) +{ + std::map contours; + + // create plane to extract contours (based on orientation) + double normal[3] = {0., 0., 0.}; + + switch (iOrientation) + { + case XY: + { + normal[2] = 1; + break; + } + case XZ: + { + normal[1] = 1; + break; + } + case YZ: + { + normal[0] = 1; + break; + } + default: + { + break; + } + } + + double origin[3] = {0., 0., 0.}; + origin[0] = m_Input->GetCenter()[0]; + origin[1] = m_Input->GetCenter()[1]; + origin[2] = m_Input->GetCenter()[2]; + + double position = m_Input->GetBounds()[4 - 2*iOrientation]; + double maxPosition = m_Input->GetBounds()[5 - 2*iOrientation]; + double spacing = this->m_Spacing[2-iOrientation]; + + while( position < maxPosition) + { + origin[2-iOrientation] = position; + + vtkPlane* plane = vtkPlane::New(); + plane->SetNormal(normal); + plane->SetOrigin(origin); + + // cut + vtkCutter* cutter = vtkCutter::New(); + cutter->SetInput(m_Input); + cutter->SetCutFunction(plane); + cutter->Update(); + + vtkPolyData* polydata = vtkPolyData::New(); + polydata->DeepCopy( cutter->GetOutput() ); + + plane->Delete(); + cutter->Delete(); + + contours[position] = polydata; + + // increase position + position += spacing; + } + + return contours; +} +//----------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoContourSeedSegmentation.h b/Code/Filters/Mesh/MeshToContourFilter.h similarity index 60% rename from Code/GUI/lib/QGoContourSeedSegmentation.h rename to Code/Filters/Mesh/MeshToContourFilter.h index 8cd369a1..f26b3b5f 100644 --- a/Code/GUI/lib/QGoContourSeedSegmentation.h +++ b/Code/Filters/Mesh/MeshToContourFilter.h @@ -1,8 +1,8 @@ /*========================================================================= Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + at Megason Lab, Systems biology, Harvard Medical school, 2009-10 - Copyright (c) 2009-11, President and Fellows of Harvard College. + Copyright (c) 2009-10, President and Fellows of Harvard College. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,52 +31,57 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#ifndef __QGoContourSeedSegmentation_h -#define __QGoContourSeedSegmentation_h +#ifndef __MeshToContourFilter_h +#define __MeshToContourFilter_h -#include -#include -#include "QGoGUILibConfigure.h" +#include "GoFiltersConfigure.h" -#include "QGoSeedSegmentationBase.h" +#include "map" -#include "vtkSmartPointer.h" +class vtkPolyData; -class vtkPoints; +/** + * \class MeshToContourFilter + * \brief + **/ +class GOFILTERS_EXPORT MeshToContourFilter +{ +public: -class vtkImageData; + MeshToContourFilter(); + ~MeshToContourFilter(); -// segmentation filters -class QGoFilterChanAndVese; -class QGoFilterShape; + enum ORIENTATION { + XY = 0, + XZ = 1, + YZ = 2 + }; -/** - * \class QGoContourSeedSegmentation - * \ingroup QGoContourSeed - * \brief Interface between the segmentation filters and the seed base widget. - * Generates contours. -*/ + /** + * \brief Set polydata to be splitted + * \param[in] iInput polydata to be splitted + */ + void SetInput(vtkPolyData* iInput); -class QGOGUILIB_EXPORT QGoContourSeedSegmentation:public QGoSeedSegmentationBase -{ - Q_OBJECT -public: /** - * \brief Constructor - */ - explicit QGoContourSeedSegmentation(QWidget *parentW = 0, - vtkPoints *seeds = 0, - std::vector< vtkSmartPointer > *iOriginalImage = 0, - int iSampling = 0); + * \brief Set spacing of the original image to know how many slices to extract + * \param[in] iX X spacing + * \param[in] iY Y spacing + * \param[in] iZ Z spacing + */ + void SetSpacing(const double& iX, const double & iY, const double& iZ); /** - * \brief Destructor - */ - ~QGoContourSeedSegmentation(); -private: - QGoFilterChanAndVese* m_LevelSetfilter; - QGoFilterShape * m_ShapeFilter; + * \brief Extract contours from polydata given an orientation + * \param[in] iOrientation Desired Orientation (XY, XZ, YZ) + * \return Map of polydatas indexed by slice position. + * \note polydatas has to be deleted + */ + std::map ExtractPolyData(ORIENTATION iOrientation); - std::vector< vtkSmartPointer > *m_OriginalImage; +private: + vtkPolyData* m_Input; + double m_Spacing[3]; }; + #endif diff --git a/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.h b/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.h new file mode 100644 index 00000000..7f1a5272 --- /dev/null +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.h @@ -0,0 +1,97 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshSplitterDanielssonDistanceImageFilter_h +#define __itkvtkMeshSplitterDanielssonDistanceImageFilter_h + +#include "itkvtkMeshSplitterImageFilterBase.h" +#include "itkImageRegionIterator.h" +#include "itkImageRegionConstIterator.h" + +#include "itkDanielssonDistanceMapImageFilter.h" + +namespace itk +{ +template< class TFeatureImage, + class TPointSet = + PointSet< typename TFeatureImage::PointType::CoordRepType, + TFeatureImage::ImageDimension > > +class vtkMeshSplitterDanielssonDistanceImageFilter : + public vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet > + { +public: + typedef vtkMeshSplitterDanielssonDistanceImageFilter Self; + typedef vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet > Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro( vtkMeshSplitterDanielssonDistanceImageFilter, + vtkMeshSplitterImageFilterBase ); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef typename Superclass::FeatureImageType FeatureImageType; + typedef typename Superclass::FeatureImagePointer FeatureImagePointer; + typedef typename Superclass::FeatureImagePixelType FeatureImagePixelType; + typedef typename Superclass::FeatureImageIndexType FeatureImageIndexType; + typedef typename Superclass::FeatureImagePointType FeatureImagePointType; + + typedef typename Superclass::PointsContainerPointer + PointsContainerPointer; + typedef typename Superclass::PointsContainerConstIterator + PointsContainerConstIterator; + + typedef ImageRegionIterator< FeatureImageType > IteratorType; + typedef ImageRegionConstIterator< FeatureImageType > ConstIteratorType; + + typedef DanielssonDistanceMapImageFilter< FeatureImageType, FeatureImageType > + DistanceFilterType; + typedef typename DistanceFilterType::Pointer DistanceFilterPointer; + +protected: + vtkMeshSplitterDanielssonDistanceImageFilter(); + ~vtkMeshSplitterDanielssonDistanceImageFilter() {} + + void SplitBinaryImage(); + +private: + vtkMeshSplitterDanielssonDistanceImageFilter( const Self& ); + void operator = ( const Self& ); + }; +} + +#include "itkvtkMeshSplitterDanielssonDistanceImageFilter.txx" +#endif // __itkvtkMeshSplitterDanielssonDistanceImageFilter_h diff --git a/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.txx b/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.txx new file mode 100644 index 00000000..6fa4b882 --- /dev/null +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterDanielssonDistanceImageFilter.txx @@ -0,0 +1,110 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx +#define __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx + +#include "itkvtkMeshSplitterDanielssonDistanceImageFilter.h" + +namespace itk +{ +template< class TFeatureImage, class TPointSet > +vtkMeshSplitterDanielssonDistanceImageFilter< TFeatureImage, TPointSet >:: +vtkMeshSplitterDanielssonDistanceImageFilter() : Superclass() +{} + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterDanielssonDistanceImageFilter< TFeatureImage, TPointSet >:: +SplitBinaryImage() +{ + FeatureImagePixelType zero = NumericTraits< FeatureImagePixelType >::Zero; + + FeatureImagePointer seed_image = FeatureImageType::New(); + seed_image->SetRegions( this->m_BinaryImage->GetLargestPossibleRegion() ); + seed_image->SetOrigin( this->m_BinaryImage->GetOrigin() ); + seed_image->SetSpacing( this->m_BinaryImage->GetSpacing() ); + seed_image->Allocate(); + seed_image->FillBuffer( zero ); + seed_image->Update(); + + // Fill the seeds + FeatureImageIndexType index; + FeatureImagePointType pt; + + PointsContainerPointer points = this->m_Seeds->GetPoints(); + PointsContainerConstIterator it = points->Begin(); + PointsContainerConstIterator end = points->End(); + + while( it != end ) + { + pt.CastFrom( it->Value() ); + seed_image->TransformPhysicalPointToIndex( pt, index ); + seed_image->SetPixel( index, 1 + it->Index() ); + ++it; + } + + //Compute the voronoi map + DistanceFilterPointer distance_filter = DistanceFilterType::New(); + distance_filter->SetInput( seed_image ); + distance_filter->UseImageSpacingOn(); + distance_filter->SetInputIsBinary( true ); + distance_filter->UpdateLargestPossibleRegion(); + distance_filter->Update(); + + this->m_OutputImage = distance_filter->GetVoronoiMap(); + this->m_OutputImage->DisconnectPipeline(); + + IteratorType Vor_it( this->m_OutputImage, + this->m_OutputImage->GetLargestPossibleRegion() ); + + ConstIteratorType Bin_it( this->m_BinaryImage, + this->m_BinaryImage->GetLargestPossibleRegion() ); + + Vor_it.GoToBegin(); + Bin_it.GoToBegin(); + + while( !Vor_it.IsAtEnd() ) + { + if( Bin_it.Get() == zero ) + { + Vor_it.Set( zero ); + } + ++Vor_it; + ++Bin_it; + } + } +} + +#endif // __itkvtkMeshSplitterDanielssonDistanceImageFilter_txx diff --git a/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.h b/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.h new file mode 100644 index 00000000..27d0137a --- /dev/null +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.h @@ -0,0 +1,109 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshSplitterFilterBase_h +#define __itkvtkMeshSplitterFilterBase_h + +#include "itkvtkMeshFilterBase.h" +#include "itkPointSet.h" +#include "vtkPolyData.h" + +#include + +namespace itk +{ +/** + \class vtkMeshSplitterFilterBase + \brief +*/ +template< class TFeatureImage > +class vtkMeshSplitterFilterBase : public vtkMeshFilterBase< TFeatureImage > + { +public: + typedef vtkMeshFilterBase< TFeatureImage > Superclass; + typedef vtkMeshSplitterFilterBase Self; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro( vtkMeshSplitterFilterBase, vtkMeshFilterBase ); + + typedef typename Superclass::FeatureImageType FeatureImageType; + typedef typename Superclass::FeatureImagePointer FeatureImagePointer; + + void SetMesh( vtkPolyData* iMesh ); + + std::vector< vtkPolyData* > GetOutputs(); + +protected: + /** \brief Constructor */ + vtkMeshSplitterFilterBase(); + + /** \brief Destructor */ + virtual ~vtkMeshSplitterFilterBase() {} + + vtkPolyData* m_Mesh; + + double m_Bounds[6]; + + + template< class TPoint > + bool IsPointInMeshBounds( const TPoint& iP ) const + { + for( unsigned int i = 0; i < 3; ++i ) + { + double t = static_cast< double >( iP[i] ); + + if( ( t < m_Bounds[2*i] ) || ( t > m_Bounds[2*i+1] ) ) + { + return false; + } + } + return true; + } + + + /** \brief Main method to be reimplemented in inherited classes */ + virtual void Split() = 0; + + virtual void GenerateData(); + +private: + vtkMeshSplitterFilterBase( const Self& ); + void operator = ( const Self& ); + }; +} + +#include "itkvtkMeshSplitterFilterBase.txx" +#endif // __itkvtkMeshSplitterFilterBase_h diff --git a/Code/GUI/lib/QGoContourSemiAutoWatershedWidget.h b/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.txx similarity index 63% rename from Code/GUI/lib/QGoContourSemiAutoWatershedWidget.h rename to Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.txx index a65836e4..5a1f64d5 100644 --- a/Code/GUI/lib/QGoContourSemiAutoWatershedWidget.h +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterFilterBase.txx @@ -32,55 +32,57 @@ =========================================================================*/ -#ifndef __QGoContourSemiAutoWatershedWidget_h -#define __QGoContourSemiAutoWatershedWidget_h +#ifndef __itkvtkMeshSplitterFilterBase_txx +#define __itkvtkMeshSplitterFilterBase_txx -#include +#include "itkvtkMeshSplitterFilterBase.h" -#include "ui_WatershedWidget.h" - -/** - * \class QGoContourSemiAutoWatershedWidget - * \ingroup QGoContourSeed - * \brief Widget suited for the watershed segmentation -*/ - -class QGoContourSemiAutoWatershedWidget: - public QWidget, - protected Ui::WatershedWidget +namespace itk { - Q_OBJECT -public: - explicit QGoContourSemiAutoWatershedWidget(QWidget *iParent = 0); - ~QGoContourSemiAutoWatershedWidget(); - - //QVBoxLayout *gridLayout2; - - signals: - /* - * \brief Signal sent when the treshmin is modified - */ - void TreshMin(int); - - /* - * \brief Signal sent when the treshmax is modified - */ - void TreshMax(int); - - /* - * \brief Signal sent when the corTresh is modified - */ - void CorrTresh(double); +template< class TFeatureImage > +vtkMeshSplitterFilterBase< TFeatureImage >:: +vtkMeshSplitterFilterBase() : Superclass(), m_Mesh( NULL ) + { + for( unsigned int dim = 0; dim < 3; ++dim ) + { + m_Bounds[2 * dim] = NumericTraits< double >::max(); + m_Bounds[2 * dim + 1] = NumericTraits< double >::min(); + } + } + +template< class TFeatureImage > +void +vtkMeshSplitterFilterBase< TFeatureImage >:: +SetMesh( vtkPolyData* iMesh ) +{ + if( ( iMesh ) && ( iMesh != m_Mesh ) ) + { + m_Mesh = iMesh; + m_Mesh->GetBounds( m_Bounds ); + this->Modified(); + } +} + +template< class TFeatureImage > +std::vector< vtkPolyData* > +vtkMeshSplitterFilterBase< TFeatureImage >:: +GetOutputs() +{ + return this->m_Outputs; +} - /* - * \brief Signal sent when the Alpha is modified - */ - void Alpha(double); +template< class TFeatureImage > +void +vtkMeshSplitterFilterBase< TFeatureImage >:: +GenerateData() +{ + if( !m_Mesh ) + { + itkGenericExceptionMacro( << "m_Mesh is NULL" ); + } - /* - * \brief Signal sent when the Beta is modified - */ - void Beta(double); -}; + this->Split(); +} +} #endif diff --git a/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.h b/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.h new file mode 100644 index 00000000..779641b7 --- /dev/null +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.h @@ -0,0 +1,125 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshSplitterImageFilterBase_h +#define __itkvtkMeshSplitterImageFilterBase_h + +#include "itkLightObject.h" +#include "itkPointSet.h" +#include "vtkPolyData.h" +#include "itkvtkMeshSplitterFilterBase.h" +#include "itkExtractMeshesFromLabelImageFilter.h" +#include "itkQuadEdgeMeshTovtkPolyData.h" +#include "itkImage.h" +#include + +namespace itk +{ +/** + \class vtkMeshSplitterImageFilterBase + \brief +*/ +template< class TFeatureImage, + class TPointSet > +class vtkMeshSplitterImageFilterBase : + public vtkMeshSplitterFilterBase< TFeatureImage > + { +public: + typedef vtkMeshSplitterImageFilterBase Self; + typedef vtkMeshSplitterFilterBase< TFeatureImage > Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro( vtkMeshSplitterFilterBase, vtkMeshSplitterFilterBase ); + + typedef TFeatureImage FeatureImageType; + typedef typename FeatureImageType::Pointer FeatureImagePointer; + typedef typename FeatureImageType::PixelType FeatureImagePixelType; + typedef typename FeatureImageType::IndexType FeatureImageIndexType; + typedef typename FeatureImageType::PointType FeatureImagePointType; + + typedef TPointSet PointSetType; + typedef typename PointSetType::Pointer PointSetPointer; + typedef typename PointSetType::PointsContainerPointer PointsContainerPointer; + typedef typename PointSetType::PointsContainerConstIterator PointsContainerConstIterator; + typedef typename PointSetType::PointType PointType; + + typedef ExtractMeshesFromLabelImageFilter< FeatureImageType > ExtracMeshFilterType; + typedef typename ExtracMeshFilterType::Pointer ExtracMeshFilterPointer; + typedef typename ExtracMeshFilterType::MeshType MeshType; + + typedef QuadEdgeMeshTovtkPolyData< MeshType > ITKVTKMeshConverterType; + typedef typename ITKVTKMeshConverterType::Pointer ITKVTKMeshConverterPointer; + + void SetSeeds( PointSetType* iSeeds ); + + +protected: + vtkMeshSplitterImageFilterBase(); + + virtual ~vtkMeshSplitterImageFilterBase() {} + + FeatureImagePointer m_BinaryImage; + FeatureImagePointer m_OutputImage; + + PointSetPointer m_Seeds; + + unsigned int m_NumberOfThreads; + unsigned int m_NumberOfTrianglesPerMesh; + unsigned int m_NumberOfSmoothingIterations; + unsigned int m_SmoothingRelaxationFactor; + + bool m_DelaunayConforming; + bool m_UseSmoothing; + bool m_UseDecimation; + + bool CheckAllSeeds() const; + + virtual void ComputeBinaryImageFromInputMesh(); + + virtual void Split(); + + virtual void SplitBinaryImage() = 0; + + void GenerateMeshesFromOutputImage(); + void SetRequiredAttributeComputationFlags(); + +private: + vtkMeshSplitterImageFilterBase( const Self& ); + void operator = ( const Self& ); + }; +} +#include "itkvtkMeshSplitterImageFilterBase.txx" +#endif // __itkvtkMeshSplitterImageFilterBase_h diff --git a/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.txx b/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.txx new file mode 100644 index 00000000..f6869b6f --- /dev/null +++ b/Code/Filters/Mesh/Split/itkvtkMeshSplitterImageFilterBase.txx @@ -0,0 +1,205 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __itkvtkMeshSplitterImageFilterBase_txx +#define __itkvtkMeshSplitterImageFilterBase_txx + +#include "itkvtkMeshSplitterImageFilterBase.h" + +#include "itkConvertMeshesToLabelImageFilter.h" +#include "itkvtkPolyDataToitkQuadEdgeMesh.h" + +namespace itk +{ +template< class TFeatureImage, class TPointSet > +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +vtkMeshSplitterImageFilterBase() : Superclass( ), m_Seeds( NULL ), + m_NumberOfThreads( 1 ), m_NumberOfTrianglesPerMesh( 200 ), + m_NumberOfSmoothingIterations( 8 ), m_SmoothingRelaxationFactor( 0.75 ), + m_DelaunayConforming( false ), m_UseSmoothing( true ), + m_UseDecimation( true ) +{ + this->SetRequiredAttributeComputationFlags(); +} + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +SetSeeds( PointSetType* iSeeds ) +{ + if( iSeeds ) + { + m_Seeds = iSeeds; + this->Modified(); + } +} + +template< class TFeatureImage, class TPointSet > +bool +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +CheckAllSeeds() const +{ + PointsContainerPointer points = m_Seeds->GetPoints(); + + PointsContainerConstIterator it = points->Begin(); + PointsContainerConstIterator end = points->End(); + + while( it != end ) + { + if( !IsPointInMeshBounds( it->Value() ) ) + { + std::cout << it->Value() << " is out of bounds" << std::endl; + return false; + } + ++it; + } + return true; + } + + + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +ComputeBinaryImageFromInputMesh() +{ + typedef ConvertMeshesToLabelImageFilter< FeatureImageType > MeshToLabelFilterType; + typedef typename MeshToLabelFilterType::Pointer MeshToLabelFilterPointer; + typedef typename MeshToLabelFilterType::MeshType MeshType; + + typedef vtkPolyDataToitkQuadEdgeMesh< MeshType > MeshConverterType; + typedef typename MeshConverterType::Pointer MeshConverterPointer; + + MeshConverterPointer converter = MeshConverterType::New(); + converter->SetInput( this->m_Mesh ); + converter->Update(); + + typename MeshToLabelFilterType::MeshVectorType mesh_vector( 1 ); + mesh_vector[0] = converter->GetOutput(); + + m_BinaryImage = FeatureImageType::New(); + m_BinaryImage->CopyInformation( this->m_Images.front() ); + m_BinaryImage->SetRegions( this->m_Images.front()->GetLargestPossibleRegion() ); + m_BinaryImage->Allocate(); + m_BinaryImage->FillBuffer( 0 ); + + typename MeshToLabelFilterType::Pointer binarizer = MeshToLabelFilterType::New(); + binarizer->SetInput( m_BinaryImage ); + binarizer->SetMeshes( mesh_vector ); + binarizer->Update(); +} + + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +Split() +{ + if( m_Seeds.IsNull() ) + { + itkGenericExceptionMacro( << "m_Seeds is NULL" ); + } + + if( !CheckAllSeeds() ) + { + itkGenericExceptionMacro( <<"Out of bounds" ); + } + + ComputeBinaryImageFromInputMesh(); + + this->SplitBinaryImage(); + GenerateMeshesFromOutputImage(); +} + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +GenerateMeshesFromOutputImage() +{ + ExtracMeshFilterPointer extractor = ExtracMeshFilterType::New(); + extractor->SetInput( m_OutputImage ); + + size_t i = 0; + size_t NumberOfImages = this->m_Images.size(); + + extractor->SetNumberOfFeatureImages( NumberOfImages ); + + for( ; i < NumberOfImages; ++i ) + { + extractor->SetFeatureImage( i, this->m_Images[i] ); + } + + extractor->SetNumberOfThreads( m_NumberOfThreads ); + extractor->SetUseSmoothing( m_UseSmoothing ); + extractor->SetUseDecimation( m_UseDecimation ); + extractor->SetNumberOfTrianglesPerMesh( m_NumberOfTrianglesPerMesh ); + extractor->SetNumberOfSmoothingIterations( m_NumberOfSmoothingIterations ); + extractor->SetSmoothingRelaxationFactor( m_SmoothingRelaxationFactor ); + extractor->SetDelaunayConforming( m_DelaunayConforming ); + extractor->Update(); + + this->m_ShapeLabelMap = extractor->GetShapeLabelMap(); + this->m_StatLabelMap = extractor->GetStatLabelMap(); + + typedef typename ExtracMeshFilterType::MeshVectorType MeshVectorType; + MeshVectorType MeshVector = extractor->GetOutputs(); + + typename MeshVectorType::const_iterator it = MeshVector.begin(); + typename MeshVectorType::const_iterator end = MeshVector.end(); + + this->m_Outputs.resize( MeshVector.size() ); + + while( it != end ) + { + ITKVTKMeshConverterPointer converter = ITKVTKMeshConverterType::New(); + converter->SetInput( *it ); + converter->Update(); + + this->m_Outputs[i] = vtkPolyData::New(); + this->m_Outputs[i]->DeepCopy( converter->GetOutput() ); + ++it; + ++i; + } +} + +template< class TFeatureImage, class TPointSet > +void +vtkMeshSplitterImageFilterBase< TFeatureImage, TPointSet >:: +SetRequiredAttributeComputationFlags() + { + this->m_ShapeComputation = false; + this->m_IntensityComputation = false; + } +} + +#endif // __itkvtkMeshSplitterImageFilterBase_txx diff --git a/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.h b/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.h new file mode 100644 index 00000000..f5770af5 --- /dev/null +++ b/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.h @@ -0,0 +1,153 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __itkConvertMeshesToLabelImageFilter_h +#define __itkConvertMeshesToLabelImageFilter_h + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif + +#include "GoFiltersConfigure.h" + +#include "itkImageToImageFilter.h" +#include "itkImage.h" + +#include "itkImageRegionIteratorWithIndex.h" +#include "itkRegionOfInterestImageFilter.h" +#include "itkQuadEdgeMesh.h" +#include "itkTriangleMeshToBinaryImageFilter.h" +#include "itkVector.h" + +#include +#include "itkMultiThreader.h" + +namespace itk +{ + +template< class TImage, + class TMesh = QuadEdgeMesh< typename TImage::PointType::CoordRepType, + TImage::ImageDimension > > +class GOFILTERS_EXPORT ConvertMeshesToLabelImageFilter : public Object +{ +public: + typedef ConvertMeshesToLabelImageFilter Self; + typedef Object Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + itkStaticConstMacro ( ImageDimension, unsigned int, TImage::ImageDimension ); + + /** Run-time type information (and related methods). */ + itkTypeMacro( ConvertMeshesToLabelImageFilter, Object ); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Input Image typedef */ + typedef TImage ImageType; + typedef typename ImageType::Pointer ImagePointer; + typedef typename ImageType::ConstPointer ImageConstPointer; + typedef typename ImageType::IndexType IndexType; + typedef typename IndexType::IndexValueType IndexValueType; + typedef typename ImageType::PixelType PixelType; + typedef typename ImageType::SizeType SizeType; + typedef typename SizeType::SizeValueType SizeValueType; + typedef typename ImageType::RegionType RegionType; + typedef typename ImageType::SpacingType SpacingType; + typedef typename ImageType::PointType PointType; + typedef typename PointType::CoordRepType CoordType; + + typedef TMesh MeshType; + typedef typename MeshType::Pointer MeshPointer; + typedef std::vector< MeshPointer > MeshVectorType; + + typedef RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; + typedef typename ROIFilterType::Pointer ROIFilterPointer; + + typedef ImageRegionIterator< ImageType > IteratorType; + typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; + + typedef TriangleMeshToBinaryImageFilter< MeshType, ImageType > MeshToImageFilterType; + typedef typename MeshToImageFilterType::Pointer MeshToImageFilterPointer; + + typedef MultiThreader ThreaderType; + typedef typename ThreaderType::Pointer ThreaderPointer; + + itkSetObjectMacro( Input , ImageType ); + itkGetConstMacro( NumberOfMeshes, size_t ); + + itkGetConstMacro( NumberOfThreads, unsigned int ); + itkSetMacro( NumberOfThreads, unsigned int ); + + void SetMeshes( const MeshVectorType& iMeshes ); + + void Update(); + +protected: + ConvertMeshesToLabelImageFilter(); + ~ConvertMeshesToLabelImageFilter(){} + void PrintSelf(std::ostream& os, Indent indent) const; + void ThreadedExtractMesh( const unsigned int& startLabel, + const unsigned int& endLabel ); + + static ITK_THREAD_RETURN_TYPE ThreaderCallback(void * arg); + + struct ThreadStruct + { + Self* Filter; + }; + + size_t m_NumberOfMeshes; +#ifdef ITKv4 + ThreadIdType m_NumberOfThreads; +#else + int m_NumberOfThreads; +#endif + + ImageType* m_Input; + + MeshVectorType m_Meshes; + + void GenerateData(); + +private: + ConvertMeshesToLabelImageFilter(const Self&); + void operator=(const Self&); +}; + +} // end namespace itk + +#include "itkConvertMeshesToLabelImageFilter.txx" + +#endif diff --git a/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.txx b/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.txx new file mode 100644 index 00000000..77a0464c --- /dev/null +++ b/Code/Filters/Mesh/itkConvertMeshesToLabelImageFilter.txx @@ -0,0 +1,223 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __itkConvertMeshesToLabelImageFilter_txx +#define __itkConvertMeshesToLabelImageFilter_txx + +#include "itkConvertMeshesToLabelImageFilter.h" + +static itk::SimpleFastMutexLock m_MutexCMLF; + +namespace itk +{ + +template< class TImage, class TMesh > +ConvertMeshesToLabelImageFilter< TImage, TMesh > +::ConvertMeshesToLabelImageFilter() +{ + m_NumberOfMeshes = 0; + m_NumberOfThreads = 1; + m_Input = NULL; +} + + +template< class TImage, class TMesh > +void +ConvertMeshesToLabelImageFilter< TImage, TMesh >:: +SetMeshes( const MeshVectorType& iMeshes ) +{ + m_Meshes = iMeshes; + this->Modified(); +} + + +template< class TImage, class TMesh > +void +ConvertMeshesToLabelImageFilter< TImage, TMesh >:: +Update() +{ + // Create an empty image + if ( !this->m_Input ) + { + itkGenericExceptionMacro( << "Input is NULL" ); + } + this->GenerateData(); +} + +template< class TImage, class TMesh > +void +ConvertMeshesToLabelImageFilter< TImage, TMesh >:: +GenerateData() +{ + m_NumberOfMeshes = this->m_Meshes.size(); + + ThreadStruct str; + str.Filter = this; + + ThreaderPointer threader = ThreaderType::New(); + threader->SetNumberOfThreads( m_NumberOfThreads ); + threader->SetSingleMethod( this->ThreaderCallback, &str ); + threader->SingleMethodExecute(); +} + +template< class TImage, class TMesh > +ITK_THREAD_RETURN_TYPE +ConvertMeshesToLabelImageFilter< TImage, TMesh >:: +ThreaderCallback(void * arg) +{ + unsigned int ThreadId = + ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; + + ThreadStruct * str = + (ThreadStruct *) (((MultiThreader::ThreadInfoStruct *)(arg))->UserData); + + size_t numOfMeshes = str->Filter->m_NumberOfMeshes; + size_t numOfThreads = static_cast< size_t >( str->Filter->m_NumberOfThreads ); + + unsigned int MeshChunk = + static_cast< unsigned int >( numOfMeshes/ numOfThreads); + + ++MeshChunk; + + unsigned int startLabel = ThreadId * MeshChunk + 1; + unsigned int endLabel = ThreadId * MeshChunk + MeshChunk; + + if ( ThreadId == numOfThreads-1 ) + { + endLabel = numOfMeshes; + } + + str->Filter->ThreadedExtractMesh( startLabel, endLabel ); + + return ITK_THREAD_RETURN_VALUE; +} + + +template< class TImage, class TMesh > +void +ConvertMeshesToLabelImageFilter< TImage, TMesh >:: +ThreadedExtractMesh( const unsigned int& startLabel, + const unsigned int& endLabel ) +{ + //PointType origin = m_Input->GetOrigin(); + SpacingType spacing = m_Input->GetSpacing(); + RegionType m_LargestRegion = m_Input->GetLargestPossibleRegion(); + + PointType pmin, pmax; + IndexType imin, imax, null_index; + SizeType size; + RegionType region, newRegion; + PointType newOrigin; + + for( unsigned int i = 0; i < ImageDimension; i++ ) + { + null_index[i] = 0; + } + + unsigned int label = startLabel; + + while( label <= endLabel ) + { + MeshPointer temp_mesh = m_Meshes[label-1]; + + // Convert the bounding box into an image region and origin + pmin = temp_mesh->GetBoundingBox()->GetMinimum(); + pmax = temp_mesh->GetBoundingBox()->GetMaximum(); + + m_Input->TransformPhysicalPointToIndex( pmin, imin ); + m_Input->TransformPhysicalPointToIndex( pmax, imax ); + + for( unsigned int i = 0; i < ImageDimension; ++i ) + { + imin[i] = imin[i] - 1; + imax[i] = imax[i] + 1; + + size[i] = imax[i] - imin[i] + 1; + } + + region.SetIndex( imin ); + region.SetSize( size ); + region.Crop( m_LargestRegion ); + + m_Input->TransformIndexToPhysicalPoint( imin, newOrigin ); + + newRegion.SetIndex( null_index ); + newRegion.SetSize( region.GetSize() ); + + // Call TriangleMeshToBinaryImageFilter + MeshToImageFilterPointer imageFilter = MeshToImageFilterType::New(); + imageFilter->SetInput( temp_mesh ); + imageFilter->SetInsideValue( label ); + imageFilter->SetOrigin( newOrigin ); + imageFilter->SetSpacing( spacing ); + imageFilter->SetIndex( null_index ); + imageFilter->SetSize( size ); + imageFilter->Update(); + + ImagePointer comp = imageFilter->GetOutput(); + + // Copy the small output image here into the m_Input + IteratorType iIt( m_Input, region ); + iIt.GoToBegin(); + + IteratorType cIt( comp, comp->GetLargestPossibleRegion() ); + cIt.GoToBegin(); + + while( !iIt.IsAtEnd() ) + { + if ( ( cIt.Get() != 0 ) && ( iIt.Get() == 0 ) ) + { + iIt.Set( cIt.Get() ); + } + ++iIt; + ++cIt; + } + + ++label; + } +} + + +/** Print Self information */ +template< class TImage, class TMesh > +void +ConvertMeshesToLabelImageFilter< TImage, TMesh > +::PrintSelf(std::ostream& os, Indent indent) const +{ + Superclass::PrintSelf(os,indent); + os << indent << "NumberOfMeshes: " << m_NumberOfMeshes << std::endl; +} + +} // end namespace + +#endif diff --git a/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.h b/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.h new file mode 100644 index 00000000..d872e5d7 --- /dev/null +++ b/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.h @@ -0,0 +1,273 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __itkExtractMeshesFromLabelImageFilter_h +#define __itkExtractMeshesFromLabelImageFilter_h + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif + +#include "GoFiltersConfigure.h" + +#include "itkImageToImageFilter.h" +#include "itkImage.h" + +#include "itkImageRegionIteratorWithIndex.h" +#include "itkRegionOfInterestImageFilter.h" +#include "itkShapeLabelObject.h" +#include "itkLabelMap.h" +#include "itkLabelImageToShapeLabelMapFilter.h" +#include "itkLabelImageToStatisticsLabelMapFilter.h" +#include "itkShapeRelabelImageFilter.h" + +#include "itkVector.h" +#include "itkQuadEdgeMesh.h" +#include "itkSmoothingQuadEdgeMeshFilter.h" +#include "itkQuadEdgeMeshParamMatrixCoefficients.h" +#include "itkQuadEdgeMeshDecimationCriteria.h" +#include "itkSquaredEdgeLengthDecimationQuadEdgeMeshFilter.h" +#include "itkBinaryMask3DMeshSource.h" + +#include +#include "itkVTKPolyDataWriter.h" +#include "itkMultiThreader.h" + +namespace itk +{ + +/** + \class ExtractMeshesFromLabelImageFilter + \brief + \author Kishore Mosaliganti + */ +template< class TImage, class TFeatureImage = TImage > +class GOFILTERS_EXPORT ExtractMeshesFromLabelImageFilter : public Object +{ +public: + typedef ExtractMeshesFromLabelImageFilter Self; + typedef Object Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + itkStaticConstMacro ( ImageDimension, unsigned int, TImage::ImageDimension ); + + /** Run-time type information (and related methods). */ + itkTypeMacro( ExtractMeshesFromLabelImageFilter, Object ); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** \typedef ImageType Input Image type */ + typedef TImage ImageType; + typedef typename ImageType::Pointer ImagePointer; + typedef typename ImageType::ConstPointer ImageConstPointer; + typedef typename ImageType::IndexType IndexType; + typedef typename IndexType::IndexValueType IndexValueType; + typedef typename ImageType::PixelType PixelType; + typedef typename ImageType::SizeType SizeType; + typedef typename SizeType::SizeValueType SizeValueType; + typedef typename ImageType::RegionType RegionType; + typedef typename ImageType::SpacingType SpacingType; + typedef typename ImageType::PointType PointType; + typedef typename PointType::CoordRepType CoordType; + + typedef TFeatureImage FeatureImageType; + typedef typename FeatureImageType::Pointer FeatureImagePointer; + + typedef std::vector< FeatureImagePointer > FeatureImageVectorType; + + /** \typedef MeshType Output Mesh type */ + typedef QuadEdgeMesh< CoordType, ImageDimension > MeshType; + typedef typename MeshType::Pointer MeshPointer; + + typedef std::vector< MeshPointer > MeshVectorType; + + /** \typedef LabelType label type*/ + typedef unsigned int LabelType; + + // --------------------------------------------------------------------------- + + /** \typedef ShapeLabelObjectType */ + typedef ShapeLabelObject< LabelType, ImageDimension > ShapeLabelObjectType; + typedef typename ShapeLabelObjectType::Pointer ShapeLabelObjectPointer; + + /** \typedef ShapeLabelMapType */ + typedef LabelMap< ShapeLabelObjectType > ShapeLabelMapType; + typedef typename ShapeLabelMapType::Pointer ShapeLabelMapPointer; + + /** \typedef ShapeConverterType */ + typedef LabelImageToShapeLabelMapFilter< ImageType, + ShapeLabelMapType > + ShapeConverterType; + typedef typename ShapeConverterType::Pointer ShapeConverterPointer; + + + typedef typename ShapeLabelMapType::LabelObjectContainerType + LabelObjectContainerType; + typedef typename LabelObjectContainerType::const_iterator + LabelObjectIterator; + + // --------------------------------------------------------------------------- + + /** \typedef StatLabelObjectType */ + typedef StatisticsLabelObject< LabelType, ImageDimension > StatLabelObjectType; + typedef typename StatLabelObjectType::Pointer StatLabelObjectPointer; + + + typedef LabelMap< StatLabelObjectType > StatLabelMapType; + typedef typename StatLabelMapType::Pointer StatLabelMapPointer; + + typedef LabelImageToStatisticsLabelMapFilter< + ImageType, + ImageType, + StatLabelMapType > StatConverterType; + + typedef typename StatConverterType::Pointer StatConverterPointer; + + // --------------------------------------------------------------------------- + + typedef RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; + typedef typename ROIFilterType::Pointer ROIFilterPointer; + + typedef ImageRegionIterator< ImageType > IteratorType; + typedef ImageRegionIteratorWithIndex< ImageType > IndexIteratorType; + + typedef BinaryMask3DMeshSource< ImageType, MeshType > MeshSourceType; + typedef typename MeshSourceType::Pointer MeshSourcePointer; + + typedef SmoothingQuadEdgeMeshFilter< MeshType, MeshType > MeshSmoothingType; + typedef typename MeshSmoothingType::Pointer MeshSmoothingPointer; + + typedef NumberOfFacesCriterion< MeshType > CriterionType; + typedef typename CriterionType::Pointer CriterionPointer; + + typedef SquaredEdgeLengthDecimationQuadEdgeMeshFilter< + MeshType, MeshType, CriterionType > DecimationType; + typedef typename DecimationType::Pointer DecimationPointer; + + typedef VTKPolyDataWriter< MeshType > MeshWriterType; + typedef typename MeshWriterType::Pointer MeshWriterPointer; + + typedef MultiThreader ThreaderType; + typedef typename ThreaderType::Pointer ThreaderPointer; + + itkSetConstObjectMacro( Input, ImageType ); + + void SetNumberOfFeatureImages( const size_t& iN ); + void SetFeatureImage( const size_t& iId, FeatureImageType* iF ); + + itkGetConstMacro( NumberOfMeshes, unsigned int ); + + itkSetMacro( NumberOfTrianglesPerMesh, unsigned int ); + itkGetConstMacro( NumberOfTrianglesPerMesh, unsigned int ); + + itkGetConstMacro( DelaunayConforming, bool ); + itkSetMacro( DelaunayConforming, bool ); + + itkSetMacro( UseDecimation, bool ); + itkGetConstMacro( UseDecimation, bool ); + + itkSetMacro( UseSmoothing, bool ); + itkGetConstMacro( UseSmoothing, bool ); + + itkSetMacro( NumberOfSmoothingIterations, unsigned int ); + itkGetConstMacro( NumberOfSmoothingIterations, unsigned int ); + + itkSetMacro( SmoothingRelaxationFactor, double ); + itkGetConstMacro( SmoothingRelaxationFactor, double ); + + itkGetConstMacro( NumberOfThreads, unsigned int ); + itkSetMacro( NumberOfThreads, unsigned int ); + + itkGetObjectMacro( ShapeLabelMap, ShapeLabelMapType ); + std::vector< StatLabelMapPointer > GetStatLabelMap() + { + return m_StatLabelMap; + } + + void Update(); + + MeshVectorType GetOutputs(); + +protected: + ExtractMeshesFromLabelImageFilter(); + ~ExtractMeshesFromLabelImageFilter(){} + void PrintSelf(std::ostream& os, Indent indent) const; + void ThreadedExtractMesh( const unsigned int& startLabel, + const unsigned int& endLabel ); + + static ITK_THREAD_RETURN_TYPE ThreaderCallback(void * arg); + + struct ThreadStruct + { + ThreadStruct( Self* iFilter ) : Filter( iFilter ) {} + + Self* Filter; + }; + + void GenerateData(); + + ImageConstPointer m_Input; + ShapeLabelMapPointer m_ShapeLabelMap; + std::vector< StatLabelMapPointer > m_StatLabelMap; + std::map< size_t, LabelType > m_MeshtoLabelIdMap; + + MeshVectorType m_Meshes; + FeatureImageVectorType m_FeatureImages; + +#ifdef ITKv4 + ThreadIdType m_NumberOfThreads; +#else + int m_NumberOfThreads; +#endif + + unsigned int m_NumberOfMeshes; + unsigned int m_NumberOfTrianglesPerMesh; + unsigned int m_NumberOfSmoothingIterations; + unsigned int m_SmoothingRelaxationFactor; + + bool m_DelaunayConforming; + bool m_UseSmoothing; + bool m_UseDecimation; + bool m_ComputeIntensityStatistics; + +private: + ExtractMeshesFromLabelImageFilter(const Self&) {} + void operator=(const Self&) {} +}; + +} // end namespace itk + +#include "itkExtractMeshesFromLabelImageFilter.txx" +#endif diff --git a/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.txx b/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.txx new file mode 100644 index 00000000..28f21c2b --- /dev/null +++ b/Code/Filters/Mesh/itkExtractMeshesFromLabelImageFilter.txx @@ -0,0 +1,322 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkExtractMeshesFromLabelImageFilter_txx +#define __itkExtractMeshesFromLabelImageFilter_txx + +#include "itkExtractMeshesFromLabelImageFilter.h" + +static itk::SimpleFastMutexLock m_Mutex; + +namespace itk +{ + +template< class TImage, class TFeatureImage > +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage > +::ExtractMeshesFromLabelImageFilter() +{ + m_Input = 0; + m_NumberOfMeshes = 0; + m_NumberOfTrianglesPerMesh = 200; + m_NumberOfSmoothingIterations = 15; + m_SmoothingRelaxationFactor = 1.0; + m_DelaunayConforming = true; + m_NumberOfThreads = 1; + m_UseSmoothing = true; + m_UseDecimation = true; + m_ComputeIntensityStatistics = false; +} + +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +SetNumberOfFeatureImages( const size_t& iN ) +{ + m_FeatureImages.resize( iN ); +} + +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +SetFeatureImage( const size_t& iId, FeatureImageType* iF ) +{ + if( iId < m_FeatureImages.size() ) + { + m_FeatureImages[iId] = iF; + } +} + +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +Update() +{ + if( m_Input.IsNull() ) + { + itkGenericExceptionMacro( << "Input is NULL" ); + } + this->GenerateData(); +} + +template< class TImage, class TFeatureImage > +typename ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >::MeshVectorType +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +GetOutputs() +{ + return m_Meshes; +} + +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +GenerateData() +{ + ShapeConverterPointer shapeConverter = ShapeConverterType::New(); + shapeConverter->SetInput ( m_Input ); + shapeConverter->SetBackgroundValue ( 0 ); + shapeConverter->Update(); + + m_ShapeLabelMap = shapeConverter->GetOutput(); + m_ShapeLabelMap->DisconnectPipeline(); + + m_NumberOfMeshes = m_ShapeLabelMap->GetNumberOfLabelObjects(); + + this->m_Meshes.resize( m_NumberOfMeshes ); + + if( m_ComputeIntensityStatistics ) + { + size_t NumberOfFeatureImages = m_FeatureImages.size(); + + if( NumberOfFeatureImages == 0 ) + { + itkGenericExceptionMacro( <<"No Feature Image Provided" ); + } + m_StatLabelMap.resize( NumberOfFeatureImages ); + + typename FeatureImageVectorType::iterator f_it = m_FeatureImages.begin(); + typename FeatureImageVectorType::iterator f_end = m_FeatureImages.end(); + + size_t i = 0; + + while( f_it != f_end ) + { + StatConverterPointer statConverter = StatConverterType::New(); + statConverter->SetInput( m_Input ); + statConverter->SetFeatureImage( *f_it ); + statConverter->SetBackgroundValue ( 0 ); + statConverter->SetComputePerimeter(false); + + try + { + statConverter->Update(); + } + catch(itk::ExceptionObject & e) + { + std::cerr << "Exception Caught: " << e << std::endl; + std::cerr << "statConverter->Update()" << std::endl; + return; + } + + m_StatLabelMap[i] = statConverter->GetOutput(); + m_StatLabelMap[i]->DisconnectPipeline(); + + ++i; + ++f_it; + } + } + + ThreadStruct str( this ); + + ThreaderPointer threader = ThreaderType::New(); + threader->SetNumberOfThreads( m_NumberOfThreads ); + threader->SetSingleMethod( this->ThreaderCallback, &str ); + threader->SingleMethodExecute(); +} + +template< class TImage, class TFeatureImage > +ITK_THREAD_RETURN_TYPE +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +ThreaderCallback(void * arg) +{ + unsigned int ThreadId = + ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; + + ThreadStruct * str = + (ThreadStruct *) (((MultiThreader::ThreadInfoStruct *)(arg))->UserData); + + unsigned int numOfMeshes = str->Filter->m_NumberOfMeshes; + unsigned int numOfThreads = str->Filter->m_NumberOfThreads; + + unsigned int MeshChunk = numOfMeshes/ numOfThreads; + ++MeshChunk; + + unsigned int startLabel = ThreadId * MeshChunk + 1; + unsigned int endLabel = ThreadId * MeshChunk + MeshChunk; + + if ( ThreadId == numOfThreads-1 ) + { + endLabel = numOfMeshes; + } + + str->Filter->ThreadedExtractMesh( startLabel, endLabel ); + + return ITK_THREAD_RETURN_VALUE; +} + + +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage >:: +ThreadedExtractMesh( const unsigned int& startLabel, + const unsigned int& endLabel ) +{ + LabelObjectContainerType container = m_ShapeLabelMap->GetLabelObjectContainer(); + + SizeType size; + IndexType index; + RegionType region; + SizeType inputSize = m_Input->GetLargestPossibleRegion().GetSize(); + + LabelObjectIterator l_it = container.begin(); + + for ( unsigned int j = 1; j < startLabel; ++j, ++l_it ) + {} + + MeshPointer mesh, smoothMesh, decimatedMesh; + + LabelType label = startLabel; + LabelObjectIterator l_end = container.end(); + + while( ( label <= endLabel ) && ( l_it != l_end ) ) + { + LabelType i = l_it->first; + region = m_ShapeLabelMap->GetLabelObject ( i )->GetBoundingBox(); + index = region.GetIndex(); + size = region.GetSize(); + + for( unsigned int j = 0; j < ImageDimension; ++j ) + { + if ( static_cast( index[j] ) > 0 ) + { + index[j] = static_cast( index[j] - 1 ); + size[j] = static_cast( size[j] + 1 ); + } + if ( static_cast( index[j] + size[j] ) < inputSize[j] ) + { + size[j] = static_cast( size[j] + 1 ); + } + } + region.SetIndex( index ); + region.SetSize( size ); + + // Extract mesh + MeshSourcePointer meshSource = MeshSourceType::New(); + meshSource->SetInput( m_Input ); + meshSource->SetRegionOfInterest ( region ); + meshSource->SetObjectValue( i ); + meshSource->Update(); + + mesh = meshSource->GetOutput(); + mesh->DisconnectPipeline(); + + // Smooth the mesh + if ( m_UseSmoothing ) + { + ConformalMatrixCoefficients< MeshType > coeff0; + + MeshSmoothingPointer smoothingFilter = MeshSmoothingType::New( ); + smoothingFilter->SetInput( mesh ); + smoothingFilter->SetNumberOfIterations( m_NumberOfSmoothingIterations ); + smoothingFilter->SetRelaxationFactor( m_SmoothingRelaxationFactor ); + smoothingFilter->SetDelaunayConforming( m_DelaunayConforming ); + smoothingFilter->SetCoefficientsMethod( &coeff0 ); + smoothingFilter->Update(); + + smoothMesh = smoothingFilter->GetOutput(); + smoothMesh->DisconnectPipeline(); + } + else + { + smoothMesh = mesh; + } + + // Check topology + + // Decimate the mesh + if ( m_UseDecimation ) + { + CriterionPointer criterion = CriterionType::New(); + criterion->SetTopologicalChange( true ); + criterion->SetNumberOfElements( m_NumberOfTrianglesPerMesh ); + + DecimationPointer decimate = DecimationType::New(); + decimate->SetInput( smoothMesh ); + decimate->SetCriterion( criterion ); + decimate->Update(); + + decimatedMesh = decimate->GetOutput(); + decimatedMesh->DisconnectPipeline(); + } + else + { + decimatedMesh = smoothMesh; + } + + m_Meshes[label-1] = decimatedMesh; + m_Meshes[label-1]->DisconnectPipeline(); + + m_MeshtoLabelIdMap.insert( std::pair< size_t, LabelType >( label - 1, i ) ); + + ++l_it; + ++label; + } +} + + +/** Print Self information */ +template< class TImage, class TFeatureImage > +void +ExtractMeshesFromLabelImageFilter< TImage, TFeatureImage > +::PrintSelf(std::ostream& os, Indent indent) const +{ + Superclass::PrintSelf(os,indent); + os << indent << "NumberOfMeshes: " << m_NumberOfMeshes << std::endl; + os << indent << "NumberOfTrianglesPerMesh: " << m_NumberOfTrianglesPerMesh << std::endl; + os << indent << "NumberOfSmoothingIterations: " << m_NumberOfSmoothingIterations << std::endl; + os << indent << "SmoothingRelaxationFactor: " << m_SmoothingRelaxationFactor << std::endl; +} + +} // end namespace + +#endif diff --git a/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.h b/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.h new file mode 100644 index 00000000..4d752465 --- /dev/null +++ b/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.h @@ -0,0 +1,103 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkQuadEdgeMeshTovtkPolyData_h +#define __itkQuadEdgeMeshTovtkPolyData_h + +#include "GoFiltersConfigure.h" + +#include "vtkPoints.h" +#include "vtkCellArray.h" +#include "vtkPolyData.h" +#include "vtkSmartPointer.h" +#include "itkQuadEdgeMesh.h" +#include "itkTriangleCell.h" +#include "itkObject.h" + + +namespace itk +{ +/** + \class QuadEdgeMeshTovtkPolyData + */ +template< class TMesh > +class GOFILTERS_EXPORT QuadEdgeMeshTovtkPolyData : public Object +{ +public: + typedef QuadEdgeMeshTovtkPolyData Self; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + typedef Object Superclass; + + + /** Run-time type information (and related methods). */ + itkTypeMacro( QuadEdgeMeshTovtkPolyData, Object ); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + + typedef TMesh MeshType; + typedef typename MeshType::Pointer MeshPointer; + typedef typename MeshType::PointIdentifier PointIdentifier; + typedef typename MeshType::PointType PointType; + typedef typename MeshType::PointsContainer PointsContainer; + typedef typename MeshType::PointsContainerPointer PointsContainerPointer; + typedef typename MeshType::PointsContainerConstIterator PointsContainerConstIterator; + typedef typename MeshType::CellType CellType; + + typedef typename MeshType::CellsContainerPointer CellsContainerPointer; + typedef typename MeshType::CellsContainerConstIterator CellsContainerConstIterator; + + void SetInput( MeshType* mesh ); + vtkPolyData * GetOutput(); + + void Update(); + +protected: + + QuadEdgeMeshTovtkPolyData( ); + virtual ~QuadEdgeMeshTovtkPolyData( ); + + + void GenerateData(); + + MeshPointer m_itkMesh; + vtkSmartPointer< vtkPolyData > m_PolyData; +}; +} + +#include "itkQuadEdgeMeshTovtkPolyData.txx" + +#endif // __itkQuadEdgeMeshTovtkPolyData_h diff --git a/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.txx b/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.txx new file mode 100644 index 00000000..703a65ae --- /dev/null +++ b/Code/Filters/Mesh/itkQuadEdgeMeshTovtkPolyData.txx @@ -0,0 +1,175 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __itkQuadEdgeMeshTovtkPolyData_txx +#define __itkQuadEdgeMeshTovtkPolyData_txx + +#include "itkQuadEdgeMeshTovtkPolyData.h" + +namespace itk +{ +template< class TMesh > +QuadEdgeMeshTovtkPolyData< TMesh > +::QuadEdgeMeshTovtkPolyData() +{ + m_PolyData = vtkSmartPointer< vtkPolyData >::New(); +} + + +template< class TMesh > +QuadEdgeMeshTovtkPolyData< TMesh > +::~QuadEdgeMeshTovtkPolyData() +{ +} + +template< class TMesh > +void +QuadEdgeMeshTovtkPolyData< TMesh > +::SetInput(MeshType* mesh) +{ + if( mesh ) + { + m_itkMesh = mesh; + this->Modified(); + } +} + +template< class TMesh > +vtkPolyData * +QuadEdgeMeshTovtkPolyData< TMesh > +::GetOutput() +{ + return m_PolyData; +} + +template< class TMesh > +void +QuadEdgeMeshTovtkPolyData< TMesh > +::Update() +{ + if( m_itkMesh.IsNull() ) + { + itkGenericExceptionMacro( << "m_itkMesh is NULL" ); + } + this->GenerateData(); +} + +template< class TMesh > +void +QuadEdgeMeshTovtkPolyData< TMesh > +::GenerateData() +{ + + PointIdentifier NumberOfPoints = m_itkMesh->GetNumberOfPoints(); + + if( NumberOfPoints == 0 ) + { + itkGenericExceptionMacro( << "NumberOfPoints == 0" ); + } + + vtkSmartPointer< vtkPoints > vtk_Points = + vtkSmartPointer< vtkPoints >::New(); + vtk_Points->SetNumberOfPoints( NumberOfPoints ); + + PointsContainerPointer itk_Points = m_itkMesh->GetPoints(); + PointsContainerConstIterator p_it = itk_Points->Begin(); + PointsContainerConstIterator p_end = itk_Points->End(); + PointType itk_point; + + vtkIdType id=0; + double vtk_point[3]; + + while( p_it != p_end ) + { + itk_point = p_it.Value(); + + vtk_point[0] = itk_point[0]; + vtk_point[1] = itk_point[1]; + vtk_point[2] = itk_point[2]; + + vtk_Points->SetPoint( id, vtk_point ); + ++p_it; + ++id; + } + + if( m_itkMesh->GetNumberOfCells() == 0 ) + { + itkGenericExceptionMacro( << "NumberOfCells == 0" ); + } + + CellsContainerPointer itk_Cells = m_itkMesh->GetCells(); + CellsContainerConstIterator c_it = itk_Cells->Begin(); + CellsContainerConstIterator c_end = itk_Cells->End(); + + vtkSmartPointer< vtkCellArray > vtk_Polys = + vtkSmartPointer< vtkCellArray >::New(); + + while ( c_it != c_end ) + { + CellType* temp_cell = c_it->Value(); + typename CellType::PointIdIterator temp_c_it = temp_cell->PointIdsBegin(); + typename CellType::PointIdIterator temp_c_end = temp_cell->PointIdsEnd(); + + size_t nb_pts = temp_cell->GetNumberOfPoints(); + + std::vector< vtkIdType > pts( nb_pts ); + size_t i = 0; + + switch (temp_cell->GetType()) + { + default: + case CellType::VERTEX_CELL: + case CellType::LINE_CELL: + break; + + case CellType::TRIANGLE_CELL: + case CellType::POLYGON_CELL: + while( temp_c_it != temp_c_end ) + { + pts[i] = *temp_c_it; + ++i; + ++temp_c_it; + } + vtk_Polys->InsertNextCell( nb_pts, &( pts.front() ) ); + break; + } + ++c_it; + } + + m_PolyData->SetPoints( vtk_Points ); + m_PolyData->SetPolys( vtk_Polys ); +} + +} + +#endif diff --git a/Code/Filters/Mesh/itkvtkMeshFilterBase.h b/Code/Filters/Mesh/itkvtkMeshFilterBase.h new file mode 100644 index 00000000..c3ee2d17 --- /dev/null +++ b/Code/Filters/Mesh/itkvtkMeshFilterBase.h @@ -0,0 +1,160 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshFilterBase_h +#define __itkvtkMeshFilterBase_h + +#include "GoFiltersConfigure.h" + +#include "itkObject.h" +#include "itkConvertMeshesToLabelImageFilter.h" +#include "itkvtkPolyDataToitkQuadEdgeMesh.h" + +#include "itkShapeLabelObject.h" +#include "itkLabelMap.h" +#include "itkLabelImageToShapeLabelMapFilter.h" +#include "itkLabelImageToStatisticsLabelMapFilter.h" + +namespace itk +{ +template< class TFeatureImage > +class GOFILTERS_EXPORT vtkMeshFilterBase : public Object +{ +public: + typedef Object Superclass; + typedef vtkMeshFilterBase Self; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro( vtkMeshFilterBase, Object ); + + typedef TFeatureImage FeatureImageType; + typedef typename FeatureImageType::Pointer FeatureImagePointer; + typedef typename FeatureImageType::PixelType FeatureImagePixelType; + typedef typename FeatureImageType::IndexType FeatureImageIndexType; + typedef typename FeatureImageType::PointType FeatureImagePointType; + + typedef ConvertMeshesToLabelImageFilter< FeatureImageType > MeshToLabelFilterType; + typedef typename MeshToLabelFilterType::Pointer MeshToLabelFilterPointer; + typedef typename MeshToLabelFilterType::MeshType QuadEdgeMeshType; + + typedef vtkPolyDataToitkQuadEdgeMesh< QuadEdgeMeshType > MeshConverterType; + typedef typename MeshConverterType::Pointer MeshConverterPointer; + + + // --------------------------------------------------------------------------- + + /** \typedef LabelType label type*/ + typedef unsigned int LabelType; + + // --------------------------------------------------------------------------- + + /** \typedef ShapeLabelObjectType */ + typedef ShapeLabelObject< LabelType, + FeatureImageType::ImageDimension > + ShapeLabelObjectType; + typedef typename ShapeLabelObjectType::Pointer ShapeLabelObjectPointer; + + /** \typedef ShapeLabelMapType */ + typedef LabelMap< ShapeLabelObjectType > ShapeLabelMapType; + typedef typename ShapeLabelMapType::Pointer ShapeLabelMapPointer; + + /** \typedef ShapeConverterType */ + typedef LabelImageToShapeLabelMapFilter< FeatureImageType, + ShapeLabelMapType > + ShapeConverterType; + typedef typename ShapeConverterType::Pointer ShapeConverterPointer; + + + typedef typename ShapeLabelMapType::LabelObjectContainerType + LabelObjectContainerType; + typedef typename LabelObjectContainerType::const_iterator + LabelObjectIterator; + + // --------------------------------------------------------------------------- + + /** \typedef StatLabelObjectType */ + typedef StatisticsLabelObject< LabelType, + FeatureImageType::ImageDimension > + StatLabelObjectType; + typedef typename StatLabelObjectType::Pointer StatLabelObjectPointer; + + + typedef LabelMap< StatLabelObjectType > StatLabelMapType; + typedef typename StatLabelMapType::Pointer StatLabelMapPointer; + + typedef LabelImageToStatisticsLabelMapFilter< + FeatureImageType, + FeatureImageType, + StatLabelMapType > StatConverterType; + + typedef typename StatConverterType::Pointer StatConverterPointer; + + // --------------------------------------------------------------------------- + + void SetNumberOfImages( const size_t& iN ); + + void SetFeatureImage( const size_t& iId, FeatureImageType* iImage ); + + void Update(); + +protected: + vtkMeshFilterBase(); + virtual ~vtkMeshFilterBase() {} + + virtual void GenerateData() = 0; + + virtual void SetRequiredAttributeComputationFlags() = 0; + + void ComputeOutputAttributes(); + + std::vector< FeatureImagePointer > m_Images; + std::vector< vtkPolyData* > m_Outputs; + ShapeLabelMapPointer m_ShapeLabelMap; + std::vector< StatLabelMapPointer > m_StatLabelMap; + std::map< size_t, LabelType > m_MeshtoLabelIdMap; + + bool m_ShapeComputation; + bool m_IntensityComputation; + +private: + vtkMeshFilterBase( const Self& ); + void operator = ( const Self& ); +}; +} + +#include "itkvtkMeshFilterBase.txx" +#endif + diff --git a/Code/Filters/Mesh/itkvtkMeshFilterBase.txx b/Code/Filters/Mesh/itkvtkMeshFilterBase.txx new file mode 100644 index 00000000..d1fa6b88 --- /dev/null +++ b/Code/Filters/Mesh/itkvtkMeshFilterBase.txx @@ -0,0 +1,166 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __itkvtkMeshFilterBase_txx +#define __itkvtkMeshFilterBase_txx + +#include "itkvtkMeshFilterBase.h" + +namespace itk +{ +template< class TFeatureImage > +vtkMeshFilterBase< TFeatureImage >:: +vtkMeshFilterBase() : Superclass(), + m_ShapeComputation( false ), + m_IntensityComputation( false ) +{ +} + +template< class TFeatureImage > +void +vtkMeshFilterBase< TFeatureImage >:: +SetNumberOfImages( const size_t& iN ) +{ + m_Images.resize( iN ); +} + +template< class TFeatureImage > +void +vtkMeshFilterBase< TFeatureImage >:: +SetFeatureImage( const size_t& iId, FeatureImageType* iImage ) +{ + if( iId < m_Images.size() ) + { + m_Images[iId] = iImage; + this->Modified(); + } +} + +template< class TFeatureImage > +void +vtkMeshFilterBase< TFeatureImage >:: +Update() +{ + this->GenerateData(); + this->ComputeOutputAttributes(); +} + +template< class TFeatureImage > +void +vtkMeshFilterBase< TFeatureImage >:: +ComputeOutputAttributes() +{ + if( m_ShapeComputation || m_IntensityComputation ) + { + std::vector< vtkPolyData* >::iterator it = m_Outputs.begin(); + std::vector< vtkPolyData* >::iterator end = m_Outputs.end(); + + typename MeshToLabelFilterType::MeshVectorType mesh_vector( m_Outputs.size() ); + size_t i = 0; + + while( it != end ) + { + MeshConverterPointer converter = MeshConverterType::New(); + converter->SetInput( *it ); + converter->Update(); + + mesh_vector[i] = converter->GetOutput(); + mesh_vector[i]->DisconnectPipeline(); + ++i; + ++it; + } + + FeatureImagePointer image = FeatureImageType::New(); + image->CopyInformation( this->m_Images.front() ); + image->SetRegions( this->m_Images.front()->GetLargestPossibleRegion() ); + image->Allocate(); + image->FillBuffer( 0 ); + + typename MeshToLabelFilterType::Pointer + labelizer = MeshToLabelFilterType::New(); + labelizer->SetInput( image ); + labelizer->SetMeshes( mesh_vector ); + labelizer->Update(); + + if( m_ShapeComputation ) + { + ShapeConverterPointer shapeConverter = ShapeConverterType::New(); + shapeConverter->SetInput( image ); + shapeConverter->SetBackgroundValue ( 0 ); + shapeConverter->Update(); + + m_ShapeLabelMap = shapeConverter->GetOutput(); + m_ShapeLabelMap->DisconnectPipeline(); + } + if( m_IntensityComputation ) + { + size_t NumberOfFeatureImages = m_Images.size(); + m_StatLabelMap.resize( NumberOfFeatureImages ); + + typename std::vector< FeatureImagePointer >::iterator f_it = m_Images.begin(); + typename std::vector< FeatureImagePointer >::iterator f_end = m_Images.end(); + + i = 0; + + while( f_it != f_end ) + { + StatConverterPointer statConverter = StatConverterType::New(); + statConverter->SetInput( image ); + statConverter->SetFeatureImage( *f_it ); + statConverter->SetBackgroundValue( 0 ); + statConverter->SetComputePerimeter(false); + + try + { + statConverter->Update(); + } + catch(itk::ExceptionObject & e) + { + std::cerr << "Exception Caught: " << e << std::endl; + std::cerr << "statConverter->Update()" << std::endl; + return; + } + + m_StatLabelMap[i] = statConverter->GetOutput(); + m_StatLabelMap[i]->DisconnectPipeline(); + + ++i; + ++f_it; + } + } + } + } +} + +#endif diff --git a/Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.h b/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.h similarity index 97% rename from Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.h rename to Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.h index 72046e4b..96f74236 100644 --- a/Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.h +++ b/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.h @@ -34,6 +34,8 @@ #ifndef __itkvtkPolyDataToBinaryMaskImageFilter_h #define __itkvtkPolyDataToBinaryMaskImageFilter_h +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "vtkSmartPointer.h" @@ -49,7 +51,7 @@ namespace itk { template< class TInput, class TOutput > -class vtkPolyDataToBinaryMaskImageFilter: +class GOFILTERS_EXPORT vtkPolyDataToBinaryMaskImageFilter: public ImageToImageFilter< TInput, TOutput > { public: diff --git a/Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.txx b/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.txx similarity index 82% rename from Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.txx rename to Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.txx index 21b650de..69e2d266 100644 --- a/Code/Filters/itkvtkPolyDataToBinaryMaskImageFilter.txx +++ b/Code/Filters/Mesh/itkvtkPolyDataToBinaryMaskImageFilter.txx @@ -42,7 +42,8 @@ namespace itk { template< class TInput, class TOutput > -vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::vtkPolyDataToBinaryMaskImageFilter() +vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: +vtkPolyDataToBinaryMaskImageFilter() { m_WhiteImage = vtkSmartPointer< vtkImageData >::New(); m_Pol2stenc = vtkSmartPointer< vtkPolyDataToImageStencil >::New(); @@ -59,7 +60,8 @@ vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: template< class TInput, class TOutput > void -vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::SetPolyData(vtkPolyData *iMesh) +vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: +SetPolyData(vtkPolyData *iMesh) { m_Mesh = iMesh; this->Modified(); @@ -67,10 +69,16 @@ vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::SetPolyData(vtkPolyData * template< class TInput, class TOutput > void -vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::GenerateData() +vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >:: +GenerateData() { InputImageConstPointer input = this->GetInput(); + if( input.IsNull() ) + { + itkGenericExceptionMacro( << "input is NULL" ); + } + double bounds[6]; m_Mesh->GetBounds(bounds); @@ -83,21 +91,37 @@ vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::GenerateData() return; } - // origin is the lowest bound! - double origin[3]; - origin[0] = bounds[0]; - origin[1] = bounds[2]; - origin[2] = bounds[4]; - // spacing is got from the input image InputImageSpacingType itk_spacing = input->GetSpacing(); double vtk_spacing[3] = { 0., 0., 0. }; int vtk_size[3] = { 0, 0, 0 }; + // origin is the lowest bound! + double origin[3]; + origin[0] = bounds[0] - itk_spacing[0]; + origin[1] = bounds[2] - itk_spacing[1]; + origin[2] = bounds[4] - itk_spacing[2]; + + typename InputImageType::PointType itk_pt; + itk_pt[0] = origin[0]; + itk_pt[1] = origin[1]; + itk_pt[2] = origin[2]; + + typename InputImageType::IndexType itk_idx; + + input->TransformPhysicalPointToIndex( itk_pt, itk_idx ); + input->TransformIndexToPhysicalPoint( itk_idx, itk_pt ); + + origin[0] = itk_pt[0]; + origin[1] = itk_pt[1]; + origin[2] = itk_pt[2]; + for ( unsigned int dim = 0; dim < ImageDimension; dim++ ) { vtk_spacing[dim] = static_cast< double >(itk_spacing[dim]); - vtk_size[dim] = static_cast< int >(vcl_ceil(bounds[2 * dim + 1] - bounds[2 * dim]) / vtk_spacing[dim]); + vtk_size[dim] = 1 + + static_cast< int >( vcl_ceil( bounds[2 * dim + 1] - + bounds[2 * dim] ) / vtk_spacing[dim]); } m_WhiteImage->SetSpacing(vtk_spacing); @@ -142,4 +166,4 @@ vtkPolyDataToBinaryMaskImageFilter< TInput, TOutput >::GenerateData() } -#endif \ No newline at end of file +#endif diff --git a/Code/Filters/Mesh/itkvtkPolyDataToitkQuadEdgeMesh.h b/Code/Filters/Mesh/itkvtkPolyDataToitkQuadEdgeMesh.h new file mode 100644 index 00000000..8d8b1ee9 --- /dev/null +++ b/Code/Filters/Mesh/itkvtkPolyDataToitkQuadEdgeMesh.h @@ -0,0 +1,160 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __vtkPolyDataToitkQuadEdgeMesh_h +#define __vtkPolyDataToitkQuadEdgeMesh_h + +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkIdList.h" + +#include "itkQuadEdgeMesh.h" +#include "itkTriangleCell.h" + +#include "itkObject.h" + +namespace itk +{ +template< class TMesh > +class vtkPolyDataToitkQuadEdgeMesh : public Object +{ +public: + typedef vtkPolyDataToitkQuadEdgeMesh Self; + typedef Object Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(vtkPolyDataToitkQuadEdgeMesh, Object); + + typedef TMesh MeshType; + typedef typename MeshType::Pointer MeshPointer; + typedef typename MeshType::PointsContainerPointer PointsContainerPointer; + typedef typename MeshType::PointIdentifier PointIdentifier; + typedef typename MeshType::CellAutoPointer CellAutoPointer; + typedef typename MeshType::CellType CellType; + typedef typename MeshType::PointType PointType; + typedef typename PointType::CoordRepType CoordType; + + typedef TriangleCell< CellType > TriangleCellType; + + void SetInput( vtkPolyData* iMesh ) + { + m_PolyData = iMesh; + } + + void Update() + { + GenerateData(); + } + + MeshType* GetOutput() const + { + return m_OutputMesh.GetPointer(); + } + +protected: + vtkPolyDataToitkQuadEdgeMesh() + { + m_OutputMesh = MeshType::New(); + } + + ~vtkPolyDataToitkQuadEdgeMesh() {} + + vtkSmartPointer< vtkPolyData > m_PolyData; + MeshPointer m_OutputMesh; + + void GenerateData() + { + vtkIdType NbOfPoints = m_PolyData->GetNumberOfPoints(); + + if( NbOfPoints == 0 ) + { + itkGenericExceptionMacro( <<"Number Of Points is 0" ); + } + + vtkIdType NbOfCells = m_PolyData->GetNumberOfCells(); + + if( NbOfCells == 0 ) + { + itkGenericExceptionMacro( <<"Number Of Cells is 0" ); + } + + PointsContainerPointer points = m_OutputMesh->GetPoints(); + points->Reserve( NbOfPoints ); + + double vtk_p[3]; + PointType itk_p; + unsigned int dim; + + for( vtkIdType i = 0; i < NbOfPoints; ++i ) + { + m_PolyData->GetPoint( i, vtk_p ); + for( dim = 0; dim < 3; ++dim ) + { + itk_p[dim] = static_cast< CoordType >( vtk_p[dim] ); + } + m_OutputMesh->SetPoint( i, itk_p ); + } + + for( vtkIdType i = 0; i < NbOfCells; ++i ) + { + vtkIdList* cell_list = vtkIdList::New(); + + m_PolyData->GetCellPoints( i, cell_list ); + + CellAutoPointer cell; + TriangleCellType *triangleCell = new TriangleCellType; + for ( vtkIdType k = 0; k < cell_list->GetNumberOfIds(); ++k ) + { + triangleCell->SetPointId( k, cell_list->GetId( k ) ); + } + + cell.TakeOwnership(triangleCell); + m_OutputMesh->SetCell(i, cell); + + cell_list->Delete(); + } + } + +private: + vtkPolyDataToitkQuadEdgeMesh( const Self& ); + void operator = ( const Self & ); +}; +} + +#endif // __vtkPolyDataToitkQuadEdgeMesh_h diff --git a/Code/Filters/itkCellFeatureGenerator.h b/Code/Filters/itkCellFeatureGenerator.h index 85097d3f..86e2cf7e 100644 --- a/Code/Filters/itkCellFeatureGenerator.h +++ b/Code/Filters/itkCellFeatureGenerator.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" @@ -63,7 +65,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT CellFeatureGenerator: +class GOFILTERS_EXPORT CellFeatureGenerator: public ImageToImageFilter< TFeatureImage, TInputImage > { public: diff --git a/Code/Filters/itkCellForegroundExtraction.h b/Code/Filters/itkCellForegroundExtraction.h index 7157ee93..03195dc2 100644 --- a/Code/Filters/itkCellForegroundExtraction.h +++ b/Code/Filters/itkCellForegroundExtraction.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkAffineTransform.h" #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" @@ -66,7 +68,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT CellForegroundExtraction:public ImageToImageFilter< +class GOFILTERS_EXPORT CellForegroundExtraction:public ImageToImageFilter< TFeatureImage, TSegmentImage > { public: diff --git a/Code/Filters/itkChanAndVeseSegmentationFilter.h b/Code/Filters/itkChanAndVeseSegmentationFilter.h index cb8b0043..2f51fc5a 100644 --- a/Code/Filters/itkChanAndVeseSegmentationFilter.h +++ b/Code/Filters/itkChanAndVeseSegmentationFilter.h @@ -35,6 +35,8 @@ #ifndef __itkChanAndVeseSegmentationFilter_h #define __itkChanAndVeseSegmentationFilter_h +#include "GoFiltersConfigure.h" + #include "itkScalarChanAndVeseSparseLevelSetImageFilter.h" #include "itkScalarChanAndVeseLevelSetFunction.h" #include "itkScalarChanAndVeseLevelSetFunctionData.h" @@ -57,7 +59,7 @@ namespace itk * \brief */ template< class TFeatureImage > -class ChanAndVeseSegmentationFilter:public Object +class GOFILTERS_EXPORT ChanAndVeseSegmentationFilter:public Object { public: typedef ChanAndVeseSegmentationFilter Self; @@ -182,6 +184,8 @@ class ChanAndVeseSegmentationFilter:public Object m_Size.Fill(0); m_Radius = 0.; m_Preprocess = false; + + m_Output = InternalImageType::New(); } ~ChanAndVeseSegmentationFilter() {} @@ -209,15 +213,35 @@ class ChanAndVeseSegmentationFilter:public Object InternalPointType origin; InternalIndexType cen; - for ( unsigned int j = 0; j < Dimension; j++ ) + if (m_Radius == 0 ) + { + origin = m_FeatureImage->GetOrigin(); + m_Size = inputSize; + //node.SetValue( (static_cast(m_Size[0]) *spacing[0])/4.); + m_Radius = static_cast(m_Size[0]) *spacing[0] / 2.; + + for( unsigned int j = 0; j < Dimension; j++ ) + { + start2[j] = 0; + cen[j] = static_cast( m_Size[j] / 2 ); + } + } + else { - m_Size[j] = - 1 + 4. * static_cast< InternalSizeValueType >( m_Radius / spacing[j] ); - cen[j] = static_cast< InternalSizeValueType >( 2 * m_Radius / spacing[j] ); - origin[j] = m_Center[j] - 2 * m_Radius; - start2[j] = 0; + for ( unsigned int j = 0; j < Dimension; j++ ) + { + m_Size[j] = + 1 + 4. * static_cast< InternalSizeValueType >( m_Radius / spacing[j] ); + cen[j] = static_cast< InternalSizeValueType >( 2 * m_Radius / spacing[j] ); + origin[j] = m_Center[j] - 2 * m_Radius; + start2[j] = 0; + } } + NodeType node; + node.SetValue(-m_Radius / 2); + node.SetIndex(cen); + std::cout << "Spacing: " << spacing << std::endl; std::cout << "Input Size: " << inputSize << std::endl; std::cout << "Output Size: " << m_Size << std::endl; @@ -225,10 +249,6 @@ class ChanAndVeseSegmentationFilter:public Object std::cout << "Radius: " << m_Radius << std::endl; std::cout << "Center: " << cen << std::endl; - NodeType node; - node.SetValue(-m_Radius / 2); - node.SetIndex(cen); - typename NodeContainer::Pointer seeds = NodeContainer::New(); seeds->Initialize(); seeds->InsertElement(0, node); @@ -274,6 +294,7 @@ class ChanAndVeseSegmentationFilter:public Object PreprocessFilterPointer preprocess = PreprocessFilterType::New(); preprocess->SetInput (m_FeatureImage); preprocess->SetLargestCellRadius (m_Radius); // in real coordinates + try { preprocess->Update(); @@ -325,7 +346,7 @@ class ChanAndVeseSegmentationFilter:public Object std::cerr << "levelsetfilter Exception:" << err << std::endl; } - m_Output = LevelSetFilter->GetLevelSet(0); + m_Output->Graft( LevelSetFilter->GetLevelSet(0) ); } private: diff --git a/Code/Filters/itkGaussianProfileMatchingImageFilter.h b/Code/Filters/itkGaussianProfileMatchingImageFilter.h index b9d3df6a..24813fc2 100644 --- a/Code/Filters/itkGaussianProfileMatchingImageFilter.h +++ b/Code/Filters/itkGaussianProfileMatchingImageFilter.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" @@ -60,7 +62,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT GaussianProfileMatchingImageFilter:public ImageToImageFilter< +class GOFILTERS_EXPORT GaussianProfileMatchingImageFilter:public ImageToImageFilter< TFeatureImage, TInputImage > { public: @@ -142,8 +144,11 @@ class ITK_EXPORT GaussianProfileMatchingImageFilter:public ImageToImageFilter< virtual void AfterThreadedGenerateData(); virtual void ThreadedGenerateData(const ImageRegionType & windowRegion, +#ifdef ITKv4 + ThreadIdType threadId ); +#else int threadId); - +#endif void GenerateInputRequestedRegion(); void EnlargeOutputRequestedRegion( DataObject *itkNotUsed(output) ); diff --git a/Code/Filters/itkGaussianProfileMatchingImageFilter.txx b/Code/Filters/itkGaussianProfileMatchingImageFilter.txx index 612ae6fe..53f838ff 100644 --- a/Code/Filters/itkGaussianProfileMatchingImageFilter.txx +++ b/Code/Filters/itkGaussianProfileMatchingImageFilter.txx @@ -220,7 +220,11 @@ template< class TFeatureImage, class TInputImage, class TSegmentImage > void GaussianProfileMatchingImageFilter< TFeatureImage, TInputImage, TSegmentImage >::ThreadedGenerateData( const ImageRegionType & windowRegion, +#ifdef ITKv4 + ThreadIdType threadId ) +#else int threadId) +#endif { (void)threadId; diff --git a/Code/Filters/itkGradientWeightedDistanceImageFilter.h b/Code/Filters/itkGradientWeightedDistanceImageFilter.h index c4713f5d..14086381 100644 --- a/Code/Filters/itkGradientWeightedDistanceImageFilter.h +++ b/Code/Filters/itkGradientWeightedDistanceImageFilter.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" @@ -65,7 +67,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT GradientWeightedDistanceImageFilter: +class GOFILTERS_EXPORT GradientWeightedDistanceImageFilter: public ImageToImageFilter< TFeatureImage, TInputImage > { public: diff --git a/Code/Filters/itkGradientWeightedIntensityImageFilter.h b/Code/Filters/itkGradientWeightedIntensityImageFilter.h index f351bf2a..41b330cb 100644 --- a/Code/Filters/itkGradientWeightedIntensityImageFilter.h +++ b/Code/Filters/itkGradientWeightedIntensityImageFilter.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkSigmoidImageFilter.h" @@ -61,7 +63,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT GradientWeightedIntensityImageFilter: +class GOFILTERS_EXPORT GradientWeightedIntensityImageFilter: public ImageToImageFilter< TFeatureImage, TInputImage > { public: diff --git a/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.h b/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.h index 890a99aa..db62b48a 100644 --- a/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.h +++ b/Code/Filters/itkMorphologicalWatershedFromMarkersImageFilter2.h @@ -53,6 +53,8 @@ #include "itkImageToImageFilter.h" +#include "GoFiltersConfigure.h" + namespace itk { /** \class MorphologicalWatershedFromMarkersImageFilter2 @@ -103,7 +105,7 @@ namespace itk * \ingroup ImageEnhancement MathematicalMorphologyImageFilters */ template< class TInputImage, class TLabelImage > -class ITK_EXPORT MorphologicalWatershedFromMarkersImageFilter2: +class GOFILTERS_EXPORT MorphologicalWatershedFromMarkersImageFilter2: public ImageToImageFilter< TInputImage, TLabelImage > { public: diff --git a/Code/Filters/itkMorphologicalWatershedImageFilter2.h b/Code/Filters/itkMorphologicalWatershedImageFilter2.h index 3ab975b3..53bd56c2 100644 --- a/Code/Filters/itkMorphologicalWatershedImageFilter2.h +++ b/Code/Filters/itkMorphologicalWatershedImageFilter2.h @@ -52,6 +52,8 @@ #ifndef __itkMorphologicalWatershedImageFilter2_h #define __itkMorphologicalWatershedImageFilter2_h +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" namespace itk @@ -77,7 +79,7 @@ namespace itk * \ingroup ImageEnhancement MathematicalMorphologyImageFilters */ template< class TInputImage, class TOutputImage > -class ITK_EXPORT MorphologicalWatershedImageFilter2: +class GOFILTERS_EXPORT MorphologicalWatershedImageFilter2: public ImageToImageFilter< TInputImage, TOutputImage > { public: diff --git a/Code/Filters/itkMultiScaleLoGDistanceImageFilter.h b/Code/Filters/itkMultiScaleLoGDistanceImageFilter.h index f185a92c..4be246f2 100644 --- a/Code/Filters/itkMultiScaleLoGDistanceImageFilter.h +++ b/Code/Filters/itkMultiScaleLoGDistanceImageFilter.h @@ -35,6 +35,8 @@ #ifndef __itkMultiScaleLoGDistanceImageFilter_h #define __itkMultiScaleLoGDistanceImageFilter_h +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include #include "itkImageRegionIterator.h" @@ -49,7 +51,7 @@ namespace itk * distance map information. */ template< class InputImageType, class DistanceMapImageType = InputImageType, class OutputImageType = InputImageType > -class ITK_EXPORT MultiScaleLoGDistanceImageFilter: +class GOFILTERS_EXPORT MultiScaleLoGDistanceImageFilter: public ImageToImageFilter< InputImageType, OutputImageType > { public: diff --git a/Code/Filters/itkMultiScaleLoGDistanceImageFilter.txx b/Code/Filters/itkMultiScaleLoGDistanceImageFilter.txx index 0f696c1e..78419ad9 100644 --- a/Code/Filters/itkMultiScaleLoGDistanceImageFilter.txx +++ b/Code/Filters/itkMultiScaleLoGDistanceImageFilter.txx @@ -113,10 +113,8 @@ MultiScaleLoGDistanceImageFilter while ( sigma <= m_SigmaMax ) { - std::cout << "Computing LoG for sigma = " << sigma << std::endl; m_LoGFilter->SetSigma(sigma); m_LoGFilter->Update(); - std::cout << "Filtering LoG with distancemap " << std::endl; this->UpdateMaximumResponse(scaleLevel); sigma = this->ComputeSigmaValue(scaleLevel); // compute sigma according to // the scale level @@ -242,4 +240,4 @@ MultiScaleLoGDistanceImageFilter } // end namespace itk -#endif \ No newline at end of file +#endif diff --git a/Code/Filters/itkMultiScaleLoGImageFilter.h b/Code/Filters/itkMultiScaleLoGImageFilter.h index 7ca8dc2d..b1de19b6 100644 --- a/Code/Filters/itkMultiScaleLoGImageFilter.h +++ b/Code/Filters/itkMultiScaleLoGImageFilter.h @@ -51,6 +51,8 @@ #ifndef __itkMultiScaleLoGImageFilter_h #define __itkMultiScaleLoGImageFilter_h +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkMatrix.h" @@ -64,7 +66,7 @@ namespace itk * \brief A filter to enhance 3D blob structures using LoG filter */ template< class TInputImage, class TOutputImage = TInputImage > -class ITK_EXPORT MultiScaleLoGImageFilter: +class GOFILTERS_EXPORT MultiScaleLoGImageFilter: public ImageToImageFilter< TInputImage, TOutputImage > { public: diff --git a/Code/Filters/itkMultiScaleLoGImageFilter.txx b/Code/Filters/itkMultiScaleLoGImageFilter.txx index 55486386..8abfdc5e 100644 --- a/Code/Filters/itkMultiScaleLoGImageFilter.txx +++ b/Code/Filters/itkMultiScaleLoGImageFilter.txx @@ -94,7 +94,6 @@ MultiScaleLoGImageFilter int scaleLevel = 1; while ( sigma <= m_SigmaMax ) { - std::cout << "Computing LoG for sigma = " << sigma << std::endl; m_LaplacianFilter->SetSigma(sigma); m_LaplacianFilter->Update(); this->UpdateMaximumResponse(); @@ -161,4 +160,4 @@ MultiScaleLoGImageFilter } // end namespace itk -#endif \ No newline at end of file +#endif diff --git a/Code/Filters/itkPreprocessImageFilter.h b/Code/Filters/itkPreprocessImageFilter.h index 78b3fc28..e9947542 100644 --- a/Code/Filters/itkPreprocessImageFilter.h +++ b/Code/Filters/itkPreprocessImageFilter.h @@ -42,6 +42,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkCastImageFilter.h" #include "itkMedianImageFilter.h" @@ -56,7 +58,7 @@ namespace itk * in the segmentation. */ template< class TInputImage, class TOutputImage = TInputImage > -class ITK_EXPORT PreprocessImageFilter:public ImageToImageFilter< +class GOFILTERS_EXPORT PreprocessImageFilter:public ImageToImageFilter< TInputImage, TOutputImage > { public: diff --git a/Code/Filters/itkViscousWatershedTransform.h b/Code/Filters/itkViscousWatershedTransform.h index daaf9964..31d45546 100644 --- a/Code/Filters/itkViscousWatershedTransform.h +++ b/Code/Filters/itkViscousWatershedTransform.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkBinaryBallStructuringElement.h" @@ -52,7 +54,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT ViscousWatershedTransform:public ImageToImageFilter< +class GOFILTERS_EXPORT ViscousWatershedTransform:public ImageToImageFilter< TFeatureImage, TFeatureImage > { public: diff --git a/Code/Filters/itkWatershedBasedCellSegmentation.h b/Code/Filters/itkWatershedBasedCellSegmentation.h index b7d7ce4b..05af1dcf 100644 --- a/Code/Filters/itkWatershedBasedCellSegmentation.h +++ b/Code/Filters/itkWatershedBasedCellSegmentation.h @@ -43,6 +43,8 @@ #define ITK_LEAN_AND_MEAN #endif +#include "GoFiltersConfigure.h" + #include "itkImageToImageFilter.h" #include "itkPreprocessImageFilter.h" #include "itkCellForegroundExtraction.h" @@ -57,7 +59,7 @@ namespace itk { template< class TFeatureImage, class TInputImage, class TSegmentImage > -class ITK_EXPORT WatershedBasedCellSegmentation:public ImageToImageFilter< +class GOFILTERS_EXPORT WatershedBasedCellSegmentation:public ImageToImageFilter< TFeatureImage, TSegmentImage > { public: diff --git a/Code/Filters/itkWatershedBasedCellSegmentation.txx b/Code/Filters/itkWatershedBasedCellSegmentation.txx index fcd5c2a0..e3d4f506 100644 --- a/Code/Filters/itkWatershedBasedCellSegmentation.txx +++ b/Code/Filters/itkWatershedBasedCellSegmentation.txx @@ -85,7 +85,7 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Gen fgFilter->SetLargestCellRadius (m_NucleusRadius); // in real coordinates fgFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); fgFilter->Update(); - std::cout << "Computed foreground" << std::endl; + // std::cout << "Computed foreground" << std::endl; m_ForegroundImg = fgFilter->GetOutput(); m_ForegroundImg->DisconnectPipeline(); @@ -101,7 +101,7 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Gen distFilter->SetAlpha(m_Alpha); distFilter->SetBeta(m_Beta); distFilter->Update(); - std::cout << "Computed distance map" << std::endl; + //std::cout << "Computed distance map" << std::endl; typename MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New(); minMax->SetImage( distFilter->GetOutput() ); @@ -112,7 +112,7 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Gen idistance->SetInput( distFilter->GetOutput() ); idistance->SetMaximum(max); idistance->Update(); - std::cout << "Inverted distance map" << std::endl; + // std::cout << "Inverted distance map" << std::endl; WatershedFilterPointer wshed = WatershedFilterType::New(); wshed->SetInput( idistance->GetOutput() ); @@ -141,7 +141,7 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Gen region.SetIndex(index2); region.SetSize(size2); - std::cout << "label: " << label << std::endl; + // std::cout << "label: " << label << std::endl; SegmentIteratorType It( output, output->GetLargestPossibleRegion() ); @@ -164,7 +164,7 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Gen ++It; } } - std::cout << "Computed watershed segmentation" << std::endl; + // std::cout << "Computed watershed segmentation" << std::endl; // InputImagePointer smooth; // { @@ -206,4 +206,4 @@ WatershedBasedCellSegmentation< TFeatureImage, TInputImage, TSegmentImage >::Pri } /* end namespace itk */ -#endif \ No newline at end of file +#endif diff --git a/Code/GUI/lib/CMakeLists.txt b/Code/GUI/lib/CMakeLists.txt index 3af64693..00fd0ec4 100644 --- a/Code/GUI/lib/CMakeLists.txt +++ b/Code/GUI/lib/CMakeLists.txt @@ -30,7 +30,7 @@ SET( QGoGUILIB_SRC QGoImageView3D.cxx QGoImageInfo.cxx QGoLUTDialog.cxx - QGoManualSegmentationSettingsDialog.cxx + TraceEditing/QGoManualSegmentationSettingsDialog.cxx Wizard/QGoOpenCreateImgSessionPage.cxx Wizard/QGoOpenCreateProjectPage.cxx QGoPrintDatabase.cxx @@ -38,7 +38,6 @@ SET( QGoGUILIB_SRC QGoTabImageView2D.cxx QGoTabImageView3D.cxx QGoTabImageView3DwT.cxx - QGoTabImageView4D.cxx QGoTabImageViewElementBase.cxx QGoTabImageViewNDBase.cxx QGoNavigationDockWidget.cxx @@ -75,39 +74,46 @@ SET( QGoGUILIB_SRC QGoColorCodingDialog.cxx QGoDockWidget.cxx QGoToolBarStatus.cxx - - # base segmentation widgets - QGoContourSegmentationBaseDockWidget.cxx - QGoMeshSegmentationBaseDockWidget.cxx - - #--manual segmentation-- - QGoContourManualSegmentation.cxx - QGoContourManualSegmentationWidget.cxx - - #--seed segmentation-- - QGoSeedSegmentationBase.cxx - QGoContourSeedSegmentation.cxx - QGoMeshSeedSegmentation.cxx - QGoSeedBaseWidget.cxx - QGoContourSemiAutoLevelsetWidget.cxx - QGoContourSemiAutoShapeWidget.cxx - QGoContourSemiAutoWatershedWidget.cxx - QGoFilterSemiAutoBase.cxx - QGoFilterChanAndVese.cxx - QGoFilterShape.cxx - QGoFilterWatershed.cxx - - # for the tracks + +# for the tracks QGoTrackViewDockWidget.cxx QGoTrackEditingWidget.cxx - + #for the lineages QGoLineageViewDockWidget.cxx - - QGoTraceEditingWidget.cxx - QGoModeEditingWidget.cxx - QGoAdvancedParametersWidget.cxx - QGoAlgorithmsWidget.cxx + + #--manual segmentation-- + TraceEditing/QGoContourManualSegmentation.cxx + TraceEditing/QGoContourManualSegmentationWidget.cxx + TraceEditing/QGoFilterChanAndVese.cxx + TraceEditing/QGoFilterShape.cxx + TraceEditing/QGoFilterWatershed.cxx + TraceEditing/QGoTraceEditingWidget.cxx + TraceEditing/QGoModesManagerWidget.cxx + TraceEditing/QGoAlgorithmsManagerWidget.cxx + TraceEditing/QGoAlgorithmWidget.cxx + TraceEditing/QGoMeshEditingWidgetManager.cxx + TraceEditing/QGoContourEditingWidgetManager.cxx + TraceEditing/QGoTraceEditingWidgetManager.cxx + TraceEditing/QGoSegmentationAlgo.cxx + TraceEditing/QGoContourLevelSetAlgo.cxx + TraceEditing/QGoMeshLevelSetAlgo.cxx + TraceEditing/QGoMeshShapeAlgo.cxx + TraceEditing/QGoMeshWaterShedAlgo.cxx + TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx + TraceEditing/QGoWaterShedAlgo.cxx + TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx + TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx + TraceEditing/QGoLevelSetAlgo.cxx + TraceEditing/QGoShapeAlgo.cxx + TraceEditing/QGoSetOfContoursShapeAlgo.cxx + TraceEditing/QGoSemiAutoSegmentationAlgo.cxx + TraceEditing/QGoFilterSemiAutoBase.cxx + + # transfer function widget + TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx + TransferFunctionEditor/GoTransferFunctionWidget.cxx + TransferFunctionEditor/hoverpoints.cpp ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/QGoAboutWidget.cxx ${GOFIGURE2_BINARY_DIR}/Code/GUI/lib/QGoNetworkUtilities.cxx @@ -176,7 +182,7 @@ SET( QGoGUILIB_HDRS QGoImageView3D.h QGoImageInfo.h QGoLUTDialog.h - QGoManualSegmentationSettingsDialog.h + TraceEditing/QGoManualSegmentationSettingsDialog.h Wizard/QGoOpenCreateImgSessionPage.h Wizard/QGoOpenCreateProjectPage.h QGoPrintDatabase.h @@ -184,7 +190,6 @@ SET( QGoGUILIB_HDRS QGoTabImageView2D.h QGoTabImageView3D.h QGoTabImageView3DwT.h - QGoTabImageView4D.h QGoTabImageViewElementBase.h QGoTabImageViewNDBase.h QGoNavigationDockWidget.h @@ -223,38 +228,34 @@ SET( QGoGUILIB_HDRS QGoDockWidget.h QGoToolBarStatus.h - # base segmentation widgets - QGoContourSegmentationBaseDockWidget.h - QGoMeshSegmentationBaseDockWidget.h - - #--manual segmentation-- - QGoContourManualSegmentation.h - QGoContourManualSegmentationWidget.h - - #--seed segmentation-- - QGoSeedSegmentationBase.h - QGoContourSeedSegmentation.h - QGoMeshSeedSegmentation.h - QGoSeedBaseWidget.h - QGoContourSemiAutoLevelsetWidget.h - QGoContourSemiAutoShapeWidget.h - QGoContourSemiAutoWatershedWidget.h - QGoFilterSemiAutoBase.h - QGoFilterChanAndVese.h - QGoFilterShape.h - QGoFilterWatershed.h - # for the tracks QGoTrackViewDockWidget.h QGoTrackEditingWidget.h - - # for the lineages + + # for the lineages: QGoLineageViewDockWidget.h - QGoTraceEditingWidget.h - QGoModeEditingWidget.h - QGoAdvancedParametersWidget.h - QGoAlgorithmsWidget.h + #--manual segmentation-- + TraceEditing/QGoContourManualSegmentation.h + TraceEditing/QGoContourManualSegmentationWidget.h + TraceEditing/QGoFilterChanAndVese.h + TraceEditing/QGoFilterShape.h + TraceEditing/QGoFilterWatershed.h + TraceEditing/QGoTraceEditingWidget.h + TraceEditing/QGoModesManagerWidget.h + TraceEditing/QGoAlgorithmsManagerWidget.h + TraceEditing/QGoAlgorithmWidget.h + TraceEditing/QGoMeshEditingWidgetManager.h + TraceEditing/QGoContourEditingWidgetManager.h + TraceEditing/QGoSegmentationAlgo.h + TraceEditing/QGoSemiAutoSegmentationAlgo.h + TraceEditing/QGoTraceEditingWidgetManager.h + TraceEditing/QGoFilterSemiAutoBase.h + + # transfer function widget + TransferFunctionEditor/GoTransferFunctionEditorWidget.h + TransferFunctionEditor/GoTransferFunctionWidget.h + TransferFunctionEditor/hoverpoints.h ) IF( BUILD_COMPARETOOL ) @@ -296,26 +297,17 @@ SET( QGoGUILIB_UI Resources/SegmentationDockWidgetBase.ui #segmentation widget - Resources/SegmentationSeedBaseWidget.ui + #Resources/SegmentationSeedBaseWidget.ui # manual contour segmentation dock widget Resources/ManualSegmentationSettingsDlg.ui Resources/ContourManualSegmentationWidget.ui -# seed segmentation dock widgets - Resources/LevelsetWidget.ui - Resources/WatershedWidget.ui - Resources/ShapeWidget.ui - # other Resources/NavigationDockWidget.ui Resources/LsmToMegaExportDialog.ui Resources/QNameDescriptionInputDialog.ui - # seed segmentation dock widgets - Resources/LevelsetWidget.ui - Resources/WatershedWidget.ui - # for tracks Resources/TrackEditingWidget.ui ) @@ -375,31 +367,13 @@ ADD_LIBRARY( QGoGui SET( QGoGUI_LIBS QVTK QGoIO + GoFilters vtkRenderingAddOn2 PoissonReconstruction ctk - ITKIO - ITKCommon - ITKBasicFilters - ITKStatistics - ) - -IF( ( ITK_VERSION_MAJOR EQUAL 4 ) AND - ( ITK_VERSION_MINOR EQUAL 0 ) AND - ( ITK_VERSION_PATCH EQUAL 0 ) - ) - - SET( QGoGUI_LIBS - ${QGoGUI_LIBS} - ITKReview - ) - -ENDIF( ( ITK_VERSION_MAJOR EQUAL 4 ) AND - ( ITK_VERSION_MINOR EQUAL 0 ) AND - ( ITK_VERSION_PATCH EQUAL 0 ) + ${ITK_LIBRARIES} ) - TARGET_LINK_LIBRARIES( QGoGui ${QGoGUI_LIBS} ) diff --git a/Code/GUI/lib/QGoContourSeedSegmentation.cxx b/Code/GUI/lib/QGoContourSeedSegmentation.cxx deleted file mode 100644 index e5c68498..00000000 --- a/Code/GUI/lib/QGoContourSeedSegmentation.cxx +++ /dev/null @@ -1,103 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ -#include "QGoContourSeedSegmentation.h" - -// To store the seeds -#include "vtkPoints.h" - -// usefull to access internal methods -#include "QGoSeedBaseWidget.h" -// ALGOS -// LevelSet algorithm -#include "QGoFilterChanAndVese.h" -#include "QGoFilterShape.h" -//#include "Watershed.h" - -//-------------------------------------------------------------------------- -QGoContourSeedSegmentation::QGoContourSeedSegmentation(QWidget *parentW, - vtkPoints *seeds, - std::vector< vtkSmartPointer< vtkImageData > > *iOriginalImage, - int iSampling) : - QGoSeedSegmentationBase(parentW, seeds, iSampling), - m_OriginalImage(iOriginalImage) -{ - int filter = 0; - -//============================================================================= -//============================================================================= - - //Add new segmentation method - - m_ShapeFilter = new QGoFilterShape(this, iSampling); // 2 i.e. 2D, to create - // a contour - filter = m_BaseAlgorithmSegmentationWidget->GetNumberOfFilters(); - m_BaseAlgorithmSegmentationWidget->AddFilter( m_ShapeFilter->getName() ); - m_ShapeFilter->getWidget()->setParent(m_BaseAlgorithmSegmentationWidget); - m_ShapeFilter->setPoints( getSeed() ); - m_ShapeFilter->setOriginalImageMC(m_OriginalImage); - m_BaseAlgorithmSegmentationWidget->GetFrame()->addWidget(m_ShapeFilter->getWidget(), 4, 0, 1, -1); - m_ShapeFilter->ConnectSignals(filter); - -//============================================================================= - - //Add new segmentation method - m_LevelSetfilter = new QGoFilterChanAndVese(this, iSampling); // 2 i.e. 2D, - // to create a - // contour - filter = m_BaseAlgorithmSegmentationWidget->GetNumberOfFilters(); - m_BaseAlgorithmSegmentationWidget->AddFilter( m_LevelSetfilter->getName() ); - m_LevelSetfilter->getWidget()->setParent(m_BaseAlgorithmSegmentationWidget); - m_LevelSetfilter->setPoints( getSeed() ); - m_LevelSetfilter->setOriginalImageMC(m_OriginalImage); - m_BaseAlgorithmSegmentationWidget->GetFrame()->addWidget(m_LevelSetfilter->getWidget(), 4, 0, 1, -1); - m_LevelSetfilter->ConnectSignals(filter); - -//============================================================================= -//============================================================================= - - m_BaseAlgorithmSegmentationWidget->Initialize(); - -//============================================================================= -//============================================================================= -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QGoContourSeedSegmentation:: -~QGoContourSeedSegmentation() -{ -} - -//-------------------------------------------------------------------------- \ No newline at end of file diff --git a/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.cxx b/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.cxx deleted file mode 100644 index d8eec59c..00000000 --- a/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.cxx +++ /dev/null @@ -1,258 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#include "QGoContourSegmentationBaseDockWidget.h" - -// base widgets -#include "QGoContourManualSegmentation.h" -#include "QGoContourSeedSegmentation.h" - -//---------------------------------------------------------------------------// -QGoContourSegmentationBaseDockWidget::QGoContourSegmentationBaseDockWidget( - QWidget *iParent, - vtkPoints *seeds, - std::vector< vtkSmartPointer< vtkImageData > > *iOriginalImage) : QGoDockWidget(iParent) -{ - this->setupUi(this); - - this->setWindowTitle( QString::fromUtf8("Contour Editing") ); - - this->m_ToggleAction->setToolTip( tr("Contour Editing") ); - QIcon ContourSegmentationIcon; - ContourSegmentationIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/ContourEditing.png") ), - QIcon::Normal, QIcon::Off); - - this->m_ToggleAction->setIcon(ContourSegmentationIcon); - this->m_ToggleAction->setStatusTip( tr("Create contours manually, semi-automatically or automatically") ); - // update interactor behavior - QObject::connect( this->mode, SIGNAL( activated(int) ), - this, SLOT( SegmentationMethod(int) ) ); - - // ADD BASE WIDGETS FOR EACH SEGMENTATION MODE - - //---------------------------------------------------------------- - // - // NOW WE HAVE TO FILL THE BASE DOCK WIDGET WITH WIDGETS - // 1 widget for each segmentation type - // Create a method do the basic connections with a dockwidget - //---------------------------------------------------------------- - - //---------------------------------------------------------------- - // Manual segmentation - //---------------------------------------------------------------- - - m_ContourManualSegmentation = new QGoContourManualSegmentation(this); - - QWidget *manual_widget = m_ContourManualSegmentation->getWidget(); - - gridLayout->addWidget(manual_widget, 1, 0, 1, -1); - manual_widget->setVisible(false); - - // connect show/hide - QObject::connect( this, SIGNAL( ManualSegmentationActivated(bool) ), - manual_widget, SLOT( setVisible(bool) ) ); - - // connect specific signals - QObject::connect( m_ContourManualSegmentation, SIGNAL( validateContour() ), - this, SIGNAL( ValidateContour() ) ); - QObject::connect( m_ContourManualSegmentation, SIGNAL( reinitializeContour() ), - this, SIGNAL( ReinitializeContourWidget() ) ); - QObject::connect( m_ContourManualSegmentation, - SIGNAL( changeContourRepresentationProperty(float, QColor, QColor, QColor) ), - this, SIGNAL( UpdateContourRepresentationProperties(float, QColor, QColor, QColor) ) ); - - //---------------------------------------------------------------- - // Semi auto segmentation ( i.e. algo with seed) - //--------------------------------------------------------------- - - m_ContourSemiAutoSegmentation = - // 0 2D - // 1 3D - // 2 2D+3D - new QGoContourSeedSegmentation(this, seeds, iOriginalImage, 0); - - QWidget *semi_auto_widget = m_ContourSemiAutoSegmentation->getWidget(); - - gridLayout->addWidget(semi_auto_widget, 1, 0, 1, -1); - semi_auto_widget->setVisible(false); - - // connect show/hide - QObject::connect( this, SIGNAL( SemiAutoSegmentationActivated(bool) ), - semi_auto_widget, SLOT( setVisible(bool) ) ); - - // connect semi-automatic segmentation specific signals - QObject::connect( m_ContourSemiAutoSegmentation, SIGNAL( UpdateSeeds() ), - this, SIGNAL( UpdateSeeds() ) ); - QObject::connect( m_ContourSemiAutoSegmentation, SIGNAL( ContourCreated(vtkPolyData *) ), - this, SIGNAL( SaveAndVisuContour(vtkPolyData *) ) ); - QObject::connect( m_ContourSemiAutoSegmentation, SIGNAL( SegmentationFinished() ), - this, SIGNAL( ClearAllSeeds() ) ); - - gridLayout->setSizeConstraint(QLayout::SetFixedSize); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -QGoContourSegmentationBaseDockWidget:: -~QGoContourSegmentationBaseDockWidget() -{ -} - -//---------------------------------------------------------------------------// -// one segmentation to another -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::SegmentationMethod(int iSegmentationMethod) -{ - emit ManualSegmentationActivated(false); - emit SemiAutoSegmentationActivated(false); - emit AutoSegmentationActivated(false); - - switch ( iSegmentationMethod ) - { - case 0: - emit ManualSegmentationActivated(true); - break; - case 1: - emit SemiAutoSegmentationActivated(true); - break; - case 2: - emit AutoSegmentationActivated(true); - break; - default: - emit ReinitializeInteractorActivated(true); - break; - } -} - -//---------------------------------------------------------------------------// -// show hide widget -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::interactorBehavior(bool iSegmentationMethod) -{ - if ( iSegmentationMethod ) - { - switch ( mode->currentIndex() ) - { - case 0: - emit ManualSegmentationActivated(iSegmentationMethod); - break; - case 1: - emit SemiAutoSegmentationActivated(iSegmentationMethod); - break; - case 2: - emit AutoSegmentationActivated(iSegmentationMethod); - break; - default: - break; - } - } - else - { - emit ManualSegmentationActivated(false); - emit SemiAutoSegmentationActivated(false); - emit AutoSegmentationActivated(false); - emit ReinitializeInteractorActivated(true); - - this->setVisible(false); - } -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::SetChannel(int iChannel, const QString & iText) -{ - QString input; - - if ( !iText.isEmpty() ) - { - input = iText; - } - else - { - input = QString("Channel %1").arg(iChannel); - } - - m_ContourSemiAutoSegmentation->SetChannel(iChannel, input); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::SetCurrentChannel(unsigned int iChannel) -{ - m_ContourSemiAutoSegmentation->SetCurrentChannel(iChannel); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::SetNumberOfChannels(int iNumberOfChannels) -{ - m_ContourSemiAutoSegmentation->SetNumberOfChannels(iNumberOfChannels); -} - -//---------------------------------------------------------------------------// -bool -QGoContourSegmentationBaseDockWidget::GetReeditMode() -{ - return m_ContourManualSegmentation->GetReeditMode(); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::SetReeditMode(bool iEnable) -{ - m_ContourManualSegmentation->SetReeditMode(iEnable); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoContourSegmentationBaseDockWidget::Initialize() -{ - m_ContourManualSegmentation->GenerateContourRepresentationProperties(true); -} -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// diff --git a/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.h b/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.h deleted file mode 100644 index e16b3eec..00000000 --- a/Code/GUI/lib/QGoContourSegmentationBaseDockWidget.h +++ /dev/null @@ -1,181 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#ifndef __QGoContourSegmentationBaseDockWidget_h -#define __QGoContourSegmentationBaseDockWidget_h - -#include - -#include "vtkPoints.h" -#include "vtkImageData.h" -#include "vtkPolyData.h" -#include "vtkSmartPointer.h" -#include "QGoDockWidget.h" - -// base widgets -class QGoContourManualSegmentation; -class QGoContourSeedSegmentation; - -#include "ui_SegmentationDockWidgetBase.h" - -/** - * \class QGoContourSegmentationBaseDockWidget - * \ingroup QGoContour - * \brief Base dockwidget for the contours segmentation -*/ - -class QGoContourSegmentationBaseDockWidget: - public QGoDockWidget, - protected Ui::SegmentationDockWidgetBase -{ - Q_OBJECT -public: - explicit QGoContourSegmentationBaseDockWidget( - QWidget *iParent = 0, - vtkPoints *seeds = 0, - std::vector< vtkSmartPointer > *iOriginalImage = 0); - - ~QGoContourSegmentationBaseDockWidget(); - - /** - * \brief Specify on which one the segmentation will be applied - * \param[in] iChannel Channel on which want we want to apply the segmentation - * algorithm - * \param[in] iText Name of the channel (not used yet) - */ - void SetChannel(int iChannel, const QString & iText = QString()); - - void SetCurrentChannel(unsigned int iChannel); - - void SetNumberOfChannels(int iNumberOfChannels); - - /** - * \brief Get reedit mode. Provides a way to know if the reedit mode in on or of - * \return true: reedit mode ON, false: reedit mode OFF - */ - bool GetReeditMode(); - - /** - * \brief Set reedit mode. Provides a way to set the reedit mode to on or of - * \param[in] iEnable true: reedit mode ON, false: reedit mode OFF - */ - void SetReeditMode(bool iEnable); - - /** - * \brief Initialize the dockwidget - */ - void Initialize(); - - //QAction* toggleViewAction(); - -public slots: - /** - * \brief Slot to know if we are in Manual, Semi Automatic ou Automatic segmentation - */ - void SegmentationMethod(int); - - /** - * \brief Slot to update the interactor behavior, depending on if we are - * in Manual, Semi Automatic ou Automatic segmentation - */ - void interactorBehavior(bool); - -signals: - /** - * \brief Signal sent when we enter/leave the Manual segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void ManualSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent when we enter/leave the Semi Automatic segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void SemiAutoSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent when we enter/leave the Automatic segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void AutoSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent to go to the default interactor behavior - */ - void ReinitializeInteractorActivated(bool); - - // manual segmentation specific signals - /** - * \brief Signal sent when a contour has been validated in manual segmentation - */ - void ValidateContour(); - - /** - * \brief Signal sent when a contour has been reinitialized in manual segmentation - */ - void ReinitializeContourWidget(); - - /** - * \brief Signal sent to update the contour properties in the visualization - */ - void UpdateContourRepresentationProperties(float, QColor, QColor, QColor); - - // semi automatic signals - /** - * \brief Signal sent before starting a "seed segmentation" to update the - * value of the seeds - */ - void UpdateSeeds(); - - /** - * \brief Signal sent after a seed segmentation to save the contour and - * update the visualization - */ - void SaveAndVisuContour(vtkPolyData *); - - /** - * \brief Signal sent after a seed segmentation to delete the seeds - */ - void ClearAllSeeds(); - -protected: - QGoContourManualSegmentation *m_ContourManualSegmentation; - QGoContourSeedSegmentation * m_ContourSemiAutoSegmentation; - //QAction* m_ToggleAction; - //void closeEvent(QCloseEvent *iEvent); -private: - Q_DISABLE_COPY(QGoContourSegmentationBaseDockWidget); -}; - -#endif diff --git a/Code/GUI/lib/QGoDBContourManager.cxx b/Code/GUI/lib/QGoDBContourManager.cxx index c2885814..4f11efa3 100644 --- a/Code/GUI/lib/QGoDBContourManager.cxx +++ b/Code/GUI/lib/QGoDBContourManager.cxx @@ -169,6 +169,7 @@ std::list< unsigned int > QGoDBContourManager::UpdateTheTracesColor( //------------------------------------------------------------------------- unsigned int QGoDBContourManager::SaveNewContourFromVisu( + int iTCoord, unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, vtkPolyData *iTraceNodes, @@ -185,13 +186,12 @@ unsigned int QGoDBContourManager::SaveNewContourFromVisu( GoDBContourRow NewContour(this->m_ImgSessionID); int NewContourID = this->CreateNewTraceInDBFromVisu< GoDBContourRow >( - iXCoordMin, iYCoordMin, iZCoordMin, *this->m_CurrentTimePoint, + iXCoordMin, iYCoordMin, iZCoordMin, iTCoord,//*this->m_CurrentTimePoint, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, *this->m_SelectedColorData, iDatabaseConnector, NewContour, iMeshID); - + // pointer to double has to be deleted after usage... double *rgba = this->GetVectorFromQColor(this->m_SelectedColorData->second); - this->m_ContourContainerInfoForVisu->UpdateCurrentElementFromDB( NewContourID, rgba); delete[] rgba; @@ -388,4 +388,4 @@ bool QGoDBContourManager::AreCheckedContoursFromCurrentTimepoint() emit DBConnectionNotNeededAnymore(); } return true; -} \ No newline at end of file +} diff --git a/Code/GUI/lib/QGoDBContourManager.h b/Code/GUI/lib/QGoDBContourManager.h index 670a2fe2..827c46a9 100755 --- a/Code/GUI/lib/QGoDBContourManager.h +++ b/Code/GUI/lib/QGoDBContourManager.h @@ -62,7 +62,8 @@ class QGOGUILIB_EXPORT QGoDBContourManager:public QGoDBTraceManager */ void SetContoursInfoContainerForVisu(ContourContainer *iContainerForVisu); - unsigned int SaveNewContourFromVisu(unsigned int iXCoordMin, + unsigned int SaveNewContourFromVisu(int iTCoord, + unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, diff --git a/Code/GUI/lib/QGoDBLineageManager.cxx b/Code/GUI/lib/QGoDBLineageManager.cxx index eb19aff5..de9b8eac 100644 --- a/Code/GUI/lib/QGoDBLineageManager.cxx +++ b/Code/GUI/lib/QGoDBLineageManager.cxx @@ -87,17 +87,16 @@ void QGoDBLineageManager::SetLineagesInfoContainersForVisu( this, SLOT( UpdateElementHighlighting(unsigned int) ) ); - // for a list of lineages - NOT TESTED + // for a list of lineages QObject::connect( m_LineageContainerInfoForVisu, - SIGNAL( HighlightLineage(unsigned int, bool) ), + SIGNAL( HighlightLineage(const unsigned int&, const bool&) ), m_TrackContainerInfoForVisu, - SLOT( HighlightCollection(unsigned int, bool) ) ); + SLOT( HighlightCollection(const unsigned int&, const bool&) ) ); QObject::connect( m_LineageContainerInfoForVisu, - SIGNAL( ShowLineage(unsigned int, bool) ), + SIGNAL( ShowLineage(const unsigned int&, const bool&) ), m_TrackContainerInfoForVisu, - SLOT( ShowCollection(unsigned int, bool) ) ); - + SLOT( ShowCollection(const unsigned int&, const bool&) ) ); // export lineage QObject::connect( m_LineageContainerInfoForVisu, SIGNAL( ExportLineages() ), @@ -203,10 +202,12 @@ unsigned int QGoDBLineageManager::CreateNewLineageWithTrackRoot( this->m_CollectionOfTraces->CreateCollectionWithNoTracesNoPoints< GoDBLineageRow >( iDatabaseConnector, *this->m_SelectedColorData, NewLineage); this->UpdateTrackRootSelectedLineage(iDatabaseConnector, NewLineageID, iTrackRoot); - - this->m_LineageContainerInfoForVisu->InsertNewLineage(NewLineageID, - this->GetVectorFromQColor(this->m_SelectedColorData->second), iTrackRoot, + // pointer to double has to be deleted after usage... + double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); + this->m_LineageContainerInfoForVisu->InsertNewLineage(NewLineageID, color + , iTrackRoot, true); + delete[] color; this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); return NewLineageID; @@ -226,9 +227,11 @@ std::list< unsigned int > QGoDBLineageManager::UpdateTheTracesColor( std::list< unsigned int >::iterator it = oList.begin(); while( it != oList.end() ) { + // pointer to double has to be deleted after usage... + double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); unsigned int trackRoot = this->m_LineageContainerInfoForVisu->GetLineageTrackRootID(*it); - m_TrackContainerInfoForVisu->UpdateCollectionColorsData( trackRoot, - this->GetVectorFromQColor(this->m_SelectedColorData->second) ); + m_TrackContainerInfoForVisu->UpdateCollectionColorsData( trackRoot, color); + delete[] color; ++it; } @@ -477,10 +480,16 @@ QGoDBLineageManager::UpdateBoundingBoxes(vtkMySQLDatabase *iDatabaseConnector, std::list::iterator iter = iListTracesIDs.begin(); while(iter != iListTracesIDs.end() ) { - this->UpdateDivisionsInTrackContainer(*iter); - if ( UpdateTW ) + std::list Listiter; + Listiter.push_back(*iter); + //need to check first that the lineage does exist, which corresponds to check if there are tracks that have this lineageid: + if (!this->m_CollectionOfTraces->GetListTracesIDsFromThisCollectionOf(iDatabaseConnector, Listiter).empty()) { - this->DisplayInfoForExistingTrace(iDatabaseConnector, *iter); + this->UpdateDivisionsInTrackContainer(*iter); + if ( UpdateTW ) + { + this->DisplayInfoForExistingTrace(iDatabaseConnector, *iter); + } } ++iter; } diff --git a/Code/GUI/lib/QGoDBMeshManager.cxx b/Code/GUI/lib/QGoDBMeshManager.cxx index c331e996..e13ff9a1 100644 --- a/Code/GUI/lib/QGoDBMeshManager.cxx +++ b/Code/GUI/lib/QGoDBMeshManager.cxx @@ -69,7 +69,6 @@ void QGoDBMeshManager::SetMeshesInfoContainerForVisu( //------------------------------------------------------------------------- //------------------------------------------------------------------------- - void QGoDBMeshManager::SetCollectionsTraceNames() { this->m_TraceName = "mesh"; @@ -179,9 +178,11 @@ void QGoDBMeshManager::AddActionsContextMenu(QMenu *iMenu) unsigned int QGoDBMeshManager::SaveNewMeshFromVisu( unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, - unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, + unsigned int iZCoordMax, int iTCoord,//int iTShift, + vtkPolyData *iTraceNodes, vtkMySQLDatabase *iDatabaseConnector, - GoFigureMeshAttributes *iMeshAttributes) + GoFigureMeshAttributes *iMeshAttributes, + unsigned int iTrackID) { GoDBMeshRow NewMesh(this->m_ImgSessionID); @@ -190,28 +191,50 @@ unsigned int QGoDBMeshManager::SaveNewMeshFromVisu( this->SetMeshBoundingBoxAndPoints(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, iDatabaseConnector, NewMesh, - iMeshAttributes, iTShift); - //unsigned int TrackID = 0; - std::string test = this->m_SelectedCollectionData->first; //for test - //if (this->m_SelectedCollectionData->first != "Add a new track ...") no need - // as it will be directly 0 - // TrackID = ss_atoi(this->m_SelectedCollectionData->first); - + iMeshAttributes, iTCoord); //save the intensities for each channel !!! unsigned int NewMeshID = this->m_CollectionOfTraces->CreateNewTraceInDB< GoDBMeshRow >( - NewMesh, iDatabaseConnector, *this->m_SelectedColorData, - ss_atoi< unsigned int >(this->m_SelectedCollectionData->first) ); - + NewMesh, iDatabaseConnector, *this->m_SelectedColorData, iTrackID ); + // pointer to double has to be deleted after usage... double *rgba = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_MeshContainerInfoForVisu->UpdateCurrentElementFromDB( NewMeshID, rgba); + delete[] rgba; this->DisplayInfoForLastCreatedMesh(iDatabaseConnector, iMeshAttributes); return NewMeshID; } +//------------------------------------------------------------------------- //------------------------------------------------------------------------- +unsigned int QGoDBMeshManager::SaveNewMeshFromVisu( + unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, + unsigned int iXCoordMax, unsigned int iYCoordMax, + unsigned int iZCoordMax, int iTCoord, vtkPolyData *iTraceNodes, + vtkMySQLDatabase *iDatabaseConnector, + GoFigureMeshAttributes *iMeshAttributes) +{ + return SaveNewMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, + iZCoordMax, iTCoord, iTraceNodes, iDatabaseConnector, iMeshAttributes, + ss_atoi(this->m_SelectedCollectionData->first) ); +} //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +unsigned int QGoDBMeshManager::SaveNewMeshWithNoTrackFromVisu( + unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, + unsigned int iXCoordMax, unsigned int iYCoordMax, + unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, + vtkMySQLDatabase *iDatabaseConnector, + GoFigureMeshAttributes *iMeshAttributes) +{ + return SaveNewMeshFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, + iZCoordMax, iTShift, iTraceNodes, iDatabaseConnector, iMeshAttributes, 0 ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + void QGoDBMeshManager::SaveGeneratedMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, @@ -270,12 +293,12 @@ unsigned int QGoDBMeshManager::CreateNewMeshWithNoContourNoPoints( unsigned int NewMeshID = this->m_CollectionOfTraces->CreateCollectionWithNoTracesNoPoints< GoDBMeshRow >( iDatabaseConnector, *this->m_SelectedColorData, NewMesh, *this->m_CurrentTimePoint); + // pointer to double has to be deleted after usage... double *color = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_MeshContainerInfoForVisu->ResetCurrentElement(); this->m_MeshContainerInfoForVisu->UpdateCurrentElementFromDB( NewMeshID, color); delete[] color; - this->m_MeshContainerInfoForVisu->InsertCurrentElement(); this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); @@ -323,12 +346,13 @@ void QGoDBMeshManager::SetMeshBoundingBoxAndPoints(unsigned int iXCoordMin, vtkMySQLDatabase *iDatabaseConnector, GoDBMeshRow & iMesh, GoFigureMeshAttributes *iMeshAttributes, - int iShift) + int iTCoord) + //int iShift) { GoDBCoordinateRow coord_min = this->GetCoordinateFromInt(iXCoordMin, - iYCoordMin, iZCoordMin, *this->m_CurrentTimePoint + iShift); + iYCoordMin, iZCoordMin, iTCoord);//*this->m_CurrentTimePoint + iShift); GoDBCoordinateRow coord_max = this->GetCoordinateFromInt(iXCoordMax, - iYCoordMax, iZCoordMax, *this->m_CurrentTimePoint + +iShift); + iYCoordMax, iZCoordMax, iTCoord);//*this->m_CurrentTimePoint + +iShift); iMesh.SetTheDataFromTheVisu(iDatabaseConnector, iTraceNodes, coord_min, coord_max, iMeshAttributes); @@ -526,7 +550,8 @@ unsigned int QGoDBMeshManager::ReassignTrackIDForPreviousMeshWithSameTimePoint(v //------------------------------------------------------------------------- QString QGoDBMeshManager::CheckExistingMeshesForTheTrack( - unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector, int iShift) + unsigned int iTrackID, vtkMySQLDatabase *iDatabaseConnector, + int iTCoord) { QString MessageToPrint(""); @@ -534,7 +559,7 @@ QString QGoDBMeshManager::CheckExistingMeshesForTheTrack( { unsigned int MeshIDKickedOut = this->ReassignTrackIDForPreviousMeshWithSameTimePoint( - iDatabaseConnector, iTrackID, *this->m_CurrentTimePoint + iShift); + iDatabaseConnector, iTrackID, iTCoord); if ( MeshIDKickedOut != 0 ) { MessageToPrint = diff --git a/Code/GUI/lib/QGoDBMeshManager.h b/Code/GUI/lib/QGoDBMeshManager.h index 7fb03faf..bd8ed5eb 100755 --- a/Code/GUI/lib/QGoDBMeshManager.h +++ b/Code/GUI/lib/QGoDBMeshManager.h @@ -104,6 +104,17 @@ class QGOGUILIB_EXPORT QGoDBMeshManager:public QGoDBTraceManager vtkMySQLDatabase *iDatabaseConnector, GoFigureMeshAttributes *iMeshAttributes); + unsigned int SaveNewMeshWithNoTrackFromVisu(unsigned int iXCoordMin, + unsigned int iYCoordMin, + unsigned int iZCoordMin, + unsigned int iXCoordMax, + unsigned int iYCoordMax, + unsigned int iZCoordMax, + int iTShift, + vtkPolyData *iTraceNodes, + vtkMySQLDatabase *iDatabaseConnector, + GoFigureMeshAttributes *iMeshAttributes); + void SaveGeneratedMeshFromVisu(unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, @@ -194,7 +205,7 @@ public slots: reassigned, the message will be "" */ QString CheckExistingMeshesForTheTrack( - unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector, int iShift = 0); + unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector, int iTCoord);//int iShift = 0); /** \overload @@ -279,6 +290,14 @@ public slots: std::pair GetInfoForTheOnlyOneCheckedMeshOfTheTrack( vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID); + unsigned int SaveNewMeshFromVisu( + unsigned int iXCoordMin, unsigned int iYCoordMin, unsigned int iZCoordMin, + unsigned int iXCoordMax, unsigned int iYCoordMax, + unsigned int iZCoordMax, int iTShift, vtkPolyData *iTraceNodes, + vtkMySQLDatabase *iDatabaseConnector, + GoFigureMeshAttributes *iMeshAttributes, + unsigned int iTrackID); + protected slots: //virtual pure method in QGoDBTraceManager virtual void UpdateHighlightedElementsInVisuContainer(int iTraceID); diff --git a/Code/GUI/lib/QGoDBTrackManager.cxx b/Code/GUI/lib/QGoDBTrackManager.cxx index 2d8ac1cf..2d7a2c0e 100644 --- a/Code/GUI/lib/QGoDBTrackManager.cxx +++ b/Code/GUI/lib/QGoDBTrackManager.cxx @@ -137,8 +137,11 @@ unsigned int QGoDBTrackManager::CreateNewTrackWithNoMesh( iDatabaseConnector, *this->m_SelectedColorData, NewTrack); this->m_TrackContainerInfoForVisu->ResetCurrentElement(); + // pointer to double has to be deleted after usage... + double* color = this->GetVectorFromQColor(this->m_SelectedColorData->second); this->m_TrackContainerInfoForVisu->UpdateCurrentElementFromDB( - NewTrackID, this->GetVectorFromQColor(this->m_SelectedColorData->second), true); + NewTrackID, color, true); + delete[] color; this->m_TrackContainerInfoForVisu->InsertCurrentElement(); this->DisplayInfoForLastCreatedTrace(iDatabaseConnector); NameWithColorData NewTrackData(ConvertToString< unsigned int >(NewTrackID), @@ -174,7 +177,32 @@ void QGoDBTrackManager::UpdateTWAndContainerForImportedTraces( //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteCheckedTraces(vtkMySQLDatabase *iDatabaseConnector) { - this->DeleteTracesTemplate< TrackContainer >(iDatabaseConnector, + //if the tracks to be deleted belongs to some divisions, the divisions need to + //be deleted first: + std::list ListDivisionsToDelete = + this->m_CollectionOfTraces->GetTrackFamilyID(iDatabaseConnector, + this->GetListHighlightedIDs() ); + std::list::iterator iter = ListDivisionsToDelete.begin(); + std::list TrackIDsWithNoLineage = std::list(); + std::list LineagesToDelete = std::list(); + while( iter != ListDivisionsToDelete.end() ) + { + if (*iter != 0) + { + emit NeedToGetDatabaseConnection(); + GoDBTrackFamilyRow Division(*iter, this->m_DatabaseConnector); + this->DeleteOneDivision(Division, this->m_DatabaseConnector, TrackIDsWithNoLineage, LineagesToDelete); + } + ++iter; + } + + if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages + { + emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete); + } + + emit NeedToGetDatabaseConnection(); + this->DeleteTracesTemplate< TrackContainer >(this->m_DatabaseConnector, this->m_TrackContainerInfoForVisu); } @@ -779,20 +807,20 @@ void QGoDBTrackManager::DeleteTheDivisions() } ++iter; } + this->PrintAMessageForTracksWithNoDivision(TrackIDNotMother); if (!TrackIDsWithNoLineage.empty() ) //set the lineageID to 0 and update the bounding boxes of the previous lineages { emit CheckedTracksToAddToSelectedLineage(TrackIDsWithNoLineage, 0, LineagesToDelete); } - - emit DBConnectionNotNeededAnymore(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoDBTrackManager::DeleteOneDivision(GoDBTrackFamilyRow iDivision, - vtkMySQLDatabase* iDatabaseConnector, std::list &ioTrackIDsNoLineage, + vtkMySQLDatabase* iDatabaseConnector, + std::list &ioTrackIDsNoLineage, std::list &ioMotherLineageToDelete) { std::list DaughtersIDs; @@ -801,14 +829,14 @@ void QGoDBTrackManager::DeleteOneDivision(GoDBTrackFamilyRow iDivision, int MotherID = iDivision.GetMapValue("TrackIDMother"); bool IsPartOfBiggerLineage = true; - if (!this->IsTheTrackADaughter(MotherID, iDatabaseConnector) ) // set the lineageID to 0 + if (!this->IsTheTrackADaughter(MotherID, this->m_DatabaseConnector) ) // set the lineageID to 0 { ioTrackIDsNoLineage.push_back(MotherID); IsPartOfBiggerLineage = false; } //delete the division from the database: - iDivision.DeleteFromDB(iDatabaseConnector); + iDivision.DeleteFromDB(this->m_DatabaseConnector); //update the different values for the daughters of the division: this->UpdateFormerDaughtersOfADeletedDivision(DaughtersIDs, ioTrackIDsNoLineage, @@ -877,25 +905,27 @@ void QGoDBTrackManager::PrintAMessageForTracksWithNoDivision( //------------------------------------------------------------------------- //------------------------------------------------------------------------- -bool QGoDBTrackManager::IsTheTrackAMother(unsigned int iDaughterID, +unsigned int QGoDBTrackManager::IsTheTrackAMother(unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector) { + unsigned int TrackFamilyID; GoDBTrackFamilyRow Family; Family.SetField("TrackIDMother", iDaughterID); - return (Family.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector) != -1); + TrackFamilyID = Family.DoesThisTrackFamilyAlreadyExists(iDatabaseConnector); + if (TrackFamilyID != -1) + { + return TrackFamilyID; + } + return 0; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -bool QGoDBTrackManager::IsTheTrackADaughter(unsigned int iTrackID, +unsigned int QGoDBTrackManager::IsTheTrackADaughter(unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector) { GoDBTrackRow Track(iTrackID, iDatabaseConnector); - if (Track.GetMapValue("TrackFamilyID") == "0") - { - return false; - } - return true; + return ss_atoi (Track.GetMapValue("TrackFamilyID") ); } //------------------------------------------------------------------------- @@ -923,3 +953,132 @@ void QGoDBTrackManager::CreateALineageWithFormerDaughterOfADeletedDivision( } } //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoDBTrackManager::CheckMeshCanBeAddedToTrack( + vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID, + unsigned int iMeshTimePoint, + std::list &ioMotherTrackDivisionToUpdate) +{ + std::string Message = ""; + unsigned int TrackMinTimePoint = + this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, true); + unsigned int TrackMaxTimePoint = + this->m_CollectionOfTraces->GetBoundedBoxTimePoint(iDatabaseConnector, iTrackID, false); + //if the mesh inside the bounding box of the track, no pb: + if (iMeshTimePoint > TrackMinTimePoint && iMeshTimePoint < TrackMaxTimePoint) + { + return Message; + } + + unsigned int DivisionIDTrackIsAMother = this->IsTheTrackAMother(iTrackID, iDatabaseConnector); + unsigned int DivisionIDTrackIsADaughter = this->IsTheTrackADaughter(iTrackID, iDatabaseConnector); + //if the track doesn't belong to any division, no pb: + if (!DivisionIDTrackIsAMother && !DivisionIDTrackIsADaughter) + { + return Message; + } + + if (DivisionIDTrackIsAMother) + { + if (iMeshTimePoint >= TrackMinTimePoint) + { + //check that the meshtimepoint < timepoint min daughter if not, message + unsigned int DivisionToUpdate = this->CheckBoundingBoxDivisionAsAMother( + iDatabaseConnector, iMeshTimePoint, DivisionIDTrackIsAMother ); + if (DivisionToUpdate != 0) + { + ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate); + } + else + { + Message = "The mesh will not belong to any track as there is a problem with the division"; + return Message; + } + } + } + + if (DivisionIDTrackIsADaughter) + { + if (iMeshTimePoint > TrackMaxTimePoint) + { + return Message; + } + //check that the meshtimepoint > timepoint max mother if not, message + unsigned int DivisionToUpdate = + this->CheckBoundingBoxDivisionAsADaughter(iDatabaseConnector, iMeshTimePoint, + DivisionIDTrackIsADaughter); + if (DivisionToUpdate != 0) + { + ioMotherTrackDivisionToUpdate.push_back(DivisionToUpdate); + } + else + { + Message = "The mesh will not belong to any track as there is a problem with the division"; + return Message; + } + } + return Message; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +unsigned int QGoDBTrackManager::CheckBoundingBoxDivisionAsAMother( + vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ) +{ + if(iTrackFamilyID != 0) + { + GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector); + if ( (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint( + iDatabaseConnector, Division.GetMapValue("TrackIDDaughter1") ) + && (iTimePoint < this->m_CollectionOfTraces->GetBoundedBoxTimePoint( + iDatabaseConnector, Division.GetMapValue("TrackIDDaughter2") ) ) ) ) + { + return Division.GetMapValue("TrackIDMother"); + } + return 0; + } + return 0; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +unsigned int QGoDBTrackManager::CheckBoundingBoxDivisionAsADaughter( + vtkMySQLDatabase* iDatabaseConnector, unsigned int iTimePoint, unsigned int iTrackFamilyID ) +{ + if (iTrackFamilyID != 0) + { + GoDBTrackFamilyRow Division(iTrackFamilyID, iDatabaseConnector); + if ( iTimePoint > this->m_CollectionOfTraces->GetBoundedBoxTimePoint( + iDatabaseConnector, Division.GetMapValue("TrackIDMother") ) ) + { + return Division.GetMapValue("TrackIDMother"); + } + return 0; + } + return 0; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::list QGoDBTrackManager::GetDivisionIDsTheTrackBelongsTo( + vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID ) +{ + std::list Tracks; + Tracks.push_back(iTrackID); + std::list oDivisionIDs = this->m_CollectionOfTraces->GetTrackFamilyID( + iDatabaseConnector, Tracks ); + return oDivisionIDs; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoDBTrackManager::UpdateDivisions(std::list iListMotherTrackIDs) +{ + std::list::iterator iter = iListMotherTrackIDs.begin(); + while (iter != iListMotherTrackIDs.end() ) + { + this->m_TrackContainerInfoForVisu->CreateDivisionPolydata(*iter); + ++iter; + } +} diff --git a/Code/GUI/lib/QGoDBTrackManager.h b/Code/GUI/lib/QGoDBTrackManager.h index 80a79cd1..57ac8817 100755 --- a/Code/GUI/lib/QGoDBTrackManager.h +++ b/Code/GUI/lib/QGoDBTrackManager.h @@ -122,6 +122,7 @@ class QGOGUILIB_EXPORT QGoDBTrackManager:public QGoDBTraceManager //virtual pure method in QGoDBTraceManager virtual void DeleteCheckedTraces( vtkMySQLDatabase *iDatabaseConnector); + //virtual pure method in QGoDBTraceManager virtual std::list< unsigned int > GetListHighlightedIDs(); @@ -142,6 +143,20 @@ class QGOGUILIB_EXPORT QGoDBTrackManager:public QGoDBTraceManager void UpdateBoundingBoxes( vtkMySQLDatabase *iDatabaseConnector,std::list< unsigned int > iListTracesIDs); + /** + \brief check if the track belongs to a division and if it is possible to add the mesh + without making the track overlapping the other tracks of the divisions, if so return + a message to the user, if not, return the trackID of the divisions to be updated in the + visu, if return empty message and empty list, the track doesn't belong to any division + */ + std::string CheckMeshCanBeAddedToTrack(vtkMySQLDatabase* iDatabaseConnector, + unsigned int iTrackID, unsigned int iMeshTimePoint, std::list &ioMotherTrackDivisionToUpdate); + + /** + \brief update the track container for visu and consequently the divisions in the visu + */ + void UpdateDivisions(std::list iListMotherTrackIDs); + signals: void NeedMeshesInfoForImportedTrack(unsigned int iTrackID); void TrackToSplit(unsigned int iTrackID, std::list iListMeshIDs); @@ -277,15 +292,17 @@ class QGOGUILIB_EXPORT QGoDBTrackManager:public QGoDBTraceManager unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector, bool &ioPartOfHigherLineage); /** - \brief return true if the track is a mother + \brief return the trackfamilyID of the division the track is a mother of or 0 if the + track is not a mother */ - bool IsTheTrackAMother(unsigned int iDaughterID, + unsigned int IsTheTrackAMother(unsigned int iDaughterID, vtkMySQLDatabase* iDatabaseConnector); /** - \brief return true if the track is a daughter + \brief return the trackfamilyID of the division the track is a daughter of or 0 if the + track is not a daughter */ - bool IsTheTrackADaughter(unsigned int iTrackID, + unsigned int IsTheTrackADaughter(unsigned int iTrackID, vtkMySQLDatabase* iDatabaseConnector); /** @@ -300,6 +317,25 @@ class QGOGUILIB_EXPORT QGoDBTrackManager:public QGoDBTraceManager std::list &ioTrackIDsNoLineage, bool &ioPartOfHigherLineage); + /** + \brief get the division IDs the track belongs to as a mother or as a daughter + */ + std::list GetDivisionIDsTheTrackBelongsTo( + vtkMySQLDatabase* iDatabaseConnector, unsigned int iTrackID ); + /** + \brief check that the iTimePoint is < to the mintimepoint of the daughter from the + division where trackID is a mother + */ + unsigned int CheckBoundingBoxDivisionAsAMother(vtkMySQLDatabase* iDatabaseConnector, + unsigned int iTimePoint, unsigned int iTrackFamilyID ); + + /** + \brief check that the iTimePoint is > to the maxtimepoint of the mother from the + division where trackID is a daughter + */ + unsigned int CheckBoundingBoxDivisionAsADaughter(vtkMySQLDatabase* iDatabaseConnector, + unsigned int iTimePoint, unsigned int iTrackFamilyID ); + protected slots: //virtual pure method in QGoDBTraceManager diff --git a/Code/GUI/lib/QGoFilterWatershed.cxx b/Code/GUI/lib/QGoFilterWatershed.cxx deleted file mode 100644 index 3dfb2611..00000000 --- a/Code/GUI/lib/QGoFilterWatershed.cxx +++ /dev/null @@ -1,442 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ -#include "QGoFilterWatershed.h" - -#include "QGoGUILibConfigure.h" - -// for apply method -#include "vtkImageExport.h" -#include "vtkImageData.h" -#include "vtkMetaImageWriter.h" -// ITK filter -#include "itkImageFileWriter.h" -#include "itkWatershedBasedCellSegmentation.h" -#include "itkImage.h" -#include "itkVTKImageImport.h" - -// to cut -#include "vtkPlane.h" -#include "vtkCutter.h" - -// to translate -#include "vtkTransform.h" -#include "vtkTransformPolyDataFilter.h" - -#include "QGoContourSemiAutoWatershedWidget.h" - -//-------------------------------------------------------------------------- -QGoFilterWatershed::QGoFilterWatershed(QObject *iParent, int iDimension) : - QGoFilterSemiAutoBase(iParent) -{ - m_Dimension = iDimension; - - m_TreshMin = 10; - m_TreshMax = 30; - m_CorrTresh = 0.50; - m_Alpha = 1.5; - m_Beta = 3.0; - - QString name = "Watershed "; - if ( m_Dimension < 2 ) - { - name.append( QString::number(m_Dimension + 2, 10) ); - name.append("D"); - } - else - { - name = "2D Watershed within 1 mesh"; - } - - setName(name); - QGoContourSemiAutoWatershedWidget *widget = new QGoContourSemiAutoWatershedWidget; - setWidget(widget); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QGoFilterWatershed:: -~QGoFilterWatershed() -{ -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::Filter2D(double *iCenter, const int & iOrientation) -{ - (void)iCenter; - (void)iOrientation; - /* - const int dimension = 2; - - // useful to translate the polydata afterwards - setCenter(iCenter); - - vtkImageData* slice = vtkImageData::New(); - - // Extract one slice if dimenesion == 2 - vtkImageData* input = extractOneSlice(getInput(), iCenter, iOrientation); - slice->DeepCopy(input); - input->Delete(); - - // Recompute new center - double* newOrigin = slice->GetOrigin(); - double center[3]; - - switch (iOrientation) - { - case 0: - { - center[0] = iCenter[0] + newOrigin[0]; - center[1] = iCenter[1] + newOrigin[1]; - center[2] = 0.; - break; - } - case 1: - { - center[0] = iCenter[0] + newOrigin[0]; - center[1] = iCenter[2] + newOrigin[1]; - center[2] = 0.; - break; - } - case 2: - { - center[0] = iCenter[1] + newOrigin[0]; - center[1] = iCenter[2] + newOrigin[1]; - center[2] = 0.; - break; - } - default: - { - break; - } - } - - // run filter - typedef itk::Image FeatureImageType; - typedef itk::Image OutputImageType; - - //VTK to ITK - //--------------------------------------------------------- - FeatureImageType::Pointer - itkImage = ConvertVTK2ITK( slice ); - - // Extract ROI - //--------------------------------------------------------- - FeatureImageType::Pointer - test2 = ExtractROI(itkImage, center, getRadius()); - - // Apply filter - // Apply LevelSet segmentation filter - //--------------------------------------------------------- - typedef itk::ChanAndVeseSegmentationFilter - SegmentationFilterType; - - FeatureImageType::PointType pt; - - SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); - - filter->SetFeatureImage(test2); - filter->SetPreprocess(1); - - pt[0] = center[0]; - pt[1] = center[1]; - pt[2] = center[2]; - filter->SetCenter(pt); - - filter->SetRadius(getRadius()); - filter->SetNumberOfIterations(m_Iterations); - filter->SetCurvatureWeight(m_Curvature); - filter->Update(); - - OutputImageType::Pointer test3 = filter->GetOutput(); - - // Convert output - //--------------------------------------------------------- - vtkImageData* itk2vtk = ConvertITK2VTK(test3); - setOutput(itk2vtk); - itk2vtk->Delete(); - - vtkPolyData* reconstructed = ReconstructContour( getOutput(), 0. ); - - // Translate to real location (i.e. see_pos[]) - vtkTransform* t = vtkTransform::New(); - t->Translate(getCenter()[0], - getCenter()[1], - getCenter()[2]); - - vtkTransformPolyDataFilter* tf = vtkTransformPolyDataFilter::New(); - tf->SetTransform(t); - tf->SetInput( reconstructed ); - tf->Update(); - - vtkPolyData* contour = vtkPolyData::New(); - contour->DeepCopy( tf->GetOutput() ); - - tf->Delete(); - t->Delete(); - reconstructed->Delete(); - - emit ContourCreated( contour ); - */ -} - -//-------------------------------------------------------------------------- - -void -QGoFilterWatershed::Filter3D(double *iCenter) -{ - const int dimension = 3; - - // useful to translate the polydata afterwards - setCenter(iCenter); - - vtkImageData *slice = vtkImageData::New(); - slice->DeepCopy( getInput() ); - - // run filter - const unsigned int Dimension = 3; - typedef itk::Image< unsigned char, Dimension > FeatureImageType; - typedef FeatureImageType::Pointer FeatureImagePointer; - typedef itk::Image< double, Dimension > InputImageType; - typedef InputImageType::IndexType InputImageIndexType; - typedef InputImageType::Pointer InputImagePointer; - typedef itk::Image< int, Dimension > SegmentImageType; - typedef SegmentImageType::Pointer SegmentImagePointer; - - typedef itk::Image< float, dimension > OutputImageType; - - typedef itk::WatershedBasedCellSegmentation< FeatureImageType, InputImageType, SegmentImageType > - SegmentationFilterType; - - //VTK to ITK - //--------------------------------------------------------- - FeatureImageType::Pointer - itkImage = ConvertVTK2ITK< unsigned char, dimension >(slice); - slice->Delete(); - - // Extract ROI - //--------------------------------------------------------- - FeatureImageType::Pointer - test2 = ExtractROI< unsigned char, dimension >( itkImage, iCenter, getRadius() ); - - // Apply filter - // Apply watershed segmentation filter - //--------------------------------------------------------- - SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); - filter->SetInput(test2); - //set up parameters - filter->SetNucleusThresholdMin(m_TreshMin); - filter->SetNucleusThresholdMax(m_TreshMax); - filter->SetCorrelationThreshold1(m_CorrTresh); - filter->SetAlpha(m_Alpha); - filter->SetBeta(m_Beta); - // run the filter - filter->Update(); - SegmentImagePointer test3 = filter->GetOutput(); - -/* - typedef itk::ImageFileWriter< SegmentImageType > WriterType; - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName( "output.mha" ); - writer->SetInput( test3 ); - writer->Update(); -*/ - - // Convert output - //--------------------------------------------------------- - vtkImageData *itk2vtk = ConvertITK2VTK< int, dimension >(test3); - setOutput(itk2vtk); - itk2vtk->Delete(); - -// vtkSmartPointer< vtkMetaImageWriter > writer = vtkSmartPointer< -// vtkMetaImageWriter >::New(); -// writer->SetFileDimensionality( 3 ); -// writer->SetInput( getOutput() ); -// writer->SetFileName("test.mha"); -// writer->Write(); - - // 3D when m_Dimension = 1 - /// \todo rename m_Dimension - if ( m_Dimension == 1 ) - { - vtkPolyData *output = ReconstructMesh(getOutput(), .5); - emit MeshCreated(output, this->getChannel() - 1); - } - else - { - // Extract each slice according top the sampling - vtkPlane *implicitFunction = vtkPlane::New(); - implicitFunction->SetNormal(0, 0, 1); - - vtkCutter * cutter = vtkCutter::New(); - vtkPolyData *reconstructed = ReconstructMesh(getOutput(), .5); - cutter->SetInput(reconstructed); - cutter->SetCutFunction(implicitFunction); - reconstructed->Delete(); - - for ( int j = 0; j < getSampling(); ++j ) - { - implicitFunction - ->SetOrigin( ( iCenter[0] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ), - ( iCenter[1] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ), - ( iCenter[2] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ) ); - cutter->Update(); - //true: we decimate the contour - vtkPolyData *output = ReorganizeContour(cutter->GetOutput(), true); - - emit AddContourForMeshToContours(output); - } - emit CreateCorrespondingMesh( getSampling() ); - implicitFunction->Delete(); - cutter->Delete(); - } -} - -//-------------------------------------------------------------------------- -vtkPolyData * -QGoFilterWatershed::Apply() -{ - // Radius has to be > 0 - if ( getRadius() <= 0 ) - { - std::cerr << "Radius should be > 0 " << std::endl; - return NULL; - } - // update the pointed value of the seeds - emit UpdateSeeds(); - - double *center2 = new double[3]; - - if ( m_Dimension == 0 ) - { - /*int orientation = 0; - - // LOOP FOR EACH SEED - for (int i = 0; i < getPoints()->GetNumberOfPoints(); i++) - { - getPoints()->GetPoint(i, center2); - - this->Filter2D( center2, orientation ); - } - */ - } - else - //if dimension is 3 - i.e. m_Dimension == 1 - { - // LOOP FOR EACH SEED - for ( int i = 0; i < getPoints()->GetNumberOfPoints(); i++ ) - { - getPoints()->GetPoint(i, center2); - - this->Filter3D(center2); - } - } - - emit SegmentationFinished(); - - delete[] center2; - - return NULL; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::ConnectSignals(int iFilterNumber) -{ - QGoFilterSemiAutoBase::ConnectSignals(iFilterNumber); - - // connect specific - QObject::connect( getWidget(), SIGNAL( TreshMin(int) ), - this, SLOT( setTreshMin(int) ) ); - QObject::connect( getWidget(), SIGNAL( TreshMax(int) ), - this, SLOT( setTreshMax(int) ) ); - QObject::connect( getWidget(), SIGNAL( CorrTresh(double) ), - this, SLOT( setCorrTresh(double) ) ); - QObject::connect( getWidget(), SIGNAL( Alpha(double) ), - this, SLOT( setAlpha(double) ) ); - QObject::connect( getWidget(), SIGNAL( Beta(double) ), - this, SLOT( setBeta(double) ) ); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::setTreshMin(int iTreshmin) -{ - m_TreshMin = iTreshmin; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::setTreshMax(int iTreshmax) -{ - m_TreshMax = iTreshmax; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::setCorrTresh(double iCorrTresh) -{ - m_CorrTresh = iCorrTresh; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::setAlpha(double iAlpha) -{ - m_Alpha = iAlpha; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterWatershed::setBeta(double iBeta) -{ - m_Beta = iBeta; -} - -//-------------------------------------------------------------------------- \ No newline at end of file diff --git a/Code/GUI/lib/QGoImageView.cxx b/Code/GUI/lib/QGoImageView.cxx index 22ae78db..de288721 100644 --- a/Code/GUI/lib/QGoImageView.cxx +++ b/Code/GUI/lib/QGoImageView.cxx @@ -46,6 +46,7 @@ #include "vtkViewImage2D.h" // For the seed widget +#include "vtkIntArray.h" #include "vtkConstrainedPointHandleRepresentation.h" #include "vtkSeedWidget.h" #include "vtkImageActorPointPlacer.h" @@ -78,6 +79,7 @@ QGoImageView::QGoImageView(QWidget *iParent) : QWidget(iParent), m_ShowAnnotations(true), m_ShowSplinePlane(true) { + m_Image = vtkImageData::New(); m_Pool = vtkViewImage2DCollection::New(); } @@ -85,30 +87,12 @@ QGoImageView::QGoImageView(QWidget *iParent) : QWidget(iParent), QGoImageView:: ~QGoImageView() { - /* - std::vector::iterator seedWidgetIterator = m_SeedWidget.begin(); - while (seedWidgetIterator != m_SeedWidget.end()) + if(m_Image) { - (*seedWidgetIterator)->Delete(); - ++seedWidgetIterator; + m_Image->Delete(); + m_Image = 0; } - std::vector::iterator - handleIterator = m_Handle.begin(); - while (handleIterator != m_Handle.end()) - { - (*handleIterator)->Delete(); - ++handleIterator; - } - - std::vector::iterator - seedIterator = m_SeedRep.begin(); - while (seedIterator != m_SeedRep.end()) - { - (*seedIterator)->Delete(); - ++seedIterator; - } -*/ if ( m_Pool ) { m_Pool->Delete(); @@ -421,24 +405,18 @@ QGoImageView::InitializeSeedWidget() { int N = this->m_Pool->GetNumberOfItems(); - // Enable seed interaction - this->m_Handle.resize(N); - this->m_SeedRep.resize(N); - this->m_SeedWidget.resize(N); - for ( int i = 0; i < N; ++i ) { - this->m_Handle[i] = vtkSmartPointer< vtkConstrainedPointHandleRepresentation >::New(); - this->m_Handle[i]->GetProperty()->SetColor(1, 0, 0); + this->m_Handle.push_back(vtkSmartPointer< vtkConstrainedPointHandleRepresentation >::New()); + this->m_Handle.back()->GetProperty()->SetColor(1, 0, 0); - this->m_SeedRep[i] = vtkSmartPointer< vtkSeedRepresentation >::New(); - this->m_SeedRep[i]->SetHandleRepresentation(this->m_Handle[i]); + this->m_SeedRep.push_back(vtkSmartPointer< vtkSeedRepresentation >::New()); + this->m_SeedRep.back()->SetHandleRepresentation(this->m_Handle.back()); - this->m_SeedWidget[i] = vtkSmartPointer< vtkSeedWidget >::New(); - this->m_SeedWidget[i]->SetRepresentation(this->m_SeedRep[i]); - this->m_SeedWidget[i]->SetRepresentation(this->m_SeedRep[i]); + this->m_SeedWidget.push_back(vtkSmartPointer< vtkSeedWidget >::New()); + this->m_SeedWidget.back()->SetRepresentation(this->m_SeedRep.back()); - this->m_SeedWidget[i]->SetInteractor( + this->m_SeedWidget.back()->SetInteractor( this->m_Pool->GetItem(i)->GetInteractor() ); // to remove right click interaction in the one click widget @@ -469,47 +447,29 @@ QGoImageView::EnableSeedWidget(bool iEnable) ++it; } } +//------------------------------------------------------------------------- -/// NOTE Returned value has to be deleted //------------------------------------------------------------------------- -vtkPoints * -QGoImageView::GetAllSeeds() +void +QGoImageView:: +GetSeeds(std::vector& iPoints) { - double worldPosition[3]; - - vtkPoints *oPoints = vtkPoints::New(); - - for ( unsigned int i = 0; i < this->m_SeedWidget.size(); i++ ) + for ( unsigned int i = 0; i < 3; i++ ) { + double worldPosition[3]; int N = this->m_SeedRep[i]->GetNumberOfSeeds(); + for ( int j = 0; j < N; j++ ) { // Get World position (may be not accurate if we are between 8 pixels // (3D)) this->m_SeedRep[i]->GetSeedWorldPosition(j, worldPosition); - // Get indexes of the closest point - int *index = this->m_Pool->GetItem(i)->GetImageCoordinatesFromWorldCoordinates(worldPosition); - - // Convert it back into world position - //qDebug() << "SLICE NUMBER: " << this->m_Pool->GetItem(i)->GetSlice(); - double spacing[3] = { 0., 0., 0. }; - this->m_Pool->GetItem(i)->GetInput()->GetSpacing(spacing); - double correctedPosition[3]; - correctedPosition[0] = static_cast< double >( index[0] ) * spacing[0]; - correctedPosition[1] = static_cast< double >( index[1] ) * spacing[1]; - correctedPosition[2] = static_cast< double >( index[2] ) * spacing[2]; - - //qDebug() << "CORRECTED: " << correctedPosition[0] << " - " - // << correctedPosition[1] << " - " - // << correctedPosition[2]; - - oPoints->InsertNextPoint(correctedPosition); - delete[] index; + + iPoints[i]->InsertNextPoint(worldPosition); } } - - return oPoints; } +//------------------------------------------------------------------------- //------------------------------------------------------------------------- void @@ -520,7 +480,7 @@ QGoImageView::ClearAllSeeds() for ( int k = this->m_SeedRep[i]->GetNumberOfSeeds() - 1; k >= 0; --k ) { this->m_SeedWidget[i]->DeleteSeed(k); - this->m_SeedRep[i]->RemoveLastHandle(); + this->m_SeedRep[i]->RemoveHandle(k); } } // automatically remove seeds from the visualization diff --git a/Code/GUI/lib/QGoImageView.h b/Code/GUI/lib/QGoImageView.h index ebcfc3b3..079a8fcf 100644 --- a/Code/GUI/lib/QGoImageView.h +++ b/Code/GUI/lib/QGoImageView.h @@ -222,11 +222,11 @@ class QGOGUILIB_EXPORT QGoImageView:public QWidget void EnableSeedWidget(bool iEnable); - /** - * \brief Get all the seeds positions. - * The seeds have been defined using the one click mode. + /* + * \brief Get seeds ordered by view in a vector + * \param iPoints vector of points containing the seeds */ - vtkPoints * GetAllSeeds(); + void GetSeeds( std::vector& iPoints ); public slots: /** \brief Set background color for all views. diff --git a/Code/GUI/lib/QGoImageView3D.cxx b/Code/GUI/lib/QGoImageView3D.cxx index 239ffb95..0b23ae64 100644 --- a/Code/GUI/lib/QGoImageView3D.cxx +++ b/Code/GUI/lib/QGoImageView3D.cxx @@ -77,6 +77,8 @@ #include "vtkImplicitPlaneWidget.h" #include "vtkPlane.h" +#include "vtkPiecewiseFunction.h" + #include //------------------------------------------------------------------------- @@ -506,8 +508,13 @@ QGoImageView3D::SetupVTKtoQtConnections() void QGoImageView3D::SetImage(vtkImageData *input) { + /** + \todo Nicolas-unecessary checks-temp solution + */ if ( !input ) { + vtkSmartPointer test = vtkSmartPointer::New(); + this->m_Image->ShallowCopy(test); return; } else @@ -515,11 +522,10 @@ QGoImageView3D::SetImage(vtkImageData *input) int dim[3]; input->GetDimensions(dim); - if ( dim[0] + dim[1] + dim[2] > 0 ) - { - m_Initialized = true; - this->m_Image = input; - } + assert ( dim[0] + dim[1] + dim[2] > 0 ); + + m_Initialized = true; + this->m_Image->ShallowCopy(input); } } @@ -956,8 +962,9 @@ QGoImageView3D::RemoveActor(const int & iId, vtkActor *iActor) { if ( iId == 3 ) { - // remove from renderer and Prop3DCollection - m_View3D->RemoveProp(iActor); + // remove from renderer + // should be add/remove view property + m_View3D->GetRenderer()->RemoveActor(iActor); } else { @@ -974,9 +981,8 @@ QGoImageView3D::AddActor(const int & iId, vtkActor *iActor) { if ( iId == 3 ) { - // add to renderer and Prop3DCollection - m_View3D->GetRenderer()->AddViewProp(iActor); - m_View3D->AddActorToProp3DCollection(iActor); + // add to renderer + m_View3D->GetRenderer()->AddActor(iActor); } else { @@ -991,11 +997,7 @@ QGoImageView3D::AddActor(const int & iId, vtkActor *iActor) void QGoImageView3D::SetLookupTable(vtkLookupTable *iLut) { - if ( this->m_Image->GetNumberOfScalarComponents() == 1 ) - { - m_View3D->SetLookupTable(iLut); - } - + m_View3D->SetLookupTable(iLut); QGoImageView::SetLookupTable(iLut); } @@ -1277,20 +1279,23 @@ QGoImageView3D::InitializePlaneWidget() /// \todo Add button to enable/disable tri planar rendering //------------------------------------------------------------------------- void -QGoImageView3D::EnableVolumeRendering(bool iValue) +QGoImageView3D:: +EnableVolumeRendering(const std::vector& iImages, + const std::vector& iOpacities) { - if ( iValue ) - { - //m_View3D->SetTriPlanarRenderingOff(); - m_View3D->SetVolumeRenderingOn(); - } - else - { - //m_View3D->SetTriPlanarRenderingOn(); - m_View3D->SetVolumeRenderingOff(); - } + m_View3D->SetVolumeRenderingOn(iImages, iOpacities); + m_View3D->Render(); } +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +void +QGoImageView3D:: +DisableVolumeRendering() +{ + m_View3D->SetVolumeRenderingOff(); + m_View3D->Render(); +} //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoImageView3D.h b/Code/GUI/lib/QGoImageView3D.h index 7a174358..7e4aa61a 100644 --- a/Code/GUI/lib/QGoImageView3D.h +++ b/Code/GUI/lib/QGoImageView3D.h @@ -70,6 +70,9 @@ class vtkOrientedBoxWidget; // For the plane widget class vtkImplicitPlaneWidget; +// volumre rendering +class vtkPiecewiseFunction; + /** \class QGoImageView3D \brief class for the visualization of 3D Image represented by one vtkImageData*. @@ -213,7 +216,10 @@ public slots: /** * \brief Creates a box in 3d view to allow multiple meshes selection */ - void EnableVolumeRendering(bool iValue); + void EnableVolumeRendering(const std::vector& iImages, + const std::vector& iOpacities); + + void DisableVolumeRendering(); void UpdateCurrentActorSelection(vtkObject *caller); diff --git a/Code/GUI/lib/QGoLineageViewDockWidget.h b/Code/GUI/lib/QGoLineageViewDockWidget.h index 49a200ea..acae096f 100755 --- a/Code/GUI/lib/QGoLineageViewDockWidget.h +++ b/Code/GUI/lib/QGoLineageViewDockWidget.h @@ -35,13 +35,13 @@ #ifndef __QGoLineageViewDockWidget_h #define __QGoLineageViewDockWidget_h - +#include #include #include "QGoDockWidget.h" +#include "QGoGUILibConfigure.h" //#include "ui_LineageViewDockWidget.h" -class QGoLineageViewDockWidget: - public QGoDockWidget//, +class QGOGUILIB_EXPORT QGoLineageViewDockWidget: public QGoDockWidget//, //protected Ui::LineageViewDockWidget { Q_OBJECT @@ -54,11 +54,12 @@ public slots: void ColorCodeLineagesByOriginalColor(bool); signals: - void ChangeDivisionsColorCode( const char* ); + void ChangeDivisionsColorCode(const QString &); protected: void SetUpUi(); QRadioButton* m_depthLineage; QRadioButton* m_real; + }; #endif diff --git a/Code/GUI/lib/QGoMeshSeedSegmentation.cxx b/Code/GUI/lib/QGoMeshSeedSegmentation.cxx deleted file mode 100644 index 309e8826..00000000 --- a/Code/GUI/lib/QGoMeshSeedSegmentation.cxx +++ /dev/null @@ -1,118 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ -#include "QGoMeshSeedSegmentation.h" - -// To store the seeds -#include "vtkPoints.h" - -// usefull to access internal methods -#include "QGoSeedBaseWidget.h" - -// ALGOS -// LevelSet algorithm -#include "QGoFilterChanAndVese.h" -#include "QGoFilterShape.h" -#include "QGoFilterWatershed.h" - -//-------------------------------------------------------------------------- -QGoMeshSeedSegmentation::QGoMeshSeedSegmentation(QWidget *parentW, - vtkPoints *seeds, - std::vector< vtkSmartPointer< vtkImageData > > *iOriginalImage, - int iSampling) : - QGoSeedSegmentationBase(parentW, seeds, iSampling), - m_OriginalImage(iOriginalImage) -{ - // ADD ARG IN CONSTRUCTORS TO ENABLE SAMPLING - - int filter = 0; - -//============================================================================= -//============================================================================= - - //Add new segmentation method - - m_ShapeFilter = new QGoFilterShape(this, iSampling); // 3 i.e. 3D, to create a - // mesh - filter = m_BaseAlgorithmSegmentationWidget->GetNumberOfFilters(); - m_BaseAlgorithmSegmentationWidget->AddFilter( m_ShapeFilter->getName() ); - m_ShapeFilter->getWidget()->setParent(m_BaseAlgorithmSegmentationWidget); - m_ShapeFilter->setPoints( getSeed() ); - m_ShapeFilter->setOriginalImageMC(m_OriginalImage); - m_BaseAlgorithmSegmentationWidget->GetFrame()->addWidget( m_ShapeFilter->getWidget() ); - m_ShapeFilter->ConnectSignals(filter); - - //============================================================================= - - //Add new segmentation method - m_LevelSetfilter = new QGoFilterChanAndVese(this, iSampling); // 3 i.e. 3D, to - // create a mesh - filter = m_BaseAlgorithmSegmentationWidget->GetNumberOfFilters(); - m_BaseAlgorithmSegmentationWidget->AddFilter( m_LevelSetfilter->getName() ); - m_LevelSetfilter->getWidget()->setParent(m_BaseAlgorithmSegmentationWidget); - m_LevelSetfilter->setPoints( getSeed() ); - m_LevelSetfilter->setOriginalImageMC(m_OriginalImage); - m_BaseAlgorithmSegmentationWidget->GetFrame()->addWidget( m_LevelSetfilter->getWidget() ); - m_LevelSetfilter->ConnectSignals(filter); - -//============================================================================= - - //Add new segmentation method - m_Watershed = new QGoFilterWatershed(this, iSampling); // 3 i.e. 3D, to - // create a mesh - filter = m_BaseAlgorithmSegmentationWidget->GetNumberOfFilters(); - m_BaseAlgorithmSegmentationWidget->AddFilter( m_Watershed->getName() ); - m_Watershed->getWidget()->setParent(m_BaseAlgorithmSegmentationWidget); - m_Watershed->setPoints( getSeed() ); - m_Watershed->setOriginalImageMC(m_OriginalImage); - m_BaseAlgorithmSegmentationWidget->GetFrame()->addWidget( m_Watershed->getWidget() ); - m_Watershed->ConnectSignals(filter); - -//============================================================================= -//============================================================================= - - m_BaseAlgorithmSegmentationWidget->Initialize(); - -//============================================================================= -//============================================================================= -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QGoMeshSeedSegmentation:: -~QGoMeshSeedSegmentation() -{ -} - -//-------------------------------------------------------------------------- \ No newline at end of file diff --git a/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.cxx b/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.cxx deleted file mode 100644 index 6005c42b..00000000 --- a/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.cxx +++ /dev/null @@ -1,251 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#include "QGoMeshSegmentationBaseDockWidget.h" - -// base widgets -#include "QGoMeshSeedSegmentation.h" - -//---------------------------------------------------------------------------// -QGoMeshSegmentationBaseDockWidget::QGoMeshSegmentationBaseDockWidget( - QWidget *iParent, - vtkPoints *seeds, - std::vector< vtkSmartPointer< vtkImageData > > * - iOriginalImage) : - QGoDockWidget(iParent) -{ - this->setupUi(this); - - this->setWindowTitle( QString::fromUtf8("Mesh Editing") ); - - QIcon MeshSegmentationIcon; - //MeshSegmentationIcon.addPixmap(QPixmap(QString::fromUtf8(":/fig/meshOneClick.png")), - // QIcon::Normal, QIcon::Off); - MeshSegmentationIcon.addPixmap(QPixmap( QString::fromUtf8(":/fig/MeshEditing.png") ), - QIcon::Normal, QIcon::Off); - - this->m_ToggleAction->setIcon(MeshSegmentationIcon); - this->m_ToggleAction->setToolTip( tr("Mesh Editing") ); - this->m_ToggleAction->setStatusTip( tr("Create meshes manually, semi-automatically or automatically") ); - - // update interactor behavior - QObject::connect( this->mode, SIGNAL( activated(int) ), - this, SLOT( SegmentationMethod(int) ) ); - - // ADD BASE WIDGETS FOR EACH SEGMENTATION MODE - - //---------------------------------------------------------------- - // - // NOW WE HAVE TO FILL THE BASE DOCK WIDGET WITH WIDGETS - // 1 widget for each segmentation type - // Create a method do the basic connections with a dockwidget - //---------------------------------------------------------------- - - //---------------------------------------------------------------- - // Manual segmentation - //---------------------------------------------------------------- - - m_MeshManualSegmentation = - // 0 2D - // 1 3D - // 2 2D+3D - new QGoMeshSeedSegmentation(this, seeds, iOriginalImage, 2); - - QWidget *manual_widget = m_MeshManualSegmentation->getWidget(); - - gridLayout->addWidget(manual_widget, 1, 0, 1, -1); - manual_widget->setVisible(false); - - // connect show/hide - QObject::connect( this, SIGNAL( ManualSegmentationActivated(bool) ), - manual_widget, SLOT( setVisible(bool) ) ); - - // connect semi-automatic segmentation specific signals - QObject::connect( m_MeshManualSegmentation, SIGNAL( UpdateSeeds() ), - this, SIGNAL( UpdateSeeds() ) ); - - QObject::connect( m_MeshManualSegmentation, SIGNAL( CreateCorrespondingMesh(int) ), - this, SIGNAL( CreateCorrespondingMesh(int) ) ); - - QObject::connect( m_MeshManualSegmentation, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ), - this, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ) ); - QObject::connect( m_MeshManualSegmentation, SIGNAL( SegmentationFinished() ), - this, SIGNAL( ClearAllSeeds() ) ); - - //---------------------------------------------------------------- - // Semi auto segmentation ( i.e. algo with seed) - //---------------------------------------------------------------- - - m_MeshSemiAutoSegmentation = - new QGoMeshSeedSegmentation(this, seeds, iOriginalImage, 1); - - QWidget *semi_auto_widget = m_MeshSemiAutoSegmentation->getWidget(); - - gridLayout->addWidget(semi_auto_widget, 1, 0, 1, -1); - semi_auto_widget->setVisible(false); - - // connect show/hide - QObject::connect( this, SIGNAL( SemiAutoSegmentationActivated(bool) ), - semi_auto_widget, SLOT( setVisible(bool) ) ); - - // connect semi-automatic segmentation specific signals - QObject::connect( m_MeshSemiAutoSegmentation, SIGNAL( UpdateSeeds() ), - this, SIGNAL( UpdateSeeds() ) ); - QObject::connect( m_MeshSemiAutoSegmentation, SIGNAL( MeshCreated(vtkPolyData *, int) ), - this, SIGNAL( SaveAndVisuMesh(vtkPolyData *, int) ) ); - QObject::connect( m_MeshSemiAutoSegmentation, SIGNAL( SegmentationFinished() ), - this, SIGNAL( ClearAllSeeds() ) ); - - // set default segmentation as semi auto segmentation - this->mode->setCurrentIndex(1); - gridLayout->setSizeConstraint(QLayout::SetFixedSize); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -QGoMeshSegmentationBaseDockWidget:: -~QGoMeshSegmentationBaseDockWidget() -{ -} - -//---------------------------------------------------------------------------// -// one segmentation to another -//---------------------------------------------------------------------------// -void -QGoMeshSegmentationBaseDockWidget::SegmentationMethod(int iSegmentationMethod) -{ - emit ManualSegmentationActivated(false); - emit SemiAutoSegmentationActivated(false); - emit AutoSegmentationActivated(false); - - switch ( iSegmentationMethod ) - { - case 0: - emit ManualSegmentationActivated(true); - break; - case 1: - emit SemiAutoSegmentationActivated(true); - break; - case 2: - emit AutoSegmentationActivated(true); - break; - default: - emit ReinitializeInteractorActivated(true); - break; - } -} - -//---------------------------------------------------------------------------// -// show hide widget -//---------------------------------------------------------------------------// -void -QGoMeshSegmentationBaseDockWidget::interactorBehavior(bool iSegmentationMethod) -{ - if ( iSegmentationMethod ) - { - switch ( mode->currentIndex() ) - { - case 0: - emit ManualSegmentationActivated(iSegmentationMethod); - break; - case 1: - emit SemiAutoSegmentationActivated(iSegmentationMethod); - break; - case 2: - emit AutoSegmentationActivated(iSegmentationMethod); - break; - default: - break; - } - } - else - { - emit ManualSegmentationActivated(false); - emit SemiAutoSegmentationActivated(false); - emit AutoSegmentationActivated(false); - emit ReinitializeInteractorActivated(true); - - this->setVisible(false); - } -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoMeshSegmentationBaseDockWidget::SetChannel(int iChannel, const QString & iText) -{ - QString input; - - if ( !iText.isEmpty() ) - { - input = iText; - } - else - { - input = QString("Channel %1").arg(iChannel); - } - - m_MeshManualSegmentation->SetChannel(iChannel, input); - m_MeshSemiAutoSegmentation->SetChannel(iChannel, input); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoMeshSegmentationBaseDockWidget::SetCurrentChannel(unsigned int iChannel) -{ - m_MeshManualSegmentation->SetCurrentChannel(iChannel); - m_MeshSemiAutoSegmentation->SetCurrentChannel(iChannel); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoMeshSegmentationBaseDockWidget::SetNumberOfChannels(int iNumberOfChannels) -{ - m_MeshManualSegmentation->SetNumberOfChannels(iNumberOfChannels); - m_MeshSemiAutoSegmentation->SetNumberOfChannels(iNumberOfChannels); -} - -//---------------------------------------------------------------------------// -/*void -QGoMeshSegmentationBaseDockWidget::Initialize() -{ - //m_ContourManualSegmentation->GenerateContourRepresentationProperties(true); -} -*/ diff --git a/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.h b/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.h deleted file mode 100644 index 7d2e2dcb..00000000 --- a/Code/GUI/lib/QGoMeshSegmentationBaseDockWidget.h +++ /dev/null @@ -1,156 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#ifndef __QGoMeshSegmentationBaseDockWidget_h -#define __QGoMeshSegmentationBaseDockWidget_h - -#include - -#include "vtkPoints.h" -#include "vtkImageData.h" -#include "vtkPolyData.h" -#include "vtkSmartPointer.h" -#include "QGoDockWidget.h" - -// base widgets -class QGoMeshSeedSegmentation; - -#include "ui_SegmentationDockWidgetBase.h" - -/** - * \class QGoMeshSegmentationBaseDockWidget - * \ingroup QGoMesh - * \brief Base dockwidget for the meshes segmentation -*/ - -class QGoMeshSegmentationBaseDockWidget: - public QGoDockWidget, - protected Ui::SegmentationDockWidgetBase -{ - Q_OBJECT -public: - explicit QGoMeshSegmentationBaseDockWidget( - QWidget *iParent = 0, - vtkPoints *seeds = 0, - std::vector< vtkSmartPointer > *iOriginalImage = 0); - - virtual ~QGoMeshSegmentationBaseDockWidget(); - - /** - * \brief Specify on which one the segmentation will be applied since the input - * data is multichannel. - * \param[in] iChannel Channel on which want we want to apply the segmentation - * algorithm - * \param[in] iText Name of the channels - */ - void SetChannel(int iChannel, const QString & iText = QString()); - - void SetCurrentChannel(unsigned int iChannel); - - void SetNumberOfChannels(int iNumberOfChannels); - -public slots: -/** - * \brief Slot to know if we are in Manual, Semi Automatic ou Automatic segmentation - */ - void SegmentationMethod(int); - - /** - * \brief Slot to update the interactor behavior, depending on if we are - * in Manual, Semi Automatic ou Automatic segmentation - */ - void interactorBehavior(bool); - -signals: -/** - * \brief Signal sent when we enter/leave the Manual segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void ManualSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent when we enter/leave the Semi Automatic segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void SemiAutoSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent when we enter/leave the Automatic segmentation mode - * \param[in] iActivated true: enter, false: leave - */ - void AutoSegmentationActivated(bool iActivated); - - /** - * \brief Signal sent to go to the default interactor behavior - */ - void ReinitializeInteractorActivated(bool); - - // manual segmentation specific signals - /** - * \brief Signal sent if we want to create a structure mesh composed of - * multiple contours - */ - void CreateCorrespondingMesh(int); - - /** - * \brief Signal sent to add a contour to an mesh created with CreateCorrespondingMesh() - */ - void AddContourForMeshToContours(vtkPolyData *); - - // semi automatic signals - /** - * \brief Signal sent before starting a "seed segmentation" to update the - * value of the seeds - */ - void UpdateSeeds(); - - /** - * \brief Signal sent after a seed segmentation to save the contour and - * update the visualization - */ - void SaveAndVisuMesh(vtkPolyData *, int); - - /** - * \brief Signal sent after a seed segmentation to delete the seeds - */ - void ClearAllSeeds(); - -private: - QGoMeshSeedSegmentation *m_MeshManualSegmentation; - QGoMeshSeedSegmentation *m_MeshSemiAutoSegmentation; - - Q_DISABLE_COPY(QGoMeshSegmentationBaseDockWidget); -}; - -#endif diff --git a/Code/GUI/lib/QGoNavigationDockWidget.cxx b/Code/GUI/lib/QGoNavigationDockWidget.cxx index ce5191fd..9720d075 100644 --- a/Code/GUI/lib/QGoNavigationDockWidget.cxx +++ b/Code/GUI/lib/QGoNavigationDockWidget.cxx @@ -38,6 +38,11 @@ #include #include +#include +#include + +#include + QGoNavigationDockWidget:: QGoNavigationDockWidget( QWidget *iParent, const GoFigure::TabDimensionType & iDim ) : @@ -65,8 +70,6 @@ QGoNavigationDockWidget( QWidget *iParent, this->TSliceLbl->setVisible(false); this->TSliceSpinBox->setVisible(false); - this->line->setVisible(false); - break; } case GoFigure::TWO_D_WITH_T: @@ -106,14 +109,14 @@ QGoNavigationDockWidget( QWidget *iParent, QObject::connect( this->TSliceSpinBox, SIGNAL( valueChanged(int) ), this, SIGNAL( TSliceChanged(int) ) ); - QObject::connect( this->AllChannelsBtn, SIGNAL( toggled(bool) ), - this, SIGNAL( ShowAllChannelsChanged(bool) ) ); - - QObject::connect( this->ChannelComboBox, SIGNAL( currentIndexChanged(int) ), - this, SIGNAL( ShowOneChannelChanged(int) ) ); - + // doppler view specific widgets + this->channelLabel->hide(); + this->channelName->hide(); this->stepLabel->hide(); this->step->hide(); + this->tLabel->hide(); + this->t->hide(); + } //------------------------------------------------------------------------- @@ -158,55 +161,6 @@ void QGoNavigationDockWidget::SetTSlice(int iSlice) //------------------------------------------------------------------------- -//------------------------------------------------------------------------- -void -QGoNavigationDockWidget::SetNumberOfChannels(const unsigned int & iN) -{ - if ( iN < 2 ) - { - this->line->setVisible(false); - this->AllChannelsBtn->setVisible(false); - this->OneChannelBtn->setVisible(false); - this->ChannelComboBox->setVisible(false); - } - else - { - this->line->setVisible(true); - this->AllChannelsBtn->setVisible(true); - this->OneChannelBtn->setVisible(true); - this->ChannelComboBox->setMaxCount(iN); - } -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoNavigationDockWidget::SetChannel(const unsigned int & i, const QString & iText) -{ - QString input; - - if ( !iText.isEmpty() ) - { - input = iText; - } - else - { - input = QString("Channel %1").arg(i); - } - this->ChannelComboBox->insertItem(i, input); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoNavigationDockWidget::SetCurrentChannel(unsigned int iChannel) -{ - this->ChannelComboBox->setCurrentIndex(iChannel); -} -//------------------------------------------------------------------------- - //------------------------------------------------------------------------- void QGoNavigationDockWidget::SetXMinimumAndMaximum(const int & iMin, const int & iMax) { @@ -216,7 +170,6 @@ void QGoNavigationDockWidget::SetXMinimumAndMaximum(const int & iMin, const int this->XSliceSpinBox->setMaximum(iMax); this->XSliceSlider->setMinimum(iMin); this->XSliceSlider->setMaximum(iMax); - //this->MinXSlicelbl->setText(ConvertToString(iMin).c_str()); this->MinXSlicelbl->setText( tr("%1").arg(iMin) ); this->MaxXSlicelbl->setText( tr("%1").arg(iMax) ); } @@ -296,11 +249,14 @@ void QGoNavigationDockWidget::SetTMinimumAndMaximum(const int & iMin, const int this, SIGNAL( ModeChanged(int) ) ); QObject::connect( this->ModeComboBox, SIGNAL( activated(int) ), - this, SLOT( StepVisibility(int) ) ); + this, SLOT( UpdateWidget(int) ) ); QObject::connect( this->step, SIGNAL( valueChanged(int) ), this, SIGNAL( StepChanged(int) ) ); + QObject::connect( this->t, SIGNAL( valueChanged(int) ), + this, SIGNAL( DopplerSizeChanged(int) ) ); + // shortcuts to move through time (void)new QShortcut( QKeySequence( tr("Ctrl+Z", "Move to previous") ), @@ -310,77 +266,202 @@ void QGoNavigationDockWidget::SetTMinimumAndMaximum(const int & iMin, const int } else { - this->line_2->hide(); this->TSliceLbl->hide(); this->TSliceSpinBox->hide(); this->TSliceSlider->hide(); this->MinTSlicelbl->hide(); this->MaxTSlicelbl->hide(); this->ModeComboBox->hide(); + this->channelLabel->hide(); + this->channelName->hide(); this->stepLabel->hide(); this->step->hide(); + this->tLabel->hide(); + this->t->hide(); } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -int QGoNavigationDockWidget::GetCurrentChannel() const +void QGoNavigationDockWidget::MoveToPreviousTimePoint() { - return this->ChannelComboBox->currentIndex(); + if ( TSliceSpinBox->value() > TSliceSpinBox->minimum() ) + { + emit TSliceChanged(TSliceSpinBox->value() - 1); + } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -bool QGoNavigationDockWidget::ShowAllChannels() const +void QGoNavigationDockWidget::MoveToNextTimePoint() { - return this->AllChannelsBtn->isChecked(); + if ( TSliceSpinBox->value() < TSliceSpinBox->maximum() ) + { + emit TSliceChanged(TSliceSpinBox->value() + 1); + } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -QString QGoNavigationDockWidget::GetChannelName(const int & iIdx) +void QGoNavigationDockWidget::UpdateWidget(int iStep) { - return this->ChannelComboBox->itemText(iIdx); + if ( iStep == 0 ) + { + this->channelLabel->hide(); + this->channelName->hide(); + this->stepLabel->hide(); + this->step->hide(); + this->tLabel->hide(); + this->t->hide(); + } + else + { + this->channelLabel->show(); + this->channelName->show(); + this->stepLabel->show(); + this->step->show(); + this->tLabel->show(); + this->t->show(); + } } +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +void +QGoNavigationDockWidget:: +AddChannel(const QString& iName, const QColor& iColor, const unsigned int& iNumber, + const bool& iChecked) +{ + // create check box + colored push button + QCheckBox *checkBox1 = new QCheckBox(iName, this); + checkBox1->setObjectName(iName); + checkBox1->setChecked(iChecked); + QPushButton *pushButton = new QPushButton(this); + pushButton->setObjectName(iName); + QString style = "background: rgb(%1, %2, %3);"; + pushButton->setStyleSheet( + style.arg(iColor.red()).arg(iColor .green()).arg(iColor.blue())); + // pushButton->setStyleSheet("QPushButton { background: red } "); + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(checkBox1); + layout->addWidget(pushButton); + // to be modified - 7 + this->gridLayout_2->addLayout(layout, 7+iNumber, 0, 0); + //create signals connections + QObject::connect( checkBox1, SIGNAL( clicked(bool) ), + this, SLOT( visibilityChanged(bool) ) ); + QObject::connect( pushButton, SIGNAL( pressed() ), + this, SLOT( changeColor() ) ); + + // vector of widget so we can remove it from layout efficiently + m_ListCheckBoxes.push_back(checkBox1); + m_ListPushButtons.push_back(pushButton); +} //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoNavigationDockWidget::MoveToPreviousTimePoint() +void +QGoNavigationDockWidget:: +visibilityChanged(bool iVisibility) { - if ( TSliceSpinBox->value() > TSliceSpinBox->minimum() ) + emit visibilityChanged(QObject::sender()->objectName(), iVisibility); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoNavigationDockWidget:: +VisibilityListChannels(const bool& iVisibility) +{ + QList::iterator it = m_ListCheckBoxes.begin(); + while(it != m_ListCheckBoxes.end()) { - emit TSliceChanged(TSliceSpinBox->value() - 1); + (*it)->setVisible(iVisibility); + (*it)->setChecked(iVisibility); + ++it; + } + + QList::iterator it2 = m_ListPushButtons.begin(); + while(it2 != m_ListPushButtons.end()) + { + (*it2)->setVisible(iVisibility); + ++it2; } } +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +void +QGoNavigationDockWidget:: +AddDoppler(const QString& iName, const QColor& iColor, const unsigned int& iNumber, + const bool& iChecked) +{ + // create check box + colored push button + QCheckBox *checkBox1 = new QCheckBox(iName, this); + checkBox1->setObjectName(iName); + checkBox1->setChecked(iChecked); + QPushButton *pushButton = new QPushButton(this); + pushButton->setObjectName(iName); + QString style = "background: rgb(%1, %2, %3);"; + pushButton->setStyleSheet( + style.arg(iColor.red()).arg(iColor .green()).arg(iColor.blue())); + // pushButton->setStyleSheet("QPushButton { background: red } "); + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(checkBox1); + layout->addWidget(pushButton); + // to be modified - 7 + this->gridLayout_2->addLayout(layout, 7+iNumber, 0, 0); + //create signals connections + QObject::connect( checkBox1, SIGNAL( clicked(bool) ), + this, SLOT( visibilityChanged(bool) ) ); + QObject::connect( pushButton, SIGNAL( pressed() ), + this, SLOT( changeColor() ) ); + // more signals for modify LUT + + // vector of widget so we can remove it from layout efficiently + m_ListDoppler.push_back(checkBox1); + m_ListDoppler.push_back(pushButton); +} //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoNavigationDockWidget::MoveToNextTimePoint() +void +QGoNavigationDockWidget:: +VisibilityListDoppler(const bool& iVisibility) { - if ( TSliceSpinBox->value() < TSliceSpinBox->maximum() ) - { - emit TSliceChanged(TSliceSpinBox->value() + 1); - } + QList::iterator it = m_ListDoppler.begin(); + while(it != m_ListDoppler.end()) + { + (*it)->setVisible(iVisibility); + ++it; + } } +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +void +QGoNavigationDockWidget:: +setChannelName(QString iChannelName) +{ + this->channelName->setText(iChannelName); +} //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoNavigationDockWidget::StepVisibility(int iStep) +void +QGoNavigationDockWidget:: DeleteDopplerWidgets() { - if ( iStep == 0 ) - { - this->step->hide(); - this->stepLabel->hide(); - } - else - { - this->step->show(); - this->stepLabel->show(); - } + qDeleteAll(m_ListDoppler.begin(), m_ListDoppler.end()); + m_ListDoppler.clear(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoNavigationDockWidget:: changeColor() +{ + emit openTransferFunctionEditor(QObject::sender()->objectName()); } diff --git a/Code/GUI/lib/QGoNavigationDockWidget.h b/Code/GUI/lib/QGoNavigationDockWidget.h index 16ec1c33..c0a33d16 100644 --- a/Code/GUI/lib/QGoNavigationDockWidget.h +++ b/Code/GUI/lib/QGoNavigationDockWidget.h @@ -45,6 +45,9 @@ class QHBoxLayout; class QVBoxLayout; +class QPushButton; +class QCheckBox; + /** \class QGoNavigationDockWidget * \brief Dock Widget for browsing images (changing slice, time point...) * \ingroup GUI @@ -63,17 +66,6 @@ class QGOGUILIB_EXPORT QGoNavigationDockWidget: /** \brief Destructor */ ~QGoNavigationDockWidget(); - /** \brief Set the number of channels */ - void SetNumberOfChannels(const unsigned int & iN); - - /** \brief Set channel name - * \param[in] i channel id - * \param[in] iText channel name - */ - void SetChannel( const unsigned int & i, const QString & iText = QString() ); - - void SetCurrentChannel(unsigned int iChannel); - /** \brief Set the extent of the images in the X direction * \param[in] iMin XMin * \param[in] iMax XMax @@ -98,14 +90,20 @@ class QGOGUILIB_EXPORT QGoNavigationDockWidget: */ void SetTMinimumAndMaximum(const int & iMin, const int & iMax); - /** \brief Get the selected channel id */ - int GetCurrentChannel() const; + // new channels representation + void AddChannel(const QString& iName, const QColor& iColor,const unsigned int& iNumber, + const bool& iChecked); + + void VisibilityListChannels(const bool& iVisibility); + + void AddDoppler(const QString& iName, const QColor& iColor,const unsigned int& iNumber, + const bool& iChecked); + + void VisibilityListDoppler(const bool& iVisibility); - /** \brief Select and show all channels */ - bool ShowAllChannels() const; + void setChannelName(QString iChannelName); - /** \brief Get the channel name */ - QString GetChannelName(const int &); + void DeleteDopplerWidgets(); public slots: /** Set X Slice */ @@ -126,13 +124,13 @@ public slots: /** Move to the next time point using shortcuts */ void MoveToNextTimePoint(); - void StepVisibility(int); + void UpdateWidget(int); -signals: - void ShowAllChannelsChanged(bool iChanged); + void visibilityChanged(bool); - void ShowOneChannelChanged(int Channel); + void changeColor(); +signals: void XSliceChanged(int Slice); void YSliceChanged(int Slice); @@ -145,7 +143,18 @@ public slots: void StepChanged(int Step); + void visibilityChanged(QString, bool); + + void openTransferFunctionEditor(QString); + + void DopplerSizeChanged(int iSize); + protected: GoFigure::TabDimensionType m_Dimension; + +private: + QList m_ListPushButtons; + QList m_ListCheckBoxes; + QList m_ListDoppler; }; #endif diff --git a/Code/GUI/lib/QGoPrintDatabase.cxx b/Code/GUI/lib/QGoPrintDatabase.cxx index dcae47d0..c7b290a1 100644 --- a/Code/GUI/lib/QGoPrintDatabase.cxx +++ b/Code/GUI/lib/QGoPrintDatabase.cxx @@ -259,7 +259,8 @@ QGoPrintDatabase::SaveContoursFromVisuInDB(unsigned int iXCoordMin, unsigned int ContourID; if ( !this->m_ReeditMode ) { - ContourID = this->m_ContoursManager->SaveNewContourFromVisu(iXCoordMin, + ContourID = this->m_ContoursManager->SaveNewContourFromVisu(iTCoord, + iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, @@ -298,7 +299,7 @@ QGoPrintDatabase::SaveMeshFromVisuInDB(unsigned int iXCoordMin, unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, - int iTShift, + int iTCoord, vtkPolyData *iMeshNodes, GoFigureMeshAttributes *iMeshAttributes) { @@ -311,21 +312,43 @@ QGoPrintDatabase::SaveMeshFromVisuInDB(unsigned int iXCoordMin, /** \todo print a different message if several meshes are created at the same timepoint*/ QString MessageToPrint = this->m_MeshesManager->CheckExistingMeshesForTheTrack(TrackID, - this->m_DatabaseConnector, iTShift); + this->m_DatabaseConnector, + iTCoord); if ( MessageToPrint != "" ) { emit PrintMessage(MessageToPrint); } - unsigned int NewMeshID = this->m_MeshesManager->SaveNewMeshFromVisu(iXCoordMin, + std::list MotherTrackDivisionToUpdate; + MessageToPrint = this->m_TracksManager->CheckMeshCanBeAddedToTrack(this->m_DatabaseConnector, TrackID, + *this->m_SelectedTimePoint, MotherTrackDivisionToUpdate).c_str(); + unsigned int NewMeshID; + if (!MessageToPrint.isEmpty() ) + { + emit PrintMessage(MessageToPrint); + NewMeshID = this->m_MeshesManager->SaveNewMeshWithNoTrackFromVisu(iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, - iTShift, + iTCoord, iMeshNodes, this->m_DatabaseConnector, iMeshAttributes); + this->CloseDBConnection(); + return; + } + + NewMeshID = this->m_MeshesManager->SaveNewMeshFromVisu(iXCoordMin, + iYCoordMin, + iZCoordMin, + iXCoordMax, + iYCoordMax, + iZCoordMax, + iTCoord, + iMeshNodes, + this->m_DatabaseConnector, + iMeshAttributes); std::list< unsigned int > ListNewMeshes; ListNewMeshes.push_back(NewMeshID); //here update the CurrentElement for trackContainer with the data from the @@ -336,6 +359,10 @@ QGoPrintDatabase::SaveMeshFromVisuInDB(unsigned int iXCoordMin, ListNewMeshes); this->m_TracksManager->UpdateBoundingBoxes(this->m_DatabaseConnector, trackIDs); + if (!MotherTrackDivisionToUpdate.empty() ) + { + this->m_TracksManager->UpdateDivisions(MotherTrackDivisionToUpdate); + } } else //for mesh generated from contours: { @@ -359,8 +386,8 @@ QGoPrintDatabase::SaveMeshFromVisuInDB(unsigned int iXCoordMin, //------------------------------------------------------------------------- void QGoPrintDatabase::SaveNewMeshForMeshToContours(int iNumberOfContours) { - this->OpenDBConnection(); - unsigned int TrackID = this->m_TraceSettingsWidget->GetCurrentSelectedCollectionID(); + /*this->OpenDBConnection(); + unsigned int TrackID = this->m_TraceWidget->GetCurrentSelectedCollectionID(); QString MessageToPrint = this->m_MeshesManager->CheckExistingMeshesForTheTrack(TrackID, this->m_DatabaseConnector); if ( MessageToPrint != "" ) @@ -389,7 +416,7 @@ void QGoPrintDatabase::SaveNewMeshForMeshToContours(int iNumberOfContours) // normally, the new added mesh from create // mesh with no //contour will add the new meshid in the TSList... - this->CloseDBConnection(); + this->CloseDBConnection();*/ } //------------------------------------------------------------------------- @@ -404,13 +431,14 @@ unsigned int QGoPrintDatabase::SaveNewContourForMeshToContours( unsigned int iZCoordMax, vtkPolyData *iTraceNodes) { - this->OpenDBConnection(); + /*this->OpenDBConnection(); unsigned int ContourID = this->m_ContoursManager->SaveNewContourFromVisu( iXCoordMin, iYCoordMin, iZCoordMin, iXCoordMax, iYCoordMax, iZCoordMax, iTraceNodes, this->m_DatabaseConnector, 0); this->CloseDBConnection(); - return ContourID; + return ContourID;*/ + return 0; } //------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoPrintDatabase.h b/Code/GUI/lib/QGoPrintDatabase.h index db9ea619..64ee8699 100644 --- a/Code/GUI/lib/QGoPrintDatabase.h +++ b/Code/GUI/lib/QGoPrintDatabase.h @@ -131,7 +131,7 @@ class QGOGUILIB_EXPORT QGoPrintDatabase:public QGoDockWidget unsigned int iXCoordMax, unsigned int iYCoordMax, unsigned int iZCoordMax, - int iTShift, + int iTCoord, vtkPolyData *iMeshNodes, GoFigureMeshAttributes *iMeshAttributes); /** @@ -524,6 +524,7 @@ public slots: if ( !ListCollectionsIDs.empty() || !lineage ) { + this->OpenDBConnection(); //in some cases the DeleteCheckedTraces closes the connection iCollectionManager->UpdateBoundingBoxes(this->m_DatabaseConnector, ListCollectionsIDs); } this->CloseDBConnection(); diff --git a/Code/GUI/lib/QGoSeedBaseWidget.cxx b/Code/GUI/lib/QGoSeedBaseWidget.cxx deleted file mode 100644 index 441352c0..00000000 --- a/Code/GUI/lib/QGoSeedBaseWidget.cxx +++ /dev/null @@ -1,179 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#include "QGoSeedBaseWidget.h" - -#include -#include - -//---------------------------------------------------------------------------// -QGoSeedBaseWidget::QGoSeedBaseWidget(QWidget *iParent, int iSampling) : QWidget(iParent) -{ - this->setupUi(this); - - // Connect signals - QObject::connect( this->filter, SIGNAL( activated(int) ), - this, SIGNAL( Filter(int) ) ); - - QObject::connect( this->apply, SIGNAL( pressed() ), this, SIGNAL( Apply() ) ); - - QObject::connect( this->radius, SIGNAL( valueChanged(double) ), - this, SIGNAL( Radius(double) ) ); - - QObject::connect( this->channel, SIGNAL( activated(int) ), - this, SIGNAL( Channel(int) ) ); - - // shortcut to the "Apply" button - (void)new QShortcut( QKeySequence( tr("X", "Apply") ), this, SIGNAL( Apply() ) ); - - // About the sampling button... - if ( iSampling == 2 ) - { - // add the button and connect it - QLabel *samplingLabel = new QLabel(this); - samplingLabel->setObjectName( QString::fromUtf8("samplingLabel") ); - samplingLabel->setText( - QApplication::translate("SegmentationSeedBaseWidget", "Sampling", - 0, QApplication::UnicodeUTF8) ); - gridLayout->addWidget(samplingLabel, 3, 0, 1, 2); - // Add the spin box - QSpinBox *sampling = new QSpinBox(this); - sampling->setObjectName( QString::fromUtf8("sampling") ); - sampling->setMinimum(1); - sampling->setValue(3); - gridLayout->addWidget(sampling, 3, 2, 1, 1); - - QObject::connect( sampling, SIGNAL( valueChanged(int) ), - this, SIGNAL( Sampling(int) ) ); - } - - gridLayout->removeWidget(apply); - gridLayout->addWidget(apply, 5, 0, 1, -1); - - groupBox = new ctkCollapsibleGroupBox(QObject::tr("Advanced Parameters"), this); - gridLayout->addWidget(groupBox, 4, 0, 1, -1); - //gridLayout->setSizeConstraint(QLayout::SetFixedSize); - groupBox->setCollapsed(true); - - vbox = new QGridLayout; - groupBox->setLayout(vbox); - - QObject::connect( this->groupBox, SIGNAL( clicked(bool) ), - this, SIGNAL( Clicked(bool) ) ); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -QGoSeedBaseWidget:: -~QGoSeedBaseWidget() -{ -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoSeedBaseWidget::AddChannel(int iPosition, QString iChannel) -{ - this->channel->insertItem(iPosition, iChannel); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoSeedBaseWidget::SetChannel( unsigned int iChannel) -{ - this->channel->setCurrentIndex(iChannel); - // update the channel in the filter - emit Channel(iChannel); -} -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// - -void -QGoSeedBaseWidget::setNumberOfChannels(int iNumberOfChannels) -{ - //qDebug() << "setNumberOfChannels" << iNumberOfChannels; - channel->clear(); - channel->setMaxCount(iNumberOfChannels); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// - -void -QGoSeedBaseWidget::AddFilter(QString iFilter) -{ - filter->addItem(iFilter); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -int -QGoSeedBaseWidget::GetNumberOfFilters() -{ - return filter->count(); -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -QGridLayout * -QGoSeedBaseWidget::GetFrame() -{ - return vbox; -} - -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -void -QGoSeedBaseWidget::Initialize() -{ - filter->setCurrentIndex(0); - emit Filter(0); -} - -//---------------------------------------------------------------------------// - -int -QGoSeedBaseWidget::GetCurrentFilter() -{ - return filter->currentIndex(); -} diff --git a/Code/GUI/lib/QGoSeedSegmentationBase.cxx b/Code/GUI/lib/QGoSeedSegmentationBase.cxx deleted file mode 100644 index cf770077..00000000 --- a/Code/GUI/lib/QGoSeedSegmentationBase.cxx +++ /dev/null @@ -1,229 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ -#include "QGoSeedSegmentationBase.h" - -// vtk stuff -#include "vtkPoints.h" - -#include "QGoSeedBaseWidget.h" - -//-------------------------------------------------------------------------- -QGoSeedSegmentationBase::QGoSeedSegmentationBase(QWidget *parentWidget, - vtkPoints *seeds, - int iSampling) : - QObject(parentWidget), - m_NumberOfChannels(0) -{ - m_Seeds = seeds; - // initialize to 0 leads to segfaults - m_Radius = 3.0; - - m_Sampling = 3; - - m_SeedsPosition[0] = 0.; - m_SeedsPosition[1] = 0.; - m_SeedsPosition[2] = 0.; - - //Create associated Widget - m_BaseAlgorithmSegmentationWidget = new QGoSeedBaseWidget(parentWidget, iSampling); - - // CONNECT SAMPLING IF REQUIERED!!!! - if ( iSampling == 2 ) - { - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( Sampling(int) ), - this, SLOT( setSampling(int) ) ); - //QObject::connect(m_BaseAlgorithmSegmentationWidget, - // SIGNAL(CreateEmptyMesh()), - //this, SIGNAL(CreateEmptyMesh())); - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( CreateCorrespondingMesh(int) ), - this, SIGNAL( CreateCorrespondingMesh(int) ) ); - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ), - this, SIGNAL( AddContourForMeshToContours(vtkPolyData *) ) ); - } - - // connect with 3DwT to add the good number of channels - QObject::connect( this, SIGNAL( addChannel(int, QString) ), - m_BaseAlgorithmSegmentationWidget, SLOT( AddChannel(int, QString) ) ); - // connect with 3DwT to add the good number of channels - QObject::connect( this, SIGNAL( setNumberOfChannels(int) ), - m_BaseAlgorithmSegmentationWidget, SLOT( setNumberOfChannels(int) ) ); - QObject::connect( this, SIGNAL( setChannel(unsigned int) ), - m_BaseAlgorithmSegmentationWidget, SLOT( SetChannel(unsigned int) ) ); - // mesh has been created by a filter - QObject::connect( m_BaseAlgorithmSegmentationWidget, - SIGNAL( MeshCreated(vtkPolyData *, int) ), - this, SIGNAL( MeshCreated(vtkPolyData *, int) ) ); - // contour has been created by a filter - QObject::connect( m_BaseAlgorithmSegmentationWidget, - SIGNAL( ContourCreated(vtkPolyData *) ), - this, SIGNAL( ContourCreated(vtkPolyData *) ) ); - // image has been processed by a filter - // should return the new image as argument - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( ImageProcessed() ), - this, SIGNAL( ImageProcessed() ) ); - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( Radius(double) ), - this, SLOT( setRadius(double) ) ); - - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( UpdateSeeds() ), - this, SIGNAL( UpdateSeeds() ) ); - QObject::connect( m_BaseAlgorithmSegmentationWidget, SIGNAL( SegmentationFinished() ), - this, SIGNAL( SegmentationFinished() ) ); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QGoSeedSegmentationBase:: -~QGoSeedSegmentationBase() -{ -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::setSeed(vtkPoints *iSeed) -{ - m_Seeds = iSeed; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -vtkPoints * -QGoSeedSegmentationBase::getSeed() -{ - return m_Seeds; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::setRadius(double iRadius) -{ - m_Radius = iRadius; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -double -QGoSeedSegmentationBase::getRadius() -{ - return m_Radius; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::setSampling(int iSampling) -{ - m_Sampling = iSampling; - emit Sampling(iSampling); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -int -QGoSeedSegmentationBase::getSampling() -{ - return m_Sampling; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -double * -QGoSeedSegmentationBase::getSeedsPosition() -{ - return m_SeedsPosition; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::ConnectSignals(QGoSeedBaseWidget *iWidget) -{ - QObject::connect( this, SIGNAL( addChannel(QString) ), - iWidget, SLOT( AddChannel(QString) ) ); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::SetChannel(int iChannel, const QString & iText) -{ - // send signal to this class - emit addChannel(iChannel, iText); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::SetCurrentChannel(unsigned int iChannel) -{ - // send signal to this class - emit setChannel(iChannel); -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoSeedSegmentationBase::SetNumberOfChannels(int iNumberOfChannels) -{ - // send signal to this class - if ( m_NumberOfChannels != iNumberOfChannels ) - { - m_NumberOfChannels = iNumberOfChannels; - emit setNumberOfChannels(iNumberOfChannels); - } -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QWidget * -QGoSeedSegmentationBase::getWidget() -{ - return m_BaseAlgorithmSegmentationWidget; -} - -//-------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoSeedSegmentationBase.h b/Code/GUI/lib/QGoSeedSegmentationBase.h deleted file mode 100644 index e3fc0f60..00000000 --- a/Code/GUI/lib/QGoSeedSegmentationBase.h +++ /dev/null @@ -1,183 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ -#ifndef __QGoSeedSegmentationBase_h -#define __QGoSeedSegmentationBase_h - -#include -#include -#include "QGoGUILibConfigure.h" - -class QGoSeedBaseWidget; -class vtkPoints; -class vtkPolyData; - -/** - * \class QGoSeedSegmentationBase - * \brief Implements common method/signals for all the seed based segmentation methods -**/ - -class QGOGUILIB_EXPORT QGoSeedSegmentationBase:public QObject -{ - Q_OBJECT -public: - /** - * \brief Constructor - */ - explicit QGoSeedSegmentationBase(QWidget *parentWidget = 0, - vtkPoints *seeds = 0, - int iSampling = 0); - - /** - * \brief Destructor - */ - virtual ~QGoSeedSegmentationBase(); - - /** - * \brief Set the seeds from which the segmentation will be computed. - * - * \param[in] iSeed Seeds from which the segmentaion will be computed. - * It can contain more than on seed. - */ - void setSeed(vtkPoints *iSeed); - - /** - * \brief Get the seeds from which the segmentation will be computed. - */ - vtkPoints * getSeed(); - - /** - * \brief Get the current seed from which the segmentation will be computed. - */ - double * getSeedsPosition(); - - /** - * \brief Get the radius parameter for the segmentation. - */ - double getRadius(); - - int getSampling(); - - /** - * \brief Get the dockwidget associated to the segmentation method. - */ - virtual QWidget * getWidget(); - - /** - * \brief Connect signals/slots to the segmentation dock widget - * \param[in] iWidget Algorithm segmentation specific dock widget - */ - void ConnectSignals(QGoSeedBaseWidget *iWidget); - - /** - * \brief Specify on which one the segmentation will be applied since the input - * data is multichannel. - * \param[in] iChannel Channel on which want we want to apply the segmentation - * algorithm - temporary since channels don't have names yet - * \param[in] iText Channel on which want we want to apply the segmentation - * algorithm - */ - void SetChannel(int iChannel, const QString & iText); - - void SetCurrentChannel(unsigned int iChannel); - - void SetNumberOfChannels(int iNumberOfChannels); - -public slots: - /** - * \brief Set the value of the radius. - * \param[in] iRadius Radius to be used for the segmentation. - */ - void setRadius(double iRadius); - - /** - * \brief Set the value of the radius. - * \param[in] iSampling Radius to be used for the segmentation. - */ - void setSampling(int iSampling); - -signals: - /** - * \brief Signal sent to update the value of the pointed seeds. - */ - void getSeeds(); - - /** - * \brief Signal sent when the segmentation is done. - */ - void segmentationFinished(); - - /** - * \brief Signal to be send to the Widget to add channel to the channel - * QComboBox - * \param[in] iChannel Channel Number - * \param[in] iQString Name of the channel. - */ - void addChannel(int iChannel, QString iQString); - - void setChannel(unsigned int iChannel); - - /** - * \brief Set the number of channels - */ - void setNumberOfChannels(int); - - void MeshCreated(vtkPolyData *, int); - - void ContourCreated(vtkPolyData *); - - void ImageProcessed(); - - void UpdateSeeds(); - - void SegmentationFinished(); - - void CreateCorrespondingMesh(int); - - void AddContourForMeshToContours(vtkPolyData *); - - void Sampling(int); - -protected: - QGoSeedBaseWidget *m_BaseAlgorithmSegmentationWidget; -private: - /** - * - */ - double m_Radius; - vtkPoints *m_Seeds; - double m_SeedsPosition[3]; - int m_Sampling; - int m_NumberOfChannels; -}; -#endif diff --git a/Code/GUI/lib/QGoTabElementBase.cxx b/Code/GUI/lib/QGoTabElementBase.cxx index afc02661..18471cbb 100644 --- a/Code/GUI/lib/QGoTabElementBase.cxx +++ b/Code/GUI/lib/QGoTabElementBase.cxx @@ -44,11 +44,11 @@ #include //-------------------------------------------------------------------------- -QGoTabElementBase::QGoTabElementBase(QWidget *iParent) +QGoTabElementBase::QGoTabElementBase(QWidget *iParent) : QMainWindow(iParent), - m_StatusBar(NULL), //m_TracesActions(NULL), + m_StatusBar(NULL) + //m_TracesActions(NULL), //m_TraceSettingsToolBar(NULL), - m_ToolBarList(NULL) { //this->m_TracesActions = new QGoToolBarStatus; } @@ -102,35 +102,35 @@ std::vector< QAction * > QGoTabElementBase::BookmarkActions() //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- -/*std::vector< QAction * > QGoTabElementBase::ModeActions() -{ - return m_ModeActions; -} +//std::vector< QAction * > QGoTabElementBase::ModeActions() +//{ +// return m_ModeActions; +//} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //std::vector< QAction * > QGoTabElementBase::TracesActions() -/*QGoToolBarStatus* QGoTabElementBase::TracesActions() -{ - return m_TracesActions; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -QGoTraceSettingsWidget* QGoTabElementBase::TraceSettingsWidget() -{ - return m_TraceSettingsWidgetForToolBar; -} -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void QGoTabElementBase::SetTraceSettingsToolBar( - QToolBar* iToolBar) -{ - this->m_TraceSettingsToolBar = iToolBar; -}*/ +//QGoToolBarStatus* QGoTabElementBase::TracesActions() +//{ +// return m_TracesActions; +//} + +////-------------------------------------------------------------------------- + +////-------------------------------------------------------------------------- +//QGoTraceSettingsWidget* QGoTabElementBase::TraceSettingsWidget() +//{ +// return m_TraceSettingsWidgetForToolBar; +//} +////-------------------------------------------------------------------------- + +////-------------------------------------------------------------------------- +//void QGoTabElementBase::SetTraceSettingsToolBar( +// QToolBar* iToolBar) +//{ +// this->m_TraceSettingsToolBar = iToolBar; +//} //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- @@ -253,4 +253,4 @@ void QGoTabElementBase::SetStatusBarPointer(QStatusBar *iStatusbar) std::list< QGoToolBarStatus* > QGoTabElementBase::GetToolBarsStatus() { return this->m_ToolBarList; -} \ No newline at end of file +} diff --git a/Code/GUI/lib/QGoTabElementBase.h b/Code/GUI/lib/QGoTabElementBase.h index f41655f7..85015ff6 100644 --- a/Code/GUI/lib/QGoTabElementBase.h +++ b/Code/GUI/lib/QGoTabElementBase.h @@ -154,7 +154,7 @@ class QGOGUILIB_EXPORT QGoTabElementBase:public QMainWindow std::list< QGoDockWidgetStatusPair > m_DockWidgetList; std::list< QGoToolBarStatus* > m_ToolBarList; - QStatusBar* m_StatusBar; + QStatusBar* m_StatusBar; private: Q_DISABLE_COPY(QGoTabElementBase); diff --git a/Code/GUI/lib/QGoTabImageView3DwT.cxx b/Code/GUI/lib/QGoTabImageView3DwT.cxx index 0525d3a8..44997483 100644 --- a/Code/GUI/lib/QGoTabImageView3DwT.cxx +++ b/Code/GUI/lib/QGoTabImageView3DwT.cxx @@ -36,10 +36,8 @@ #include "QDebug" #include "QGoImageView3D.h" -#include "QGoLUTDialog.h" +//#include "QGoLUTDialog.h" #include "QGoNavigationDockWidget.h" -#include "GoDBCoordinateRow.h" -#include "GoDBMeshRow.h" #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) @@ -98,8 +96,8 @@ #include // base segmentation dock widgets -#include "QGoContourSegmentationBaseDockWidget.h" -#include "QGoMeshSegmentationBaseDockWidget.h" +#include "QGoMeshEditingWidgetManager.h" +#include "QGoContourEditingWidgetManager.h" // track dockwidget #include "QGoTrackViewDockWidget.h" @@ -110,16 +108,19 @@ //trackediting dw #include "QGoTrackEditingWidget.h" -// TESTS -#include "vtkPolyDataWriter.h" -#include "vtkViewImage3D.h" +// image processors +#include "GoMegaImageProcessor.h" +#include "GoLSMImageProcessor.h" + +// transfer function editor +#include "GoTransferFunctionEditorWidget.h" //------------------------------------------------------------------------- QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : QGoTabElementBase(iParent), - m_LSMReader(0), - m_Image(0), + m_ImageProcessor(NULL), m_BackgroundColor(Qt::black), + m_TraceSettingsToolBar(NULL), m_IntersectionLineWidth(2.), m_PCoord(0), m_RCoord(0), @@ -127,16 +128,24 @@ QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : m_XTileCoord(0), m_YTileCoord(0), m_ZTileCoord(0), - m_TraceSettingsToolBar(NULL), - m_TCoord(-1) + m_TCoord(-1), + m_MeshEditingWidget(NULL), + m_Seeds( 3, NULL ) //m_TraceWidgetRequiered(false) { - m_Image = vtkImageData::New(); - m_Seeds = vtkPoints::New(); + //m_Image = vtkImageData::New(); + + m_Seeds[0] = vtkPoints::New(); + m_Seeds[1] = vtkPoints::New(); + m_Seeds[2] = vtkPoints::New(); + // new - m_ChannelClassicMode = true; - m_ChannelOfInterest = 0; - m_DopplerStep = 1; +// vtkPoints* xy = vtkPoints::New(); +// vtkPoints* xz = vtkPoints::New(); +// vtkPoints* yz = vtkPoints::New(); +// m_OrderedSeeds.push_back(xy); +// m_OrderedSeeds.push_back(xz); +// m_OrderedSeeds.push_back(yz); m_HighlightedContoursProperty = vtkProperty::New(); m_HighlightedContoursProperty->SetColor(1., 0., 0.); @@ -173,31 +182,31 @@ QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : CreateVisuDockWidget(); // segmentation dockwidgets - CreateContourSegmentationDockWidget(); - CreateMeshSegmentationDockWidget(); + //CreateContourSegmentationDockWidget(); + //CreateMeshSegmentationDockWiget();in setmegacapture/LSM files now // track dock widget m_TrackViewDockWidget = new QGoTrackViewDockWidget(this); this->m_TrackViewDockWidget->setObjectName("TrackViewDockWidget"); QObject::connect( m_TrackViewDockWidget, - SIGNAL( ChangeColorCode(const char *) ), + SIGNAL( ChangeColorCode(const QString&) ), m_TrackContainer, - SLOT( ChangeColorCode(const char *) ) ); + SLOT( ChangeColorCode(const QString&) ) ); QObject::connect( m_TrackViewDockWidget, - SIGNAL( UpdateTracksRepresentation(double, double) ), + SIGNAL( UpdateTracksRepresentation(const double&, const double&) ), m_TrackContainer, - SLOT( UpdateTracksRepresentation(double, double) ) ); + SLOT( UpdateTracksRepresentation(const double&, const double&) ) ); // lineage dock widget m_LineageViewDockWidget = new QGoLineageViewDockWidget(this); this->m_LineageViewDockWidget->setObjectName("LineageViewDockWidget"); QObject::connect( m_LineageViewDockWidget, - SIGNAL( ChangeDivisionsColorCode(const char *) ), + SIGNAL( ChangeDivisionsColorCode(const QString&) ), m_TrackContainer, - SLOT( ChangeDivisionsColorCode(const char *) ) ); + SLOT( ChangeDivisionsColorCode(const QString&) ) ); CreateDataBaseTablesConnection(); @@ -211,11 +220,10 @@ QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : CreateBookmarkActions(); - //CreateModeActions(); - - CreateTracesActions(); + //CreateModeActions(); in setmegacapture/LSM files now + //CreateTracesActions(); - ReadSettings(); + ReadSettings(); m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( @@ -223,17 +231,23 @@ QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : m_NavigationDockWidget, Qt::RightDockWidgetArea, false, true), m_NavigationDockWidget) ); - m_DockWidgetList.push_back( + /*m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( m_ContourSegmentationDockWidget, Qt::LeftDockWidgetArea, false, true), - m_ContourSegmentationDockWidget) ); + m_ContourSegmentationDockWidget) );*/ - m_DockWidgetList.push_back( + /*m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus( - m_MeshSegmentationDockWidget, Qt::LeftDockWidgetArea, false, true), - m_MeshSegmentationDockWidget) ); + this->m_MeshEditingWidget->GetDockWidget(), Qt::LeftDockWidgetArea, true, true), + this->m_MeshEditingWidget->GetDockWidget()) ); in setmegacapture/LSM files now */ + + /*m_DockWidgetList.push_back( + std::pair< QGoDockWidgetStatus *, QDockWidget * >( + new QGoDockWidgetStatus(this->m_DataBaseTables->GetTraceSettingsDockWidget(), + Qt::LeftDockWidgetArea, false, true), + this->m_DataBaseTables->GetTraceSettingsDockWidget() ) );*/ m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( @@ -241,6 +255,7 @@ QGoTabImageView3DwT::QGoTabImageView3DwT(QWidget *iParent) : Qt::LeftDockWidgetArea, false, true), this->m_TrackViewDockWidget) ); + m_DockWidgetList.push_back( std::pair< QGoDockWidgetStatus *, QDockWidget * >( new QGoDockWidgetStatus(this->m_LineageViewDockWidget, @@ -271,24 +286,20 @@ QGoTabImageView3DwT:: m_HighlightedContoursProperty->Delete(); m_HighlightedMeshesProperty->Delete(); - m_Image->Delete(); - m_Seeds->Delete(); - - if ( !m_LSMReader.empty() ) - { - if ( m_LSMReader[0] ) - { - m_LSMReader[0]->Delete(); - } - } + m_Seeds[0]->Delete(); + m_Seeds[1]->Delete(); + m_Seeds[2]->Delete(); + // new + /* + std::vector::iterator it = m_OrderedSeeds.begin(); + while(it != m_OrderedSeeds.end()) + { + (*it)->Delete(); + (*it) = NULL; + ++it; + } - // clean the LSMReader vector - /*while(!m_LSMReader.empty()) - { - m_LSMReader.back()->Delete(); - m_LSMReader.pop_back(); - } -*/ + */ unsigned int minch = m_MegaCaptureReader->GetMinChannel(); unsigned int maxch = m_MegaCaptureReader->GetMaxChannel(); @@ -318,6 +329,11 @@ QGoTabImageView3DwT:: { delete m_LineageContainer; } + + if(m_ImageProcessor) + { + delete m_ImageProcessor; + } } //------------------------------------------------------------------------- @@ -326,35 +342,80 @@ QGoTabImageView3DwT:: void QGoTabImageView3DwT::UpdateSeeds() { - vtkPoints *temp = m_ImageView->GetAllSeeds(); + // should be used now + // clean the ordered seeds + /* + std::vector::iterator it = m_OrderedSeeds.begin(); + while(it != m_OrderedSeeds.end()) + { + (*it)->Initialize(); + ++it; + } + m_ImageView->GetSeeds(m_OrderedSeeds);*/ - m_Seeds->DeepCopy(temp); - temp->Delete(); + for( size_t id = 0; id < m_Seeds.size(); id++ ) + { + m_Seeds[id]->Initialize(); + } + + m_ImageView->GetSeeds( m_Seeds ); + +// vtkPoints *temp = m_ImageView->GetAllSeeds(); + +// // deep copy vtkPoints not properly working (warning) +// for(int l = 0; l< temp->GetNumberOfPoints(); l++) +// { +// double p[3]; +// temp->GetPoint(l,p); +// m_Seeds->InsertNextPoint(p); +// } +// m_Seeds->GetData()->DeepCopy( temp->GetData() ); + +// /* +// for(int l = 0; lGetData()->GetNumberOfTuples(); l++) +// { +// double* value = m_Seeds->GetData()->GetTuple(l); +// std::cout << "m_Seeds: " << l << " orientation: " << value[0] << std::endl; +// } +// */ + +// temp->Delete(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -QGoTabImageView3DwT::CreateContourSegmentationDockWidget() +QGoTabImageView3DwT::CreateContourEditingDockWidget( + int iTimeMin, int iTimeMax) { //---------------------------------------------------------------- // Create base contour segmentation dock widget: // basic interactor connections //---------------------------------------------------------------- - m_ContourSegmentationDockWidget = - new QGoContourSegmentationBaseDockWidget(this, m_Seeds, &m_InternalImages); + // build channel vector + unsigned int numberOfChannels = m_ImageProcessor->getNumberOfChannels(); + std::vector< QString > channelNames; + channelNames.resize( numberOfChannels ); + for(unsigned int i =0; igetChannelName(i)); + } - QObject::connect( m_ContourSegmentationDockWidget, + this->m_ContourEditingWidget = new QGoContourEditingWidgetManager( + channelNames, iTimeMin, iTimeMax, &m_Seeds, + m_ImageProcessor, &m_TCoord, this); + + this->CreateConnectionsTraceEditingWidget( + iTimeMin, iTimeMax, this->m_ContourEditingWidget); + + /*QObject::connect( m_ContourSegmentationDockWidget, SIGNAL( ReinitializeInteractorActivated(bool) ), this, SLOT( DefaultInteractorBehavior(bool) ) ); - QObject::connect( m_ContourSegmentationDockWidget, - SIGNAL( ManualSegmentationActivated(bool) ), - this, - SLOT( ManualInteractorBehavior(bool) ) ); QObject::connect( m_ContourSegmentationDockWidget, SIGNAL( SemiAutoSegmentationActivated(bool) ), @@ -364,31 +425,38 @@ QGoTabImageView3DwT::CreateContourSegmentationDockWidget() QObject::connect( m_ContourSegmentationDockWidget, SIGNAL( AutoSegmentationActivated(bool) ), this, - SLOT( DefaultInteractorBehavior(bool) ) ); + SLOT( DefaultInteractorBehavior(bool) ) );*/ // signals from the manual segmentation - QObject::connect( m_ContourSegmentationDockWidget, - SIGNAL( ValidateContour() ), - this, SLOT( ValidateContour() ) ); + QObject::connect( m_ContourEditingWidget, + SIGNAL( ManualSegmentationActivated(bool) ), + this, + SLOT( ManualInteractorBehavior(bool) ) ); - QObject::connect( m_ContourSegmentationDockWidget, - SIGNAL( ReinitializeContourWidget() ), + QObject::connect( this->m_ContourEditingWidget, + SIGNAL( ContourValidated(int) ), + this, SLOT( ValidateContour(int) ) ); + + QObject::connect( this->m_ContourEditingWidget, + SIGNAL( reinitializeContour() ), m_ImageView, SLOT( ReinitializeContourWidget() ) ); - QObject::connect( m_ContourSegmentationDockWidget, - SIGNAL( UpdateContourRepresentationProperties(float, QColor, + QObject::connect( this->m_ContourEditingWidget, + SIGNAL( changeContourRepresentationProperty(float, QColor, QColor, QColor) ), m_ImageView, SLOT( UpdateContourRepresentationProperties(float, QColor, QColor, QColor) ) ); - // signals for the semi automated segmentation - QObject::connect( m_ContourSegmentationDockWidget, - SIGNAL( UpdateSeeds() ), + QObject::connect( this->m_ContourEditingWidget, + SIGNAL(TracesCreatedFromAlgo(std::vector, int) ), this, - SLOT( UpdateSeeds() ) ); + SLOT( SaveInDBAndRenderContourForVisu(std::vector, int) ) ); + + this->m_ContourEditingWidget->InitializeSettingsForManualMode(); + /* QObject::connect( m_ContourSegmentationDockWidget, SIGNAL( SaveAndVisuContour(vtkPolyData *) ), this, @@ -403,27 +471,76 @@ QGoTabImageView3DwT::CreateContourSegmentationDockWidget() // ... // intialize the widget - m_ContourSegmentationDockWidget->Initialize(); + m_ContourSegmentationDockWidget->Initialize();*/ } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -QGoTabImageView3DwT::CreateMeshSegmentationDockWidget() +QGoTabImageView3DwT::CreateMeshEditingDockWidget(int iTimeMin, int iTimeMax) { //---------------------------------------------------------------- // Create base contour segmentation dock widget: // basic interactor connections //---------------------------------------------------------------- - m_MeshSegmentationDockWidget = - new QGoMeshSegmentationBaseDockWidget(this, m_Seeds, &m_InternalImages); + // build channel vector + unsigned int numberOfChannels = m_ImageProcessor->getNumberOfChannels(); + std::vector< QString > channelNames; + channelNames.resize( numberOfChannels ); + for(unsigned int i =0; igetChannelName(i)); + } - QObject::connect( m_MeshSegmentationDockWidget, + this->m_MeshEditingWidget = new QGoMeshEditingWidgetManager( + channelNames, iTimeMin, iTimeMax, &m_Seeds, + m_ImageProcessor, &m_TCoord, this); + + this->CreateConnectionsTraceEditingWidget( + iTimeMin, iTimeMax, this->m_MeshEditingWidget); + /* + QObject::connect(this->m_MeshEditingWidget, + SIGNAL(ClearAllSeeds() ), + this->m_ImageView, + SLOT(ClearAllSeeds() ) ); now on the template method + + m_DockWidgetList.push_back( + std::pair< QGoDockWidgetStatus *, QDockWidget * >( + new QGoDockWidgetStatus( + this->m_MeshEditingWidget->GetDockWidget(), Qt::LeftDockWidgetArea, false, true), + this->m_MeshEditingWidget->GetDockWidget()) ); + + QObject::connect( this->m_MeshEditingWidget, + SIGNAL( SetSeedInteractorBehaviour(bool) ), + this, + SLOT( SeedInteractorBehavior(bool) ) );*/ + + QObject::connect( this->m_MeshEditingWidget, + SIGNAL(TracesCreatedFromAlgo(std::vector, int) ), + this, + SLOT( SaveInDBAndRenderMeshForVisu(std::vector, int) ) ); + + /** \todo connect the signal, reimplement the slot*/ + QObject::connect( this->m_MeshEditingWidget, + SIGNAL(SetOfContoursFromAlgo(std::vector >, int) ), + this, + SLOT(SaveInDBAndRenderSetOfContoursForVisu(std::vector >, int))); + + QObject::connect( this, + SIGNAL( TimePointChanged(int) ), + this, + SLOT(UpdateTracesEditingWidget() ) ); + + + /*QObject::connect( m_MeshSegmentationDockWidget, SIGNAL( ReinitializeInteractorActivated(bool) ), this, - SLOT( DefaultInteractorBehavior(bool) ) ); + SLOT( DefaultInteractorBehavior(bool) ) ); seems useless for now + as we are in defaultmode as soon as the seedinteractorbehaviour is called + // we need seeds for the manual mesh segmentation QObject::connect( m_MeshSegmentationDockWidget, @@ -452,12 +569,6 @@ QGoTabImageView3DwT::CreateMeshSegmentationDockWidget() this, SLOT( AddContourForMeshToContours(vtkPolyData *) ) ); - // signals for the semi automatic segmentation - QObject::connect( m_MeshSegmentationDockWidget, - SIGNAL( UpdateSeeds() ), - this, - SLOT( UpdateSeeds() ) ); - QObject::connect( m_MeshSegmentationDockWidget, SIGNAL( SaveAndVisuMesh(vtkPolyData *, int) ), this, @@ -466,7 +577,7 @@ QGoTabImageView3DwT::CreateMeshSegmentationDockWidget() QObject::connect( m_MeshSegmentationDockWidget, SIGNAL( ClearAllSeeds() ), m_ImageView, - SLOT( ClearAllSeeds() ) ); + SLOT( ClearAllSeeds() ) );*/ } //------------------------------------------------------------------------- @@ -608,17 +719,20 @@ QGoTabImageView3DwT::CreateVisuDockWidget() QObject::connect( this, SIGNAL( TimePointChanged(int) ), m_NavigationDockWidget, SLOT( SetTSlice(int) ) ); - QObject::connect( m_NavigationDockWidget, SIGNAL( ShowAllChannelsChanged(bool) ), - this, SLOT( ShowAllChannels(bool) ) ); - - QObject::connect( m_NavigationDockWidget, SIGNAL( ShowOneChannelChanged(int) ), - this, SLOT( ShowOneChannel(int) ) ); - QObject::connect( m_NavigationDockWidget, SIGNAL( ModeChanged(int) ), this, SLOT( ModeChanged(int) ) ); QObject::connect( m_NavigationDockWidget, SIGNAL( StepChanged(int) ), this, SLOT( StepChanged(int) ) ); + + QObject::connect( m_NavigationDockWidget, SIGNAL( DopplerSizeChanged(int) ), + this, SLOT( DopplerSizeChanged(int) ) ); + + QObject::connect( m_NavigationDockWidget, SIGNAL( visibilityChanged(QString, bool) ), + this, SLOT( visibilityChanged(QString, bool) ) ); + + QObject::connect( m_NavigationDockWidget, SIGNAL( openTransferFunctionEditor(QString) ), + this, SLOT( openTransferFunctionEditor(QString) ) ); } //------------------------------------------------------------------------- @@ -631,7 +745,8 @@ QGoTabImageView3DwT::CreateDataBaseTablesConnection() SIGNAL( DBVariablesSet() ), this, SLOT( SetDatabaseContainersAndDelayedConnections() ) ); - + //in order also, to update the list of meshes in the collectionIDs when + //the trace is contour and to update the show/hide contours and meshes QObject::connect( this, SIGNAL( TimePointChanged(int) ), this->m_DataBaseTables, @@ -865,7 +980,7 @@ QGoTabImageView3DwT::CreateAllViewActions() LookupTableAction->setStatusTip( tr(" Change the associated lookup table") ); //take - QIcon luticon; + /*QIcon luticon; luticon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LookupTable.png") ), QIcon::Normal, QIcon::Off); LookupTableAction->setIcon(luticon); @@ -874,7 +989,7 @@ QGoTabImageView3DwT::CreateAllViewActions() QObject::connect( LookupTableAction, SIGNAL( triggered() ), this, SLOT( ChangeLookupTable() ) ); - this->m_ViewActions.push_back(LookupTableAction); + this->m_ViewActions.push_back(LookupTableAction);*/ QAction *ScalarBarAction = new QAction(tr("Display Scalar Bar"), this); ScalarBarAction->setEnabled(false); @@ -915,7 +1030,7 @@ QGoTabImageView3DwT::CreateAllViewActions() QIcon::Normal, QIcon::Off); Change3DPerspectiveToAxialAction->setIcon(axialicon); this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToAxialAction); - + QObject::connect( Change3DPerspectiveToAxialAction, SIGNAL( triggered() ), this, SLOT( Change3DPerspectiveToAxial() ) ); @@ -925,7 +1040,7 @@ QGoTabImageView3DwT::CreateAllViewActions() coronalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/DorsalView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToCoronalAction->setIcon(coronalicon); - + this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToCoronalAction); QObject::connect( Change3DPerspectiveToCoronalAction, SIGNAL( triggered() ), @@ -937,7 +1052,7 @@ QGoTabImageView3DwT::CreateAllViewActions() sagittalicon.addPixmap(QPixmap( QString::fromUtf8(":/fig/LeftView.png") ), QIcon::Normal, QIcon::Off); Change3DPerspectiveToSagittalAction->setIcon(sagittalicon); - + this->m_ViewNoToolBarActions.push_back(Change3DPerspectiveToSagittalAction); QObject::connect( Change3DPerspectiveToSagittalAction, SIGNAL( triggered() ), @@ -960,7 +1075,7 @@ QGoTabImageView3DwT::CreateAllViewActions() VolumeRenderingAction->setIcon(volumerenderingicon); QObject::connect( VolumeRenderingAction, SIGNAL( toggled(bool) ), - this->m_ImageView, SLOT( EnableVolumeRendering(bool) ) ); + this, SLOT( EnableVolumeRendering(bool) ) ); // Enable synchronization QAction *SynchronizeViewsAction = @@ -993,60 +1108,13 @@ QGoTabImageView3DwT::CreateTracesActions() //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void -QGoTabImageView3DwT::ChannelTimeMode(bool iEnable) -{ - m_ChannelClassicMode = !iEnable; - - // if we leave the time mode, go back to the classic mode automatically - if ( m_ChannelClassicMode ) - { - unsigned int min_ch = m_MegaCaptureReader->GetMinChannel(); - unsigned int max_ch = m_MegaCaptureReader->GetMaxChannel(); - unsigned int NumberOfChannels = max_ch - min_ch + 1; - // resize internal and update the internal image - m_InternalImages.resize(NumberOfChannels, NULL); - SetTimePointWithMegaCapture(); - - // Update navigation widget - // Initialize the widgets with the good number of channels - // it will update the size of the related combobox - m_NavigationDockWidget->blockSignals(true); - m_NavigationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_ContourSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_MeshSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); - - if ( NumberOfChannels > 1 ) - { - m_NavigationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - m_ContourSegmentationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - m_MeshSegmentationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - for ( unsigned int i = 1; i < NumberOfChannels; i++ ) - { - m_NavigationDockWidget->SetChannel( i, m_ChannelNames[i] ); - - m_ContourSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - m_MeshSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - } - } - m_NavigationDockWidget->blockSignals(false); - // update visualization - Update(); - } -} - -//------------------------------------------------------------------------- - -void QGoTabImageView3DwT::LoadChannelTime() +void QGoTabImageView3DwT::StartDopplerView() { bool ok; QStringList channel; - unsigned int minch = m_MegaCaptureReader->GetMinChannel(); - unsigned int maxch = m_MegaCaptureReader->GetMaxChannel(); + unsigned int* boundChannel = m_ImageProcessor->getBoundsChannel(); - maxch += maxch; - - for ( unsigned int i = minch; i < maxch; ++i ) + for ( unsigned int i = boundChannel[0]; i < boundChannel[1]+1; ++i ) { channel << QString::number(i, 10); } @@ -1059,19 +1127,39 @@ void QGoTabImageView3DwT::LoadChannelTime() if ( ok ) { - //qDebug() << "user selected an item and pressed OK"; - // use the item - int value = item.toInt(&ok, 10); - //qDebug() << "value:" << value; - // emit with channel... - // keep track of channel of interest when we move through time - m_ChannelOfInterest = value; - SetTimePointWithMegaCaptureTimeChannels(m_ChannelOfInterest); - Update(); - } - else - { - //qDebug() << "user selected an item and pressed CANCEL"; + m_ImageProcessor->setDopplerMode(ok, // bool: true/false + item.toInt(&ok, 10)); // selected channel ID + // update image + m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... + + // update widget + // hide channels + this->m_NavigationDockWidget->VisibilityListChannels(false); + //update values - show requiered widgets + std::vector time = m_ImageProcessor->getDopplerTime(m_TCoord); + // get number of items in container + // requiereds to call this method since the number of items varies + for(unsigned int i=0; igetDopplerSize(); ++i) + { + if(time[i]>=0) + { + std::string name = m_ImageProcessor->getChannelName(time[i]); + // channel color + std::vector color = m_ImageProcessor->getColor(name); + // update navigation dockwidget + m_NavigationDockWidget->AddDoppler( + QString::fromStdString(name), + QColor(color[0], + color[1], + color[2], + color[3]), + time[i], + true); // all checkboxes are check edwhen we start + } + } + // set channel name + this->m_NavigationDockWidget->setChannelName( + QString("Channel %1").arg(m_ImageProcessor->getDopplerChannel())); } } @@ -1454,7 +1542,7 @@ QGoTabImageView3DwT::setupUi(QWidget *iParent) this->addDockWidget(Qt::TopDockWidgetArea, m_DataBaseTables); m_DataBaseTables->hide(); - + m_ImageView->SetIntersectionLineWidth(this->m_IntersectionLineWidth); m_ImageView->SetBackgroundColor(m_BackgroundColor); @@ -1480,8 +1568,7 @@ QGoTabImageView3DwT::setupUi(QWidget *iParent) retranslateUi(iParent); QMetaObject::connectSlotsByName(iParent); -} // setupUi - +} //------------------------------------------------------------------------- //------------------------------------------------------------------------- @@ -1491,7 +1578,6 @@ QGoTabImageView3DwT::retranslateUi(QWidget *iParent) iParent->setWindowTitle( tr("QGoTabImageView3DwT") ); Q_UNUSED(iParent); } - //------------------------------------------------------------------------- //------------------------------------------------------------------------- @@ -1503,89 +1589,30 @@ QGoTabImageView3DwT::GetTabDimensionType() const //------------------------------------------------------------------------- -//######################################################################### -//######################################################################### -// Set Inputs - //------------------------------------------------------------------------- void QGoTabImageView3DwT::SetLSMReader(vtkLSMReader *iReader, const int & iTimePoint) { - if ( iReader ) - { - if ( m_LSMReader.empty() ) - { - m_LSMReader.push_back(iReader); - } - else - { - if ( iReader != m_LSMReader[0] ) - { - m_LSMReader[0] = iReader; - } - } - - m_LSMReader[0]->Update(); - - int dim[5]; - m_LSMReader[0]->GetDimensions(dim); - - int NumberOfChannels = m_LSMReader[0]->GetNumberOfChannels(); - - // Initialize the widgets with the good number of channels - // it will update the size of the related combobox - m_NavigationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_ContourSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_MeshSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); - - m_ChannelNames.resize( NumberOfChannels ); - - if ( NumberOfChannels > 1 ) - { - m_NavigationDockWidget->SetChannel(0); - m_ChannelNames[0] = m_NavigationDockWidget->GetChannelName( 0 ); - - m_ContourSegmentationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - m_MeshSegmentationDockWidget->SetChannel( 0 , m_ChannelNames[0] ); - m_InternalImages.resize(NumberOfChannels); - - for ( int i = 1; i < NumberOfChannels; i++ ) - { - m_NavigationDockWidget->SetChannel(i); - m_ChannelNames[i] = m_NavigationDockWidget->GetChannelName( i ); - - m_ContourSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - m_MeshSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - - m_LSMReader.push_back( vtkSmartPointer< vtkLSMReader >::New() ); - m_LSMReader.back()->SetFileName( m_LSMReader[0]->GetFileName() ); - m_LSMReader.back()->SetUpdateChannel(i); - } - } - - m_NavigationDockWidget->SetXMinimumAndMaximum(0, dim[0] - 1); - m_NavigationDockWidget->SetXSlice( ( dim[0] - 1 ) / 2 ); - - m_NavigationDockWidget->SetYMinimumAndMaximum(0, dim[1] - 1); - m_NavigationDockWidget->SetYSlice( ( dim[1] - 1 ) / 2 ); - - m_NavigationDockWidget->SetZMinimumAndMaximum(0, dim[2] - 1); - m_NavigationDockWidget->SetZSlice( ( dim[2] - 1 ) / 2 ); - - m_NavigationDockWidget->SetTMinimumAndMaximum(0, dim[3] - 1); - m_NavigationDockWidget->SetTSlice(iTimePoint); - if ( m_TCoord != iTimePoint ) - { - SetTimePoint(iTimePoint); - } + GoLSMImageProcessor* processor = new GoLSMImageProcessor; + processor->setReader(iReader); + m_ImageProcessor = processor; + + m_TCoord = iTimePoint; + // update image processor + m_ImageProcessor->initTimePoint(m_TCoord); + //update images + UpdateImage(); + // update actors + this->m_ContourContainer->ShowActorsWithGivenTimePoint(iTimePoint); + this->m_MeshContainer->ShowActorsWithGivenTimePoint(iTimePoint); + // update widgets on image loading + InitializeImageRelatedWidget(); + // render + m_ImageView->Update(); -#if defined( ENABLEFFMPEG ) || defined( ENABLEAVI ) - m_VideoRecorderWidget->SetXMinAndMax(0, dim[0] - 1); - m_VideoRecorderWidget->SetYMinAndMax(0, dim[1] - 1); - m_VideoRecorderWidget->SetZMinAndMax(0, dim[2] - 1); - m_VideoRecorderWidget->SetTMinAndMax(0, dim[3] - 1); -#endif /* ENABLEVIDEORECORD */ - } + // for the trace widget, navigation widget and table widget + // should not be requiered since we just initialize it before + emit TimePointChanged(m_TCoord); } //------------------------------------------------------------------------- @@ -1601,6 +1628,7 @@ QGoTabImageView3DwT::SetMegaCaptureFile( m_FileList = iContainer; m_FileType = iFileType; + // setup megacapture reader m_MegaCaptureReader->SetInput(m_FileList); m_MegaCaptureReader->SetMegaCaptureHeader(iHeader); m_MegaCaptureReader->SetFileType(m_FileType); @@ -1608,47 +1636,59 @@ QGoTabImageView3DwT::SetMegaCaptureFile( m_MegaCaptureReader->SetTimePoint(iTimePoint); m_MegaCaptureReader->Update(); - unsigned int min_t = m_MegaCaptureReader->GetMinTimePoint(); - unsigned int max_t = m_MegaCaptureReader->GetMaxTimePoint(); - - unsigned int min_ch = m_MegaCaptureReader->GetMinChannel(); - unsigned int max_ch = m_MegaCaptureReader->GetMaxChannel(); - - unsigned int NumberOfChannels = max_ch - min_ch + 1; - - m_ChannelNames.resize( NumberOfChannels ); + GoMegaImageProcessor* processor = new GoMegaImageProcessor; + processor->setReader(m_MegaCaptureReader); + m_ImageProcessor = processor; + + m_TCoord = iTimePoint; + // update image processor + m_ImageProcessor->initTimePoint(m_TCoord); + //update images + UpdateImage(); + // update actors + this->m_ContourContainer->ShowActorsWithGivenTimePoint(iTimePoint); + this->m_MeshContainer->ShowActorsWithGivenTimePoint(iTimePoint); + // update widgets on image loading + InitializeImageRelatedWidget(); + // render + m_ImageView->Update(); - vtkImageData *temp = m_MegaCaptureReader->GetOutput(min_ch); + // for the trace widget, navigation widget and table widget + // should not be requiered since we just initialize it before + emit TimePointChanged(m_TCoord); +} +//------------------------------------------------------------------------- - int extent[6]; - temp->GetExtent(extent); +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +InitializeImageRelatedWidget() +{ + unsigned int* boundTime = m_ImageProcessor->getBoundsTime(); + unsigned int NumberOfChannels = m_ImageProcessor->getNumberOfChannels(); + int* extent = m_ImageProcessor->getExtent(); // Initialize the widgets with the good number of channels // it will update the size of the related combobox - m_NavigationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_ContourSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); - m_MeshSegmentationDockWidget->SetNumberOfChannels(NumberOfChannels); + m_NavigationDockWidget->blockSignals(true); - // Set up QSpinBox in m_VideoRecorderWidget - if ( NumberOfChannels > 1 ) + for ( unsigned int i = 0; i < NumberOfChannels; i++ ) { - m_NavigationDockWidget->SetChannel(0); - m_ChannelNames[0] = m_NavigationDockWidget->GetChannelName(0); - - m_ContourSegmentationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - m_MeshSegmentationDockWidget->SetChannel( 0, m_ChannelNames[0] ); - m_InternalImages.resize(NumberOfChannels, NULL); - - for ( unsigned int i = 1; i < NumberOfChannels; i++ ) - { - m_NavigationDockWidget->SetChannel(i); - m_ChannelNames[i] = m_NavigationDockWidget->GetChannelName(i); - - m_ContourSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - m_MeshSegmentationDockWidget->SetChannel( i, m_ChannelNames[i] ); - } + std::string name = m_ImageProcessor->getChannelName(i); + // channel color + std::vector color = m_ImageProcessor->getColor(name); + // update navigation dockwidget + m_NavigationDockWidget->AddChannel( + QString::fromStdString(name), + QColor(color[0], + color[1], + color[2], + color[3]), + i, + true); // all checkboxes are check edwhen we start } + m_NavigationDockWidget->SetXMinimumAndMaximum(extent[0], extent[1]); m_NavigationDockWidget->SetXSlice( ( extent[0] + extent[1] ) / 2 ); @@ -1658,23 +1698,24 @@ QGoTabImageView3DwT::SetMegaCaptureFile( m_NavigationDockWidget->SetZMinimumAndMaximum(extent[4], extent[5]); m_NavigationDockWidget->SetZSlice( ( extent[4] + extent[5] ) / 2 ); - m_NavigationDockWidget->SetTMinimumAndMaximum(min_t, max_t); - m_NavigationDockWidget->SetTSlice(iTimePoint); + m_NavigationDockWidget->SetTMinimumAndMaximum(boundTime[0], boundTime[1]); + m_NavigationDockWidget->SetTSlice(boundTime[0]); + m_NavigationDockWidget->blockSignals(false); - if ( static_cast< unsigned int >( m_TCoord ) != iTimePoint ) - { - SetTimePoint(iTimePoint); - } + /**\ todo Lydie: the dock widget needs to have the channels and the timepoints, + do a separated method ??*/ + CreateMeshEditingDockWidget(boundTime[0], boundTime[1]); + CreateContourEditingDockWidget(boundTime[0], boundTime[1]); + //CreateModeActions(); // Set up QSpinBox in m_VideoRecorderWidget #if defined( ENABLEFFMPEG ) || defined( ENABLEAVI ) m_VideoRecorderWidget->SetXMinAndMax(extent[0], extent[1]); m_VideoRecorderWidget->SetYMinAndMax(extent[2], extent[3]); m_VideoRecorderWidget->SetZMinAndMax(extent[4], extent[5]); - m_VideoRecorderWidget->SetTMinAndMax(min_t, max_t); + m_VideoRecorderWidget->SetTMinAndMax(boundTime[0], boundTime[1]); #endif /* ENABLEVIDEORECORD */ } - //------------------------------------------------------------------------- //######################################################################### @@ -1682,290 +1723,69 @@ QGoTabImageView3DwT::SetMegaCaptureFile( //------------------------------------------------------------------------- void -QGoTabImageView3DwT::SetTimePointWithMegaCapture() +QGoTabImageView3DwT::UpdateImage() { - m_MegaCaptureReader->SetTimePoint(m_TCoord); - - unsigned int min_ch = m_MegaCaptureReader->GetMinChannel(); - unsigned int max_ch = m_MegaCaptureReader->GetMaxChannel(); + // get number of visible channels instead + unsigned int NumberOfVisibleChannels = m_ImageProcessor->getNumberOfVisibleChannels(); - unsigned int NumberOfChannels = max_ch - min_ch + 1; - // delete the preivous pointers - // and reassign it - m_InternalImages.resize(NumberOfChannels, NULL); - - m_MegaCaptureReader->Update(); - - if ( max_ch != min_ch ) + if ( NumberOfVisibleChannels>1 ) { - vtkSmartPointer< vtkImageAppendComponents > append_filter = - vtkSmartPointer< vtkImageAppendComponents >::New(); - - for ( unsigned int i = min_ch; i <= max_ch; i++ ) - { - vtkSmartPointer< vtkImageData > input = vtkSmartPointer< vtkImageData >::New(); - input->ShallowCopy( m_MegaCaptureReader->GetOutput(i) ); - m_InternalImages[i] = input; - append_filter->AddInput(m_InternalImages[i]); - } - // This is really stupid!!! - if ( max_ch < 2 ) - { - for ( unsigned int i = max_ch + 1; i < 3; i++ ) - { - append_filter->AddInput(m_InternalImages[0]); - } - } - append_filter->Update(); - - if ( this->m_NavigationDockWidget->ShowAllChannels() ) - { - m_Image->ShallowCopy( append_filter->GetOutput() ); - - // LUT DISABLED - this->findChild("LUT")->setEnabled(false); - this->findChild("ScalarBar")->setEnabled(false); - } - else - { - int ch = this->m_NavigationDockWidget->GetCurrentChannel(); - if ( ch != -1 ) - { - m_Image->ShallowCopy(m_InternalImages[ch]); - } - // LUT ENABLED - this->findChild("LUT")->setEnabled(true); - this->findChild("ScalarBar")->setEnabled(true); - } + m_ImageView->SetImage(m_ImageProcessor->getVisibleImages()); } - else + else if( NumberOfVisibleChannels == 1) { - m_Image->ShallowCopy( m_MegaCaptureReader->GetOutput(min_ch) ); - m_Image->SetNumberOfScalarComponents(1); - - if( m_InternalImages.size() != 1 ) - { - m_InternalImages.resize( 1 ); - } - m_InternalImages[0] = m_Image; + // BUG HERE - 2 update + hide actors if opacity <1 + //update Image + m_ImageView->SetImage(m_ImageProcessor->getImageBW()); + // update LUT + vtkSmartPointer lut = vtkSmartPointer::New(); + lut->DeepCopy(m_ImageProcessor->getLookuptable()); + // WHEN WE MODIFY WE WANT TO KEEP THE MODIF (FROM ANDREA) + m_ImageView->SetLookupTable(lut); - // LUT ENABLED + // CONFIGURE LUT this->findChild("LUT")->setEnabled(true); this->findChild("ScalarBar")->setEnabled(true); } -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTabImageView3DwT::SetTimePointWithMegaCaptureTimeChannels(int iChannel, - int iPreviousT) -{ - int min_t = m_MegaCaptureReader->GetMinTimePoint(); - int max_t = m_MegaCaptureReader->GetMaxTimePoint(); - - int t0 = m_TCoord - m_DopplerStep; - int t1 = m_TCoord; - int t2 = m_TCoord + m_DopplerStep; - - // special case if we are at the borders - if ( t0 < min_t ) - { - t0 = min_t; - } - - if ( t2 > max_t ) - { - t2 = max_t; - } - - vtkSmartPointer< vtkImageAppendComponents > append_filter = - vtkSmartPointer< vtkImageAppendComponents >::New(); - - // if step != 1 and we have previous and next time point loaded - if( m_DopplerStep != 1 || iPreviousT == 0 ) - { - // resize internal image - // clean the vector since is is a vector of smartpointers - m_InternalImages.resize(3, NULL); - - vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); - i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); - m_InternalImages[0] = i0; - append_filter->AddInput(m_InternalImages[0]); - - vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); - i1->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t1) ); - m_InternalImages[1] = i1; - append_filter->AddInput(m_InternalImages[1]); - - vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); - i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); - m_InternalImages[2] = i2; - append_filter->AddInput(m_InternalImages[2]); - } - else - { - // if we go FORWARD and step == 1 - if( iPreviousT < m_TCoord) - { - // assume we imcrease t point all the time for testing - vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); - i0->ShallowCopy(m_InternalImages[1]); - // clean smartpointer - m_InternalImages[0] = NULL; - m_InternalImages[0] = i0; - append_filter->AddInput(m_InternalImages[0]); - - vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); - i1->ShallowCopy(m_InternalImages[2]); - // clean smartpointer - m_InternalImages[1] = NULL; - m_InternalImages[1] = i1; - append_filter->AddInput(m_InternalImages[1]); - - vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); - i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); - // clean smartpointer - m_InternalImages[2] = NULL; - m_InternalImages[2] = i2; - append_filter->AddInput(m_InternalImages[2]); - } - // if we go BACKWARD and step == 1 - else - { - vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); - i2->ShallowCopy(m_InternalImages[1]); - // clean smartpointer - m_InternalImages[2] = NULL; - m_InternalImages[2] = i2; - append_filter->AddInput(m_InternalImages[2]); - - vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); - i1->ShallowCopy(m_InternalImages[0]); - // clean smartpointer - m_InternalImages[1] = NULL; - m_InternalImages[1] = i1; - append_filter->AddInput(m_InternalImages[1]); - - vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); - i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); - // clean smartpointer - m_InternalImages[0] = NULL; - m_InternalImages[0] = i0; - append_filter->AddInput(m_InternalImages[0]); - } - } - - append_filter->Update(); - - if ( this->m_NavigationDockWidget->ShowAllChannels() ) - { - m_Image->ShallowCopy( append_filter->GetOutput() ); - - // LUT DISABLED - this->findChild("LUT")->setEnabled(false); - this->findChild("ScalarBar")->setEnabled(false); - } else { - int ch = this->m_NavigationDockWidget->GetCurrentChannel(); - if ( ch != -1 ) - { - m_Image->ShallowCopy(m_InternalImages[ch]); - } - // LUT ENABLED - this->findChild("LUT")->setEnabled(true); - this->findChild("ScalarBar")->setEnabled(true); + m_ImageView->SetImage(NULL); + m_ImageView->SetLookupTable(NULL); } - - // Create channels names - QString t_minus_step; - t_minus_step.append( QLatin1String("t: ") ); // + m_DopplerStep); - t_minus_step.append( QString::number(t0, 10) ); - - QString t_current_step; - t_current_step.append( QLatin1String("t: ") ); // + m_DopplerStep); - t_current_step.append( QString::number(t1, 10) ); - - QString t_plus_step; - t_plus_step.append( QLatin1String("t: ") ); //() + m_DopplerStep); - t_plus_step.append( QString::number(t2, 10) ); - - // update channels in navigation DockWidget - m_NavigationDockWidget->SetNumberOfChannels(3); - m_NavigationDockWidget->blockSignals(true); - // Create the channels labels - m_NavigationDockWidget->SetChannel(0, t_minus_step); - m_NavigationDockWidget->SetChannel(1, t_current_step); - m_NavigationDockWidget->SetChannel(2, t_plus_step); - // Update the current channel - m_NavigationDockWidget->SetCurrentChannel(1); - m_NavigationDockWidget->blockSignals(false); - - //update channels in segmentation widgets - // Create the channels labels - m_ContourSegmentationDockWidget->SetNumberOfChannels(3); - m_ContourSegmentationDockWidget->SetChannel(0, t_minus_step); - m_ContourSegmentationDockWidget->SetChannel(1, t_current_step); - m_ContourSegmentationDockWidget->SetChannel(2, t_plus_step); - // Update the current channel - m_ContourSegmentationDockWidget->SetCurrentChannel(1); - - // Create the channels labels - m_MeshSegmentationDockWidget->SetNumberOfChannels(3); - m_MeshSegmentationDockWidget->SetChannel(0, t_minus_step); - m_MeshSegmentationDockWidget->SetChannel(1, t_current_step); - m_MeshSegmentationDockWidget->SetChannel(2, t_plus_step); - // Update the current channel - m_MeshSegmentationDockWidget->SetCurrentChannel(1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -QGoTabImageView3DwT::SetTimePointWithLSMReaders() +QGoTabImageView3DwT::BuildDopplerWidget() { - m_LSMReader[0]->SetUpdateTimePoint(m_TCoord); - - int NumberOfChannels = m_LSMReader[0]->GetNumberOfChannels(); - - if ( NumberOfChannels > 1 ) + // update widget + //update values - show requiered widgets + std::vector time = m_ImageProcessor->getDopplerTime(m_TCoord); + // get number of items in container + // requiereds to call this method since the number of items varies + for(unsigned int i=0; igetDopplerSize(); ++i) { - m_InternalImages[0] = m_LSMReader[0]->GetOutput(); - - vtkSmartPointer< vtkImageAppendComponents > append_filter = - vtkSmartPointer< vtkImageAppendComponents >::New(); - append_filter->AddInput(m_InternalImages[0]); - - for ( int i = 1; i < NumberOfChannels; i++ ) + if(time[i]>=0) { - m_LSMReader[i]->SetUpdateTimePoint(m_TCoord); - m_LSMReader[i]->Update(); - - m_InternalImages[i] = m_LSMReader[i]->GetOutput(); - append_filter->AddInput(m_InternalImages[i]); - } - // This is really stupid!!! - if ( NumberOfChannels < 3 ) - { - for ( int i = NumberOfChannels; i < 3; i++ ) - { - append_filter->AddInput(m_InternalImages[0]); - } + std::string name = m_ImageProcessor->getChannelName(time[i]); + // channel color + std::vector color = m_ImageProcessor->getColor(name); + // update navigation dockwidget + m_NavigationDockWidget->AddDoppler( + QString::fromStdString(name), + QColor(color[0], + color[1], + color[2], + color[3]), + time[i], + true); // all checkboxes are check edwhen we start } - append_filter->Update(); - - m_Image->ShallowCopy( append_filter->GetOutput() ); - } - else - { - m_LSMReader[0]->Update(); - - m_Image->ShallowCopy( m_LSMReader[0]->GetOutput() ); } + // set channel name + this->m_NavigationDockWidget->setChannelName( + QString("Channel %1").arg(m_ImageProcessor->getDopplerChannel())); } //------------------------------------------------------------------------- @@ -1981,72 +1801,41 @@ QGoTabImageView3DwT::SetTimePoint(const int & iTimePoint) QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); - if ( !m_LSMReader.empty() ) + m_TCoord = iTimePoint; + + if (!m_ImageProcessor->getDopplerMode()) { - if ( iTimePoint >= m_LSMReader[0]->GetNumberOfTimePoints() ) - { - return; - } - else - { - m_TCoord = iTimePoint; - SetTimePointWithLSMReaders(); - emit TimePointChanged(m_TCoord); - } + // update image processor + m_ImageProcessor->setTimePoint(m_TCoord); } else { - if ( !m_FileList.empty() ) - { - unsigned int t = static_cast< unsigned int >( iTimePoint ); - if ( ( t < m_MegaCaptureReader->GetMinTimePoint() ) - || ( t > m_MegaCaptureReader->GetMaxTimePoint() ) ) - { - return; - } - else - { - int previousT = m_TCoord; - m_TCoord = iTimePoint; - if ( m_ChannelClassicMode ) - { - //qDebug() << "CLASSIC mode"; - SetTimePointWithMegaCapture(); - } - else - { - //qDebug() << "TRACK mode"; - //qDebug() << "CHANNEL: " << m_ChannelOfInterest; - SetTimePointWithMegaCaptureTimeChannels(m_ChannelOfInterest, previousT); - } - emit TimePointChanged(m_TCoord); - } - } - else - { - // no lsm reader, no file list. did you really provide any input? - qWarning() << "No lsm reader. No file list"; - } + // delete previous doppler widget + this->m_NavigationDockWidget->DeleteDopplerWidgets(); + // update the image processor + m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... + //rebuild navigation widget + BuildDopplerWidget(); } + UpdateImage(); + + EnableVolumeRendering(this->m_ViewActions.at(12)->isChecked()); + + // for the trace widget, navigation widget and table widget + emit TimePointChanged(m_TCoord); + this->m_ContourContainer->ShowActorsWithGivenTimePoint(m_TCoord); this->m_MeshContainer->ShowActorsWithGivenTimePoint(m_TCoord); - //this->m_TrackContainer->ShowActorsWithGivenTimePoint(m_TCoord); - Update(); + m_ImageView->Update(); QApplication::restoreOverrideCursor(); } - //------------------------------------------------------------------------- -void QGoTabImageView3DwT::Update() -{ - m_ImageView->SetImage(m_Image); - m_ImageView->Update(); -} //------------------------------------------------------------------------- -void +/*void QGoTabImageView3DwT::ChangeLookupTable() { vtkImageData *image = m_ImageView->GetImage(); @@ -2063,7 +1852,7 @@ QGoTabImageView3DwT::ChangeLookupTable() lut->Delete(); } } -} +}*/ //------------------------------------------------------------------------- @@ -2257,111 +2046,59 @@ QGoTabImageView3DwT::ChangeBackgroundColor() //------------------------------------------------------------------------- void -QGoTabImageView3DwT::ShowAllChannels(bool iChecked) +QGoTabImageView3DwT::ModeChanged(int iChannel) { - if ( iChecked ) + if ( iChannel == 1 ) { - // Requiered if we modified the window level - /** \todo Nicolas-Find a better solution */ - m_ImageView->ResetWindowLevel(); - - vtkSmartPointer< vtkImageAppendComponents > append_filter = - vtkSmartPointer< vtkImageAppendComponents >::New(); - - for ( unsigned int i = 0; i < m_InternalImages.size(); i++ ) - { - append_filter->AddInput(m_InternalImages[i]); - } - - // This is really stupid!!! - if ( m_InternalImages.size() < 3 ) - { - for ( size_t i = m_InternalImages.size(); i < 3; i++ ) - { - append_filter->AddInput(m_InternalImages[0]); - } - } - - append_filter->Update(); - - m_Image->ShallowCopy( append_filter->GetOutput() ); - Update(); - - // Update LUT - this->findChild("LUT")->setEnabled(false); - this->findChild("ScalarBar")->setEnabled(false); + // set image processor and build navigation widget if we click on ok + StartDopplerView(); } else { - int ch = this->m_NavigationDockWidget->GetCurrentChannel(); - if ( ch != -1 ) - { - m_Image->ShallowCopy(m_InternalImages[ch]); - Update(); - } - - // Update LUT - this->findChild("LUT")->setEnabled(true); - this->findChild("ScalarBar")->setEnabled(true); - - // show the scalarbar automatically if the button is checked - bool showScalarBar = this->findChild("ScalarBar")->isChecked(); - m_ImageView->ShowScalarBar(showScalarBar); - } -} - -//------------------------------------------------------------------------ - -//------------------------------------------------------------------------- -void -QGoTabImageView3DwT::ShowOneChannel(int iChannel) -{ - if ( ( iChannel != -1 ) && ( !m_InternalImages.empty() ) ) - { - // Update lut - this->findChild("LUT")->setEnabled(true); - this->findChild("ScalarBar")->setEnabled(true); - - m_Image->ShallowCopy(m_InternalImages[iChannel]); - Update(); + this->m_NavigationDockWidget->DeleteDopplerWidgets(); + m_ImageProcessor->setDopplerMode(false, 0); + // update image processor + m_ImageProcessor->initTimePoint(m_TCoord); + // change visibility + this->m_NavigationDockWidget->VisibilityListChannels(true); } -} - -//------------------------------------------------------------------------ -//------------------------------------------------------------------------- -void -QGoTabImageView3DwT::ModeChanged(int iChannel) -{ - //std::cout << "channel: " << iChannel << std::endl; - - if ( iChannel == 1 ) - { - LoadChannelTime(); - } - - ChannelTimeMode(iChannel); + //update images + UpdateImage(); + // update visualization + m_ImageView->Update(); + //update the trace editing widget + UpdateTracesEditingWidget(); } - //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::StepChanged(int iStep) { - m_DopplerStep = iStep; - - SetTimePointWithMegaCaptureTimeChannels(m_ChannelOfInterest); - Update(); + // delete previous doppler widget + this->m_NavigationDockWidget->DeleteDopplerWidgets(); + // set the new doppler step + m_ImageProcessor->setDopplerStep(iStep); + // update the image processor + m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... + //rebuild navigation widget + BuildDopplerWidget(); + // build new image + UpdateImage(); + //update + m_ImageView->Update(); + //update the trace editing widget + UpdateTracesEditingWidget(); } - //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -QGoTabImageView3DwT::SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes) +QGoTabImageView3DwT::SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes, + int iTCoord) { - if ( ( contour->GetNumberOfPoints() > 2 ) && ( m_TCoord >= 0 ) ) + if ( ( contour->GetNumberOfPoints() > 2 ) && ( iTCoord >= 0 ) ) { // Compute Bounding Box std::vector< int > bounds = GetBoundingBox(contour); @@ -2369,7 +2106,7 @@ QGoTabImageView3DwT::SaveContour(vtkPolyData *contour, vtkPolyData *contour_node this->m_DataBaseTables->SaveContoursFromVisuInDB(bounds[0], bounds[2], bounds[4], - m_TCoord, + iTCoord, bounds[1], bounds[3], bounds[5], @@ -2405,7 +2142,7 @@ QGoTabImageView3DwT::GetBoundingBox(vtkPolyData *iElement) int *max_idx = this->GetImageCoordinatesFromWorldCoordinates(Max); int extent[6]; - this->m_Image->GetExtent(extent); + m_ImageProcessor->getImageBW()->GetExtent(extent); for ( i = 0; i < 3; i++ ) { @@ -2469,10 +2206,9 @@ QGoTabImageView3DwT::VisualizeTrace(vtkPolyData *iTrace, double *iRGBA) //------------------------------------------------------------------------- void -QGoTabImageView3DwT::ValidateContour() +QGoTabImageView3DwT::ValidateContour(int iTCoord) { - bool re_edit = m_ContourSegmentationDockWidget->GetReeditMode(); - + bool re_edit = this->m_ContourEditingWidget->GetReeditMode(); for ( int i = 0; i < m_ImageView->GetNumberOfImageViewers(); i++ ) { vtkPolyData *nodes = m_ImageView->GetContourRepresentationNodePolydata(i); @@ -2485,7 +2221,7 @@ QGoTabImageView3DwT::ValidateContour() contour->DeepCopy( m_ImageView->GetContourRepresentationAsPolydata(i) ); //polydata for bounding box, node for points - SaveContour(contour, nodes); + SaveContour(contour, nodes, iTCoord); // polydata //ADD TRACE ID IN POLYDATA @@ -2499,7 +2235,8 @@ QGoTabImageView3DwT::ValidateContour() //nodes m_ContourContainer->UpdateCurrentElementFromVisu(actors, nodes, - m_TCoord, + // m_TCoord, + iTCoord, re_edit, //highlighted true); //visible @@ -2511,9 +2248,10 @@ QGoTabImageView3DwT::ValidateContour() { this->m_TraceSettingsToolBar->setEnabled(true); this->m_TraceSettingsWidget->setEnabled(true); - m_ContourSegmentationDockWidget->SetReeditMode(false); + this->m_ContourEditingWidget->SetReeditMode(false); m_ImageView->ReinitializeContourWidget(); - m_ContourSegmentationDockWidget->hide(); + //m_ContourSegmentationDockWidget->hide(); + this->m_ContourEditingWidget->GetDockWidget()->hide(); } } @@ -2567,9 +2305,12 @@ QGoTabImageView3DwT::ReEditContour(const unsigned int & iId) this->m_TraceSettingsToolBar->setEnabled(false); this->m_TraceSettingsWidget->setEnabled(false); - this->m_ContourSegmentationDockWidget->show(); - this->m_ContourSegmentationDockWidget->SegmentationMethod(0); - this->m_ContourSegmentationDockWidget->SetReeditMode(true); + //this->m_ContourSegmentationDockWidget->show(); + //this->m_ContourSegmentationDockWidget->SegmentationMethod(0); + //this->m_ContourSegmentationDockWidget->SetReeditMode(true); + this->m_ContourEditingWidget->SetReeditMode(true); + this->m_ContourEditingWidget->GetDockWidget()->show(); + } } } @@ -2683,7 +2424,7 @@ int QGoTabImageView3DwT::GetTimePoint() const //------------------------------------------------------------------------- int QGoTabImageView3DwT::GetTimeInterval() const { - return static_cast< int >( m_MegaCaptureReader->GetTimeInterval() ); + return m_ImageProcessor->getTimeInterval(); } //------------------------------------------------------------------------- @@ -2742,7 +2483,7 @@ QGoTabImageView3DwT::SetSliceView() //------------------------------------------------------------------------- int -QGoTabImageView3DwT::SaveAndVisuContour(vtkPolyData *iView) +QGoTabImageView3DwT::SaveAndVisuContour(int iTCoord, vtkPolyData *iView) { if ( !m_DataBaseTables->IsDatabaseUsed() ) { @@ -2761,7 +2502,7 @@ QGoTabImageView3DwT::SaveAndVisuContour(vtkPolyData *iView) CreateContour(contour_nodes, iView); // polydata for bounding box, nodes for db - SaveContour(iView, contour_nodes); + SaveContour(iView, contour_nodes, iTCoord); AddTraceIDIntoPolydata(iView, this->m_ContourContainer->m_CurrentElement.TraceID, "CONTOUR"); @@ -2775,7 +2516,8 @@ QGoTabImageView3DwT::SaveAndVisuContour(vtkPolyData *iView) // update the container m_ContourContainer->UpdateCurrentElementFromVisu(actors, contour_nodes, - m_TCoord, + //m_TCoord, + iTCoord, false, //highlighted true); //visible @@ -2814,21 +2556,19 @@ QGoTabImageView3DwT::CreateContour(vtkPolyData *contour_nodes, vtkPolyData *iVie //------------------------------------------------------------------------- void -QGoTabImageView3DwT::SaveMesh(vtkPolyData *iView, int iTShift) +QGoTabImageView3DwT::SaveMesh(vtkPolyData *iView, int iTCoord) { // Compute Bounding Box std::vector< int > bounds = this->GetBoundingBox(iView); - int tcoord = static_cast< int >( m_TCoord ) + iTShift; - // Save mesh in database GoFigureMeshAttributes MeshAttributes = - ComputeMeshAttributes( iView, true, static_cast< unsigned int >( tcoord ) ); + ComputeMeshAttributes( iView, true, static_cast< unsigned int >( iTCoord ) ); this->m_DataBaseTables->SaveMeshFromVisuInDB(bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5], - iTShift, + iTCoord, iView, &MeshAttributes); } @@ -2836,33 +2576,84 @@ QGoTabImageView3DwT::SaveMesh(vtkPolyData *iView, int iTShift) //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void +/*void QGoTabImageView3DwT::SaveAndVisuMeshFromSegmentation(vtkPolyData *iView, int iTCoord) { SaveAndVisuMesh(iView, m_TCoord, iTCoord); +}*/ +void +QGoTabImageView3DwT::SaveInDBAndRenderMeshForVisu( + std::vector iVectPolydata, int iTCoord) +{ + std::cout<< "reveived..." << std::endl; + std::vector::iterator iter = iVectPolydata.begin(); + while(iter != iVectPolydata.end()) + { + SaveAndVisuMesh(*iter, iTCoord); + ++iter; + } +} +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +SaveInDBAndRenderSetOfContoursForVisu( + std::vector > iVectorSetOfContours, int iTCoord) +{ + // just add to visu as of now + std::vector >::iterator it1 = + iVectorSetOfContours.begin(); + while(it1!=iVectorSetOfContours.end()) + { + std::vector::iterator it2 = (*it1).begin(); + while(it2!=(*it1).end()) + { + vtkPolyData* data = vtkPolyData::New(); + data->DeepCopy(*it2); + this->AddContour(data); + ++it2; + } + ++it1; + } } +//------------------------------------------------------------------------- +void QGoTabImageView3DwT::SaveInDBAndRenderContourForVisu( + std::vector iVectPolydata, int iTCoord) +{ + std::vector::iterator iter = iVectPolydata.begin(); + while(iter != iVectPolydata.end()) + { + std::cout << "receive polydata" << std::endl; + vtkPolyData* data = vtkPolyData::New(); + data->DeepCopy(*iter); + this->AddContour(data); + //SaveAndVisuContour(*iter, m_TCoord, iTCoord); + ++iter; + } + +} //------------------------------------------------------------------------- //------------------------------------------------------------------------- void QGoTabImageView3DwT::SaveAndVisuMesh(vtkPolyData *iView, - unsigned int iTCoord, - int iTShift) + unsigned int iTCoord) { - if ( !this->m_ChannelClassicMode ) + /* + if (m_ImageProcessor->getDopplerMode()) { - iTShift = iTShift * m_DopplerStep; + iTShift = iTShift * m_ImageProcessor->getDopplerStep(); + unsigned int* time = m_ImageProcessor->getBoundsTime(); - if ( iTCoord + iTShift < m_MegaCaptureReader->GetMinTimePoint() ) + if ( iTCoord + iTShift < time[0] ) { - iTShift = -( m_TCoord - m_MegaCaptureReader->GetMinTimePoint() ); + iTShift = -( m_TCoord - time[0] ); } else { - if ( iTCoord + iTShift > m_MegaCaptureReader->GetMaxTimePoint() ) + if ( iTCoord + iTShift > time[1] ) { - iTShift = m_MegaCaptureReader->GetMaxTimePoint() - m_TCoord; + iTShift = time[1] - m_TCoord; } } } @@ -2874,7 +2665,7 @@ QGoTabImageView3DwT::SaveAndVisuMesh(vtkPolyData *iView, { std::cerr << "Problem with DB" << std::endl; return; - } + }*/ if ( !iView ) { @@ -2882,7 +2673,13 @@ QGoTabImageView3DwT::SaveAndVisuMesh(vtkPolyData *iView, return; } - SaveMesh(iView, iTShift); + std::cout << "save mesh..." << std::endl; + + SaveMesh(iView, iTCoord); + + std::cout << "add mesh to visu..." << std::endl; + + // should be done in the mesh manager, from goprintdatabase //ADD TRACE ID IN POLYDATA AddTraceIDIntoPolydata(iView, this->m_MeshContainer->m_CurrentElement.TraceID, "MESH"); @@ -2894,7 +2691,7 @@ QGoTabImageView3DwT::SaveAndVisuMesh(vtkPolyData *iView, // update container since a new mesh is created m_MeshContainer->UpdateCurrentElementFromVisu(actors, iView, - iTCoord + iTShift, + iTCoord, false, // highlighted true); // visible m_MeshContainer->InsertCurrentElement(); @@ -2981,17 +2778,16 @@ ComputeMeshAttributes(vtkPolyData *iMesh, calculator->SetIntensityBasedComputation(iIntensity); GoFigureMeshAttributes oAttributes; - - if( this->m_ChannelClassicMode ) + if(!m_ImageProcessor->getDopplerMode()) { - for ( size_t i = 0; i < m_InternalImages.size(); i++ ) + for ( size_t i = 0; i < m_ImageProcessor->getNumberOfChannels(); i++ ) { vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); itk::VTKImageImport< ImageType >::Pointer itk_importer = itk::VTKImageImport< ImageType >::New(); - vtk_exporter->SetInput(m_InternalImages[i]); + vtk_exporter->SetInput(m_ImageProcessor->getImageBW(i)); ConnectPipelines< vtkImageExport, itk::VTKImageImport< ImageType >::Pointer >( vtk_exporter, itk_importer); @@ -2999,14 +2795,12 @@ ComputeMeshAttributes(vtkPolyData *iMesh, calculator->Update(); oAttributes.m_Volume = calculator->GetPhysicalSize(); - //qDebug() << "volume:" << oAttributes.m_Volume; oAttributes.m_Area = calculator->GetArea(); oAttributes.m_Size = calculator->GetSize(); if ( iIntensity ) { - QString q_channelname = this->m_ChannelNames[i]; - std::string channelname = q_channelname.toStdString(); + std::string channelname = m_ImageProcessor->getChannelName(i); oAttributes.m_TotalIntensityMap[channelname] = static_cast< int >( calculator->GetSumIntensity() ); @@ -3021,18 +2815,17 @@ ComputeMeshAttributes(vtkPolyData *iMesh, } else { - unsigned int min_ch = m_MegaCaptureReader->GetMinChannel(); - unsigned int max_ch = m_MegaCaptureReader->GetMaxChannel(); - unsigned int NumberOfChannels = max_ch - min_ch + 1; + unsigned int* boundChannel = m_ImageProcessor->getBoundsChannel(); + unsigned int NumberOfChannels = m_ImageProcessor->getNumberOfChannels(); std::vector< vtkSmartPointer< vtkImageData > > temp_image( NumberOfChannels ); - m_MegaCaptureReader->SetTimePoint( iTCoord ); - m_MegaCaptureReader->Update(); + // load real image + m_ImageProcessor->initTimePoint(iTCoord); - for ( unsigned int i = min_ch; i <= max_ch; i++ ) + for ( unsigned int i = boundChannel[0]; i <= boundChannel[1]; i++ ) { - temp_image[i] = m_MegaCaptureReader->GetOutput( i ); + temp_image[i] = m_ImageProcessor->getImageBW(i); vtkSmartPointer< vtkImageExport > vtk_exporter = vtkSmartPointer< vtkImageExport >::New(); @@ -3053,8 +2846,7 @@ ComputeMeshAttributes(vtkPolyData *iMesh, if ( iIntensity ) { - QString q_channelname = this->m_ChannelNames[i]; - std::string channelname = q_channelname.toStdString(); + std::string channelname = m_ImageProcessor->getChannelName(i); oAttributes.m_TotalIntensityMap[channelname] = static_cast< int >( calculator->GetSumIntensity() ); @@ -3066,6 +2858,9 @@ ComputeMeshAttributes(vtkPolyData *iMesh, break; } } + // load doppler image + // visibility should be updated... + m_ImageProcessor->setDoppler(m_TCoord, 0); } return oAttributes; } @@ -3139,7 +2934,8 @@ QGoTabImageView3DwT::CreateMeshFromSelectedContours( vtkPolyData *mesh = filter->GetOutput(); vtkBox *implicitFunction = vtkBox::New(); - implicitFunction->SetBounds( m_InternalImages[0]->GetBounds() ); + // get bounds from the first visible image + implicitFunction->SetBounds( m_ImageProcessor->getImageBW()->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput(mesh); @@ -3157,7 +2953,7 @@ QGoTabImageView3DwT::CreateMeshFromSelectedContours( //as the element is already in the container we need to delete it in order //to update it in the SaveAndVisuMesh: this->m_MeshContainer->RemoveElementFromVisualizationWithGivenTraceID(iMeshID); - SaveAndVisuMesh(temp, tcoord, 0); + SaveAndVisuMesh(temp, tcoord); } } @@ -3224,8 +3020,8 @@ QGoTabImageView3DwT::SetTraceSettingsToolBarVisible(bool IsVisible) { if (!IsVisible) { - if (!this->m_ContourSegmentationDockWidget->toggleViewAction()->isChecked() && - !this->m_MeshSegmentationDockWidget->toggleViewAction()->isChecked() && + if (!this->m_ContourEditingWidget->GetToggleViewAction()->isChecked() && + !this->m_MeshEditingWidget->GetToggleViewAction()->isChecked() && !this->m_DataBaseTables->toggleViewAction()->isChecked() ) { this->m_TraceSettingsToolBar->setVisible(IsVisible); @@ -3233,15 +3029,15 @@ QGoTabImageView3DwT::SetTraceSettingsToolBarVisible(bool IsVisible) } else { - if (this->m_ContourSegmentationDockWidget->toggleViewAction()->isChecked()) + if (this->m_ContourEditingWidget->GetToggleViewAction()->isChecked()) { this->m_DataBaseTables->SetTraceNameForTableWidget("contour"); } - if (this->m_MeshSegmentationDockWidget->toggleViewAction()->isChecked() ) + if (this->m_MeshEditingWidget->GetToggleViewAction()->isChecked() ) { this->m_DataBaseTables->SetTraceNameForTableWidget("mesh"); } - if(this->m_DataBaseTables->NeedTraceSettingsToolBarVisible() ) //if the dockwidget is not on floating mode + if(this->m_DataBaseTables->NeedTraceSettingsToolBarVisible() ) //if the dockwidget is not on floating mode //or if the trace settings widget is not already visible in the dockwidget or if the TW is not visible { this->m_TraceSettingsToolBar->setVisible(IsVisible); @@ -3256,53 +3052,61 @@ QGoTabImageView3DwT::InitializeToolsForTracesToolBar( QMenu* iMenu, QToolBar* iToolBar) { //iToolBar->clear(); - QGoToolBarStatus* TracesToolBar = + QGoToolBarStatus* TracesToolBar = new QGoToolBarStatus(iToolBar, iMenu, Qt::TopToolBarArea, true, true, this); QActionGroup* group = this->findChild< QActionGroup* >("ModeGroup"); //Contour Editing QAction *ContourSegmentationAction = - m_ContourSegmentationDockWidget->toggleViewAction(); + this->m_ContourEditingWidget->GetToggleViewAction(); ContourSegmentationAction->setParent(this); ContourSegmentationAction->setObjectName("ContourEditingMode"); group->addAction(ContourSegmentationAction); //group->addAction(this->m_ContourSegmentationDockWidget->GetActionForToggle() ); - TracesToolBar->m_VectorAction.push_back(ContourSegmentationAction); - //this->m_TracesActions.push_back(this->m_ContourSegmentationDockWidget->GetActionForToggle()); + TracesToolBar->m_VectorAction.push_back(ContourSegmentationAction); + //this->m_TracesActions.push_back(this->m_ContourSegmentationDockWidget->GetActionForToggle()); //Mesh Editing QAction *MeshSegmentationAction = - m_MeshSegmentationDockWidget->toggleViewAction(); + this->m_MeshEditingWidget->GetToggleViewAction(); group->addAction(MeshSegmentationAction); TracesToolBar->m_VectorAction.push_back(MeshSegmentationAction); // Track Color Coding - TracesToolBar->m_VectorAction.push_back( + TracesToolBar->m_VectorAction.push_back( m_TrackViewDockWidget->toggleViewAction() ); // Lineage Color Coding - TracesToolBar->m_VectorAction.push_back( + TracesToolBar->m_VectorAction.push_back( m_LineageViewDockWidget->toggleViewAction() ); + //QObject::connect( ContourSegmentationAction, + // SIGNAL( toggled(bool) ), + // m_ContourSegmentationDockWidget, + // SLOT( interactorBehavior(bool) ) ); QObject::connect( ContourSegmentationAction, SIGNAL( toggled(bool) ), - m_ContourSegmentationDockWidget, - SLOT( interactorBehavior(bool) ) ); + m_ContourEditingWidget, + SLOT( SetVisible(bool) ) ); QObject::connect( ContourSegmentationAction, SIGNAL( toggled(bool) ), this, SLOT( SetTraceSettingsToolBarVisible(bool) ) ); + //QObject::connect( MeshSegmentationAction, + // SIGNAL( toggled(bool) ), + // m_MeshSegmentationDockWidget, + // SLOT( interactorBehavior(bool) ) ); QObject::connect( MeshSegmentationAction, SIGNAL( toggled(bool) ), - m_MeshSegmentationDockWidget, - SLOT( interactorBehavior(bool) ) ); + m_MeshEditingWidget, + SLOT( SetVisible(bool) ) ); QObject::connect( MeshSegmentationAction, SIGNAL( toggled(bool) ), @@ -3326,6 +3130,45 @@ QGoTabImageView3DwT::InitializeTraceSettingsToolBar(QToolBar* iToolBar) } //------------------------------------------------------------------------- +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT::UpdateTracesEditingWidget() +{ + if (this->m_MeshEditingWidget != NULL && this->m_ContourEditingWidget != NULL) + { + if (!this->m_ImageProcessor->getDopplerMode()) + { + this->m_MeshEditingWidget->SetTSliceForClassicView(); + this->m_ContourEditingWidget->SetTSliceForClassicView(); + } + else + { + std::map ListTimePoints; + std::vector dopplerT = + this->m_ImageProcessor->getDopplerTime(this->m_TCoord); + + for(unsigned int i=0; im_ImageProcessor->getDopplerSize(); ++i) + { + if (dopplerT[i] >= 0 ) + { + double* rgb = vtkMath::HSVToRGB( + static_cast(i) / + static_cast( + this->m_ImageProcessor->getDopplerSize()),1,1); + QColor color(rgb[0]*255, rgb[1]*255, rgb[2]*255); + ListTimePoints[tr("%1").arg(dopplerT[i])] = color; + } + } + + this->m_MeshEditingWidget->SetTSliceForDopplerView(ListTimePoints, + m_ImageProcessor->getDopplerChannel()); + this->m_ContourEditingWidget->SetTSliceForDopplerView(ListTimePoints, + m_ImageProcessor->getDopplerChannel()); + } + } +} +//------------------------------------------------------------------------- + //------------------------------------------------------------------------- void QGoTabImageView3DwT::CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar) @@ -3449,3 +3292,112 @@ QGoTabImageView3DwT::CreateModeToolBar(QMenu* iMenu, QToolBar* iToolBar) //this->m_ToolBarList.push_back(this->m_ModeToolBar); } +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +visibilityChanged(QString iName, bool iVisibility) +{ + m_ImageProcessor->visibilityChanged(iName.toStdString(), iVisibility); + UpdateImage(); + //if we are in volume rendering + EnableVolumeRendering(this->m_ViewActions.at(12)->isChecked()); + // update visu + m_ImageView->Update(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +DopplerSizeChanged(int iDopplerSize) +{ + // delete previous doppler widget + this->m_NavigationDockWidget->DeleteDopplerWidgets(); + // set the new doppler step + m_ImageProcessor->setDopplerSize(iDopplerSize); + // update the image processor + m_ImageProcessor->setDoppler(m_TCoord, 0); // 0 is for optimization later on... + //rebuild navigation widget + BuildDopplerWidget(); + // build new image + UpdateImage(); + //update + m_ImageView->Update(); + //update the trace editing widget + UpdateTracesEditingWidget(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +openTransferFunctionEditor(QString iName) +{ + // create editor + GoTransferFunctionEditorWidget* editor = + new GoTransferFunctionEditorWidget(NULL, iName ); + // connect signals + + QObject::connect( editor, + SIGNAL( updateVisualization() ), + this, + SLOT( updateSlot()) ); + + QObject::connect( editor, + SIGNAL( updatePoints(QString, std::vector< std::map< unsigned int, unsigned int> >) ), + this, + SLOT( updatePoints(QString, std::vector< std::map< unsigned int, unsigned int> >)) ); + + // show editor - to have consistent geomerty to add the points + editor->show(); + // add color + editor->AddColor(m_ImageProcessor->getColor(iName.toStdString())); + // add points + editor->AddPoints(m_ImageProcessor->getRGBA(iName.toStdString())); + // add LUT + editor->AddLookupTable(m_ImageProcessor->getLookuptable(iName.toStdString())); + // add Opacity TF + editor->AddOpacityTransferFunction( + m_ImageProcessor->getOpacityTransferFunction(iName.toStdString())); + // add histogram - should not recalculate all the time... + editor->AddHistogram(m_ImageProcessor->getHistogram(iName.toStdString())); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +// color changed +void +QGoTabImageView3DwT::updateSlot() +{ + UpdateImage(); + EnableVolumeRendering(this->m_ViewActions.at(12)->isChecked()); + m_ImageView->Update(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +updatePoints(QString iName, std::vector< std::map< unsigned int, unsigned int> > iPoints) +{ + m_ImageProcessor->updatePoints(iName.toStdString(), iPoints); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +QGoTabImageView3DwT:: +EnableVolumeRendering(bool iEnable) +{ + if(iEnable) + { + m_ImageView->EnableVolumeRendering(m_ImageProcessor->getColoredImages(), + m_ImageProcessor->getOpacityTransferFunctions()); + } + else + { + m_ImageView->DisableVolumeRendering(); + } +} diff --git a/Code/GUI/lib/QGoTabImageView3DwT.h b/Code/GUI/lib/QGoTabImageView3DwT.h index 5e09b51b..fcf41f34 100644 --- a/Code/GUI/lib/QGoTabImageView3DwT.h +++ b/Code/GUI/lib/QGoTabImageView3DwT.h @@ -54,9 +54,13 @@ #include "vtkSmartPointer.h" +#include "GoImageProcessor.h" + // base segmentation dock widget -class QGoContourSegmentationBaseDockWidget; -class QGoMeshSegmentationBaseDockWidget; +class QGoContourEditingWidgetManager; +class QGoMeshEditingWidgetManager; +//class QGoContourSegmentationBaseDockWidget; +//class QGoMeshSegmentationBaseDockWidget; //track dockwidget class QGoTrackViewDockWidget; @@ -136,11 +140,6 @@ class QGOGUILIB_EXPORT QGoTabImageView3DwT:public QGoTabElementBase const std::string & iHeader, const unsigned int & iTimePoint); - /** - * \brief - */ - virtual void Update(); - /** * \brief * \param parent @@ -271,6 +270,8 @@ public slots: void GoToDefaultMenu(bool iEnable = false); + void updatePoints(QString, std::vector< std::map< unsigned int, unsigned int> >); + #if defined ( ENABLEFFMPEG ) || defined ( ENABLEAVI ) void SetRendererWindow(int); #endif /* ENABLEVIDEORECORD */ @@ -305,33 +306,38 @@ public slots: void FullScreenViewXYZ(); - void ChangeLookupTable(); + //void ChangeLookupTable(); void ChangeBackgroundColor(); - void ShowAllChannels(bool iChecked); - - void ShowOneChannel(int iChannel); - void ModeChanged(int iChannel); void StepChanged(int iStep); - void ValidateContour(); + void DopplerSizeChanged( int iSize); - int SaveAndVisuContour(vtkPolyData *iView = NULL); + void ValidateContour(int iTCoord); + + int SaveAndVisuContour(int iTCoord, vtkPolyData *iView = NULL); //void SaveAndVisuContoursList(std::vector* iContours); /** \brief Save a mesh in the database and render the mesh * at the given time point. \todo to be renamed */ - void SaveAndVisuMesh(vtkPolyData *iView, unsigned int iTCoord, int iTShift); + void SaveAndVisuMesh(vtkPolyData *iView, unsigned int iTCoord); /** \brief Save a mesh in the database and render the mesh. * at the current time point - \todo to be renamed */ - void SaveAndVisuMeshFromSegmentation(vtkPolyData *iView, int iTCoord); + */ + void SaveInDBAndRenderMeshForVisu( + std::vector iVectPolydata, int iTCoord); + + void SaveInDBAndRenderSetOfContoursForVisu( + std::vector >, int); + + void SaveInDBAndRenderContourForVisu( + std::vector iVectPolydata, int iTCoord); void ReEditContour(const unsigned int & iId); @@ -348,15 +354,20 @@ public slots: void AddContourForMeshToContours(vtkPolyData *); + void visibilityChanged(QString iName, bool iVisibility); + + void openTransferFunctionEditor(QString iName); + + void updateSlot(); + protected: QGoImageView3D * m_ImageView; - std::vector< vtkSmartPointer< vtkLSMReader > > m_LSMReader; - std::vector< vtkSmartPointer< vtkImageData > > m_InternalImages; - vtkImageData * m_Image; vtkProperty *m_HighlightedContoursProperty; vtkProperty *m_HighlightedMeshesProperty; + GoImageProcessor* m_ImageProcessor; + // TODO Nicolas don't need it... itk::MegaCaptureReader::Pointer m_MegaCaptureReader; GoFigureFileInfoHelperMultiIndexContainer m_FileList; GoFigure::FileType m_FileType; @@ -366,7 +377,6 @@ public slots: QToolBar* m_TraceSettingsToolBar; float m_IntersectionLineWidth; - std::vector< QString > m_ChannelNames; int m_PCoord; int m_RCoord; @@ -379,10 +389,12 @@ public slots: QGoNavigationDockWidget *m_NavigationDockWidget; // base segmentation dockwidget for contours - QGoContourSegmentationBaseDockWidget *m_ContourSegmentationDockWidget; + //QGoContourSegmentationBaseDockWidget *m_ContourSegmentationDockWidget; // base segmentation dockwidget for meshes - QGoMeshSegmentationBaseDockWidget *m_MeshSegmentationDockWidget; + //QGoMeshSegmentationBaseDockWidget *m_MeshSegmentationDockWidget; + QGoMeshEditingWidgetManager* m_MeshEditingWidget; + QGoContourEditingWidgetManager* m_ContourEditingWidget; QGoTrackViewDockWidget* m_TrackViewDockWidget; @@ -390,7 +402,8 @@ public slots: QGoTraceSettingsWidget* m_TraceSettingsWidget; - vtkPoints *m_Seeds; + std::vector< vtkPoints* > m_Seeds; + //std::vector m_OrderedSeeds; ContourContainer *m_ContourContainer; MeshContainer *m_MeshContainer; @@ -399,22 +412,13 @@ public slots: //bool m_TraceWidgetRequiered; - /** \brief We are in the regular visualization mode (true) or in the time - * visualization mode (false) */ - bool m_ChannelClassicMode; - /** \brief ID of the channel that we want to visualize in the time - * visualization mode */ - int m_ChannelOfInterest; - - int m_DopplerStep; - /// \todo remove m_FFMPEGWriter and m_AVIWriter from this class #if defined ENABLEFFMPEG || defined ENABLEAVI QGoVideoRecorder *m_VideoRecorderWidget; #endif /* ENABLEFFMPEG || ENABLEAVI */ - void SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes); + void SaveContour(vtkPolyData *contour, vtkPolyData *contour_nodes, int iTCoord); std::vector< vtkActor * > VisualizeTrace(vtkPolyData *iTrace, double* iRGBA); @@ -513,6 +517,32 @@ public slots: iVisible ); } + template + void CreateConnectionsTraceEditingWidget(int iTimeMin, int iTimeMax, T* iTraceWidget) + { + m_DockWidgetList.push_back( + std::pair< QGoDockWidgetStatus *, QDockWidget * >( + new QGoDockWidgetStatus( + iTraceWidget->GetDockWidget(), Qt::LeftDockWidgetArea, false, true), + iTraceWidget->GetDockWidget()) ); + + QObject::connect(iTraceWidget, + SIGNAL(UpdateSeeds() ), + this, + SLOT(UpdateSeeds() ) ); + + QObject::connect(iTraceWidget, + SIGNAL(ClearAllSeeds() ), + this->m_ImageView, + SLOT(ClearAllSeeds() ) ); + + QObject::connect( iTraceWidget, + SIGNAL( SetSeedInteractorBehaviour(bool) ), + this, + SLOT( SeedInteractorBehavior(bool) ) ); + } + + std::vector< int > GetBoundingBox(vtkPolyData *contour); void CreateContour(vtkPolyData *contour_nodes, vtkPolyData *iView); @@ -520,9 +550,9 @@ public slots: /** * \brief Save mesh in Database * \param[in] iMesh mesh to be saved - * \param[in] iTShift time shift (used in the Doppler View case) + * \param[in] iTCoord */ - void SaveMesh(vtkPolyData *iMesh, int iTShift); + void SaveMesh(vtkPolyData *iMesh, int iTCoord); void GetBackgroundColorFromImageViewer(); @@ -541,9 +571,10 @@ public slots: void CreateVisuDockWidget(); // segmentation dockwidgets - void CreateContourSegmentationDockWidget(); - - void CreateMeshSegmentationDockWidget(); + //void CreateContourSegmentationDockWidget(); + void CreateContourEditingDockWidget(int iTimeMin, int iTimeMax); + //void CreateMeshSegmentationDockWidget(); + void CreateMeshEditingDockWidget(int iTimeMin, int iTimeMax); void CreateDataBaseTablesConnection(); @@ -558,11 +589,11 @@ public slots: std::vector< vtkActor * > AddContour(vtkPolyData *dataset, vtkProperty *property = NULL); - void SetTimePointWithLSMReaders(); - - void SetTimePointWithMegaCapture(); + // TODO remove megacapture + void UpdateImage(); - void SetTimePointWithMegaCaptureTimeChannels(int channel, int PreviousT = 0); + // TODO remove megacaptureZz + void BuildDopplerWidget(); /** \brief give the adress for the contours, meshes and tracks container to the @@ -642,18 +673,11 @@ protected slots: void ImportTracks(); - /** - \brief switch between the 2 visualization modes: - -classic mode where a channel is an entity (nuclei, membrane) of interest. - -time mode where a channel represents the same entity through the time. (t-1, t and t+1). - updates the navigation widget. - */ - void ChannelTimeMode( bool ); /** \brief access to the megacapture reader to get the entity of interest images through time. updates the navigation widget. */ - void LoadChannelTime(); + void StartDopplerView(); /** \brief give the adress for the contours, meshes and tracks container to the @@ -664,7 +688,17 @@ protected slots: void AddTraceIDIntoPolydata( vtkPolyData* iPolydata, unsigned int iTraceID, const char* iTrace); + /** + \brief depending on the doppler/classic mode, update the TimePoints and channels + of the mesh and contour widget + */ + void UpdateTracesEditingWidget(); + + void EnableVolumeRendering(bool iEnable); + private: + void InitializeImageRelatedWidget(); + Q_DISABLE_COPY(QGoTabImageView3DwT); }; diff --git a/Code/GUI/lib/QGoTabImageViewNDBase.cxx b/Code/GUI/lib/QGoTabImageViewNDBase.cxx index 8ec94051..ca8fe075 100644 --- a/Code/GUI/lib/QGoTabImageViewNDBase.cxx +++ b/Code/GUI/lib/QGoTabImageViewNDBase.cxx @@ -72,26 +72,26 @@ void QGoTabImageViewNDBase::SetImage(vtkImageData *iImage) m_Image = iImage; int n = m_Image->GetNumberOfScalarComponents(); - this->m_NavigationDockWidget->SetNumberOfChannels(n); + //this->m_NavigationDockWidget->SetNumberOfChannels(n); if ( n != 1 ) { if ( ( n == 3 ) || ( n == 4 ) ) { - this->m_NavigationDockWidget->SetChannel( 0, tr("Red") ); - this->m_NavigationDockWidget->SetChannel( 1, tr("Green") ); - this->m_NavigationDockWidget->SetChannel( 2, tr("Blue") ); + //this->m_NavigationDockWidget->SetChannel( 0, tr("Red") ); + //this->m_NavigationDockWidget->SetChannel( 1, tr("Green") ); + //this->m_NavigationDockWidget->SetChannel( 2, tr("Blue") ); if ( n == 4 ) { - this->m_NavigationDockWidget->SetChannel( 3, tr("Alpha") ); + //this->m_NavigationDockWidget->SetChannel( 3, tr("Alpha") ); } } else { for ( int i = 0; i < n; i++ ) { - this->m_NavigationDockWidget->SetChannel(i); + //this->m_NavigationDockWidget->SetChannel(i); } } } @@ -135,7 +135,7 @@ void QGoTabImageViewNDBase::ShowAllChannels(bool iChecked) } else { - int ch = this->m_NavigationDockWidget->GetCurrentChannel(); + int ch = 0;//this->m_NavigationDockWidget->GetCurrentChannel(); if ( ch != -1 ) { vtkSmartPointer< vtkImageExtractComponents > extract = @@ -173,4 +173,4 @@ void QGoTabImageViewNDBase::ShowOneChannel(int iChannel) } } -//-------------------------------------------------------------------------- \ No newline at end of file +//-------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoToolBarStatus.cxx b/Code/GUI/lib/QGoToolBarStatus.cxx index a0a3f8ff..dc321fb9 100644 --- a/Code/GUI/lib/QGoToolBarStatus.cxx +++ b/Code/GUI/lib/QGoToolBarStatus.cxx @@ -38,17 +38,19 @@ QGoToolBarStatus::QGoToolBarStatus(QWidget* iParent) : QObject(iParent), - m_ToolBar(NULL), m_Menu(NULL), m_Area(Qt::TopToolBarArea), m_DefaultArea(Qt::TopToolBarArea), - m_Visibility(true), m_Attached(true), m_Widget(NULL) + m_ToolBar(NULL), m_Menu(NULL), m_Area(Qt::TopToolBarArea), + m_DefaultArea(Qt::TopToolBarArea), m_Visibility(true), m_Attached(true), + m_Widget(NULL) { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- QGoToolBarStatus::QGoToolBarStatus(const QGoToolBarStatus & iS) : - m_ToolBar(iS.m_ToolBar), m_Menu(iS.m_Menu), m_Area(iS.m_Area), m_DefaultArea(iS.m_Area), - m_Visibility(iS.m_Visibility), m_Attached(iS.m_Attached), - m_VectorAction(iS.m_VectorAction), m_Widget(iS.m_Widget) + m_ToolBar(iS.m_ToolBar), m_Menu(iS.m_Menu), m_Area(iS.m_Area), + m_DefaultArea(iS.m_Area), m_Visibility(iS.m_Visibility), + m_Attached(iS.m_Attached), m_VectorAction(iS.m_VectorAction), + m_Widget(iS.m_Widget) { this->setParent(iS.parent()); } @@ -67,18 +69,17 @@ QGoToolBarStatus::QGoToolBarStatus(Qt::ToolBarArea iArea, //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- -QGoToolBarStatus::QGoToolBarStatus(QToolBar* iToolBar, QMenu* iMenu, +QGoToolBarStatus::QGoToolBarStatus(QToolBar* iToolBar, QMenu* iMenu, Qt::ToolBarArea iArea, const bool & iVisibility, const bool & iAttached, QWidget* iParent, QWidget* iWidget): - QObject(iParent), - m_ToolBar(iToolBar), m_Menu(iMenu), - m_Area(iArea), m_Visibility(iVisibility), m_Attached(iAttached), + QObject(iParent), m_ToolBar(iToolBar), m_Menu(iMenu), + m_Area(iArea), m_Visibility(iVisibility), m_Attached(iAttached), m_Widget(iWidget) { if(m_Widget && m_ToolBar) { QAction* Action = this->m_ToolBar->addWidget(iWidget); - Action->setVisible(true); + Action->setVisible(true); } } //-------------------------------------------------------------------------- @@ -137,14 +138,14 @@ QGoToolBarStatus::SetUpToolBar() if (this->m_Widget) { QAction* Action = this->m_ToolBar->addWidget(this->m_Widget); - Action->setVisible(true); + Action->setVisible(true); } if(this->m_ToolBar) { this->m_ToolBar->setVisible(this->m_Visibility); } - + if (!this->m_ToolBar && !this->m_Menu) { std::cout<<"initialize first the toolbar and/or the qmenu "; @@ -217,4 +218,4 @@ void QGoToolBarStatus::Disconnect() std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; std::cout << std::endl; } -}*/ \ No newline at end of file +}*/ diff --git a/Code/GUI/lib/QGoToolBarStatus.h b/Code/GUI/lib/QGoToolBarStatus.h index 9eaa050d..597d01f8 100644 --- a/Code/GUI/lib/QGoToolBarStatus.h +++ b/Code/GUI/lib/QGoToolBarStatus.h @@ -65,29 +65,29 @@ class QGoToolBarStatus:public QObject void InitializeToolBarAndMenu(QToolBar* iToolBar, QMenu* iMenu); + /** \brief clear the toolbar and disconnect all the slots + inside this class connected to the toolbar*/ + void ClearToolBar(); + + /** \brief add all the actions coontained in the m_VectorAction + into the toolbar and connect the slots*/ + void SetUpToolBar(); + + /*\\todo Nicolas why public?? + */ + // variables - why public....? QToolBar * m_ToolBar; QMenu * m_Menu; - /** \brief Position */ Qt::ToolBarArea m_Area; Qt::ToolBarArea m_DefaultArea; - /** \brief is Visible */ bool m_Visibility; - /** \brief Attached to QGoMainWindow*/ bool m_Attached; std::vector< QAction* > m_VectorAction; - /** \brief clear the toolbar and disconnect all the slots - inside this class connected to the toolbar*/ - void ClearToolBar(); - - /** \brief add all the actions coontained in the m_VectorAction - into the toolbar and connect the slots*/ - void SetUpToolBar(); - public slots: /** \brief set the area of the m_ToolBar*/ void SetArea(Qt::ToolBarArea iArea); diff --git a/Code/GUI/lib/QGoTraceSettingsWidget.cxx b/Code/GUI/lib/QGoTraceSettingsWidget.cxx index 4ea149f0..cc947595 100644 --- a/Code/GUI/lib/QGoTraceSettingsWidget.cxx +++ b/Code/GUI/lib/QGoTraceSettingsWidget.cxx @@ -603,6 +603,12 @@ void QGoTraceSettingsWidget::CurrentTraceToUpdate( int iIndexTrace ) //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerSelectedCellType(std::string* iCellType) { + if(this->m_SelectedCellType) + { + delete this->m_SelectedCellType; + this->m_SelectedCellType = NULL; + } + this->m_SelectedCellType = iCellType; } //------------------------------------------------------------------------- @@ -610,6 +616,12 @@ void QGoTraceSettingsWidget::SetPointerSelectedCellType(std::string* iCellType) //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerSelectedSubCellType(std::string* iSubCellType) { + if(this->m_SelectedSubCellType) + { + delete this->m_SelectedSubCellType; + this->m_SelectedSubCellType = NULL; + } + this->m_SelectedSubCellType = iSubCellType; } //------------------------------------------------------------------------- @@ -617,6 +629,12 @@ void QGoTraceSettingsWidget::SetPointerSelectedSubCellType(std::string* iSubCell //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerCollectionData(ItemColorComboboxData* iCollectionData) { + if(this->m_SelectedCollectionData) + { + delete this->m_SelectedCollectionData; + this->m_SelectedCollectionData = NULL; + } + this->m_SelectedCollectionData = iCollectionData; } //------------------------------------------------------------------------- @@ -624,6 +642,12 @@ void QGoTraceSettingsWidget::SetPointerCollectionData(ItemColorComboboxData* iCo //------------------------------------------------------------------------- void QGoTraceSettingsWidget::SetPointerColorData(ItemColorComboboxData* iColorData) { + if(this->m_SelectedColorData) + { + delete this->m_SelectedColorData; + this->m_SelectedColorData = NULL; + } + this->m_SelectedColorData = iColorData; } //------------------------------------------------------------------------- @@ -646,4 +670,4 @@ void QGoTraceSettingsWidget::SetCurrentTraceName(std::string iTraceName) } //------------------------------------------------------------------------- -//------------------------------------------------------------------------- \ No newline at end of file +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoTrackViewDockWidget.h b/Code/GUI/lib/QGoTrackViewDockWidget.h index c957bc50..132347be 100755 --- a/Code/GUI/lib/QGoTrackViewDockWidget.h +++ b/Code/GUI/lib/QGoTrackViewDockWidget.h @@ -58,8 +58,8 @@ public slots: void ColorCodeTracksBySpeed(bool); void ColorCodeTracksByOriginalColor(bool); signals: - void UpdateTracksRepresentation(double, double); - void ChangeColorCode( const char* ); + void UpdateTracksRepresentation(const double&, const double&); + void ChangeColorCode( const QString& ); protected: diff --git a/Code/GUI/lib/Resources/ContourManualSegmentationWidget.ui b/Code/GUI/lib/Resources/ContourManualSegmentationWidget.ui index d01df7a3..1ffd8eba 100644 --- a/Code/GUI/lib/Resources/ContourManualSegmentationWidget.ui +++ b/Code/GUI/lib/Resources/ContourManualSegmentationWidget.ui @@ -6,8 +6,8 @@ 0 0 - 120 - 130 + 184 + 253 @@ -23,7 +23,7 @@ QFrame::Raised - + true @@ -42,7 +42,7 @@ - + true @@ -61,7 +61,7 @@ - + true diff --git a/Code/GUI/lib/Resources/LevelsetWidget.ui b/Code/GUI/lib/Resources/LevelsetWidget.ui deleted file mode 100644 index 3227b8a6..00000000 --- a/Code/GUI/lib/Resources/LevelsetWidget.ui +++ /dev/null @@ -1,78 +0,0 @@ - - - LevelsetWidget - - - - 0 - 0 - 142 - 79 - - - - - 0 - 0 - - - - Form - - - - - - - - Curvature - - - - - - - 999 - - - 20 - - - - - - - Iterations - - - - - - - 999 - - - 100 - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/Code/GUI/lib/Resources/NavigationDockWidget.ui b/Code/GUI/lib/Resources/NavigationDockWidget.ui index 8886573a..b7ba6c9a 100644 --- a/Code/GUI/lib/Resources/NavigationDockWidget.ui +++ b/Code/GUI/lib/Resources/NavigationDockWidget.ui @@ -7,7 +7,7 @@ 0 0 139 - 618 + 564 @@ -27,7 +27,7 @@ Navigation - + @@ -217,115 +217,80 @@ - - - Qt::Vertical - - - - 20 - 2 - - - - - - + - + Qt::Horizontal - - + + + + + + + + + Classic + + + + + Doppler + + + + + + - All Channels + Step - - true + + + + + + 1 - - + + - One Channel + # of T - - - + + + false - - -1 - - - true - - - 0 + + 3 - - - - Qt::Vertical - - - - 20 - 40 - + + + + Channel - + - - - - - - - - Qt::Horizontal + + + + Name - - - - - Classic - - - - - Doppler - - - - - - - - Step - - - - - - - 1 - - - - + Qt::Vertical @@ -346,29 +311,11 @@ YSliceSpinBox ZSliceSpinBox TSliceSpinBox - AllChannelsBtn - OneChannelBtn - - OneChannelBtn - toggled(bool) - ChannelComboBox - setEnabled(bool) - - - 84 - 303 - - - 88 - 329 - - - XSliceSpinBox valueChanged(int) diff --git a/Code/GUI/lib/Resources/ShapeWidget.ui b/Code/GUI/lib/Resources/ShapeWidget.ui deleted file mode 100644 index 33d5998b..00000000 --- a/Code/GUI/lib/Resources/ShapeWidget.ui +++ /dev/null @@ -1,46 +0,0 @@ - - - ShapeWidget - - - - 0 - 0 - 150 - 47 - - - - Form - - - - - - - - Shape - - - - - - - - Sphere - - - - - Cube - - - - - - - - - - - diff --git a/Code/GUI/lib/Resources/WatershedWidget.ui b/Code/GUI/lib/Resources/WatershedWidget.ui deleted file mode 100644 index 58d5d792..00000000 --- a/Code/GUI/lib/Resources/WatershedWidget.ui +++ /dev/null @@ -1,133 +0,0 @@ - - - WatershedWidget - - - - 0 - 0 - 167 - 177 - - - - Form - - - - - - Minimum intensity of a nuclei - - - Thres. Min. - - - - - - - Minimum intensity of a nuclei - - - 999 - - - 10 - - - - - - - Intensities above the threshold are nuclei - - - Thres. Max. - - - - - - - Intensities above the threshold are nuclei - - - 0 - - - 999 - - - 30 - - - - - - - Similarity between the shape of the nuclei and a gaussian profile - - - Corr. Thres. - - - - - - - Similarity between the shape of the nuclei and a gaussian profile - - - 0.010000000000000 - - - 0.500000000000000 - - - - - - - Weight of the gradient - - - Alpha - - - - - - - Weight of the gradient - - - 0.100000000000000 - - - 1.500000000000000 - - - - - - - Beta - - - - - - - 0.100000000000000 - - - 3.000000000000000 - - - - - - - - diff --git a/Code/GUI/lib/TraceEditing/QGoAlgoParameter.h b/Code/GUI/lib/TraceEditing/QGoAlgoParameter.h new file mode 100644 index 00000000..519c5b8a --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoAlgoParameter.h @@ -0,0 +1,203 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoAlgoParameter_h +#define __QGoAlgoParameter_h + +#include +#include +#include +#include +#include +#include + +/** +\brief specialized class for a parameter to be added in an +algorithm widget +*/ +template< class T > +class QGoAlgoParameter +{ + public: + QGoAlgoParameter() + {}; + ~QGoAlgoParameter(){}; + + protected: + T m_Value; + T m_DefaultValue; + std::string m_ParamName; +}; +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +template<> +class QGoAlgoParameter< int > +{ + public: + typedef QSpinBox RepresentationType; + QGoAlgoParameter(std::string iParamName, + bool iAdvParam, int iMin, int iMax, int iDefaultValue = 0) + { + m_ParamName = iParamName; + m_Box = new RepresentationType; + m_AdvParam = iAdvParam; + SetRangeValues(iMin, iMax, iDefaultValue); + }; + + ~QGoAlgoParameter() + { + /*if (m_Box != NULL) + { + delete m_Box; + }*/ + }; + + std::string m_ParamName; + bool m_AdvParam; + RepresentationType* m_Box; + + int GetValue() + { + return m_Box->value(); + }; + + protected: + + void SetRangeValues(int iMin, int iMax, int iDefaultValue) + { + m_Box->setRange(iMin, iMax); + if (iDefaultValue != 0) + { + m_Box->setValue(iDefaultValue); + } + }; + +}; +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +template<> +class QGoAlgoParameter< double > +{ + public: + typedef QDoubleSpinBox RepresentationType; + QGoAlgoParameter(std::string iParamName, + bool iAdvParam, double iMin, double iMax, + int iNbDecimal, double iDefaultValue = 0) + { + m_ParamName = iParamName; + m_Box = new RepresentationType; + m_AdvParam = iAdvParam; + SetRangeValues(iMin, iMax, iNbDecimal, iDefaultValue); + }; + + ~QGoAlgoParameter() + { + /*if (m_Box != NULL) + { + delete m_Box; + }*/ + }; + + std::string m_ParamName; + bool m_AdvParam; + RepresentationType* m_Box; + + double GetValue() + { + return m_Box->value(); + }; + + protected: + + void SetRangeValues(double iMin, double iMax, + int iNbDecimal, double iDefaultValue) + { + m_Box->setRange(iMin, iMax); + m_Box->setDecimals(iNbDecimal); + if (iDefaultValue != 0) + { + m_Box->setValue(iDefaultValue); + } + }; +}; +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +template<> +class QGoAlgoParameter< std::string > +{ + public: + typedef QComboBox RepresentationType; + QGoAlgoParameter(std::string iParamName, + bool iAdvParam, + QStringList iListValues, std::string iDefaultValue = "") + { + m_ParamName = iParamName; + m_Box = new RepresentationType; + m_AdvParam = iAdvParam; + SetListValues(iListValues, iDefaultValue); + } + + ~QGoAlgoParameter() + { + /*if (m_Box != NULL) + { + delete m_Box; + }*/ + }; + + std::string m_ParamName; + bool m_AdvParam; + RepresentationType* m_Box; + + std::string Getvalue() + { + return m_Box->currentText().toStdString(); + } + + protected: + + void SetListValues(QStringList iListValues, std::string iDefaultValue) + { + m_Box->addItems(iListValues); + if (!iDefaultValue.empty()) + { + m_Box->setCurrentIndex(m_Box->findText(iDefaultValue.c_str())); + } + }; +}; + + +#endif \ No newline at end of file diff --git a/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.cxx b/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.cxx new file mode 100644 index 00000000..7504578a --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.cxx @@ -0,0 +1,110 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "QGoAlgorithmWidget.h" +#include +#include +#include "ctkCollapsibleGroupBox.h" +#include "ConvertToStringHelper.h" + + +QGoAlgorithmWidget::QGoAlgorithmWidget(std::string iMethodName, QWidget *iParent ) + :QWidget(iParent) +{ + this->m_MethodName = iMethodName; + this->Initialize(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoAlgorithmWidget::~QGoAlgorithmWidget() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmWidget::Initialize() +{ + this->m_VBoxLayout = new QVBoxLayout; + this->m_ParamLayout = new QFormLayout; + this->m_AdvParamLayout = new QFormLayout; + + this->m_VBoxLayout->addLayout(this->m_ParamLayout); + + this->setLayout(this->m_VBoxLayout); + this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); + this->m_AdvParamAlreadySetUp = false; + //can not setflat + set checked before inserting the parameters + //or no ones will appear... + //this->m_AdvParamGroupBox->setFlat(true); + //this->m_AdvParamGroupBox->setChecked(false); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoAlgorithmWidget::GetMethodName() +{ + return this->m_MethodName; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmWidget::show() +{ + if (!this->m_AdvParamAlreadySetUp) //in order not to add another collapsible box + //each time the widget is shown + { + if (this->m_AdvParamLayout->rowCount()>0 ) //if there is at least one advanced parameter, + //if not, no need to add the collapsible box + { + ctkCollapsibleGroupBox* AdvParamGroupBox = + new ctkCollapsibleGroupBox(tr("Advanced")); + AdvParamGroupBox->setLayout(this->m_AdvParamLayout); + AdvParamGroupBox->setFlat(true); + AdvParamGroupBox->setChecked(false); + this->m_VBoxLayout->addWidget(AdvParamGroupBox); + } + this->m_AdvParamAlreadySetUp = true; //no need to check again when widget shown another time + } + + QWidget::show(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmWidget::EmitApplyAlgo() +{ + emit ApplyAlgo(); +} \ No newline at end of file diff --git a/Code/GUI/lib/QGoAlgorithmsWidget.h b/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.h similarity index 56% rename from Code/GUI/lib/QGoAlgorithmsWidget.h rename to Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.h index 35f04c72..1c1a6295 100644 --- a/Code/GUI/lib/QGoAlgorithmsWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoAlgorithmWidget.h @@ -32,45 +32,74 @@ =========================================================================*/ -#ifndef __QGoAlgorithmsWidget_h -#define __QGoAlgorithmsWidget_h +#ifndef __QGoAlgorithmWidget_h +#define __QGoAlgorithmWidget_h #include -#include #include -#include -#include "QGoAdvancedParametersWidget.h" +#include +#include +#include +#include +#include "ctkCollapsibleGroupBox.h" +#include "QGoAlgoParameter.h" /** - * \class QGoAlgorithmsWidget - * \ingroup GUI manages all the algorithms widget for a same result, - has a combobox with the name of the methods which display a different - layout with the parameters, the advanced parameters in an expandable - box depending on the method selected in the combobox + * \class QGoAlgorithmWidget + * \ingroup GUI * \brief */ -class QGoAlgorithmsWidget: +class QGoAlgorithmWidget: public QWidget { Q_OBJECT public: - explicit QGoAlgorithmsWidget(QWidget *iParent = 0); - ~QGoAlgorithmsWidget(); + explicit QGoAlgorithmWidget(std::string iMethodName, QWidget *iParent = 0); + ~QGoAlgorithmWidget(); /** - \brief add a widget in the stacked widgets with the name - of the method associated in the combobox to display it, - including the parameters and the advanced parameters - displayed in an expandable box + \brief + \return the name of the algorithms */ - void AddMethod(std::string iNameMethod, - QWidget* iParametersWidget, QWidget* iAdvParamWidget); + std::string GetMethodName(); + + /** + \brief add the Advanced parameters box if there are parameters inside and reduce it + before showing the widget + */ + void show(); + + template + void AddParameter(QGoAlgoParameter* iParameter) + { + if (iParameter->m_AdvParam) + { + this->m_AdvParamLayout->addRow(tr("%1:").arg(iParameter->m_ParamName.c_str() ), + iParameter->m_Box); + } + else + { + this->m_ParamLayout->addRow(tr("%1:").arg(iParameter->m_ParamName.c_str() ), + iParameter->m_Box); + } + } + + /** + \brief method called by the QGoAlgoManagerWidget when the apply button is clicked, + emit the signal applyAlgo() + */ + void EmitApplyAlgo(); + +signals: + void ApplyAlgo(); protected: - QVBoxLayout* m_VBoxLayout; - QComboBox* m_MethodComboBox; - QStackedWidget* m_MethodWidgets; - + QVBoxLayout* m_VBoxLayout; + std::string m_MethodName; + QFormLayout* m_ParamLayout; + QFormLayout* m_AdvParamLayout; + bool m_AdvParamAlreadySetUp; + void Initialize(); }; diff --git a/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.cxx b/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.cxx new file mode 100644 index 00000000..befa6d28 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.cxx @@ -0,0 +1,310 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "QGoAlgorithmsManagerWidget.h" +#include +#include +#include +#include +#include +#include + + +QGoAlgorithmsManagerWidget:: +QGoAlgorithmsManagerWidget( std::string iModeName, + QWidget *iParent, + std::vector iVectChannels, + QStringList iListTime, + bool iOnlyOneMethod, + bool NeedApplyResetButton ) : QWidget(iParent), m_MethodComboBox(NULL), + m_ChannelComboBox(NULL), m_TimeComboBox(NULL) +{ + this->m_ModeName = iModeName; + this->Initialize(iVectChannels, iListTime, iOnlyOneMethod, NeedApplyResetButton); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoAlgorithmsManagerWidget::~QGoAlgorithmsManagerWidget() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::Initialize(std::vector iVectChannels, + QStringList iListTime, bool iOnlyOneMethod, bool NeedApplyResetButton) +{ + this->m_VBoxLayout = new QVBoxLayout; + QHBoxLayout* HBox = new QHBoxLayout; + QFormLayout* FormLayout = new QFormLayout; + if (!iListTime.empty() ) + { + this->m_ListTimePoints = iListTime; + this->m_TimeComboBox = new QComboBox(this); + this->m_TimeComboBox->addItems(iListTime); + QLabel* Label= new QLabel("TSlice",this); + HBox->addWidget(Label); + HBox->addWidget(this->m_TimeComboBox); + this->m_InvertBox = new QCheckBox("Invert", this); + HBox->addWidget(this->m_InvertBox); + //FormLayout->addRow(tr("TSlice:"), this->m_TimeComboBox); + } + + this->m_VBoxLayout->addLayout(HBox); + if (!iVectChannels.empty() ) + { + this->m_ChannelComboBox = new QComboBox(this); + std::vector::iterator iter = iVectChannels.begin(); + while (iter != iVectChannels.end()) + { + this->m_ChannelComboBox->addItem(*iter); + ++iter; + } + + FormLayout->addRow(tr("Channel:"), this->m_ChannelComboBox); + } + + this->m_MethodWidgets = new QStackedWidget(this); + + if (!iOnlyOneMethod) + { + this->m_MethodComboBox = new QComboBox(this); + FormLayout->addRow(tr("Method:"), this->m_MethodComboBox); + + QObject::connect(this->m_MethodComboBox, SIGNAL(activated(int)), + this->m_MethodWidgets, SLOT(setCurrentIndex(int))); + } + + this->m_VBoxLayout->addLayout(FormLayout); + this->m_VBoxLayout->addWidget(this->m_MethodWidgets); + + if (NeedApplyResetButton) + { + QHBoxLayout* ButtonLayout = new QHBoxLayout; + QPushButton* ApplyButton = new QPushButton(tr("Apply"),this); + QPushButton* ResetButton = new QPushButton(tr("Reset"), this); + ButtonLayout->addWidget(ApplyButton); + ButtonLayout->addWidget(ResetButton); + this->m_VBoxLayout->addLayout(ButtonLayout); + + QObject::connect(ApplyButton, SIGNAL(clicked()), + this, SLOT(EmitApplyAlgo())); + + QObject::connect(ResetButton, SIGNAL(clicked()), this, SIGNAL(ResetClicked())); + + } + + this->setLayout(this->m_VBoxLayout); + this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::AddMethod(QGoAlgorithmWidget* iAlgoWidget) +{ + this->m_MethodWidgets->addWidget(iAlgoWidget); + int Index = this->m_MethodWidgets->indexOf(iAlgoWidget); + this->m_MethodComboBox->insertItem(Index, iAlgoWidget->GetMethodName().c_str()); + iAlgoWidget->show(); + this->m_MethodComboBox->setCurrentIndex(Index); + this->m_MethodWidgets->setCurrentWidget(iAlgoWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::SetCurrentIndex(int iIndex) +{ + if (this->m_MethodComboBox != NULL) + { + this->m_MethodComboBox->setCurrentIndex(iIndex); + } + this->m_MethodWidgets->setCurrentIndex(iIndex); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoAlgorithmsManagerWidget::GetModeName() +{ + return this->m_ModeName; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::SetCurrentChannel(QString iChannel) +{ + this->m_ChannelComboBox->setCurrentIndex( + this->m_ChannelComboBox->findText(iChannel) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::SetTSliceForClassicView(QString iTimePoint) +{ + if (this->m_TimeComboBox) + { + this->m_TimeComboBox->clear(); + this->m_TimeComboBox->addItems(this->m_ListTimePoints); + this->m_TimeComboBox->setCurrentIndex( + this->m_TimeComboBox->findText(iTimePoint) ); + this->m_TimeComboBox->setEnabled(false); + } + if (this->m_ChannelComboBox) + { + this->m_ChannelComboBox->setEnabled(true); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::SetTSliceForDopplerView( + std::map iListTimePoints, int iIndexChannel) +{ + if (this->m_TimeComboBox) + { + this->m_TimeComboBox->clear(); + if (!iListTimePoints.empty() ) + { + std::map::iterator iter = iListTimePoints.begin(); + while(iter != iListTimePoints.end() ) + { + QPixmap pix(12, 12); + QPainter painter(&pix); + painter.setPen(Qt::gray); + painter.setBrush( QBrush(iter->second) ); + painter.drawRect(0, 0, 12, 12); + QIcon Icon; + Icon.addPixmap(pix); + + this->m_TimeComboBox->addItem(Icon, iter->first); + + ++iter; + } + } + if (iListTimePoints.size() > 0) + { + this->m_TimeComboBox->setCurrentIndex(1); + } + this->m_TimeComboBox->setEnabled(true); + } + if (this->m_ChannelComboBox) + { + this->m_ChannelComboBox->setCurrentIndex(iIndexChannel); + this->m_ChannelComboBox->setEnabled(false); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +bool QGoAlgorithmsManagerWidget::HasMethod() +{ + return this->m_MethodComboBox->count(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::EmitApplyAlgo() +{ + QGoAlgorithmWidget* iCurrentWidget = + dynamic_cast(m_MethodWidgets->currentWidget()); + iCurrentWidget->EmitApplyAlgo(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoAlgorithmsManagerWidget::GetCurrentImageName() +{ + std::string imageName; + if(this->m_ChannelComboBox->isEnabled()) + { + imageName = this->m_ChannelComboBox->currentText().toStdString(); + } + else + { + imageName = this->m_TimeComboBox->currentText().toStdString(); + } + return imageName; +} + +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +int QGoAlgorithmsManagerWidget::GetSelectedTimePoint() +{ + return this->m_TimeComboBox->currentText().toInt(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoAlgorithmsManagerWidget::AddWidgetForOnlyOneMethod( + QWidget* iWidget) +{ + this->m_MethodWidgets->addWidget(iWidget); + //int Index = this->m_MethodWidgets->indexOf(iWidget); + this->m_MethodWidgets->setCurrentWidget(iWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +bool QGoAlgorithmsManagerWidget::IsInvertChecked() +{ + if (this->m_InvertBox->checkState() == Qt::Checked) + { + return true; + } + else + { + return false; + } +} +/*void QGoAlgorithmsManagerWidget::AddMethod(std::string iNameMethod, + QWidget* iParametersWidget, QWidget* iAdvParamWidget) +{ + QWidget* MethodWidget = new QWidget(this); + + QVBoxLayout* MethodLayout = new QVBoxLayout; + MethodLayout->addWidget(iParametersWidget); + + QGoAdvancedParametersWidget* AdvParamWidget = + new QGoAdvancedParametersWidget(this); + AdvParamWidget->AddAdvancedParamWidget(iAdvParamWidget); + + + MethodLayout->addWidget(AdvParamWidget); + + MethodWidget->setLayout(MethodLayout); + this->m_MethodWidgets->addWidget(MethodWidget); + + int Index = this->m_MethodWidgets->indexOf(MethodWidget); + this->m_MethodComboBox->insertItem(Index,iNameMethod.c_str()); +}*/ diff --git a/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.h b/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.h new file mode 100644 index 00000000..2058fe00 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoAlgorithmsManagerWidget.h @@ -0,0 +1,155 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __QGoAlgorithmsManagerWidget_h +#define __QGoAlgorithmsManagerWidget_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include "QGoAlgorithmWidget.h" + +/** + * \class QGoAlgorithmsManagerWidget + * \ingroup GUI + * \brief manages all the algorithms widget for a same mode, + has a combobox with the name of the methods which display a different + QGoAlgorithmWidget depending on the method selected in the combobox +*/ +class QGoAlgorithmsManagerWidget: + public QWidget +{ + Q_OBJECT +public: + explicit QGoAlgorithmsManagerWidget(std::string iModeName, + QWidget *iParent = 0, + std::vector iVectChannels = std::vector(), + QStringList iListTime = QStringList(), + bool iOnlyOneMethod = false, + bool NeedApplyResetButton = true); + ~QGoAlgorithmsManagerWidget(); + + /** + \brief add a widget in the stacked layout with the name + of the method associated in the combobox to display it, + including the parameters and the advanced parameters + displayed in an expandable box + \param[in] iAlgoWidget widget with all the parameters for the + algorithm + */ + void AddMethod(QGoAlgorithmWidget* iAlgoWidget); + + /** + \brief add the widget in the stacked_widgets and hide the methodcombobox + as there will be only one method in this algomanagerwidget + */ + void AddWidgetForOnlyOneMethod(QWidget* iWidget); + + /** + \brief set the current index in the combobox to iIndex and + get the corresponding widget to display + \param[in] iIndex index to be displayed as the current one + */ + void SetCurrentIndex(int iIndex); + + void SetCurrentChannel(QString iChannel); + + + void SetTSliceForClassicView(QString iTimePoint); + + void SetTSliceForDopplerView( + std::map iListTimePoints, int iIndexChannel); + + /** + \brief return the name of the mode + \return the name of the mode + */ + std::string GetModeName(); + + /** + \brief return true if it has at least one QGoAlgorithmWidget in + the stackedWidgets + \return false if there is no algorithm + */ + bool HasMethod(); + + /** + \brief return the number of the selected channel + */ + std::string GetCurrentImageName(); + + int GetSelectedTimePoint(); + + bool IsInvertChecked(); + +signals: + + void ResetClicked(); + void InvertChecked(Qt::CheckState); + +protected: + QVBoxLayout* m_VBoxLayout; + QComboBox* m_MethodComboBox; + QStackedWidget* m_MethodWidgets; + std::string m_ModeName; + QComboBox* m_ChannelComboBox; + QComboBox* m_TimeComboBox; + QStringList m_ListTimePoints; + QLabel* m_MethodLabel; + QCheckBox* m_InvertBox; + + /** + \brief add the different widgets, buttons and fill the comboboxes + for channel and timepoint + \param[in] iListChannels list of the names of the channels + \param[in] iListTime list of the timepoints + */ + void Initialize(std::vector iVectChannels = std::vector(), + QStringList iListTime = QStringList(), bool iOnlyOneMethod = false, + bool NeedApplyResetButton = true); + + protected slots: + /** + \brief after button clicked signal is emitted, get the current widget + of the stackedwidgets and call the method in QGoAlgoWidget to make + it emit a signal + */ + void EmitApplyAlgo(); +}; +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.cxx b/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.cxx new file mode 100644 index 00000000..cfb66551 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.cxx @@ -0,0 +1,189 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoContourEditingWidgetManager.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoAlgorithmsManagerWidget.h" +#include "GoImageProcessor.h" + +#include "vtkSmartPointer.h" +#include "vtkImageExport.h" +#include "vtkImageData.h" +#include + + +QGoContourEditingWidgetManager::QGoContourEditingWidgetManager( + std::vector iVectChannels, + int iTimeMin, + int iTimeMax, + std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent): QGoTraceEditingWidgetManager("Contour", + iVectChannels, iTimeMin, iTimeMax, iSeeds, iImages, + iCurrentTimePoint, iParent) +{ + this->SetSemiAutomaticAlgorithms(iParent); + this->SetManualMode(this->m_ListTimePoint, iParent); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoContourEditingWidgetManager::~QGoContourEditingWidgetManager() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::SetManualMode( + QStringList iListTimePoint, QWidget* iParent) +{ + m_ManualMode = new QGoContourManualSegmentation(iParent); + + this->m_TraceEditingWidget->AddWidgetForManualMode(m_ManualMode->getWidget(), + iListTimePoint, false); + + this->SetTSliceForClassicView(); + + QObject::connect( this->m_ManualMode, + SIGNAL (changeContourRepresentationProperty(float, QColor, + QColor, QColor) ), + this, SIGNAL(changeContourRepresentationProperty(float, QColor, + QColor, QColor) ) ); + + QObject::connect( this->m_ManualMode, + SIGNAL (validateContour() ), + this, SLOT(ContourToValidate() ) ); + + QObject::connect( this->m_ManualMode, + SIGNAL (reinitializeContour() ), + this, SIGNAL(reinitializeContour() ) ); + + QObject::connect( this->m_ManualMode, + SIGNAL (ManualSegmentationActivated(bool) ), + this, SIGNAL(ManualSegmentationActivated(bool) ) ); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::ContourToValidate() +{ + int CurrentTimePoint = this->GetSelectedTimePoint(); //for test purpose + emit ContourValidated( CurrentTimePoint ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) +{ + //level set: + m_LevelSetAlgo = new QGoContourLevelSetAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); + + QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyLevelSetAlgo() ) ); + + /*//shape: + this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); + + QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyShapeAlgo() ) ); + + //watershed: + this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); + + QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyWaterShedAlgo() ) );*/ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::ApplyLevelSetAlgo() +{ + std::cout << "apply levelset 2d" << std::endl; + this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +/*void QGoContourEditingWidgetManager::ApplyShapeAlgo() +{ + this->GetPolydatasFromAlgo(this->m_ShapeAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::ApplyWaterShedAlgo() +{ + this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); +}*/ +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::SetReeditMode(bool iReeditMode) +{ + this->m_ManualMode->SetReeditMode(iReeditMode); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +bool QGoContourEditingWidgetManager::GetReeditMode() +{ + return this->m_ManualMode->GetReeditMode(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::InitializeSettingsForManualMode() +{ + this->m_ManualMode->GenerateContourRepresentationProperties(true); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoContourEditingWidgetManager::SetVisible(bool isVisible) +{ + QGoTraceEditingWidgetManager::SetVisible(isVisible); + + if (this->m_TraceEditingWidget->GetCurrentModeName() == "Manual") + { + emit ManualSegmentationActivated(isVisible); + } +} diff --git a/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.h b/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.h new file mode 100644 index 00000000..78bc6dc0 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoContourEditingWidgetManager.h @@ -0,0 +1,137 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoContourEditingWidgetManager_h +#define __QGoContourEditingWidgetManager_h + +#include "QGoTraceEditingWidgetManager.h" +#include "QGoContourManualSegmentation.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include +#include +#include "QGoContourLevelSetAlgo.h" + +class GoImageProcessor; + + +/** +\class QGoContourEditingWidgetManager handles the interactions between the user +and the algorithms for the contours +\brief +*/ +class QGOGUILIB_EXPORT QGoContourEditingWidgetManager: public QGoTraceEditingWidgetManager +{ + Q_OBJECT +public: + + QGoContourEditingWidgetManager(std::vector iVectChannels, + int iTimeMin, int iTimeMax, std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent=0); + + ~QGoContourEditingWidgetManager(); + //related to manual mode: + + /** + * \brief Set the reedit mode + * \param[in] iReeditMode true: we are in reedit mode, false:classic segmentation + */ + void SetReeditMode(bool iReeditMode); + + /** + * \brief Get the reedit mode + * \return true: we are in reedit mode, false:classic segmentation + */ + bool GetReeditMode(); + + void InitializeSettingsForManualMode(); + + /** + \brief display only the current timepoint in the TSlice comboboxes + of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes + */ + //void SetTSliceForClassicView(); + + /** + \brief display the 3 timepoints chosen by the user in the TSlice comboboxes + of the qgoalgomanagerwidgets, enable them, display only the channel tracked + by the user and disable the channel comboboxes + */ + //void SetTSliceForDopplerView(QStringList iListTimePoints, int iChannelNumber); + +public slots: + virtual void SetVisible(bool isVisible); + +signals: + +protected: + QGoContourManualSegmentation* m_ManualMode; + + QGoContourLevelSetAlgo* m_LevelSetAlgo; + /*QGoMeshShapeAlgo* m_ShapeAlgo; + QGoMeshWaterShedAlgo* m_WaterShedAlgo; + QGoMeshSplitDanielssonDistanceAlgo* m_DanielAlgo;*/ + + /** + \brief add the algowidget of the different algo in the algomanagerwidget + for the semi automatic mode and set the different SIGNAL/SLOTS connections + */ + virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0); + + void SetManualMode( + QStringList iListTimePoint, QWidget* iParent); + +signals: + //from the manual mode: + void ContourValidated(int iTCoord); + void reinitializeContour(); + void changeContourRepresentationProperty(float iLinewidth, QColor iLinecolor, + QColor iNodecolor, QColor iActivenodecolor); + void ManualSegmentationActivated(bool); + +protected slots: + /** + \brief slot called when the user clicks on "validate" for the manual mode + */ + void ContourToValidate(); + void ApplyLevelSetAlgo(); + /*void ApplyShapeAlgo(); + void ApplyWaterShedAlgo();*/ + +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.cxx new file mode 100644 index 00000000..2fc235fc --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.cxx @@ -0,0 +1,107 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoContourLevelSetAlgo.h" +#include "QGoFilterChanAndVese.h" + +#include "GoImageProcessor.h" + + +QGoContourLevelSetAlgo:: +QGoContourLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoLevelSetAlgo(iSeeds, iParent) +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoContourLevelSetAlgo::~QGoContourLevelSetAlgo() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector QGoContourLevelSetAlgo::ApplyAlgo( + GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) +{ + std::vector oNewContours = std::vector(); + + if ( this->m_Radius->GetValue() <= 0 ) + { + std::cerr << "Radius should be > 0 " << std::endl; + return oNewContours; + } + + double Center[3]; + std::vector CenterVect(3); + + // LOOP FOR EACH SEED + for( size_t id = 0; id < this->m_Seeds->size(); id++ ) + { + unsigned int dimension2Collapse(0); + if(id == 0) + { + dimension2Collapse = 2; // we are in XY view, collapse Z + } + else if(id == 1) + { + dimension2Collapse = 1; // we are in XZ view, collapse Y + } + else if(id == 2) + { + dimension2Collapse = 0; // we are in YZ view, collapse X + } + + for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) + { + (*this->m_Seeds)[id]->GetPoint(i, Center); + + CenterVect[0] = Center[0]; + CenterVect[1] = Center[1]; + CenterVect[2] = Center[2]; + + vtkPolyData* temp_output = + this->ApplyLevelSetFilter< unsigned char >( + CenterVect, + iImages->getImageITK< unsigned char, 3>(iChannel),//input raw image + dimension2Collapse);// axe to be collapsed(0=x, 1=y, 2=z) + + oNewContours.push_back( temp_output ); + } + } + + return oNewContours; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.h b/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.h new file mode 100644 index 00000000..e9100605 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoContourLevelSetAlgo.h @@ -0,0 +1,210 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoContourLevelSetAlgo_h +#define __QGoContourLevelSetAlgo_h + +#include "QGoLevelSetAlgo.h" +#include "QGoFilterChanAndVese.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +class GoImageProcessor; + + +/** +\class QGoContourLevelSetAlgo +\brief class to be the interface between the levelset algo for contours +and GoFigure +*/ +class QGoContourLevelSetAlgo: public QGoLevelSetAlgo +{ +public: + QGoContourLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); + ~QGoContourLevelSetAlgo(); + + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); + +protected: + + template < class TPixel> + vtkPolyData * ApplyLevelSetFilter( + const std::vector& iCenter, + typename itk::Image< TPixel, 3 >::Pointer iImages, + const unsigned int& iOrientation) + { + assert( iCenter.size() == 3); + + const unsigned int ImageDimension = 3; + + typedef TPixel PixelType; + typedef itk::Image< PixelType, ImageDimension > ImageType; + typedef typename ImageType::Pointer ImagePointer; + typedef itk::Image< PixelType, 2 > ImageType2D; + typedef typename ImageType2D::Pointer ImageType2DPointer; + + // let's compute the bounds of the region of interest + double radius = this->m_Radius->GetValue(); + + std::vector< double > bounds( 2 * ImageDimension, 0. ); + unsigned int k = 0; + for( unsigned int dim = 0; dim < ImageDimension; dim++ ) + { + bounds[k++] = iCenter[dim] - 2. * radius; + bounds[k++] = iCenter[dim] + 2. * radius; + } + + bounds[2*iOrientation] = iCenter[iOrientation]; + bounds[2*iOrientation +1] = iCenter[iOrientation]; + + for(int i=0;i<6;++i) + { + std::cout << "bounds: " << bounds[i] << std::endl; + } + + // then let's extract the Slice of Interest + ImageType2DPointer ITK_Slice_Image = + this->ITKExtractSlice( bounds, iImages ); + + // Compute the segmentation in 3D + // why no call to the filter itself...? + QGoFilterChanAndVese Filter; + Filter.Apply2DFilter< PixelType >( ITK_Slice_Image, + iCenter, + 0, // we dont want to extract ROI from input since we already did + this->m_Iterations->GetValue(), + this->m_Curvature->GetValue()); + + typename QGoFilterChanAndVese::Output2DPointer + ItkOutPut = Filter.GetOutput2D(); + + // Here it would be better if the mesh extraction would be performed directly + // in ITK instead. + vtkImageData * FilterOutPutToVTK = + this->ConvertITK2VTK< + typename QGoFilterChanAndVese::OutputPixelType, + 2 // image dimension + >( ItkOutPut ); + + vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); + + // translation transform ----------------------- + //------------------------------------------------------------------------ + double temp_bounds[6]; + FilterOutPutToVTK->GetBounds( temp_bounds ); + + double temp_center[3]; + temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; + temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; + temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; + + vtkSmartPointer< vtkTransform > translation2 = + vtkSmartPointer< vtkTransform >::New(); + + translation2->Translate(-temp_center[0], + -temp_center[1], + -temp_center[2]); + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform2->SetTransform(translation2); + mesh_transform2->SetInput( temp_output ); + mesh_transform2->Update(); + + // rotation transform ----------------------- + //------------------------------------------------------------------------ + vtkSmartPointer< vtkTransform > translation = + vtkSmartPointer< vtkTransform >::New(); + // rotate polydata if necessary + if(iOrientation == 0) + { + translation->RotateY(-90); // check if + or - 90 + } + else if(iOrientation == 1) + { + translation->RotateX(-90); // check if + or - 90 + } + else if(iOrientation == 2) + { + // no rotation, we are in the good plan + } + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform->SetTransform(translation); + mesh_transform->SetInput( mesh_transform2->GetOutput() ); + mesh_transform->Update(); + + // translate back ----------------------- + //------------------------------------------------------------------------ + double temp_center2[3]; + temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5; + temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5; + temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5; + + vtkSmartPointer< vtkTransform > translation23 = + vtkSmartPointer< vtkTransform >::New(); + + translation23->Translate(temp_center2[0], + temp_center2[1], + temp_center2[2]); + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform23->SetTransform(translation23); + mesh_transform23->SetInput( mesh_transform->GetOutput() ); + mesh_transform23->Update(); + + //----------------------------------------------------------------------- + + // MIGHT LEAK! CHECK IT IS DELETED! + vtkPolyData* mesh = vtkPolyData::New(); + mesh->DeepCopy( mesh_transform23->GetOutput() ); + + temp_output->Delete(); + + return mesh; + } +}; + +#endif diff --git a/Code/GUI/lib/QGoContourManualSegmentation.cxx b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.cxx similarity index 96% rename from Code/GUI/lib/QGoContourManualSegmentation.cxx rename to Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.cxx index 0ceb0a35..a1ff4cbc 100644 --- a/Code/GUI/lib/QGoContourManualSegmentation.cxx +++ b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.cxx @@ -58,6 +58,10 @@ QGoContourManualSegmentation::QGoContourManualSegmentation(QWidget *iParent) : QObject::connect( m_ContourSegmentationWidget, SIGNAL( ReinitializePressed() ), this, SIGNAL( reinitializeContour() ) ); + + QObject::connect( + m_ContourSegmentationWidget, SIGNAL( ManualSegmentationActivated(bool) ), + this, SIGNAL(ManualSegmentationActivated(bool) ) ); } //-------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoContourManualSegmentation.h b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.h similarity index 98% rename from Code/GUI/lib/QGoContourManualSegmentation.h rename to Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.h index 4e87914b..3dbe8dba 100644 --- a/Code/GUI/lib/QGoContourManualSegmentation.h +++ b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentation.h @@ -106,6 +106,8 @@ public slots: void changeContourRepresentationProperty(float iLinewidth, QColor iLinecolor, QColor iNodecolor, QColor iActivenodecolor); + void ManualSegmentationActivated(bool); + protected: QGoContourManualSegmentationWidget *m_ContourSegmentationWidget; diff --git a/Code/GUI/lib/QGoContourManualSegmentationWidget.cxx b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.cxx similarity index 90% rename from Code/GUI/lib/QGoContourManualSegmentationWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.cxx index 7c94c809..8335522b 100644 --- a/Code/GUI/lib/QGoContourManualSegmentationWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.cxx @@ -66,5 +66,12 @@ QGoContourManualSegmentationWidget:: ~QGoContourManualSegmentationWidget() { } +//---------------------------------------------------------------------------// +//---------------------------------------------------------------------------// +void QGoContourManualSegmentationWidget::setVisible(bool iVisible) +{ + QWidget::setVisible(iVisible); + emit ManualSegmentationActivated(iVisible); +} //---------------------------------------------------------------------------// \ No newline at end of file diff --git a/Code/GUI/lib/QGoContourManualSegmentationWidget.h b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.h similarity index 97% rename from Code/GUI/lib/QGoContourManualSegmentationWidget.h rename to Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.h index bddd0a3e..86fea719 100644 --- a/Code/GUI/lib/QGoContourManualSegmentationWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoContourManualSegmentationWidget.h @@ -63,6 +63,9 @@ class QGOGUILIB_EXPORT QGoContourManualSegmentationWidget: * \brief Pop up dialog to choose the contour properties */ QGoManualSegmentationSettingsDialog *m_SettingsDialog; + + virtual void setVisible(bool iVisible); + signals: /* * \brief Signal sent if "Reinitialize" button clicked @@ -84,6 +87,8 @@ class QGOGUILIB_EXPORT QGoContourManualSegmentationWidget: */ void UpdateContourRepresentationProperties(); + void ManualSegmentationActivated(bool); + private: Q_DISABLE_COPY(QGoContourManualSegmentationWidget); }; diff --git a/Code/GUI/lib/QGoContourSemiAutoShapeWidget.cxx b/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.cxx similarity index 68% rename from Code/GUI/lib/QGoContourSemiAutoShapeWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.cxx index 1038bb44..044db03e 100644 --- a/Code/GUI/lib/QGoContourSemiAutoShapeWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.cxx @@ -31,25 +31,38 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#include "QGoContourWaterShedAlgo.h" +#include "QGoFilterWatershed.h" -#include "QGoContourSemiAutoShapeWidget.h" -//---------------------------------------------------------------------------// -QGoContourSemiAutoShapeWidget::QGoContourSemiAutoShapeWidget(QWidget *iParent) : QWidget(iParent) +QGoContourWaterShedAlgo::QGoContourWaterShedAlgo(QWidget* iParent) + :QGoWaterShedAlgo(iParent) { - this->setupUi(this); - - // Connect signals - QObject::connect( this->shape, SIGNAL( activated(int) ), - this, SIGNAL( Shape(int) ) ); } +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// +//------------------------------------------------------------------------- +QGoContourWaterShedAlgo::~QGoContourWaterShedAlgo() +{ + this->DeleteParameters(); +} +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// -QGoContourSemiAutoShapeWidget:: -~QGoContourSemiAutoShapeWidget() +//------------------------------------------------------------------------- +std::vector QGoContourWaterShedAlgo::ApplyAlgo( + vtkPoints* iSeeds, std::vector >* iImages, + int iChannel) { + QGoFilterWatershed WatershedFilter; + + std::vector NewContours = + WatershedFilter.ApplyFilter3D(this->m_Radius->GetValue(), + this->m_ThresMin->GetValue(), this->m_ThresMax->GetValue(), + this->m_CorrThres->GetValue(),this->m_Alpha->GetValue(),this->m_Beta->GetValue(), + iSeeds, iImages, iChannel); + + return NewContours; } +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// \ No newline at end of file +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.h b/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.h similarity index 72% rename from Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.h rename to Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.h index 0911e7f9..488f6d8b 100644 --- a/Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoContourWaterShedAlgo.h @@ -31,37 +31,35 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#ifndef __QGoContourWaterShedAlgo_h +#define __QGoContourWaterShedAlgo_h -#ifndef __QGoContourSemiAutoLevelsetWidget_h -#define __QGoContourSemiAutoLevelsetWidget_h +#include "QGoWaterShedAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" -#include -#include "ui_LevelsetWidget.h" /** - * \class QGoContourSemiAutoLevelsetWidget - * \ingroup QGoContourSeed - * \brief Widget suited for the levelset segmentation +\class QGoContourWaterShedAlgo +\brief class to be the interface between the watershed algo for contours +and GoFigure */ - -class QGoContourSemiAutoLevelsetWidget: - public QWidget, - protected Ui::LevelsetWidget +class QGoContourWaterShedAlgo: public QGoWaterShedAlgo { - Q_OBJECT public: - explicit QGoContourSemiAutoLevelsetWidget(QWidget *iParent = 0); - ~QGoContourSemiAutoLevelsetWidget(); -signals: - /* - * \brief Signal sent when the curvature is modified - */ - void Curvature(int); + QGoContourWaterShedAlgo(QWidget* iParent = 0); + ~QGoContourWaterShedAlgo(); + + std::vector ApplyAlgo( + vtkPoints* iSeeds, std::vector >* iImages, + int iChannel); - /* - * \brief Signal sent when the number of iterations is modified - */ - void Iterations(int); +protected: + int m_Orientation; }; -#endif +#endif \ No newline at end of file diff --git a/Code/GUI/lib/QGoFilterChanAndVese.cxx b/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.cxx similarity index 54% rename from Code/GUI/lib/QGoFilterChanAndVese.cxx rename to Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.cxx index 5a149be3..df619ac9 100644 --- a/Code/GUI/lib/QGoFilterChanAndVese.cxx +++ b/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.cxx @@ -52,30 +52,20 @@ #include "vtkTransform.h" #include "vtkTransformPolyDataFilter.h" -#include "QGoContourSemiAutoLevelsetWidget.h" +#include "GoImageProcessor.h" + +//#include "QGoContourSemiAutoLevelsetWidget.h" //-------------------------------------------------------------------------- QGoFilterChanAndVese::QGoFilterChanAndVese(QObject *iParent, int iDimension) : QGoFilterSemiAutoBase(iParent) { + m_Image3D = itk::Image< float, 3 >::New(); + m_Image2D = itk::Image< float, 2 >::New(); + m_Dimension = iDimension; m_Iterations = 15; m_Curvature = 5; - - QString name = "Levelset "; - if ( m_Dimension < 2 ) - { - name.append( QString::number(m_Dimension + 2, 10) ); - name.append("D"); - } - else - { - name = "2D Levelset in 1 mesh"; - } - - setName(name); - QGoContourSemiAutoLevelsetWidget *widget = new QGoContourSemiAutoLevelsetWidget; - setWidget(widget); } //-------------------------------------------------------------------------- @@ -85,27 +75,8 @@ QGoFilterChanAndVese:: ~QGoFilterChanAndVese() { } - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterChanAndVese::setIterations(int iIterations) -{ - m_Iterations = iIterations; -} - -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -void -QGoFilterChanAndVese::setCurvature(int iCurvature) -{ - m_Curvature = iCurvature; -} - //-------------------------------------------------------------------------- - +/* //-------------------------------------------------------------------------- void QGoFilterChanAndVese::Filter2D(double *iCenter, const int & iOrientation) @@ -185,7 +156,7 @@ QGoFilterChanAndVese::Filter2D(double *iCenter, const int & iOrientation) pt[0] = center[0]; pt[1] = center[1]; - pt[2] = center[2]; + filter->SetCenter(pt); filter->SetRadius( getRadius() ); @@ -222,161 +193,145 @@ QGoFilterChanAndVese::Filter2D(double *iCenter, const int & iOrientation) reconstructed->Delete(); emit ContourCreated(contour); -} - +}*/ //-------------------------------------------------------------------------- -void -QGoFilterChanAndVese::Filter3D(double *iCenter) -{ - const int dimension = 3; - - // useful to translate the polydata afterwards - setCenter(iCenter); - - vtkImageData *slice = vtkImageData::New(); - slice->DeepCopy( getInput() ); - - // run filter - typedef itk::Image< unsigned char, dimension > FeatureImageType; - typedef itk::Image< float, dimension > OutputImageType; - - //VTK to ITK - //--------------------------------------------------------- - FeatureImageType::Pointer - itkImage = ConvertVTK2ITK< unsigned char, dimension >(slice); - slice->Delete(); - - // Extract ROI - //--------------------------------------------------------- - FeatureImageType::Pointer - test2 = ExtractROI< unsigned char, dimension >( itkImage, iCenter, getRadius() ); - - // Apply filter - // Apply LevelSet segmentation filter - //--------------------------------------------------------- - typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > - SegmentationFilterType; - - FeatureImageType::PointType pt; - - SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); - - filter->SetFeatureImage(test2); - filter->SetPreprocess(1); - - pt[0] = iCenter[0]; - pt[1] = iCenter[1]; - pt[2] = iCenter[2]; - filter->SetCenter(pt); - - filter->SetRadius( getRadius() ); - filter->SetNumberOfIterations(m_Iterations); - filter->SetCurvatureWeight(m_Curvature); - filter->Update(); - - OutputImageType::Pointer test3 = filter->GetOutput(); - - // Convert output - //--------------------------------------------------------- - vtkImageData *itk2vtk = ConvertITK2VTK< float, dimension >(test3); - setOutput(itk2vtk); - itk2vtk->Delete(); - - if ( m_Dimension == 1 ) - { - vtkPolyData *output = ReconstructMesh(getOutput(), 0.); - emit MeshCreated(output, this->getChannel() - 1); - } - else - { - // Extract each slice according top the sampling - vtkPlane *implicitFunction = vtkPlane::New(); - implicitFunction->SetNormal(0, 0, 1); - - vtkCutter * cutter = vtkCutter::New(); - vtkPolyData *reconstructed = ReconstructMesh(getOutput(), 0.); - cutter->SetInput(reconstructed); - cutter->SetCutFunction(implicitFunction); - reconstructed->Delete(); - - for ( int j = 0; j < getSampling(); ++j ) - { - implicitFunction - ->SetOrigin( ( iCenter[0] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ), - ( iCenter[1] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ), - ( iCenter[2] - getRadius() + ( j + 1 ) * 2 * getRadius() / ( getSampling() + 1 ) ) ); - cutter->Update(); - //true: we decimate the contour - vtkPolyData *output = ReorganizeContour(cutter->GetOutput(), true); - - emit AddContourForMeshToContours(output); - } - emit CreateCorrespondingMesh( getSampling() ); - implicitFunction->Delete(); - cutter->Delete(); - } -} - //-------------------------------------------------------------------------- -vtkPolyData * -QGoFilterChanAndVese::Apply() +std::vector > QGoFilterChanAndVese:: + ApplyFilterSetOf2D( + double iRadius, std::vector< vtkPoints* >* iPoints, + int iIterations, int iCurvature, int iSampling, + GoImageProcessor* iImages, int iChannel) { - // Radius has to be > 0 - if ( getRadius() <= 0 ) - { - std::cerr << "Radius should be > 0 " << std::endl; - return NULL; - } - // update the pointed value of the seeds - emit UpdateSeeds(); + std::vector > oSetOfContours = + std::vector >(); - double *center2 = new double[3]; - if ( m_Dimension == 0 ) - { - int orientation = 0; - - // LOOP FOR EACH SEED - for ( int i = 0; i < getPoints()->GetNumberOfPoints(); i++ ) - { - getPoints()->GetPoint(i, center2); - - this->Filter2D(center2, orientation); - } - } - else - //if dimension is 3 - i.e. m_Dimension == 1 - { - // LOOP FOR EACH SEED - for ( int i = 0; i < getPoints()->GetNumberOfPoints(); i++ ) - { - getPoints()->GetPoint(i, center2); - - this->Filter3D(center2); - } - } - - emit SegmentationFinished(); - - delete[] center2; - - return NULL; + return oSetOfContours; } - //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- -void -QGoFilterChanAndVese::ConnectSignals(int iFilterNumber) -{ - QGoFilterSemiAutoBase::ConnectSignals(iFilterNumber); - - // connect specific - QObject::connect( getWidget(), SIGNAL( Curvature(int) ), - this, SLOT( setCurvature(int) ) ); - QObject::connect( getWidget(), SIGNAL( Iterations(int) ), - this, SLOT( setIterations(int) ) ); -} - -//-------------------------------------------------------------------------- \ No newline at end of file +//itk::Image< float, VImageDimension >::Pointer QGoFilterChanAndVese::Apply2DFilter( +// itk::Image< unsigned int, VImageDimension >::Pointer iPointer, +// int iIterations, int iCurvature) +//{ +// //const int dimension = 2; + +// // useful to translate the polydata afterwards +// //setCenter(iCenter); + +// //vtkImageData *slice = vtkImageData::New(); + +// // Extract one slice if dimenesion == 2 +// //vtkImageData *input = extractOneSlice(getInput(), iCenter, iOrientation); +// //slice->DeepCopy(input); +// //input->Delete(); + +// // Recompute new center +// //double *newOrigin = slice->GetOrigin(); +// //double center[3]; + +// switch ( iOrientation ) +// { +// case 0: +// { +// center[0] = iCenter[0] + newOrigin[0]; +// center[1] = iCenter[1] + newOrigin[1]; +// center[2] = 0.; +// break; +// } +// case 1: +// { +// center[0] = iCenter[0] + newOrigin[0]; +// center[1] = iCenter[2] + newOrigin[1]; +// center[2] = 0.; +// break; +// } +// case 2: +// { +// center[0] = iCenter[1] + newOrigin[0]; +// center[1] = iCenter[2] + newOrigin[1]; +// center[2] = 0.; +// break; +// } +// default: +// { +// break; +// } +// } + +// // run filter +// typedef itk::Image< unsigned char, dimension > FeatureImageType; +// typedef itk::Image< float, dimension > OutputImageType; + +// //VTK to ITK +// //--------------------------------------------------------- +// FeatureImageType::Pointer +// itkImage = ConvertVTK2ITK< unsigned char, dimension >(slice); +// slice->Delete(); + +// // Extract ROI +// //--------------------------------------------------------- +// FeatureImageType::Pointer +// test2 = ExtractROI< unsigned char, dimension >( itkImage, center, getRadius() ); + +// // Apply filter +// // Apply LevelSet segmentation filter +// //---------------------------------------------------------- +// const int dimension = 2; +// typedef itk::Image< unsigned char, dimension > FeatureImageType; +// typedef itk::Image< float, dimension > OutputImageType; +// typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > +// SegmentationFilterType; + +// FeatureImageType::PointType pt; + +// SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); + +// //filter->SetFeatureImage(test2); +// filter->SetFeatureImage(iPointer); +// filter->SetPreprocess(1); + +// //pt[0] = center[0]; +// //pt[1] = center[1]; + +// //filter->SetCenter(pt); + +// //filter->SetRadius( getRadius() ); +// //filter->SetNumberOfIterations(m_Iterations); +// //filter->SetCurvatureWeight(m_Curvature); +// filter->SetNumberOfIterations(iIterations); +// filter->SetCurvatureWeight(iCurvature); +// filter->Update(); + +// //OutputImageType::Pointer test3 = filter->GetOutput(); +// return filter->GetOutput(); +// // Convert output +// //--------------------------------------------------------- +// vtkImageData *itk2vtk = ConvertITK2VTK< float, dimension >(test3); +// setOutput(itk2vtk); +// itk2vtk->Delete(); + +// vtkPolyData *reconstructed = ReconstructContour(getOutput(), 0.); + +// // Translate to real location (i.e. see_pos[]) +// vtkTransform *t = vtkTransform::New(); +// t->Translate(getCenter()[0], +// getCenter()[1], +// getCenter()[2]); + +// vtkTransformPolyDataFilter *tf = vtkTransformPolyDataFilter::New(); +// tf->SetTransform(t); +// tf->SetInput(reconstructed); +// tf->Update(); + +// vtkPolyData *contour = vtkPolyData::New(); +// contour->DeepCopy( tf->GetOutput() ); + +// tf->Delete(); +// t->Delete(); +// reconstructed->Delete(); + +// emit ContourCreated(contour); +//} diff --git a/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.h b/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.h new file mode 100644 index 00000000..fcdc0dba --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoFilterChanAndVese.h @@ -0,0 +1,202 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoFilterChanAndVese_h +#define __QGoFilterChanAndVese_h + +#include "QGoFilterSemiAutoBase.h" +#include +#include "QGoGUILibConfigure.h" +#include "itkImage.h" +#include "itkChanAndVeseSegmentationFilter.h" +#include "itkVTKImageImport.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" + +class GoImageProcessor; + +/** + * \class QGoFilterChanAndVese + * \brief Levelset segmentation algorithm implementation. + * Can generate contours and meshes. + * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. + */ +class QGOGUILIB_EXPORT QGoFilterChanAndVese : public QGoFilterSemiAutoBase +{ + Q_OBJECT +public: + typedef float OutputPixelType; + + typedef itk::Image< float, 3 > Output3DType; + typedef Output3DType::Pointer Output3DPointer; + + typedef itk::Image< float, 2 > Output2DType; + typedef Output2DType::Pointer Output2DPointer; + + /** \brief Constructor */ + explicit QGoFilterChanAndVese(QObject *iParent = NULL, int iDimension = 2); + + /** \brief Destructor */ + ~QGoFilterChanAndVese(); + + std::vector ApplyFilterLevelSet3D(double iRadius, vtkPoints* iPoints, + int iIterations, int iCurvature, + GoImageProcessor* iImages, + int iChannel); + + template< typename TPixel > + void Apply3DFilter( + typename itk::Image< TPixel, 3 >::Pointer iITKInput, + const std::vector< double >& iCenter, + const double& iRadius, + const int& iIterations, + const int& iCurvature) + { + typedef itk::Image< TPixel, 3 > FeatureImageType; + typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > + SegmentationFilterType; + typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; + + typedef typename SegmentationFilterType::InternalPointType ITKPointType; + typedef typename SegmentationFilterType::InternalCoordRepType ITKCoordType; + + // convert center into ITKPointType + ITKPointType itk_center; + + for( unsigned int dim = 0; dim < 3; dim++ ) + { + itk_center[dim] = static_cast< ITKCoordType >( iCenter[dim] ); + } + + // convert radius into ITKCoordType + ITKCoordType itk_radius = static_cast< ITKCoordType >( iRadius ); + + // ITK filter + SegmentationFilterPointer filter = SegmentationFilterType::New(); + filter->SetCenter( itk_center ); + filter->SetRadius( itk_radius ); + filter->SetFeatureImage(iITKInput); + filter->SetPreprocess(0);//1); + filter->SetNumberOfIterations(iIterations); + filter->SetCurvatureWeight(iCurvature); + filter->Update(); + + typename Output3DType::Pointer resulting_image = filter->GetOutput(); + + if( resulting_image.IsNotNull() ) + { + m_Image3D->Graft( resulting_image ); + } + else + { + itkGenericExceptionMacro( + <<"ChanAndVeseSegmentationFilter's output is NULL" ); + } + } + + + template< typename TPixel > + void Apply2DFilter( + typename itk::Image< TPixel, 2 >::Pointer iITKInput, + const std::vector< double >& iCenter, + const double& iRadius, + const int& iIterations, + const int& iCurvature) + { + typedef itk::Image< TPixel, 2 > FeatureImageType; + typedef itk::ChanAndVeseSegmentationFilter< FeatureImageType > + SegmentationFilterType; + typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; + + typedef typename SegmentationFilterType::InternalPointType ITKPointType; + typedef typename SegmentationFilterType::InternalCoordRepType ITKCoordType; + + // convert center into ITKPointType + ITKPointType itk_center; + + for( unsigned int dim = 0; dim < 2; dim++ ) + { + itk_center[dim] = static_cast< ITKCoordType >( iCenter[dim] ); + } + + // convert radius into ITKCoordType + ITKCoordType itk_radius = static_cast< ITKCoordType >( iRadius ); + + // ITK filter + SegmentationFilterPointer filter = SegmentationFilterType::New(); + filter->SetCenter( itk_center ); + filter->SetRadius( itk_radius ); + filter->SetFeatureImage(iITKInput); + filter->SetPreprocess(0);//1); + filter->SetNumberOfIterations(iIterations); + filter->SetCurvatureWeight(iCurvature); + filter->Update(); + + typename Output2DType::Pointer resulting_image = filter->GetOutput(); + + if( resulting_image.IsNotNull() ) + { + m_Image2D->Graft( resulting_image ); + } + else + { + itkGenericExceptionMacro( + <<"ChanAndVeseSegmentationFilter's output is NULL" ); + } + } + + std::vector > ApplyFilterSetOf2D( + double iRadius, std::vector< vtkPoints* >* iPoints, + int iIterations, int iCurvature, int iSampling, + GoImageProcessor* iImages, int iChannel); + + Output3DType::Pointer GetOutput3D() + { + return m_Image3D; + } + + Output2DType::Pointer GetOutput2D() + { + return m_Image2D; + } + +private: + //void Filter2D(double *iCenter, const int & iOrientation); + Output3DType::Pointer m_Image3D; + Output2DType::Pointer m_Image2D; + + int m_Iterations; + int m_Curvature; + int m_Dimension; +}; +#endif diff --git a/Code/GUI/lib/QGoFilterSemiAutoBase.cxx b/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.cxx similarity index 90% rename from Code/GUI/lib/QGoFilterSemiAutoBase.cxx rename to Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.cxx index 9eee98ec..7753b1c9 100644 --- a/Code/GUI/lib/QGoFilterSemiAutoBase.cxx +++ b/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.cxx @@ -38,7 +38,7 @@ #include "vtkSmartPointer.h" #include "vtkImageData.h" -#include "QGoSeedBaseWidget.h" +//#include "QGoSeedBaseWidget.h" //Extract one slice #include "vtkMatrix4x4.h" @@ -59,7 +59,7 @@ // fill the holes! #include "vtkFillHolesFilter.h" // and smooth it...! -#include "vtkSmoothPolyDataFilter.h" +#include "vtkWindowedSincPolyDataFilter.h" #include "vtkPolyDataWriter.h" // to cut @@ -121,7 +121,7 @@ QGoFilterSemiAutoBase::getName() void QGoFilterSemiAutoBase::setWidget(QWidget *iWidget) { - m_Widget = iWidget; + //m_Widget = iWidget; } //-------------------------------------------------------------------------- @@ -269,7 +269,7 @@ QGoFilterSemiAutoBase::setOriginalImageMC(std::vector< vtkSmartPointer< vtkImage void QGoFilterSemiAutoBase::UpdateVisibility(int iCurrentFilter) { - QWidget *w = m_Widget->parentWidget()->parentWidget(); + /*QWidget *w = m_Widget->parentWidget()->parentWidget(); if ( m_Number == iCurrentFilter ) { @@ -282,7 +282,7 @@ QGoFilterSemiAutoBase::UpdateVisibility(int iCurrentFilter) m_Widget->hide(); QObject::disconnect( w, SIGNAL( Apply() ), this, SLOT( Apply() ) ); - } + }*/ } //-------------------------------------------------------------------------- @@ -291,13 +291,13 @@ QGoFilterSemiAutoBase::UpdateVisibility(int iCurrentFilter) void QGoFilterSemiAutoBase::UpdateAdvancedMode(bool checked) { - QWidget * w = m_Widget->parentWidget()->parentWidget(); - QGoSeedBaseWidget *baseWidget = dynamic_cast< QGoSeedBaseWidget * >( w ); + //QWidget * w = m_Widget->parentWidget()->parentWidget(); + //QGoSeedBaseWidget *baseWidget = dynamic_cast< QGoSeedBaseWidget * >( w ); - if ( checked && ( m_Number != baseWidget->GetCurrentFilter() ) ) - { - m_Widget->hide(); - } + //if ( checked && ( m_Number != baseWidget->GetCurrentFilter() ) ) + // { + // m_Widget->hide(); + // } } //-------------------------------------------------------------------------- @@ -306,7 +306,7 @@ QGoFilterSemiAutoBase::UpdateAdvancedMode(bool checked) void QGoFilterSemiAutoBase::ConnectSignals(int iFilterNumber) { - m_Number = iFilterNumber; + /*m_Number = iFilterNumber; QWidget *w = m_Widget->parentWidget()->parentWidget(); @@ -340,7 +340,7 @@ QGoFilterSemiAutoBase::ConnectSignals(int iFilterNumber) QObject::connect( this, SIGNAL( UpdateSeeds() ), w, SIGNAL( UpdateSeeds() ) ); QObject::connect( this, SIGNAL( SegmentationFinished() ), - w, SIGNAL( SegmentationFinished() ) ); + w, SIGNAL( SegmentationFinished() ) );*/ } //-------------------------------------------------------------------------- @@ -519,50 +519,59 @@ QGoFilterSemiAutoBase::ReconstructMesh(vtkImageData *iInputImage, const double & contours->SetValue(0, iThreshold); contours->Update(); - vtkSmoothPolyDataFilter *smoother = - vtkSmoothPolyDataFilter::New(); - smoother->SetInput( contours->GetOutput() ); - smoother->SetNumberOfIterations(400); - smoother->Update(); - - vtkSmartPointer< vtkFeatureEdges > feature = vtkSmartPointer< vtkFeatureEdges >::New(); - feature->SetInputConnection( smoother->GetOutputPort() ); + vtkSmartPointer< vtkFeatureEdges > feature = + vtkSmartPointer< vtkFeatureEdges >::New(); + feature->SetInputConnection( contours->GetOutputPort() ); feature->BoundaryEdgesOn(); feature->FeatureEdgesOff(); feature->NonManifoldEdgesOn(); feature->ManifoldEdgesOff(); feature->Update(); - vtkSmartPointer< vtkPolyData > temp; - vtkFillHolesFilter * fillFilter = vtkFillHolesFilter::New(); + vtkSmartPointer< vtkFillHolesFilter > fillFilter = + vtkSmartPointer< vtkFillHolesFilter >::New(); + + vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = + vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); + connectivityFilter->SetExtractionModeToLargestRegion(); + if ( feature->GetOutput()->GetNumberOfCells() > 0 ) { - // fill holes + // fill holes if any! fillFilter->SetInputConnection( contours->GetOutputPort() ); fillFilter->Update(); - temp = fillFilter->GetOutput(); + connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); } else { - temp = smoother->GetOutput(); + connectivityFilter->SetInputConnection( contours->GetOutputPort() ); } // keep the largest region - vtkPolyDataConnectivityFilter *connectivityFilter = vtkPolyDataConnectivityFilter::New(); - connectivityFilter->SetInput(temp); - connectivityFilter->SetExtractionModeToLargestRegion(); connectivityFilter->Update(); + unsigned int smoothingIterations = 15; + double passBand = 0.001; + double featureAngle = 120.0; + + // smoothing + vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = + vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); + smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); + smoother->SetNumberOfIterations( smoothingIterations ); + smoother->BoundarySmoothingOff(); + smoother->FeatureEdgeSmoothingOff(); + smoother->SetFeatureAngle(featureAngle); + smoother->SetPassBand(passBand); + smoother->NonManifoldSmoothingOn(); + smoother->NormalizeCoordinatesOn(); + smoother->Update(); + vtkPolyData *output = vtkPolyData::New(); output->DeepCopy( connectivityFilter->GetOutput() ); - smoother->Delete(); - connectivityFilter->Delete(); -// contours->Delete(); - fillFilter->Delete(); - return output; } diff --git a/Code/GUI/lib/QGoFilterSemiAutoBase.h b/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.h similarity index 99% rename from Code/GUI/lib/QGoFilterSemiAutoBase.h rename to Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.h index 5f921566..9db8f18b 100644 --- a/Code/GUI/lib/QGoFilterSemiAutoBase.h +++ b/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.h @@ -179,8 +179,6 @@ class QGOGUILIB_EXPORT QGoFilterSemiAutoBase:public QObject int m_Dimension; public slots: - virtual vtkPolyData * Apply() = 0; - void UpdateVisibility(int iFilter); void setRadius(double iRadius); diff --git a/Code/GUI/lib/QGoFilterSemiAutoBase.txx b/Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.txx similarity index 100% rename from Code/GUI/lib/QGoFilterSemiAutoBase.txx rename to Code/GUI/lib/TraceEditing/QGoFilterSemiAutoBase.txx diff --git a/Code/GUI/lib/QGoFilterShape.cxx b/Code/GUI/lib/TraceEditing/QGoFilterShape.cxx similarity index 77% rename from Code/GUI/lib/QGoFilterShape.cxx rename to Code/GUI/lib/TraceEditing/QGoFilterShape.cxx index c4cb7b04..13925268 100644 --- a/Code/GUI/lib/QGoFilterShape.cxx +++ b/Code/GUI/lib/TraceEditing/QGoFilterShape.cxx @@ -35,8 +35,6 @@ #include "QGoGUILibConfigure.h" -#include "QGoContourSemiAutoShapeWidget.h" - // Shapes to be generated #include "vtkPolyData.h" #include "vtkPointData.h" @@ -55,6 +53,8 @@ #include "vtkCylinderSource.h" //#include "vtkTriangleFilter.h" +#include "GoImageProcessor.h" + //-------------------------------------------------------------------------- QGoFilterShape::QGoFilterShape(QObject *iParent, int iDimension) : QGoFilterSemiAutoBase(iParent) @@ -72,10 +72,10 @@ QGoFilterShape::QGoFilterShape(QObject *iParent, int iDimension) : name = "2D Shapes in 1 mesh"; } - setName(name); - QGoContourSemiAutoShapeWidget *widget = - new QGoContourSemiAutoShapeWidget(NULL); - setWidget(widget); + //setName(name); + //QGoContourSemiAutoShapeWidget *widget = + // new QGoContourSemiAutoShapeWidget(NULL); + //setWidget(widget); m_Shape = 0; } @@ -120,10 +120,10 @@ QGoFilterShape::Apply() switch ( m_Shape ) { case 0: - testing = GenerateSphere( getCenter() ); + testing = GenerateSphere( getCenter(), getRadius(), this->getInput() ); break; case 1: - testing = GenerateCube( getCenter() ); + testing = GenerateCube( getCenter(), getRadius(), this->getInput() ); break; //case 2: // testing = GenerateCylinder(getCenter()); @@ -222,12 +222,13 @@ QGoFilterShape::setShape(int iShape) //-------------------------------------------------------------------------- vtkPolyData * -QGoFilterShape::GenerateSphere(double *iCenter) +QGoFilterShape::GenerateSphere(double *iCenter, double iRadius, + vtkSmartPointer< vtkImageData > iImage) { // create sphere geometry vtkSphereSource *sphere = vtkSphereSource::New(); - sphere->SetRadius( getRadius() ); + sphere->SetRadius( iRadius ); sphere->SetThetaResolution(30); sphere->SetPhiResolution(30); sphere->SetCenter(iCenter); @@ -236,7 +237,8 @@ QGoFilterShape::GenerateSphere(double *iCenter) // Deal with borders vtkBox *implicitFunction = vtkBox::New(); - implicitFunction->SetBounds( this->getInput()->GetBounds() ); + //implicitFunction->SetBounds( this->getInput()->GetBounds() ); + implicitFunction->SetBounds( iImage->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput( sphere->GetOutput() ); @@ -258,7 +260,8 @@ QGoFilterShape::GenerateSphere(double *iCenter) //-------------------------------------------------------------------------- vtkPolyData * -QGoFilterShape::GenerateCube(double *iCenter) +QGoFilterShape::GenerateCube(double *iCenter, double iRadius, + vtkSmartPointer< vtkImageData > iImage) { // time consuming /* @@ -303,9 +306,9 @@ QGoFilterShape::GenerateCube(double *iCenter) vtkCubeSource *cube = vtkCubeSource::New(); cube->SetCenter(iCenter); - cube->SetXLength( 2 * this->getRadius() ); - cube->SetYLength( 2 * this->getRadius() ); - cube->SetZLength( 2 * this->getRadius() ); + cube->SetXLength( 2 * iRadius); + cube->SetYLength( 2 * iRadius); + cube->SetZLength( 2 * iRadius); cube->Update(); cube->GetOutput()->GetPointData()->SetNormals(NULL); @@ -315,7 +318,7 @@ QGoFilterShape::GenerateCube(double *iCenter) // Deal with borders vtkBox *implicitFunction = vtkBox::New(); - implicitFunction->SetBounds( this->getInput()->GetBounds() ); + implicitFunction->SetBounds( iImage->GetBounds() ); vtkClipPolyData *cutter = vtkClipPolyData::New(); cutter->SetInput( triangle->GetOutput() ); @@ -361,5 +364,71 @@ QGoFilterShape::GenerateCylinder(double *iCenter) return output; } +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector QGoFilterShape::ApplyFilter3D( + double iRadius, std::vector< vtkPoints* >* iPoints, std::string iShape, + GoImageProcessor* iImages, + int iChannel) +{ + std::vector oMeshes = std::vector(); + if ( iRadius <= 0 ) + { + std::cerr << "Radius should be > 0 " << std::endl; + return oMeshes; + } + + vtkImageData* temp_image = iImages->getImageBW(iChannel); + + double center2[3]; + + for ( size_t id = 0; id < iPoints->size(); id++ ) + { + // LOOP FOR EACH SEED + for ( vtkIdType i = 0; i < (*iPoints)[id]->GetNumberOfPoints(); i++ ) + { + (*iPoints)[id]->GetPoint(i, center2); + + // useful to translate the polydata afterwards + setCenter(center2); + + vtkPolyData * MeshPolydata = NULL; + + if (iShape == "Sphere") + { + MeshPolydata = GenerateSphere( center2, iRadius, temp_image ); + } + else + { + if (iShape == "Cube") + { + MeshPolydata = GenerateCube( center2, iRadius, temp_image ); + } + else + { + std::cout<<"doesn't know the chosen shape "; + std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; + std::cout << std::endl; + } + } + oMeshes.push_back(MeshPolydata); + } + } + return oMeshes; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector > QGoFilterShape:: + ApplyFilterSetOf2D(double iRadius, + std::string iShape, int iSampling, + std::vector< vtkPoints* >* iPoints, + GoImageProcessor* iImages, int iChannel) +{ + std::vector > oSetOfContours = + std::vector >(); -//-------------------------------------------------------------------------- \ No newline at end of file + + return oSetOfContours; +} diff --git a/Code/GUI/lib/QGoFilterShape.h b/Code/GUI/lib/TraceEditing/QGoFilterShape.h similarity index 78% rename from Code/GUI/lib/QGoFilterShape.h rename to Code/GUI/lib/TraceEditing/QGoFilterShape.h index ea7e8a90..ea143a67 100644 --- a/Code/GUI/lib/QGoFilterShape.h +++ b/Code/GUI/lib/TraceEditing/QGoFilterShape.h @@ -38,6 +38,7 @@ #include "QGoGUILibConfigure.h" +class GoImageProcessor; class vtkPolyData; /** @@ -61,6 +62,20 @@ class QGOGUILIB_EXPORT QGoFilterShape:public QGoFilterSemiAutoBase virtual void ConnectSignals(int iFilterNumber); + //integration algo + /** + \brief return the polydatas corresponding to the new created Shapes + */ + std::vector ApplyFilter3D( double iRadius, + std::vector< vtkPoints* >* iPoints, std::string iShape, + GoImageProcessor* iImages, + int iChannel); + + std::vector > ApplyFilterSetOf2D(double iRadius, + std::string iShape, int iSampling, + std::vector< vtkPoints* >* iPoints, + GoImageProcessor* iImages, int iChannel); + public slots: void setShape(int); @@ -69,9 +84,11 @@ public slots: int m_Shape; - vtkPolyData * GenerateSphere(double *iCenter); + vtkPolyData * GenerateSphere(double *iCenter, double iRadius, + vtkSmartPointer< vtkImageData > iImage); - vtkPolyData * GenerateCube(double *iCenter); + vtkPolyData * GenerateCube(double *iCenter, double iRadius, + vtkSmartPointer< vtkImageData > iImage); vtkPolyData * GenerateCylinder(double *iCenter); diff --git a/Code/GUI/lib/TraceEditing/QGoFilterWatershed.cxx b/Code/GUI/lib/TraceEditing/QGoFilterWatershed.cxx new file mode 100644 index 00000000..63f8472e --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoFilterWatershed.cxx @@ -0,0 +1,218 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoFilterWatershed.h" + +#include "QGoGUILibConfigure.h" + +// for apply method +#include "vtkImageExport.h" +#include "vtkImageData.h" +#include "vtkMetaImageWriter.h" +// ITK filter +#include "itkImageFileWriter.h" +#include "itkWatershedBasedCellSegmentation.h" +#include "itkImage.h" +#include "itkVTKImageImport.h" + +// to cut +#include "vtkPlane.h" +#include "vtkCutter.h" + +// to translate +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +#include "GoImageProcessor.h" + +//-------------------------------------------------------------------------- +QGoFilterWatershed::QGoFilterWatershed(QObject *iParent, int iDimension) : + QGoFilterSemiAutoBase(iParent) +{ + m_Image3D = itk::Image< int, 3 >::New(); + m_Image2D = itk::Image< int, 2 >::New(); + + m_Dimension = iDimension; + m_TreshMin = 10; + m_TreshMax = 30; + m_CorrTresh = 0.50; + m_Alpha = 1.5; + m_Beta = 3.0; +} + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +QGoFilterWatershed:: +~QGoFilterWatershed() +{ +} + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +QGoFilterWatershed::Filter2D(double *iCenter, const int & iOrientation) +{ + (void)iCenter; + (void)iOrientation; + /* + const int dimension = 2; + + // useful to translate the polydata afterwards + setCenter(iCenter); + + vtkImageData* slice = vtkImageData::New(); + + // Extract one slice if dimenesion == 2 + vtkImageData* input = extractOneSlice(getInput(), iCenter, iOrientation); + slice->DeepCopy(input); + input->Delete(); + + // Recompute new center + double* newOrigin = slice->GetOrigin(); + double center[3]; + + switch (iOrientation) + { + case 0: + { + center[0] = iCenter[0] + newOrigin[0]; + center[1] = iCenter[1] + newOrigin[1]; + center[2] = 0.; + break; + } + case 1: + { + center[0] = iCenter[0] + newOrigin[0]; + center[1] = iCenter[2] + newOrigin[1]; + center[2] = 0.; + break; + } + case 2: + { + center[0] = iCenter[1] + newOrigin[0]; + center[1] = iCenter[2] + newOrigin[1]; + center[2] = 0.; + break; + } + default: + { + break; + } + } + + // run filter + typedef itk::Image FeatureImageType; + typedef itk::Image OutputImageType; + + //VTK to ITK + //--------------------------------------------------------- + FeatureImageType::Pointer + itkImage = ConvertVTK2ITK( slice ); + + // Extract ROI + //--------------------------------------------------------- + FeatureImageType::Pointer + test2 = ExtractROI(itkImage, center, getRadius()); + + // Apply filter + // Apply LevelSet segmentation filter + //--------------------------------------------------------- + typedef itk::ChanAndVeseSegmentationFilter + SegmentationFilterType; + + FeatureImageType::PointType pt; + + SegmentationFilterType::Pointer filter = SegmentationFilterType::New(); + + filter->SetFeatureImage(test2); + filter->SetPreprocess(1); + + pt[0] = center[0]; + pt[1] = center[1]; + pt[2] = center[2]; + filter->SetCenter(pt); + + filter->SetRadius(getRadius()); + filter->SetNumberOfIterations(m_Iterations); + filter->SetCurvatureWeight(m_Curvature); + filter->Update(); + + OutputImageType::Pointer test3 = filter->GetOutput(); + + // Convert output + //--------------------------------------------------------- + vtkImageData* itk2vtk = ConvertITK2VTK(test3); + setOutput(itk2vtk); + itk2vtk->Delete(); + + vtkPolyData* reconstructed = ReconstructContour( getOutput(), 0. ); + + // Translate to real location (i.e. see_pos[]) + vtkTransform* t = vtkTransform::New(); + t->Translate(getCenter()[0], + getCenter()[1], + getCenter()[2]); + + vtkTransformPolyDataFilter* tf = vtkTransformPolyDataFilter::New(); + tf->SetTransform(t); + tf->SetInput( reconstructed ); + tf->Update(); + + vtkPolyData* contour = vtkPolyData::New(); + contour->DeepCopy( tf->GetOutput() ); + + tf->Delete(); + t->Delete(); + reconstructed->Delete(); + + emit ContourCreated( contour ); + */ +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector > QGoFilterWatershed:: + ApplyFilterSetOf2D(double iRadius, + int iThresMin, int iThresMax, double iCorrTresh, double iAlpha, + double iBeta, int iSampling, + std::vector< vtkPoints* >* iPoints, + GoImageProcessor* iImages, int iChannel) +{ + std::vector > oSetOfContours = + std::vector >(); + + + return oSetOfContours; +} diff --git a/Code/GUI/lib/TraceEditing/QGoFilterWatershed.h b/Code/GUI/lib/TraceEditing/QGoFilterWatershed.h new file mode 100644 index 00000000..2634e735 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoFilterWatershed.h @@ -0,0 +1,198 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoFilterWatershed_h +#define __QGoFilterWatershed_h + +#include "QGoFilterSemiAutoBase.h" + +#include "itkWatershedBasedCellSegmentation.h" + +#include "QGoGUILibConfigure.h" + +class GoImageProcessor; +/** + * \class QGoFilterWatershed + * \brief Watershed segmentation algorithm implementation. + * Can generate contours and meshes. + * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. + */ + +class QGOGUILIB_EXPORT QGoFilterWatershed:public QGoFilterSemiAutoBase +{ + Q_OBJECT +public: + typedef int OutputPixelType; + + typedef itk::Image< int, 3 > Output3DType; + typedef Output3DType::Pointer Output3DPointer; + + typedef itk::Image< int, 2 > Output2DType; + typedef Output2DType::Pointer Output2DPointer; + + /** \brief Constructor */ + explicit QGoFilterWatershed(QObject *iParent = NULL, int iDimension = 2); + + /** \brief Destructor */ + ~QGoFilterWatershed(); + + template< typename TPixel > + void Apply3DFilter( + typename itk::Image< TPixel, 3 >::Pointer iITKInput, + const int& iThresMin, + const int& iThresMax, + const double& iCorrTresh, + const double& iAlpha, + const double& iBeta) + { + const unsigned int Dimension = 3; + typedef itk::Image< TPixel, Dimension > FeatureImageType; + typedef typename FeatureImageType::Pointer FeatureImagePointer; + typedef itk::Image< double, Dimension > InputImageType; + typedef typename InputImageType::IndexType InputImageIndexType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef itk::Image< int, Dimension > SegmentImageType; + typedef typename SegmentImageType::Pointer SegmentImagePointer; + + // Apply filter + // Apply watershed segmentation filter + //--------------------------------------------------------- + typedef itk::Image< TPixel, 3 > FeatureImageType; + typedef itk::WatershedBasedCellSegmentation + + SegmentationFilterType; + typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; + + // ITK filter + SegmentationFilterPointer filter = SegmentationFilterType::New(); + filter->SetInput(iITKInput); + filter->SetNucleusThresholdMin(iThresMin); + filter->SetNucleusThresholdMax(iThresMax); + filter->SetCorrelationThreshold1(iCorrTresh); + filter->SetAlpha(iAlpha); + filter->SetBeta(iBeta); + filter->Update(); + + typename Output3DType::Pointer resulting_image = filter->GetOutput(); + + if( resulting_image.IsNotNull() ) + { + m_Image3D->Graft( resulting_image ); + } + else + { + itkGenericExceptionMacro( + <<"WaterShedSegmentationFilter's output is NULL" ); + } + } + + + template< typename TPixel > + void Apply2DFilter( + typename itk::Image< TPixel, 2 >::Pointer iITKInput, + const int& iThresMin, + const int& iThresMax, + const double& iCorrTresh, + const double& iAlpha, + const double& iBeta) + { + const unsigned int Dimension = 2; + typedef itk::Image< TPixel, Dimension > FeatureImageType; + typedef typename FeatureImageType::Pointer FeatureImagePointer; + typedef itk::Image< double, Dimension > InputImageType; + typedef typename InputImageType::IndexType InputImageIndexType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef itk::Image< int, Dimension > SegmentImageType; + typedef typename SegmentImageType::Pointer SegmentImagePointer; + + // Apply filter + // Apply watershed segmentation filter + //--------------------------------------------------------- + typedef itk::Image< TPixel, 2 > FeatureImageType; + typedef itk::WatershedBasedCellSegmentation + + SegmentationFilterType; + typedef typename SegmentationFilterType::Pointer SegmentationFilterPointer; + + // ITK filter + SegmentationFilterPointer filter = SegmentationFilterType::New(); + filter->SetInput(iITKInput); + filter->SetNucleusThresholdMin(iThresMin); + filter->SetNucleusThresholdMax(iThresMax); + filter->SetCorrelationThreshold1(iCorrTresh); + filter->SetAlpha(iAlpha); + filter->SetBeta(iBeta); + filter->Update(); + + typename Output2DType::Pointer resulting_image = filter->GetOutput(); + + if( resulting_image.IsNotNull() ) + { + m_Image2D->Graft( resulting_image ); + } + else + { + itkGenericExceptionMacro( + <<"WaterShedSegmentationFilter's output is NULL" ); + } + } + + std::vector > ApplyFilterSetOf2D(double iRadius, + int iThresMin, int iThresMax, double iCorrTresh, double iAlpha, + double iBeta, int iSampling, + std::vector< vtkPoints* >* iPoints, + GoImageProcessor* iImages, int iChannel); + + Output3DType::Pointer GetOutput3D() + { + return m_Image3D; + } + + Output2DType::Pointer GetOutput2D() + { + return m_Image2D; + } + +private: + void Filter2D(double *iCenter, const int & iOrientation); + + Output3DType::Pointer m_Image3D; + Output2DType::Pointer m_Image2D; + + int m_TreshMin; + int m_TreshMax; + double m_CorrTresh; + double m_Alpha; + double m_Beta; +}; +#endif diff --git a/Code/GUI/lib/QGoModeEditingWidget.cxx b/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.cxx similarity index 69% rename from Code/GUI/lib/QGoModeEditingWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.cxx index 6971e108..e7957432 100644 --- a/Code/GUI/lib/QGoModeEditingWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.cxx @@ -31,50 +31,46 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#include "QGoModeEditingWidget.h" +#include "QGoLevelSetAlgo.h" -QGoModeEditingWidget::QGoModeEditingWidget(QWidget *iParent) - :QWidget(iParent) + +QGoLevelSetAlgo::QGoLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoSemiAutoSegmentationAlgo(iSeeds, iParent) +{ + this->SetAlgoWidget(iParent); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoLevelSetAlgo::~QGoLevelSetAlgo() { - this->Initialize(); + this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -QGoModeEditingWidget::~QGoModeEditingWidget() +void QGoLevelSetAlgo::DeleteParameters() { + delete m_Curvature; + delete m_Iterations; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoModeEditingWidget::Initialize() +void QGoLevelSetAlgo::SetAlgoWidget(QWidget* iParent) { - this->m_VBoxLayout = new QVBoxLayout; - - this->m_ModeComboBox = new QComboBox(this); - this->m_VBoxLayout->addWidget(this->m_ModeComboBox); - - this->m_ModeWidgets = new QStackedWidget; - this->m_VBoxLayout->addWidget(this->m_ModeWidgets); + this->m_AlgoWidget = + new QGoAlgorithmWidget("LevelSet", iParent); - this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); + m_Curvature = new QGoAlgoParameter("Curvature", true, 0, 1000, 20); + this->m_AlgoWidget->AddParameter(m_Curvature); - this->setLayout(this->m_VBoxLayout); + m_Iterations = new QGoAlgoParameter ("Iterations", true, 0, 1000, 100); + this->m_AlgoWidget->AddParameter(m_Iterations); - QObject::connect(this->m_ModeComboBox, SIGNAL(activated(int)), - this->m_ModeWidgets, SLOT(setCurrentIndex(int))); + QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoModeEditingWidget::AddWidgetWithModeName( - std::string iModeName, QWidget* iWidget ) -{ - int Index = 0; - if (iWidget != 0) - { - this->m_ModeWidgets->addWidget(iWidget); - Index = this->m_ModeWidgets->indexOf(iWidget); - } - this->m_ModeComboBox->insertItem(Index,iModeName.c_str()); -} \ No newline at end of file + diff --git a/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.h b/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.h new file mode 100644 index 00000000..96db581e --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoLevelSetAlgo.h @@ -0,0 +1,74 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoLevelSetAlgo_h +#define __QGoLevelSetAlgo_h + +#include "QGoSemiAutoSegmentationAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +class GoImageProcessor; + + +/** +\class QGoLevelSetAlgo +\brief class to be the interface between the levelset algo for meshes, +contours and set of contours and GoFigure +*/ +class QGoLevelSetAlgo: public QGoSemiAutoSegmentationAlgo +{ +public: + QGoLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + virtual ~QGoLevelSetAlgo(); + + virtual std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false ) = 0; + +protected: + + QGoAlgoParameter* m_Curvature; + QGoAlgoParameter* m_Iterations; + + virtual void SetAlgoWidget(QWidget* iParent = 0); + + virtual void DeleteParameters(); +}; + +#endif diff --git a/Code/GUI/lib/QGoManualSegmentationSettingsDialog.cxx b/Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.cxx similarity index 100% rename from Code/GUI/lib/QGoManualSegmentationSettingsDialog.cxx rename to Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.cxx diff --git a/Code/GUI/lib/QGoManualSegmentationSettingsDialog.h b/Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.h similarity index 100% rename from Code/GUI/lib/QGoManualSegmentationSettingsDialog.h rename to Code/GUI/lib/TraceEditing/QGoManualSegmentationSettingsDialog.h diff --git a/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.cxx b/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.cxx new file mode 100644 index 00000000..399841de --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.cxx @@ -0,0 +1,239 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoMeshEditingWidgetManager.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoAlgorithmsManagerWidget.h" +#include "vtkSmartPointer.h" +#include "vtkImageExport.h" +#include "vtkImageData.h" +#include + +#include "QGoMeshWaterShedAlgo.h" +#include "GoImageProcessor.h" + + +QGoMeshEditingWidgetManager::QGoMeshEditingWidgetManager( + std::vector iVectChannels, + int iTimeMin, + int iTimeMax, + std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent): QGoTraceEditingWidgetManager("Mesh", + iVectChannels, iTimeMin, iTimeMax, iSeeds, iImages, + iCurrentTimePoint, iParent) +{ + this->SetSemiAutomaticAlgorithms(iParent); + this->SetSplitMergeMode(iParent); + this->SetSetOfContoursAlgorithms(iVectChannels, this->m_ListTimePoint, + iParent); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoMeshEditingWidgetManager::~QGoMeshEditingWidgetManager() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetTSliceForClassicView() +{ + QGoTraceEditingWidgetManager::SetTSliceForClassicView(); + if (this->m_SetOfContoursWidget != NULL) + { + this->m_SetOfContoursWidget->SetTSliceForClassicView( + tr("%1").arg(*this->m_CurrentTimePoint) ); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetTSliceForDopplerView( + std::map iListTimePoints, int iChannelNumber) +{ + QGoTraceEditingWidgetManager::SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); + this->m_SetOfContoursWidget->SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) +{ + //level set: + m_LevelSetAlgo = new QGoMeshLevelSetAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); + + QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyLevelSetAlgo() ) ); + + //shape: + this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); + + QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyShapeAlgo() ) ); + + //watershed: + this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); + this->m_TraceEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); + + QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyWaterShedAlgo() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetSetOfContoursAlgorithms( + std::vector iVectChannels, QStringList iListTime, + QWidget* iParent) +{ + // initialize the widget + m_SetOfContoursWidget = + new QGoAlgorithmsManagerWidget("Set of Contours", + iParent, iVectChannels, iListTime); + + this->SetTSliceForClassicView(); + + this->m_TraceEditingWidget->AddMode(m_SetOfContoursWidget, true); + + //watershed + this->m_SetOfContoursWaterShedAlgo = + new QGoSetOfContoursWaterShedAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursWaterShedWidget = + this->m_SetOfContoursWaterShedAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursWaterShedWidget); + + QObject::connect(SetOfContoursWaterShedWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursWaterShedAlgo() ) ); + + //levelset + this->m_SetOfContoursLevelSetAlgo = + new QGoSetOfContoursLevelSetAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursLevelSetWidget = + this->m_SetOfContoursLevelSetAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursLevelSetWidget); + + QObject::connect(SetOfContoursLevelSetWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursLevelSetAlgo() ) ); + + //shape + this->m_SetOfContoursShapeAlgo = + new QGoSetOfContoursShapeAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursShapeWidget = + this->m_SetOfContoursShapeAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursShapeWidget); + + QObject::connect(SetOfContoursShapeWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursShapeAlgo() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetSplitMergeMode(QWidget* iParent) +{ + QGoAlgorithmsManagerWidget* SplitAlgoWidget = + new QGoAlgorithmsManagerWidget("Split", iParent); + this->m_TraceEditingWidget->AddMode(SplitAlgoWidget, true); + + m_DanielAlgo = new QGoMeshSplitDanielssonDistanceAlgo(iParent); + QGoAlgorithmWidget * DanielWidget = m_DanielAlgo->GetAlgoWidget(); + SplitAlgoWidget->AddMethod(DanielWidget ); + + QObject::connect( DanielWidget, SIGNAL(ApplyAlgo() ) , + this, SLOT(ApplyDanielAlgo() ) ); + + QGoAlgorithmsManagerWidget* MergeAlgoWidget = + new QGoAlgorithmsManagerWidget("Merge", iParent); + this->m_TraceEditingWidget->AddMode(MergeAlgoWidget, true); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyDanielAlgo() +{ + this->GetPolydatasFromAlgo(this->m_DanielAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyLevelSetAlgo() +{ + this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyShapeAlgo() +{ + this->GetPolydatasFromAlgo(this->m_ShapeAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyWaterShedAlgo() +{ + this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursWaterShedAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursWaterShedAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursLevelSetAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursLevelSetAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursShapeAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursShapeAlgo); +} diff --git a/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.h b/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.h new file mode 100644 index 00000000..6ffdc958 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshEditingWidgetManager.h @@ -0,0 +1,146 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoMeshEditingWidgetManager_h +#define __QGoMeshEditingWidgetManager_h + +#include "QGoTraceEditingWidgetManager.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "QGoMeshLevelSetAlgo.h" +#include "QGoMeshShapeAlgo.h" +#include "QGoMeshWaterShedAlgo.h" +#include "QGoSetOfContoursWaterShedAlgo.h" +#include "QGoSetOfContoursLevelSetAlgo.h" +#include "QGoSetOfContoursShapeAlgo.h" +#include "QGoMeshSplitDanielssonDistanceAlgo.h" +#include +#include + +class GoImageProcessor; +//class QGoMeshWaterShedAlgo; + + +/** +\class QGoMeshEditingWidgetManager handles the interactions between the user +and the algorithms for the meshes +\brief +*/ +class QGOGUILIB_EXPORT QGoMeshEditingWidgetManager: public QGoTraceEditingWidgetManager +{ + Q_OBJECT +public: + + QGoMeshEditingWidgetManager(std::vector iVectChannels, + int iTimeMin, int iTimeMax, + std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent=0); + + ~QGoMeshEditingWidgetManager(); + + /** + \brief display only the current timepoint in the TSlice comboboxes + of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes + */ + void SetTSliceForClassicView(); + + /** + \brief display the 3 timepoints chosen by the user in the TSlice comboboxes + of the qgoalgomanagerwidgets, enable them, display only the channel tracked + by the user and disable the channel comboboxes + */ + void SetTSliceForDopplerView(std::map iListTimePoints, int iChannelNumber); + +public slots: + +signals: + + void SetOfContoursFromAlgo(std::vector > iVectVectPolydata, int iTCoord); + +protected: + QGoAlgorithmsManagerWidget* m_SetOfContoursWidget; + + QGoMeshLevelSetAlgo* m_LevelSetAlgo; + QGoMeshShapeAlgo* m_ShapeAlgo; + QGoMeshWaterShedAlgo* m_WaterShedAlgo; + QGoMeshSplitDanielssonDistanceAlgo* m_DanielAlgo; + + QGoSetOfContoursWaterShedAlgo* m_SetOfContoursWaterShedAlgo; + QGoSetOfContoursLevelSetAlgo* m_SetOfContoursLevelSetAlgo; + QGoSetOfContoursShapeAlgo* m_SetOfContoursShapeAlgo; + + /** + \brief add the algowidget of the different algo in the algomanagerwidget + for the semi automatic mode and set the different SIGNAL/SLOTS connections + */ + virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0); + + void SetSetOfContoursAlgorithms( + std::vector iVectChannels, QStringList iListTime, QWidget* iParent = 0); + + void SetSplitMergeMode(QWidget* iParent); + + /** + \brief get the sets of vtkpolydata for the new created sets of contours + by the chosen algo + */ + template + void GetSetOfPolydatasFromAlgo(T* iAlgo) + { + emit UpdateSeeds(); + std::vector< std::vector > NewSetsOfContours = + iAlgo->ApplyAlgoSeveralSeeds(this->m_Images, + this->m_TraceEditingWidget->GetCurrentImageName() ); + emit SetOfContoursFromAlgo(NewSetsOfContours , + this->GetSelectedTimePoint() ); + emit ClearAllSeeds(); + } + +signals: + +protected slots: + void ApplyLevelSetAlgo(); + void ApplyShapeAlgo(); + void ApplyWaterShedAlgo(); + void ApplyDanielAlgo(); + void ApplySetOfContoursWaterShedAlgo(); + void ApplySetOfContoursLevelSetAlgo(); + void ApplySetOfContoursShapeAlgo(); + +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.cxx new file mode 100644 index 00000000..f6607926 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.cxx @@ -0,0 +1,99 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoMeshLevelSetAlgo.h" +#include "QGoFilterChanAndVese.h" + + +QGoMeshLevelSetAlgo:: +QGoMeshLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoLevelSetAlgo(iSeeds, iParent) +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoMeshLevelSetAlgo::~QGoMeshLevelSetAlgo() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector QGoMeshLevelSetAlgo::ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn) +{ + std::vector oNewMeshes = std::vector(); + + if ( this->m_Radius->GetValue() <= 0 ) + { + std::cerr << "Radius should be > 0 " << std::endl; + return oNewMeshes; + } + + double Center[3]; + std::vector CenterVect(3); + + // LOOP FOR EACH SEED + for( size_t id = 0; id < this->m_Seeds->size(); id++ ) + { + for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) + { + (*this->m_Seeds)[id]->GetPoint(i, Center); + + CenterVect[0] = Center[0]; + CenterVect[1] = Center[1]; + CenterVect[2] = Center[2]; + + vtkPolyData* temp_output = + this->ApplyLevelSetFilter< unsigned char >( + CenterVect, + iImages->getImageITK< unsigned char, 3>(iChannel)); //input raw image + + if(temp_output->GetNumberOfCells() > 0) + { + oNewMeshes.push_back( temp_output ); + } + /*else + { + std::cout << "No polydata could be generated - check parameters" + << std::endl; + temp_output->Delete(); + }*/ + } + } + + return oNewMeshes; +} +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.h b/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.h new file mode 100644 index 00000000..745ce7eb --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshLevelSetAlgo.h @@ -0,0 +1,154 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoMeshLevelSetAlgo_h +#define __QGoMeshLevelSetAlgo_h + +#include "QGoLevelSetAlgo.h" +#include "QGoFilterChanAndVese.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +#include "GoImageProcessor.h" + + +/** +\class QGoMeshLevelSetAlgo +\brief class to be the interface between the levelset algo for meshes +and GoFigure +*/ +class QGoMeshLevelSetAlgo: public QGoLevelSetAlgo +{ +public: + QGoMeshLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); + ~QGoMeshLevelSetAlgo(); + + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); + +protected: + + template < class TPixel > + // note this will work only in 3D, so we can remove the template + // parameter on the image dimension + //unsigned int VImageDimension > + vtkPolyData * ApplyLevelSetFilter( + const std::vector& iCenter, + typename itk::Image< TPixel, 3 >::Pointer iImages) + { + assert( iCenter.size() == 3); + + const unsigned int ImageDimension = 3; + + typedef TPixel PixelType; + + typedef itk::Image< PixelType, ImageDimension > ImageType; + typedef typename ImageType::Pointer ImagePointer; + + // let's compute the bounds of the region of interest + double radius = this->m_Radius->GetValue(); + + std::vector< double > bounds( 2 * ImageDimension, 0. ); + unsigned int k = 0; + for( unsigned int dim = 0; dim < ImageDimension; dim++ ) + { + bounds[k++] = iCenter[dim] - 2. * radius; + bounds[k++] = iCenter[dim] + 2. * radius; + } + + // then let's extract the Region of Interest + ImagePointer ITK_ROI_Image = + this->ITKExtractROI< PixelType, ImageDimension >( bounds, iImages ); + + // Compute the segmentation in 3D + // why no call to the filter itself...? + QGoFilterChanAndVese Filter; + Filter.Apply3DFilter< PixelType >( ITK_ROI_Image, + iCenter, + 0, // we dont want to extract ROI from input since we already did + this->m_Iterations->GetValue(), + this->m_Curvature->GetValue()); + + typename QGoFilterChanAndVese::Output3DPointer + ItkOutPut = Filter.GetOutput3D(); + + // Here it would be better if the mesh extraction would be performed directly + // in ITK instead. + vtkImageData * FilterOutPutToVTK = + this->ConvertITK2VTK< + typename QGoFilterChanAndVese::OutputPixelType, + ImageDimension>( ItkOutPut ); + + vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0); + FilterOutPutToVTK->Delete(); + + double temp_bounds[6]; + temp_output->GetBounds( temp_bounds ); + + double temp_center[3]; + temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; + temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; + temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; + + vtkSmartPointer< vtkTransform > translation = + vtkSmartPointer< vtkTransform >::New(); + + /// \todo fix it to get the real center!!! + translation->Translate(iCenter[0] - temp_center[0], + iCenter[1] - temp_center[1], + iCenter[2] - temp_center[2] ); + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform->SetTransform(translation); + mesh_transform->SetInput( temp_output ); + mesh_transform->Update(); + temp_output->Delete(); + + // MIGHT LEAK! CHECK IT IS DELETED! + vtkPolyData* mesh = vtkPolyData::New(); + mesh->DeepCopy( mesh_transform->GetOutput() ); + + return mesh; + } +}; + +#endif diff --git a/Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.cxx b/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.cxx similarity index 68% rename from Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.cxx index b80c074e..c0d1fe5b 100644 --- a/Code/GUI/lib/QGoContourSemiAutoLevelsetWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.cxx @@ -31,28 +31,41 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#include "QGoMeshShapeAlgo.h" +#include "QGoFilterShape.h" -#include "QGoContourSemiAutoLevelsetWidget.h" +#include "GoImageProcessor.h" -//---------------------------------------------------------------------------// -QGoContourSemiAutoLevelsetWidget::QGoContourSemiAutoLevelsetWidget(QWidget *iParent) : QWidget(iParent) -{ - this->setupUi(this); - - // Connect signals - QObject::connect( this->curvature, SIGNAL( valueChanged(int) ), - this, SIGNAL( Curvature(int) ) ); - QObject::connect( this->iterations, SIGNAL( valueChanged(int) ), - this, SIGNAL( Iterations(int) ) ); +QGoMeshShapeAlgo::QGoMeshShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoShapeAlgo(iSeeds, iParent) +{ } +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// +//------------------------------------------------------------------------- +QGoMeshShapeAlgo::~QGoMeshShapeAlgo() +{ + this->DeleteParameters(); +} +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// -QGoContourSemiAutoLevelsetWidget:: -~QGoContourSemiAutoLevelsetWidget() +//------------------------------------------------------------------------- +std::vector QGoMeshShapeAlgo::ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn) { + QGoFilterShape ShapeFilter; + + std::cout << __FILE__ << " NOT WORKING" << std::endl; + std::cout << "Problem in ApplyFilter3D: it does not use iChannel" << std::endl; + std::vector NewMeshes = + ShapeFilter.ApplyFilter3D(m_Radius->GetValue(), + this->m_Seeds, this->m_Shape->Getvalue(), iImages, 0); + + return NewMeshes; } +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// \ No newline at end of file +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/QGoTraceEditingWidget.h b/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.h similarity index 73% rename from Code/GUI/lib/QGoTraceEditingWidget.h rename to Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.h index ce709978..0789bfaa 100644 --- a/Code/GUI/lib/QGoTraceEditingWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoMeshShapeAlgo.h @@ -31,32 +31,38 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#ifndef __QGoMeshShapeAlgo_h +#define __QGoMeshShapeAlgo_h -#ifndef __QGoTraceEditingWidget_h -#define __QGoTraceEditingWidget_h +#include "QGoShapeAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" -#include -#include -#include -#include -#include -#include "QGoModeEditingWidget.h" +class GoImageProcessor; -class QGoTraceEditingWidget: - public QWidget +/** +\class QGoMeshShapeAlgo +\brief class to be the interface between the shape algo for meshes +and GoFigure +*/ +class QGoMeshShapeAlgo: public QGoShapeAlgo { - Q_OBJECT public: - explicit QGoTraceEditingWidget(std::string iTraceName, QWidget *iParent = 0 ); - ~QGoTraceEditingWidget(); + QGoMeshShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoMeshShapeAlgo(); - void AddMode( std::string iModeName, QWidget* iModeWidget = 0); + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); protected: - void Initialize(QWidget *iParent = 0); - QGoModeEditingWidget* m_ModeEditingWidget; - QVBoxLayout* m_VLayout; }; + #endif diff --git a/Code/GUI/lib/QGoAlgorithmsWidget.cxx b/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx similarity index 61% rename from Code/GUI/lib/QGoAlgorithmsWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx index 98edf6ce..e615a3bb 100644 --- a/Code/GUI/lib/QGoAlgorithmsWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.cxx @@ -31,67 +31,53 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#include "QGoMeshSplitDanielssonDistanceAlgo.h" -#include "QGoAlgorithmsWidget.h" -#include -#include -#include -#include "QGoAdvancedParametersWidget.h" +#include "GoImageProcessor.h" -QGoAlgorithmsWidget::QGoAlgorithmsWidget(QWidget *iParent ) - :QWidget(iParent) +QGoMeshSplitDanielssonDistanceAlgo::QGoMeshSplitDanielssonDistanceAlgo(QWidget* iParent) { - this->Initialize(); + this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -QGoAlgorithmsWidget::~QGoAlgorithmsWidget() +QGoMeshSplitDanielssonDistanceAlgo::~QGoMeshSplitDanielssonDistanceAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoAlgorithmsWidget::Initialize() +void QGoMeshSplitDanielssonDistanceAlgo::DeleteParameters() { - this->m_VBoxLayout = new QVBoxLayout; - this->m_MethodComboBox = new QComboBox(this); - this->m_MethodWidgets = new QStackedWidget(this); - - this->m_VBoxLayout->addWidget(this->m_MethodComboBox); - this->m_VBoxLayout->addWidget(this->m_MethodWidgets); - this->setLayout(this->m_VBoxLayout); - this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); - - QObject::connect(this->m_MethodComboBox, SIGNAL(activated(int)), - this->m_MethodWidgets, SLOT(setCurrentIndex(int))); - } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoAlgorithmsWidget::AddMethod(std::string iNameMethod, - QWidget* iParametersWidget, QWidget* iAdvParamWidget) +void QGoMeshSplitDanielssonDistanceAlgo::SetAlgoWidget(QWidget* iParent) { - QWidget* MethodWidget = new QWidget(this); - - QVBoxLayout* MethodLayout = new QVBoxLayout; - MethodLayout->addWidget(iParametersWidget); - - QGoAdvancedParametersWidget* AdvParamWidget = - new QGoAdvancedParametersWidget(this); - AdvParamWidget->AddAdvancedParamWidget(iAdvParamWidget); - - - MethodLayout->addWidget(AdvParamWidget); - - MethodWidget->setLayout(MethodLayout); - this->m_MethodWidgets->addWidget(MethodWidget); + this->m_AlgoWidget = + new QGoAlgorithmWidget("Danielsson", iParent); +} +//------------------------------------------------------------------------- - int Index = this->m_MethodWidgets->indexOf(MethodWidget); - this->m_MethodComboBox->insertItem(Index,iNameMethod.c_str()); +//------------------------------------------------------------------------- +std::vector QGoMeshSplitDanielssonDistanceAlgo::ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn) +{ + std::vector NewMeshes = std::vector (); + /*QGoFilterChanAndVese LevelSetFilter; + + std::vector NewMeshes = + LevelSetFilter.ApplyFilterLevelSet3D(m_Radius->GetValue(), + iSeeds, m_Iterations->GetValue(), + m_Curvature->GetValue(), iImages, iChannel);*/ + + return NewMeshes; } //------------------------------------------------------------------------- -//------------------------------------------------------------------------- \ No newline at end of file +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.h b/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.h new file mode 100644 index 00000000..df54f094 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshSplitDanielssonDistanceAlgo.h @@ -0,0 +1,70 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoMeshSplitDanielssonDistanceAlgo_h +#define __QGoMeshSplitDanielssonDistanceAlgo_h + +#include "QGoSegmentationAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +class GoImageProcessor; + + +/** +\class QGoMeshSplitDanielssonDistanceAlgo +\brief class to be the interface between the QGoMeshSplitDanielssonDistanceAlgo algo for meshes +and GoFigure +*/ +class QGoMeshSplitDanielssonDistanceAlgo: public QGoSegmentationAlgo +{ +public: + QGoMeshSplitDanielssonDistanceAlgo(QWidget *iParent = 0); + ~QGoMeshSplitDanielssonDistanceAlgo(); + + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); + +protected: + + void SetAlgoWidget(QWidget* iParent = 0); + void DeleteParameters(); +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.cxx new file mode 100644 index 00000000..b30607e4 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.cxx @@ -0,0 +1,100 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoMeshWaterShedAlgo.h" +#include "QGoFilterWatershed.h" + + +QGoMeshWaterShedAlgo:: +QGoMeshWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoWaterShedAlgo(iSeeds, iParent) +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoMeshWaterShedAlgo:: +~QGoMeshWaterShedAlgo() +{ + this->DeleteParameters(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoMeshWaterShedAlgo:: +ApplyAlgo(GoImageProcessor* iImages, std::string iChannel, bool iIsInvertedOn) +{ + std::vector oNewMeshes = std::vector(); + + if ( this->m_Radius->GetValue() <= 0 ) + { + std::cerr << "Radius should be > 0 " << std::endl; + return oNewMeshes; + } + + double Center[3]; + std::vector CenterVect(3); + + // LOOP FOR EACH SEED + for( size_t id = 0; id < this->m_Seeds->size(); id++ ) + { + for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) + { + (*this->m_Seeds)[id]->GetPoint(i, Center); + + CenterVect[0] = Center[0]; + CenterVect[1] = Center[1]; + CenterVect[2] = Center[2]; + + vtkPolyData* temp_output = + this->ApplyWaterShedFilter< unsigned char >( + CenterVect, //cente + iImages->getImageITK< unsigned char, 3>(iChannel, iIsInvertedOn)); //input raw image + + if(temp_output->GetNumberOfCells() > 0) + { + oNewMeshes.push_back( temp_output ); + } + /* else + { + std::cout << "No polydata could be generated - check parameters" + << std::endl; + temp_output->Delete(); + }*/ + } + } + + return oNewMeshes; +} +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.h b/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.h new file mode 100644 index 00000000..16dfbef7 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoMeshWaterShedAlgo.h @@ -0,0 +1,132 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoMeshWaterShedAlgo_h +#define __QGoMeshWaterShedAlgo_h + +#include "QGoWaterShedAlgo.h" +#include "QGoFilterWatershed.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +#include "GoImageProcessor.h" + +/** +\class QGoMeshWaterShedAlgo +\brief class to be the interface between the watershed algo for meshes +and GoFigure +*/ +class QGoMeshWaterShedAlgo: public QGoWaterShedAlgo +{ +public: + QGoMeshWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoMeshWaterShedAlgo(); + + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); + +protected: + + template < class TPixel > + // note this will work only in 3D, so we can remove the template + // parameter on the image dimension + //unsigned int VImageDimension > + vtkPolyData * ApplyWaterShedFilter( + const std::vector& iCenter, + typename itk::Image< TPixel, 3 >::Pointer iImages) + { + assert( iCenter.size() == 3); + + const unsigned int ImageDimension = 3; + + typedef TPixel PixelType; + + typedef itk::Image< PixelType, ImageDimension > ImageType; + typedef typename ImageType::Pointer ImagePointer; + + // let's compute the bounds of the region of interest + double radius = this->m_Radius->GetValue(); + + std::vector< double > bounds( 2 * ImageDimension, 0. ); + unsigned int k = 0; + for( unsigned int dim = 0; dim < ImageDimension; dim++ ) + { + bounds[k++] = iCenter[dim] - 2. * radius; + bounds[k++] = iCenter[dim] + 2. * radius; + } + + // then let's extract the Region of Interest + ImagePointer ITK_ROI_Image = + this->ITKExtractROI< PixelType, ImageDimension >( bounds, iImages ); + + // Compute the segmentation in 3D + QGoFilterWatershed Filter; + Filter.Apply3DFilter< PixelType >( + ITK_ROI_Image, + this->m_ThresMin->GetValue(), + this->m_ThresMax->GetValue(), + this->m_CorrThres->GetValue(), + this->m_Alpha->GetValue(), + this->m_Beta->GetValue()); + + typename QGoFilterWatershed::Output3DPointer + ItkOutPut = Filter.GetOutput3D(); + + // Here it would be better if the mesh extraction would be performed directly + // in ITK instead. + vtkImageData * FilterOutPutToVTK = + this->ConvertITK2VTK< + typename QGoFilterWatershed::OutputPixelType, + ImageDimension>( ItkOutPut ); + + // Nicolas- should be able to tune the parameter -0.5- + vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); + FilterOutPutToVTK->Delete(); + + // MIGHT LEAK! CHECK IT IS DELETED! + vtkPolyData* mesh = vtkPolyData::New(); + mesh->DeepCopy( temp_output ); + + return mesh; + } +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.cxx b/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.cxx new file mode 100644 index 00000000..510f4e22 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.cxx @@ -0,0 +1,264 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoModesManagerWidget.h" +#include +#include + +QGoModesManagerWidget::QGoModesManagerWidget(std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent) + :QWidget(iParent), m_ManualModeManager(NULL) +{ + this->Initialize(iVectChannels, iListTimePoints); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoModesManagerWidget::~QGoModesManagerWidget() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::Initialize(std::vector iVectChannels, + QStringList iListTimePoints) +{ + this->m_ModeAlreadyCleaned = false; + this->m_VBoxLayout = new QVBoxLayout; + this->m_ModeComboBox = new QComboBox(this); + + QHBoxLayout* ModeLayout = new QHBoxLayout; + QLabel* ModeLabel = new QLabel(tr("Mode:"), this); + ModeLayout->addWidget(ModeLabel); + ModeLayout->addWidget(this->m_ModeComboBox); + + this->m_VBoxLayout->addLayout(ModeLayout); + + this->m_ModeWidgets = new QStackedWidget; + this->m_VBoxLayout->addWidget(this->m_ModeWidgets); + + this->setLayout(this->m_VBoxLayout); + this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); + + //add default modes: + this->m_SemiAutoAlgoManagerWidget = new + QGoAlgorithmsManagerWidget("SemiAutomatic", this, iVectChannels, + iListTimePoints); + this->AddAlgoManagerWidget(this->m_SemiAutoAlgoManagerWidget, true); + + this->m_AutoAlgoManagerWidget = new + QGoAlgorithmsManagerWidget("Automatic",this, iVectChannels, + iListTimePoints); + this->AddAlgoManagerWidget(this->m_AutoAlgoManagerWidget, false); + + m_ModesWhoNeedSeeds.append("SemiAutomatic"); + m_ModesWhoNeedSeeds.append("Automatic"); + + QObject::connect(this->m_ModeComboBox, SIGNAL(activated(int)), + this, SLOT(SetTheRightMode(int))); + + QObject::connect(this->m_AutoAlgoManagerWidget, SIGNAL(ResetClicked() ), + this, SIGNAL(ResetClicked() ) ); + + QObject::connect(this->m_SemiAutoAlgoManagerWidget, SIGNAL(ResetClicked() ), + this, SIGNAL(ResetClicked() ) ); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::AddWidgetWithModeName( + std::string iModeName, QWidget* iWidget, bool ModeNeedSeeds ) +{ + int Index = 0; + if (iWidget != 0) + { + this->m_ModeWidgets->addWidget(iWidget); + Index = this->m_ModeWidgets->indexOf(iWidget); + } + this->m_ModeComboBox->insertItem(Index,iModeName.c_str()); + + if (ModeNeedSeeds) + { + this->m_ModesWhoNeedSeeds.append(iModeName.c_str() ); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::AddAlgoManagerWidget( + QGoAlgorithmsManagerWidget* iAlgoManagerWidget, bool ModeNeedSeeds, + int iDefaultIndex) +{ + this->AddWidgetWithModeName(iAlgoManagerWidget->GetModeName(), + iAlgoManagerWidget, ModeNeedSeeds); + iAlgoManagerWidget->SetCurrentIndex(iDefaultIndex); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::CheckDefaultModes() +{ + if (!this->m_AutoAlgoManagerWidget->HasMethod()) + { + this->m_ModeComboBox->removeItem( + this->m_ModeComboBox->findText("Automatic") ); + this->m_ModeWidgets->removeWidget(this->m_AutoAlgoManagerWidget); + } + if (!this->m_SemiAutoAlgoManagerWidget->HasMethod()) + { + this->m_ModeComboBox->removeItem( + this->m_ModeComboBox->findText("SemiAutomatic") ); + this->m_ModeWidgets->removeWidget(this->m_SemiAutoAlgoManagerWidget); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::AddAlgoWidgetForSemiAutomaticMode( + QGoAlgorithmWidget* iAlgoWidget) +{ + this->m_SemiAutoAlgoManagerWidget->AddMethod(iAlgoWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::AddAlgoWidgetForAutomaticMode( + QGoAlgorithmWidget* iAlgoWidget) +{ + this->m_AutoAlgoManagerWidget->AddMethod(iAlgoWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::AddWidgetForManualMode(QWidget* iWidget, + QStringList iListTimePoint, bool ModeNeedSeeds) +{ + std::vector Channels = std::vector(); + this->m_ManualModeManager = new QGoAlgorithmsManagerWidget( + "Manual",this, Channels, iListTimePoint, true, false); + this->m_ManualModeManager->AddWidgetForOnlyOneMethod(iWidget); + this->AddAlgoManagerWidget(this->m_ManualModeManager, ModeNeedSeeds); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoModesManagerWidget::GetCurrentImageName() +{ + QGoAlgorithmsManagerWidget* CurrentWidget = + dynamic_cast + (this->m_ModeWidgets->currentWidget()); + return CurrentWidget->GetCurrentImageName(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +int QGoModesManagerWidget::GetSelectedTimePoint() +{ + QGoAlgorithmsManagerWidget* CurrentWidget = + dynamic_cast + (this->m_ModeWidgets->currentWidget()); + return CurrentWidget->GetSelectedTimePoint(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +bool QGoModesManagerWidget::GetIsInvertedOn() +{ + QGoAlgorithmsManagerWidget* CurrentWidget = + dynamic_cast + (this->m_ModeWidgets->currentWidget()); + return CurrentWidget->IsInvertChecked(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::SetTheRightMode(int iIndex) +{ + if(! m_ModeAlreadyCleaned) + { + this->CheckDefaultModes(); + m_ModeAlreadyCleaned = true; + } + + if (iIndex != -1) + { + this->m_ModeWidgets->setCurrentIndex(iIndex); + } + + if (this->m_ModesWhoNeedSeeds.indexOf( + this->m_ModeComboBox->currentText() ) != -1) + { + emit SetSeedInteractorBehaviour(true); + } + else + { + emit SetSeedInteractorBehaviour(false); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::SetTSliceForClassicViewInAllAlgoModes(int iTimePoint) +{ + this->m_AutoAlgoManagerWidget->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); + this->m_SemiAutoAlgoManagerWidget->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); + if (this->m_ManualModeManager) + { + this->m_ManualModeManager->SetTSliceForClassicView(tr("%1").arg(iTimePoint) ); + } + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoModesManagerWidget::SetTSliceForDopplerViewInAllAlgoModes( + std::map iListTimePoints, int iChannelNumber) +{ + this->m_AutoAlgoManagerWidget->SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); + this->m_SemiAutoAlgoManagerWidget->SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); + if (this->m_ManualModeManager) + { + this->m_ManualModeManager->SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + std::string QGoModesManagerWidget::GetCurrentModeName() +{ + return this->m_ModeComboBox->currentText().toStdString(); +} diff --git a/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.h b/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.h new file mode 100644 index 00000000..8e1158a5 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoModesManagerWidget.h @@ -0,0 +1,151 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __QGoModesManagerWidget_h +#define __QGoModesManagerWidget_h + +#include +#include +#include +#include +#include "QGoAlgorithmsManagerWidget.h" + +/** + * \class QGoModesManagerWidget + * \ingroup GUI + * \brief widget that manages the different modes for the TraceEditingWidget, + has a combobox with the mode names and a corresponging stackedWidgets which + display the right widget according to the mode selected in the combobox, + has semiautomatic and automatic default modes +*/ +class QGoModesManagerWidget: + public QWidget +{ + Q_OBJECT +public: + explicit QGoModesManagerWidget(std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent = 0); + ~QGoModesManagerWidget(); + + /** + \brief add a widget in the StackedWidget with the mode name that will + be added in the combobox. + \param[in] iModeName name of the mode + \param[in] iWidget widget that will be displayed when iModeName is selected + \param[in] ModeNeedSeeds if true, a signal will be emitted everytime the mode name appear + in the combobox + */ + void AddWidgetWithModeName (std::string iModeName, QWidget* iWidget, + bool ModeNeedSeeds); + + /** + \brief add a QGoAlgorithmsManagerWidget and set the default index of this algo widget + to iDefaultIndex + \param[in] iAlgoManagerWidget + \param[in] iDefaultIndex default index for the algo widget + */ + void AddAlgoManagerWidget(QGoAlgorithmsManagerWidget* iAlgoManagerWidget, + bool ModeNeedSeeds, int iDefaultIndex = 0); + + /** + \brief add the iAlgoWidget directly in the QgoAlgomanager corresponding + to the Semi Automatic mode + \param[in] iAlgoWidget widget to be added for the parameters of the algo + */ + void AddAlgoWidgetForSemiAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); + + /** + \brief add the iAlgoWidget directly in the QgoAlgomanager corresponding + to the Automatic mode + \param[in] iAlgoWidget widget to be added for the parameters of the algo + */ + void AddAlgoWidgetForAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); + + /** + \brief create the "manual" mode and makes it correspond to the provided + widget + \param[in] iWidget widget to be added for the manual mode + */ + void AddWidgetForManualMode(QWidget* iWidget, + QStringList iListTimePoint, bool ModeNeedSeeds); + + /** + \brief return the number of the selected channel + */ + std::string GetCurrentImageName(); + int GetSelectedTimePoint(); + bool GetIsInvertedOn(); + + void SetTSliceForClassicViewInAllAlgoModes(int iTimePoint); + void SetTSliceForDopplerViewInAllAlgoModes( + std::map iListTimePoints, int iChannelNumber); + + /** + \brief return the mode name currently selected in the combobox + */ + std::string GetCurrentModeName(); + +public slots: + /** + \brief set the right mode according to the combobox if iIndex is different than + -1 and emit a signal to enable/disable the seeds interactor mode based on the + name of the selected mode + */ + void SetTheRightMode(int iIndex = -1); + +signals: + void SetSeedInteractorBehaviour(bool enable); + void ResetClicked(); + +protected: + QVBoxLayout* m_VBoxLayout; + QComboBox* m_ModeComboBox; + QStackedWidget* m_ModeWidgets; + QGoAlgorithmsManagerWidget* m_SemiAutoAlgoManagerWidget; + QGoAlgorithmsManagerWidget* m_AutoAlgoManagerWidget; + QGoAlgorithmsManagerWidget* m_ManualModeManager; + bool m_ModeAlreadyCleaned; + QStringList m_ModesWhoNeedSeeds; + + void Initialize(std::vector iVectChannels, QStringList iListTimePoints); + + /** + \brief check that there is something in the default modes, if not, remove the mode + name from the combobox + */ + void CheckDefaultModes(); + + +}; +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx new file mode 100644 index 00000000..d0119b17 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx @@ -0,0 +1,482 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoSegmentationAlgo.h" + +// Extract ROI +#include "vtkExtractVOI.h" + +// extract polydata 2d +#include "vtkMarchingSquares.h" +//reorder contour +#include "vtkStripper.h" +#include "vtkCellArray.h" +// extract polydata 3d +#include "vtkContourFilter.h" +#include "vtkFeatureEdges.h" +#include "vtkFillHolesFilter.h" +#include "vtkPolyDataConnectivityFilter.h" +#include "vtkWindowedSincPolyDataFilter.h" + +#include "vtkMath.h" + +// Decimation 2d +#include "vtkPolylineDecimation.h" +// Decimation 3d +#include "vtkDecimatePro.h" + + +// test code +#include + + +QGoSegmentationAlgo::QGoSegmentationAlgo(QWidget *iParent) + : QObject( iParent ), m_Decimate(true), + m_NumberOfPoints(100), m_AlgoWidget(NULL) +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoSegmentationAlgo::~QGoSegmentationAlgo() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoAlgorithmWidget* QGoSegmentationAlgo::GetAlgoWidget() +{ + return this->m_AlgoWidget; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSegmentationAlgo::VTKExtractROI( + const std::vector& iBounds, + const std::vector< vtkSmartPointer< vtkImageData > > & iImages) +{ + assert( iBounds.size() == 6 ); + + // vector to be returned + std::vector listOfImages; + + //iterator on the images + std::vector< vtkSmartPointer< vtkImageData > >::const_iterator + it = iImages.begin(); + + while( it != iImages.end()) + { + listOfImages.push_back( VTKExtractROI(iBounds, *it) ); + ++it; + } + + return listOfImages; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +vtkImageData* +QGoSegmentationAlgo:: +VTKExtractROI(const std::vector& iBounds, + const vtkSmartPointer< vtkImageData > & iImage) +{ + // make sure there + assert( iBounds.size() == 6 ); + + double org[3]; + iImage->GetOrigin( org ); + + double spacing[3]; + iImage->GetSpacing( spacing ); + + std::vector< int > bounds_idx(6); + + int k = 0; + for( int i = 0; i < 3; i++ ) + { + bounds_idx[k] = vtkMath::Round( ( iBounds[k] - org[i] ) / spacing[i] ); + ++k; + bounds_idx[k] = vtkMath::Round( ( iBounds[k] - org[i] ) / spacing[i] ); + ++k; + } + + vtkSmartPointer extractVOI = + vtkSmartPointer::New(); + extractVOI->SetInput( iImage ); + extractVOI->SetVOI( bounds_idx[0], bounds_idx[1], + bounds_idx[2], bounds_idx[3], + bounds_idx[4], bounds_idx[5]); + extractVOI->Update(); + + vtkImageData* temp_image = vtkImageData::New(); + temp_image->DeepCopy( extractVOI->GetOutput() ); + + return temp_image; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSegmentationAlgo:: +ExtractPolyData( + std::vector& iInputImage, + const double & iThreshold) +{ + // vector to be returned + std::vector listOfPolys; + + //iterator on the images + std::vector::iterator it = iInputImage.begin(); + + while( it != iInputImage.end()) + { + vtkPolyData* extractedPolyData = ExtractPolyData(*it, iThreshold); + if( extractedPolyData ) + { + listOfPolys.push_back( extractedPolyData ); + } + ++it; + } + + return listOfPolys; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractPolyData(vtkImageData *iInputImage, const double & iThreshold) +{ + // make sure there is an image + assert( iInputImage ); + + // test dimension of the input + int extent[6]; + iInputImage->GetExtent( extent ); + + int dimension = 3; + + for( int i = 0; i < 3; i++ ) + { + if( extent[2*i] == extent[2*i+1] ) + { + --dimension; + } + } + + switch ( dimension ) + { + case 2 : + return ExtractContour( iInputImage, iThreshold); + case 3 : + return ExtractMesh( iInputImage, iThreshold); + default : + std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; + } + + return NULL; +} +//------------------------------------------------------------------------- + +/* + * \todo Nicolas-do a better reconstruction.. + */ +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold) +{ + // create iso-contours + vtkSmartPointer contours = + vtkSmartPointer::New(); + + contours->SetInput(iInputImage); + contours->GenerateValues (1, iThreshold, iThreshold); + contours->Update(); + + return ReorganizeContour( contours->GetOutput() ); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ReorganizeContour(vtkSmartPointer iInputImage) +{ + /* + * \note Nicolas-to be enhanced + */ + // Create reorganize contours + vtkStripper *stripper = vtkStripper::New(); + + stripper->SetInput(iInputImage); + //Is it useful?? Which number is the best suited? + stripper->SetMaximumLength(999); + stripper->Update(); + + // Reorder points + stripper->GetOutput()->GetLines()->InitTraversal(); + + // npts = nb of points in the line + // *pts = pointer to each point + + vtkIdType *pts = NULL; + vtkIdType npts = 0; + stripper->GetOutput()->GetLines()->GetNextCell(npts, pts); + vtkPoints *points = vtkPoints::New(); + + vtkCellArray *lines = vtkCellArray::New(); + vtkIdType * lineIndices = new vtkIdType[static_cast< int >( npts + 1 )]; + + for ( int k = 0; k < static_cast< int >( npts ); k++ ) + { + points->InsertPoint( k, stripper->GetOutput()->GetPoints()->GetPoint(pts[k]) ); + lineIndices[k] = k; + } + + lineIndices[static_cast< int >( npts )] = 0; + lines->InsertNextCell(npts + 1, lineIndices); + delete[] lineIndices; + + vtkSmartPointer output = vtkSmartPointer::New(); + output->SetPoints(points); + output->SetLines(lines); + + lines->Delete(); + points->Delete(); + stripper->Delete(); + + vtkPolyData* output2 = vtkPolyData::New(); + output2->DeepCopy(output); + + return output2; +} + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractMesh(vtkSmartPointer iInputImage, const double & iThreshold) +{ + vtkSmartPointer< vtkContourFilter > contours = vtkSmartPointer< vtkContourFilter >::New(); + contours->SetInput(iInputImage); + contours->SetComputeGradients(0); + contours->SetComputeNormals(0); + contours->SetComputeScalars(0); + contours->SetNumberOfContours(1); + contours->SetValue(0, iThreshold); + contours->Update(); + + std::cout << "Number Of Points: " << iInputImage->GetNumberOfPoints() + << std::endl; + + vtkSmartPointer< vtkFeatureEdges > feature = + vtkSmartPointer< vtkFeatureEdges >::New(); + feature->SetInputConnection( contours->GetOutputPort() ); + feature->BoundaryEdgesOn(); + feature->FeatureEdgesOff(); + feature->NonManifoldEdgesOn(); + feature->ManifoldEdgesOff(); + feature->Update(); + + vtkSmartPointer< vtkFillHolesFilter > fillFilter = + vtkSmartPointer< vtkFillHolesFilter >::New(); + + vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = + vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); + connectivityFilter->SetExtractionModeToLargestRegion(); + + + if ( feature->GetOutput()->GetNumberOfCells() > 0 ) + { + // fill holes if any! + fillFilter->SetInputConnection( contours->GetOutputPort() ); + fillFilter->Update(); + + connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); + } + else + { + connectivityFilter->SetInputConnection( contours->GetOutputPort() ); + } + + // keep the largest region + connectivityFilter->Update(); + /* + * \note Nicolas-Smoother not connected + */ +/* + unsigned int smoothingIterations = 15; + double passBand = 0.001; + double featureAngle = 120.0; + + // smoothing + vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = + vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); + smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); + smoother->SetNumberOfIterations( smoothingIterations ); + smoother->BoundarySmoothingOff(); + smoother->FeatureEdgeSmoothingOff(); + smoother->SetFeatureAngle(featureAngle); + smoother->SetPassBand(passBand); + smoother->NonManifoldSmoothingOn(); + smoother->NormalizeCoordinatesOn(); + smoother->Update(); +*/ + vtkPolyData* output = vtkPolyData::New(); + output->DeepCopy( connectivityFilter->GetOutput() ); + + return output; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimatePolyData( + vtkSmartPointer& iPolyData, + const unsigned int& iNumberOfPoints) +{ + // make sure there is a polydata + assert( iPolyData ); + + /* + * \todo Nicolas-might be better solution to test dimension of a PolyData + */ + // test dimension of the input + double* bounds = iPolyData->GetBounds(); + int dimension = 3; + + for( int i = 0; i < 3; i++ ) + { + if( bounds[2*i] == bounds[2*i+1] ) + { + --dimension; + } + } + + switch ( dimension ) + { + case 2 : + return DecimateContour( iPolyData, iNumberOfPoints); + case 3 : + return DecimateMesh( iPolyData, iNumberOfPoints); + default : + itkGenericExceptionMacro( << "dimension unknown (Reconstruct polydata)" ); + } + + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) +{ + // define target reduction + unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); + + double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; + + vtkSmartPointer decimator = + vtkSmartPointer::New(); + decimator->SetInput(iPolyData); + decimator->SetTargetReduction(target); + decimator->Update(); + + return decimator->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) +{ + // define target reduction + unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); + + double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; + + vtkSmartPointer decimator = + vtkSmartPointer::New(); + decimator->SetInput(iPolyData); + decimator->SetTargetReduction(target); + decimator->Update(); + + /* + * \todo Nicolas-fill holes -smooth..? + */ + + return decimator->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +QGoSegmentationAlgo:: +SetDecimate(bool& iDecimate) +{ + m_Decimate = iDecimate; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +bool +QGoSegmentationAlgo:: +GetDecimate() +{ + return m_Decimate; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +QGoSegmentationAlgo:: +SetNumberOfPoints( const unsigned int& iNumberOfPoints) +{ + m_NumberOfPoints = iNumberOfPoints; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +QGoSegmentationAlgo:: +GetNumberOfPoints() const +{ + return m_NumberOfPoints; +} +//-------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx.bak b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx.bak new file mode 100644 index 00000000..0e2a20ff --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.cxx.bak @@ -0,0 +1,429 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoSegmentationAlgo.h" + +// Extract ROI +#include "vtkExtractVOI.h" + +// extract polydata 2d +#include "vtkMarchingSquares.h" +//reorder contour +#include "vtkStripper.h" +#include "vtkCellArray.h" +// extract polydata 3d +#include "vtkContourFilter.h" +#include "vtkFeatureEdges.h" +#include "vtkFillHolesFilter.h" +#include "vtkPolyDataConnectivityFilter.h" +#include "vtkWindowedSincPolyDataFilter.h" + +// Decimation 2d +#include "vtkPolylineDecimation.h" +// Decimation 3d +#include "vtkDecimatePro.h" + + +// test code +#include + + +QGoSegmentationAlgo::QGoSegmentationAlgo(QWidget *iParent) + : m_Decimate(true), m_NumberOfPoints(100), m_AlgoWidget(NULL) +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoSegmentationAlgo::~QGoSegmentationAlgo() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoAlgorithmWidget* QGoSegmentationAlgo::GetAlgoWidget() +{ + return this->m_AlgoWidget; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSegmentationAlgo:: +ExtractROI(std::vector iBounds, std::vector iImages) +{ + // vector to be returned + std::vector listOfImages; + + //iterator on the images + std::vector::iterator it = iImages.begin(); + + while( it != iImages.end()) + { + listOfImages.push_back( ExtractROI(iBounds, *it) ); + ++it; + } + + return listOfImages; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +<<<<<<< HEAD +ExtractROI(std::vector iBounds, vtkImageData* iImage) +======= +ExtractROI(double* iBounds, vtkSmartPointer iImage) +>>>>>>> add_genericMethods +{ + // make sure there + // assert( iBounds ); + + vtkSmartPointer extractVOI = + vtkSmartPointer::New(); + extractVOI->SetInput( iImage ); + extractVOI->SetVOI( iBounds[0] ,iBounds[1], + iBounds[2] ,iBounds[3], + iBounds[4], iBounds[5]); + extractVOI->Update(); + + return extractVOI->GetOutput(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSegmentationAlgo:: +ExtractPolyData(std::vector iInputImage, + const double & iThreshold) +{ + // vector to be returned + std::vector listOfPolys; + + //iterator on the images + std::vector::iterator it = iInputImage.begin(); + + while( it != iInputImage.end()) + { + vtkPolyData* extractedPolyData = ExtractPolyData(*it, iThreshold); + if( extractedPolyData ) + { + listOfPolys.push_back( extractedPolyData ); + } + ++it; + } + + return listOfPolys; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractPolyData(vtkImageData *iInputImage, const double & iThreshold) +{ + // make sure there is an image + assert( iInputImage ); + + // test dimension of the input + int dimension = iInputImage->GetDataDimension(); + + switch ( dimension ) { + case 2 : + return ExtractContour( iInputImage, iThreshold); + case 3 : + return ExtractMesh( iInputImage, iThreshold); + default : + std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; + } + + return NULL; +} +//------------------------------------------------------------------------- + +/* + * \todo Nicolas-do a better reconstruction.. + */ +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractContour( vtkSmartPointer iInputImage, const double & iThreshold) +{ + // create iso-contours + vtkSmartPointer contours = + vtkSmartPointer::New(); + + contours->SetInput(iInputImage); + contours->GenerateValues (1, iThreshold, iThreshold); + contours->Update(); + + return ReorganizeContour( contours->GetOutput() ); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ReorganizeContour(vtkSmartPointer iInputImage) +{ + /* + * \note Nicolas-to be enhanced + */ + // Create reorganize contours + vtkStripper *stripper = vtkStripper::New(); + + stripper->SetInput(iInputImage); + //Is it useful?? Which number is the best suited? + stripper->SetMaximumLength(999); + stripper->Update(); + + // Reorder points + stripper->GetOutput()->GetLines()->InitTraversal(); + + // npts = nb of points in the line + // *pts = pointer to each point + + vtkIdType *pts = NULL; + vtkIdType npts = 0; + stripper->GetOutput()->GetLines()->GetNextCell(npts, pts); + vtkPoints *points = vtkPoints::New(); + + vtkCellArray *lines = vtkCellArray::New(); + vtkIdType * lineIndices = new vtkIdType[static_cast< int >( npts + 1 )]; + + for ( int k = 0; k < static_cast< int >( npts ); k++ ) + { + points->InsertPoint( k, stripper->GetOutput()->GetPoints()->GetPoint(pts[k]) ); + lineIndices[k] = k; + } + + lineIndices[static_cast< int >( npts )] = 0; + lines->InsertNextCell(npts + 1, lineIndices); + delete[] lineIndices; + + vtkSmartPointer output = vtkSmartPointer::New(); + output->SetPoints(points); + output->SetLines(lines); + + lines->Delete(); + points->Delete(); + stripper->Delete(); + + return output; +} + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +ExtractMesh(vtkSmartPointer iInputImage, const double & iThreshold) +{ + vtkSmartPointer< vtkContourFilter > contours = vtkSmartPointer< vtkContourFilter >::New(); + contours->SetInput(iInputImage); + contours->SetComputeGradients(0); + contours->SetComputeNormals(0); + contours->SetComputeScalars(0); + contours->SetNumberOfContours(1); + contours->SetValue(0, iThreshold); + contours->Update(); + + vtkSmartPointer< vtkFeatureEdges > feature = + vtkSmartPointer< vtkFeatureEdges >::New(); + feature->SetInputConnection( contours->GetOutputPort() ); + feature->BoundaryEdgesOn(); + feature->FeatureEdgesOff(); + feature->NonManifoldEdgesOn(); + feature->ManifoldEdgesOff(); + feature->Update(); + + vtkSmartPointer< vtkFillHolesFilter > fillFilter = + vtkSmartPointer< vtkFillHolesFilter >::New(); + + vtkSmartPointer< vtkPolyDataConnectivityFilter > connectivityFilter = + vtkSmartPointer< vtkPolyDataConnectivityFilter >::New(); + connectivityFilter->SetExtractionModeToLargestRegion(); + + + if ( feature->GetOutput()->GetNumberOfCells() > 0 ) + { + // fill holes if any! + fillFilter->SetInputConnection( contours->GetOutputPort() ); + fillFilter->Update(); + + connectivityFilter->SetInputConnection( fillFilter->GetOutputPort() ); + } + else + { + connectivityFilter->SetInputConnection( contours->GetOutputPort() ); + } + + // keep the largest region + connectivityFilter->Update(); + /* + * \note Nicolas-Smoother not connected + */ +/* + unsigned int smoothingIterations = 15; + double passBand = 0.001; + double featureAngle = 120.0; + + // smoothing + vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoother = + vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New(); + smoother->SetInputConnection( connectivityFilter->GetOutputPort() ); + smoother->SetNumberOfIterations( smoothingIterations ); + smoother->BoundarySmoothingOff(); + smoother->FeatureEdgeSmoothingOff(); + smoother->SetFeatureAngle(featureAngle); + smoother->SetPassBand(passBand); + smoother->NonManifoldSmoothingOn(); + smoother->NormalizeCoordinatesOn(); + smoother->Update(); +*/ + return connectivityFilter->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimatePolyData( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) +{ + // make sure there is a polydata + assert( iPolyData ); + + /* + * \todo Nicolas-might be better solution to test dimension of a PolyData + */ + // test dimension of the input + double* bounds = iPolyData->GetBounds(); + int dimension = 3; + if(bounds[0] == bounds[1] || bounds[2] == bounds[3] || bounds[4] == bounds[5]) + { + --dimension; + } + + switch ( dimension ) { + case 2 : + return DecimateContour( iPolyData, iNumberOfPoints); + case 3 : + return DecimateMesh( iPolyData, iNumberOfPoints); + default : + std::cout << "dimension unknown (Reconstruct polydata)" << std::endl; + } + + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimateContour( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) +{ + // define target reduction + unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); + + double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; + + vtkSmartPointer decimator = + vtkSmartPointer::New(); + decimator->SetInput(iPolyData); + decimator->SetTargetReduction(target); + decimator->Update(); + + return decimator->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +QGoSegmentationAlgo:: +DecimateMesh( vtkSmartPointer iPolyData, unsigned int iNumberOfPoints) +{ + // define target reduction + unsigned int numberOfPoints = iPolyData->GetNumberOfPoints(); + + double target = 1 - (double)iNumberOfPoints/(double)numberOfPoints; + + vtkSmartPointer decimator = + vtkSmartPointer::New(); + decimator->SetInput(iPolyData); + decimator->SetTargetReduction(target); + decimator->Update(); + + /* + * \todo Nicolas-fill holes -smooth..? + */ + + return decimator->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +QGoSegmentationAlgo:: +SetDecimate(bool& iDecimate) +{ + m_Decimate = iDecimate; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +bool +QGoSegmentationAlgo:: +GetDecimate() +{ + return m_Decimate; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +QGoSegmentationAlgo:: +SetNumberOfPoints( unsigned int& iNumberOfPoints) +{ + m_NumberOfPoints = iNumberOfPoints; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +QGoSegmentationAlgo:: +GetNumberOfPoints() +{ + return m_NumberOfPoints; +} +//-------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h new file mode 100644 index 00000000..19cad84d --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h @@ -0,0 +1,531 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoSegmentationAlgo_h +#define __QGoSegmentationAlgo_h + +#include "QGoAlgorithmWidget.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "QGoGUILibConfigure.h" + +// convert VTK to ITK +#include "itkImage.h" +#include "itkVTKImageImport.h" +#include "vtkImageExport.h" +#include "vtkitkAdaptor.h" + +// convert itk to vtk +#include "itkImageToVTKImageFilter.h" + +// extract 2d from 2d or 3d from 3d +#include "itkRegionOfInterestImageFilter.h" + +// extract 2d from 3d +#include "itkExtractImageFilter.h" + +// change info +#include "itkChangeInformationImageFilter.h" + +class GoImageProcessor; + +/** +\class QGoSegmentationAlgo +\brief abstract class to be the interface between the algorithms for meshes +and contours and GoFigure +*/ +class QGOGUILIB_EXPORT QGoSegmentationAlgo:public QObject +{ + Q_OBJECT +public: + explicit QGoSegmentationAlgo(QWidget *iParent = 0); + virtual ~QGoSegmentationAlgo(); + + /** + \brief return the algowidget + */ + QGoAlgorithmWidget* GetAlgoWidget(); + + /** + \brief return the vtkpolydata created by the algorithm + */ + virtual std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false) = 0; + + /* + * \note Nicolas-shouldnt be public-move to protected + */ + /* + * \brief Extract region of interest, given a bounding box and a list of vtk images + * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) + * \param[in] iImages vector of vtkimagedata + * \return list of roi + */ + std::vector VTKExtractROI( + const std::vector& iBounds, + const std::vector< vtkSmartPointer< vtkImageData > >& iImages); + /* + * \brief Extract region of interest, given a bounding box and a vtk image + * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) + * \param[in] iImage vtkimagedata + * \return roi + */ + vtkImageData* VTKExtractROI( + const std::vector& iBounds, + const vtkSmartPointer< vtkImageData > & iImage); + + /* + * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", + * the dimension should be 3 all the time. + * (Even if we extract a2D region from a 3d image) + * \tparam PixelType type of pixel (unsigned char, etc.) + * \tparam VImageDimension dimension of the image (2 or 3) + * \param[in] iInput Pointer to a vtkImageData + * \return Pointer to an itkImage + */ + template< class PixelType, unsigned int VImageDimension > + typename itk::Image< PixelType, VImageDimension >::Pointer + ConvertVTK2ITK(vtkImageData *iInput) + { + // make sure there is an input + assert ( iInput ); + + //Export VTK image to ITK + vtkSmartPointer exporter = + vtkSmartPointer::New(); + exporter->SetInput(iInput); + exporter->Update(); + + // ImageType + typedef itk::Image< PixelType, VImageDimension > ImageType; + // Import VTK Image to ITK + typedef itk::VTKImageImport< ImageType > ImageImportType; + typedef typename ImageImportType::Pointer ImageImportPointer; + ImageImportPointer importer = ImageImportType::New(); + + ConnectPipelines< vtkImageExport, ImageImportPointer >( + exporter, + importer); + + typename ImageType::Pointer itkImage = importer->GetOutput(); + itkImage->DisconnectPipeline(); + + return itkImage; + } + + /* + * \brief Convert a itkImage to a vtkImage. If we call after "ExtractROI", + * the dimension should be 3 all the time. + * (Even if we extract a2D region from a 3d image) + * \tparam PixelType type of pixel (unsigned char, etc.) + * \tparam VImageDimension dimension of the image (2 or 3) + * \param[in] iInput Pointer to an itkImage + * \return Pointer to an vtkImageData + */ + template< class PixelType, unsigned int VImageDimension > + vtkImageData* + ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput) + { + typedef itk::Image< PixelType, VImageDimension > InternalImageType; + typedef itk::ImageToVTKImageFilter< InternalImageType > ConverterType; + typedef typename ConverterType::Pointer ConverterPointer; + + ConverterPointer converter = ConverterType::New(); + converter->SetInput(iInput); + + try + { + converter->Update(); + } + catch (itk::ExceptionObject & err) + { + std::cerr << "converter Exception:" << err << std::endl; + } + + vtkImageData* output_image = vtkImageData::New(); + output_image->DeepCopy( converter->GetOutput() ); + + return output_image; + } + + //------------------------------------------------------------------------- + template< class PixelType, unsigned int VImageDimension > + typename itk::Image< PixelType, VImageDimension >::Pointer + ITKExtractROI( + const std::vector< double > & iBounds, + typename itk::Image< PixelType, VImageDimension >::Pointer iInput ) + { + typedef itk::Image< PixelType, VImageDimension > ImageType; + typedef typename ImageType::PointType ImagePointType; + typedef typename ImageType::IndexType ImageIndexType; + typedef typename ImageType::IndexValueType ImageIndexValueType; + typedef typename ImageType::SizeType ImageSizeType; + typedef typename ImageType::SizeValueType ImageSizeValueType; + typedef typename ImageType::RegionType ImageRegionType; + typedef typename ImageType::SpacingType ImageSpacingType; + + assert( iBounds.size() == 2 * VImageDimension ); + + if ( iInput.IsNull() ) + { + std::cerr << "iInput is Null" << std::endl; + } + + ImagePointType t_min, t_max; + + unsigned int k = 0; + for( unsigned int dim = 0; dim < VImageDimension; dim++ ) + { + t_min[dim] = iBounds[k++]; + t_max[dim] = iBounds[k++]; + } + + ImageIndexType startOfROI, endOfROI; + iInput->TransformPhysicalPointToIndex( t_min, startOfROI ); + iInput->TransformPhysicalPointToIndex( t_max, endOfROI ); + + ImageSizeType sizeOfLargeImage = + iInput->GetLargestPossibleRegion().GetSize(); + + ImageSizeType size; + size.Fill( 0 ); + + for( unsigned int dim = 0; dim < VImageDimension; dim++ ) + { + if( startOfROI[dim] < 0 ) + { + startOfROI[dim] = 0; + } + if( startOfROI[dim] > sizeOfLargeImage[dim] ) + { + startOfROI[dim] = sizeOfLargeImage[dim] - 1; + } + + if( endOfROI[dim] < 0 ) + { + endOfROI[dim] = 0; + } + if( endOfROI[dim] > sizeOfLargeImage[dim] ) + { + endOfROI[dim] = sizeOfLargeImage[dim] - 1; + } + + size[dim] = endOfROI[dim] - startOfROI[dim]; + + if( size[dim] < 0 ) + { + size[dim] = 0; + } + } + + ImageRegionType region; + region.SetSize(size); + region.SetIndex(startOfROI); + + typedef itk::RegionOfInterestImageFilter< ImageType, ImageType > ROIFilterType; + typedef typename ROIFilterType::Pointer ROIFilterPointer; + + ROIFilterPointer roi = ROIFilterType::New(); + roi->SetInput(iInput); + roi->SetRegionOfInterest(region); + try + { + roi->Update(); + } + catch (itk::ExceptionObject & err) + { + std::cerr << "roi Exception:" << err << std::endl; + } + return roi->GetOutput(); + } + + template< class PixelType> + typename itk::Image< PixelType, 2>::Pointer + ITKExtractSlice( + const std::vector< double > & iBounds, + typename itk::Image< PixelType, 3 >::Pointer iInput ) + { + typedef itk::Image< PixelType, 3 > InputImageType; + typedef itk::Image< PixelType, 2 > OutputImageType; + + typedef typename InputImageType::PointType ImagePointType; + typedef typename InputImageType::IndexType ImageIndexType; + typedef typename InputImageType::IndexValueType ImageIndexValueType; + typedef typename InputImageType::SizeType ImageSizeType; + typedef typename InputImageType::SizeValueType ImageSizeValueType; + typedef typename InputImageType::RegionType ImageRegionType; + typedef typename InputImageType::SpacingType ImageSpacingType; + + typedef typename OutputImageType::PointType oImagePointType; + typedef typename OutputImageType::OffsetType oImageOffsetType; + + ImagePointType t_min, t_max; + oImagePointType new_origin; + + // create ROI + unsigned int k = 0; + for( unsigned int dim = 0; dim < 3; dim++ ) + { + t_min[dim] = iBounds[k++]; + t_max[dim] = iBounds[k++]; + } + + ImageIndexType startOfROI, endOfROI; + iInput->TransformPhysicalPointToIndex( t_min, startOfROI ); + iInput->TransformPhysicalPointToIndex( t_max, endOfROI ); + + ImageSizeType sizeOfLargeImage = + iInput->GetLargestPossibleRegion().GetSize(); + + ImageSizeType size; + size.Fill( 0 ); +#ifdef ITKv4 + oImageOffsetType new_offset; +#else + long int* new_offset; +#endif + + + int l = 0; + + for( unsigned int dim = 0; dim < 3; dim++ ) + { + if( startOfROI[dim] < 0 ) + { + startOfROI[dim] = 0; + } + if( startOfROI[dim] > sizeOfLargeImage[dim] ) + { + startOfROI[dim] = sizeOfLargeImage[dim] - 1; + } + + if( endOfROI[dim] < 0 ) + { + endOfROI[dim] = 0; + } + if( endOfROI[dim] > sizeOfLargeImage[dim] ) + { + endOfROI[dim] = sizeOfLargeImage[dim] - 1; + } + + size[dim] = endOfROI[dim] - startOfROI[dim]; + + if( size[dim] < 0 ) + { + size[dim] = 0; + } + + // new origin + if( size[dim] > 0 ) + { + new_origin[l] = t_min[dim]; + double sizeTest = startOfROI[dim]; + new_offset[l] = -sizeTest; + ++l; + } + } + + ImageRegionType region; + region.SetSize(size); + region.SetIndex(startOfROI); + + typedef itk::ExtractImageFilter< InputImageType, OutputImageType > FilterType; + typedef typename FilterType::Pointer FilterTypePointer; + FilterTypePointer filter = FilterType::New(); + filter->SetExtractionRegion( region ); + filter->SetInput( iInput ); +#ifdef ITKv4 + filter->SetDirectionCollapseToIdentity(); +#endif + + try + { + filter->Update(); + } + catch (itk::ExceptionObject & err) + { + std::cerr << "extract slice Exception:" << err << std::endl; + } + + // change information + typedef typename itk::ChangeInformationImageFilter CenterFilterType; + typedef typename CenterFilterType::Pointer CenterFilterTypePointer; + + CenterFilterTypePointer center = CenterFilterType::New(); + center->SetInput(filter->GetOutput()); + center->ChangeOriginOn(); + center->SetOutputOrigin(new_origin); + center->ChangeRegionOn(); + center->SetOutputOffset(new_offset); + + try + { + center->Update(); + } + catch (itk::ExceptionObject & err) + { + std::cerr << "change information slice Exception:" << err << std::endl; + } + return center->GetOutput(); + } + + /* + * \brief Generate list of polydata given a list of vtkimages and a threshold + * \param[in] iInputImage list of images + * \param[in] iThreshold threshold + * \return list of polydatas + */ + std::vector ExtractPolyData( + std::vector& iInputImage, + const double & iThreshold); + /* + * \brief Generate a polydata given a vtkimage and a threshold + * \param[in] iInputImage vtk image + * \param[in] iThreshold threshold + * \return polydata + */ + vtkSmartPointer ExtractPolyData( + vtkImageData *iInputImage, + const double & iThreshold); + + /* + * \brief Decimate a polydata + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimatePolyData( + vtkSmartPointer& iPolyData, + const unsigned int& iNumberOfPoints); + + /* + * \brief Enable decimation during polydata extraction. + * \param[in] iDecimate yes (true), no (false) + */ + void SetDecimate(bool& iDecimate); + /* + * \brief Is decimation enabled? + * \return true (yes), false (no) + */ + bool GetDecimate(); + + /* + * \brief Set target number of points for polydata extraction + * \param[in] iNumberOfPoints number of points + */ + void SetNumberOfPoints( const unsigned int& iNumberOfPoints); + /* + * \brief Get target number of points for polydata extraction + * \return number of points + */ + unsigned int GetNumberOfPoints() const; + +private: + + /* + * \brief Reconstruct a contour from a vtkImageData and a threshold + * \param[in] iInputImage vtkImageData + * \param[in] iThreshold threshold + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ExtractContour( + vtkSmartPointer iInputImage, + const double & iThreshold); + + /* + * \brief Reorganize points within a contour + * Required if we want to reedit this contour after. + * 1-reorganize + * \param[in] iInputImage vtkImageData + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ReorganizeContour( + vtkSmartPointer iInputImage); + + /* + * \brief Reconstruct a mesh from a vtkImageData and a threshold + * \param[in] iInputImage vtkImageData + * \param[in] iThreshold threshold + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ExtractMesh( + vtkSmartPointer iInputImage, + const double & iThreshold); + + /* + * \brief Decimate a contour (line) + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimateContour( + vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); + + /* + * \brief Decimate a mesh + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimateMesh( + vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); + + bool m_Decimate; + unsigned int m_NumberOfPoints; + +protected: + QGoAlgorithmWidget* m_AlgoWidget; + + /** + \brief construct the algowidget with the different parameters + */ + virtual void SetAlgoWidget(QWidget* iParent = 0) = 0; + + /** + \brief delete the different parameters + */ + virtual void DeleteParameters() = 0; + + /* + * \todo Arnaud has something for itkimage to vtkpolydata in 3d + */ + //add a method std::vector ConvertITKImagesToPolyData(std::vector iImages) + //add a method std::vector GetAttribut(std::vector iNewTraces) + //add a method itkImage ConvertVTKToITK(vtkImageIData iImage) +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h.bak b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h.bak new file mode 100644 index 00000000..7b6ea6c5 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSegmentationAlgo.h.bak @@ -0,0 +1,293 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoSegmentationAlgo_h +#define __QGoSegmentationAlgo_h + +#include "QGoAlgorithmWidget.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "QGoGUILibConfigure.h" + +// convert VTK to ITK +#include "itkImage.h" +#include "itkVTKImageImport.h" +#include "vtkImageExport.h" +#include "vtkitkAdaptor.h" + +// convert itk to vtk +#include "itkImageToVTKImageFilter.h" + +/** +\class QGoSegmentationAlgo +\brief abstract class to be the interface between the algorithms for meshes +and contours and GoFigure +*/ +class QGOGUILIB_EXPORT QGoSegmentationAlgo:public QObject +{ + Q_OBJECT +public: + QGoSegmentationAlgo(QWidget *iParent = 0); + ~QGoSegmentationAlgo(); + + /** + \brief return the algowidget + */ + QGoAlgorithmWidget* GetAlgoWidget(); + + /** + \brief return the vtkpolydata created by the algorithm + */ + virtual std::vector ApplyAlgo( + std::vector >* iImages, + int iChannel) = 0; + + /* + * \note Nicolas-shouldnt be public-move to protected + */ + /* + * \brief Extract region of interest, given a bounding box and a list of vtk images + * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) + * \param[in] iImages vector of vtkimagedata + * \return list of roi + */ + std::vector ExtractROI(std::vector iBounds, std::vector iImages); + /* + * \brief Extract region of interest, given a bounding box and a vtk image + * \param[in] iBounds bounding box (xmin, xmax, ymin, ymax, zmin, zmax) + * \param[in] iImage vtkimagedata + * \return roi + */ +<<<<<<< HEAD + vtkImageData* ExtractROI(std::vector iBounds, vtkImageData* iImage); +======= + vtkSmartPointer ExtractROI(double* iBounds, + vtkSmartPointer iImage); +>>>>>>> add_genericMethods + + /* + * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", + * the dimension should be 3 all the time. + * (Even if we extract a2D region from a 3d image) + * \tparam PixelType type of pixel (unsigned char, etc.) + * \tparam VImageDimension dimension of the image (2 or 3) + * \param[in] iInput Pointer to a vtkImageData + * \return Pointer to an itkImage + */ + template< class PixelType, unsigned int VImageDimension > + typename itk::Image< PixelType, VImageDimension >::Pointer + ConvertVTK2ITK(vtkImageData *iInput) + { + // make sure there is an input + assert ( iInput ); + + //Export VTK image to ITK + vtkSmartPointer exporter = + vtkSmartPointer::New(); + exporter->SetInput(iInput); + exporter->Update(); + + // ImageType + typedef itk::Image< PixelType, VImageDimension > ImageType; + // Import VTK Image to ITK + typedef itk::VTKImageImport< ImageType > ImageImportType; + typedef typename ImageImportType::Pointer ImageImportPointer; + ImageImportPointer importer = ImageImportType::New(); + + ConnectPipelines< vtkImageExport, ImageImportPointer >( + exporter, + importer); + + typename ImageType::Pointer itkImage = importer->GetOutput(); + itkImage->DisconnectPipeline(); + + return itkImage; + } + + /* + * \brief Convert a itkImage to a vtkImage. If we call after "ExtractROI", + * the dimension should be 3 all the time. + * (Even if we extract a2D region from a 3d image) + * \tparam PixelType type of pixel (unsigned char, etc.) + * \tparam VImageDimension dimension of the image (2 or 3) + * \param[in] iInput Pointer to an itkImage + * \return Pointer to an vtkImageData + */ + template< class PixelType, unsigned int VImageDimension > + vtkSmartPointer + ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput) + { + typedef itk::Image< PixelType, VImageDimension > InternalImageType; + typedef itk::ImageToVTKImageFilter< InternalImageType > ConverterType; + typedef typename ConverterType::Pointer ConverterPointer; + + ConverterPointer converter = ConverterType::New(); + converter->SetInput(iInput); + + try + { + converter->Update(); + } + catch (itk::ExceptionObject & err) + { + std::cerr << "converter Exception:" << err << std::endl; + } + + return converter->GetOutput(); + } + + /* + * \brief Generate list of polydata given a list of vtkimages and a threshold + * \param[in] iInputImage list of images + * \param[in] iThreshold threshold + * \return list of polydatas + */ + std::vector ExtractPolyData(std::vector iInputImage, + const double & iThreshold); + /* + * \brief Generate a polydata given a vtkimage and a threshold + * \param[in] iInputImage vtk image + * \param[in] iThreshold threshold + * \return polydata + */ + vtkSmartPointer ExtractPolyData(vtkImageData *iInputImage, + const double & iThreshold); + + /* + * \brief Decimate a polydata + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimatePolyData( + vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); + + /* + * \brief Enable decimation during polydata extraction. + * \param[in] iDecimate yes (true), no (false) + */ + void SetDecimate(bool& iDecimate); + /* + * \brief Is decimation enabled? + * \return true (yes), false (no) + */ + bool GetDecimate(); + + /* + * \brief Set target number of points for polydata extraction + * \param[in] iNumberOfPoints number of points + */ + void SetNumberOfPoints( unsigned int& iNumberOfPoints); + /* + * \brief Get target number of points for polydata extraction + * \return number of points + */ + unsigned int GetNumberOfPoints(); + +private: + + /* + * \brief Reconstruct a contour from a vtkImageData and a threshold + * \param[in] iInputImage vtkImageData + * \param[in] iThreshold threshold + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ExtractContour( + vtkSmartPointer iInputImage, + const double & iThreshold); + + /* + * \brief Reorganize points within a contour + * Required if we want to reedit this contour after. + * 1-reorganize + * \param[in] iInputImage vtkImageData + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ReorganizeContour( + vtkSmartPointer iInputImage); + + /* + * \brief Reconstruct a mesh from a vtkImageData and a threshold + * \param[in] iInputImage vtkImageData + * \param[in] iThreshold threshold + * \return Pointer to a vtkPolyData + */ + vtkSmartPointer ExtractMesh( + vtkSmartPointer iInputImage, + const double & iThreshold); + + /* + * \brief Decimate a contour (line) + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimateContour( + vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); + + /* + * \brief Decimate a mesh + * \param[in] iPolyData polyData to be decimated + * \param[in] iNumberOfPoints target number of points + * \return Decimated polyData + */ + vtkSmartPointer DecimateMesh( + vtkSmartPointer iPolyData, unsigned int iNumberOfPoints); + + bool m_Decimate; + unsigned int m_NumberOfPoints; + +protected: + QGoAlgorithmWidget* m_AlgoWidget; + + /** + \brief construct the algowidget with the different parameters + */ + virtual void SetAlgoWidget(QWidget* iParent = 0) = 0; + + /** + \brief delete the different parameters + */ + virtual void DeleteParameters() = 0; + + /* + * \todo Arnaud has something for itkimage to vtkpolydata in 3d + */ + //add a method std::vector ConvertITKImagesToPolyData(std::vector iImages) + //add a method std::vector GetAttribut(std::vector iNewTraces) + //add a method itkImage ConvertVTKToITK(vtkImageIData iImage) +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.cxx new file mode 100644 index 00000000..ef51fcfe --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.cxx @@ -0,0 +1,105 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoSemiAutoSegmentationAlgo.h" + +//------------------------------------------------------------------------- +QGoSemiAutoSegmentationAlgo:: +QGoSemiAutoSegmentationAlgo( + std::vector< vtkPoints* >* iSeeds, + QWidget *iParent) : QGoSegmentationAlgo( iParent ), m_Seeds( iSeeds ) +{} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoSemiAutoSegmentationAlgo::~QGoSemiAutoSegmentationAlgo() +{ + /* + * \note Nicolas-Requiered this one? We just copy the address in the constructor. + if(this->m_Seeds) + { + this->m_Seeds->Delete(); + } + */ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoSemiAutoSegmentationAlgo::SetAlgoWidget(QWidget* iParent) +{ + if (this->m_AlgoWidget != NULL) + { + m_Radius = new QGoAlgoParameter("Radius", false, 0.1, 99.99, 2, 3); + this->m_AlgoWidget->AddParameter(m_Radius); + } + else + { + std::cout<<"the widget has to be created before"; + std::cout << "Debug: In " << __FILE__ << ", line " << __LINE__; + std::cout << std::endl; + } +} + +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSemiAutoSegmentationAlgo:: +GetBounds(const std::vector& iCenter, + const double& iRadius, + const unsigned int& iOrientation) +{ + assert( iCenter.size() == 3 ); + assert( iRadius >= 0. ); + assert( iOrientation < 4 ); + + std::vector boundingBox( 6, 0. ); + unsigned int k = 0; + + for(unsigned int i=0; i<3; i++) + { + if(i == iOrientation) + { + boundingBox[k++] = iCenter[i]; + boundingBox[k++] = iCenter[i]; + } + else + { + boundingBox[k++] = iCenter[i] - iRadius; + boundingBox[k++] = iCenter[i] + iRadius; + } + } + + return boundingBox; +} +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.h b/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.h new file mode 100644 index 00000000..f719b982 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSemiAutoSegmentationAlgo.h @@ -0,0 +1,96 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoSemiAutoSegmentationAlgo_h +#define __QGoSemiAutoSegmentationAlgo_h + +#include "QGoSegmentationAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "QGoGUILibConfigure.h" + +class GoImageProcessor; + +/** +\class QGoSemiAutoSegmentationAlgo +\brief abstract class to be the interface between the semi automatic +algorithms for meshes and contours and GoFigure +*/ +class QGOGUILIB_EXPORT QGoSemiAutoSegmentationAlgo:public QGoSegmentationAlgo +{ + Q_OBJECT +public: + explicit QGoSemiAutoSegmentationAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0); + virtual ~QGoSemiAutoSegmentationAlgo(); + + + /** + \brief return the vtkpolydata created by the algorithm + */ + virtual std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false) = 0; + +protected: + std::vector< vtkPoints* >* m_Seeds; + QGoAlgoParameter* m_Radius; + + /** + \brief construct the algowidget with the different parameters + */ + virtual void SetAlgoWidget(QWidget* iParent = 0); + + /** + \brief delete the different parameters + */ + virtual void DeleteParameters() = 0; + + /* + * \brief Get boundingBox from a center and a radius + * \param[in] iCenter center of the box + * \param[in] iRadius radius of the box + * \param[in] iOrientation 0-xy, 1-xz, 2-yz, 3-xyz + * \return vector[6] containing the bounding box (xmin, xmax, ymin, imax, ...) + */ + std::vector GetBounds( + const std::vector& iCenter, + const double& iRadius, + const unsigned int& iOrientation = 3); + +}; + +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx new file mode 100644 index 00000000..1cf55621 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.cxx @@ -0,0 +1,83 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoSetOfContoursLevelSetAlgo.h" +#include "QGoFilterChanAndVese.h" + +#include "GoImageProcessor.h" + +QGoSetOfContoursLevelSetAlgo::QGoSetOfContoursLevelSetAlgo( + std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoLevelSetAlgo(iSeeds, iParent) +{ + m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); + this->m_AlgoWidget->AddParameter(m_Sampling); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoSetOfContoursLevelSetAlgo::~QGoSetOfContoursLevelSetAlgo() +{ + //this->DeleteParameters(); + delete m_Sampling; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector QGoSetOfContoursLevelSetAlgo::ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn) +{ + std::vector NewContours = std::vector(); + return NewContours; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector > QGoSetOfContoursLevelSetAlgo:: + ApplyAlgoSeveralSeeds( + GoImageProcessor* iImages, std::string iChannel) +{ + std::vector > NewContours; + QGoFilterChanAndVese LevelSetFilter; + //double *center = new double[3]; + + /* NewContours = + LevelSetFilter.ApplyFilterSetOf2D(this->m_Radius->GetValue(), + this->m_Seeds, this->m_Iterations->GetValue(), + this->m_Curvature->GetValue(),this->m_Sampling->GetValue(), + iImages, iChannel );*/ + + return NewContours; +} diff --git a/Code/GUI/lib/QGoModeEditingWidget.h b/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.h similarity index 66% rename from Code/GUI/lib/QGoModeEditingWidget.h rename to Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.h index cc05daed..f6e1b8ec 100644 --- a/Code/GUI/lib/QGoModeEditingWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursLevelSetAlgo.h @@ -31,42 +31,43 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#ifndef __QGoSetOfContoursLevelSetAlgo_h +#define __QGoSetOfContoursLevelSetAlgo_h -#ifndef __QGoModeEditingWidget_h -#define __QGoModeEditingWidget_h +#include "QGoLevelSetAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +class GoImageProcessor; -#include -#include -#include -#include /** - * \class QGoModeEditingWidget - * \ingroup GUI - * \brief widget that manages the different modes for the TraceEditingWidget, - has a combobox with the mode names and a corresponging stackedWidgets which - display the right widget according to the mode selected in the combobox +\class QGoSetOfContoursLevelSetAlgo +\brief class to be the interface between the levelset algo for set of contours +and GoFigure */ -class QGoModeEditingWidget: - public QWidget +class QGoSetOfContoursLevelSetAlgo: public QGoLevelSetAlgo { - Q_OBJECT public: - explicit QGoModeEditingWidget(QWidget *iParent = 0); - ~QGoModeEditingWidget(); + QGoSetOfContoursLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoSetOfContoursLevelSetAlgo(); + + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); - /** - \brief add a widget in the StackedWidget with the mode name that will - be added in the combobox. - */ - void AddWidgetWithModeName (std::string iModeName, QWidget* iWidget= 0); + std::vector > ApplyAlgoSeveralSeeds( + GoImageProcessor* iImages, std::string iChannel); protected: - QVBoxLayout* m_VBoxLayout; - QComboBox* m_ModeComboBox; - QStackedWidget* m_ModeWidgets; - - void Initialize(); + + QGoAlgoParameter* m_Sampling; }; + #endif diff --git a/Code/GUI/lib/QGoContourSemiAutoWatershedWidget.cxx b/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.cxx similarity index 59% rename from Code/GUI/lib/QGoContourSemiAutoWatershedWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.cxx index 6b274ba3..838394e6 100644 --- a/Code/GUI/lib/QGoContourSemiAutoWatershedWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.cxx @@ -31,37 +31,51 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#include "QGoSetOfContoursShapeAlgo.h" +#include "QGoFilterShape.h" -#include "QGoContourSemiAutoWatershedWidget.h" +#include "GoImageProcessor.h" -//---------------------------------------------------------------------------// -QGoContourSemiAutoWatershedWidget::QGoContourSemiAutoWatershedWidget(QWidget *iParent) : QWidget(iParent) +QGoSetOfContoursShapeAlgo::QGoSetOfContoursShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoShapeAlgo(iSeeds, iParent) { - this->setupUi(this); - - // Connect signals - QObject::connect( this->tresholdMinSpinBox, SIGNAL( valueChanged(int) ), - this, SIGNAL( TreshMin(int) ) ); - - QObject::connect( this->tresholdMaxSpinBox, SIGNAL( valueChanged(int) ), - this, SIGNAL( TreshMax(int) ) ); - - QObject::connect( this->correlationDoubleSpinBox, SIGNAL( valueChanged(double) ), - this, SIGNAL( CorrTresh(double) ) ); - - QObject::connect( this->alphaDoubleSpinBox, SIGNAL( valueChanged(double) ), - this, SIGNAL( Alpha(double) ) ); - - QObject::connect( this->betaDoubleSpinBox, SIGNAL( valueChanged(double) ), - this, SIGNAL( Beta(double) ) ); + m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); + this->m_AlgoWidget->AddParameter(m_Sampling); } +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// +//------------------------------------------------------------------------- +QGoSetOfContoursShapeAlgo::~QGoSetOfContoursShapeAlgo() +{ + this->DeleteParameters(); + delete m_Sampling; +} +//------------------------------------------------------------------------- -//---------------------------------------------------------------------------// -QGoContourSemiAutoWatershedWidget:: -~QGoContourSemiAutoWatershedWidget() +//------------------------------------------------------------------------- +std::vector QGoSetOfContoursShapeAlgo::ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn) { + std::vector NewContours = std::vector(); + return NewContours; } +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector > QGoSetOfContoursShapeAlgo:: + ApplyAlgoSeveralSeeds( + GoImageProcessor* iImages, std::string iChannel) +{ + std::vector > NewContours; + QGoFilterShape ShapeFilter; + //double *center = new double[3]; -//---------------------------------------------------------------------------// \ No newline at end of file + /*NewContours = + ShapeFilter.ApplyFilterSetOf2D(this->m_Radius->GetValue(), + this->m_Shape->Getvalue(), this->m_Sampling->GetValue(), this->m_Seeds, + iImages, iChannel );*/ + + return NewContours; +} diff --git a/Code/GUI/lib/QGoFilterChanAndVese.h b/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.h similarity index 68% rename from Code/GUI/lib/QGoFilterChanAndVese.h rename to Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.h index 8f65acf9..272ef6af 100644 --- a/Code/GUI/lib/QGoFilterChanAndVese.h +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursShapeAlgo.h @@ -31,45 +31,43 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#ifndef __QGoFilterChanAndVese_h -#define __QGoFilterChanAndVese_h - -#include "QGoFilterSemiAutoBase.h" +#ifndef __QGoSetOfContoursShapeAlgo_h +#define __QGoSetOfContoursShapeAlgo_h +#include "QGoShapeAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +class GoImageProcessor; + /** - * \class QGoFilterChanAndVese - * \brief Levelset segmentation algorithm implementation. - * Can generate contours and meshes. - * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. - */ -class QGOGUILIB_EXPORT QGoFilterChanAndVese : public QGoFilterSemiAutoBase +\class QGoSetOfContoursShapeAlgo +\brief class to be the interface between the shape algo for set of contours +and GoFigure +*/ +class QGoSetOfContoursShapeAlgo: public QGoShapeAlgo { - Q_OBJECT public: - /** \brief Constructor */ - explicit QGoFilterChanAndVese(QObject *iParent = NULL, int iDimension = 2); - - /** \brief Destructor */ - ~QGoFilterChanAndVese(); + QGoSetOfContoursShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoSetOfContoursShapeAlgo(); - virtual vtkPolyData * Apply(); + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); - virtual void ConnectSignals(int iFilterNumber); - -public slots: - void setIterations(int iIterations); - - void setCurvature(int iCurvature); + std::vector > ApplyAlgoSeveralSeeds( + GoImageProcessor* iImages, std::string iChannel); protected: - void Filter2D(double *iCenter, const int & iOrientation); - void Filter3D(double *iCenter); + QGoAlgoParameter* m_Sampling; -private: - int m_Iterations; - int m_Curvature; }; + #endif diff --git a/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx b/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx new file mode 100644 index 00000000..16588b34 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.cxx @@ -0,0 +1,119 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoSetOfContoursWaterShedAlgo.h" + +#include "GoImageProcessor.h" + +QGoSetOfContoursWaterShedAlgo:: +QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoWaterShedAlgo(iSeeds, iParent) +{ + m_Sampling = new QGoAlgoParameter("Sampling", false, 0, 999, 3); + this->m_AlgoWidget->AddParameter(m_Sampling); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoSetOfContoursWaterShedAlgo:: +~QGoSetOfContoursWaterShedAlgo() +{ + //this->DeleteParameters(); + delete m_Sampling; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector +QGoSetOfContoursWaterShedAlgo:: +ApplyAlgo(GoImageProcessor* iImages,std::string iChannel, bool iIsInvertedOn) +{ + std::vector NewContours = std::vector(); + return NewContours; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::vector > +QGoSetOfContoursWaterShedAlgo:: +ApplyAlgoSeveralSeeds( GoImageProcessor* iImages, std::string iChannel) +{ + std::vector > NewContours; + + if ( this->m_Radius->GetValue() <= 0 ) + { + std::cerr << "Radius should be > 0 " << std::endl; + return NewContours; + } + + double Center[3]; + std::vector CenterVect(3); + + // LOOP FOR EACH SEED + for( size_t id = 0; id < this->m_Seeds->size(); id++ ) + { + unsigned int dimension2Collapse(0); + if(id == 0) + { + dimension2Collapse = 2; // we are in XY view, collapse Z + } + else if(id == 1) + { + dimension2Collapse = 1; // we are in XZ view, collapse Y + } + else if(id == 2) + { + dimension2Collapse = 0; // we are in YZ view, collapse X + } + + for ( int i = 0; i < (*this->m_Seeds)[id]->GetNumberOfPoints(); i++ ) + { + std::cout << "dimension2Collapse: " << dimension2Collapse << std::endl; + (*this->m_Seeds)[id]->GetPoint(i, Center); + + CenterVect[0] = Center[0]; + CenterVect[1] = Center[1]; + CenterVect[2] = Center[2]; + + std::vector temp_output = + this->ApplyWaterShedFilter< unsigned char >( + CenterVect, + iImages->getImageITK< unsigned char, 3>(iChannel),//input raw image + dimension2Collapse);// axe to be collapsed(0=x, 1=y, 2=z) + + NewContours.push_back( temp_output ); + } + } + + return NewContours; +} diff --git a/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.h b/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.h new file mode 100644 index 00000000..ce4289bc --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoSetOfContoursWaterShedAlgo.h @@ -0,0 +1,245 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoSetOfContoursWaterShedAlgo_h +#define __QGoSetOfContoursWaterShedAlgo_h + +// external files +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "vtkTransform.h" +#include "vtkTransformPolyDataFilter.h" + +// project files +#include "QGoWaterShedAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "QGoFilterWatershed.h" + +// temp for debug purpose +#include "vtkPolyDataMapper.h" +#include "vtkActor.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "itkImageFileWriter.h" + + +#include "vtkPointData.h" + +class GoImageProcessor; + + +/** +\class QGoSetOfContoursWaterShedAlgo +\brief class to be the interface between the watershed algo for set of contours +and GoFigure +*/ +class QGoSetOfContoursWaterShedAlgo: public QGoWaterShedAlgo +{ +public: + QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoSetOfContoursWaterShedAlgo(); + + // should not be virutal pure since we dont implement it.... + std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false); + + std::vector > ApplyAlgoSeveralSeeds( + GoImageProcessor* iImages, std::string iChannel); + +protected: + + QGoAlgoParameter* m_Sampling; + + template < class TPixel > + // note this will work only in 3D, so we can remove the template + // parameter on the image dimension + //unsigned int VImageDimension > + std::vector ApplyWaterShedFilter( + const std::vector& iCenter, + typename itk::Image< TPixel, 3 >::Pointer iImages, + const unsigned int& iOrientation) + { + assert( iCenter.size() == 3); + + const unsigned int ImageDimension = 3; + + typedef TPixel PixelType; + typedef itk::Image< PixelType, ImageDimension > ImageType; + typedef typename ImageType::Pointer ImagePointer; + typedef itk::Image< PixelType, 2 > ImageType2D; + typedef typename ImageType2D::Pointer ImageType2DPointer; + typedef typename ImageType::SpacingType ImageSpacingType; + + std::vector output; + + ImageSpacingType spacing = iImages->GetSpacing(); + + for(unsigned int i= 0; im_Sampling->GetValue(); ++i) + { + // let's compute the bounds of the region of interest + double radius = this->m_Radius->GetValue(); + + std::vector< double > bounds( 2 * ImageDimension, 0. ); + unsigned int k = 0; + for( unsigned int dim = 0; dim < ImageDimension; dim++ ) + { + bounds[k++] = iCenter[dim] - 2. * radius; + bounds[k++] = iCenter[dim] + 2. * radius; + } + + int pair = i+ i%2 -1; + if(pair < 0) + { + pair = 0; + } + + bounds[2*iOrientation] = + iCenter[iOrientation] + (pair*(pow(-1., static_cast(i) ) )*spacing[iOrientation]); + bounds[2*iOrientation +1] = + iCenter[iOrientation] + (pair*(pow(-1., static_cast(i) ) )*spacing[iOrientation]); + + // then let's extract the Slice of Interest + ImageType2DPointer ITK_Slice_Image = + this->ITKExtractSlice( bounds, iImages ); + + // Compute the segmentation in 3D + QGoFilterWatershed Filter; + Filter.Apply2DFilter< PixelType >( + ITK_Slice_Image, + this->m_ThresMin->GetValue(), + this->m_ThresMax->GetValue(), + this->m_CorrThres->GetValue(), + this->m_Alpha->GetValue(), + this->m_Beta->GetValue()); + + typename QGoFilterWatershed::Output2DPointer + ItkOutPut = Filter.GetOutput2D(); + + // Here it would be better if the mesh extraction would be performed directly + // in ITK instead. + vtkImageData * FilterOutPutToVTK = + this->ConvertITK2VTK< + typename QGoFilterWatershed::OutputPixelType, + 2>( ItkOutPut ); + + // Nicolas- should be able to tune the parameter -0.5- + vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5); + + // translation transform ----------------------- + //------------------------------------------------------------------------ + double temp_bounds[6]; + FilterOutPutToVTK->GetBounds( temp_bounds ); + + double temp_center[3]; + temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5; + temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5; + temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5; + + vtkSmartPointer< vtkTransform > translation2 = + vtkSmartPointer< vtkTransform >::New(); + + translation2->Translate(-temp_center[0], + -temp_center[1], + -temp_center[2]); + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform2->SetTransform(translation2); + mesh_transform2->SetInput( temp_output ); + mesh_transform2->Update(); + + // rotation transform ----------------------- + //------------------------------------------------------------------------ + vtkSmartPointer< vtkTransform > translation = + vtkSmartPointer< vtkTransform >::New(); + // rotate polydata if necessary + if(iOrientation == 0) + { + translation->RotateY(-90); // check if + or - 90 + } + else if(iOrientation == 1) + { + translation->RotateX(-90); // check if + or - 90 + } + else if(iOrientation == 2) + { + // no rotation, we are in the good plan + } + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform->SetTransform(translation); + mesh_transform->SetInput( mesh_transform2->GetOutput() ); + mesh_transform->Update(); + + // translate back ----------------------- + //------------------------------------------------------------------------ + double temp_center2[3]; + temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5; + temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5; + temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5; + + vtkSmartPointer< vtkTransform > translation23 = + vtkSmartPointer< vtkTransform >::New(); + + translation23->Translate(temp_center2[0], + temp_center2[1], + temp_center2[2]); + + vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 = + vtkSmartPointer< vtkTransformPolyDataFilter >::New(); + mesh_transform23->SetTransform(translation23); + mesh_transform23->SetInput( mesh_transform->GetOutput() ); + mesh_transform23->Update(); + + //----------------------------------------------------------------------- + + temp_output->Delete(); + + vtkPolyData* testt = vtkPolyData::New(); + testt->DeepCopy(mesh_transform23->GetOutput()); + + output.push_back(testt); + } + + return output; + } +}; + +#endif diff --git a/Code/GUI/lib/QGoTraceEditingWidget.cxx b/Code/GUI/lib/TraceEditing/QGoShapeAlgo.cxx similarity index 68% rename from Code/GUI/lib/QGoTraceEditingWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoShapeAlgo.cxx index fc38a0d0..8fb326ff 100644 --- a/Code/GUI/lib/QGoTraceEditingWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoShapeAlgo.cxx @@ -31,46 +31,49 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#include "QGoTraceEditingWidget.h" -#include "QGoAdvancedParametersWidget.h" -#include "QGoModeEditingWidget.h" -#include +#include "QGoShapeAlgo.h" -QGoTraceEditingWidget::QGoTraceEditingWidget( - std::string iTraceName, QWidget *iParent) + +QGoShapeAlgo::QGoShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoSemiAutoSegmentationAlgo(iSeeds, iParent), m_Shape(NULL) { - this->Initialize(iParent); - this->setWindowTitle(tr("%1 Editing").arg(iTraceName.c_str())); + this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -QGoTraceEditingWidget::~QGoTraceEditingWidget() +QGoShapeAlgo::~QGoShapeAlgo() { + this->DeleteParameters(); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoTraceEditingWidget::Initialize(QWidget *iParent) +void QGoShapeAlgo::DeleteParameters() { - this->m_ModeEditingWidget = new QGoModeEditingWidget(this); - this->m_VLayout = new QVBoxLayout; - this->m_VLayout->addWidget(this->m_ModeEditingWidget); - QPushButton* ApplyButton = new QPushButton(tr("Apply"),this); - this->m_VLayout->addWidget(ApplyButton); - this->setLayout(this->m_VLayout); - this->m_VLayout->setSizeConstraint(QLayout::SetFixedSize); + if(m_Shape) + { + delete m_Shape; + m_Shape = NULL; + } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoTraceEditingWidget:: AddMode( - std::string iModeName, QWidget* iModeWidget) +void QGoShapeAlgo::SetAlgoWidget(QWidget* iParent) { - QWidget* ModeWidget = new QWidget; - if (iModeWidget != 0) - { - ModeWidget = iModeWidget; - } - this->m_ModeEditingWidget->AddWidgetWithModeName(iModeName, ModeWidget); -} \ No newline at end of file + this->m_AlgoWidget = + new QGoAlgorithmWidget("Shape 3D", iParent); + + QStringList ShapeList; + ShapeList.append("Sphere"); + ShapeList.append("Cube"); + this->m_Shape = new QGoAlgoParameter("Shape",true, ShapeList, "Sphere"); + this->m_AlgoWidget->AddParameter(m_Shape); + + QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + diff --git a/Code/GUI/lib/QGoAdvancedParametersWidget.h b/Code/GUI/lib/TraceEditing/QGoShapeAlgo.h similarity index 68% rename from Code/GUI/lib/QGoAdvancedParametersWidget.h rename to Code/GUI/lib/TraceEditing/QGoShapeAlgo.h index 0a5468dc..97f1463a 100644 --- a/Code/GUI/lib/QGoAdvancedParametersWidget.h +++ b/Code/GUI/lib/TraceEditing/QGoShapeAlgo.h @@ -31,40 +31,43 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#ifndef __QGoAdvancedParametersWidget_h -#define __QGoAdvancedParametersWidget_h +#ifndef __QGoShapeAlgo_h +#define __QGoShapeAlgo_h + +#include "QGoSemiAutoSegmentationAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" + +class GoImageProcessor; -#include -#include -#include -#include -#include -#include "ctkCollapsibleGroupBox.h" /** - * \class QGoAdvancedParametersWidget - * \ingroup GUI - * \brief widget for the advanced parameters displayed in an - expandable box +\class QGoShapeAlgo +\brief class to be the interface between the shape algo for meshes, +contours and set of contours and GoFigure */ -class QGoAdvancedParametersWidget: - public QWidget +class QGoShapeAlgo: public QGoSemiAutoSegmentationAlgo { - Q_OBJECT public: - explicit QGoAdvancedParametersWidget(QWidget *iParent = 0); - ~QGoAdvancedParametersWidget(); + QGoShapeAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoShapeAlgo(); - void Initialize(); - /** - \brief add a widget in the expandable box - */ - void AddAdvancedParamWidget(QWidget* iWidget); + virtual std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false ) = 0; protected: - QVBoxLayout* m_VBoxLayout; - ctkCollapsibleGroupBox* m_ExpandableBox; + QGoAlgoParameter* m_Shape; + + virtual void SetAlgoWidget(QWidget* iParent = 0); + + void DeleteParameters(); }; -#endif \ No newline at end of file +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.cxx b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.cxx new file mode 100644 index 00000000..825a8725 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.cxx @@ -0,0 +1,200 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoTraceEditingWidget.h" +#include "QGoModesManagerWidget.h" +#include "QGoAlgorithmsManagerWidget.h" +#include + +QGoTraceEditingWidget::QGoTraceEditingWidget( + std::string iTraceName,std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent) +{ + this->Initialize(iVectChannels, iListTimePoints, iParent); + this->setWindowTitle(tr("%1 Editing").arg(iTraceName.c_str())); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoTraceEditingWidget::~QGoTraceEditingWidget() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::Initialize(std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent) +{ + this->m_ListTimePoints = iListTimePoints; + this->m_ModeEditingWidget = new QGoModesManagerWidget( + iVectChannels, iListTimePoints, this); + + this->m_VLayout = new QVBoxLayout; + + this->SetModesManager(this->m_ModeEditingWidget); + this->setLayout(this->m_VLayout); + this->m_VLayout->setSizeConstraint(QLayout::SetFixedSize); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::AddMode( + std::string iModeName, QWidget* iModeWidget, bool ModeNeedSeeds) +{ + QWidget* ModeWidget = new QWidget; + if (iModeWidget != 0) + { + ModeWidget = iModeWidget; + } + this->m_ModeEditingWidget->AddWidgetWithModeName(iModeName, ModeWidget, + ModeNeedSeeds); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::AddMode(QGoAlgorithmsManagerWidget* iAlgoModeWidget, + bool ModeNeedSeeds) +{ + this->m_ModeEditingWidget->AddWidgetWithModeName(iAlgoModeWidget->GetModeName(), + iAlgoModeWidget, ModeNeedSeeds); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::SetModesManager(QGoModesManagerWidget* iModeWidget) +{ + this->m_ModeEditingWidget = iModeWidget; + this->m_VLayout->addWidget(this->m_ModeEditingWidget); + + QObject::connect( this->m_ModeEditingWidget, + SIGNAL (SetSeedInteractorBehaviour(bool) ), + this, + SIGNAL (SetSeedInteractorBehaviour(bool) ) ); + + QObject::connect( this->m_ModeEditingWidget, + SIGNAL(ResetClicked() ), + this, + SIGNAL(ResetClicked() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::SetANewModesManager(QGoModesManagerWidget* iModeWidget) +{ + delete this->m_ModeEditingWidget; + this->SetModesManager(iModeWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::AddAlgoWidgetForSemiAutomaticMode( + QGoAlgorithmWidget* iAlgoWidget) +{ + this->m_ModeEditingWidget->AddAlgoWidgetForSemiAutomaticMode(iAlgoWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::AddAlgoWidgetForAutomaticMode( + QGoAlgorithmWidget* iAlgoWidget) +{ + this->m_ModeEditingWidget->AddAlgoWidgetForAutomaticMode(iAlgoWidget); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidget::AddWidgetForManualMode(QWidget* iWidget, + QStringList iListTimePoint, bool ModeNeedSeeds) +{ + this->m_ModeEditingWidget->AddWidgetForManualMode(iWidget, + iListTimePoint, ModeNeedSeeds); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +std::string QGoTraceEditingWidget::GetCurrentImageName() +{ + return this->m_ModeEditingWidget->GetCurrentImageName(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +int QGoTraceEditingWidget::GetSelectedTimePoint() +{ + return this->m_ModeEditingWidget->GetSelectedTimePoint(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +bool QGoTraceEditingWidget::GetIsInvertedOn() +{ + return this->m_ModeEditingWidget->GetIsInvertedOn(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + void QGoTraceEditingWidget::CheckTheCurrentMode(bool IsVisible) + { + if (IsVisible) + { + this->m_ModeEditingWidget->SetTheRightMode(); + } + else + { + emit SetSeedInteractorBehaviour(false); + } + } + //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + void QGoTraceEditingWidget::SetTSliceForClassicView(int iTimePoint) + { + this->m_ModeEditingWidget->SetTSliceForClassicViewInAllAlgoModes(iTimePoint); + } + //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + void QGoTraceEditingWidget::SetTSliceForDopplerView( + std::map iListTimePoints, + int iChannelNumber) + { + this->m_ModeEditingWidget->SetTSliceForDopplerViewInAllAlgoModes( + iListTimePoints, iChannelNumber); + } + //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + std::string QGoTraceEditingWidget::GetCurrentModeName() +{ + return this->m_ModeEditingWidget->GetCurrentModeName(); +} diff --git a/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.h b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.h new file mode 100644 index 00000000..3f2b5300 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidget.h @@ -0,0 +1,115 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef __QGoTraceEditingWidget_h +#define __QGoTraceEditingWidget_h + +#include +#include +#include +#include +#include +#include "QGoModesManagerWidget.h" +#include "QGoAlgorithmsManagerWidget.h" + + +class QGoTraceEditingWidget: + public QWidget +{ + Q_OBJECT +public: + explicit QGoTraceEditingWidget(std::string iTraceName , + std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent = 0 ); + ~QGoTraceEditingWidget(); + + /** + \brief add iModeWidget as a widget to be displayed when iModeName is selected + in the combobox of m_ModeEditingWidget + \param[in] iModeName name of the mode corresponding to iModeWidget + \param[in] iModeWidget Widget corresponding to iModeName + */ + void AddMode( std::string iModeName, QWidget* iModeWidget, bool ModeNeedSeeds); + + void AddMode(QGoAlgorithmsManagerWidget* iAlgoModeWidget, bool ModeNeedSeeds); + + /** + \brief replace the existing m_ModeEditingWidget with iModeWidget: all the + previous mode will be erased + \param[in] iModeWidget modes manager + */ + void SetANewModesManager(QGoModesManagerWidget* iModeWidget); + + void AddAlgoWidgetForSemiAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); + + void AddAlgoWidgetForAutomaticMode(QGoAlgorithmWidget* iAlgoWidget); + + void AddWidgetForManualMode(QWidget* iWidget, + QStringList iListTimePoint, bool ModeNeedSeeds); + + std::string GetCurrentImageName(); + int GetSelectedTimePoint(); + bool GetIsInvertedOn(); + + /** + \brief check which mode is selected and if the seeds are needed or not and + emit the corresponding signals based on the visibility of the widget + */ + void CheckTheCurrentMode(bool IsVisible); + + void SetTSliceForClassicView(int iTimePoint); + void SetTSliceForDopplerView( + std::map iListTimePoints, int iChannelNumber); + + /** + \brief return the name of the current mode in the combobox + */ + std::string GetCurrentModeName(); + +signals: + void SetSeedInteractorBehaviour(bool enable); + + void ResetClicked(); + +protected: + void Initialize(std::vector iVectChannels, + QStringList iListTimePoints, QWidget *iParent = 0); + QGoModesManagerWidget* m_ModeEditingWidget; + QVBoxLayout* m_VLayout; + QStringList m_ListTimePoints; + + void SetModesManager(QGoModesManagerWidget* iModeWidget); + +}; +#endif diff --git a/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.cxx b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.cxx new file mode 100644 index 00000000..e9c53541 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.cxx @@ -0,0 +1,312 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "QGoTraceEditingWidgetManager.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" +#include "QGoAlgorithmsManagerWidget.h" +#include "vtkSmartPointer.h" +#include "vtkImageExport.h" +#include "vtkImageData.h" +#include + +#include "GoImageProcessor.h" + + +QGoTraceEditingWidgetManager::QGoTraceEditingWidgetManager( + std::string iTraceName, + std::vector iVectChannels, + int iTimeMin, + int iTimeMax, + std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent) +{ + this->m_TraceName = iTraceName; + this->m_Seeds = iSeeds; + this->m_Images = iImages; + this->m_CurrentTimePoint = iCurrentTimePoint; + + this->SetTheTraceWidget(iVectChannels, iTimeMin, iTimeMax, iParent); + this->SetTheDockWidget(iParent); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoTraceEditingWidgetManager::~QGoTraceEditingWidgetManager() +{ +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidgetManager::SetTheTraceWidget( + std::vector iVectChannels, int iTimeMin, + int iTimeMax, QWidget* iParent) +{ + + QStringList ListTimePoints; + for (int i = iTimeMin; i < iTimeMax+1; ++i) + { + ListTimePoints.push_back(tr("%1").arg(i)); + } + this->m_ListTimePoint = ListTimePoints; + + this->m_TraceEditingWidget = new QGoTraceEditingWidget( + this->m_TraceName.c_str(), iVectChannels, ListTimePoints, iParent); + + QObject::connect( this->m_TraceEditingWidget, + SIGNAL(SetSeedInteractorBehaviour(bool) ), + this, + SIGNAL(SetSeedInteractorBehaviour(bool) ) ); + + QObject::connect( this->m_TraceEditingWidget, + SIGNAL(ResetClicked() ), + this, SIGNAL(ClearAllSeeds() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidgetManager::SetTheDockWidget(QWidget* iParent) +{ + + this->m_TraceEditingDockWidget = new QGoDockWidget(iParent); + std::string WindowTitle = this->m_TraceName; + WindowTitle += " Editing"; + this->m_TraceEditingDockWidget->setWindowTitle(WindowTitle.c_str()); + this->m_TraceEditingDockWidget->setWidget(this->m_TraceEditingWidget); + + QIcon TraceSegmentationIcon; + std::string PathIcon = ":/fig/"; + PathIcon += this->m_TraceName; + PathIcon += "Editing.png"; + + TraceSegmentationIcon.addPixmap(QPixmap( QString::fromUtf8(PathIcon.c_str() ) ), + QIcon::Normal, QIcon::Off); + + this->m_TraceEditingDockWidget->toggleViewAction()->setIcon(TraceSegmentationIcon); + this->m_TraceEditingDockWidget->toggleViewAction()->setToolTip( tr("%1 Editing").arg(this->m_TraceName.c_str() ) ); + this->m_TraceEditingDockWidget->toggleViewAction()->setStatusTip( + tr("Create %1s manually, semi-automatically or automatically").arg(this->m_TraceName.c_str() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QAction* QGoTraceEditingWidgetManager::GetToggleViewAction() +{ + return this->m_TraceEditingDockWidget->toggleViewAction(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QGoDockWidget* QGoTraceEditingWidgetManager::GetDockWidget() +{ + return this->m_TraceEditingDockWidget; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidgetManager::SetVisible(bool isVisible) +{ + this->m_TraceEditingDockWidget->setVisible(isVisible); + this->m_TraceEditingWidget->CheckTheCurrentMode(isVisible); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidgetManager::SetTSliceForClassicView() +{ + this->m_TraceEditingWidget->SetTSliceForClassicView( + *this->m_CurrentTimePoint); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoTraceEditingWidgetManager::SetTSliceForDopplerView( + std::map iListTimePoints, int iChannelNumber) +{ + this->m_TraceEditingWidget->SetTSliceForDopplerView( + iListTimePoints, iChannelNumber); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +int QGoTraceEditingWidgetManager::GetSelectedTimePoint() +{ + return this->m_TraceEditingWidget->GetSelectedTimePoint(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +/*void QGoMeshEditingWidgetManager::SetSemiAutomaticAlgorithms(QWidget* iParent) +{ + //level set: + m_LevelSetAlgo = new QGoMeshLevelSetAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* LevelSetWidget = m_LevelSetAlgo->GetAlgoWidget(); + this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(LevelSetWidget); + + QObject::connect(LevelSetWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyLevelSetAlgo() ) ); + + //shape: + this->m_ShapeAlgo = new QGoMeshShapeAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* ShapeWidget = this->m_ShapeAlgo->GetAlgoWidget(); + this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(ShapeWidget); + + QObject::connect(ShapeWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyShapeAlgo() ) ); + + //watershed: + this->m_WaterShedAlgo = new QGoMeshWaterShedAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* WaterShedWidget = m_WaterShedAlgo->GetAlgoWidget(); + this->m_MeshEditingWidget->AddAlgoWidgetForSemiAutomaticMode(WaterShedWidget); + + QObject::connect(WaterShedWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplyWaterShedAlgo() ) ); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetSetOfContoursAlgorithms( + std::vector iVectChannels, QStringList iListTime, + QWidget* iParent) +{ + m_SetOfContoursWidget = + new QGoAlgorithmsManagerWidget("Set of Contours", + iParent, iVectChannels, iListTime); + + this->m_SetOfContoursWaterShedAlgo = + new QGoSetOfContoursWaterShedAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursWaterShedWidget = + this->m_SetOfContoursWaterShedAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursWaterShedWidget); + + this->m_SetOfContoursLevelSetAlgo = + new QGoSetOfContoursLevelSetAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursLevelSetWidget = + this->m_SetOfContoursLevelSetAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursLevelSetWidget); + + this->m_SetOfContoursShapeAlgo = + new QGoSetOfContoursShapeAlgo(this->m_Seeds, iParent); + QGoAlgorithmWidget* SetOfContoursShapeWidget = + this->m_SetOfContoursShapeAlgo->GetAlgoWidget(); + this->m_SetOfContoursWidget->AddMethod(SetOfContoursShapeWidget); + + this->m_MeshEditingWidget->AddMode(m_SetOfContoursWidget, true); + + QObject::connect(SetOfContoursWaterShedWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursWaterShedAlgo() ) ); + + QObject::connect(SetOfContoursLevelSetWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursLevelSetAlgo() ) ); + + QObject::connect(SetOfContoursShapeWidget, SIGNAL(ApplyAlgo() ), + this, SLOT(ApplySetOfContoursShapeAlgo() ) ); + + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::SetSplitMergeMode(QWidget* iParent) +{ + QGoAlgorithmsManagerWidget* SplitAlgoWidget = + new QGoAlgorithmsManagerWidget("Split", iParent); + this->m_MeshEditingWidget->AddMode(SplitAlgoWidget, true); + + m_DanielAlgo = new QGoMeshSplitDanielssonDistanceAlgo(iParent); + QGoAlgorithmWidget * DanielWidget = m_DanielAlgo->GetAlgoWidget(); + SplitAlgoWidget->AddMethod(DanielWidget ); + + QObject::connect( DanielWidget, SIGNAL(ApplyAlgo() ) , + this, SLOT(ApplyDanielAlgo() ) ); + + QGoAlgorithmsManagerWidget* MergeAlgoWidget = + new QGoAlgorithmsManagerWidget("Merge", iParent); + this->m_MeshEditingWidget->AddMode(MergeAlgoWidget, true); + +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyDanielAlgo() +{ + this->GetPolydatasFromAlgo(this->m_DanielAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyLevelSetAlgo() +{ + this->GetPolydatasFromAlgo(this->m_LevelSetAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyShapeAlgo() +{ + this->GetPolydatasFromAlgo(this->m_ShapeAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplyWaterShedAlgo() +{ + this->GetPolydatasFromAlgo(this->m_WaterShedAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursWaterShedAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursWaterShedAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursLevelSetAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursLevelSetAlgo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void QGoMeshEditingWidgetManager::ApplySetOfContoursShapeAlgo() +{ + this->GetSetOfPolydatasFromAlgo( + this->m_SetOfContoursShapeAlgo); +}*/ diff --git a/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.h b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.h new file mode 100644 index 00000000..19cca535 --- /dev/null +++ b/Code/GUI/lib/TraceEditing/QGoTraceEditingWidgetManager.h @@ -0,0 +1,158 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#ifndef __QGoTraceEditingWidgetManager_h +#define __QGoTraceEditingWidgetManager_h + +#include "QGoTraceEditingWidget.h" +#include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" +#include "QGoDockWidget.h" +#include +#include + +class GoImageProcessor; + + +/** +\class QGoTraceEditingWidgetManager abstract class handles the interactions +between the user and the algorithms for one kind of trace +\brief +*/ +class QGOGUILIB_EXPORT QGoTraceEditingWidgetManager: public QObject +{ + Q_OBJECT +public: + QGoTraceEditingWidgetManager(std::string iTraceName, + std::vector iVectChannels, + int iTimeMin, int iTimeMax, + std::vector< vtkPoints* >* iSeeds, + GoImageProcessor* iImages, + int* iCurrentTimePoint, + QWidget* iParent=0); + + ~QGoTraceEditingWidgetManager(); + + QAction* GetToggleViewAction(); + + /** + \return the dockwidget for it to be integrated in the mainwindow + */ + QGoDockWidget* GetDockWidget(); + + /** + \brief display only the current timepoint in the TSlice comboboxes + of the qgoalgomanagerwidgets, disable them and enable the channel comboboxes + */ + virtual void SetTSliceForClassicView(); + + /** + \brief display the 3 timepoints chosen by the user in the TSlice comboboxes + of the qgoalgomanagerwidgets, enable them, display only the channel tracked + by the user and disable the channel comboboxes + */ + virtual void SetTSliceForDopplerView( + std::map iListTimePoints, int iChannelNumber); + +public slots: + /** + \brief show or hide the dockwidget and check the current selected mode in order + to emit a signal to get the seeds widget if show or to disable it of hide + */ + void SetVisible(bool isVisible); + +signals: + + void UpdateSeeds(); + void ClearAllSeeds(); + /** + \brief emitted when new meshes need to be saved in database and rendered in the + vizu, return the TSlice selected in the TSlice combobox + */ + void TracesCreatedFromAlgo(std::vector iVectPolydata, int iTCoord); + +protected: + QGoDockWidget* m_TraceEditingDockWidget; + QGoTraceEditingWidget* m_TraceEditingWidget; + + std::string m_TraceName; + std::vector< vtkPoints* >* m_Seeds; //useful ??? + GoImageProcessor* m_Images; + int* m_CurrentTimePoint; + QStringList m_ListTimePoint; + + void SetTheTraceWidget(std::vector iVectChannels, int iTimeMin, + int iTimeMax, QWidget* iParent); + + void SetTheDockWidget(QWidget* iParent); + + /** + \brief return the selected timepoint in the TSlice combobox + */ + int GetSelectedTimePoint(); + + /** + \brief add the algowidget of the different algo in the algomanagerwidget + for the semi automatic mode and set the different SIGNAL/SLOTS connections + */ + virtual void SetSemiAutomaticAlgorithms(QWidget* iParent = 0) = 0; + + /** + \brief get the vtkpolydata for the new created meshes by the chosen algo + */ + template + void GetPolydatasFromAlgo(T* iAlgo) + { + emit UpdateSeeds(); + std::vector NewTraces = iAlgo->ApplyAlgo( + this->m_Images, + this->m_TraceEditingWidget->GetCurrentImageName(), + this->m_TraceEditingWidget->GetIsInvertedOn() ); + + emit TracesCreatedFromAlgo(NewTraces, this->GetSelectedTimePoint() ); + emit ClearAllSeeds(); + } + +signals: + /** + \brief emit true to get the seeds widget enabled and false to disable it + */ + void SetSeedInteractorBehaviour(bool enable); + +protected slots: + +}; + +#endif diff --git a/Code/GUI/lib/QGoAdvancedParametersWidget.cxx b/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.cxx similarity index 63% rename from Code/GUI/lib/QGoAdvancedParametersWidget.cxx rename to Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.cxx index f67c4591..7034a530 100644 --- a/Code/GUI/lib/QGoAdvancedParametersWidget.cxx +++ b/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.cxx @@ -31,58 +31,57 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ +#include "QGoWaterShedAlgo.h" -#include "QGoAdvancedParametersWidget.h" -#include -#include -#include - -QGoAdvancedParametersWidget::QGoAdvancedParametersWidget(QWidget *iParent ) - :QWidget(iParent) +QGoWaterShedAlgo::QGoWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent) + :QGoSemiAutoSegmentationAlgo(iSeeds,iParent) { - this->Initialize(); + this->SetAlgoWidget(iParent); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -QGoAdvancedParametersWidget::~QGoAdvancedParametersWidget() +QGoWaterShedAlgo::~QGoWaterShedAlgo() { } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoAdvancedParametersWidget::Initialize() +void QGoWaterShedAlgo::DeleteParameters() { - this->m_VBoxLayout = new QVBoxLayout; - //this->m_ComboBox = new QComboBox(this); - //this->m_VBoxLayout->addWidget(this->m_ComboBox); - - m_ExpandableBox = new ctkCollapsibleGroupBox(tr("Advanced") ); - //this->m_AdvParamStackedLayout = new QStackedLayout(this); - this->m_ExpandableBox->setFlat(true); -// this->m_ExpandableBox->setLayout(this->m_AdvParamStackedLayout); - - this->m_VBoxLayout->addWidget(this->m_ExpandableBox); - this->m_VBoxLayout->setSizeConstraint(QLayout::SetFixedSize); - this->setLayout(this->m_VBoxLayout); - - //QObject::connect(this->m_ComboBox, SIGNAL(activated(int)), - // this->m_AdvParamStackedLayout, SLOT(setCurrentIndex(int))); - + delete m_ThresMin; + delete m_ThresMax; + delete m_CorrThres; + delete m_Alpha; + delete m_Beta; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- -void QGoAdvancedParametersWidget::AddAdvancedParamWidget(QWidget* iWidget) +void QGoWaterShedAlgo::SetAlgoWidget(QWidget* iParent) { - this->m_ExpandableBox->setLayout(iWidget->layout()); - this->m_ExpandableBox->setChecked(false); - //this->m_AdvParamStackedLayout->addWidget(iWidget); - //int Index = this->m_AdvParamStackedLayout->indexOf(iWidget); - //this->m_AdvParamStackedLayout - //this->m_ComboBox->insertItem(Index,iName.c_str()); + this->m_AlgoWidget = + new QGoAlgorithmWidget("WaterShed", iParent); + + m_ThresMin = new QGoAlgoParameter("Thres.Min.", true, 0, 999, 10); + this->m_AlgoWidget->AddParameter(m_ThresMin); + + m_ThresMax = new QGoAlgoParameter("Thres.Max.", true, 0, 999, 30); + this->m_AlgoWidget->AddParameter(m_ThresMax); + + m_CorrThres = new QGoAlgoParameter("Corr.Thres.", true, 0, 99.99, 2, 0.5); + this->m_AlgoWidget->AddParameter(m_CorrThres); + + m_Alpha = new QGoAlgoParameter("Alpha", true, 0, 99.99, 2, 1.5); + this->m_AlgoWidget->AddParameter(m_Alpha); + + m_Beta = new QGoAlgoParameter("Beta", true, 0, 99.99, 2, 3); + this->m_AlgoWidget->AddParameter(m_Beta); + + QGoSemiAutoSegmentationAlgo::SetAlgoWidget(); } //------------------------------------------------------------------------- -//------------------------------------------------------------------------- \ No newline at end of file +//------------------------------------------------------------------------- + diff --git a/Code/GUI/lib/QGoFilterWatershed.h b/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.h similarity index 65% rename from Code/GUI/lib/QGoFilterWatershed.h rename to Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.h index 2c889584..5e78f71a 100644 --- a/Code/GUI/lib/QGoFilterWatershed.h +++ b/Code/GUI/lib/TraceEditing/QGoWaterShedAlgo.h @@ -31,55 +31,47 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#ifndef __QGoFilterWatershed_h -#define __QGoFilterWatershed_h - -#include "QGoFilterSemiAutoBase.h" +#ifndef __QGoWaterShedAlgo_h +#define __QGoWaterShedAlgo_h +#include "QGoSemiAutoSegmentationAlgo.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" #include "QGoGUILibConfigure.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" -/** - * \class QGoFilterWatershed - * \brief Watershed segmentation algorithm implementation. - * Can generate contours and meshes. - * Will generate 2D objects if m_Dimension<2, 3D objects in the other case. - */ +#include "GoImageProcessor.h" -class QGOGUILIB_EXPORT QGoFilterWatershed:public QGoFilterSemiAutoBase + +/** +\class QGoWaterShedAlgo +\brief class to be the interface between the watershed algo for meshes +and GoFigure +*/ +class QGoWaterShedAlgo: public QGoSemiAutoSegmentationAlgo { - Q_OBJECT public: - /** \brief Constructor */ - explicit QGoFilterWatershed(QObject *iParent = NULL, int iDimension = 2); - - /** \brief Destructor */ - ~QGoFilterWatershed(); - - virtual vtkPolyData * Apply(); - - virtual void ConnectSignals(int iFilterNumber); + QGoWaterShedAlgo(std::vector< vtkPoints* >* iSeeds, QWidget* iParent = 0); + ~QGoWaterShedAlgo(); - int m_TreshMin; - int m_TreshMax; + virtual std::vector ApplyAlgo( + GoImageProcessor* iImages, + std::string iChannel, + bool iIsInvertedOn = false) = 0; - double m_CorrTresh; - double m_Alpha; - double m_Beta; - -public slots: - void setTreshMin(int); - - void setTreshMax(int); - - void setCorrTresh(double); - - void setAlpha(double); +protected: - void setBeta(double); + QGoAlgoParameter* m_ThresMin; + QGoAlgoParameter* m_ThresMax; + QGoAlgoParameter* m_CorrThres; + QGoAlgoParameter* m_Alpha; + QGoAlgoParameter* m_Beta; -protected: - void Filter2D(double *iCenter, const int & iOrientation); + virtual void SetAlgoWidget(QWidget* iParent = 0); - void Filter3D(double *iCenter); + void DeleteParameters(); }; + #endif diff --git a/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx new file mode 100644 index 00000000..146489ac --- /dev/null +++ b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.cxx @@ -0,0 +1,561 @@ +#include "GoTransferFunctionEditorWidget.h" + +// Gofigure +#include "GoTransferFunctionWidget.h" +#include "QGoLUTDialog.h" + +//qt +#include "hoverpoints.h" + +//vtk +#include "vtkLookupTable.h" +#include "vtkImageAccumulate.h" +#include "vtkImageData.h" +#include "vtkPointData.h" +#include "vtkPiecewiseFunction.h" + +// temp +#include + +//------------------------------------------------------------------------- + +GoTransferFunctionEditorWidget::GoTransferFunctionEditorWidget(QWidget *parent, + QString iChannel) + : QWidget(parent ) +{ + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setSpacing(1); + vbox->setMargin(1); + + m_red_shade = new GoTransferFunctionWidget( + GoTransferFunctionWidget::RedShade, this); + m_green_shade = new GoTransferFunctionWidget( + GoTransferFunctionWidget::GreenShade, this); + m_blue_shade = new GoTransferFunctionWidget( + GoTransferFunctionWidget::BlueShade, this); + m_alpha_shade = new GoTransferFunctionWidget( + GoTransferFunctionWidget::ARGBShade, this); + + m_LUT = NULL; + + m_Channel = iChannel; + + QPushButton *presetLUTPushButton = new QPushButton("Preset LUT", this); + presetLUTPushButton->setEnabled(false); + + + QHBoxLayout *lutLayout = new QHBoxLayout; + QPushButton *saveLUTPushButton = new QPushButton("Save LUT", this); + QPushButton *loadLUTPushButton = new QPushButton("Load LUT", this); + lutLayout->addWidget(loadLUTPushButton); + lutLayout->addWidget(saveLUTPushButton); + + QPushButton *okPushButton = new QPushButton("OK", this); + QPushButton *resetLUTPushButton = new QPushButton("Reset", this); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(okPushButton); + layout->addWidget(resetLUTPushButton); + + QHBoxLayout *nameLayout = new QHBoxLayout; + QLabel* channelName = new QLabel("Channel:"); + QLabel* channelNameText = new QLabel(iChannel); + nameLayout->addWidget(channelName); + nameLayout->addWidget(channelNameText); + + vbox->addLayout(nameLayout); + vbox->addWidget(m_red_shade); + vbox->addWidget(m_green_shade); + vbox->addWidget(m_blue_shade); + vbox->addWidget(m_alpha_shade); + vbox->addLayout(lutLayout); + vbox->addWidget(presetLUTPushButton); + vbox->addLayout(layout); + + connect(m_red_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated())); + connect(m_green_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated())); + connect(m_blue_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated())); + connect(m_alpha_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated())); + connect(m_alpha_shade, SIGNAL(colorsChanged()), this, SLOT(updateOpacityTF())); + + connect(okPushButton, SIGNAL(released()), this, SLOT(close())); + connect(okPushButton, SIGNAL(released()), this, SLOT(savePoints())); + + connect(resetLUTPushButton, SIGNAL(pressed()), this, SLOT(resetLUT())); + connect(saveLUTPushButton, SIGNAL(pressed()), this, SLOT(saveLUT())); + connect(loadLUTPushButton, SIGNAL(pressed()), this, SLOT(readLUT())); + // useless...? + connect(presetLUTPushButton, SIGNAL(pressed()), this, SLOT(presetLUT())); + + + // enable event filter + this->installEventFilter(this); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +inline static bool x_less_than(const QPointF &p1, const QPointF &p2) +{ + return p1.x() < p2.x(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void GoTransferFunctionEditorWidget::pointsUpdated() +{ + changeAlphaGradients(); + + // update the LUT + if(m_LUT) + { + m_alpha_shade->UpdateLookupTable(m_LUT); + // send signal to update the visualization + emit updateVisualization(); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +static void set_shade_points(const QPolygonF &points, GoTransferFunctionWidget *shade) +{ + shade->hoverPoints()->setPoints(points); + shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft); + shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight); + shade->update(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void GoTransferFunctionEditorWidget::setGradientStops(const QGradientStops &stops) +{ + QPolygonF pts_red, pts_green, pts_blue, pts_alpha; + + qreal h_red = m_red_shade->height(); + qreal h_green = m_green_shade->height(); + qreal h_blue = m_blue_shade->height(); + qreal h_alpha = m_alpha_shade->height(); + + for (int i=0; iwidth(), h_red - qRed(color) * h_red / 255); + pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255); + pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255); + pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255); + } + + set_shade_points(pts_red, m_red_shade); + set_shade_points(pts_green, m_green_shade); + set_shade_points(pts_blue, m_blue_shade); + set_shade_points(pts_alpha, m_alpha_shade); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddPoints( const std::vector< std::map< unsigned int, unsigned int> >& iRGBA) +{ + + + //red + QPolygonF redPoints; + computePointsFromMap(iRGBA[0], redPoints); + m_red_shade->AddPoints(redPoints); + + // green + QPolygonF greenPoints; + computePointsFromMap(iRGBA[1], greenPoints); + m_green_shade->AddPoints(greenPoints); + + // blue + QPolygonF bluePoints; + computePointsFromMap(iRGBA[2], bluePoints); + m_blue_shade->AddPoints(bluePoints); + + // alpha + QPolygonF alphaPoints; + computePointsFromMap(iRGBA[3], alphaPoints); + m_alpha_shade->AddPoints(alphaPoints); + + // update histogram and alpha gradient + pointsUpdated(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +computePointsFromMap(const std::map< unsigned int, unsigned int>& iMap, QPolygonF& iPoints) +{ + // all shades have same width and height + qreal width = m_red_shade->width(); + qreal height = m_red_shade->height(); + + std::map< unsigned int, unsigned int>::const_iterator it0; + std::map< unsigned int, unsigned int>::const_iterator it255; + it0 = iMap.begin(); + it255 = iMap.end(); + + // check x and y + while(it0!=it255) + { + iPoints << QPointF((qreal)(it0->first)*width/255, + height*(1-(qreal)(it0->second)/255)); + ++it0; + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddLookupTable(vtkLookupTable* iLUT) +{ + m_LUT = iLUT; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddOpacityTransferFunction(vtkPiecewiseFunction* iOpacity) +{ + m_OpacityTF = iOpacity; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddHistogram(vtkImageAccumulate* iHistogram) +{ + int x_range = iHistogram->GetOutput()->GetNumberOfPoints(); + vtkDataArray* scalars = iHistogram->GetOutput()->GetPointData()->GetScalars(); + double* range = iHistogram->GetOutput()->GetScalarRange(); + + QVector histo; + + // do we want the background values in the histogram...? + for(int i=0; iGetTuple1(i); + histo.push_back(log(value)/log(range[1])); + } + + m_red_shade->SetHistogram(histo); + m_green_shade->SetHistogram(histo); + m_blue_shade->SetHistogram(histo); + m_alpha_shade->SetHistogram(histo); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddColor(const std::vector& iColor) +{ + m_Color.setRedF(iColor[0]/255); + m_Color.setGreenF(iColor[1]/255); + m_Color.setBlueF(iColor[2]/255); + m_Color.setAlphaF(iColor[3]/255); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +AddName(QString iChannel) +{ + m_Channel = iChannel; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +presetLUT() +{ + vtkLookupTable *lut = QGoLUTDialog::GetLookupTable( this, + tr("Choose one look-up table") ); + if ( lut ) + { + if(m_LUT) + { + m_LUT->DeepCopy(lut); + //m_red_shade->setEnabled(false); + m_red_shade->setDisabled(true); + //m_green_shade->setEnabled(false); + //m_blue_shade->setEnabled(false); + // update alpha color.. + + //m_->UpdateLookupTable(m_LUT); + // send signal to update the visualization + emit updateVisualization(); + } + // free memory since it is not freed in the QGoLUTDialog + lut->Delete(); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +resetLUT() +{ + m_red_shade->Reset(m_Color.redF()); + m_green_shade->Reset(m_Color.greenF()); + m_blue_shade->Reset(m_Color.blueF()); + m_alpha_shade->Reset(m_Color.alphaF()); + + // update gradient and transfer function + pointsUpdated(); + + //update opacity TF + updateOpacityTF(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +savePoints() +{ + std::vector< std::map< unsigned int, unsigned int> > pointsVector; + pointsVector.resize(4); + + // RED ------------------------------ + QPolygonF redPoints = m_red_shade->points(); + computeMapFromPoints(pointsVector[0], redPoints); + + // GREEN ------------------------------ + QPolygonF greenPoints = m_green_shade->points(); + computeMapFromPoints(pointsVector[1], greenPoints); + + // BLUE ------------------------------ + QPolygonF bluePoints = m_blue_shade->points(); + computeMapFromPoints(pointsVector[2], bluePoints); + + // BLUE ------------------------------ + QPolygonF alphaPoints = m_alpha_shade->points(); + computeMapFromPoints(pointsVector[3], alphaPoints); + + emit updatePoints(m_Channel, pointsVector); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +computeMapFromPoints(std::map< unsigned int, unsigned int>& iMap, const QPolygonF& iPoints) +{ + // all shades have same width and height + qreal width = m_red_shade->width(); + qreal height = m_red_shade->height(); + int numberOfPoints = iPoints.size(); + + if(numberOfPoints>255) + { + qDebug() << "Too many points: " << numberOfPoints << " points"; + return; + } + + for(int i=0; itype()) { + + case QEvent::Resize: + { + changeAlphaGradients(); + return true; + } + default: + break; + } + return false; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +changeAlphaGradients() +{ + qreal w = m_alpha_shade->width(); + + QGradientStops stops; + + QPolygonF points; + + points += m_red_shade->points(); + points += m_green_shade->points(); + points += m_blue_shade->points(); + points += m_alpha_shade->points(); + + qSort(points.begin(), points.end(), x_less_than); + + for (int i=0; icolorAt(int(x))) >> 16, + (0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8, + (0x000000ff & m_blue_shade->colorAt(int(x))), + (0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24); + + stops << QGradientStop(x / w, color); + } + + m_alpha_shade->setGradientStops(stops); + + emit gradientStopsChanged(stops); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +saveLUT() +{ + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File")); + //qDebug() << "filename: " << fileName; + QFile file(fileName); + file.open(QIODevice::WriteOnly | QIODevice::Text); + //if (!) + // return 1; + + QTextStream out(&file); + + // format text file - xml style + // RED ------------------------------ + out <<" "; + WriteLUTComponent(m_red_shade, out); + out <<"\n"; + // GREEN ------------------------------ + out <<" "; + WriteLUTComponent(m_green_shade, out); + out <<"\n"; + // BLUE ------------------------------ + out <<" "; + WriteLUTComponent(m_blue_shade, out); + out <<"\n"; + // ALPHA ------------------------------ + out <<" "; + WriteLUTComponent(m_alpha_shade, out); + out <<"\n"; + + file.close(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +WriteLUTComponent(GoTransferFunctionWidget* iTFWidget, QTextStream& iStream) +{ + qreal width = iTFWidget->width(); + qreal height = iTFWidget->height(); + + int numberOfPoints = iTFWidget->points().size(); + + for(int i=0; ipoints().at(i).x())*255/width; + unsigned int y = (1-(iTFWidget->points().at(i).y())/height)*255; + iStream << x << " " << y << " "; + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +readLUT() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Save File")); + //qDebug() << "filename: " << fileName; + QFile file(fileName); + file.open(QIODevice::ReadOnly | QIODevice::Text); + + QTextStream in(&file); + QString firstBalise; + in >> firstBalise; + + ReadLUTComponent(m_red_shade, in, ""); + ReadLUTComponent(m_green_shade, in, ""); + ReadLUTComponent(m_blue_shade, in, ""); + ReadLUTComponent(m_alpha_shade, in, ""); + + file.close(); + + // update histogram and alpha gradient + pointsUpdated(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +ReadLUTComponent(GoTransferFunctionWidget* iTFWidget, QTextStream& iStream, const QString& iBalise) +{ + qreal width = m_red_shade->width(); + qreal height = m_red_shade->height(); + + QString x,y; + + QPolygonF points; + while (1) + { + iStream >> x; + iStream >> y; + if(x!=iBalise) + { + points << QPointF((x.toDouble())*width/255, + height*(1-(y.toDouble()/255))); + } + else + { + iTFWidget->AddPoints(points); + break; + } + + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionEditorWidget:: +updateOpacityTF() +{ + // all shades have same width and height + qreal width = m_red_shade->width(); + qreal height = m_red_shade->height(); + int numberOfPoints = m_alpha_shade->points().size(); + + m_OpacityTF->Initialize(); + + for(int i=0; ipoints().at(i).x())*255/width; + // y 0 to 1 + double y = (1-(m_alpha_shade->points().at(i).y())/height); + m_OpacityTF->AddPoint(x, y); + } + m_OpacityTF->Modified(); +} diff --git a/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.h b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.h new file mode 100644 index 00000000..db14fd54 --- /dev/null +++ b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionEditorWidget.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +/*========================================================================= + Modifications were made by the GoFigure Dev. Team. + while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + =========================================================================*/ +#ifndef __GoTransferFunctionEditorWidget_h +#define __GoTransferFunctionEditorWidget_h + +#include "QGoGUILibConfigure.h" + +#include + +class HoverPoints; +class GoTransferFunctionWidget; + +//vtk +class vtkLookupTable; +class vtkImageAccumulate; +class vtkPiecewiseFunction; + +class GoTransferFunctionEditorWidget : public QWidget +{ + Q_OBJECT +public: + GoTransferFunctionEditorWidget(QWidget *parent, QString iChannel); + + void setGradientStops(const QGradientStops &stops); + + void AddPoints( + const std::vector >& iRGBA); + + void AddLookupTable(vtkLookupTable* iLUT); + + void AddHistogram(vtkImageAccumulate* iHistogram); + + void AddColor(const std::vector& iColor); + + void AddName(QString iChannel); + + void AddOpacityTransferFunction(vtkPiecewiseFunction* iOpacity); + +public slots: + void pointsUpdated(); + + // LUT + void presetLUT(); + void resetLUT(); + void saveLUT(); + void readLUT(); + void savePoints(); + + // opacity TF + void updateOpacityTF(); + +signals: + void gradientStopsChanged(const QGradientStops &stops); + + void updateVisualization(); + void updatePoints(QString, + std::vector< std::map< unsigned int, unsigned int> >); + +private: + + bool eventFilter(QObject *object, QEvent *event); + + void changeAlphaGradients(); + + void computeMapFromPoints( + std::map< unsigned int, unsigned int>& iMap, const QPolygonF& iPoints); + void computePointsFromMap( + const std::map< unsigned int, unsigned int>& iMap, QPolygonF& iPoints); + + void WriteLUTComponent(GoTransferFunctionWidget* iTFWidget, + QTextStream& iStream); + void ReadLUTComponent(GoTransferFunctionWidget* iTFWidget, + QTextStream& iStream, + const QString& iBalise); + + GoTransferFunctionWidget *m_red_shade; + GoTransferFunctionWidget *m_green_shade; + GoTransferFunctionWidget *m_blue_shade; + GoTransferFunctionWidget *m_alpha_shade; + + QColor m_Color; + QString m_Channel; + + vtkLookupTable *m_LUT; + vtkPiecewiseFunction *m_OpacityTF; +}; + +#endif diff --git a/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.cxx b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.cxx new file mode 100644 index 00000000..db6aa239 --- /dev/null +++ b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.cxx @@ -0,0 +1,201 @@ +#include "GoTransferFunctionWidget.h" + +#include "hoverpoints.h" + +//vtk +#include "vtkLookupTable.h" + +//------------------------------------------------------------------------- + +GoTransferFunctionWidget::GoTransferFunctionWidget(ShadeType type, QWidget *parent) + : QWidget(parent), m_shade_type(type), m_alpha_gradient(QLinearGradient(0, 0, 0, 0)) +{ + // Checkers background + if (m_shade_type == ARGBShade) { + QPixmap pm(20, 20); + QPainter pmp(&pm); + pmp.fillRect(0, 0, 10, 10, Qt::lightGray); + pmp.fillRect(10, 10, 10, 10, Qt::lightGray); + pmp.fillRect(0, 10, 10, 10, Qt::darkGray); + pmp.fillRect(10, 0, 10, 10, Qt::darkGray); + pmp.end(); + QPalette pal = palette(); + pal.setBrush(backgroundRole(), QBrush(pm)); + setAutoFillBackground(true); + setPalette(pal); + + } else { + setAttribute(Qt::WA_NoBackground); + + } + + m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape); + m_hoverPoints->setConnectionType(HoverPoints::LineConnection); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + connect(m_hoverPoints, SIGNAL(pointsChanged(QPolygonF)), this, SIGNAL(colorsChanged())); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +QPolygonF GoTransferFunctionWidget::points() const +{ + return m_hoverPoints->points(); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +uint GoTransferFunctionWidget::colorAt(int x) +{ + generateShade(); + + QPolygonF pts = m_hoverPoints->points(); + for (int i=1; i < pts.size(); ++i) { + if (pts.at(i-1).x() <= x && pts.at(i).x() >= x) { + QLineF l(pts.at(i-1), pts.at(i)); + l.setLength(l.length() * ((x - l.x1()) / l.dx())); + return m_shade.pixel(qRound(qMin(l.x2(), (qreal(m_shade.width() - 1)))), + qRound(qMin(l.y2(), qreal(m_shade.height() - 1)))); + } + } + return 0; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void GoTransferFunctionWidget::setGradientStops(const QGradientStops &stops) +{ + if (m_shade_type == ARGBShade) { + m_alpha_gradient = QLinearGradient(0, 0, width(), 0); + + for (int i=0; i 0) + { + QVector listOfPoints; + qreal x_range = m_Histogram.size(); + + for(int i=0; isetPoints(iPoints); + m_hoverPoints->setPointLock(0, HoverPoints::LockToLeft); + m_hoverPoints->setPointLock(iPoints.size()-1, HoverPoints::LockToRight); + m_hoverPoints->setSortType(HoverPoints::XSort); +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionWidget:: +UpdateLookupTable(vtkLookupTable* iLUT) +{ + for(int i=0; iGetNumberOfTableValues();++i) + { + QColor color(m_shade.pixel(i*(m_shade.width()-1)/iLUT->GetNumberOfTableValues(), 0)); + iLUT->SetTableValue(i, color.redF(), color.greenF(), color.blueF()); + iLUT->Modified(); + } +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionWidget:: +SetHistogram(QVector iHistogram) +{ + m_Histogram = iHistogram; +} +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- +void +GoTransferFunctionWidget:: +Reset(const qreal& iValue) +{ +QPolygonF points; +points << QPointF(0, height()) + << QPointF(width(),(height())*(1-iValue)); +m_hoverPoints->setPoints(points); +m_hoverPoints->setPointLock(0, HoverPoints::LockToLeft); +m_hoverPoints->setPointLock(1, HoverPoints::LockToRight); +m_hoverPoints->setSortType(HoverPoints::XSort); + +update(); +} +//------------------------------------------------------------------------- diff --git a/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.h b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.h new file mode 100644 index 00000000..8769cfe0 --- /dev/null +++ b/Code/GUI/lib/TransferFunctionEditor/GoTransferFunctionWidget.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*========================================================================= + Modifications were made by the GoFigure Dev. Team. + while at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + =========================================================================*/ + +#ifndef __GoTransferFunctionWidget_h +#define __GoTransferFunctionWidget_h + +#include + +class HoverPoints; + +// vtk +class vtkLookupTable; + + +class GoTransferFunctionWidget : public QWidget +{ + Q_OBJECT +public: + enum ShadeType { + RedShade, + GreenShade, + BlueShade, + ARGBShade + }; + + GoTransferFunctionWidget(ShadeType type, QWidget *parent); + + void setGradientStops(const QGradientStops &stops); + + void paintEvent(QPaintEvent *e); + + QSize sizeHint() const { return QSize(150, 40); } + QPolygonF points() const; + + HoverPoints *hoverPoints() const { return m_hoverPoints; } + + uint colorAt(int x); + + void AddPoints(const QPolygonF& iPoints); + + void UpdateLookupTable(vtkLookupTable* iLUT); + + void SetHistogram(QVector iHistogram); + + void Reset(const qreal& iValue); + +signals: + void colorsChanged(); + +private: + void generateShade(); + + ShadeType m_shade_type; + QImage m_shade; + HoverPoints *m_hoverPoints; + QLinearGradient m_alpha_gradient; + + QVector m_Histogram; +}; + +#endif diff --git a/Code/GUI/lib/TransferFunctionEditor/hoverpoints.cpp b/Code/GUI/lib/TransferFunctionEditor/hoverpoints.cpp new file mode 100644 index 00000000..0c7a940b --- /dev/null +++ b/Code/GUI/lib/TransferFunctionEditor/hoverpoints.cpp @@ -0,0 +1,414 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifdef QT_OPENGL_SUPPORT +#include +#endif + +#include "hoverpoints.h" + +#define printf + +HoverPoints::HoverPoints(QWidget *widget, PointShape shape) + : QObject(widget) +{ + m_widget = widget; + widget->installEventFilter(this); + widget->setAttribute(Qt::WA_AcceptTouchEvents); + + m_connectionType = CurveConnection; + m_sortType = NoSort; + m_shape = shape; + m_pointPen = QPen(QColor(255, 255, 255, 191), 1); + m_connectionPen = QPen(QColor(255, 255, 255, 127), 2); + m_pointBrush = QBrush(QColor(191, 191, 191, 127)); + m_pointSize = QSize(11, 11); + m_currentIndex = -1; + m_editable = true; + m_enabled = true; + + connect(this, SIGNAL(pointsChanged(QPolygonF)), + m_widget, SLOT(update())); +} + + +void HoverPoints::setEnabled(bool enabled) +{ + if (m_enabled != enabled) { + m_enabled = enabled; + m_widget->update(); + } +} + + +bool HoverPoints::eventFilter(QObject *object, QEvent *event) +{ + if (object == m_widget && m_enabled) { + switch (event->type()) { + + case QEvent::MouseButtonPress: + { + if (!m_fingerPointMapping.isEmpty()) + return true; + QMouseEvent *me = (QMouseEvent *) event; + + QPointF clickPos = me->pos(); + int index = -1; + for (int i=0; ibutton() == Qt::LeftButton) { + if (index == -1) { + if (!m_editable) + return false; + int pos = 0; + // Insert sort for x or y + if (m_sortType == XSort) { + for (int i=0; i clickPos.x()) { + pos = i; + break; + } + } else if (m_sortType == YSort) { + for (int i=0; i clickPos.y()) { + pos = i; + break; + } + } + + m_points.insert(pos, clickPos); + m_locks.insert(pos, 0); + m_currentIndex = pos; + firePointChange(); + } else { + m_currentIndex = index; + } + return true; + + } else if (me->button() == Qt::RightButton) { + if (index >= 0 && m_editable) { + if (m_locks[index] == 0) { + m_locks.remove(index); + m_points.remove(index); + } + firePointChange(); + return true; + } + } + + } + break; + + case QEvent::MouseButtonRelease: + if (!m_fingerPointMapping.isEmpty()) + return true; + m_currentIndex = -1; + break; + + case QEvent::MouseMove: + if (!m_fingerPointMapping.isEmpty()) + return true; + if (m_currentIndex >= 0) + movePoint(m_currentIndex, ((QMouseEvent *)event)->pos()); + break; + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + { + const QTouchEvent *const touchEvent = static_cast(event); + const QList points = touchEvent->touchPoints(); + const qreal pointSize = qMax(m_pointSize.width(), m_pointSize.height()); + foreach (const QTouchEvent::TouchPoint &touchPoint, points) { + const int id = touchPoint.id(); + switch (touchPoint.state()) { + case Qt::TouchPointPressed: + { + // find the point, move it + QSet activePoints = QSet::fromList(m_fingerPointMapping.values()); + int activePoint = -1; + qreal distance = -1; + const int pointsCount = m_points.size(); + const int activePointCount = activePoints.size(); + if (pointsCount == 2 && activePointCount == 1) { // only two points + activePoint = activePoints.contains(0) ? 1 : 0; + } else { + for (int i=0; i::iterator it = m_fingerPointMapping.find(id); + movePoint(it.value(), touchPoint.pos()); + m_fingerPointMapping.erase(it); + } + break; + case Qt::TouchPointMoved: + { + // move the point + const int pointIdx = m_fingerPointMapping.value(id, -1); + if (pointIdx >= 0) // do we track this point? + movePoint(pointIdx, touchPoint.pos()); + } + break; + default: + break; + } + } + if (m_fingerPointMapping.isEmpty()) { + event->ignore(); + return false; + } else { + return true; + } + } + break; + case QEvent::TouchEnd: + if (m_fingerPointMapping.isEmpty()) { + event->ignore(); + return false; + } + return true; + break; + + case QEvent::Resize: + { + QResizeEvent *e = (QResizeEvent *) event; + if (e->oldSize().width() == 0 || e->oldSize().height() == 0) + break; + qreal stretch_x = e->size().width() / qreal(e->oldSize().width()); + qreal stretch_y = e->size().height() / qreal(e->oldSize().height()); + for (int i=0; i(that_widget); + if (af && af->usesOpenGL()) + af->glWidget()->swapBuffers(); +#endif + return true; + } + default: + break; + } + } + + return false; +} + + +void HoverPoints::paintPoints() +{ + QPainter p; +#ifdef QT_OPENGL_SUPPORT + ArthurFrame *af = qobject_cast(m_widget); + if (af && af->usesOpenGL()) + p.begin(af->glWidget()); + else + p.begin(m_widget); +#else + p.begin(m_widget); +#endif + + p.setRenderHint(QPainter::Antialiasing); + + if (m_connectionPen.style() != Qt::NoPen && m_connectionType != NoConnection) { + p.setPen(m_connectionPen); + + if (m_connectionType == CurveConnection) { + QPainterPath path; + path.moveTo(m_points.at(0)); + for (int i=1; i right || (lock & HoverPoints::LockToRight)) p.setX(right); + + if (p.y() < top || (lock & HoverPoints::LockToTop)) p.setY(top); + else if (p.y() > bottom || (lock & HoverPoints::LockToBottom)) p.setY(bottom); + + return p; +} + +void HoverPoints::setPoints(const QPolygonF &points) +{ + if (points.size() != m_points.size()) + m_fingerPointMapping.clear(); + m_points.clear(); + for (int i=0; i 0) { + m_locks.resize(m_points.size()); + + m_locks.fill(0); + } +} + + +void HoverPoints::movePoint(int index, const QPointF &point, bool emitUpdate) +{ + m_points[index] = bound_point(point, boundingRect(), m_locks.at(index)); + if (emitUpdate) + firePointChange(); +} + + +inline static bool x_less_than(const QPointF &p1, const QPointF &p2) +{ + return p1.x() < p2.x(); +} + + +inline static bool y_less_than(const QPointF &p1, const QPointF &p2) +{ + return p1.y() < p2.y(); +} + +void HoverPoints::firePointChange() +{ +// printf("HoverPoints::firePointChange(), current=%d\n", m_currentIndex); + + if (m_sortType != NoSort) { + + QPointF oldCurrent; + if (m_currentIndex != -1) { + oldCurrent = m_points[m_currentIndex]; + } + + if (m_sortType == XSort) + qSort(m_points.begin(), m_points.end(), x_less_than); + else if (m_sortType == YSort) + qSort(m_points.begin(), m_points.end(), y_less_than); + + // Compensate for changed order... + if (m_currentIndex != -1) { + for (int i=0; i + +QT_FORWARD_DECLARE_CLASS(QBypassWidget) + +class HoverPoints : public QObject +{ + Q_OBJECT +public: + enum PointShape { + CircleShape, + RectangleShape + }; + + enum LockType { + LockToLeft = 0x01, + LockToRight = 0x02, + LockToTop = 0x04, + LockToBottom = 0x08 + }; + + enum SortType { + NoSort, + XSort, + YSort + }; + + enum ConnectionType { + NoConnection, + LineConnection, + CurveConnection + }; + + HoverPoints(QWidget *widget, PointShape shape); + + bool eventFilter(QObject *object, QEvent *event); + + void paintPoints(); + + inline QRectF boundingRect() const; + void setBoundingRect(const QRectF &boundingRect) { m_bounds = boundingRect; } + + QPolygonF points() const { return m_points; } + void setPoints(const QPolygonF &points); + + QSizeF pointSize() const { return m_pointSize; } + void setPointSize(const QSizeF &size) { m_pointSize = size; } + + SortType sortType() const { return m_sortType; } + void setSortType(SortType sortType) { m_sortType = sortType; } + + ConnectionType connectionType() const { return m_connectionType; } + void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; } + + void setConnectionPen(const QPen &pen) { m_connectionPen = pen; } + void setShapePen(const QPen &pen) { m_pointPen = pen; } + void setShapeBrush(const QBrush &brush) { m_pointBrush = brush; } + + void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; } + + void setEditable(bool editable) { m_editable = editable; } + bool editable() const { return m_editable; } + +public slots: + void setEnabled(bool enabled); + void setDisabled(bool disabled) { setEnabled(!disabled); } + +signals: + void pointsChanged(const QPolygonF &points); + +public: + void firePointChange(); + +private: + inline QRectF pointBoundingRect(int i) const; + void movePoint(int i, const QPointF &newPos, bool emitChange = true); + + QWidget *m_widget; + + QPolygonF m_points; + QRectF m_bounds; + PointShape m_shape; + SortType m_sortType; + ConnectionType m_connectionType; + + QVector m_locks; + + QSizeF m_pointSize; + int m_currentIndex; + bool m_editable; + bool m_enabled; + + QHash m_fingerPointMapping; + + QPen m_pointPen; + QBrush m_pointBrush; + QPen m_connectionPen; +}; + + +inline QRectF HoverPoints::pointBoundingRect(int i) const +{ + QPointF p = m_points.at(i); + qreal w = m_pointSize.width(); + qreal h = m_pointSize.height(); + qreal x = p.x() - w / 2; + qreal y = p.y() - h / 2; + return QRectF(x, y, w, h); +} + +inline QRectF HoverPoints::boundingRect() const +{ + if (m_bounds.isEmpty()) + return m_widget->rect(); + else + return m_bounds; +} + +#endif // HOVERPOINTS_H diff --git a/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.cxx b/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.cxx index b7c8c8c2..5979b8a8 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.cxx +++ b/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.cxx @@ -93,7 +93,7 @@ ContourMeshContainer::SetTimePoint(const unsigned int & iT) //------------------------------------------------------------------------- void -ContourMeshContainer::UpdateCurrentElementFromVisu(std::vector< vtkActor * > iActors, +ContourMeshContainer::UpdateCurrentElementFromVisu(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, @@ -265,6 +265,9 @@ ContourMeshContainer::DeleteAllHighlightedElements() while ( it0 != it1 ) { + + std::cout << "TRACE ID TO BE DELETED: " << it0->TraceID << std::endl; + oList.push_back(it0->TraceID); if ( it0->ActorXY ) diff --git a/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.h b/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.h index 31669936..37187fa7 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.h +++ b/Code/GUI/lib/VisualizationTraceContainers/ContourMeshContainer.h @@ -144,7 +144,7 @@ class QGOGUILIB_EXPORT ContourMeshContainer: \param[in] iVisible \see ContourMeshStructure */ - void UpdateCurrentElementFromVisu(std::vector< vtkActor * > iActors, + void UpdateCurrentElementFromVisu(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const unsigned int & iT, const bool & iHighlighted, diff --git a/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.h b/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.h index ff5e5d72..b478ca9f 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.h +++ b/Code/GUI/lib/VisualizationTraceContainers/LineageContainer.h @@ -169,14 +169,14 @@ class LineageContainer: std::list< unsigned int > DeleteAllHighlightedElements(); signals: - void HighlightLineage(unsigned int, bool); + void HighlightLineage(const unsigned int&, const bool&); /* \todo Nicolas-Signal there to avoid warning but has to be connected to the box widget */ void TraceVisibilityChanged(unsigned int, Qt::CheckState); - void ShowLineage(unsigned int, bool); - void DeleteLineage(unsigned int); - /** \brief When one track has been picked (highlighted) from the visualization */ + void ShowLineage(const unsigned int&, const bool&); + void DeleteLineage(unsigned int); +/** \brief When one track has been picked (highlighted) from the visualization */ void TracePicked(unsigned int, Qt::CheckState); void ExportLineages(); diff --git a/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.h b/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.h index a73a5a4c..6d936b2f 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.h +++ b/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.h @@ -80,7 +80,7 @@ template struct change_highlighted template struct change_visible { - change_visible(bool& iVisibile):visible(iVisibile){} + change_visible(const bool& iVisibile):visible(iVisibile){} void operator()(T& iStructure) { @@ -607,7 +607,7 @@ class TraceContainerBase : public QObject /** \brief Set the scalar range */ void SetScalarRangeForAllElements(const double& iMin, const double& iMax ); - void UpdateCurrentElementFromVisuBase( std::vector< vtkActor* > iActors, + void UpdateCurrentElementFromVisuBase( std::vector< vtkActor* >& iActors, vtkPolyData* iNodes, const bool& iHighlighted, const bool& iVisible ); @@ -621,7 +621,7 @@ class TraceContainerBase : public QObject \return false else */ void UpdateElementHighlightingWithTraceID( - unsigned int& oTraceId, + const unsigned int& oTraceId, Qt::CheckState& oState ) { using boost::multi_index::get; @@ -672,8 +672,8 @@ class TraceContainerBase : public QObject } void UpdateElementVisibilityWithTraceID( - unsigned int& oTraceId, - bool iState) + const unsigned int& oTraceId, + const bool& iState) { using boost::multi_index::get; diff --git a/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.txx b/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.txx index 84010138..230517b2 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.txx +++ b/Code/GUI/lib/VisualizationTraceContainers/TraceContainerBase.txx @@ -276,10 +276,9 @@ TraceContainerBase< TContainer >::UpdateElementHighlightingWithGivenTraceID(cons MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); - vtkProperty *temp_property = vtkProperty::New(); - if ( it != m_Container.get< TraceID >().end() ) { + vtkProperty *temp_property = vtkProperty::New(); if ( it->Highlighted ) { temp_property->SetColor(it->rgba[0], @@ -326,8 +325,6 @@ TraceContainerBase< TContainer >::UpdateElementHighlightingWithGivenTraceIDsBase { MultiIndexContainerTraceIDIterator it; - vtkProperty *temp_property = vtkProperty::New(); - QStringList::const_iterator constIterator = iList.begin(); while ( constIterator != iList.end() ) @@ -336,6 +333,8 @@ TraceContainerBase< TContainer >::UpdateElementHighlightingWithGivenTraceIDsBase if ( it != m_Container.get< TraceID >().end() ) { + vtkProperty *temp_property = vtkProperty::New(); + if ( !iCheck ) { temp_property->SetColor(it->rgba[0], @@ -350,16 +349,13 @@ TraceContainerBase< TContainer >::UpdateElementHighlightingWithGivenTraceIDsBase } it->SetActorProperties(temp_property); - temp_property->Delete(); bool highlight = iCheck; m_Container.get< TraceID >(). modify( it , change_highlighted(highlight) ); - } - ++constIterator; } @@ -908,7 +904,7 @@ TraceContainerBase< TContainer >::SetRandomColor(const std::string & iColumnName //------------------------------------------------------------------------- template< class TContainer > void -TraceContainerBase< TContainer >::UpdateCurrentElementFromVisuBase(std::vector< vtkActor * > iActors, +TraceContainerBase< TContainer >::UpdateCurrentElementFromVisuBase(std::vector< vtkActor * >& iActors, vtkPolyData *iNodes, const bool & iHighlighted, const bool & iVisible) diff --git a/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.cxx b/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.cxx index 33cdaf0d..0aadbfb0 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.cxx +++ b/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.cxx @@ -59,7 +59,9 @@ #include //------------------------------------------------------------------------- -TrackContainer::TrackContainer(QObject *iParent, QGoImageView3D *iView) : Superclass(iParent, iView) +TrackContainer:: +TrackContainer(QObject *iParent, QGoImageView3D *iView): + Superclass(iParent, iView) { m_TimeInterval = 0; m_ActiveTrackScalars.append("Original"); @@ -85,7 +87,8 @@ TrackContainer:: //------------------------------------------------------------------------- bool -TrackContainer::DeleteElement(const unsigned int & iId) +TrackContainer:: +DeleteElement(const unsigned int & iId) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iId); @@ -96,7 +99,9 @@ TrackContainer::DeleteElement(const unsigned int & iId) //------------------------------------------------------------------------- //------------------------------------------------------------------------- -bool TrackContainer::DeleteElement(MultiIndexContainerTraceIDIterator iIter) +bool +TrackContainer:: +DeleteElement(MultiIndexContainerTraceIDIterator iIter) { assert ( iIter != m_Container.get< TraceID >().end() ); assert ( this->m_ImageView ); @@ -130,7 +135,8 @@ bool TrackContainer::DeleteElement(MultiIndexContainerTraceIDIterator iIter) //------------------------------------------------------------------------- std::list< unsigned int > -TrackContainer::DeleteAllHighlightedElements() +TrackContainer:: +DeleteAllHighlightedElements() { assert ( this->m_ImageView ); @@ -178,7 +184,8 @@ TrackContainer::DeleteAllHighlightedElements() //------------------------------------------------------------------------- bool -TrackContainer::UpdateTrackStructurePolyData(const TrackStructure & iTrackStructure) +TrackContainer:: +UpdateTrackStructurePolyData(const TrackStructure & iTrackStructure) { if ( iTrackStructure.PointsMap.empty() ) { @@ -250,16 +257,14 @@ TrackContainer::UpdateTrackStructurePolyData(const TrackStructure & iTrackStruct iTrackStructure.Nodes->GetPointData()->SetActiveScalars(NULL); - // update the lineage if necessary - //UpdateTrackStructureLineage(const_cast(&(iTrackStructure))); - return true; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -TrackContainer::ImportTrackInCurrentElement(std::map< unsigned int, double * > iMeshes) +TrackContainer:: +ImportTrackInCurrentElement(std::map& iMeshes) { std::map< unsigned int, double * >::iterator beginMesh = iMeshes.begin(); std::map< unsigned int, double * >::iterator endMesh = iMeshes.end(); @@ -284,7 +289,8 @@ TrackContainer::ImportTrackInCurrentElement(std::map< unsigned int, double * > i //------------------------------------------------------------------------- void -TrackContainer::CreateTrackActors( TrackStructure& iStructure ) +TrackContainer:: +CreateTrackActors(TrackStructure& iStructure) { assert( this->m_ImageView ); @@ -321,7 +327,8 @@ TrackContainer::CreateTrackActors( TrackStructure& iStructure ) //------------------------------------------------------------------------- void -TrackContainer::UpdateTrackActors( TrackStructure& iStructure ) +TrackContainer:: +UpdateTrackActors(TrackStructure& iStructure ) { if(iStructure.Nodes->GetNumberOfPoints() < 2 ) { @@ -337,8 +344,8 @@ TrackContainer::UpdateTrackActors( TrackStructure& iStructure ) //------------------------------------------------------------------------- TrackStructure* TrackContainer:: -UpdatePointsForATrack(unsigned int iTrackID, - std::list< double * > iListCenterBoundingBoxes) +UpdatePointsForATrack(const unsigned int& iTrackID, + std::list< double * >& iListCenterBoundingBoxes) { assert( iTrackID != 0 ); @@ -351,7 +358,8 @@ UpdatePointsForATrack(unsigned int iTrackID, assert ( motherIt != m_Container.get< TraceID >().end() ); /* - * \todo Nicolas- const_cast is OK to modify polydata but better avoid it + * \note Nicolas- const_cast is OK to modify polydata in the container since + we don't sort on it but better avoid it */ TrackStructure* mother = const_cast(&(*motherIt)); RecomputeMap(mother, iListCenterBoundingBoxes); @@ -382,7 +390,8 @@ UpdatePointsForATrack(unsigned int iTrackID, //------------------------------------------------------------------------- void -TrackContainer::RecomputeMap(TrackStructure* iStructure, std::list< double * > iPoints) +TrackContainer:: +RecomputeMap(TrackStructure* iStructure, std::list< double * >& iPoints) { // empty current element map @@ -428,19 +437,22 @@ TrackContainer::RecomputeMap(TrackStructure* iStructure, std::list< double * > i //------------------------------------------------------------------------- void -TrackContainer::UpdateElementHighlightingWithGivenTraceIDs(const QStringList & iList, - const Qt::CheckState & iCheck) +TrackContainer:: +UpdateElementHighlightingWithGivenTraceIDs(const QStringList & iList, + const Qt::CheckState & iCheck) { + Superclass::UpdateElementHighlightingWithGivenTraceIDsBase(iList, - iCheck); + iCheck); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void -TrackContainer::UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iList, - const Qt::CheckState & iCheck) +TrackContainer:: +UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iList, + const Qt::CheckState & iCheck) { Superclass::UpdateElementVisibilityWithGivenTraceIDsBase(iList, iCheck); } @@ -448,7 +460,8 @@ TrackContainer::UpdateElementVisibilityWithGivenTraceIDs(const QStringList & iLi //------------------------------------------------------------------------- void -TrackContainer::ChangeColorCode(const char *iColorCode) +TrackContainer:: +ChangeColorCode(const QString& iColorCode) { m_ActiveTrackScalars.clear(); m_ActiveTrackScalars.append(iColorCode); @@ -481,7 +494,8 @@ TrackContainer::ChangeColorCode(const char *iColorCode) //------------------------------------------------------------------------- void -TrackContainer::ChangeDivisionsColorCode(const char *iColorCode) +TrackContainer:: +ChangeDivisionsColorCode(const QString& iColorCode) { m_ActiveDivisionScalars.clear(); m_ActiveDivisionScalars.append(iColorCode); @@ -492,7 +506,8 @@ TrackContainer::ChangeDivisionsColorCode(const char *iColorCode) double *range = setDivisionNodeScalars(iColorCode); // associated LUT - vtkSmartPointer< vtkLookupTable > LUT = vtkSmartPointer< vtkLookupTable >::New(); + vtkSmartPointer< vtkLookupTable > LUT = + vtkSmartPointer< vtkLookupTable >::New(); LUT->SetTableRange(range); LUT->SetNumberOfTableValues(1024); LUT->SetHueRange(0, 0.7); @@ -516,7 +531,7 @@ TrackContainer::ChangeDivisionsColorCode(const char *iColorCode) //------------------------------------------------------------------------- void TrackContainer:: -SetScalarRangeForAllDivisions(double iMin, double iMax) +SetScalarRangeForAllDivisions(const double& iMin, const double& iMax) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().begin(); @@ -530,16 +545,15 @@ SetScalarRangeForAllDivisions(double iMin, double iMax) ++it; } } - //------------------------------------------------------------------------- //------------------------------------------------------------------------- void TrackContainer:: -SetLookupTableForAllDivisionsColorCoding(vtkLookupTable *iLut) +SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut) { MultiIndexContainerTraceIDIterator - it = m_Container.get< TraceID >().begin(); + it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { @@ -550,7 +564,6 @@ SetLookupTableForAllDivisionsColorCoding(vtkLookupTable *iLut) ++it; } } - //------------------------------------------------------------------------- //------------------------------------------------------------------------- @@ -559,7 +572,7 @@ TrackContainer:: RenderAllDivisionsWithOriginalColors() { MultiIndexContainerTraceIDIterator - it = m_Container.get< TraceID >().begin(); + it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { @@ -575,7 +588,8 @@ RenderAllDivisionsWithOriginalColors() //------------------------------------------------------------------------- double * -TrackContainer::setTrackNodeScalars(const char *iArrayName) +TrackContainer:: +setTrackNodeScalars(const QString& iArrayName) { double *range = new double[2]; @@ -583,22 +597,25 @@ TrackContainer::setTrackNodeScalars(const char *iArrayName) range[1] = std::numeric_limits< double >::min(); MultiIndexContainerTraceIDIterator - it = m_Container.get< TraceID >().begin(); + it = m_Container.get< TraceID >().begin(); while ( it != m_Container.get< TraceID >().end() ) { // does the track have a polydata if ( it->Nodes ) { + // convert qstring to const char* double *realTime = - it->Nodes->GetPointData()->GetArray(iArrayName)->GetRange(); + it->Nodes->GetPointData()->GetArray( + iArrayName.toLocal8Bit().data())->GetRange(); range[0] = std::min(range[0], realTime[0]); range[1] = std::max(range[1], realTime[1]); //set active scalar - it->Nodes->GetPointData()->SetActiveScalars(iArrayName); + // convert qstring to const char* + it->Nodes->GetPointData()->SetActiveScalars( + iArrayName.toLocal8Bit().data()); } - ++it; } @@ -609,7 +626,8 @@ TrackContainer::setTrackNodeScalars(const char *iArrayName) //------------------------------------------------------------------------- double * -TrackContainer::setDivisionNodeScalars(const char *iArrayName) +TrackContainer:: +setDivisionNodeScalars(const QString& iArrayName) { double *range = new double[2]; @@ -624,13 +642,17 @@ TrackContainer::setDivisionNodeScalars(const char *iArrayName) // does the division have a polydata if ( !it->IsLeaf() ) { + // convert qstring to const char* double *realTime = - it->TreeNode.Nodes->GetPointData()->GetArray(iArrayName)->GetRange(); + it->TreeNode.Nodes->GetPointData()->GetArray( + iArrayName.toLocal8Bit().data())->GetRange(); range[0] = std::min(range[0], realTime[0]); range[1] = std::max(range[1], realTime[1]); //set active scalar - it->TreeNode.Nodes->GetPointData()->SetActiveScalars(iArrayName); + // convert qstring to const char* + it->TreeNode.Nodes->GetPointData()->SetActiveScalars( + iArrayName.toLocal8Bit().data()); } ++it; @@ -643,7 +665,8 @@ TrackContainer::setDivisionNodeScalars(const char *iArrayName) //------------------------------------------------------------------------- void -TrackContainer::setTimeInterval(int iTimeInterval) +TrackContainer:: +setTimeInterval(const int& iTimeInterval) { m_TimeInterval = iTimeInterval; } @@ -652,7 +675,8 @@ TrackContainer::setTimeInterval(int iTimeInterval) //------------------------------------------------------------------------- int -TrackContainer::getTimeInterval() +TrackContainer:: +getTimeInterval() { return m_TimeInterval; } @@ -661,7 +685,8 @@ TrackContainer::getTimeInterval() //------------------------------------------------------------------------- void -TrackContainer::UpdateTracksRepresentation(double iRadius, double iRadius2) +TrackContainer:: +UpdateTracksRepresentation(const double& iRadius, const double& iRadius2) { MultiIndexContainerType::iterator it = m_Container.begin(); @@ -671,7 +696,7 @@ TrackContainer::UpdateTracksRepresentation(double iRadius, double iRadius2) bool pointsInPolydata = UpdateTrackStructurePolyData( ( *it ) ); // add glyphs if necessary - if ( ( iRadius || iRadius2 ) && pointsInPolydata ) + if ( ( iRadius > 0 || iRadius2 > 0 ) && pointsInPolydata ) { it->UpdateTracksRepresentation(iRadius, iRadius2); } @@ -680,9 +705,7 @@ TrackContainer::UpdateTracksRepresentation(double iRadius, double iRadius2) // update color since active scalar is set to NULL in // UpdateTrackStructurePolyData - QByteArray bytes = m_ActiveTrackScalars.toAscii(); - const char *ptr = bytes.data(); - ChangeColorCode(ptr); + ChangeColorCode(m_ActiveTrackScalars); assert ( this->m_ImageView ); @@ -693,7 +716,8 @@ TrackContainer::UpdateTracksRepresentation(double iRadius, double iRadius2) //------------------------------------------------------------------------- double* -TrackContainer::GetLastPointOfTheTrack(unsigned int iTrackID) +TrackContainer::GetBorderOfTheTrack( const unsigned int& iTrackID, + const BorderType& iBorder) { MultiIndexContainerTraceIDIterator it = m_Container.get< TraceID >().find(iTrackID); @@ -701,27 +725,15 @@ TrackContainer::GetLastPointOfTheTrack(unsigned int iTrackID) if( it != m_Container.get< TraceID >().end() ) { vtkPoints* points = it->Nodes->GetPoints(); - vtkIdType nbOfPoints = points->GetNumberOfPoints(); - - return points->GetPoint(nbOfPoints-1); - } - - return NULL; -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -double* -TrackContainer::GetFirstPointOfTheTrack(unsigned int iTrackID) -{ - MultiIndexContainerTraceIDIterator - it = m_Container.get< TraceID >().find(iTrackID); - - if( it != m_Container.get< TraceID >().end() ) - { - vtkPoints* points = it->Nodes->GetPoints(); - - return points->GetPoint(0); + if(!iBorder) + { + return points->GetPoint(0); + } + else + { + vtkIdType nbOfPoints = points->GetNumberOfPoints(); + return points->GetPoint(nbOfPoints-1); + } } return NULL; @@ -731,7 +743,7 @@ TrackContainer::GetFirstPointOfTheTrack(unsigned int iTrackID) //------------------------------------------------------------------------- void TrackContainer:: -SetListOfDivisions( std::list iListOfDivisions) +SetListOfDivisions( std::list& iListOfDivisions) { // Create list iterator std::list::iterator it = iListOfDivisions.begin(); @@ -754,11 +766,9 @@ SetListOfDivisions( std::list iListOfDivisions) //------------------------------------------------------------------------- void TrackContainer:: -AddDivision( unsigned int iMotherID, unsigned int iDaughter1ID, - unsigned int iDaughter2ID, bool iVisible) +AddDivision( const unsigned int& iMotherID, const unsigned int& iDaughter1ID, + const unsigned int& iDaughter2ID, const bool& iVisible) { - //todo Update Tracks Collection IDs - // get address of the structures of interest //------------------------------ MultiIndexContainerTraceIDIterator motherIt @@ -782,13 +792,18 @@ AddDivision( unsigned int iMotherID, unsigned int iDaughter1ID, // ->D2 //------------------------------ TrackStructure* mother = const_cast(&(*motherIt)); - mother->TreeNode.m_Child[0] = const_cast(&(*daughter1It)); - mother->TreeNode.m_Child[1] = const_cast(&(*daughter2It)); + mother->TreeNode.m_Child.push_back( + const_cast(&(*daughter1It))); + mother->TreeNode.m_Child.push_back( + const_cast(&(*daughter2It))); // Create Polydata - CreateDivisionPolydata(iMotherID, iDaughter1ID, iDaughter2ID); + CreateDivisionPolydata(iMotherID); // Create Actor + /* + \todo Nicolas - should do it through a modify + */ std::vector< vtkActor * > actors = CreateDivisionActor(mother->TreeNode.Nodes, iVisible); mother->TreeNode.ActorXY = actors[0]; @@ -801,6 +816,9 @@ AddDivision( unsigned int iMotherID, unsigned int iDaughter1ID, // D1->motherID // D2->motherID //------------------------------ + /* + \todo Nicolas - should do it through a modify + */ TrackStructure* d1 = const_cast(&(*daughter1It)); d1->TreeNode.m_Mother = const_cast(&(*motherIt)); @@ -815,7 +833,7 @@ AddDivision( unsigned int iMotherID, unsigned int iDaughter1ID, //------------------------------------------------------------------------- void TrackContainer:: -CreateDivisionPolydata(unsigned int iMother, unsigned int iDaughter1, unsigned int iDaughter2) +CreateDivisionPolydata(const unsigned int& iMother) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iMother); @@ -830,9 +848,11 @@ CreateDivisionPolydata(unsigned int iMother, unsigned int iDaughter1, unsigned i // Get points of interest: // Mother: last point // D1 & D2: first point - double* mother = this->GetLastPointOfTheTrack(iMother); - double* daughter1 = this->GetFirstPointOfTheTrack(iDaughter1); - double* daughter2 = this->GetFirstPointOfTheTrack(iDaughter2); + double* mother = this->GetBorderOfTheTrack(iMother, LAST); + double* daughter1 = this->GetBorderOfTheTrack( + motherIt->TreeNode.m_Child[0]->TraceID, FIRST); + double* daughter2 = this->GetBorderOfTheTrack( + motherIt->TreeNode.m_Child[1]->TraceID, FIRST); //setup points (geometry) vtkSmartPointer points = vtkSmartPointer::New(); @@ -879,10 +899,10 @@ CreateDivisionPolydata(unsigned int iMother, unsigned int iDaughter1, unsigned i //------------------------------------------------------------------------- std::vector TrackContainer:: -CreateDivisionActor(vtkPolyData* iPolyData, bool iVisible) +CreateDivisionActor(vtkPolyData* iPolyData, const bool& iVisible) { /* - * \todo Nicolas: Which color should it be? White as of now + * \todo Nicolas: to be enhanced */ vtkSmartPointer trace_property = vtkSmartPointer::New(); @@ -899,6 +919,9 @@ CreateDivisionActor(vtkPolyData* iPolyData, bool iVisible) std::vector< vtkActor * > divisionActors = this->m_ImageView->AddContour( iPolyData, trace_property ); + /* + \todo Nicolas- clear all that. Should be requiered or should be consistent at least + */ // add it to visu?? if( iVisible ) { @@ -920,76 +943,7 @@ CreateDivisionActor(vtkPolyData* iPolyData, bool iVisible) //------------------------------------------------------------------------- void TrackContainer:: -CutLineage(unsigned int iMotherID) -{ - std::cout << "CutLineage can't work because of temp structures - use modify instead" - << std::endl; - // update connections - //------------------------------ - // motherID->NULL - // ->NULL - //------------------------------ - MultiIndexContainerTraceIDIterator motherIt - = m_Container.get< TraceID >().find(iMotherID); - - if( motherIt != m_Container.get< TraceID >().end() ) - { - // Create temporary structures so we can modify it - TrackStructure tempMother(*motherIt); - - // Get daughters IDs - unsigned int daughter1ID = (*(tempMother.TreeNode.m_Child[0])).TraceID; - unsigned int daughter2ID = (*(tempMother.TreeNode.m_Child[2])).TraceID; - - // Update daughters pointers - tempMother.TreeNode.m_Child[0] = NULL; - tempMother.TreeNode.m_Child[1] = NULL; - tempMother.TreeNode.ReleaseData(); - - // Push current element - m_Container.get< TraceID >().replace(motherIt, tempMother); - - // Find the daughter1 and update mother connection to NULL - //------------------------------ - MultiIndexContainerTraceIDIterator daughter1It - = m_Container.get< TraceID >().find(daughter1ID); - - if( daughter1It != m_Container.get< TraceID >().end() ) - { - // Create temporary structures so we can modify it - TrackStructure tempDaughter1(*daughter1It); - - // Update daughters pointers - tempDaughter1.TreeNode.m_Mother = NULL; - - // Push current element - m_Container.get< TraceID >().replace(daughter1It, tempDaughter1); - } - - // Find the daughter2 and update mother connection to NULL - //------------------------------ - MultiIndexContainerTraceIDIterator daughter2It - = m_Container.get< TraceID >().find(daughter2ID); - - if( daughter2It != m_Container.get< TraceID >().end() ) - { - // Create temporary structures so we can modify it - TrackStructure tempDaughter2(*daughter2It); - - // Update daughters pointers - tempDaughter2.TreeNode.m_Mother = NULL; - - // Push current element - m_Container.get< TraceID >().replace(daughter2It, tempDaughter2); - } - } -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -TrackContainer:: -HighlightCollection(unsigned int iRootTrackID, bool iHilighted) +HighlightCollection(const unsigned int& iRootTrackID, const bool& iHilighted) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); @@ -1006,7 +960,7 @@ HighlightCollection(unsigned int iRootTrackID, bool iHilighted) //------------------------------------------------------------------------- void TrackContainer:: -ShowCollection(unsigned int iRootTrackID, bool iVisible) +ShowCollection(const unsigned int& iRootTrackID, const bool& iVisible) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); @@ -1023,35 +977,28 @@ ShowCollection(unsigned int iRootTrackID, bool iVisible) //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionVisibility( MultiIndexContainerTraceIDIterator& it, bool iVisible) +UpdateCollectionVisibility(MultiIndexContainerTraceIDIterator& it, + const bool& iVisible) { if( !it->IsLeaf() ) { ModifyDivisionVisibility(it, iVisible); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionVisibility(childIt,iVisible); - } - } - - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionVisibility(childIt,iVisible); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1063,8 +1010,6 @@ DeleteCollection(unsigned int iRootTrackID) MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iRootTrackID); - //DeleteADivision; - if( motherIt != m_Container.get< TraceID >().end() ) { UpdateCollectionDelete(motherIt); @@ -1077,36 +1022,22 @@ DeleteCollection(unsigned int iRootTrackID) //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionDelete( MultiIndexContainerTraceIDIterator& it) +UpdateCollectionDelete(MultiIndexContainerTraceIDIterator& it) { - std::cout<< "update delete " << it->TraceID << std::endl; + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[0]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - - std::cout<< "child 1 " << it->TreeNode.m_Child[0]->TraceID << std::endl; - - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionDelete(childIt); - } - } - - if(it->TreeNode.m_Child[1]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); - - std::cout<< "child 2 " << it->TreeNode.m_Child[1]->TraceID << std::endl; + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionDelete(childIt); } + ++itDivision; } if( !it->IsLeaf() ) @@ -1119,42 +1050,37 @@ UpdateCollectionDelete( MultiIndexContainerTraceIDIterator& it) //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionHighlighted( MultiIndexContainerTraceIDIterator& it, bool iHighlighted) +UpdateCollectionHighlighted(MultiIndexContainerTraceIDIterator& it, + const bool& iHighlighted) { if( !it->IsLeaf() ) { ModifyDivisionHighlight(it, iHighlighted); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionHighlighted(childIt,iHighlighted); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionHighlighted(childIt,iHighlighted); } + ++itDivision; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- int -TrackContainer::ModifyDivisionVisibility( MultiIndexContainerTraceIDIterator& it, bool iVisible) +TrackContainer:: +ModifyDivisionVisibility(MultiIndexContainerTraceIDIterator& it, + const bool& iVisible) { m_Container.get< TraceID >().modify( it , change_visible_division(iVisible) ); @@ -1182,14 +1108,13 @@ TrackContainer::ModifyDivisionVisibility( MultiIndexContainerTraceIDIterator& it //------------------------------------------------------------------------- int -TrackContainer::ModifyDivisionHighlight( MultiIndexContainerTraceIDIterator& it, bool iHighlight ) +TrackContainer:: +ModifyDivisionHighlight(MultiIndexContainerTraceIDIterator& it, + const bool& iHighlight ) { vtkProperty* temp_property = vtkProperty::New(); - if ( !iHighlight ) + if (!iHighlight) { - /* - * \todo Nicolas - which color for the divisions?? - */ temp_property->SetColor(it->TreeNode.rgba[0], it->TreeNode.rgba[1], it->TreeNode.rgba[2]); @@ -1201,7 +1126,8 @@ TrackContainer::ModifyDivisionHighlight( MultiIndexContainerTraceIDIterator& it, temp_property->DeepCopy(this->m_HighlightedProperty); } - m_Container.get< TraceID >().modify( it , change_highlighted_division(temp_property, iHighlight) ); + m_Container.get< TraceID >().modify( + it, change_highlighted_division(temp_property, iHighlight)); temp_property->Delete(); @@ -1212,111 +1138,13 @@ TrackContainer::ModifyDivisionHighlight( MultiIndexContainerTraceIDIterator& it, //------------------------------------------------------------------------- void TrackContainer:: -UpdateTrackStructureLineage(TrackStructure* iStructure) -{ - // Modify Mother - if( ! iStructure->IsRoot() ) - { - // What if new tracks overlap now??? - std::cout << "Update mother division polydata/actor" << std::endl; - UpdateDivisionActor( iStructure->TreeNode.m_Mother ); - } - - // Modify Daughters - if( ! iStructure->IsLeaf() ) - { - UpdateDivisionActor( iStructure ); - std::cout << "Update daughter divisions polydata/actor" << std::endl; - } -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -TrackContainer:: -UpdateDivisionActor(TrackStructure* iStructure) -{ - double* mother = this->GetLastPointOfTheTrack(iStructure->TraceID); - double* daughter1 = this->GetFirstPointOfTheTrack(iStructure->TreeNode.m_Child[0]->TraceID); - double* daughter2 = this->GetFirstPointOfTheTrack(iStructure->TreeNode.m_Child[1]->TraceID); - - //setup points (geometry) - vtkSmartPointer points = vtkSmartPointer::New(); - points->InsertNextPoint ( daughter1[0], daughter1[1], daughter1[2] ); - points->InsertNextPoint ( mother[0], mother[1], mother[2] ); - points->InsertNextPoint ( daughter2[0], daughter2[1], daughter2[2] ); - - // create the lines - vtkSmartPointer lines = vtkSmartPointer::New(); - for(int i=0; i<2; ++i) - { - //Create the first line (between Origin and P0) - vtkSmartPointer line = - vtkSmartPointer::New(); - line->GetPointIds()->SetId(0,i); - line->GetPointIds()->SetId(1,i+1); - lines->InsertNextCell(line); - } - - // create polydata - vtkSmartPointer division = vtkSmartPointer::New(); - division->SetPoints(points); - division->SetLines(lines); - /* - * \todo Nicolas: we might want to extend it to more parameters: color, ... - * and to the meshes->efficiency of show/hide, picking, boxwidget, ...! - */ - // add track ID to the polydata so we can get it from the actor later on - vtkSmartPointer trackIDArray = vtkSmartPointer::New(); - trackIDArray->SetNumberOfComponents(1); - trackIDArray->SetNumberOfValues(1); - trackIDArray->SetName("DIVISION"); - trackIDArray->SetValue(0,iStructure->TraceID); - - division->GetFieldData()->AddArray(trackIDArray); - - vtkSmartPointer trace_property = - vtkSmartPointer::New(); - double r = 1.0; - double g = 1.0; - double b = 1.0; - double a = 1.0; - - trace_property->SetColor(r, - g, - b); - trace_property->SetOpacity(a); - - // remove actor from visu and delete them - this->m_ImageView->RemoveActor(0, iStructure->TreeNode.ActorXY); - this->m_ImageView->RemoveActor(1, iStructure->TreeNode.ActorXZ); - this->m_ImageView->RemoveActor(2, iStructure->TreeNode.ActorYZ); - this->m_ImageView->RemoveActor(3, iStructure->TreeNode.ActorXYZ); - iStructure->TreeNode.ReleaseData(); - - // create actors and add it to the visualization - std::vector< vtkActor * > divisionActors = - m_ImageView->AddContour( division, trace_property ); - iStructure->TreeNode.ActorXY = divisionActors[0]; - iStructure->TreeNode.ActorXZ = divisionActors[1]; - iStructure->TreeNode.ActorYZ = divisionActors[2]; - iStructure->TreeNode.ActorXYZ = divisionActors[3]; - - this->m_ImageView->AddActor(3, divisionActors[3]); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -TrackContainer:: -DeleteADivision( unsigned int iMotherID) +DeleteADivision( const unsigned int& iMotherID) { // find iterator MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iMotherID); - if( motherIt != m_Container.get< TraceID >().end() ) + if(motherIt!= m_Container.get< TraceID >().end()) { TrackStructure* mother = const_cast(&(*motherIt)); @@ -1330,12 +1158,14 @@ DeleteADivision( unsigned int iMotherID) // Reset pointers // child (to do first) + /* + \todo Nicolas - do a loop + */ mother->TreeNode.m_Child[0]->TreeNode.m_Mother = NULL; mother->TreeNode.m_Child[1]->TreeNode.m_Mother = NULL; // mother - mother->TreeNode.m_Child[0] = NULL; - mother->TreeNode.m_Child[1] = NULL; + mother->TreeNode.m_Child.resize(0); } } //------------------------------------------------------------------------- @@ -1343,7 +1173,7 @@ DeleteADivision( unsigned int iMotherID) //------------------------------------------------------------------------- std::list TrackContainer:: -GetSubLineage( unsigned int iTrackID ) +GetSubLineage( const unsigned int& iTrackID ) { std::list listOfIDs; @@ -1363,30 +1193,24 @@ GetSubLineage( unsigned int iTrackID ) //------------------------------------------------------------------------- void TrackContainer:: -UpdateSubLineage( MultiIndexContainerTraceIDIterator it, std::list& iList) +UpdateSubLineage(MultiIndexContainerTraceIDIterator it, + std::list& iList) { iList.push_back( it->TraceID ); - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateSubLineage(childIt,iList); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateSubLineage(childIt,iList); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1394,12 +1218,12 @@ UpdateSubLineage( MultiIndexContainerTraceIDIterator it, std::list //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionHighlighting(unsigned int iTraceId) +UpdateCollectionHighlighting(const unsigned int& iTraceId) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTraceId); - if( motherIt != m_Container.get< TraceID >().end() ) + if(motherIt!=m_Container.get().end()) { GetRootIterator( motherIt ); @@ -1433,13 +1257,13 @@ GetRootIterator(MultiIndexContainerTraceIDIterator& iMotherIterator) //------------------------------------------------------------------------- GoFigureLineageAttributes -TrackContainer::UpdateDivisionsForALineage( - unsigned int iTrackIDRoot, double* color) +TrackContainer:: +UpdateDivisionsForALineage(unsigned int iTrackIDRoot, double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackIDRoot); GoFigureLineageAttributes Attributes; - if( motherIt != m_Container.get< TraceID >().end() ) + if(motherIt!=m_Container.get().end()) { UpdateDivisionScalar(motherIt, 0); // 0=depth of the root Attributes = this->GetLineageAttributes(iTrackIDRoot); @@ -1454,7 +1278,7 @@ TrackContainer::UpdateDivisionsForALineage( //------------------------------------------------------------------------- GoFigureLineageAttributes TrackContainer:: -UpdateCollectionScalars( unsigned int iTrackID) +UpdateCollectionScalars(const unsigned int& iTrackID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); @@ -1472,9 +1296,10 @@ UpdateCollectionScalars( unsigned int iTrackID) //------------------------------------------------------------------------- void TrackContainer:: -UpdateDivisionScalar(MultiIndexContainerTraceIDIterator& it, unsigned int iDepth) +UpdateDivisionScalar(MultiIndexContainerTraceIDIterator& it, + const unsigned int& iDepth) { - if( !it->IsLeaf() ) + if(!it->IsLeaf()) { //add array vtkSmartPointer< vtkIntArray > depthArray = @@ -1487,26 +1312,20 @@ UpdateDivisionScalar(MultiIndexContainerTraceIDIterator& it, unsigned int iDepth m_Container.get< TraceID >().modify( it , add_array_division(depthArray) ); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateDivisionScalar(childIt,iDepth+1); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { - UpdateDivisionScalar(childIt,iDepth+1); + unsigned int depth = iDepth+1; + UpdateDivisionScalar(childIt,depth); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1514,12 +1333,12 @@ UpdateDivisionScalar(MultiIndexContainerTraceIDIterator& it, unsigned int iDepth //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionColors( unsigned int iTrackID, double* color) +UpdateCollectionColors(const unsigned int& iTrackID, const double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); - if( motherIt != m_Container.get< TraceID >().end() ) + if(motherIt != m_Container.get< TraceID >().end()) { UpdateDivisionColor(motherIt, color); @@ -1531,34 +1350,28 @@ UpdateCollectionColors( unsigned int iTrackID, double* color) //------------------------------------------------------------------------- void TrackContainer:: -UpdateDivisionColor(MultiIndexContainerTraceIDIterator& it, double* iColor) +UpdateDivisionColor(MultiIndexContainerTraceIDIterator& it, + const double* iColor) { - if( !it->IsLeaf() ) + if(!it->IsLeaf()) { m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) ); m_Container.get< TraceID >().modify( it , change_actor_color_division(iColor) ); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateDivisionColor(childIt,iColor); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionColor(childIt,iColor); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1566,7 +1379,7 @@ UpdateDivisionColor(MultiIndexContainerTraceIDIterator& it, double* iColor) //------------------------------------------------------------------------- void TrackContainer:: -UpdateCollectionColorsData( unsigned int iTrackID, double* color) +UpdateCollectionColorsData(const unsigned int& iTrackID, const double* color) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); @@ -1583,33 +1396,27 @@ UpdateCollectionColorsData( unsigned int iTrackID, double* color) //------------------------------------------------------------------------- void TrackContainer:: -UpdateDivisionColorData(MultiIndexContainerTraceIDIterator& it, double* iColor) +UpdateDivisionColorData(MultiIndexContainerTraceIDIterator& it, + const double* iColor) { - if( !it->IsLeaf() ) + if(!it->IsLeaf()) { m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) ); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateDivisionColorData(childIt,iColor); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionColorData(childIt,iColor); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1617,7 +1424,7 @@ UpdateDivisionColorData(MultiIndexContainerTraceIDIterator& it, double* iColor) //------------------------------------------------------------------------- unsigned int TrackContainer:: -GetCollectionMaxDepth( unsigned int iTrackRootID ) +GetCollectionMaxDepth(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); @@ -1640,7 +1447,8 @@ GetCollectionMaxDepth( unsigned int iTrackRootID ) void TrackContainer:: UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, - unsigned int iDivisionDepth, unsigned int& iLineageDepth) + const unsigned int& iDivisionDepth, + unsigned int& iLineageDepth) { if( it->IsLeaf() ) { @@ -1649,27 +1457,20 @@ UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, iLineageDepth = iDivisionDepth; } } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[0]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { - UpdateCollectionMaxDepth(childIt,iDivisionDepth+1,iLineageDepth); - } - } - - if(it->TreeNode.m_Child[1]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionMaxDepth(childIt,iDivisionDepth+1, iLineageDepth); + unsigned int depth = iDivisionDepth+1; + UpdateCollectionMaxDepth(childIt,depth,iLineageDepth); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1677,7 +1478,7 @@ UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, //------------------------------------------------------------------------- unsigned int TrackContainer:: -GetCollectionMinDepth( unsigned int iTrackRootID ) +GetCollectionMinDepth(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); @@ -1700,7 +1501,8 @@ GetCollectionMinDepth( unsigned int iTrackRootID ) void TrackContainer:: UpdateCollectionMinDepth(MultiIndexContainerTraceIDIterator& it, - unsigned int iDivisionDepth, unsigned int& iLineageDepth) + const unsigned int& iDivisionDepth, + unsigned int& iLineageDepth) { if( it->IsLeaf() ) { @@ -1710,26 +1512,20 @@ UpdateCollectionMinDepth(MultiIndexContainerTraceIDIterator& it, } } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionMinDepth(childIt,iDivisionDepth+1,iLineageDepth); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { - UpdateCollectionMinDepth(childIt,iDivisionDepth+1, iLineageDepth); + unsigned int depth = iDivisionDepth+1; + UpdateCollectionMinDepth(childIt,depth,iLineageDepth); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1737,7 +1533,7 @@ UpdateCollectionMinDepth(MultiIndexContainerTraceIDIterator& it, //------------------------------------------------------------------------- unsigned int TrackContainer:: -GetCollectionNumberOfDivisions( unsigned int iTrackRootID ) +GetCollectionNumberOfDivisions(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); @@ -1760,33 +1556,26 @@ GetCollectionNumberOfDivisions( unsigned int iTrackRootID ) void TrackContainer:: UpdateCollectionNumberOfDivisions(MultiIndexContainerTraceIDIterator& it, - unsigned int& iNumberOfDivisions) + unsigned int& iNumberOfDivisions) { - if( !it->IsLeaf() ) + if(!it->IsLeaf()) { ++iNumberOfDivisions; } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionNumberOfDivisions(childIt,iNumberOfDivisions); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionNumberOfDivisions(childIt,iNumberOfDivisions); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1794,12 +1583,12 @@ UpdateCollectionNumberOfDivisions(MultiIndexContainerTraceIDIterator& it, //------------------------------------------------------------------------- unsigned int TrackContainer:: -GetCollectionNumberOfLeaves( unsigned int iTrackRootID ) +GetCollectionNumberOfLeaves(const unsigned int& iTrackRootID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackRootID); - if( motherIt != m_Container.get< TraceID >().end() ) + if(motherIt != m_Container.get< TraceID >().end()) { unsigned int numberOfLeaves = 1; UpdateCollectionNumberOfDivisions(motherIt,numberOfLeaves); @@ -1814,8 +1603,9 @@ GetCollectionNumberOfLeaves( unsigned int iTrackRootID ) //------------------------------------------------------------------------- //------------------------------------------------------------------------- -GoFigureLineageAttributes TrackContainer::GetLineageAttributes( - unsigned int iTrackRootID) +GoFigureLineageAttributes +TrackContainer:: +GetLineageAttributes(unsigned int iTrackRootID) { //check if possible to iterate on the tree only once GoFigureLineageAttributes LineageAttributes; @@ -1833,33 +1623,26 @@ GoFigureLineageAttributes TrackContainer::GetLineageAttributes( void TrackContainer:: UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator& it, - unsigned int& iNumberOfLeaves) + unsigned int& iNumberOfLeaves) { - if( it->IsLeaf() ) + if(it->IsLeaf()) { ++iNumberOfLeaves; } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateCollectionNumberOfLeaves(childIt,iNumberOfLeaves); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateCollectionNumberOfLeaves(childIt,iNumberOfLeaves); } + ++itDivision; } } //------------------------------------------------------------------------- @@ -1867,7 +1650,7 @@ UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator& it, //------------------------------------------------------------------------- vtkMutableDirectedGraph* TrackContainer:: -ExportLineage(unsigned int iTrackID) +ExportLineage(const unsigned int& iTrackID) { MultiIndexContainerTraceIDIterator motherIt = m_Container.get< TraceID >().find(iTrackID); @@ -1906,8 +1689,9 @@ ExportLineage(unsigned int iTrackID) void TrackContainer:: UpdateLineage(MultiIndexContainerTraceIDIterator& it, - vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree, vtkIdType mother, - unsigned int iDepth, vtkDoubleArray* iDepthArray, vtkDoubleArray* iIDArray) + vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree, + vtkIdType mother, unsigned int iDepth, + vtkDoubleArray* iDepthArray, vtkDoubleArray* iIDArray) { // Update mother ID vtkIdType motherPedigree = iPedrigree; @@ -1922,26 +1706,19 @@ UpdateLineage(MultiIndexContainerTraceIDIterator& it, return; } - if(it->TreeNode.m_Child[0]) + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); + + while(itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); // add edge iPedrigree = iGraph->AddChild(motherPedigree); //go through tree UpdateLineage(childIt,iGraph, iPedrigree, motherPedigree, iDepth+1, iDepthArray,iIDArray); - } - - if(it->TreeNode.m_Child[1]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); - // add edge - iPedrigree = iGraph->AddChild(motherPedigree); - // go through tree - UpdateLineage(childIt,iGraph, iPedrigree, motherPedigree, iDepth+1, iDepthArray, iIDArray); + ++itDivision; } } //------------------------------------------------------------------------- @@ -1950,7 +1727,7 @@ UpdateLineage(MultiIndexContainerTraceIDIterator& it, void TrackContainer:: SetCollectionColorCode(const std::string& iColumnName, - const std::map< unsigned int, std::string >& iValues) + const std::map< unsigned int, std::string >& iValues) { typedef std::map< unsigned int, std::string > MapType; typedef MapType::const_iterator MapConstIterator; @@ -2042,8 +1819,8 @@ SetCollectionColorCode(const std::string& iColumnName, void TrackContainer:: UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator& it, - std::string iColumnName, double& iValue, - double& iMin, double& iMax) + const std::string& iColumnName, const double& iValue, + double& iMin, double& iMax) { if( !it->IsLeaf() ) @@ -2060,26 +1837,19 @@ UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator& it, it->TreeNode.SetScalarData(iColumnName, iValue); } - if(it->TreeNode.m_Child[0]) - { - // find the iterator - MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[0]->TraceID); - if( childIt != m_Container.get< TraceID >().end() ) - { - UpdateDivisionScalarData(childIt, iColumnName, iValue, iMin, iMax); - } - } + std::vector::const_iterator itDivision = + it->TreeNode.m_Child.begin(); - if(it->TreeNode.m_Child[1]) + while( itDivision != it->TreeNode.m_Child.end()) { // find the iterator MultiIndexContainerTraceIDIterator childIt - = m_Container.get< TraceID >().find(it->TreeNode.m_Child[1]->TraceID); + = m_Container.get< TraceID >().find((*itDivision)->TraceID); if( childIt != m_Container.get< TraceID >().end() ) { UpdateDivisionScalarData(childIt, iColumnName, iValue, iMin, iMax); } + ++itDivision; } } //------------------------------------------------------------------------- diff --git a/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.h b/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.h index caa37e25..ee888f65 100644 --- a/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.h +++ b/Code/GUI/lib/VisualizationTraceContainers/TrackContainer.h @@ -71,7 +71,7 @@ //----------------------------------------------------------------------------- struct change_visible_division { - change_visible_division(bool& iVisible):visible(iVisible){} + change_visible_division(const bool& iVisible):visible(iVisible){} void operator()(TrackStructure& iStructure) { @@ -113,7 +113,7 @@ struct change_highlighted_division */ struct change_data_color_division { - change_data_color_division(double* iColor):color(iColor){} + change_data_color_division(const double* iColor):color(iColor){} void operator()(TrackStructure& iStructure) { @@ -121,7 +121,7 @@ struct change_data_color_division } private: - double* color; + const double* color; }; //----------------------------------------------------------------------------- @@ -133,7 +133,7 @@ struct change_data_color_division */ struct change_actor_color_division { - change_actor_color_division(double* iColor):color(iColor){} + change_actor_color_division(const double* iColor):color(iColor){} void operator()(TrackStructure& iStructure) { @@ -141,7 +141,7 @@ struct change_actor_color_division } private: - double* color; + const double* color; }; //----------------------------------------------------------------------------- @@ -245,17 +245,6 @@ class QGOGUILIB_EXPORT TrackContainer: /** \brief Destructor. */ virtual ~TrackContainer(); - /* - \brief Remove all actors (elements) from the scene for a given time point - \param[in] iT - */ - // void RemoveActorsWithGivenTimePoint(const unsigned int & iT); - - /* - \brief Add all actors (elements) from the scene for a given time point - */ - // void AddActorsWithGivenTimePoint(const unsigned int & iT); - //------------------------------------------------------------------------- /** @@ -286,7 +275,7 @@ class QGOGUILIB_EXPORT TrackContainer: \return true if the polydata has been updated \return false if it hasn't (i.e. mesh without point) */ - bool UpdateTrackStructurePolyData( const TrackStructure& iTrackStructure); + bool UpdateTrackStructurePolyData(const TrackStructure& iTrackStructure); /** \brief Update the points strings of the tracks @@ -304,19 +293,19 @@ class QGOGUILIB_EXPORT TrackContainer: \param[in] iTrackList List containing IDs of the track of interest */ template< class TList > - void UpdateTracksStrings( const TList& iTrackList) + void UpdateTracksStrings(const TList& iTrackList) { typename TList::const_iterator it = iTrackList.begin(); unsigned int temp = 0; - while( it != iTrackList.end() ) + while(it!=iTrackList.end()) { - temp = static_cast< unsigned int >( * it ); + temp = static_cast< unsigned int >(*it); // update the current element - UpdateCurrentElementFromExistingOne( temp ); + UpdateCurrentElementFromExistingOne(temp); // emit signal to get the meshes informations - emit NeedMeshesInfoForImportedTrack( temp ); + emit NeedMeshesInfoForImportedTrack(temp); ++it; } @@ -326,19 +315,22 @@ class QGOGUILIB_EXPORT TrackContainer: * \brief Update the current element map then polydata * \param[in] iMeshes meshes to be added in the map */ - void ImportTrackInCurrentElement( std::map< unsigned int, double* > iMeshes); + void ImportTrackInCurrentElement(std::map< unsigned int, double*>& iMeshes); /** * \brief Create new actors for the current polydata and update and visualize * the current actors + * \param[in] iStructure Structure to be updated + * \note input paramter not cont sine it is modified in the method */ - void CreateTrackActors( TrackStructure& iStructure); + void CreateTrackActors(TrackStructure& iStructure); /* * \brief Remove the actors from the visualization if the track has less than 2 points. - * \param[in] iStructure structure to be tested. + * \param[in] iStructure Structure to be updated + * \note input paramter not cont sine it is modified in the method */ - void UpdateTrackActors( TrackStructure& iStructure); + void UpdateTrackActors(TrackStructure& iStructure); /** \brief get the element with iTrackID into the current element, remove it from @@ -347,8 +339,8 @@ class QGOGUILIB_EXPORT TrackContainer: \param[in] iTrackID ID for the track to be updated \param[in] iListCenterBoundingBoxes list of the center of the bounding boxes for the meshes belonging to this track */ - TrackStructure* UpdatePointsForATrack(unsigned int iTrackID, - std::list< double*> iListCenterBoundingBoxes); + TrackStructure* UpdatePointsForATrack(const unsigned int& iTrackID, + std::list< double*>& iListCenterBoundingBoxes); /** \brief Update highlighting property of one element given one actor. @@ -357,11 +349,11 @@ class QGOGUILIB_EXPORT TrackContainer: \return false else \note move to superclass */ - void UpdateElementHighlighting(unsigned int TraceId) + void UpdateElementHighlighting(const unsigned int& TraceId) { Qt::CheckState state; Superclass::UpdateElementHighlightingWithTraceID(TraceId, - state ); + state); emit TracePicked(TraceId, state); } @@ -373,7 +365,7 @@ class QGOGUILIB_EXPORT TrackContainer: * 4-Modify highlight * \param[in] iTraceId ID of the track which owns the picked division */ - void UpdateCollectionHighlighting(unsigned int iTraceId); + void UpdateCollectionHighlighting(const unsigned int& iTraceId); /* * \brief Convenience method to get an iterator to the root structure. @@ -388,10 +380,8 @@ class QGOGUILIB_EXPORT TrackContainer: \return true if the element exists \return false else \note move to superclass*/ - void UpdateElementVisibility(unsigned int iTraceID, bool iState) + void UpdateElementVisibility(const unsigned int& iTraceID, const bool& iState) { - std::cout << "UpdateElementVisibility" << std::endl; - Superclass::UpdateElementVisibilityWithTraceID(iTraceID, iState); if(iState) { @@ -406,14 +396,14 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iId1 ID of the first track * \param[in] iId2 ID of the second track */ - void MergeTrack( const unsigned int& iId1, const unsigned int& iId2 ); + void MergeTrack(const unsigned int& iId1, const unsigned int& iId2); /* * \brief Set time interval between each image. * Useful to estimate the speed of a cell. * \param[in] iTimeInterval time interval between 2 time points */ - void setTimeInterval( int iTimeInterval); + void setTimeInterval(const int& iTimeInterval); /* * \brief Get time interval between each image. @@ -423,20 +413,21 @@ class QGOGUILIB_EXPORT TrackContainer: int getTimeInterval(); /* - * \brief Convenience to get the position of the first point of a track. - * Used to create the divisions actors. - * \param[in] iTrackID track of interest - * \return position of the first point (double* pointing to a double[3]) + * \brief Border type enum to define FIRST and LAST point for a better + * lisibility */ - double* GetFirstPointOfTheTrack(unsigned int iTrackID); + enum BorderType { FIRST = 0, LAST = 1 }; /* - * \brief Convenience to get the position of the last point of a track. + * \brief Convenience to get the position (x,y,z) of a border of a track. + * (first or last point). * Used to create the divisions actors. * \param[in] iTrackID track of interest - * \return position of the last point (double* pointing to a double[3]) + * \param[in] iBorder FIRST or LAST + * \return position of the first point (double* pointing to a double[3]) */ - double* GetLastPointOfTheTrack(unsigned int iTrackID); + double* GetBorderOfTheTrack(const unsigned int& iTrackID, + const BorderType& iBorder); /* * \brief Create divisions from a list of track ids. @@ -444,7 +435,7 @@ class QGOGUILIB_EXPORT TrackContainer: * motherID daughter1ID daughter2ID motherID daughter1ID ... * \param[in] iListOfDivisions list of the track ids to create the divisions */ - void SetListOfDivisions( std::list iListOfDivisions); + void SetListOfDivisions(std::list& iListOfDivisions); /* * \brief Create a division between 3 tracks. @@ -453,9 +444,12 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iMotherID ID of the mother of the division * \param[in] iDaughter1ID ID of the daughter1 of the division * \param[in] iDaughter2ID ID of the daughter2 of the division + * \param[in] iVisible visible = true */ - void AddDivision( unsigned int iMotherID, unsigned int iDaughter1ID, - unsigned int iDaughter2ID, bool iVisible = true); + void AddDivision( const unsigned int& iMotherID, + const unsigned int& iDaughter1ID, + const unsigned int& iDaughter2ID, + const bool& iVisible = true); /* * \brief Create 4 actors (one for each view) @@ -464,38 +458,30 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iVisible visibility of the polydata (defaut = true) * \return vector of 4 actors (1 for each view) representing the division */ - std::vector CreateDivisionActor( vtkPolyData* iPolyData, bool iVisible = true); + std::vector CreateDivisionActor(vtkPolyData* iPolyData, + const bool& iVisible = true); /* * \brief Create Create a division from 3 track IDs. * Updates the node in the structure. * \param[in] iMother ID of the mother - * \param[in] iDaughter1 ID of the daughter1 - * \param[in] iDaughter2 ID of the daughter2 */ - void CreateDivisionPolydata( unsigned int iMother, unsigned int iDaughter1, - unsigned int iDaughter2); - - /* - * \brief Cut the lineage after the given track ID. Modifies mother child pointers to NULL. - * Modifies child mother pointer to NULL; - * \param[in] iMotherID last track of the "mother lineage" - */ - void CutLineage(unsigned int iMotherID); + void CreateDivisionPolydata(const unsigned int& iMother); /* * \brief get the tree below a given division * \param[in] iTrackID division to start the search * \return list containing all the track IDs */ - std::list GetSubLineage( unsigned int iTrackID ); + std::list GetSubLineage(const unsigned int& iTrackID); /* * \brief Convenience method to go through the tree and get a SubLineage * * \param[in] it iterator to go through the lineage * \param[in] iList list of tracks to be returned */ - void UpdateSubLineage( MultiIndexContainerTraceIDIterator it, std::list& iList); + void UpdateSubLineage(MultiIndexContainerTraceIDIterator it, + std::list& iList); /** \brief update the color and the divisions scalars of an all lineage which has @@ -506,14 +492,15 @@ class QGOGUILIB_EXPORT TrackContainer: * \brief Update the lineage's divisions scalars given the track root ID * \param[in] iTrackID track root ID */ - GoFigureLineageAttributes UpdateCollectionScalars( unsigned int iTrackID); + GoFigureLineageAttributes UpdateCollectionScalars(const unsigned int& iTrackID); /* * \brief Update the lineage's divisions scalars given the track root ID * \param[in] iMotherIterator iterator to go through the lineage * \param[in] iDepth depth or the structure referenced by the iterator */ void UpdateDivisionScalar( - MultiIndexContainerTraceIDIterator& iMotherIterator, unsigned int iDepth); + MultiIndexContainerTraceIDIterator& iMotherIterator, + const unsigned int& iDepth); GoFigureLineageAttributes GetLineageAttributes(unsigned int iTrackRootID); @@ -523,15 +510,16 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iTrackID track root ID * \param[in] color color of the divisions */ - void UpdateCollectionColors( unsigned int iTrackID, double* color); + void UpdateCollectionColors(const unsigned int& iTrackID, + const double* color); /* * \brief Update the lineage's divisions color given the track root ID and a color * \param[in] iMotherIterator iterator to go through the lineage * \param[in] color color of the divisions */ void UpdateDivisionColor( - MultiIndexContainerTraceIDIterator& iMotherIterator, double* iColor); - + MultiIndexContainerTraceIDIterator& iMotherIterator, + const double* iColor); /* * \brief Update the lineage's divisions data color given the track root ID and @@ -539,14 +527,16 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iTrackID track root ID * \param[in] color color of the divisions */ - void UpdateCollectionColorsData( unsigned int iTrackID, double* color); + void UpdateCollectionColorsData(const unsigned int& iTrackID, + const double* color); /* * \brief Update the lineage's divisions data color given the track root ID and a color * \param[in] iMotherIterator iterator to go through the lineage * \param[in] color color of the divisions */ void UpdateDivisionColorData( - MultiIndexContainerTraceIDIterator& iMotherIterator, double* iColor); + MultiIndexContainerTraceIDIterator& iMotherIterator, + const double* iColor); // compute statistics on the collection /* @@ -554,54 +544,62 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ - unsigned int GetCollectionMaxDepth( unsigned int iTrackRootID ); + unsigned int GetCollectionMaxDepth(const unsigned int& iTrackRootID); /* * \brief Update the collection max depth * \param[in] it iterator to go through the lineage * \param[in] iDivisionDepth depth of the division * \param[in] iLineageDepth depth of the lineage + * \note iLineageDepth should not be const */ - void UpdateCollectionMaxDepth( MultiIndexContainerTraceIDIterator& it, - unsigned int iDivisionDepth, unsigned int& iLineageDepth); + void UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator& it, + const unsigned int& iDivisionDepth, + unsigned int& iLineageDepth); /* * \brief Get the min depth of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ - unsigned int GetCollectionMinDepth( unsigned int iTrackRootID ); + unsigned int GetCollectionMinDepth(const unsigned int& iTrackRootID ); /* * \brief Update the collection min depth * \param[in] it iterator to go through the lineage * \param[in] iDivisionDepth depth of the division * \param[in] iLineageDepth depth of the lineage + * \note iLineageDepth shouldnt be const */ void UpdateCollectionMinDepth( MultiIndexContainerTraceIDIterator& it, - unsigned int iDivisionDepth, unsigned int& iLineageDepth); + const unsigned int& iDivisionDepth, + unsigned int& iLineageDepth); /* * \brief Get the number of divisions of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ - unsigned int GetCollectionNumberOfDivisions( unsigned int iTrackRootID ); + unsigned int GetCollectionNumberOfDivisions( + const unsigned int& iTrackRootID); /* * \brief Update the collection number of divisions * \param[in] it iterator to go through the lineage * \param[in] iNumberOfDivisions number of divisions of the lineage + * \note iNumberOfDivisions shouldnt be const */ - void UpdateCollectionNumberOfDivisions( MultiIndexContainerTraceIDIterator& it, - unsigned int& iNumberOfDivisions); + void UpdateCollectionNumberOfDivisions( + MultiIndexContainerTraceIDIterator& it, + unsigned int& iNumberOfDivisions); /* * \brief Get the number of leaves of the lineage * \param[in] iTrackRootID id of the track root * \return depth of the lineage */ - unsigned int GetCollectionNumberOfLeaves( unsigned int iTrackRootID ); + unsigned int GetCollectionNumberOfLeaves(const unsigned int& iTrackRootID); /* * \brief Update the collection number of leaves * \param[in] it iterator to go through the lineage * \param[in] iNumberOfLeaves number of leaves of the lineage + * \note iNumberOfLeaves shouldnt be const */ - void UpdateCollectionNumberOfLeaves( MultiIndexContainerTraceIDIterator& it, + void UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator& it, unsigned int& iNumberOfLeaves); /* @@ -609,7 +607,7 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iTrackID track root ID for the lineage export. * \return pointer to vtkMutableDirectedGraph. IMPORTANT: has to be deleted. */ - vtkMutableDirectedGraph* ExportLineage(unsigned int iTrackID); + vtkMutableDirectedGraph* ExportLineage(const unsigned int& iTrackID); /* * \brief Color code lineages from the table widget @@ -617,7 +615,8 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iValues pair track root id/value */ void SetCollectionColorCode(const std::string& iColumnName, - const std::map< unsigned int, std::string >& iValues); + const std::map< unsigned int, + std::string >& iValues); /* * \brief Randomly color code lineages from the table widget @@ -625,7 +624,7 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iValues pair track root id/value */ void SetDivisionRandomColor(const std::string & iColumnName, - const std::map< unsigned int, std::string > & iValues); + const std::map< unsigned int, std::string >& iValues); /* * \brief Update whole tree for table widget color coding @@ -634,23 +633,26 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iValue value of the current lineage * \param[in|out] iMin to adjust the lookup table after modifying polydata scalars * \param[in|out] iMax to adjust the lookup table after modifying polydata scalars + * \note iMin and iMax should not be constant */ void UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator& it, - std::string iColumnName, double& iValue, - double& iMin, double& iMax); + const std::string& iColumnName, + const double& iValue, + double& iMin, + double& iMax); /* * \brief Set the scalar range for all the divisions * \param[in] iMin min scalar * \param[in] iMax max value */ - void SetScalarRangeForAllDivisions(double iMin, double iMax); + void SetScalarRangeForAllDivisions(const double& iMin, const double& iMax); /* * \brief Set the LUT for all the divisions * \param[in] iLut the lookup table */ - void SetLookupTableForAllDivisionsColorCoding(vtkLookupTable *iLut); + void SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut); /* * \brief Render all the divisions of all the lineages with the original @@ -670,10 +672,12 @@ class QGOGUILIB_EXPORT TrackContainer: * \param[in] iIDArray array to be modified to add information to the graph */ void UpdateLineage(MultiIndexContainerTraceIDIterator& it, - vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree, - vtkIdType mother, - unsigned int iDepth, vtkDoubleArray* iDepthArray, - vtkDoubleArray* iIDArray); + vtkMutableDirectedGraph* iGraph, + unsigned int iPedrigree, + vtkIdType mother, + unsigned int iDepth, + vtkDoubleArray* iDepthArray, + vtkDoubleArray* iIDArray); signals: /** \brief When one track has been picked (highlighted) from the visualization */ @@ -697,66 +701,71 @@ public slots: new status. \param[in] iList list of TraceIDs \param[in] iCheck */ - virtual void UpdateElementHighlightingWithGivenTraceIDs( const QStringList& iList, - const Qt::CheckState& iCheck ); + virtual void UpdateElementHighlightingWithGivenTraceIDs( + const QStringList& iList, const Qt::CheckState& iCheck); /** \brief Change elements visibility property given a list of TraceIDs and the new status. \param[in] iList list of TraceIDs \param[in] iCheck */ - virtual void UpdateElementVisibilityWithGivenTraceIDs( const QStringList& iList, - const Qt::CheckState& iCheck ); + virtual void UpdateElementVisibilityWithGivenTraceIDs( + const QStringList& iList, const Qt::CheckState& iCheck); /** \brief Color code the track by an array \param[in] iColorCode name of the active array*/ - void ChangeColorCode( const char* iColorCode); + void ChangeColorCode(const QString& iColorCode); /** \brief Color code the lineage by an array \param[in] iColorCode name of the active array */ - void ChangeDivisionsColorCode( const char* iColorCode ); + void ChangeDivisionsColorCode(const QString& iColorCode); /* * \brief Change the representation of a track, adding glyphs and tubes * param[in] iRadius radius of the glyph * param[in] iRadius2 radius of the tube */ - void UpdateTracksRepresentation( double iRadius,double iRadius2); + void UpdateTracksRepresentation(const double& iRadius, + const double& iRadius2); /* * \brief Highlight a collection given the track root ID * param[in] iRootTrackID trackID root * param[in] iHighlighted true (highlight) or false (real color) */ - void HighlightCollection(unsigned int iRootTrackID, bool iHighlighted); + void HighlightCollection(const unsigned int& iRootTrackID, + const bool& iHighlighted); /* * \brief Update the collection highlight * \param[in] it iterator to go through the lineage * \param[in] iHighlighted highlight (true) or real color (false) */ - void UpdateCollectionHighlighted( MultiIndexContainerTraceIDIterator& it, bool iHighlighted); + void UpdateCollectionHighlighted(MultiIndexContainerTraceIDIterator& it, + const bool& iHighlighted); /* * \brief Change the highlight of the division belonging to the given structure. * Structure is modified through unary function. * \param[in] it iterator to the structure to be modified * \param[in] iHighlight highlight (true) or real color (false) */ - int ModifyDivisionHighlight( MultiIndexContainerTraceIDIterator& it, bool iHighlight ); + int ModifyDivisionHighlight(MultiIndexContainerTraceIDIterator& it, + const bool& iHighlight); /* * \brief Show/hide a collection given the track root ID * param[in] iRootTrackID trackID root * param[in] iVisibility true (show) or false (hide) */ - void ShowCollection(unsigned int, bool); + void ShowCollection(const unsigned int&, const bool&); /* * \brief Update the collection visibility * \param[in] it iterator to go through the lineage * \param[in] iVisibility show (true) or hide (false) */ - void UpdateCollectionVisibility( MultiIndexContainerTraceIDIterator& it, bool iVisibility); + void UpdateCollectionVisibility(MultiIndexContainerTraceIDIterator& it, + const bool& iVisibility); /* * \brief Delete a collection given the track root ID * param[in] iRootTrackID trackID root @@ -773,43 +782,37 @@ public slots: * \param[in] it iterator to the structure to be modified * \param[in] iVisibility show (true) or hide (false) */ - int ModifyDivisionVisibility( MultiIndexContainerTraceIDIterator& it, bool iVisibility ); - - /* - * \note Not useful since we don't allow add point to a track if we want to add a point to a border... - */ - void UpdateTrackStructureLineage(TrackStructure* iStructure); - /* - * \note Not useful since we don't allow add point to a track if we want to add a point to a border... - */ - void UpdateDivisionActor(TrackStructure* iStructure); - + int ModifyDivisionVisibility(MultiIndexContainerTraceIDIterator& it, + const bool& iVisibility ); /* * \brief Delete the division belonging to the given track * \param[in] iMotherID ID of the track which owns the division */ - void DeleteADivision( unsigned int iMotherID); + void DeleteADivision(const unsigned int& iMotherID); protected: + /* + \todo Nicolas why protected?? + */ /** \brief Recompute a polydata from a list of point (coordinates) for the current element. If the current element is a new track, then the polydata, actors are allocated and added in consequence. \param[in] iPoints list of points to generate the new polydata */ - void RecomputeMap( TrackStructure* iStructure, std::list< double* > iPoints); + void RecomputeMap( TrackStructure* iStructure, std::list< double* >& iPoints); /** \brief Changes the scalars to be displayed and return the new range * \param[in] iArrayName Array to be displayed * \return Pointer to double[2] where [0] is the min scalar value and [1] is * the max scalar value. Pointer has to be deleted (delete[] pointer) */ - double* setTrackNodeScalars(const char *iArrayName); + double* setTrackNodeScalars(const QString& iArrayName); /** \brief Changes the divisions scalars to be displayed and return the new range * \param[in] iArrayName Array to be displayed * \return Pointer to double[2] where [0] is the min scalar value and [1] is * the max scalar value. Pointer has to be deleted (delete[] pointer) */ - double* setDivisionNodeScalars(const char *iArrayName); + double* setDivisionNodeScalars(const QString& iArrayName); void ComputeSpeed(); diff --git a/Code/IO/CMakeLists.txt b/Code/IO/CMakeLists.txt index de0433c7..24d664aa 100644 --- a/Code/IO/CMakeLists.txt +++ b/Code/IO/CMakeLists.txt @@ -47,13 +47,20 @@ SET( QGOIO_SRC GoDBTWContainerForLineage.cxx GoDBExport.cxx GoDBImport.cxx + + # Mega related files + GoImage/GoImageProcessor.cxx + GoImage/GoMegaImageProcessor.cxx + GoImage/GoLSMImageProcessor.cxx + itkMegaCaptureImport.cxx + itkMegaCaptureReader.cxx MegaCaptureHeaderReader.cxx + QueryDataBaseHelper.cxx SelectQueryDatabaseHelper.cxx QueryBuilderHelper.cxx # itkLsm3DSerieImport.cxx - itkMegaCaptureImport.cxx - itkMegaCaptureReader.cxx + GoFigureFileInfoMultiIndexContainerHelper.cxx vtkPolyDataMySQLContourReader.cxx vtkPolyDataMySQLMeshReader.cxx @@ -87,8 +94,7 @@ TARGET_LINK_LIBRARIES( QGoIO vtkIO vtkImaging vtkLSMReader - ITKCommon - ITKIO + ${ITK_LIBRARIES} ) SET_TARGET_PROPERTIES( QGoIO PROPERTIES VERSION ${GOFIGURE2_LIB_VERSION} SOVERSION ${GOFIGURE2_LIB_VERSION} ) diff --git a/Code/IO/GoDBCollectionOfTraces.cxx b/Code/IO/GoDBCollectionOfTraces.cxx index 2523eb32..c12ee1a1 100644 --- a/Code/IO/GoDBCollectionOfTraces.cxx +++ b/Code/IO/GoDBCollectionOfTraces.cxx @@ -1060,7 +1060,7 @@ int GoDBCollectionOfTraces::GetTraceIDWithLowestTimePoint( true); } - //------------------------------------------------------------------------- +//------------------------------------------------------------------------- //------------------------------------------------------------------------- std::list GoDBCollectionOfTraces::GetTrackFamiliesForLineages( @@ -1072,4 +1072,20 @@ int GoDBCollectionOfTraces::GetTraceIDWithLowestTimePoint( return GetAllSelectedValuesFromTwoTables( iDatabaseConnector, "track", "trackfamily", "trackfamily.trackfamilyID", JoinCondition, "track.lineageid", VectorLineages ); - } \ No newline at end of file + } +//------------------------------------------------------------------------- + +//------------------------------------------------------------------------- + std::list GoDBCollectionOfTraces::GetTrackFamilyID( + vtkMySQLDatabase *iDatabaseConnector, std::list iListTrackIDs) + { + FieldWithValue JoinCondition = { "trackID", "trackIDMother", "=" }; + std::vector VectTrackIDs = ListUnsgIntToVectorString(iListTrackIDs); + std::list oList = GetTwoFieldsFromTwoTables(iDatabaseConnector, + this->m_TracesName, "trackfamily", JoinCondition, "track.trackfamilyID", + "trackfamily.trackfamilyID", this->m_TracesIDName, VectTrackIDs, true); + return oList; + } + //------------------------------------------------------------------------- + +//------------------------------------------------------------------------- diff --git a/Code/IO/GoDBCollectionOfTraces.h b/Code/IO/GoDBCollectionOfTraces.h index 786e0039..74bbe91f 100644 --- a/Code/IO/GoDBCollectionOfTraces.h +++ b/Code/IO/GoDBCollectionOfTraces.h @@ -486,6 +486,13 @@ class QGOIO_EXPORT GoDBCollectionOfTraces std::list GetTrackFamiliesForLineages( vtkMySQLDatabase *iDatabaseConnector, std::list iLineagesID); + /** + \brief return the trackFamilyIDs the track belongs to (as a mother or as + a daughter) + */ + std::list GetTrackFamilyID(vtkMySQLDatabase *iDatabaseConnector, + std::list iListTrackIDs); + protected: std::string m_CollectionName; diff --git a/Code/IO/GoImage/GoImageProcessor.cxx b/Code/IO/GoImage/GoImageProcessor.cxx new file mode 100644 index 00000000..bd7456a1 --- /dev/null +++ b/Code/IO/GoImage/GoImageProcessor.cxx @@ -0,0 +1,576 @@ + +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "GoImageProcessor.h" + +// external library include +#include "vtkLookupTable.h" +#include "vtkMath.h" +#include "vtkImageMapToColors.h" +#include "vtkImageBlend.h" +#include "vtkPointData.h" +#include "vtkImageShiftScale.h" +//histogram +#include "vtkImageExtractComponents.h" +#include "vtkImageAccumulate.h" + +#include "vtkPiecewiseFunction.h" + +#include + +// temp +#include "vtkImageWeightedSum.h" + +//-------------------------------------------------------------------------- +GoImageProcessor::GoImageProcessor():m_Output(NULL), + m_DopplerMode(false), m_DopplerStep(1), m_DopplerChannel(0), m_DopplerSize(3) +{ + m_BoundsTime[0] = 0; + m_BoundsTime[1] = 0; + + m_BoundsChannel[0] = 0; + m_BoundsChannel[1] = 0; + + m_Extent[0] = 0; + m_Extent[1] = 0; + m_Extent[2] = 0; + m_Extent[3] = 0; + m_Extent[4] = 0; + m_Extent[5] = 0; + + m_DopplerTime.resize(m_DopplerSize); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +GoImageProcessor::GoImageProcessor(const GoImageProcessor & iE): + m_MegaImageContainer(iE.m_MegaImageContainer), m_Output(iE.m_Output), + m_DopplerMode(iE.m_DopplerMode), m_DopplerStep(iE.m_DopplerStep), + m_DopplerChannel(iE.m_DopplerChannel), m_DopplerSize(iE.m_DopplerSize) +{ + m_BoundsTime[0] = iE.m_BoundsTime[0]; + m_BoundsTime[1] = iE.m_BoundsTime[1]; + + m_BoundsChannel[0] = iE.m_BoundsChannel[0]; + m_BoundsChannel[1] = iE.m_BoundsChannel[1]; + + m_Extent[0] = iE.m_Extent[0]; + m_Extent[1] = iE.m_Extent[1]; + m_Extent[2] = iE.m_Extent[2]; + m_Extent[3] = iE.m_Extent[3]; + m_Extent[4] = iE.m_Extent[4]; + m_Extent[5] = iE.m_Extent[5]; + + m_DopplerTime = iE.m_DopplerTime; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +GoImageProcessor:: +~GoImageProcessor() +{ +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +createLUT(const double& iRed, const double& iGreen, const double& iBlue, + const double& iAlpha, const double* iRange) +{ + vtkSmartPointer lut = vtkSmartPointer::New(); + double* HSV = vtkMath::RGBToHSV(iRed,iGreen,iBlue); + lut->SetAlphaRange(0, 1); + lut->SetHueRange(HSV[0], HSV[0]); + lut->SetSaturationRange(1, 1); + lut->SetValueRange(0, 1); + lut->SetRange(const_cast(iRange)); + lut->Build(); + return lut; +} +//-------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getLookuptable(const std::string& iName) const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + if(it!=m_MegaImageContainer.get< Name >().end()) + { + return it->LUT; + } + + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getLookuptable() const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true); + + assert(it!=m_MegaImageContainer.get< Visibility >().end()); + + return it->LUT; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getOpacityTransferFunction(const std::string& iName) const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + if(it!=m_MegaImageContainer.get< Name >().end()) + { + return it->OpacityTF; + } + + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector +GoImageProcessor:: +getOpacityTransferFunctions() +{ + std::vector opacityTFs; + + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true); + + while(it!=m_MegaImageContainer.get< Visibility >().end()) + { + opacityTFs.push_back(it->OpacityTF); + ++it; + } + + return opacityTFs; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector +GoImageProcessor:: +getColor(const std::string& iName) const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + assert(it!=m_MegaImageContainer.get< Name >().end()); + + return it->Color; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector > +GoImageProcessor:: +getRGBA(const std::string& iName) const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + assert(it!=m_MegaImageContainer.get< Name >().end()); + + return it->RGBA; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getHistogram(const std::string& iName) const +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + assert(it!=m_MegaImageContainer.get< Name >().end()); + + return it->Histogram; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +colorImage(vtkSmartPointer iImage, + vtkSmartPointer iLUT) +{ + vtkSmartPointer coloredImage = + vtkSmartPointer::New(); + coloredImage->SetLookupTable(iLUT); + coloredImage->SetInput( iImage ); + coloredImage->SetOutputFormatToRGB(); + coloredImage->SetNumberOfThreads(VTK_MAX_THREADS); + coloredImage->Update(); + + return coloredImage->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getImageBW(const unsigned int& iIndex) +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Index >().find(iIndex); + if(it!=m_MegaImageContainer.get< Index >().end()) + { + return it->Image; + } + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getImageBW() +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true); + + if(it!=m_MegaImageContainer.get< Visibility >().end()) + { + return it->Image; + } + return NULL; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector +GoImageProcessor:: +getColoredImages() +{ + std::vector images; + + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true); + + while(it!=m_MegaImageContainer.get< Visibility >().end()) + { + // requiered deepcopy.... + vtkImageData* image = vtkImageData::New(); + image->DeepCopy(colorImage(it->Image, it->LUT)); + images.push_back(image); + ++it; + } + + return images; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +vtkSmartPointer +GoImageProcessor:: +getVisibleImages() +{ + vtkSmartPointer blendedImage = + vtkSmartPointer::New(); + blendedImage->RemoveAllInputs(); + blendedImage->SetBlendModeToCompound(); + blendedImage->SetNumberOfThreads(VTK_MAX_THREADS); + + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true); + + vtkIdType i(0); + + std::cout << __FILE__ << " start coloring " << std::endl; + + while(it!=m_MegaImageContainer.get< Visibility >().end()) + { + blendedImage->AddInput(colorImage(it->Image, it->LUT)); + ++i; + ++it; + } + blendedImage->Update(); + + std::cout << __FILE__ << " finish coloring " << std::endl; + + double rangeR[2]; + blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeR, 0); + double rangeG[2]; + blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeG, 1); + double rangeB[2]; + blendedImage->GetOutput()->GetPointData()->GetScalars()->GetRange(rangeB, 2); + + double range = std::max(rangeB[1], std::max(rangeR[1], rangeG[1])); + + vtkSmartPointer scale = + vtkSmartPointer::New(); + scale->SetInput(blendedImage->GetOutput()); + scale->SetScale(255/range); + scale->SetOutputScalarTypeToUnsignedChar(); + scale->SetNumberOfThreads(VTK_MAX_THREADS); + scale->Update(); + + std::cout << __FILE__ << " finish rescaling" << std::endl; + + return scale->GetOutput(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int* +GoImageProcessor:: +getBoundsTime() +{ + return m_BoundsTime; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int* +GoImageProcessor:: +getBoundsChannel() +{ + return m_BoundsChannel; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +int* +GoImageProcessor:: +getExtent() +{ + return m_Extent; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getNumberOfTimePoints() +{ + return m_BoundsTime[1] - m_BoundsTime[0] + 1; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getNumberOfChannels() +{ + return m_BoundsChannel[1] - m_BoundsChannel[0] + 1; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getTimeInterval() const +{ + return m_TimeInterval; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getDopplerStep() +{ + return m_DopplerStep; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoImageProcessor:: +setDopplerStep(unsigned int iStep) +{ + m_DopplerStep = iStep; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::vector +GoImageProcessor:: +getDopplerTime(unsigned int iTime) +{ + // get min t point + int time = iTime - (m_DopplerSize/2)*m_DopplerStep; + + for(unsigned int i=0; i(m_BoundsTime[0])) + { + m_DopplerTime[i] = -1; + } + if (m_DopplerTime[i] > static_cast(m_BoundsTime[1])) + { + m_DopplerTime[i] = -1; + } + } +/* + m_DopplerTime[0] = iTime - m_DopplerStep; + m_DopplerTime[1] = iTime; + m_DopplerTime[2]= iTime + m_DopplerStep; + +*/ + + return m_DopplerTime; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoImageProcessor:: +setDopplerMode(const bool& iEnable, const unsigned int& iChannel) +{ + m_DopplerMode = iEnable; + m_DopplerChannel = iChannel; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +bool +GoImageProcessor:: +getDopplerMode() +{ + return m_DopplerMode; +} +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getDopplerChannel() +{ + return m_DopplerChannel; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getDopplerSize() +{ + return m_DopplerSize; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoImageProcessor:: +setDopplerSize(int iSize) +{ + m_DopplerSize = iSize; + m_DopplerTime.resize(iSize); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +std::string +GoImageProcessor:: +getChannelName(const unsigned int& iIndex) +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Index >().find(iIndex); + + if(it!=m_MegaImageContainer.get< Index >().end()) + { + return it->Name; + } + return ""; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoImageProcessor:: +visibilityChanged(std::string iName, bool iVisibility) +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + if(it!=m_MegaImageContainer.get< Name >().end()) + { + m_MegaImageContainer.get< Name >().modify( it , set_visibility(iVisibility)); + } +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +unsigned int +GoImageProcessor:: +getNumberOfVisibleChannels() +{ + unsigned int numberOfVisibleChannels(0); + + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Visibility >().find(true) + ; + while(it!=m_MegaImageContainer.get< Visibility >().end()) + { + ++numberOfVisibleChannels; + ++it; + } + + return numberOfVisibleChannels; +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoImageProcessor:: +updatePoints(std::string iName, std::vector< std::map< unsigned int, unsigned int> > iVector) +{ + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iName); + + if(it!=m_MegaImageContainer.get< Name >().end()) + { + m_MegaImageContainer.get< Name >().modify( it , set_PointsRGBA(iVector)); + } +} diff --git a/Code/IO/GoImage/GoImageProcessor.h b/Code/IO/GoImage/GoImageProcessor.h new file mode 100644 index 00000000..f30e98ba --- /dev/null +++ b/Code/IO/GoImage/GoImageProcessor.h @@ -0,0 +1,460 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef GoImageProcessor_H +#define GoImageProcessor_H + +// Required for dynamic libs on Windows (QGoIOExport) +#include "QGoIOConfigure.h" + +// external library include +// VTK +#include "vtkSmartPointer.h" +// ITK +#include "itkInvertIntensityImageFilter.h" +// BOOST +#include +#include +#include +#include + +// include project +#include "GoMegaImageStructure.h" + +// external include +class vtkLookupTable; +class vtkImageData; +class vtkImageAccumulate; + +class QString; + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/** + \struct set_visibility + \brief change visibility of given structure + \sa GoMegaImageStructure + */ +struct set_visibility +{ + set_visibility(bool iVisibility):visibility(iVisibility){} + + void operator()(GoMegaImageStructure& iStructure) + { + iStructure.setVisibility(visibility); + } + +private: + bool visibility; +}; +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/** + \struct set_image + \brief change visibility of given structure + \sa GoMegaImageStructure + */ +struct set_image +{ + set_image(vtkImageData* iImage):image(iImage){} + + void operator()(GoMegaImageStructure& iStructure) + { + iStructure.setImage(image); + } + +private: + vtkImageData* image; +}; +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/** + \struct set_image + \brief change visibility of given structure + \sa GoMegaImageStructure + */ +struct set_PointsRGBA +{ + set_PointsRGBA(std::vector< std::map< unsigned int, unsigned int> > iPoints):points(iPoints){} + + void operator()(GoMegaImageStructure& iStructure) + { + iStructure.setPointsRGBA(points); + } + +private: + std::vector< std::map< unsigned int, unsigned int> > points; +}; +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/* tags for accessing the corresponding indices of GoMegaImageStructure */ + +struct Index{}; +struct Visibility{}; +struct Name{}; + +/* Define a multi_index_container of images with following indices: + * - a non-unique index sorted by GoMegaImageStructure::Index, + * - a non-unique index sorted by GoMegaImageStructure::Visibility, + * - a non-unique index sorted by GoMegaImageStructure::Channel, + */ + +typedef boost::multi_index_container< + GoMegaImageStructure, + boost::multi_index::indexed_by< + boost::multi_index::ordered_non_unique< + boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,unsigned int,Index)>, + boost::multi_index::ordered_non_unique< + boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,bool,Visibility)>, + boost::multi_index::hashed_non_unique< + boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(GoMegaImageStructure,std::string,Name)> > +> GoMegaImageStructureMultiIndexContainer; + +//----------------------------------------------------------------------------- + +/** +\defgroup GoImage GoImage +*/ + +/** + * \struct GoImageProcessor + * \brief Interface between image reader and vtkImageData + * \ingroup GoImage + */ +class QGOIO_EXPORT GoImageProcessor +{ +public: + + /** Constructor */ + GoImageProcessor(); + + /** Constructor */ + GoImageProcessor( const GoImageProcessor& iE ); + + /** Destructor */ + ~GoImageProcessor(); + + /** Printing one element. std::cout << element << std::endl; */ + friend std::ostream & operator<< + (std::ostream & os, const GoImageProcessor & c) + { + //os << "TraceID " << c.TraceID << std::endl; + return os; + } + + // LUT + //--------------------------------------------------------------------------- + + /** + * \brief create a lookuptable (LUT) given r, g, b, a and range + * LUT will go from black to the color. + * \param[in] iRed red value + * \param[in] iGreen green value + * \param[in] iBlue blue value + * \param[in] iAlpha alpha value + * \param[in] iRange scalar range + * \return new LUT + **/ + vtkSmartPointer createLUT(const double& iRed, + const double& iGreen, + const double& iBlue, + const double& iAlpha, + const double* iRange); + + /** + * \brief get LUT from channel name. Useful for the Transfer function editor. + * \param[in] iName channel of interest. + * (See getChannelName(index) to get channel name from index.) + * \return pointer to LUT + **/ + vtkSmartPointer getLookuptable(const std::string& iName) const; + + /** + * \brief get LUT of the first visible channel. Useful is we are in single channel visualization mode. + * \param[in] iName channel of interest. + * (See getChannelName(index) to get channel name from index.) + * \return pointer to LUT + **/ + vtkSmartPointer getLookuptable() const; + + // opacity transfer functions + //--------------------------------------------------------------------------- + /** + * \brief get opacity from channel name. + Useful for the transfer function editor while volume rendering. + * \param[in] iName channel of interest. + * (See getChannelName(index) to get channel name from index.) + * \return pointer to opacity Transfer Function + **/ + vtkSmartPointer + getOpacityTransferFunction(const std::string& iName) const; + + /** + * \brief get vector of visible opacity transfer functions. + Useful for the transfer function editor while volume rendering. + * \return vector of pointer to opacity TF + **/ + std::vector getOpacityTransferFunctions(); + + // colors + //--------------------------------------------------------------------------- + /** + * \brief get color from channel name. + * \param[in] iName channel of interest. + * (See getChannelName(index) to get channel name from index.) + * \return vector of double: rgba [0-255] + **/ + std::vector getColor(const std::string& iName) const; + + /** + * \brief get points to update r, g, b and a TFs in TF editor. + * \param[in] iName channel of interest. + * (See getChannelName(index) to get channel name from index.) + * \return vector of map.1 vector: rgba, map: position/value + **/ + std::vector > getRGBA( + const std::string& iName) const; + + /** + * \brief store points from TF editor + * \param[in] iChannel channel of interest. + * \param[in] iPointsRGBA new points + **/ + void updatePoints(std::string iChannel, + std::vector< std::map< unsigned int, unsigned int> > iPointsRGBA); + + /** + * \brief get histogram from 1 channel image + * \param[in] iChannel channel of interest. + * \return pointer to histogram + **/ + vtkSmartPointer< vtkImageAccumulate> + getHistogram(const std::string& iName) const; + + /** + * \brief load all the channels for the given time point into the + * GoMegaImageStructure + * \param[in] iTime requested time point + **/ + virtual void initTimePoint(const unsigned int& iTime) = 0; + + /** + * \brief update images from the current GoMegaImageStructure + * \param[in] iTime requested time point + **/ + virtual void setTimePoint(const unsigned int& iTime) = 0; + + /** + * \brief load all time points of the given channel into the + * GoMegaImageStructure. Called Doppler View. + * \param[in] iTime requested central time point + * \param[in] iPrevious -to be used for optimization? + * \note need to store parameters if we want to go through volume + * efficiently (not reload everything all the time) + **/ + virtual void setDoppler(const unsigned int& iTime, + const unsigned int& iPrevious) = 0; + + // images + //--------------------------------------------------------------------------- + + /** + * \brief get raw (not colored) image given index + * \param[in] iIndex requested index + * \note Used to compute the mesh attributes at load time + * \return raw image. + **/ + vtkSmartPointer getImageBW(const unsigned int& iIndex); + + /** + * \brief get first raw (not colored) visible image + * \param[in] iIndex requested index + * \return raw image. + **/ + vtkSmartPointer getImageBW(); + + /** + * \brief get name of a channel given its index. + * \param[in] iIndex requested index + * \return channel name + **/ + std::string getChannelName(const unsigned int& iIndex); + + /** + * \brief get all the visible images colored separately (N images). + * \return vector containing all the visible colored images + **/ + std::vector getColoredImages(); + + /** + * \brief get an ITK image (vs vtkImageData) given its index + * \return ITK image pointer + **/ + template< class PixelType, const unsigned int VImageDimension > + typename itk::Image< PixelType, VImageDimension >::Pointer + getImageITK(std::string iIndex, bool iIsInverted = false) + { + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Name >().find(iIndex); + + assert(it!=m_MegaImageContainer.get< Name >().end()); + + if(iIsInverted) + { + //get image and invert it + typedef itk::Image ImageType; + typedef itk::InvertIntensityImageFilter InvertFilterType; + typename InvertFilterType::Pointer invertFilter = InvertFilterType::New(); + invertFilter->SetInput( it->Convert2ITK() ); + invertFilter->Update(); + + typename ImageType::Pointer itkImage = invertFilter->GetOutput(); + itkImage->DisconnectPipeline(); + + return itkImage; + } + else + { + return it->Convert2ITK(); + } + return NULL; + } + + /** + * \brief get all the -visible- images present in the containerl. + * Colors the image and combuine them into 1 image. + * \return 1 colored image. + **/ + vtkSmartPointer getVisibleImages(); + + // Image parameters + //--------------------------------------------------------------------------- + unsigned int* getBoundsTime(); + unsigned int* getBoundsChannel(); + + int* getExtent(); + + unsigned int getNumberOfTimePoints(); + unsigned int getNumberOfChannels(); + + unsigned int getTimeInterval() const; + + // Doppler parameters + //--------------------------------------------------------------------------- + unsigned int getDopplerStep(); + void setDopplerStep(unsigned int iStep); + std::vector getDopplerTime(unsigned int iTime); + void setDopplerMode(const bool& iEnable, const unsigned int& iChannel); + bool getDopplerMode(); + unsigned int getDopplerChannel(); + void setDopplerSize(int iSize); + unsigned int getDopplerSize(); + + /** + * \brief change visibility of one channel given its name. + * \param[in] iName channel of interest + * \param[in] iVisibility new visibility + **/ + void visibilityChanged(std::string iName, bool iVisibility); + + /** + * \brief get number of visible channels + * \return number of visible channels + **/ + unsigned int getNumberOfVisibleChannels(); + +protected: + /* + * \brief Color an image given the original image and a lookuptable (LUT) + * \param[in] iImage image to be colored + * \param[in] iLUT LUT to be applied to the image + * \return colored image + */ + vtkSmartPointer colorImage(vtkSmartPointer iImage, + vtkSmartPointer iLUT); + + GoMegaImageStructureMultiIndexContainer m_MegaImageContainer; + vtkSmartPointer m_Output; + + // Image parameters + //-------------------- + unsigned int m_BoundsTime[2]; + unsigned int m_BoundsChannel[2]; + int m_Extent[6]; + unsigned int m_TimeInterval; + //-------------------- + + // Doppler view parameters + //-------------------- + bool m_DopplerMode; + unsigned int m_DopplerStep; + std::vector m_DopplerTime; + unsigned int m_DopplerChannel; + unsigned int m_DopplerSize; + //-------------------- + +private: + // overload "=" operator + GoImageProcessor& operator=(const GoImageProcessor &rhs) + { + // Only do assignment if RHS is a different object from this. + if (this != &rhs) + { + this->m_MegaImageContainer = rhs.m_MegaImageContainer; + this->m_BoundsTime[0] = rhs.m_BoundsTime[0]; + this->m_BoundsTime[1] = rhs.m_BoundsTime[1]; + this->m_BoundsChannel[0] = rhs.m_BoundsChannel[0]; + this->m_BoundsChannel[1] = rhs.m_BoundsChannel[1]; + this->m_Extent[0] = rhs.m_Extent[0]; + this->m_Extent[1] = rhs.m_Extent[1]; + this->m_Extent[2] = rhs.m_Extent[2]; + this->m_Extent[3] = rhs.m_Extent[3]; + this->m_Extent[4] = rhs.m_Extent[4]; + this->m_Extent[5] = rhs.m_Extent[5]; + this->m_TimeInterval = rhs.m_TimeInterval; + this->m_DopplerMode = rhs.m_DopplerMode; + this->m_DopplerStep = rhs.m_DopplerStep; + this->m_DopplerTime = rhs.m_DopplerTime; + this->m_DopplerChannel = rhs.m_DopplerChannel; + } + return *this; + } + +}; + +#endif // GoImageProcessor_H diff --git a/Code/IO/GoImage/GoLSMImageProcessor.cxx b/Code/IO/GoImage/GoLSMImageProcessor.cxx new file mode 100644 index 00000000..19614448 --- /dev/null +++ b/Code/IO/GoImage/GoLSMImageProcessor.cxx @@ -0,0 +1,247 @@ + +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "GoLSMImageProcessor.h" + +#include "vtkMath.h" + +//-------------------------------------------------------------------------- +void +GoLSMImageProcessor:: +setReader(vtkLSMReader* iReader) +{ + m_LSMReader = iReader; + + // update general parameters + //-------------------- + int numberOfTimePoints = m_LSMReader->GetNumberOfTimePoints(); + m_BoundsTime[0] = 0; + m_BoundsTime[1] = numberOfTimePoints -1; + + int numberOfChannels = m_LSMReader->GetNumberOfChannels(); + m_BoundsChannel[0] = 0; + m_BoundsChannel[1] = numberOfChannels -1; + + (m_LSMReader->GetTimePointOutput(m_BoundsChannel[0], m_BoundsTime[0]))-> + GetExtent(m_Extent); + + m_TimeInterval = m_LSMReader->GetTimeInterval(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoLSMImageProcessor:: +initTimePoint(const unsigned int& iTime) +{ + //check if time point exists + if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + m_MegaImageContainer.clear(); + } + else + { + return; + } + + // update the container + // Get Number of channels from reader + int numberOfChannels = getNumberOfChannels(); + + while(numberOfChannels>0) + { + --numberOfChannels; + + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(m_LSMReader->GetFileName()); + reader->SetUpdateChannel(numberOfChannels); + reader->SetUpdateTimePoint(iTime); + reader->Update(); + + // get image + vtkSmartPointer image = reader->GetOutput(); + + // Get Color + double random1 = reader-> + GetChannelColorComponent(numberOfChannels, 0); + double value1 = random1; + + double random2 = reader-> + GetChannelColorComponent(numberOfChannels, 1); + double value2 = random2; + + double random3 = reader-> + GetChannelColorComponent(numberOfChannels, 2); + double value3 = random3; + + std::vector color; + color.push_back(value1); + color.push_back(value2); + color.push_back(value3); + color.push_back(255); + + // Create LUT + vtkSmartPointer lut = createLUT(color[0], + color[1], + color[2], + color[3], + image->GetScalarRange()); + // create name... + std::stringstream channelName; + channelName << "Channel "; + channelName << numberOfChannels; + + // Update the MegaImageStructure + // image, LUT, channel, time point + m_MegaImageContainer.insert(GoMegaImageStructure(numberOfChannels, + lut, + image, + color, + true, + channelName.str())); + } +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoLSMImageProcessor:: +setTimePoint(const unsigned int& iTime) +{ + //check if time point exists + if(iTime < m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + return; + } + + // update the container + // Get Number of channels from reader + int numberOfChannels = getNumberOfChannels(); + + while(numberOfChannels>0) + { + --numberOfChannels; + + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(m_LSMReader->GetFileName()); + reader->SetUpdateChannel(numberOfChannels); + reader->SetUpdateTimePoint(iTime); + reader->Update(); + + // get image + vtkSmartPointer image = reader->GetOutput(); + + // could iterate on sth else... + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Index >().find(numberOfChannels); + + if(it!=m_MegaImageContainer.get< Index >().end()) + { + m_MegaImageContainer.get< Index >().modify( it , set_image(image) ); + } + } +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoLSMImageProcessor:: +setDoppler(const unsigned int& iTime, const unsigned int& iPrevious) +{ + //to optimize doppler view later on + (void) iPrevious; + + //check if time point exists + if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + } + else + { + return; + } + + std::vector dopplerTime = getDopplerTime(iTime); + + for(unsigned int i=0; i= 0) + { + vtkSmartPointer reader = + vtkSmartPointer::New(); + reader->SetFileName(m_LSMReader->GetFileName()); + reader->SetUpdateChannel(m_DopplerChannel); + reader->SetUpdateTimePoint(dopplerTime[i]); + reader->Update(); + + // get image + vtkSmartPointer image = reader->GetOutput(); + + // hue: 0 to 0.7 + double* rgb = vtkMath::HSVToRGB( + static_cast(i)/static_cast(getDopplerSize()),1,1); + + // color from red to blue + std::vector color; + color.push_back(rgb[0]*255); + color.push_back(rgb[1]*255); + color.push_back(rgb[2]*255); + color.push_back(255); + + // Create LUT + vtkSmartPointer lut = createLUT(color[0], + color[1], + color[2], + color[3], + image->GetScalarRange()); + + // channel name + std::stringstream channelName; + //channelName << "t: "; + channelName << dopplerTime[i]; + + // Update the MegaImageStructure + // image, LUT, channel, time point + m_MegaImageContainer.insert(GoMegaImageStructure(dopplerTime[i], + lut, + image, + color, + true, + channelName.str())); + } + } +} +//-------------------------------------------------------------------------- diff --git a/Code/IO/GoImage/GoLSMImageProcessor.h b/Code/IO/GoImage/GoLSMImageProcessor.h new file mode 100644 index 00000000..2d39d2fd --- /dev/null +++ b/Code/IO/GoImage/GoLSMImageProcessor.h @@ -0,0 +1,74 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef GoLSMImageProcessor_H +#define GoLSMImageProcessor_H + +// Required for dynamic libs on Windows (QGoIOExport) +#include "QGoIOConfigure.h" + +// include project +#include "GoImageProcessor.h" + +// external includes +#include "vtkLSMReader.h" + +/** + * \struct GoLSMImageProcessor + * \brief Specialization of GoImageProcessor to handle LSM files + * \ingroup GoImage + */ +class QGOIO_EXPORT GoLSMImageProcessor:public GoImageProcessor +{ +public: + /** + * \brief Set the reader. + * \param[in] iReader Pointer to the reader + **/ + void setReader(vtkLSMReader* iReader); + + virtual void initTimePoint(const unsigned int& iTime); + + virtual void setTimePoint(const unsigned int& iTime); + + virtual void setDoppler(const unsigned int& iTime, const unsigned int& iPrevious); + +private: + + ~GoLSMImageProcessor(); + + vtkLSMReader *m_LSMReader; +}; + +#endif // GoLSMImageProcessor_H diff --git a/Code/IO/GoImage/GoMegaImageProcessor.cxx b/Code/IO/GoImage/GoMegaImageProcessor.cxx new file mode 100644 index 00000000..8c1bd5f2 --- /dev/null +++ b/Code/IO/GoImage/GoMegaImageProcessor.cxx @@ -0,0 +1,325 @@ + +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "GoMegaImageProcessor.h" + +#include "vtkMath.h" + +//-------------------------------------------------------------------------- +void +GoMegaImageProcessor:: +setReader(itk::MegaCaptureReader::Pointer iReader) +{ + m_MegaImageReader = iReader; + + // update general parameters + //-------------------- + // todo Nicolas- Create a method for that... + m_BoundsTime[0] = m_MegaImageReader->GetMinTimePoint(); + m_BoundsTime[1] = m_MegaImageReader->GetMaxTimePoint(); + m_BoundsChannel[0] = m_MegaImageReader->GetMinChannel(); + m_BoundsChannel[1] = m_MegaImageReader->GetMaxChannel(); + (m_MegaImageReader->GetImage(m_BoundsChannel[0], m_BoundsTime[0]))-> + GetExtent(m_Extent); + + m_TimeInterval = m_MegaImageReader->GetTimeInterval(); +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoMegaImageProcessor:: +initTimePoint(const unsigned int& iTime) +{ + //check if time point exists + if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + m_MegaImageReader->SetTimePoint(iTime); + m_MegaImageReader->Update(); + m_MegaImageContainer.clear(); + } + else + { + return; + } + + // update the container + // Get Number of channels from reader + int numberOfChannels = getNumberOfChannels(); + + while(numberOfChannels>0) + { + --numberOfChannels; + + // Get useful information from the reader + // Nicolas Get Image or get output...? + vtkSmartPointer image = + m_MegaImageReader->GetOutput(numberOfChannels); + + // Get Color + std::vector >channelColor = + m_MegaImageReader->GetChannelColor(); + + + double random1 = channelColor[numberOfChannels][0]; + double value1 = random1; + + double random2 = channelColor[numberOfChannels][1]; + double value2 = random2; + + double random3 = channelColor[numberOfChannels][2]; + double value3 = random3; + + std::vector color; + color.push_back(value1); + color.push_back(value2); + color.push_back(value3); + color.push_back(255); + + // Create LUT + vtkSmartPointer lut = createLUT(color[0], + color[1], + color[2], + color[3], + image->GetScalarRange()); + + // create name... + std::stringstream channelName; + channelName << "Channel "; + channelName << numberOfChannels; + + // Update the MegaImageStructure + // image, LUT, channel, time point + m_MegaImageContainer.insert(GoMegaImageStructure(numberOfChannels, + lut, + image, + color, + true, + channelName.str())); + } +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoMegaImageProcessor:: +setTimePoint(const unsigned int& iTime) +{ + //check if time point exists + if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + m_MegaImageReader->SetTimePoint(iTime); + m_MegaImageReader->Update(); + } + else + { + return; + } + + // update the container + // Get Number of channels from reader + int numberOfChannels = getNumberOfChannels(); + + while(numberOfChannels>0) + { + --numberOfChannels; + + // Get useful information from the reader + // Nicolas Get Image or get output...? + vtkSmartPointer image = + m_MegaImageReader->GetOutput(numberOfChannels); + + GoMegaImageStructureMultiIndexContainer::index::type::iterator it = + m_MegaImageContainer.get< Index >().find(numberOfChannels); + + if(it!=m_MegaImageContainer.get< Index >().end()) + { + m_MegaImageContainer.get< Index >().modify( it , set_image(image) ); + } + } +} +//-------------------------------------------------------------------------- + +//-------------------------------------------------------------------------- +void +GoMegaImageProcessor:: +setDoppler(const unsigned int& iTime, const unsigned int& iPrevious) +{ + //to optimize doppler view later on + (void) iPrevious; + + //check if time point exists + if(iTime >= m_BoundsTime[0] && iTime <= m_BoundsTime[1]) + { + m_MegaImageReader->SetTimePoint(iTime); + m_MegaImageReader->Update(); + m_MegaImageContainer.clear(); + } + else + { + return; + } + + std::vector dopplerTime = getDopplerTime(iTime); + + for(unsigned int i=0; i= 0) + { + // Get useful information from the reader + // Nicolas Get Image or get output...? + vtkSmartPointer image = + m_MegaImageReader->GetImage(m_DopplerChannel,dopplerTime[i]); + + // hue: 0 to 0.7 + double* rgb = vtkMath::HSVToRGB( + static_cast(i)/static_cast(getDopplerSize()),1,1); + + // color from red to blue + std::vector color; + color.push_back(rgb[0]*255); + color.push_back(rgb[1]*255); + color.push_back(rgb[2]*255); + color.push_back(255); + + std::cout << " R: " << color[0] + << " G: " << color[1] + << " G: " << color[2] << std::endl; + + // Create LUT + vtkSmartPointer lut = createLUT(color[0], + color[1], + color[2], + color[3], + image->GetScalarRange()); + + // channel name + std::stringstream channelName; + //channelName << "t: "; + channelName << dopplerTime[i]; + + // Update the MegaImageStructure + // image, LUT, channel, time point + m_MegaImageContainer.insert(GoMegaImageStructure(dopplerTime[i], + lut, + image, + color, + true, + channelName.str())); + + } + } + +/* + vtkSmartPointer< vtkImageAppendComponents > append_filter = + vtkSmartPointer< vtkImageAppendComponents >::New(); + + // if step != 1 and we have previous and next time point loaded + if( m_DopplerStep != 1 || iPreviousT == 0 ) + { + // resize internal image + // clean the vector since is is a vector of smartpointers + m_InternalImages.resize(3, NULL); + + vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); + i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); + m_InternalImages[0] = i0; + append_filter->AddInput(m_InternalImages[0]); + + vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); + i1->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t1) ); + m_InternalImages[1] = i1; + append_filter->AddInput(m_InternalImages[1]); + + vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); + i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); + m_InternalImages[2] = i2; + append_filter->AddInput(m_InternalImages[2]); + } + else + { + // if we go FORWARD and step == 1 + if( iPreviousT < m_TCoord) + { + // assume we imcrease t point all the time for testing + vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); + i0->ShallowCopy(m_InternalImages[1]); + // clean smartpointer + m_InternalImages[0] = NULL; + m_InternalImages[0] = i0; + append_filter->AddInput(m_InternalImages[0]); + + vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); + i1->ShallowCopy(m_InternalImages[2]); + // clean smartpointer + m_InternalImages[1] = NULL; + m_InternalImages[1] = i1; + append_filter->AddInput(m_InternalImages[1]); + + vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); + i2->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t2) ); + // clean smartpointer + m_InternalImages[2] = NULL; + m_InternalImages[2] = i2; + append_filter->AddInput(m_InternalImages[2]); + } + // if we go BACKWARD and step == 1 + else + { + vtkSmartPointer< vtkImageData > i2 = vtkSmartPointer< vtkImageData >::New(); + i2->ShallowCopy(m_InternalImages[1]); + // clean smartpointer + m_InternalImages[2] = NULL; + m_InternalImages[2] = i2; + append_filter->AddInput(m_InternalImages[2]); + + vtkSmartPointer< vtkImageData > i1 = vtkSmartPointer< vtkImageData >::New(); + i1->ShallowCopy(m_InternalImages[0]); + // clean smartpointer + m_InternalImages[1] = NULL; + m_InternalImages[1] = i1; + append_filter->AddInput(m_InternalImages[1]); + + vtkSmartPointer< vtkImageData > i0 = vtkSmartPointer< vtkImageData >::New(); + i0->ShallowCopy( m_MegaCaptureReader->GetImage(iChannel, t0) ); + // clean smartpointer + m_InternalImages[0] = NULL; + m_InternalImages[0] = i0; + append_filter->AddInput(m_InternalImages[0]); + } + } + */ +} +//-------------------------------------------------------------------------- diff --git a/Code/IO/GoImage/GoMegaImageProcessor.h b/Code/IO/GoImage/GoMegaImageProcessor.h new file mode 100644 index 00000000..f8e74b78 --- /dev/null +++ b/Code/IO/GoImage/GoMegaImageProcessor.h @@ -0,0 +1,69 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef GoMegaImageProcessor_H +#define GoMegaImageProcessor_H + +// Required for dynamic libs on Windows (QGoIOExport) +#include "QGoIOConfigure.h" + +// include project +#include "GoImageProcessor.h" +#include "itkMegaCaptureReader.h" + +/** + * \struct GoMegaImageProcessor + * \brief Specialization of GoImageProcessor to handle mega capture files + * \ingroup GoImage + */ +class QGOIO_EXPORT GoMegaImageProcessor:public GoImageProcessor +{ +public: + /** + * \brief Set the reader. + * \param[in] iReader Pointer to the reader + **/ + void setReader(itk::MegaCaptureReader::Pointer iReader); + + virtual void initTimePoint(const unsigned int& iTime); + + virtual void setTimePoint(const unsigned int& iTime); + + virtual void setDoppler(const unsigned int& iTime,const unsigned int& iPrevious); + +private: + itk::MegaCaptureReader::Pointer m_MegaImageReader; +}; + +#endif // GoMegaImageProcessor_H diff --git a/Code/IO/GoImage/GoMegaImageStructure.h b/Code/IO/GoImage/GoMegaImageStructure.h new file mode 100644 index 00000000..6e428b83 --- /dev/null +++ b/Code/IO/GoImage/GoMegaImageStructure.h @@ -0,0 +1,195 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#ifndef GoMegaImageStructure_H +#define GoMegaImageStructure_H + +// Required for dynamic libs on Windows (QGoIOExport) +#include "QGoIOConfigure.h" + +// includes from external libs +// VTK +#include "vtkSmartPointer.h" +#include "vtkLookupTable.h" +#include "vtkImageData.h" +#include "vtkPiecewiseFunction.h" +#include "vtkImageAccumulate.h" + +// convert VTK to ITK +#include "itkImage.h" +#include "itkVTKImageImport.h" +#include "vtkImageExport.h" +#include "vtkitkAdaptor.h" + +/** + * \struct GoMegaImageStructure + * \brief Convenience structure to store visible image + * \ingroup GoImage + */ +struct QGOIO_EXPORT GoMegaImageStructure +{ + unsigned int Index; + vtkSmartPointer LUT; + vtkSmartPointer Image; + std::vector< double > Color; + bool Visibility; + std::string Name; + std::vector > RGBA; + vtkSmartPointer OpacityTF; + vtkSmartPointer Histogram; + + /** Constructor */ + GoMegaImageStructure(unsigned int iIndex, + vtkSmartPointer iLUT, + vtkSmartPointer iImage, + std::vector< double > iColor, + bool iVisibility, + std::string iName): + Index(iIndex), LUT(iLUT), Color(iColor), Visibility(iVisibility), + Name(iName) + { + Image = iImage; + + // init RGBA vectors + // vector might not be the best.... + RGBA.resize(4); + for(int i = 0; i<4; ++i) + { + RGBA[i][0] = 0; + RGBA[i][255] = Color[i]; + } + + //temp + OpacityTF = vtkSmartPointer::New(); + OpacityTF->AddPoint(0, 0); + OpacityTF->AddPoint(255, Color[3]/255); + + //compute histogram + double* range; + range = Image->GetScalarRange(); + Histogram = vtkSmartPointer::New(); + Histogram->SetInput( Image ); + Histogram->SetComponentExtent( + 0, + static_cast(range[1])-static_cast(range[0])-1,0,0,0,0 ); + Histogram->SetComponentOrigin( range[0],0,0 ); + Histogram->SetComponentSpacing( 1,0,0 ); + Histogram->SetIgnoreZero( false ); + Histogram->Update(); + } + + // functions to modify the structure through the boost::multiindexcontainer + void setLUT(vtkSmartPointer iLUT) + { + LUT = iLUT; + } + + void setVisibility(bool iVisibility) + { + Visibility = iVisibility; + } + + void setName(std::string iName) + { + Name = iName; + } + + void setImage(vtkImageData* iImage) + { + Image = iImage; + + // compute new histogram + double* range; + range = Image->GetScalarRange(); + + Histogram->RemoveAllInputs(); + Histogram->SetInput( Image ); + Histogram->SetComponentExtent( + 0, + static_cast(range[1])-static_cast(range[0])-1,0,0,0,0 ); + Histogram->SetComponentOrigin( range[0],0,0 ); + Histogram->SetComponentSpacing( 1,0,0 ); + Histogram->SetIgnoreZero( false ); + Histogram->Update(); + } + + void setPointsRGBA(std::vector< std::map< unsigned int, unsigned int> > iRGBA) + { + RGBA = iRGBA; + } + + /* + * \brief Convert a vtkImage to a itkImage. If we call after "ExtractROI", + * the dimension should be 3 all the time. + * (Even if we extract a2D region from a 3d image) + * \tparam PixelType type of pixel (unsigned char, etc.) + * \tparam VImageDimension dimension of the image (2 or 3) + * \param[in] iInput Pointer to a vtkImageData + * \return Pointer to an itkImage + */ + template< class PixelType, const unsigned int VImageDimension > + typename itk::Image< PixelType, VImageDimension >::Pointer + Convert2ITK() const + { + //Export VTK image to ITK + vtkSmartPointer exporter = + vtkSmartPointer::New(); + exporter->SetInput(Image); + exporter->Update(); + + // ImageType + typedef itk::Image< PixelType, VImageDimension > ImageType; + // Import VTK Image to ITK + typedef itk::VTKImageImport< ImageType > ImageImportType; + typedef typename ImageImportType::Pointer ImageImportPointer; + ImageImportPointer importer = ImageImportType::New(); + + ConnectPipelines< vtkImageExport, ImageImportPointer >( + exporter, + importer); + + typename ImageType::Pointer itkImage = importer->GetOutput(); + itkImage->DisconnectPipeline(); + + return itkImage; + } + + friend std::ostream& operator<<(std::ostream& os,const GoMegaImageStructure& e) + { + os<< "index: "< GetSamefieldFromTwoTables( return result; } +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +std::list< unsigned int > GetTwoFieldsFromTwoTables( + vtkMySQLDatabase *iDatabaseConnector, std::string iTableOne, + std::string iTableTwo, FieldWithValue iOnCondition, std::string iColumnOne, std::string iColumnTwo, + std::string iField, std::vector< std::string > iListValues, bool Distinct) +{ + std::string QueryString = SelectQueryStreamListConditions(iTableOne, iColumnOne, iField, iListValues, Distinct); + QueryString += " UNION "; + std::string What = GetLeftJoinTwoTables(iTableOne, iTableTwo, iOnCondition); + QueryString += SelectQueryStreamListConditions(What, iColumnTwo, iField, iListValues, Distinct); + return ExecuteSelectQuery< std::list< unsigned int > >(iDatabaseConnector, QueryString); +} //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ diff --git a/Code/IO/SelectQueryDatabaseHelper.h b/Code/IO/SelectQueryDatabaseHelper.h index 438e8f2c..461cecef 100644 --- a/Code/IO/SelectQueryDatabaseHelper.h +++ b/Code/IO/SelectQueryDatabaseHelper.h @@ -447,6 +447,14 @@ std::vector< std::string > GetSamefieldsFromTwoTables(vtkMySQLDatabase *Database std::string iField, std::string iValue); +//query: select distinct iColumnOne FROM TableOne where ifield = listconditions union select +//distinct icolumntwo from tableOne left join tabletwo on iOnCondition where ifield = listconditions +QGOIO_EXPORT +std::list< unsigned int > GetTwoFieldsFromTwoTables( + vtkMySQLDatabase *DatabaseConnector, std::string iTableOne, + std::string iTableTwo, FieldWithValue iOnCondition, std::string iColumnOne, std::string iColumnTwo, + std::string iField, std::vector< std::string > iListValues, bool Distinct); + //query: SELECT iColumnOne FROM TableOne WHERE...UNION SELECT iColumnTwo FROM // TableOne... //UNION SELECT iColumnOne FROM TableTwo WHERE listconditions2.... diff --git a/Code/IO/TraceStructure.cxx b/Code/IO/TraceStructure.cxx index d6205f10..1966be87 100644 --- a/Code/IO/TraceStructure.cxx +++ b/Code/IO/TraceStructure.cxx @@ -302,25 +302,29 @@ TraceStructure::RenderWithOriginalColors() const //-------------------------------------------------------------------------- void -TraceStructure::SetLookupTable(vtkLookupTable *iLut) const +TraceStructure::SetLookupTable(const vtkLookupTable *iLut) const { if ( iLut ) { if ( this->ActorXY ) { - this->ActorXY->GetMapper()->SetLookupTable(iLut); + this->ActorXY->GetMapper()->SetLookupTable( + const_cast(iLut)); } if ( this->ActorXZ ) { - this->ActorXZ->GetMapper()->SetLookupTable(iLut); + this->ActorXZ->GetMapper()->SetLookupTable( + const_cast(iLut)); } if ( this->ActorYZ ) { - this->ActorYZ->GetMapper()->SetLookupTable(iLut); + this->ActorYZ->GetMapper()->SetLookupTable( + const_cast(iLut)); } if ( this->ActorXYZ ) { - this->ActorXYZ->GetMapper()->SetLookupTable(iLut); + this->ActorXYZ->GetMapper()->SetLookupTable( + const_cast(iLut)); } } } diff --git a/Code/IO/TraceStructure.h b/Code/IO/TraceStructure.h index 3e2aa7aa..ebd5258d 100644 --- a/Code/IO/TraceStructure.h +++ b/Code/IO/TraceStructure.h @@ -164,7 +164,7 @@ class QGOIO_EXPORT TraceStructure /** \brief Set the lookup table \param[in] iLut */ - void SetLookupTable( vtkLookupTable* iLut ) const; + void SetLookupTable( const vtkLookupTable* iLut ) const; virtual void ReleaseData() const; diff --git a/Code/IO/TrackStructure.cxx b/Code/IO/TrackStructure.cxx index 26475842..3d3780f4 100644 --- a/Code/IO/TrackStructure.cxx +++ b/Code/IO/TrackStructure.cxx @@ -279,7 +279,7 @@ ModifyDivisionHighlight( vtkProperty* iProperty, const bool& iHighlight ) //-------------------------------------------------------------------------- void TrackStructure:: -ModifyDivisionColorData( double* iColor ) +ModifyDivisionColorData( const double* iColor ) { this->TreeNode.rgba[0] = iColor[0]; this->TreeNode.rgba[1] = iColor[1]; @@ -291,12 +291,12 @@ this->TreeNode.rgba[3] = iColor[3]; //-------------------------------------------------------------------------- void TrackStructure:: -ModifyDivisionColorActor( double* iColor ) +ModifyDivisionColorActor( const double* iColor ) { - this->TreeNode.ActorXY->GetProperty()->SetColor(iColor); - this->TreeNode.ActorXZ->GetProperty()->SetColor(iColor); - this->TreeNode.ActorYZ->GetProperty()->SetColor(iColor); - this->TreeNode.ActorXYZ->GetProperty()->SetColor(iColor); + this->TreeNode.ActorXY->GetProperty()->SetColor(const_cast(iColor)); + this->TreeNode.ActorXZ->GetProperty()->SetColor(const_cast(iColor)); + this->TreeNode.ActorYZ->GetProperty()->SetColor(const_cast(iColor)); + this->TreeNode.ActorXYZ->GetProperty()->SetColor(const_cast(iColor)); } //-------------------------------------------------------------------------- diff --git a/Code/IO/TrackStructure.h b/Code/IO/TrackStructure.h index 43f092cd..2858a447 100644 --- a/Code/IO/TrackStructure.h +++ b/Code/IO/TrackStructure.h @@ -150,9 +150,9 @@ class QGOIO_EXPORT TrackStructure : public TraceStructure void ModifyDivisionHighlight( vtkProperty* iProperty, const bool& iHighlight ); - void ModifyDivisionColorData( double* iColor ); + void ModifyDivisionColorData( const double* iColor ); // for the highlight - void ModifyDivisionColorActor( double* iColor ); + void ModifyDivisionColorActor( const double* iColor ); void AddDivisionArray( vtkIntArray* iArray ); diff --git a/Code/IO/TreeNodeStructure.h b/Code/IO/TreeNodeStructure.h index 7690be3d..2a58bdd7 100644 --- a/Code/IO/TreeNodeStructure.h +++ b/Code/IO/TreeNodeStructure.h @@ -57,15 +57,13 @@ class QGOIO_EXPORT TreeNodeStructure : public TraceStructure public: TreeNodeStructure() : TraceStructure(), m_Mother( NULL ) { - m_Child[0] = NULL; - m_Child[1] = NULL; + m_Child.resize(0); } TreeNodeStructure( const TreeNodeStructure & iE ) : TraceStructure( iE ), m_Mother(iE.m_Mother) { - m_Child[0] = iE.m_Child[0]; - m_Child[1] = iE.m_Child[1]; + m_Child = iE.m_Child; } ~TreeNodeStructure(){}; @@ -106,12 +104,11 @@ class QGOIO_EXPORT TreeNodeStructure : public TraceStructure const bool IsLeaf() const { - return ( ( this->m_Child[0] == NULL ) && - ( this->m_Child[1] == NULL ) ); + return ( !this->m_Child.size() ); } T* m_Mother; - T* m_Child[2]; + std::vector m_Child; }; #endif diff --git a/Code/IO/VisualizePolydataHelper.h b/Code/IO/VisualizePolydataHelper.h index 3464e04c..c97da605 100644 --- a/Code/IO/VisualizePolydataHelper.h +++ b/Code/IO/VisualizePolydataHelper.h @@ -44,6 +44,8 @@ #include "vtkImageViewer2.h" +#include "vtkExtractVOI.h" + void ShowPolyData(vtkPolyData *iPolyData) { vtkSmartPointer< vtkPolyDataMapper > mapper = @@ -84,6 +86,12 @@ void ShowImage(vtkImageData *iData) vtkSmartPointer< vtkImageViewer2 > viewer = vtkSmartPointer< vtkImageViewer2 >::New(); + /*vtkSmartPointer voi = vtkSmartPointer::New(); + voi->SetInput(iData); + voi->SetVOI(25, 75, 25, 75, 25, 75); + voi->Update();*/ + + viewer->SetInput(iData); viewer->SetRenderWindow(renWin); viewer->SetRenderer(ren1); @@ -93,4 +101,23 @@ void ShowImage(vtkImageData *iData) iren->Start(); } +void ShowActor(vtkActor *iActor) +{ + vtkSmartPointer< vtkRenderer > renderer = + vtkSmartPointer< vtkRenderer >::New(); + renderer->AddActor(iActor); + + vtkSmartPointer< vtkRenderWindow > renderWindow = + vtkSmartPointer< vtkRenderWindow >::New(); + renderWindow->AddRenderer(renderer); + + vtkSmartPointer< vtkRenderWindowInteractor > renderWindowInteractor = + vtkSmartPointer< vtkRenderWindowInteractor >::New(); + renderWindowInteractor->SetRenderWindow(renderWindow); + + renderWindowInteractor->Initialize(); + renderWindow->Render(); + renderWindowInteractor->Start(); +} + #endif diff --git a/Code/IO/itkMegaCaptureReader.cxx b/Code/IO/itkMegaCaptureReader.cxx index 60df4e7d..1d9ca5a7 100644 --- a/Code/IO/itkMegaCaptureReader.cxx +++ b/Code/IO/itkMegaCaptureReader.cxx @@ -136,6 +136,9 @@ MegaCaptureReader::SetMegaCaptureHeader(const std::string & iHeader) { m_HeaderReader->SetFileName(iHeader); m_HeaderReader->Read(); + + m_ChannelColor = m_HeaderReader->m_ChannelColor; + m_Modified = true; } @@ -254,6 +257,7 @@ MegaCaptureReader::AddToVTKVolumeBuilder(const int & iCounter, void MegaCaptureReader::Update() { + std::cout << __FILE__ << " START building new IMAGE" << std::endl; if ( m_Modified ) { std::map< unsigned int, std::list< std::string > > filelistperchannel; @@ -272,7 +276,6 @@ MegaCaptureReader::Update() } // prepare the final output - std::map< unsigned int, std::list< std::string > >::iterator fch_it = filelistperchannel.begin(); std::map< unsigned int, std::list< std::string > >::iterator @@ -284,6 +287,7 @@ MegaCaptureReader::Update() vtkSmartPointer< vtkImageAppend > volumeBuilder = vtkSmartPointer< vtkImageAppend >::New(); + volumeBuilder->SetNumberOfThreads(VTK_MAX_THREADS); volumeBuilder->SetAppendAxis(2); std::list< std::string >::iterator f_it = fch_it->second.begin(); @@ -328,6 +332,7 @@ MegaCaptureReader::Update() ++fch_it; } + std::cout << __FILE__ << " FINISH building new IMAGE" << std::endl; m_TimeInterval = m_HeaderReader->m_TimeInterval; } } @@ -372,6 +377,7 @@ MegaCaptureReader::GetImage(const unsigned int & iCh, { vtkSmartPointer< vtkImageAppend > volumeBuilder = vtkSmartPointer< vtkImageAppend >::New(); + volumeBuilder->SetNumberOfThreads(VTK_MAX_THREADS); volumeBuilder->SetAppendAxis(2); std::list< std::string >::iterator f_it = filenames.begin(); @@ -402,5 +408,14 @@ MegaCaptureReader::GetOutputs() { return m_OutputImageMap; } +//-------------------------------------------------------------------------- -} //end of namespace \ No newline at end of file +//-------------------------------------------------------------------------- +std::vector< std::vector< int > > +MegaCaptureReader:: +GetChannelColor() +{ + return m_ChannelColor; +} +//-------------------------------------------------------------------------- +}//end of namespace diff --git a/Code/IO/itkMegaCaptureReader.h b/Code/IO/itkMegaCaptureReader.h index 32069661..f408701d 100644 --- a/Code/IO/itkMegaCaptureReader.h +++ b/Code/IO/itkMegaCaptureReader.h @@ -99,6 +99,8 @@ class QGOIO_EXPORT MegaCaptureReader:public LightProcessObject std::map< unsigned int, vtkImageData * > GetOutputs(); + std::vector< std::vector< int > > GetChannelColor(); + protected: MegaCaptureReader(); ~MegaCaptureReader(); @@ -108,11 +110,13 @@ class QGOIO_EXPORT MegaCaptureReader:public LightProcessObject const std::string& iFileName, vtkImageAppend * iBuilder ); - std::map< unsigned int, vtkImageData * > m_OutputImageMap; + std::map< unsigned int, vtkImageData * > m_OutputImageMap; GoFigureFileInfoHelperMultiIndexContainer m_FileList; GoFigure::FileType m_FileType; MegaCaptureHeaderReader *m_HeaderReader; + std::vector< std::vector< int > > m_ChannelColor; + unsigned int m_MinTimePoint; unsigned int m_MaxTimePoint; unsigned int m_UpdateTimePoint; diff --git a/Examples/GUI/lib/qgotabimageview4d.cxx b/Examples/Attic/qgotabimageview4d.cxx similarity index 100% rename from Examples/GUI/lib/qgotabimageview4d.cxx rename to Examples/Attic/qgotabimageview4d.cxx diff --git a/Examples/Filters/CMakeLists.txt b/Examples/Filters/CMakeLists.txt index cb11771a..7d2f67e0 100644 --- a/Examples/Filters/CMakeLists.txt +++ b/Examples/Filters/CMakeLists.txt @@ -2,8 +2,7 @@ ADD_EXECUTABLE( itkvtkPolyDatatoBinaryMaskImageFilterTest itkvtkPolyDatatoBinaryMaskImageFilterTest.cxx ) TARGET_LINK_LIBRARIES( itkvtkPolyDatatoBinaryMaskImageFilterTest - ITKIO - ITKCommon + ${ITK_LIBRARIES} vtkGraphics vtkHybrid ) @@ -51,7 +50,7 @@ TARGET_LINK_LIBRARIES( ContourToMeshFilterTest PoissonReconstruction vtkHybrid vtkRenderingAddOn2 - ITKCommon + ${ITK_LIBRARIES} ) ADD_TEST( ContourToMeshFilterTest @@ -59,3 +58,96 @@ ADD_TEST( ContourToMeshFilterTest 1 ) +ADD_EXECUTABLE( MeshToContourFilterTest + MeshToContourFilterTest.cxx + ${GOFIGURE2_SOURCE_DIR}/Code/Filters/Mesh/MeshToContourFilter.cxx + ) +TARGET_LINK_LIBRARIES( MeshToContourFilterTest + vtkHybrid + ) + +ADD_TEST( MeshToContourFilterTest + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MeshToContourFilterTest + 1 + ) + +#ADD_EXECUTABLE( singleCellSplitImageFilter +# SingleCellSplitImageFilter.cxx +# ) +#TARGET_LINK_LIBRARIES( +# singleCellSplitImageFilter +# ITKReview +# ITKIO +# ) + +ADD_EXECUTABLE( cellMergeImageFilter + CellMergeImageFilter.cxx + ) + +TARGET_LINK_LIBRARIES( cellMergeImageFilter + vtkHybrid + ) + +#ADD_TEST( singleCellSplitImageFilterTest +# ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/singleCellSplitImageFilter +# ${TESTING_DATA_PATH}/MultiphaseCells2D.png +# split.mhd +#) + + +ADD_EXECUTABLE( itkvtkMeshSplitterDanielssonImageFilterTest + itkvtkMeshSplitterDanielssonImageFilterTest.cxx +) +TARGET_LINK_LIBRARIES( itkvtkMeshSplitterDanielssonImageFilterTest + QGoGui +) + +ADD_TEST( itkvtkMeshSplitterDanielssonImageFilterTest + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkMeshSplitterDanielssonImageFilterTest + ${TESTING_DATA_PATH}/Circle3D.mhd +) + +ADD_EXECUTABLE( ExtractMeshesFromLabelImageFilter + ExtractMeshesFromLabelImageFilter.cxx +) +TARGET_LINK_LIBRARIES( ExtractMeshesFromLabelImageFilter + #ITKCommon + #ITKIO + #ITKReview + ${ITK_LIBRARIES} +) + +ADD_EXECUTABLE(ConvertMeshesToLabelImageFilter ConvertMeshesToLabelImageFilter.cxx ) +TARGET_LINK_LIBRARIES( ConvertMeshesToLabelImageFilter + # ITKIO ITKReview + ${ITK_LIBRARIES} +) + +ADD_EXECUTABLE( itkQuadEdgeMeshTovtkPolyDataTest itkQuadEdgeMeshTovtkPolyDataTest.cxx ) +TARGET_LINK_LIBRARIES( itkQuadEdgeMeshTovtkPolyDataTest + #ITKCommon + ${ITK_LIBRARIES} + vtkHybrid +) + +ADD_EXECUTABLE( itkvtkPolyDataToitkQuadEdgeMeshTest + itkvtkPolyDataToitkQuadEdgeMeshTest.cxx ) +TARGET_LINK_LIBRARIES( itkvtkPolyDataToitkQuadEdgeMeshTest + #ITKCommon + ${ITK_LIBRARIES} + vtkHybrid +) + +ADD_TEST( itkvtkPolyDataToitkQuadEdgeMeshTest + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkPolyDataToitkQuadEdgeMeshTest +) + +ADD_EXECUTABLE( itkvtkMeshMergeConvexHullFilterTest + itkvtkMeshMergeConvexHullFilterTest.cxx ) +TARGET_LINK_LIBRARIES( itkvtkMeshMergeConvexHullFilterTest + QGoGui +) +ADD_TEST( itkvtkMeshMergeConvexHullFilterTest + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/itkvtkMeshMergeConvexHullFilterTest + ${TESTING_DATA_PATH}/Circle3D.mhd +) diff --git a/Code/GUI/lib/QGoMeshSeedSegmentation.h b/Examples/Filters/CellMergeImageFilter.cxx similarity index 57% rename from Code/GUI/lib/QGoMeshSeedSegmentation.h rename to Examples/Filters/CellMergeImageFilter.cxx index 6ad6cbb1..ba51af77 100644 --- a/Code/GUI/lib/QGoMeshSeedSegmentation.h +++ b/Examples/Filters/CellMergeImageFilter.cxx @@ -31,54 +31,50 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ -#ifndef __QGoMeshSeedSegmentation_h -#define __QGoMeshSeedSegmentation_h -#include -#include -#include "QGoGUILibConfigure.h" - -#include "QGoSeedSegmentationBase.h" +#include "vtkPolyDataReader.h" +#include "vtkPolyDataWriter.h" #include "vtkSmartPointer.h" +#include "vtkAppendPolyData.h" +#include "vtkHull.h" + +int main( int argc, char** argv ) +{ + if( argc < 3 ) + { + std::cerr << "Missing arguments" << std::endl; + std::cerr << "Usage: " << std::endl; + std::cerr << argv[0] << " polydata1 polydata2 hullOutput" << std::endl; + return EXIT_FAILURE; + } -class vtkPoints; -class vtkImageData; + vtkSmartPointer reader1 = vtkSmartPointer::New(); + reader1->SetFileName( argv[1] ); + reader1->Update(); + vtkPolyData* contour1 = reader1->GetOutput(); -// segmentation filters -class QGoFilterChanAndVese; -class QGoFilterShape; -class QGoFilterWatershed; + vtkSmartPointer reader2 = vtkSmartPointer::New(); + reader2->SetFileName( argv[2] ); + reader2->Update(); + vtkPolyData* contour2 = reader2->GetOutput(); -/** - * \class QGoMeshSeedSegmentation - * \ingroup QGoMeshSeed - * \brief Interface between the segmentation filters and the seed base widget. - * Generates meshes. -*/ + // Append the local and remote data + vtkSmartPointer append = vtkSmartPointer::New(); + append->AddInput( contour1 ); + append->AddInput( contour2 ); + + vtkSmartPointer hullFilter = vtkSmartPointer::New(); + hullFilter->SetInputConnection( append->GetOutputPort() ); + hullFilter->AddRecursiveSpherePlanes( 2 ); + hullFilter->Update(); + + vtkSmartPointer writer = vtkSmartPointer::New(); + writer->SetFileName( argv[3] ); + writer->SetInput( hullFilter->GetOutput() ); + writer->Write(); + + return EXIT_SUCCESS; +} -class QGOGUILIB_EXPORT QGoMeshSeedSegmentation:public QGoSeedSegmentationBase -{ - Q_OBJECT -public: - /** - * \brief Constructor - */ - explicit QGoMeshSeedSegmentation(QWidget *parentW = 0, - vtkPoints *seeds = 0, - std::vector< vtkSmartPointer > *iOriginalImage = 0, - int iSampling = 1); - - /** - * \brief Destructor - */ - ~QGoMeshSeedSegmentation(); -private: - QGoFilterChanAndVese* m_LevelSetfilter; - QGoFilterShape* m_ShapeFilter; - QGoFilterWatershed* m_Watershed; - - std::vector< vtkSmartPointer > *m_OriginalImage; -}; -#endif diff --git a/Examples/Filters/ConvertMeshesToLabelImageFilter.cxx b/Examples/Filters/ConvertMeshesToLabelImageFilter.cxx new file mode 100644 index 00000000..2786d603 --- /dev/null +++ b/Examples/Filters/ConvertMeshesToLabelImageFilter.cxx @@ -0,0 +1,110 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#include "itkConvertMeshesToLabelImageFilter.h" +#include "itkVTKPolyDataReader.h" +#include "itkNumericSeriesFileNames.h" +#include + +int main (int argc, char *argv[]) +{ + if (argc < 5) + { + std::cout << "Usage: " << argv[0] << " InfoVolume InputMeshFormat OutputVolume numOfThreads numOfMeshes" << std::endl; + return EXIT_FAILURE; + } + + const unsigned int Dimension = 3; + typedef itk::Image< unsigned int, Dimension > SegmentImageType; + typedef itk::ImageFileReader< SegmentImageType > ReaderType; + + typedef itk::ConvertMeshesToLabelImageFilter< SegmentImageType > ImageSourceType; + + typedef ImageSourceType::MeshType MeshType; + typedef itk::VTKPolyDataReader< MeshType > MeshReaderType; + + typedef itk::NumericSeriesFileNames NameGeneratorType; + typedef itk::ImageFileWriter< SegmentImageType > WriterType; + + // Define all of the variables + unsigned int numOfThreads = atoi( argv[4] ); + unsigned int numOfMeshes = atoi( argv[5] ); + + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName ( argv[1] ); + reader->Update(); + SegmentImageType::Pointer input = reader->GetOutput(); + + SegmentImageType::Pointer m_OutputImage = SegmentImageType::New(); + m_OutputImage->CopyInformation( input ); + m_OutputImage->SetRegions( input->GetLargestPossibleRegion() ); + m_OutputImage->Allocate(); + m_OutputImage->FillBuffer( 0 ); + + NameGeneratorType::Pointer nameGeneratorOutput = NameGeneratorType::New(); + nameGeneratorOutput->SetSeriesFormat( argv[2] ); + nameGeneratorOutput->SetStartIndex( 1 ); + nameGeneratorOutput->SetEndIndex( numOfMeshes ); + nameGeneratorOutput->SetIncrementIndex( 1 ); + + ImageSourceType::Pointer imageSource = ImageSourceType::New(); + + ImageSourceType::MeshVectorType meshes( numOfMeshes ); + + for( unsigned int i = 0; i < numOfMeshes; ++i ) + { + std::stringstream ss; + ss << nameGeneratorOutput->GetFileNames()[i]; + // std::cout << argv[0] << " writing " << ss.str() << std::endl; + + MeshReaderType::Pointer meshReader = MeshReaderType::New( ); + meshReader->SetFileName( ss.str().c_str() ); + meshReader->Update(); + meshes[i] = meshReader->GetOutput(); + meshes[i]->DisconnectPipeline(); + } + + imageSource->SetInput( m_OutputImage ); + imageSource->SetNumberOfThreads( numOfThreads ); + imageSource->SetMeshes( meshes ); + imageSource->Update(); + + WriterType::Pointer writer = WriterType::New( ); + writer->SetInput( m_OutputImage ); + writer->SetFileName( argv[3] ); + writer->Update(); + + return EXIT_SUCCESS; +} diff --git a/Examples/Filters/ExtractMeshesFromLabelImageFilter.cxx b/Examples/Filters/ExtractMeshesFromLabelImageFilter.cxx new file mode 100644 index 00000000..df0869cb --- /dev/null +++ b/Examples/Filters/ExtractMeshesFromLabelImageFilter.cxx @@ -0,0 +1,106 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "itkImageFileReader.h" +#include "itkVTKPolyDataReader.h" +#include "itkVTKPolyDataWriter.h" +#include "itkExtractMeshesFromLabelImageFilter.h" +#include "itkNumericSeriesFileNames.h" +#include + +int main (int argc, char *argv[]) +{ + if (argc < 3) + { + std::cout << "Usage: " << argv[0] + << " InputVolume OutputMeshFormat numOfThreads" + << std::endl; + return EXIT_FAILURE; + } + + const unsigned int Dimension = 3; + typedef itk::Image< unsigned int, Dimension > SegmentImageType; + typedef itk::ImageFileReader< SegmentImageType > ReaderType; + + typedef itk::ExtractMeshesFromLabelImageFilter< SegmentImageType > + MeshSourceType; + + typedef MeshSourceType::MeshType MeshType; + typedef itk::VTKPolyDataReader< MeshType > MeshReaderType; + typedef itk::VTKPolyDataWriter< MeshType > MeshWriterType; + + typedef itk::NumericSeriesFileNames NameGeneratorType; + typedef itk::VTKPolyDataWriter< MeshType > MeshWriterType; + + // Define all of the variables + unsigned int smoothingIterations = 8; + double relaxationFactor = 0.75; + unsigned int numberOfTriangles = 200; + unsigned int numOfThreads = atoi( argv[3] ); + + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName ( argv[1] ); + reader->Update(); + SegmentImageType::Pointer input = reader->GetOutput(); + + MeshSourceType::Pointer meshSource = MeshSourceType::New(); + meshSource->SetInput( input ); + meshSource->SetUseSmoothing( true ); + meshSource->SetUseDecimation( true ); + meshSource->SetNumberOfTrianglesPerMesh( numberOfTriangles ); + meshSource->SetNumberOfSmoothingIterations( smoothingIterations ); + meshSource->SetSmoothingRelaxationFactor( relaxationFactor ); + meshSource->SetDelaunayConforming( false ); + meshSource->SetNumberOfThreads( numOfThreads ); + meshSource->Update(); + + NameGeneratorType::Pointer nameGeneratorOutput = NameGeneratorType::New(); + nameGeneratorOutput->SetSeriesFormat( argv[2] ); + nameGeneratorOutput->SetStartIndex( 1 ); + nameGeneratorOutput->SetEndIndex( meshSource->GetNumberOfMeshes() ); + nameGeneratorOutput->SetIncrementIndex( 1 ); + + for( unsigned int i = 0; i < meshSource->GetNumberOfMeshes(); ++i ) + { + std::stringstream ss; + ss << nameGeneratorOutput->GetFileNames()[i]; +// std::cout << argv[0] << " writing " << ss.str() << std::endl; + + MeshWriterType::Pointer writer = MeshWriterType::New( ); + writer->SetInput( meshSource->GetOutputs()[i] ); + writer->SetFileName( ss.str().c_str() ); + writer->Update(); + } + + return EXIT_SUCCESS; +} diff --git a/Examples/Filters/MeshToContourFilterTest.cxx b/Examples/Filters/MeshToContourFilterTest.cxx new file mode 100644 index 00000000..ffb71ef2 --- /dev/null +++ b/Examples/Filters/MeshToContourFilterTest.cxx @@ -0,0 +1,120 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009 + + Copyright (c) 2009, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include "vtkSphereSource.h" +#include "vtkPolyData.h" +#include "vtkSmartPointer.h" +#include "vtkPolyDataMapper.h" +#include "vtkActor.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" + +#include "MeshToContourFilter.h" + +int main(int argc, char *argv[]) +{ + if ( argc != 2 ) + { + std::cerr << "./ContourToMeshFilter(.exe) takes 1 arguments" << std::endl; + std::cerr << "1- boolean value (test)" << std::endl; + return EXIT_FAILURE; + } + + // create sphere + vtkSmartPointer sphereSource2 = + vtkSmartPointer::New(); + sphereSource2->SetRadius(10); + sphereSource2->SetCenter(25,0,0); + sphereSource2->SetThetaResolution(10); + sphereSource2->SetPhiResolution(10); + sphereSource2->Update(); + + + // split sphere + MeshToContourFilter filter; + + filter.SetInput(sphereSource2->GetOutput()); + filter.SetSpacing(1, 1, 1); + + std::map output = + filter.ExtractPolyData( MeshToContourFilter::XY ); + + vtkSmartPointer< vtkRenderer > renderer = + vtkSmartPointer< vtkRenderer >::New(); + + std::map::iterator it = output.begin(); + + while (it!=output.end()) + { + vtkSmartPointer mapper = + vtkSmartPointer::New(); + mapper->SetInput( it->second ); + + vtkSmartPointer actor = + vtkSmartPointer::New(); + actor->SetMapper(mapper); + renderer->AddActor(actor); + + ++it; + } + + vtkSmartPointer< vtkRenderWindow > renwin = + vtkSmartPointer< vtkRenderWindow >::New(); + renwin->AddRenderer(renderer); + + vtkSmartPointer< vtkRenderWindowInteractor > iren = + vtkSmartPointer< vtkRenderWindowInteractor >::New(); + iren->SetRenderWindow(renwin); + + renwin->Render(); + + if ( atoi(argv[1]) == 1 ) + { + iren->CreateOneShotTimer(1); + } + else + { + iren->Start(); + } + + // clean map + it = output.begin(); + while (it!=output.end()) + { + (it->second)->Delete(); + ++it; + } + + return EXIT_SUCCESS; +} diff --git a/Code/GUI/lib/QGoSeedBaseWidget.h b/Examples/Filters/SingleCellSplitImageFilter.cxx similarity index 52% rename from Code/GUI/lib/QGoSeedBaseWidget.h rename to Examples/Filters/SingleCellSplitImageFilter.cxx index 5bb221fe..4d7534c9 100644 --- a/Code/GUI/lib/QGoSeedBaseWidget.h +++ b/Examples/Filters/SingleCellSplitImageFilter.cxx @@ -32,81 +32,70 @@ =========================================================================*/ -#ifndef __QGoSeedBaseWidget_h -#define __QGoSeedBaseWidget_h - -#include -#include -#include - -// Collapsible groupbox for the parameters -#include "ctkCollapsibleGroupBox.h" - -#include "vtkPolyData.h" - -#include "ui_SegmentationSeedBaseWidget.h" - -/** - * \class QGoSeedBaseWidget - * \ingroup QGoSeed - * \brief Base widget for all the seed-based segmentations (contours and meshes) -*/ - -class QGoSeedBaseWidget: - public QWidget, - protected Ui::SegmentationSeedBaseWidget -{ - Q_OBJECT -public: - explicit QGoSeedBaseWidget(QWidget *iParent = 0, int iSampling = 0); - ~QGoSeedBaseWidget(); - - void Initialize(); - - int GetCurrentFilter(); - - ctkCollapsibleGroupBox* groupBox; - QGridLayout *vbox; - -public slots: - void AddChannel(int iPosition, QString iChannel); - - void setNumberOfChannels(int iNumberOfChannels); - - void AddFilter(QString iFilter); - - int GetNumberOfFilters(); - - QGridLayout * GetFrame(); - - void SetChannel( unsigned int iChannel); - -signals: - void Apply(); - - void Radius(double); - - void Filter(int); - - void Channel(int); - - void Sampling(int); - - void MeshCreated(vtkPolyData *, int timePoint = 0); - - void ContourCreated(vtkPolyData *); - - void ImageProcessed(); - - void UpdateSeeds(); - - void SegmentationFinished(); - - void CreateCorrespondingMesh(int); - - void AddContourForMeshToContours(vtkPolyData *); - - void Clicked(bool); -}; - -#endif +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#include "itkPointSet.h" +#include "itkSingleCellSplitImageFilter.h" +#include +#include + +int main ( int argc, char* argv[] ) + { + if ( argc < 3 ) + { + std::cerr << "Usage: " << std::endl; + std::cerr << argv[0] << " input output" << std::endl; + return EXIT_FAILURE; + } + + const unsigned int Dimension = 2; + typedef itk::Image< unsigned char, Dimension > ImageType; + typedef ImageType::PointType ImagePointType; + typedef itk::PointSet< ImagePointType::CoordRepType, 2 > PointSetType; + + typedef itk::ImageFileReader< ImageType > ReaderType; + typedef itk::ImageFileWriter< ImageType > WriterType; + typedef itk::SingleCellSplitImageFilter< ImageType, PointSetType > FilterType; + + ImageType::Pointer input; + { + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName ( argv[1] ); + reader->Update(); + input = reader->GetOutput(); + input->DisconnectPipeline(); + } + + FilterType::Pointer filter = FilterType::New(); + filter->SetInput ( input ); + filter->SetForegroundValue( 1 ); + + PointSetType::Pointer seeds = PointSetType::New(); + + ImagePointType p; + p[0] = 40; + p[1] = 40; + seeds->SetPoint( 0, p ); + + p[0] = 60; + p[1] = 60; + seeds->SetPoint( 1, p ); + + filter->SetSeeds( seeds ); + filter->Update(); + + WriterType::Pointer writer = WriterType::New(); + writer->SetInput ( filter->GetOutput() ); + writer->SetFileName ( argv[2] ); + + try + { + writer->Update(); + } + catch ( itk::ExceptionObject e ) + { + std::cerr << "Error: " << e << std::endl; + } + + return EXIT_SUCCESS; + } diff --git a/Examples/Filters/itkQuadEdgeMeshTovtkPolyDataTest.cxx b/Examples/Filters/itkQuadEdgeMeshTovtkPolyDataTest.cxx new file mode 100644 index 00000000..1ea609fa --- /dev/null +++ b/Examples/Filters/itkQuadEdgeMeshTovtkPolyDataTest.cxx @@ -0,0 +1,96 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + + +#include "itkQuadEdgeMesh.h" +#include "itkRegularSphereMeshSource.h" +#include "itkQuadEdgeMeshTovtkPolyData.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkPolyDataMapper.h" +#include "vtkActor.h" +#include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" + +int main( int, char** ) +{ + typedef double CoordType; + const unsigned int Dimension = 3; + typedef itk::QuadEdgeMesh< CoordType, Dimension > MeshType; + typedef itk::RegularSphereMeshSource< MeshType > SphereSourceType; + + MeshType::PointType center; + center.Fill( 0. ); + + SphereSourceType::Pointer sphere = SphereSourceType::New(); + sphere->SetCenter( center ); + sphere->SetResolution( 5 ); + sphere->Update(); + + typedef itk::QuadEdgeMeshTovtkPolyData< MeshType > ConverterType; + ConverterType::Pointer converter = ConverterType::New(); + converter->SetInput( sphere->GetOutput() ); + converter->Update(); + + vtkSmartPointer< vtkPolyData > vtk_mesh = converter->GetOutput(); + + vtkSmartPointer< vtkPolyDataMapper > mapper = + vtkSmartPointer< vtkPolyDataMapper >::New(); + mapper->SetInput( vtk_mesh ); + + vtkSmartPointer< vtkActor > actor = + vtkSmartPointer< vtkActor >::New(); + actor->SetMapper( mapper ); + actor->GetProperty()->SetColor( 0.5, 0.5, 0.5 ); + + vtkSmartPointer< vtkRenderer > renderer = + vtkSmartPointer< vtkRenderer >::New(); + renderer->AddActor( actor ); + + // Create a render window + vtkSmartPointer renwin = + vtkSmartPointer::New(); + renwin->AddRenderer(renderer); + + // Create an interactor + vtkSmartPointer iren = + vtkSmartPointer::New(); + iren->SetRenderWindow(renwin); + iren->Initialize(); + iren->Start(); + + return EXIT_SUCCESS; +} diff --git a/Examples/Filters/itkvtkMeshMergeConvexHullFilterTest.cxx b/Examples/Filters/itkvtkMeshMergeConvexHullFilterTest.cxx new file mode 100644 index 00000000..d98e0aa3 --- /dev/null +++ b/Examples/Filters/itkvtkMeshMergeConvexHullFilterTest.cxx @@ -0,0 +1,114 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "itkvtkMeshMergeConvexHullFilter.h" + +#include "itkImage.h" +#include "itkImageFileReader.h" + +#include "vtkSmartPointer.h" +#include "vtkSphereSource.h" +#include "vtkPolyDataWriter.h" + +#include "vcl_algorithm.h" + +int main( int argc, char* argv[] ) +{ + const unsigned int Dimension = 3; + typedef unsigned char PixelType; + + typedef itk::Image< PixelType, Dimension > ImageType; + typedef itk::ImageFileReader< ImageType > ReaderType; + + ImageType::Pointer input; + { + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName ( argv[1] ); + reader->Update(); + input = reader->GetOutput(); + input->DisconnectPipeline(); + } + + ImageType::PointType im_org = input->GetOrigin(); + ImageType::SizeType im_size = input->GetLargestPossibleRegion().GetSize(); + + ImageType::IndexType idx; + idx[0] = im_size[0] - 1; + idx[1] = im_size[1] - 1; + idx[2] = im_size[2] - 1; + + ImageType::PointType p; + input->TransformIndexToPhysicalPoint( idx, p ); + + ImageType::PointType center; + center.SetToMidPoint( im_org, p ); + + ImageType::PointType::CoordRepType radius; + radius = vcl_min( p[0] - im_org[0], p[1] - im_org[1] ); + radius = vcl_min( radius, p[2] - im_org[2] ); + + radius *= 0.25; + + vtkSmartPointer< vtkSphereSource > sphere_source = + vtkSmartPointer< vtkSphereSource >::New(); + sphere_source->SetCenter( center[0] - 0.5 * radius, center[1], center[2] ); + sphere_source->SetRadius( radius ); + sphere_source->Update(); + + vtkSmartPointer< vtkSphereSource > sphere_source2 = + vtkSmartPointer< vtkSphereSource >::New(); + sphere_source2->SetCenter( center[0] + 0.5 * radius, center[1], center[2] ); + sphere_source2->SetRadius( radius ); + sphere_source2->Update(); + + typedef itk::vtkMeshMergeConvexHullFilter< ImageType > MergerType; + MergerType::Pointer filter = MergerType::New(); + + std::list< vtkPolyData* > meshes; + meshes.push_back( sphere_source->GetOutput() ); + meshes.push_back( sphere_source2->GetOutput() ); + + filter->SetInputs( meshes ); + filter->SetNumberOfImages( 1 ); + filter->SetFeatureImage( 0, input ); + filter->Update(); + + vtkSmartPointer< vtkPolyDataWriter > writer = + vtkSmartPointer< vtkPolyDataWriter >::New(); + writer->SetInput( filter->GetOutput() ); + writer->SetFileName( "merged.vtk" ); + writer->Write(); + + return EXIT_SUCCESS; +} diff --git a/Examples/Filters/itkvtkMeshSplitterDanielssonImageFilterTest.cxx b/Examples/Filters/itkvtkMeshSplitterDanielssonImageFilterTest.cxx new file mode 100644 index 00000000..77ad4877 --- /dev/null +++ b/Examples/Filters/itkvtkMeshSplitterDanielssonImageFilterTest.cxx @@ -0,0 +1,138 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + + +#include "itkvtkMeshSplitterDanielssonDistanceImageFilter.h" + +#include "itkImage.h" +#include "itkImageFileReader.h" + +#include "vtkSmartPointer.h" +#include "vtkSphereSource.h" +#include "vtkPolyDataWriter.h" + +#include "vcl_algorithm.h" + +int main( int argc, char* argv[] ) +{ + const unsigned int Dimension = 3; + typedef unsigned char PixelType; + + typedef itk::Image< PixelType, Dimension > ImageType; + typedef itk::ImageFileReader< ImageType > ReaderType; + + ImageType::Pointer input; + { + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName ( argv[1] ); + reader->Update(); + input = reader->GetOutput(); + input->DisconnectPipeline(); + } + + ImageType::PointType im_org = input->GetOrigin(); + ImageType::SizeType im_size = input->GetLargestPossibleRegion().GetSize(); + + ImageType::IndexType idx; + idx[0] = im_size[0] - 1; + idx[1] = im_size[1] - 1; + idx[2] = im_size[2] - 1; + + ImageType::PointType p; + input->TransformIndexToPhysicalPoint( idx, p ); + + ImageType::PointType center; + center.SetToMidPoint( im_org, p ); + + ImageType::PointType::CoordRepType radius; + radius = vcl_min( p[0] - im_org[0], p[1] - im_org[1] ); + radius = vcl_min( radius, p[2] - im_org[2] ); + + radius *= 0.25; + + vtkSmartPointer< vtkSphereSource > sphere_source = + vtkSmartPointer< vtkSphereSource >::New(); + sphere_source->SetCenter( center[0], center[1], center[2] ); + sphere_source->SetRadius( radius ); + sphere_source->Update(); + + typedef itk::vtkMeshSplitterDanielssonDistanceImageFilter< ImageType > + SplitterType; + SplitterType::Pointer filter = SplitterType::New(); + filter->SetMesh( sphere_source->GetOutput() ); + filter->SetNumberOfImages( 1 ); + filter->SetFeatureImage( 0, input ); + + typedef SplitterType::PointSetType PointSetType; + PointSetType::Pointer seeds = PointSetType::New(); + + p[0] = center[0] - 0.5 * radius; + p[1] = center[1]; + p[2] = center[2]; + seeds->SetPoint( 0, p ); + + p[0] = center[0] + 0.5 * radius; + seeds->SetPoint( 1, p ); + + filter->SetSeeds( seeds ); + filter->Update(); + + std::vector< vtkPolyData* > outputs = filter->GetOutputs(); + + std::vector< vtkPolyData* >::iterator it = outputs.begin(); + size_t i = 0; + + while( it != outputs.end() ) + { + vtkSmartPointer< vtkPolyDataWriter > writer = + vtkSmartPointer< vtkPolyDataWriter >::New(); + writer->SetInput( *it ); + + std::stringstream os; + os << i; + + std::string filename = "mesh"; + filename += os.str(); + filename += ".vtk"; + + std::cout << filename.c_str() << std::endl; + writer->SetFileName( filename.c_str() ); + writer->Write(); + + ++i; + ++it; + } + + return EXIT_SUCCESS; +} diff --git a/Examples/Filters/itkvtkPolyDataToitkQuadEdgeMeshTest.cxx b/Examples/Filters/itkvtkPolyDataToitkQuadEdgeMeshTest.cxx new file mode 100644 index 00000000..940ecd7a --- /dev/null +++ b/Examples/Filters/itkvtkPolyDataToitkQuadEdgeMeshTest.cxx @@ -0,0 +1,62 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009-11 + + Copyright (c) 2009-11, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include "vtkSphereSource.h" +#include "itkQuadEdgeMesh.h" +#include "itkvtkPolyDataToitkQuadEdgeMesh.h" +#include "itkVTKPolyDataWriter.h" + +int main( int , char** ) +{ + vtkSmartPointer< vtkSphereSource > sphere_source = + vtkSmartPointer< vtkSphereSource >::New(); + sphere_source->SetCenter( 0., 0., 0. ); + sphere_source->Update(); + + typedef itk::QuadEdgeMesh< double, 3 > MeshType; + typedef itk::vtkPolyDataToitkQuadEdgeMesh< MeshType > ConverterType; + ConverterType::Pointer converter = ConverterType::New(); + converter->SetInput( sphere_source->GetOutput() ); + converter->Update(); + + MeshType::Pointer mesh = converter->GetOutput(); + + typedef itk::VTKPolyDataWriter< MeshType > WriterType; + WriterType::Pointer writer = WriterType::New(); + writer->SetInput( mesh ); + writer->SetFileName( "ConvertVTKtoITKMesh.vtk" ); + writer->Update(); + + return EXIT_SUCCESS; +} diff --git a/Examples/GUI/lib/CMakeLists.txt b/Examples/GUI/lib/CMakeLists.txt index 7dae1097..a82a17eb 100644 --- a/Examples/GUI/lib/CMakeLists.txt +++ b/Examples/GUI/lib/CMakeLists.txt @@ -8,7 +8,6 @@ SET( QGOGUILIB_EXAMPLE_SRC qgotabimageview2d qgotabimageview3d qgotabimageview3dwt - qgotabimageview4d qgomanualsegmentationsettingsdialog qgonavigationdockwidget QGoContourManualSegmentationDockWidgetTest @@ -27,9 +26,13 @@ SET( QGOGUILIB_EXAMPLE_SRC QGoDBInitCreateAuthorPageTest QGoDBInitCreateMicroscopePageTest QGoColorComboBoxTest + QGoSegmentationAlgoTest #QGoTrackEditingWidgetTest - QGoTraceEditingWidgetTest - QGoAlgorithmsWidgetTest +# QGoTraceEditingWidgetTest +# QGoAlgorithmsManagerWidgetTest +# QGoAlgorithmWidgetTest +# QGoModesManagerWidgetTest +# QGoMeshEditingWidgetManagerTest ) IF( BUILD_COMPARETOOL ) @@ -217,6 +220,11 @@ ADD_TEST( QGoDBInitCreateMicroscopePageTest 1 ) +ADD_TEST( QGoSegmentationAlgoTest + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoSegmentationAlgoTest + ${TESTING_DATA_PATH}/Circle3D.mhd + 1 +) #ADD_TEST( QGoTrackEditingWidgetTest # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/QGoTrackEditingWidgetTest diff --git a/Examples/GUI/lib/QGoTraceManualEditingWidgetTest.cxx b/Examples/GUI/lib/QGoAlgorithmWidgetTest.cxx similarity index 65% rename from Examples/GUI/lib/QGoTraceManualEditingWidgetTest.cxx rename to Examples/GUI/lib/QGoAlgorithmWidgetTest.cxx index 21e671c7..1bec3f81 100644 --- a/Examples/GUI/lib/QGoTraceManualEditingWidgetTest.cxx +++ b/Examples/GUI/lib/QGoAlgorithmWidgetTest.cxx @@ -31,36 +31,54 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ - #include #include +#include +#include "QGoAlgorithmWidget.h" + + + -#include "QGoTraceSettingsWidget.h" +//**************************************************************************// +// MAIN // +//**************************************************************************// int main(int argc, char *argv[]) { + if ( argc != 1 ) + { + return EXIT_FAILURE; + } + QApplication app(argc, argv); + QTimer * timer = new QTimer; + timer->setSingleShot(true); - QGoTraceSettingsWidget *win = new QGoTraceSettingsWidget(); + QGoAlgorithmWidget* AlgoWidget = new QGoAlgorithmWidget("Test", NULL); + QStringList ChannelName; + ChannelName.append("Channel 1"); + ChannelName.append("Channel 2"); + ChannelName.append("All Channels"); + AlgoWidget->AddParameter("Channel", ChannelName); + AlgoWidget->AddParameter("IntParam", 0, 100, 50); + AlgoWidget->AddParameter("DoubleParam", 20.56, 53.21, 24, 2); + AlgoWidget->AddAdvParameter("IntParam", 20, 50, 40); + AlgoWidget->AddAdvParameter("DoubleParam", 11, 23.00, 15, 3); - //QTimer* timer = new QTimer; - //timer->setSingleShot( true ); - //QObject::connect( timer, SIGNAL( timeout() ), win, SLOT( close() ) ); - win->show(); + //QObject::connect( timer, SIGNAL( timeout() ), AlgoWidget, SLOT( close() ) ); -// if( atoi( argv[1] ) == 1 ) -// { -// timer->start( 1000 ); -// } + AlgoWidget->show(); + timer->start(1000); - app.processEvents(); + app.processEvents(); int output = app.exec(); app.closeAllWindows(); -// delete timer; - delete win; + + delete timer; + delete AlgoWidget; return output; -} \ No newline at end of file +} diff --git a/Examples/GUI/lib/QGoAlgorithmsManagerWidgetTest.cxx b/Examples/GUI/lib/QGoAlgorithmsManagerWidgetTest.cxx new file mode 100644 index 00000000..6028bd78 --- /dev/null +++ b/Examples/GUI/lib/QGoAlgorithmsManagerWidgetTest.cxx @@ -0,0 +1,112 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009 + + Copyright (c) 2009, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include +#include +#include + +#include "QGoAlgorithmsManagerWidget.h" +#include "QGoAlgorithmWidget.h" + + + + +//**************************************************************************// +// MAIN // +//**************************************************************************// + +int main(int argc, char *argv[]) +{ + if ( argc != 1 ) + { + return EXIT_FAILURE; + } + + QApplication app(argc, argv); + QTimer * timer = new QTimer; + timer->setSingleShot(true); + + QGoAlgorithmsManagerWidget* SemiAutoModeMeshEditingAlgoWidget = new QGoAlgorithmsManagerWidget("SemiAutomatedWidget", NULL); + + QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", SemiAutoModeMeshEditingAlgoWidget); + QStringList ChannelName; + ChannelName.append("Channel 1"); + ChannelName.append("Channel 2"); + LevelSetWidget->AddParameter("Channel", ChannelName); + LevelSetWidget->AddParameter("Radius", 0, 10, 3); + LevelSetWidget->AddAdvParameter("Curvature", 0, 100, 20); + LevelSetWidget->AddAdvParameter("Iterations", 0, 1000, 100); + + + QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", SemiAutoModeMeshEditingAlgoWidget); + Shape3D->AddParameter("Channel", ChannelName); + Shape3D->AddParameter("Radius", 0, 10, 3); + + QStringList ShapeList; + ShapeList.append("Sphere"); + ShapeList.append("Cube"); + + Shape3D->AddAdvParameter("Shape", ShapeList); + + QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", SemiAutoModeMeshEditingAlgoWidget); + WaterShedWidget->AddParameter("Channel", ChannelName); + WaterShedWidget->AddParameter("Radius", 0, 10, 3); + WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 10, 20); + WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 30, 50); + WaterShedWidget->AddAdvParameter("Corr.Thres.", 0, 5, 2, 2); + WaterShedWidget->AddAdvParameter("Alpha", 0, 5, 1.50, 2); + WaterShedWidget->AddAdvParameter("Beta", 0, 5, 3, 1); + + SemiAutoModeMeshEditingAlgoWidget->AddMethod(LevelSetWidget); + SemiAutoModeMeshEditingAlgoWidget->AddMethod(WaterShedWidget); + SemiAutoModeMeshEditingAlgoWidget->AddMethod(Shape3D); + + SemiAutoModeMeshEditingAlgoWidget->SetCurrentIndex(0); + + QObject::connect( timer, SIGNAL( timeout() ), SemiAutoModeMeshEditingAlgoWidget, SLOT( close() ) ); + + + timer->start(1000); + + SemiAutoModeMeshEditingAlgoWidget->show(); + + app.processEvents(); + int output = app.exec(); + + app.closeAllWindows(); + + delete timer; + delete SemiAutoModeMeshEditingAlgoWidget; + + return output; +} diff --git a/Examples/GUI/lib/QGoLevelset2DTest.cxx b/Examples/GUI/lib/QGoLevelset2DTest.cxx index 4fa8fb5b..c94867c5 100644 --- a/Examples/GUI/lib/QGoLevelset2DTest.cxx +++ b/Examples/GUI/lib/QGoLevelset2DTest.cxx @@ -71,9 +71,9 @@ int main(int argc, char **argv) std::vector< vtkSmartPointer< vtkImageData > > imagesVector(1); imagesVector[0] = castFilter->GetOutput(); levelSet2DFilter->setOriginalImageMC(&imagesVector); - levelSet2DFilter->setIterations(50); - levelSet2DFilter->setRadius(2); - levelSet2DFilter->setCurvature(10); +// levelSet2DFilter->setIterations(50); +// levelSet2DFilter->setRadius(2); +// levelSet2DFilter->setCurvature(10); double seedPos[3]; seedPos[0] = 5; @@ -102,4 +102,4 @@ int main(int argc, char **argv) seeds->Delete(); return oResult; -} \ No newline at end of file +} diff --git a/Examples/GUI/lib/QGoAlgorithmsWidgetTest.cxx b/Examples/GUI/lib/QGoMeshEditingWidgetManagerTest.cxx similarity index 68% rename from Examples/GUI/lib/QGoAlgorithmsWidgetTest.cxx rename to Examples/GUI/lib/QGoMeshEditingWidgetManagerTest.cxx index 93877706..0e88c6b9 100644 --- a/Examples/GUI/lib/QGoAlgorithmsWidgetTest.cxx +++ b/Examples/GUI/lib/QGoMeshEditingWidgetManagerTest.cxx @@ -33,14 +33,16 @@ =========================================================================*/ #include #include - -#include "QGoAlgorithmsWidget.h" -#include "QGoSeedBaseWidget.h" -#include "QGoContourSemiAutoLevelsetWidget.h" -#include "QGoContourSemiAutoWatershedWidget.h" - - - +#include +#include "QGoMeshEditingWidgetManager.h" +#include "QGoTraceSettingsWidget.h" +#include "QGoModesManagerWidget.h" +#include "QGoAlgorithmWidget.h" +#include "QGoTraceSettingsWidget.h" +#include "QGoAlgoParameter.h" +#include "vtkSmartPointer.h" +#include "vtkPolyData.h" +#include "vtkImageData.h" //**************************************************************************// // MAIN // @@ -56,36 +58,33 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); //QTimer * timer = new QTimer; //timer->setSingleShot(true); - //QStringList ListFilters; - //ListFilters.append("Shape"); - //ListFilters.append("LevelSet"); - //ListFilters.append("WaterShed"); - - QGoAlgorithmsWidget* SemiAutoModeMeshEditingAlgoWidget = new QGoAlgorithmsWidget(NULL); - QGoSeedBaseWidget* SemiAutoModeParamWidget = new QGoSeedBaseWidget(SemiAutoModeMeshEditingAlgoWidget); - QGoSeedBaseWidget* SemiAutoModeParamWidgetTwo = new QGoSeedBaseWidget(SemiAutoModeMeshEditingAlgoWidget); + std::vector ChannelName; + ChannelName.push_back("Channel 1"); + ChannelName.push_back("Channel 2"); + QStringList ListTimePoint; + ListTimePoint.append("t-1"); + ListTimePoint.append("t"); + ListTimePoint.append("t+1"); + vtkPoints* Seeds = NULL; + + std::vector< vtkSmartPointer< vtkImageData > >* Images = NULL; + QGoMeshEditingWidgetManager* MeshEditing = new QGoMeshEditingWidgetManager(ChannelName, ListTimePoint, + Seeds, Images, NULL); - QGoContourSemiAutoLevelsetWidget* LevelSetParam = new QGoContourSemiAutoLevelsetWidget(SemiAutoModeMeshEditingAlgoWidget); - QGoContourSemiAutoWatershedWidget* WaterShedParam = new QGoContourSemiAutoWatershedWidget(SemiAutoModeMeshEditingAlgoWidget); - - SemiAutoModeMeshEditingAlgoWidget->AddMethod("LevelSet 3D", SemiAutoModeParamWidget, LevelSetParam); - SemiAutoModeMeshEditingAlgoWidget->AddMethod("WaterShed 3D", SemiAutoModeParamWidgetTwo, WaterShedParam); - //QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); - - //timer->start(1000); - SemiAutoModeMeshEditingAlgoWidget->show(); + MeshEditing->showWidget(); app.processEvents(); int output = app.exec(); + app.closeAllWindows(); //delete timer; - delete SemiAutoModeMeshEditingAlgoWidget; + delete MeshEditing; return output; } diff --git a/Examples/GUI/lib/QGoModesManagerWidgetTest.cxx b/Examples/GUI/lib/QGoModesManagerWidgetTest.cxx new file mode 100644 index 00000000..9c92f074 --- /dev/null +++ b/Examples/GUI/lib/QGoModesManagerWidgetTest.cxx @@ -0,0 +1,150 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009 + + Copyright (c) 2009, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ +#include +#include +#include + +#include "QGoModesManagerWidget.h" +#include "QGoAlgorithmWidget.h" +#include "QGoAlgoParameter.h" + + + + +//**************************************************************************// +// MAIN // +//**************************************************************************// + +int main(int argc, char *argv[]) +{ + if ( argc != 1 ) + { + return EXIT_FAILURE; + } + + QApplication app(argc, argv); + //QTimer * timer = new QTimer; + //timer->setSingleShot(true); + + QStringList ChannelName; + ChannelName.append("Channel 1"); + ChannelName.append("Channel 2"); + QStringList ListTimePoint; + ListTimePoint.append("t-1"); + ListTimePoint.append("t"); + ListTimePoint.append("t+1"); + + QGoModesManagerWidget* MeshMode = new QGoModesManagerWidget(ChannelName, ListTimePoint, NULL); + + + //QGoAlgorithmsManagerWidget* SemiAutoModeMeshEditingAlgoWidget = new QGoAlgorithmsManagerWidget( + // "Semi Automated",ChannelName, ListTimePoint, NULL); + QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", MeshMode); + //SemiAutoModeMeshEditingAlgoWidget); + + QGoAlgoParameter Radius ("Radius", false, 0, 10, 2, 3); + LevelSetWidget->AddParameter(&Radius); + QGoAlgoParameter Curvature ("Curvature", true, 0, 100, 20); + LevelSetWidget->AddParameter(&Curvature); + QGoAlgoParameter Iteration ("Iterations", true, 0, 1000, 100); + LevelSetWidget->AddParameter(&Iteration); + + //LevelSetWidget->AddParameter("Channel", ChannelName); + //LevelSetWidget->AddParameter("Radius", 0, 10, 3); + //LevelSetWidget->AddAdvParameter("Curvature", 0, 100, 20); + //LevelSetWidget->AddAdvParameter("Iterations", 0, 1000, 100); + + QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", MeshMode);//SemiAutoModeMeshEditingAlgoWidget); + //Shape3D->AddParameter("Channel", ChannelName); + //Shape3D->AddParameter("Radius", 0, 10, 3); + Shape3D->AddParameter(&Radius); + QStringList ShapeList; + ShapeList.append("Sphere"); + ShapeList.append("Cube"); + QGoAlgoParameter Shape("Shape",true, ShapeList, "Sphere"); + //Shape3D->AddAdvParameter("Shape", ShapeList); + Shape3D->AddParameter(&Shape); + + QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", MeshMode);//SemiAutoModeMeshEditingAlgoWidget); + //WaterShedWidget->AddParameter("Channel", ChannelName); + //WaterShedWidget->AddParameter("Radius", 0, 10, 3); + WaterShedWidget->AddParameter(&Radius); + QGoAlgoParameter ThresMin ("Thres.Min.", true, 0, 100, 20); + WaterShedWidget->AddParameter(&ThresMin); + //WaterShedWidget->AddAdvParameter ("Thres.Min.", 0, 100, 20); + QGoAlgoParameter ThresMax ("Thres.Max.", true, 0, 30, 50); + WaterShedWidget->AddParameter(&ThresMax); + // WaterShedWidget->AddAdvParameter("Thres.Min.", 0, 30, 50); + QGoAlgoParameter CorrThres ("Corr.Thres.", true, 0, 5, 2, 2); + WaterShedWidget->AddParameter(&CorrThres); + //WaterShedWidget->AddAdvParameter("Corr.Thres.", 0, 5, 2, 2); + QGoAlgoParameter Alpha ("Alpha", true, 0, 5, 1.50, 2); + WaterShedWidget->AddParameter(&Alpha); + //WaterShedWidget->AddAdvParameter("Alpha", 0, 5, 1.50, 2); + QGoAlgoParameter Beta ("Beta", true, 0, 5, 3, 1); + WaterShedWidget->AddParameter(&Beta); + //WaterShedWidget->AddAdvParameter("Beta", 0, 5, 3, 1); + + //SemiAutoModeMeshEditingAlgoWidget->AddMethod(LevelSetWidget); + //SemiAutoModeMeshEditingAlgoWidget->AddMethod(WaterShedWidget); + //SemiAutoModeMeshEditingAlgoWidget->AddMethod(Shape3D); + MeshMode->AddAlgoWidgetForSemiAutomatedMode(LevelSetWidget); + MeshMode->AddAlgoWidgetForSemiAutomatedMode(WaterShedWidget); + MeshMode->AddAlgoWidgetForSemiAutomatedMode(Shape3D); + + MeshMode->CheckDefaultModes(); + + + //MeshMode->AddAlgoManagerWidget(SemiAutoModeMeshEditingAlgoWidget); + //MeshMode->AddWidgetWithModeName("Test", SemiAutoModeMeshEditingAlgoWidget); + //SemiAutomatedMode->AddMethod(WaterShedWidget); + //SemiAutomatedMode->AddMethod(Shape3D); + //QObject::connect( timer, SIGNAL( timeout() ), SemiAutoModeMeshEditingAlgoWidget, SLOT( close() ) ); + + + //timer->start(1000); + + MeshMode->show(); + + app.processEvents(); + int output = app.exec(); + + app.closeAllWindows(); + + //delete timer; + // delete SemiAutoModeMeshEditingAlgoWidget; + delete MeshMode; + + return output; +} diff --git a/Examples/GUI/lib/QGoSegmentationAlgoTest.cxx b/Examples/GUI/lib/QGoSegmentationAlgoTest.cxx new file mode 100644 index 00000000..d2f24c27 --- /dev/null +++ b/Examples/GUI/lib/QGoSegmentationAlgoTest.cxx @@ -0,0 +1,210 @@ +/*========================================================================= + Authors: The GoFigure Dev. Team. + at Megason Lab, Systems biology, Harvard Medical school, 2009 + + Copyright (c) 2009, President and Fellows of Harvard College. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + Neither the name of the President and Fellows of Harvard College + nor the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================*/ + +#include + +#include "vtkSmartPointer.h" + +#include "vtkMetaImageReader.h" +#include "itkImage.h" + + +// helper for debugging +#include "VisualizePolydataHelper.h" + +//converter to be tested +#include "QGoMeshLevelSetAlgo.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + if ( argc != 3 ) + { + std::cout << "Usage : QGoSynchronizedView2DTest(.exe) " << std::endl; + std::cout << "1-file.mhd" << std::endl; + std::cout << "2-test (boolean)" << std::endl; + return EXIT_FAILURE; + } + + vtkSmartPointer< vtkMetaImageReader > reader = + vtkSmartPointer< vtkMetaImageReader >::New(); + reader->SetFileName( argv[1] ); + reader->Update(); + + std::cout << "Data Range: " << reader->GetOutput()->GetScalarRange()[0] + << " to " << reader->GetOutput()->GetScalarRange()[1] + << std::endl; + std::cout << "Data Dimensions: " << reader->GetOutput()->GetDimensions()[0] + << " x " << reader->GetOutput()->GetDimensions()[1] + << " x " << reader->GetOutput()->GetDimensions()[2] + < ImageType; + typedef ImageType::Pointer ImageTypePointer; + + + //------------------------------------------------------------------ + // 3d + //------------------------------------------------------------------ + // extract roi + std::vector< double > voi3D(6); + voi3D[0] = 10; + voi3D[1] = 20; + voi3D[2] = 10; + voi3D[3] = 20; + voi3D[4] = 10; + voi3D[5] = 20; + + vtkSmartPointer roi3D = vtkSmartPointer::New(); + roi3D->ShallowCopy( algo.VTKExtractROI( voi3D, reader->GetOutput() )); + + assert( roi3D->GetDataDimension() == 3); + + // convert vtk to itk + ImageTypePointer + itkImage3D = algo.ConvertVTK2ITK< PixelType, dimension >(roi3D); + + // convert itk to vtk + vtkSmartPointer vtkImage3D = vtkSmartPointer::New(); + vtkImage3D->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage3D)); + vtkImage3D->Update(); + + std::cout << "Dimension 3D: " << vtkImage3D->GetDataDimension() <GetDimensions()[0] + << " x " << vtkImage3D->GetDimensions()[1] + << " x " << vtkImage3D->GetDimensions()[2] + <GetDataDimension() == 3); + + // Reconstruct polydata + vtkSmartPointer poly3D = vtkSmartPointer::New(); + poly3D->ShallowCopy(algo.ExtractPolyData( vtkImage3D, 100 )); + ShowPolyData(poly3D); + + //------------------------------------------------------------------ + // 3d - too large ROI + //------------------------------------------------------------------ + // extract roi + std::vector< double > voi3D2Large(6); + voi3D2Large[0] = 0; + voi3D2Large[1] = 30; + voi3D2Large[2] = 0; + voi3D2Large[3] = 50; + voi3D2Large[4] = 0; + voi3D2Large[5] = 50; + + vtkSmartPointer roi3D2Large = vtkSmartPointer::New(); + roi3D2Large->ShallowCopy(algo.VTKExtractROI( voi3D2Large, reader->GetOutput() )); + + assert( roi3D2Large->GetDataDimension() == 3); + + // convert vtk to itk + ImageTypePointer + itkImage3D2Large = algo.ConvertVTK2ITK< PixelType, dimension >(roi3D2Large); + + // convert itk to vtk + vtkSmartPointer vtkImage3D2Large = vtkSmartPointer::New(); + vtkImage3D2Large->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage3D2Large)); + vtkImage3D2Large->Update(); + + std::cout << "Dimension 3D Too Large: " << vtkImage3D2Large->GetDataDimension() <GetDimensions()[0] + << " x " << vtkImage3D2Large->GetDimensions()[1] + << " x " << vtkImage3D2Large->GetDimensions()[2] + <GetDataDimension() == 3); + + // Reconstruct polydata + vtkSmartPointer poly3D2Large = vtkSmartPointer::New(); + poly3D2Large->ShallowCopy(algo.ExtractPolyData( vtkImage3D2Large, 100 )); + ShowPolyData(poly3D2Large); + + // Decimate polydata + vtkSmartPointer decimate3D = vtkSmartPointer::New(); + decimate3D->ShallowCopy(algo.DecimatePolyData(poly3D2Large, 200)); + ShowPolyData(decimate3D); + + //------------------------------------------------------------------ + // 2d + //------------------------------------------------------------------ + // extract roi + std::vector< double > voi2D(6); + voi2D[0] = 15; + voi2D[1] = 15; + voi2D[2] = 0; + voi2D[3] = 30; + voi2D[4] = 0; + voi2D[5] = 30; + + vtkSmartPointer roi2D = vtkSmartPointer::New(); + roi2D->ShallowCopy(algo.VTKExtractROI( voi2D, reader->GetOutput() )); + + assert( roi2D->GetDataDimension() == 2); + + // convert vtk to itk + ImageTypePointer + itkImage2D = algo.ConvertVTK2ITK< PixelType, dimension >(roi2D); + + // convert itk to vtk + vtkSmartPointer vtkImage2D = vtkSmartPointer::New(); + vtkImage2D->ShallowCopy(algo.ConvertITK2VTK< PixelType, dimension >(itkImage2D)); + vtkImage2D->Update(); + + std::cout << "Dimension 2D: " << vtkImage2D->GetDataDimension() <GetDimensions()[0] + << " x " << vtkImage2D->GetDimensions()[1] + << " x " << vtkImage2D->GetDimensions()[2] + <GetDataDimension() == 2); + + // Reconstruct polydata + vtkSmartPointer poly2D = vtkSmartPointer::New(); + poly2D->ShallowCopy(algo.ExtractPolyData( vtkImage2D, 100 )); + ShowPolyData(poly2D); + + vtkSmartPointer decimate2D = vtkSmartPointer::New(); + decimate2D->ShallowCopy(algo.DecimatePolyData(poly2D, 10)); + + ShowPolyData(decimate2D); + + return EXIT_SUCCESS; +} diff --git a/Examples/GUI/lib/QGoTraceEditingWidgetTest.cxx b/Examples/GUI/lib/QGoTraceEditingWidgetTest.cxx index 84dd67d9..f8395e0a 100644 --- a/Examples/GUI/lib/QGoTraceEditingWidgetTest.cxx +++ b/Examples/GUI/lib/QGoTraceEditingWidgetTest.cxx @@ -33,20 +33,13 @@ =========================================================================*/ #include #include - +#include #include "QGoTraceEditingWidget.h" #include "QGoTraceSettingsWidget.h" -#include "QGoSeedBaseWidget.h" -#include "QGoContourManualSegmentationWidget.h" -#include "QGoContourSemiAutoLevelsetWidget.h" -#include "QGoContourSemiAutoWatershedWidget.h" -#include "QGoAdvancedParametersWidget.h" - -#include "QGoContourManualSegmentationWidget.h" -#include "QGoAlgorithmsWidget.h" -#include "QGoContourSemiAutoShapeWidget.h" - - +#include "QGoModesManagerWidget.h" +#include "QGoAlgorithmWidget.h" +#include "QGoTraceSettingsWidget.h" +#include "QGoAlgoParameter.h" //**************************************************************************// // MAIN // @@ -62,46 +55,81 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); //QTimer * timer = new QTimer; //timer->setSingleShot(true); - //QStringList ListFilters; - //ListFilters.append("Shape"); - //ListFilters.append("LevelSet"); - //ListFilters.append("WaterShed"); - QGoTraceEditingWidget* MeshEditing = new QGoTraceEditingWidget("Mesh", NULL); + QStringList ChannelName; + ChannelName.append("Channel 1"); + ChannelName.append("Channel 2"); + QStringList ListTimePoint; + ListTimePoint.append("t-1"); + ListTimePoint.append("t"); + ListTimePoint.append("t+1"); - //semi automated mode - QGoAlgorithmsWidget* SemiAutomatedMethodsWidget = new QGoAlgorithmsWidget(MeshEditing); + QGoTraceEditingWidget* MeshEditing = new QGoTraceEditingWidget( + "Mesh", ChannelName, ListTimePoint, NULL); - QGoSeedBaseWidget* LevelSetParamWidget = new QGoSeedBaseWidget(MeshEditing); - QGoContourSemiAutoLevelsetWidget* LevelSetAdvParamWidget = new QGoContourSemiAutoLevelsetWidget(MeshEditing); - SemiAutomatedMethodsWidget->AddMethod("Level Set 3D", LevelSetParamWidget, LevelSetAdvParamWidget); + //semi automated mode + + //QGoAlgorithmsManagerWidget* SemiAutomatedMethodsWidget = new QGoAlgorithmsManagerWidget("Semi Automated", + // ChannelName, ListTimePoint, MeshEditing); - QGoSeedBaseWidget* WaterShedParamWidget = new QGoSeedBaseWidget(MeshEditing); - QGoContourSemiAutoWatershedWidget* WaterShedAdvParamWidget = new QGoContourSemiAutoWatershedWidget(MeshEditing); - SemiAutomatedMethodsWidget->AddMethod("WaterShed 3D", WaterShedParamWidget, WaterShedAdvParamWidget); + //levelSet + QGoAlgorithmWidget* LevelSetWidget = new QGoAlgorithmWidget("LevelSet", MeshEditing);//SemiAutomatedMethodsWidget); - //manual mode - QGoAlgorithmsWidget* ManualMethodsWidget = new QGoAlgorithmsWidget(MeshEditing); - - QGoSeedBaseWidget* ParamMeshToContours = new QGoSeedBaseWidget(MeshEditing); - QGoContourSemiAutoShapeWidget* AdvParamMeshToContours = new QGoContourSemiAutoShapeWidget(MeshEditing); - ManualMethodsWidget->AddMethod("2D Shapes in 1 mesh", ParamMeshToContours, AdvParamMeshToContours); - - QGoSeedBaseWidget* ParamMeshToContoursLevelSet = new QGoSeedBaseWidget(MeshEditing); - QGoContourSemiAutoLevelsetWidget* AdvParamMeshToContoursLevelSet = new QGoContourSemiAutoLevelsetWidget(MeshEditing); - ManualMethodsWidget->AddMethod("2D Levelset in 1 mesh", ParamMeshToContoursLevelSet, AdvParamMeshToContoursLevelSet); - - QGoSeedBaseWidget* ParamMeshToContoursWaterShed = new QGoSeedBaseWidget(MeshEditing); - QGoContourSemiAutoWatershedWidget* AdvParamMeshToContoursWaterShed = new QGoContourSemiAutoWatershedWidget(MeshEditing); - ManualMethodsWidget->AddMethod("2D WaterShed within 1 mesh", ParamMeshToContoursWaterShed, AdvParamMeshToContoursWaterShed); - + //def of the parameters: + QGoAlgoParameter Radius ("Radius", false, 0, 10, 3); + QGoAlgoParameter Curvature ("Curvature", true, 0, 100, 20); + QGoAlgoParameter Iteration ("Iterations", true,0, 1000, 100); + + LevelSetWidget->AddParameter(&Radius); + LevelSetWidget->AddParameter(&Curvature); + LevelSetWidget->AddParameter(&Iteration); + + //Shape3D + QGoAlgorithmWidget* Shape3D = new QGoAlgorithmWidget("Shape 3D", MeshEditing);//SemiAutomatedMethodsWidget); + + Shape3D->AddParameter(&Radius); + QStringList ShapeList; + ShapeList.append("Sphere"); + ShapeList.append("Cube"); + QGoAlgoParameter Shape("Shape", true, ShapeList, "Sphere"); + Shape3D->AddParameter(&Shape); + + //watershed + QGoAlgorithmWidget* WaterShedWidget = new QGoAlgorithmWidget("WaterShed", MeshEditing);//SemiAutomatedMethodsWidget); + + WaterShedWidget->AddParameter(&Radius); + QGoAlgoParameter ThresMin("Thres.Min.", true, 0, 10, 20); + + WaterShedWidget->AddParameter(&ThresMin); + QGoAlgoParameter ThresMax("Thres.Max.", true, 0, 50, 30); + WaterShedWidget->AddParameter(&ThresMax); + + QGoAlgoParameter CorrThres("Corr.Thres.", true, 0, 5, 2, 2); + WaterShedWidget->AddParameter(&CorrThres); + + QGoAlgoParameter Alpha("Alpha", true, 0, 5, 2, 1.5); + WaterShedWidget->AddParameter(&Alpha); + + QGoAlgoParameter Beta("Beta", true, 0, 5, 1, 3); + WaterShedWidget->AddParameter(&Beta); + + //SemiAutomatedMethodsWidget->AddMethod(LevelSetWidget); + //SemiAutomatedMethodsWidget->AddMethod(WaterShedWidget); + //SemiAutomatedMethodsWidget->AddMethod(Shape3D); + MeshEditing->AddAlgoWidgetForSemiAutomatedMode(LevelSetWidget); + MeshEditing->AddAlgoWidgetForSemiAutomatedMode(WaterShedWidget); + MeshEditing->AddAlgoWidgetForSemiAutomatedMode(Shape3D); + + //QGoModesManagerWidget* SemiAutomatedMode = new QGoModesManagerWidget(NULL); + //SemiAutomatedMode->AddAlgoManagerWidget(SemiAutomatedMethodsWidget); - MeshEditing->AddMode("Manual", ManualMethodsWidget); - MeshEditing->AddMode("Semi Automated", SemiAutomatedMethodsWidget); + //MeshEditing->SetModesManager(SemiAutomatedMode); + //add mode: + QGoTraceSettingsWidget* TestAddMode = new QGoTraceSettingsWidget(MeshEditing); + MeshEditing->AddMode("TestAddMode", TestAddMode); + MeshEditing->CheckDefaultModes(); //QObject::connect( timer, SIGNAL( timeout() ), window, SLOT( close() ) ); - - //timer->start(1000); MeshEditing->show(); @@ -109,6 +137,9 @@ int main(int argc, char *argv[]) app.processEvents(); int output = app.exec(); + std::cout<< "Alpha "<< Alpha.GetValue()<EnableBoxWidget(true); viewer->EnableBoxWidget(false); - vtkPoints *points = viewer->GetAllSeeds(); - points->Delete(); - viewer->ClearAllSeeds(); + //vtkPoints *points = viewer->GetAllSeeds(); + //points->Delete(); + //viewer->ClearAllSeeds(); if ( atoi(argv[2]) == 1 ) { diff --git a/Main/QGoMainWindow.cxx b/Main/QGoMainWindow.cxx index 4c4b7ad7..a7dbb7c8 100644 --- a/Main/QGoMainWindow.cxx +++ b/Main/QGoMainWindow.cxx @@ -87,8 +87,8 @@ //-------------------------------------------------------------------------- QGoMainWindow::QGoMainWindow(QWidget *iParent, Qt::WindowFlags iFlags) : - QMainWindow(iParent, iFlags), m_ModeToolBar(NULL), m_TracesToolBar(NULL), - m_TraceSettingsToolBar(NULL), m_ViewToolBar(NULL) + QMainWindow(iParent, iFlags), m_ViewToolBar(NULL), m_ModeToolBar(NULL), + m_TracesToolBar(NULL), m_TraceSettingsToolBar(NULL) { QString title("<*)0|00|0>< ~~ <*)0|00|0>< GoFigure ><0|00|0(*> ~~ ><0|00|0(*>"); @@ -184,7 +184,12 @@ QGoMainWindow::QGoMainWindow(QWidget *iParent, Qt::WindowFlags iFlags) : //-------------------------------------------------------------------------- QGoMainWindow::~QGoMainWindow() { -// m_LSMReader->Delete(); + // clear will call destructor on all of the element in the list + // what is the point of the list? + if(this->m_LSMReader.back()) + { + this->m_LSMReader.back()->Delete(); + } this->WriteSettings(); delete m_TabManager; delete m_DBWizard; @@ -521,6 +526,7 @@ QGoMainWindow::LoadMeshesFromDatabase(const int & iT) w3t->m_DataBaseTables->PrintVolumeAreaForMesh( &attributes, mesh_list_it->TraceID); } + w3t->AddMeshFromNodes< TraceID >(mesh_list_it); progress.setValue( i ); diff --git a/Main/gofigure.cxx.in b/Main/gofigure.cxx.in index 454a65ab..5c86cf30 100644 --- a/Main/gofigure.cxx.in +++ b/Main/gofigure.cxx.in @@ -112,4 +112,4 @@ int main(int argc, char **argv) delete form; return output; -} \ No newline at end of file +} diff --git a/QGoTraceSettingsWidget.cxx b/QGoTraceSettingsWidget.cxx deleted file mode 100644 index 2db65bb9..00000000 --- a/QGoTraceSettingsWidget.cxx +++ /dev/null @@ -1,557 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#include "QGoTraceSettingsDockWidget.h" - -#include -#include -#include -#include - -#include - -QGoTraceSettingsDockWidget::QGoTraceSettingsDockWidget(QWidget *iParent) : - //QDockWidget(iParent) - QWidget(iParent) -{ - this->SetUpUi(); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -QGoTraceSettingsDockWidget:: -~QGoTraceSettingsDockWidget() -{ - if ( this->m_SelectedCollectionData ) - { - delete this->m_SelectedCollectionData; - } - if ( this->m_SelectedCellType ) - { - delete this->m_SelectedCellType; - } - if ( this->m_SelectedSubCellType ) - { - delete this->m_SelectedSubCellType; - } - if ( this->m_SelectedColorData ) - { - delete this->m_SelectedColorData; - } -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetUpUi() -{ - QWidget* TraceSettingsWidget = new QWidget(this); - - QHBoxLayout* ColorLayout = new QHBoxLayout; - SetSelectedColorComboBox(ColorLayout); - QHBoxLayout* TraceLayout = new QHBoxLayout; - - QHBoxLayout* TraceCollectionLayout = new QHBoxLayout; - SetTraceCollectionColorComboBox(TraceCollectionLayout); - - QHBoxLayout* CellTypeLayout = new QHBoxLayout; - SetCellTypeComboBox(CellTypeLayout); - - QHBoxLayout* SubCellLayout = new QHBoxLayout; - SetSubCellTypeComboBox(SubCellLayout); - - QHBoxLayout* MainLayout = new QHBoxLayout; - QLabel* Blank = new QLabel(this); - MainLayout->addLayout(TraceCollectionLayout); - MainLayout->addWidget(Blank); - MainLayout->addLayout(ColorLayout); - MainLayout->addWidget(Blank); - MainLayout->addLayout(CellTypeLayout); - MainLayout->addLayout(SubCellLayout); - - this->SetWidgetFont(); - this->UpdateTraceAndCollection("contour", "mesh"); - - this->setLayout(MainLayout); - this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetListCollectionID( - std::list< ItemColorComboboxData > iListExistingID, - std::string iCollectionIDtoSelect) -{ - if ( !iCollectionIDtoSelect.empty() ) - { - this->m_CollectionColorComboBox->SetItemsFromListWithColor( iListExistingID, - this->m_CollectionName->text().toStdString() ); - this->m_CollectionColorComboBox->SetCurrentItemAndActivate(iCollectionIDtoSelect); - } - else - { - this->m_CollectionColorComboBox->InitializeTheListWithColor( iListExistingID, - this->m_CollectionName->text().toStdString() ); - } -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetListColors( - std::list< ItemColorComboboxData > iListColors, std::string iColorToSelect) -{ - this->SetListItemAndSelect< QGoSelectedColorComboBox >(this->m_SelectedColorComboBox, - iListColors, iColorToSelect); - this->m_SelectedColorComboBox->SetCurrentItemAndActivate(iColorToSelect); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetListColorsWithSelectedOne( - std::list< ItemColorComboboxData > iListColors) -{ - this->SetListColors(iListColors, this->m_SelectedColorData->first); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetListCellTypes(NamesDescrContainerType iCellTypesData, - std::string iCellTypeToSelect) -{ - this->SetListItemAndSelect< QGoComboBox >(this->m_ChoseCellType, - iCellTypesData, iCellTypeToSelect); - this->m_ChoseCellType->SetCurrentItemAndActivate(iCellTypeToSelect); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetListCellTypeWithSelectedOne( - NamesDescrContainerType iCellTypesData) -{ - this->SetListCellTypes(iCellTypesData, *this->m_SelectedCellType); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetListSubCellTypes(NamesDescrContainerType iSubCellTypesData, - std::string iSubCellTypeToSelect) -{ - this->SetListItemAndSelect< QGoComboBox >(this->m_ChoseSubCellType, - iSubCellTypesData, iSubCellTypeToSelect); - this->m_ChoseSubCellType->SetCurrentItemAndActivate(iSubCellTypeToSelect); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetListSubCellTypeWithSelectedOne( - NamesDescrContainerType iSubCellTypesData) -{ - this->SetListSubCellTypes(iSubCellTypesData, *this->m_SelectedSubCellType); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetSelectedColorComboBox( - QHBoxLayout* iColorLayout) -{ - this->m_SelectedColorComboBox = new QGoSelectedColorComboBox; - QLabel* ColorLbl = new QLabel(tr("Color:"), this); - iColorLayout->addWidget(ColorLbl); - iColorLayout->addWidget(this->m_SelectedColorComboBox); - - this->m_SelectedColorData = new ItemColorComboboxData; - - QObject::connect( this->m_SelectedColorComboBox, - SIGNAL( ItemSelected(ItemColorComboboxData) ), - this, SLOT( UpdateValueSelectedColor(ItemColorComboboxData) ) ); - - QObject::connect( this->m_SelectedColorComboBox, - SIGNAL( AddNewColorActivated() ), - this, SIGNAL( AddNewColor() ) ); - - QObject::connect( this->m_SelectedColorComboBox, - SIGNAL( DeleteActivated() ), - this, SIGNAL( DeleteColor() ) ); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetTraceCollectionColorComboBox( - QHBoxLayout* iLayoutTraceCollection) -{ - this->m_TraceName = new QLabel(this); - QHBoxLayout *HLayoutForTrace = new QHBoxLayout; - - this->m_TraceLbl = new QLabel(tr("Trace:"), this); - HLayoutForTrace->addWidget(this->m_TraceLbl); - HLayoutForTrace->addWidget(this->m_TraceName); - this->m_CollectionLbl = new QLabel( tr("Collection:") ); - this->m_CollectionColorComboBox = new QGoCollectionColorComboBox; - this->m_CollectionName = new QLabel ( tr("mesh") ); - - QHBoxLayout *HLayoutForCollection = new QHBoxLayout; - HLayoutForCollection->addWidget(this->m_CollectionName); - HLayoutForCollection->addWidget(this->m_CollectionColorComboBox); - iLayoutTraceCollection->addLayout(HLayoutForTrace); - iLayoutTraceCollection->addWidget(this->m_CollectionLbl); - iLayoutTraceCollection->addLayout(HLayoutForCollection); - - this->m_SelectedCollectionData = new ItemColorComboboxData; - - QObject::connect( this->m_CollectionColorComboBox, - SIGNAL( ItemSelected(ItemColorComboboxData) ), - this, SLOT( UpdateValueSelectedCollection(ItemColorComboboxData) ) ); - - QObject::connect( this->m_CollectionColorComboBox, - SIGNAL( NewCollectionToCreate() ), - this, SIGNAL( NewCollectionToBeCreated() ) ); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetCellTypeComboBox( - QHBoxLayout* iCellLayout) -{ - this->m_ChoseCellType = new QGoComboBox("Add a new celltype...", - this, "Delete a celltype..."); - - QHBoxLayout *HLayoutForCellType = new QHBoxLayout; - this->m_LabelCellType = new QLabel(tr("CellType:"), this); - HLayoutForCellType->addWidget(this->m_LabelCellType); - HLayoutForCellType->addWidget(m_ChoseCellType); - - iCellLayout->addLayout(HLayoutForCellType); - - this->m_SelectedCellType = new std::string; - - QObject::connect( this->m_ChoseCellType, - SIGNAL( ItemSelected(std::string) ), - this, SLOT( UpdateValueSelectedCellType(std::string) ) ); - - QObject::connect( this->m_ChoseCellType, - SIGNAL( AddANewOneActivated() ), - this, SIGNAL( AddANewCellType() ) ); - - QObject::connect( this->m_ChoseCellType, - SIGNAL( DeleteActivated() ), - this, SIGNAL( DeleteCellType() ) ); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void -QGoTraceSettingsDockWidget::SetSubCellTypeComboBox( - QHBoxLayout* iSubCellLayout) -{ - this->m_ChoseSubCellType = new QGoComboBox("Add a new subcelltype...", this, - "Delete a subcelltype..."); - this->m_LabelSubCellType = new QLabel(tr("SubCellType:"), this); - iSubCellLayout->addWidget(this->m_LabelSubCellType); - iSubCellLayout->addWidget(m_ChoseSubCellType); - - this->m_SelectedSubCellType = new std::string; - - QObject::connect( this->m_ChoseSubCellType, - SIGNAL( ItemSelected(std::string) ), - this, SLOT( UpdateValueSelectedSubCellType(std::string) ) ); - - QObject::connect( this->m_ChoseSubCellType, - SIGNAL( AddANewOneActivated() ), - this, SIGNAL( AddANewSubCellType() ) ); - - QObject::connect( this->m_ChoseSubCellType, - SIGNAL( DeleteActivated() ), - this, SIGNAL( DeleteSubCellType() ) ); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentCellType( - std::string iCellTypeText) -{ - this->m_ChoseCellType->SetCurrentItem(iCellTypeText); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentCellTypeToSelectedOne() -{ - this->SetCurrentCellType(*this->m_SelectedCellType); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentSubCellType( - std::string iSubCellTypeText) -{ - this->m_ChoseSubCellType->SetCurrentItem(iSubCellTypeText); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentSubCellTypeToSelectedOne() -{ - this->SetCurrentSubCellType(*this->m_SelectedSubCellType); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentColor(std::string iColorText) -{ - this->m_SelectedColorComboBox->SetCurrentItem(iColorText); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentColorToSelectedOne() -{ - this->SetCurrentColor(this->m_SelectedColorData->first); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetCurrentCollectionID(std::string iID) -{ - this->m_CollectionColorComboBox->SetCurrentItem(iID); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::UpdateTraceAndCollection( - std::string iTrace, std::string iCollection) -{ - this->ChangeWindowTitle(iTrace); - - this->m_TraceName->setText( iTrace.c_str() ); - this->m_CollectionName->setText( iCollection.c_str() ); - this->m_CollectionName->show(); - this->m_CollectionLbl->show(); - - if ( iTrace == "contour" || iTrace == "mesh" ) - { - this->m_ChoseCellType->show(); - this->m_LabelCellType->show(); - this->m_ChoseSubCellType->show(); - this->m_LabelSubCellType->show(); - this->m_CollectionName->show(); - this->m_CollectionColorComboBox->show(); - } - else - { - this->m_ChoseCellType->hide(); - this->m_LabelCellType->hide(); - this->m_ChoseSubCellType->hide(); - this->m_LabelSubCellType->hide(); - this->m_CollectionColorComboBox->hide(); - } - - if (iTrace == "lineage") - { - this->m_CollectionName->hide(); - this->m_CollectionLbl->hide(); - } - // update visualization - this->show(); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::ChangeWindowTitle(std::string iTrace) -{ - QString Title(tr("%1 Settings").arg(iTrace.c_str() ) ); - this->setWindowTitle(Title); -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::SetWidgetFont() -{ - //all widget: - QFont Font; - Font.setCapitalization(QFont::Capitalize); - this->setFont(Font); - - //trace and collection name: - Font.setCapitalization(QFont::AllUppercase); - Font.setBold(true); - this->m_TraceName->setFont(Font); - this->m_CollectionName->setFont(Font); - - //trace and collection label: - Font.setCapitalization(QFont::Capitalize); - Font.setPointSize(8); - Font.setUnderline(true); - Font.setWeight(50); - Font.setBold(false); - - this->m_TraceLbl->setFont(Font); - this->m_CollectionLbl->setFont(Font); -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -std::string QGoTraceSettingsDockWidget::GetTraceName() -{ - return this->m_TraceName->text().toStdString(); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::AddANewCollectionID( - std::pair iNewCollectionID) -{ - this->m_CollectionColorComboBox->AddItemWithColor(iNewCollectionID, true); -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -std::string * QGoTraceSettingsDockWidget::GetPointerSelectedCellType() -{ - return this->m_SelectedCellType; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -std::string * QGoTraceSettingsDockWidget::GetPointerSelectedSubCellType() -{ - return this->m_SelectedSubCellType; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -QGoTraceSettingsDockWidget::ItemColorComboboxData * -QGoTraceSettingsDockWidget::GetPointerCollectionData() -{ - return this->m_SelectedCollectionData; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -QGoTraceSettingsDockWidget::ItemColorComboboxData * -QGoTraceSettingsDockWidget::GetPointerColorData() -{ - return this->m_SelectedColorData; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::UpdateValueSelectedCollection( - ItemColorComboboxData iCollectionData) -{ - std::string CollectionID = iCollectionData.first; - - if ( CollectionID.size() > 9 ) - { - if ( CollectionID.substr(0, 9) == "Add a new" ) - { - this->m_SelectedCollectionData->first = "0"; - } - } - else - { - *this->m_SelectedCollectionData = iCollectionData; - } -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -/** \todo Lydie: except when adding a new value, these methods are called -twice when something changes in the comboboxes*/ -void QGoTraceSettingsDockWidget::UpdateValueSelectedCellType(std::string iCellType) -{ - *this->m_SelectedCellType = iCellType; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::UpdateValueSelectedSubCellType(std::string iSubCellType) -{ - *this->m_SelectedSubCellType = iSubCellType; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -void QGoTraceSettingsDockWidget::UpdateValueSelectedColor( - ItemColorComboboxData iColorData) -{ - *this->m_SelectedColorData = iColorData; -} - -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- -unsigned int QGoTraceSettingsDockWidget::GetCurrentSelectedCollectionID() -{ - return atoi( this->m_SelectedCollectionData->first.c_str() ); -} -//------------------------------------------------------------------------- - -//------------------------------------------------------------------------- diff --git a/QGoTraceSettingsWidget.h b/QGoTraceSettingsWidget.h deleted file mode 100644 index 83e94fa0..00000000 --- a/QGoTraceSettingsWidget.h +++ /dev/null @@ -1,338 +0,0 @@ -/*========================================================================= - Authors: The GoFigure Dev. Team. - at Megason Lab, Systems biology, Harvard Medical school, 2009-11 - - Copyright (c) 2009-11, President and Fellows of Harvard College. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - Neither the name of the President and Fellows of Harvard College - nor the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=========================================================================*/ - -#ifndef __QGoTraceSettingsWidget_h -#define __QGoTraceSettingsWidget_h - -#include -#include -#include -#include -#include -#include "QGoSelectedColorComboBox.h" -#include "QGoCollectionColorComboBox.h" -#include "QGoComboBox.h" - -#include -#include "QGoGUILibConfigure.h" - -/** -\class QGoTraceSettingsWidget -\brief this class contains all the comboboxes for collectionID,color, -celltypes and subcelltypes, and displays the trace and collection name. -\ingroup GUI -*/ -class QGOGUILIB_EXPORT QGoTraceSettingsWidget: - public QWidget -{ - Q_OBJECT -public: - explicit QGoTraceSettingsWidget(QWidget *parent = 0); - ~QGoTraceSettingsWidget(); - - typedef QGoColorComboBox::ItemColorComboboxData ItemColorComboboxData; - typedef std::vector< std::pair< std::string, std::string > > - NamesDescrContainerType; - - /** - \brief get the name of the trace currently displayed in the QLabel - \return std::string contains the name of the trace - */ - std::string GetTraceName(); - - /** - \brief set the selected celltype in the combobox corresponding to iCellTypeText - \param[in] iCellTypeText name of the CellType to be selected - */ - void SetCurrentCellType(std::string iCellTypeText); - - /** - \brief set the selected subcelltype in the combobox corresponding to the previous - selected one, stored in m_SelectedSubCellType - */ - void SetCurrentCellTypeToSelectedOne(); - - /** - \brief set the selected subcelltype in the combobox corresponding to iSubCellTypeText - \param[in] iSubCellTypeText name of the SubCellType to be selected - */ - void SetCurrentSubCellType(std::string iSubCellTypeText); - - /** - \brief set the selected subcelltype in the combobox corresponding to the previous - selected one, stored in m_SelectedSubCellType - */ - void SetCurrentSubCellTypeToSelectedOne(); - - /** - \brief set the selected color in the combobox corresponding to iColorText - \param[in] iColorText name of the Color to be selected - */ - void SetCurrentColor(std::string iColorText); - - /** - \brief set the selected color in the combobox corresponding to the previous - selected one, stored in m_SelectedColorData - */ - void SetCurrentColorToSelectedOne(); - - /** - \brief set the selected collectionID in the combobox to iID - \param[in] iID ID of the collection to be selected - */ - void SetCurrentCollectionID(std::string iID); - - /** - \brief update the QLabel with iTrace and iCollection, the "add a new.." in the - CollectionColorComboBox and hide/show the celltype and subcelltype comboboxes - according to the iTrace - \param[in] iTrace name of the trace to update - \param[in] iCollection name of the collection to update - */ - void UpdateTraceAndCollection( - std::string iTrace, std::string iCollection); - - /** - \brief replace the list of collectionID with the ID and corresponding color - in the iListExistingID and select the ID corresponding to iCollectionIDtoSelect - if not empty, if empty, select the 1rst one - \param[in] iListExistingID list of IDs with QColor to be displayed - \param[in] iCollectionIDtoSelect ID to be selected in the combobox - */ - void SetListCollectionID( - std::list< ItemColorComboboxData > iListExistingID, - std::string iCollectionIDtoSelect = ""); - - /** - \brief replace the list of colors with the name and corresponding color - in the iListColors and select the color corresponding to iColortoSelect - if not empty, if empty, select the 1rst one - \param[in] iListColors list of colors with their names and QColor to be displayed - \param[in] iColorToSelect name of the color to be selected in the combobox - */ - void SetListColors(std::list< ItemColorComboboxData > iListColors, - std::string iColorToSelect = ""); - - /** - \brief replace the list of colors with the name and corresponding color - in the iListColors and select the color corresponding to m_SelectedColorData - \param[in] iListColors list of colors with their names and QColor to be displayed - */ - void SetListColorsWithSelectedOne(std::list< ItemColorComboboxData > iListColors); - - /** - \brief replace the list of celltype with the names in the iCellTypesData and - select the celltype corresponding to iCellTypetoSelect if not empty, if empty, - select the 1rst one. - \param[in] iCellTypesData list of celltypes with their names and description - to be displayed - \param[in] iCellTypeToSelect name of the celltype to be selected in the combobox - */ - void SetListCellTypes(NamesDescrContainerType iCellTypesData, - std::string iCellTypeToSelect = ""); - - /** - \brief replace the list of celltype with the name in the iCellTypesData - and select the celltype corresponding to m_SelectedCelltype - \param[in] iCellTypesData list of celltypes with their names and description - to be displayed - */ - void SetListCellTypeWithSelectedOne(NamesDescrContainerType iCellTypesData); - - /** - \brief replace the list of subcelltype with the names in the iSubCellTypesData and - select the subcelltype corresponding to iSubCellTypetoSelect if not empty, if empty, - select the 1rst one. - \param[in] iSubCellData list of subcelltypes with their names and description - to be displayed - \param[in] iSubCellTypeToSelect name of the subcelltype to be selected in the combobox - */ - void SetListSubCellTypes(NamesDescrContainerType iSubCellData, - std::string iSubCellTypeToSelect = ""); - - /** - \brief replace the list of subcelltype with the name in the iSubCellTypesData - and select the subcelltype corresponding to m_SelectedSubCelltype - \param[in] iSubCellTypesData list of subcelltypes with their names and description - to be displayed - */ - void SetListSubCellTypeWithSelectedOne(NamesDescrContainerType iSubCellTypesData); - - std::string* GetPointerSelectedCellType(); - std::string* GetPointerSelectedSubCellType(); - ItemColorComboboxData* GetPointerCollectionData(); - ItemColorComboboxData* GetPointerColorData(); - - unsigned int GetCurrentSelectedCollectionID(); - -public slots: - - /** - \brief add a new collection in the collectionColorCombobox and select it - \param[in] iNewCollectionID ID and QColor of the new item - */ - void AddANewCollectionID(std::pair iNewCollectionID); - -signals: - void AddANewCellType(); - - void DeleteCellType(); - - void AddANewSubCellType(); - - void DeleteSubCellType(); - - void AddNewColor(); - - void DeleteColor(); - - void NewCollectionToBeCreated(); - - //void WindowsTitleToModify(QString); - -protected: - QLabel * m_TraceName; - QLabel * m_CollectionName; - QLabel* m_TraceLbl; - QLabel* m_CollectionLbl; - - QGoSelectedColorComboBox* m_SelectedColorComboBox; - QGoCollectionColorComboBox* m_CollectionColorComboBox; - QLabel* m_LabelCellType; - QLabel* m_LabelSubCellType; - QGoComboBox * m_ChoseCellType; - QGoComboBox * m_ChoseSubCellType; - std::string * m_SelectedCellType; - std::string * m_SelectedSubCellType; - ItemColorComboboxData * m_SelectedCollectionData; - ItemColorComboboxData * m_SelectedColorData; - - QToolBar* m_ToolBar; - - void SetUpUi(); - - /** - \brief add the SelectedColorCombobox to the layout and make the signal/slot connections - for it - */ - void SetSelectedColorComboBox(QHBoxLayout* iColorLayout); - - /** - \brief add the CollectionColorCombobox to the layout,set the trace and collection name labels, - and make the signal/slot connections - for it - */ - void SetTraceCollectionColorComboBox( - QHBoxLayout* iLayoutTraceCollection); - - /** - \brief add the Celltype QGoCombobox to the layout and make the signal/slot connections - for it - */ - void SetCellTypeComboBox( - QHBoxLayout* iCellLayout); - - /** - \brief add the SubCellType QGoCombobox to the layout and make the signal/slot connections - for it - */ - void SetSubCellTypeComboBox( - QHBoxLayout* iSubCellLayout); - - //void ChangeWindowTitle(std::string iTraceName); - - void SetWidgetFont(); - - /** - \brief call the right methods to initialize the list if there is no iTextItemToSelect - or select the iTextItemToSelect if not empty. - \param[in] iComboBox the combobox with the list to be set up - \param[in] iItemsData the list of items with their names and descriptions to be displayed - \param[in] iTextItemToSelect the item to be selected - \tparam T could be a QGoComboBox - */ - template< typename T > - void SetListItemAndSelect(T *iComboBox, NamesDescrContainerType iItemsData, - std::string iTextItemToSelect = "") - { - if ( !iTextItemToSelect.empty() ) - { - iComboBox->SetItemsFromList(iItemsData); - if ( iComboBox->findText( iTextItemToSelect.c_str() ) != -1 ) - { - iComboBox->SetCurrentItem(iTextItemToSelect); - } - else - { - iComboBox->SetCurrentItemAndActivate(0); - } - } - else - { - iComboBox->InitializeTheList(iItemsData); - } - } - - /** - \overload - */ - template< typename T > - void SetListItemAndSelect(T *iComboBox, std::list< ItemColorComboboxData > iItemsData, - std::string iTextItemToSelect = "") - { - if ( !iTextItemToSelect.empty() ) - { - iComboBox->SetItemsFromListWithColor(iItemsData); - if ( iComboBox->findText( iTextItemToSelect.c_str() ) != -1 ) - { - iComboBox->SetCurrentItem(iTextItemToSelect); - } - else - { - iComboBox->SetCurrentItemAndActivate(0); - } - } - else - { - iComboBox->InitializeTheListWithColor(iItemsData); - } - } - -protected slots: - void UpdateValueSelectedCollection(ItemColorComboboxData iCollectionData); - void UpdateValueSelectedCellType(std::string iCellType); - void UpdateValueSelectedSubCellType(std::string iSubCellType); - void UpdateValueSelectedColor(ItemColorComboboxData iColorData); -}; -#endif