Mercurial > hg > orthanc
changeset 481:4f5b4b0fa626
VTK sample
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 16 Jul 2013 10:10:55 +0200 |
parents | 482cde3f3c14 |
children | b05eb8708aee |
files | Resources/Samples/OrthancCppClient/Basic/CMakeLists.txt Resources/Samples/OrthancCppClient/OrthancCppClient.cmake Resources/Samples/OrthancCppClient/Vtk/CMakeLists.txt Resources/Samples/OrthancCppClient/Vtk/main.cpp |
diffstat | 4 files changed, 243 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/Resources/Samples/OrthancCppClient/Basic/CMakeLists.txt Tue Jul 16 09:22:55 2013 +0200 +++ b/Resources/Samples/OrthancCppClient/Basic/CMakeLists.txt Tue Jul 16 10:10:55 2013 +0200 @@ -5,48 +5,12 @@ project(OrthancCppClientTest) -SET(STATIC_BUILD OFF) - +set(STATIC_BUILD OFF) set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../../..) -include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake) -include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake) -include(${ORTHANC_ROOT}/Resources/CMake/LibCurlConfiguration.cmake) -include(${ORTHANC_ROOT}/Resources/CMake/LibPngConfiguration.cmake) -include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake) - -if (${CMAKE_COMPILER_IS_GNUCXX}) - set(CMAKE_C_FLAGS "-Wall -pedantic -Wno-implicit-function-declaration") # --std=c99 makes libcurl not to compile - set(CMAKE_CXX_FLAGS "-Wall -pedantic -Wno-long-long -Wno-variadic-macros") - set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") - set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") -elseif (${MSVC}) - add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) -endif() - -add_library(OrthancCppClient - SHARED - ${THIRD_PARTY_SOURCES} - ${ORTHANC_ROOT}/Core/OrthancException.cpp - ${ORTHANC_ROOT}/Core/Enumerations.cpp - ${ORTHANC_ROOT}/Core/Toolbox.cpp - ${ORTHANC_ROOT}/Core/HttpClient.cpp - ${ORTHANC_ROOT}/Core/MultiThreading/ArrayFilledByThreads.cpp - ${ORTHANC_ROOT}/Core/MultiThreading/ThreadedCommandProcessor.cpp - ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp - ${ORTHANC_ROOT}/Core/FileFormats/PngReader.cpp - ${ORTHANC_ROOT}/OrthancCppClient/OrthancConnection.cpp - ${ORTHANC_ROOT}/OrthancCppClient/Series.cpp - ${ORTHANC_ROOT}/OrthancCppClient/Study.cpp - ${ORTHANC_ROOT}/OrthancCppClient/Instance.cpp - ${ORTHANC_ROOT}/OrthancCppClient/Patient.cpp - ${ORTHANC_ROOT}/Resources/sha1/sha1.cpp - ${ORTHANC_ROOT}/Resources/md5/md5.c - ${ORTHANC_ROOT}/Resources/base64/base64.cpp - ) +include(../OrthancCppClient.cmake) add_executable(Test main.cpp + ${ORTHANC_CPP_CLIENT_SOURCES} ) - -target_link_libraries(Test OrthancCppClient)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Samples/OrthancCppClient/OrthancCppClient.cmake Tue Jul 16 10:10:55 2013 +0200 @@ -0,0 +1,34 @@ +include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/LibCurlConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/LibPngConfiguration.cmake) +include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake) + +if (${CMAKE_COMPILER_IS_GNUCXX}) + set(CMAKE_C_FLAGS "-Wall -pedantic -Wno-implicit-function-declaration") # --std=c99 makes libcurl not to compile + set(CMAKE_CXX_FLAGS "-Wall -pedantic -Wno-long-long -Wno-variadic-macros") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") +elseif (${MSVC}) + add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) +endif() + +set(ORTHANC_CPP_CLIENT_SOURCES + ${THIRD_PARTY_SOURCES} + ${ORTHANC_ROOT}/Core/OrthancException.cpp + ${ORTHANC_ROOT}/Core/Enumerations.cpp + ${ORTHANC_ROOT}/Core/Toolbox.cpp + ${ORTHANC_ROOT}/Core/HttpClient.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/ArrayFilledByThreads.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/ThreadedCommandProcessor.cpp + ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp + ${ORTHANC_ROOT}/Core/FileFormats/PngReader.cpp + ${ORTHANC_ROOT}/OrthancCppClient/OrthancConnection.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Series.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Study.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Instance.cpp + ${ORTHANC_ROOT}/OrthancCppClient/Patient.cpp + ${ORTHANC_ROOT}/Resources/sha1/sha1.cpp + ${ORTHANC_ROOT}/Resources/md5/md5.c + ${ORTHANC_ROOT}/Resources/base64/base64.cpp + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Samples/OrthancCppClient/Vtk/CMakeLists.txt Tue Jul 16 10:10:55 2013 +0200 @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8) + +project(OrthancCppClientTest) + +set(STATIC_BUILD OFF) +set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../../..) + +include(../OrthancCppClient.cmake) + +find_package(VTK REQUIRED) +include(${VTK_USE_FILE}) + +add_executable(Test + main.cpp + ${ORTHANC_CPP_CLIENT_SOURCES} + ) + +if(VTK_LIBRARIES) + target_link_libraries(Test ${VTK_LIBRARIES}) +else() + target_link_libraries(Test vtkHybrid vtkVolumeRendering) +endif() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Samples/OrthancCppClient/Vtk/main.cpp Tue Jul 16 10:10:55 2013 +0200 @@ -0,0 +1,183 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2013 Medical Physics Department, CHU of Liege, + * Belgium + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + **/ + + +#include <iostream> + +#include <vtkRenderWindow.h> +#include <vtkImageData.h> +#include <vtkPiecewiseFunction.h> +#include <vtkFixedPointVolumeRayCastMapper.h> +#include <vtkColorTransferFunction.h> +#include <vtkVolumeProperty.h> +#include <vtkRenderWindowInteractor.h> +#include <vtkRenderer.h> +#include <vtkSmartPointer.h> +#include <vtkOpenGLRenderer.h> +#include <vtkInteractorStyleTrackballCamera.h> + +#include "../../../../OrthancCppClient/OrthancConnection.h" + + +class DisplayProgress : public Orthanc::ThreadedCommandProcessor::IListener +{ +public: + virtual void SignalProgress(unsigned int current, + unsigned int total) + { + std::cout << "Slice loaded (" << current << "/" << total << ")" << std::endl; + } + + virtual void SignalSuccess(unsigned int total) + { + std::cout << "Success loading image (" << total << " images)" << std::endl; + } + + virtual void SignalCancel() + { + } + + virtual void SignalFailure() + { + std::cout << "Error loading image" << std::endl; + } +}; + + + +void Display(OrthancClient::Series& series) +{ + /** + * Load the 3D image from Orthanc into VTK. + **/ + + vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New(); + image->SetDimensions(series.GetWidth(), series.GetHeight(), series.GetInstanceCount()); + image->SetScalarType(VTK_SHORT); + image->AllocateScalars(); + + if (series.GetWidth() != 0 && + series.GetHeight() != 0 && + series.GetInstanceCount() != 0) + { + DisplayProgress listener; + series.Load3DImage(image->GetScalarPointer(0, 0, 0), Orthanc::PixelFormat_SignedGrayscale16, + 2 * series.GetWidth(), 2 * series.GetHeight() * series.GetWidth(), listener); + } + + float sx, sy, sz; + series.GetVoxelSize(sx, sy, sz); + image->SetSpacing(sx, sy, sz); + + + /** + * The following code is based on the VTK sample for MIP + * http://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/MinIntensityRendering + **/ + + // Create a transfer function mapping scalar value to opacity + double range[2]; + image->GetScalarRange(range); + + vtkSmartPointer<vtkPiecewiseFunction> opacityTransfer = + vtkSmartPointer<vtkPiecewiseFunction>::New(); + opacityTransfer->AddSegment(range[0], 0.0, range[1], 1.0); + + vtkSmartPointer<vtkColorTransferFunction> colorTransfer = + vtkSmartPointer<vtkColorTransferFunction>::New(); + colorTransfer->AddRGBPoint(0, 1.0, 1.0, 1.0); + colorTransfer->AddRGBPoint(range[1], 1.0, 1.0, 1.0); + + vtkSmartPointer<vtkVolumeProperty> property = + vtkSmartPointer<vtkVolumeProperty>::New(); + property->SetScalarOpacity(opacityTransfer); + property->SetColor(colorTransfer); + property->SetInterpolationTypeToLinear(); + + // Create a Maximum Intensity Projection rendering + vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> mapper = + vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New(); + mapper->SetBlendModeToMaximumIntensity(); + mapper->SetInput(image); + + vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New(); + volume->SetMapper(mapper); + volume->SetProperty(property); + + vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkOpenGLRenderer>::New(); + renderer->AddViewProp(volume); + renderer->SetBackground(0.1, 0.2, 0.3); // Background color dark blue + + vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = + vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); + + vtkSmartPointer<vtkRenderWindow> window = vtkSmartPointer<vtkRenderWindow>::New(); + window->AddRenderer(renderer); + + vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); + interactor->SetRenderWindow(window); + interactor->SetInteractorStyle(style); + interactor->Start(); +} + + +int main() +{ + // Try and find a 3D image inside the local store + OrthancClient::OrthancConnection orthanc("http://localhost:8042"); + + for (unsigned int i = 0; i < orthanc.GetPatientCount(); i++) + { + OrthancClient::Patient& patient = orthanc.GetPatient(i); + std::cout << "Patient: " << patient.GetId() << std::endl; + + for (unsigned int j = 0; j < patient.GetStudyCount(); j++) + { + OrthancClient::Study& study = patient.GetStudy(j); + std::cout << " Study: " << study.GetId() << std::endl; + + for (unsigned int k = 0; k < study.GetSeriesCount(); k++) + { + OrthancClient::Series& series = study.GetSeries(k); + std::cout << " Series: " << series.GetId() << std::endl; + + if (series.Is3DImage()) + { + Display(series); + return 0; + } + else + { + std::cout << " => Not a 3D image..." << std::endl; + } + } + } + } + + std::cout << "Unable to find a 3D image in the local Orthanc store" << std::endl; + + return 0; +}