├── BuildAndTest.bat.in ├── BuildAndTest.sh.in ├── CMake └── PlusAppMacros.cmake ├── CMakeLists.txt ├── CONTRIBUTING.md ├── CPackConfig.cmake ├── CTestConfig.cmake ├── CTestCustom.cmake.in ├── CreatePackage.bat.in ├── CreatePackage.sh.in ├── CreateUserManual.bat.in ├── CreateUserManual.sh.in ├── DiagnosticTools ├── CMakeLists.txt ├── DiagDataCollection.cxx └── TrackingDataServer.cxx ├── Documentation ├── AnalyticsFooter.html.in ├── ApplicationDiagDataCollection.dox ├── ApplicationPlusServer.dox ├── ApplicationPlusServerLauncher.dox ├── ApplicationPlusServerLauncher.png ├── ApplicationPointSetExtractor.dox ├── ApplicationPointSetExtractorPoint.png ├── ApplicationPointSetExtractorSphere.png ├── ApplicationPointSetExtractorTube.png ├── ApplicationSpatialSensorFusion.dox ├── ApplicationfCal.dox ├── ApplicationfCalCoordinateSystemDefinitions.dox ├── CMakeLists.txt ├── Calibration.dox ├── Configuration.dox ├── DataAcquisitionProcessing.dox ├── Doxyfile.txt.in ├── DoxygenLayout.xml ├── Faq.dox ├── GenerateDoc.cmake.in ├── MainPage.dox ├── PlusAppDoxygenStyle.css ├── PlusServerLauncherRemote.png ├── ProcedureStreamingToSlicer.dox ├── ProcedureTrackedUltrasoundRecording.dox ├── ProcedureUltrasoundSimulation.dox ├── ProcedureVolumeReconstruction.dox ├── ReportError.dox ├── Specifications.dox └── Tools.dox ├── InstallFiles.cmake ├── PlusAppConfig.cmake.in ├── PlusAppConfigVersion.cmake.in ├── PlusConfig.xml.in ├── PlusServerLauncher ├── CMakeLists.txt ├── PlusServerLauncher.qrc ├── PlusServerLauncher.rc ├── PlusServerLauncherMain.cxx ├── PlusServerLauncherMainWindow.cxx ├── PlusServerLauncherMainWindow.h ├── PlusServerLauncherMainWindow.ui ├── Resources │ ├── icon_ConnectLarge.ico │ └── icon_Edit.png └── Testing │ ├── CMakeLists.txt │ └── PlusServerLauncherRemoteControl.cxx ├── PointSetExtractor ├── CMakeLists.txt └── PointSetExtractor.cxx ├── README.md ├── SpatialSensorFusion ├── CMakeLists.txt ├── SpatialSensorFusion.cxx └── Testing │ └── CMakeLists.txt ├── UsePlusApp.cmake.in ├── Utilities ├── SetupForDevelopment.sh └── hooks │ └── commit-msg └── fCal ├── CMakeLists.txt ├── PlusCaptureControlWidget.cxx ├── PlusCaptureControlWidget.h ├── PlusCaptureControlWidget.ui ├── QPlusChannelAction.cxx ├── QPlusChannelAction.h ├── QPlusSegmentationParameterDialog.cxx ├── QPlusSegmentationParameterDialog.h ├── QPlusSegmentationParameterDialog.ui ├── Resources ├── icon_Apply.png ├── icon_DownArrow.png ├── icon_DownArrow.xcf ├── icon_Edit.png ├── icon_HorizontalFlip.png ├── icon_ImageControl.png ├── icon_Import.png ├── icon_ObjectMode.png ├── icon_OpenFile.png ├── icon_Pause.png ├── icon_Play.png ├── icon_Plug.png ├── icon_Plug.xcf ├── icon_PopOut.png ├── icon_Record.png ├── icon_Save.png ├── icon_SaveAll.png ├── icon_SaveAll.xcf ├── icon_ShowDevices.png ├── icon_ShowDevices.xcf ├── icon_Snapshot.png ├── icon_Tools.png ├── icon_Tools.xcf ├── icon_fCal.ico └── icon_fCal.png ├── Testing ├── CMakeLists.txt └── SegmentationParameterDialogTest.cxx ├── Toolboxes ├── QAbstractToolbox.h ├── QCapturingToolbox.cxx ├── QCapturingToolbox.h ├── QCapturingToolbox.ui ├── QConfigurationToolbox.cxx ├── QConfigurationToolbox.h ├── QConfigurationToolbox.ui ├── QPhantomRegistrationToolbox.cxx ├── QPhantomRegistrationToolbox.h ├── QPhantomRegistrationToolbox.ui ├── QSpatialCalibrationToolbox.cxx ├── QSpatialCalibrationToolbox.h ├── QSpatialCalibrationToolbox.ui ├── QStylusCalibrationToolbox.cxx ├── QStylusCalibrationToolbox.h ├── QStylusCalibrationToolbox.ui ├── QTemporalCalibrationToolbox.cxx ├── QTemporalCalibrationToolbox.h ├── QTemporalCalibrationToolbox.ui ├── QVolumeReconstructionToolbox.cxx ├── QVolumeReconstructionToolbox.h └── QVolumeReconstructionToolbox.ui ├── fCal.qrc ├── fCal.rc ├── fCalMain.cxx ├── fCalMainWindow.cxx ├── fCalMainWindow.h ├── fCalMainWindow.ui ├── vtkPlus3DObjectVisualizer.cxx ├── vtkPlus3DObjectVisualizer.h ├── vtkPlusDisplayableObject.cxx ├── vtkPlusDisplayableObject.h ├── vtkPlusImageVisualizer.cxx ├── vtkPlusImageVisualizer.h ├── vtkPlusVisualizationController.cxx └── vtkPlusVisualizationController.h /BuildAndTest.bat.in: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | 3 | SET ORIGPATH=%PATH% 4 | 5 | SET BUILD_TYPE=Release 6 | 7 | REM Parse arguments 8 | SET COMMAND=%0 9 | SET TEST_MODE=%1 10 | SHIFT 11 | 12 | :loop 13 | IF NOT "%1"=="" ( 14 | IF "%1"=="--test" ( 15 | SET INDIVIDUAL_TEST=%2 16 | SHIFT 17 | ) 18 | IF "%1"=="--track" ( 19 | SET TEST_TRACK=--track %2 20 | SHIFT 21 | ) 22 | SHIFT 23 | GOTO :loop 24 | ) 25 | 26 | REM Skip build step if continuous or individual mode 27 | REM Skip clean build step if not nightly mode 28 | if "%TEST_MODE%" == "-C" goto cleansuccess 29 | if "%TEST_MODE%" == "-I" goto cleansuccess 30 | if "%TEST_MODE%" == "" goto cleansuccess 31 | if "%TEST_MODE%" == "-E" goto cleansuccess 32 | 33 | ECHO Clean... 34 | "${CMAKE_MAKE_PROGRAM}" ALL_BUILD.vcxproj /p:Configuration=Release /target:clean 35 | IF ERRORLEVEL 1 GOTO buildfail 36 | 37 | :cleansuccess 38 | 39 | rem --------------------------------------- 40 | if "%TEST_MODE%" == "" goto experimental 41 | if "%TEST_MODE%" == "-E" goto experimental 42 | if "%TEST_MODE%" == "-N" goto nightly 43 | if "%TEST_MODE%" == "-C" goto continuous 44 | if "%TEST_MODE%" == "-I" goto individual 45 | 46 | :experimental 47 | "${CMAKE_CTEST_COMMAND}" -C %BUILD_TYPE% -D Experimental --output-on-failure %TEST_TRACK% 48 | goto success 49 | 50 | :nightly 51 | @REM Clean before the nightly build to enforce all build warnings appear on all nightly dashboard submissions 52 | "${CMAKE_CTEST_COMMAND}" -C %BUILD_TYPE% -D Nightly %TEST_TRACK% 53 | goto success 54 | 55 | :continuous 56 | "${CMAKE_CTEST_COMMAND}" -C %BUILD_TYPE% -D Continuous %TEST_TRACK% 57 | @REM Wait for some time before continue to allow checking the results of the executions 58 | timeout /t 15 59 | goto success 60 | 61 | :individual 62 | @REM Run individual tests with regexp search 63 | @REM Display the list of tests 64 | "${CMAKE_CTEST_COMMAND}" -C %BUILD_TYPE% -R "%INDIVIDUAL_TEST" -N 65 | @REM Run selected tests 66 | "${CMAKE_CTEST_COMMAND}" -C %BUILD_TYPE% -R "%INDIVIDUAL_TEST" -V 67 | goto success 68 | 69 | :success 70 | SET PATH=%ORIGPATH% 71 | exit /b 0 72 | 73 | :buildfail 74 | ECHO Failed to build PlusLib 75 | SET PATH=%ORIGPATH% 76 | exit /b 1 77 | -------------------------------------------------------------------------------- /BuildAndTest.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ORIGPATH=$PATH 4 | DIRCMD=0 5 | 6 | finish() 7 | { 8 | PATH=$ORIGPATH 9 | } 10 | 11 | buildFailed () 12 | { 13 | echo "ERROR: Build failed..." 14 | finish 15 | exit $1 16 | } 17 | 18 | command=$0 19 | if [ "$1" == "-E" ] || [ "$1" == "-N" ] || [ "$1" == "-C" ] || [ "$1" == "-I" ]; then 20 | test_mode=$1 21 | shift 22 | else 23 | test_mode="-E" 24 | fi 25 | 26 | test_track="" 27 | individual_test="" 28 | while [ "${1:-}" != "" ]; do 29 | case "$1" in 30 | "--test") 31 | shift 32 | individial_test=$1 33 | ;; 34 | "--track") 35 | shift 36 | test_track="--track \"$1\"" 37 | ;; 38 | esac 39 | shift 40 | done 41 | 42 | if [ "$test_mode" == "" ] || [ "$test_mode" == "-E" ]; then 43 | "@CMAKE_COMMAND@" --build . --config Release 44 | errorVal=$? 45 | if [ "$?" == 1 ]; then 46 | buildFailed $errorVal 47 | fi 48 | "@CMAKE_CTEST_COMMAND@" -C Release -D Experimental --output-on-failure $test_track 49 | fi 50 | 51 | if [ "$test_mode" == "-N" ]; then 52 | # Clean before the nightly build to enforce all build warnings appear on all nightly dashboard submissions 53 | "@CMAKE_COMMAND@" --build . --config Release --clean-first 54 | "@CMAKE_CTEST_COMMAND@" -C Release -D Nightly $test_track 55 | fi 56 | 57 | if [ "$test_mode" == "-C" ]; then 58 | "@CMAKE_COMMAND@" --build . --config Release 59 | "@CMAKE_CTEST_COMMAND@" -C Release -D Continuous $test_track 60 | # Wait for some time before continue to allow checking the results of the executions 61 | sleep 15 62 | fi 63 | 64 | if [ "$test_mode" == "-I" ]; then 65 | # Run individual tests with regexp search 66 | # Display the list of tests 67 | "@CMAKE_CTEST_COMMAND@" -C Release -R "%individial_test" -N 68 | # Run selected tests 69 | "@CMAKE_CTEST_COMMAND@" -C Release -R "%individial_test" -V 70 | fi 71 | 72 | finish 73 | echo "DONE" 74 | -------------------------------------------------------------------------------- /CMake/PlusAppMacros.cmake: -------------------------------------------------------------------------------- 1 | FUNCTION(AddPlusQt5Executable _exec_name) 2 | LIST(POP_FRONT ARGV) 3 | ADD_EXECUTABLE(${_exec_name} ${ARGV}) 4 | 5 | set(PLUSAPP_QT_COMPONENTS_ARGS) 6 | IF (PLUSAPP_QT_COMPONENTS) 7 | # Ensure that all required Qt components are specified as arugments to windeployqt 8 | # Ex. "--core --multimedia --test" etc. 9 | foreach (COMPONENT ${PLUSAPP_QT_COMPONENTS}) 10 | string(TOLOWER ${COMPONENT} COMPONENT_LOWER) 11 | list(APPEND PLUSAPP_QT_COMPONENTS_ARGS --${COMPONENT_LOWER}) 12 | endforeach(COMPONENT ${PLUSAPP_QT_COMPONENTS}) 13 | ENDIF() 14 | 15 | IF(TARGET Qt5::windeployqt) 16 | # execute windeployqt in a tmp directory after build 17 | ADD_CUSTOM_COMMAND(TARGET ${_exec_name} 18 | POST_BUILD 19 | COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" 20 | COMMAND set PATH=%PATH%$${qt5_install_prefix}/bin 21 | COMMAND Qt5::windeployqt ${PLUSAPP_QT_COMPONENTS_ARGS} --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$/$" 22 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/windeployqt $ 23 | ) 24 | 25 | # copy deployment directory during installation 26 | INSTALL( 27 | DIRECTORY 28 | "${CMAKE_CURRENT_BINARY_DIR}/windeployqt/" 29 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 30 | COMPONENT RuntimeLibraries 31 | ) 32 | ENDIF() 33 | ENDFUNCTION() 34 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How to contribute to Plus: 2 | https://github.com/PlusToolkit/PlusLib/blob/master/CONTRIBUTING.md 3 | -------------------------------------------------------------------------------- /CTestConfig.cmake: -------------------------------------------------------------------------------- 1 | ## This file should be placed in the root directory of your project. 2 | ## Then modify the CMakeLists.txt file in the root directory of your 3 | ## project to incorporate the testing dashboard. 4 | ## # The following are required to uses Dart and the Cdash dashboard 5 | ## enable_testing() 6 | ## include(CTest) 7 | set(CTEST_PROJECT_NAME "PlusApp") 8 | set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") 9 | 10 | set(CTEST_DROP_METHOD "https") 11 | set(CTEST_DROP_SITE "open.cdash.org") 12 | set(CTEST_DROP_LOCATION "/submit.php?project=PlusApp") 13 | set(CTEST_DROP_SITE_CDASH TRUE) 14 | -------------------------------------------------------------------------------- /CTestCustom.cmake.in: -------------------------------------------------------------------------------- 1 | SET(CTEST_CUSTOM_COVERAGE_EXCLUDE 2 | ${CTEST_CUSTOM_COVERAGE_EXCLUDE} 3 | 4 | # Exclude try_compile sources from coverage results: 5 | "/CMakeFiles/CMakeTmp/" 6 | 7 | # Exclude files generated by the moc pre-compiler 8 | ".*/moc_.*" 9 | 10 | # Exclude files generated by the uic pre-compiler 11 | ".*/ui_.*" 12 | 13 | # Exclude files from the Testing directories 14 | ".*/Testing/.*" 15 | 16 | ".*/CMakeExternals/.*" 17 | 18 | "./ctkPixmapIconEngine.*" 19 | "./ctkIconEngine.*" 20 | ) 21 | 22 | # The following tests should not be run under valgrind 23 | SET(CTEST_CUSTOM_MEMCHECK_IGNORE 24 | 25 | ) 26 | 27 | SET(CTEST_CUSTOM_ERROR_MATCH 28 | ${CTEST_CUSTOM_ERROR_MATCH} 29 | "CMake Error[ :]" 30 | ) 31 | 32 | SET(CTEST_CUSTOM_WARNING_MATCH 33 | ${CTEST_CUSTOM_WARNING_MATCH} 34 | "CMake Warning[ :]" 35 | ) 36 | 37 | SET(CTEST_CUSTOM_WARNING_EXCEPTION 38 | ${CTEST_CUSTOM_WARNING_EXCEPTION} 39 | 40 | # kwstyle suppressions 41 | "[Kk][Ww][Ss]tyle.*kws.*cxx" 42 | "[Kk][Ww][Ss]tyle.*kws.*h" 43 | "[Kk][Ww][Ss]tyle.*metaCommand.*cxx" 44 | 45 | # vtk suppressions 46 | "vtkfreetype" 47 | "Utilities.vtktiff" 48 | "VTK.*IO.vtkMySQLQuery.cxx" 49 | "VTK.*Utilities.vtkexodus2" 50 | "VTK.*Utilities.vtklibproj" 51 | "VTK.*Utilities.vtksqlite" 52 | "VTK.*Utilities.vtkmetaio" 53 | "VTK.*warn_unused_result" 54 | "VTK.*Filtering.*cxx" 55 | "VTK.*IO.*cxx" 56 | "VTK.*Infovis.*cxx" 57 | 58 | # qt suppressions from vtk... 59 | # Some VTK dashboards include building bits of Qt which produce lots of 60 | # the following warnings when built with the MS compilers. Qt guys should 61 | # fix their code. Until they do, keep the Qt chatter off the VTK dashboard 62 | # results: 63 | "include.[Qq]t([Cc]ore|[Gg]ui).*warning C4127: conditional expression is constant" 64 | "[Qq]t.*h.*warning.*declaration of .* shadows a member of .this" 65 | "[Qq]t.*h.*warning.*(copy constructor|assignment operator) could not be generated" 66 | 67 | # Suppress warning caused when QT 'foreach' loops are combined 68 | ".*warning: declaration of '_container_' shadows a previous local" 69 | 70 | # Suppress warning caused by the moc compiler 71 | ".*warning : No relevant classes found. No output generated." 72 | 73 | # PythonQt suppressions 74 | "PythonQt.*src.*PythonQt.*(cpp|h)" 75 | "include.PythonQt.PythonQt.*h" 76 | 77 | # Suppressing warnings about duplicate libraries in Darwin 78 | # At some point this may be addressed by CMake feature request: 79 | # http://public.kitware.com/Bug/view.php?id=10179 80 | "ld: warning: duplicate dylib.*" 81 | 82 | # Visual studio spurious warnings... 83 | "The following environment variables were not found" 84 | 85 | # QtMobility 86 | "warning: jobserver unavailable: using -j1. Add `+' to parent make rule." 87 | ) 88 | -------------------------------------------------------------------------------- /CreatePackage.bat.in: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | REM Hide all your directories from users 3 | 4 | REM Return code is 0 on success and >0 if something failed 5 | SET RETURN_CODE=0 6 | 7 | REM First we need to build a Release version 8 | 9 | "${CMAKE_MAKE_PROGRAM}" ALL_BUILD.vcxproj /p:Configuration=Release /target:build 10 | IF ERRORLEVEL 1 GOTO BUILDFAILED 11 | 12 | :BUILDDOCUMENTATION 13 | REM Build documentation 14 | IF ${BUILD_DOCUMENTATION}==OFF GOTO PACKAGE 15 | call CreateUserManual.bat 16 | IF ERRORLEVEL 1 GOTO BUILDFAILED 17 | ECHO User manual generation DONE 18 | 19 | :PACKAGE 20 | REM Build the package 21 | "${CMAKE_CPACK_COMMAND}" --config ./CPackConfig.cmake 22 | IF ERRORLEVEL 1 GOTO PACKAGINGFAILED 23 | ECHO Packaging DONE 24 | 25 | :SUCCESS 26 | ECHO Package generation is successfully completed. 27 | exit /b 0 28 | 29 | :BUILDFAILED 30 | ECHO ERROR: Build failed... 31 | timeout /t 30 32 | exit /b 1 33 | 34 | :PACKAGINGFAILED 35 | ECHO ERROR: Package generation failed... 36 | timeout /t 30 37 | exit /b 2 38 | -------------------------------------------------------------------------------- /CreatePackage.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # First we need to build a Release version 4 | ${CMAKE_COMMAND} --build . --config Release 5 | 6 | # Build documentation 7 | if [ "${BUILD_DOCUMENTATION}" == "ON"]; then 8 | ./CreateUserManual.sh 9 | echo User manual generation DONE 10 | fi 11 | 12 | # Build the package 13 | "${CMAKE_CPACK_COMMAND}" --config ./CPackConfig.cmake 14 | if [ $? -ne 0 ]; then 15 | echo Unable to complete package 16 | exit 1 17 | fi 18 | 19 | echo Package generation is successfully completed. 20 | exit 0 21 | -------------------------------------------------------------------------------- /CreateUserManual.bat.in: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | ECHO Build UserManual... 3 | 4 | ECHO Clear old files to force rebuild of documentation 5 | "${CMAKE_MAKE_PROGRAM}" Documentation/Documentation-PlusApp-UserManual.vcxproj /p:Configuration=Release /target:clean 1> CreateUserManual.log 2>&1 6 | IF ERRORLEVEL 1 GOTO fail 7 | 8 | ECHO Generating documentation 9 | "${CMAKE_MAKE_PROGRAM}" Documentation/Documentation-PlusApp-UserManual.vcxproj /p:Configuration=Release /target:rebuild 1>> CreateUserManual.log 2>&1 10 | IF ERRORLEVEL 1 GOTO fail 11 | 12 | rem --------------------------------------- 13 | 14 | :success 15 | ECHO Documentation available at: ${PLUS_EXECUTABLE_OUTPUT_PATH}/Doc 16 | exit /b 0 17 | 18 | :fail 19 | ECHO Failed to generate documentation 20 | exit /b 1 21 | -------------------------------------------------------------------------------- /CreateUserManual.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo Build UserManual... 4 | 5 | echo Clear old files to force rebuild of documentation 6 | "${CMAKE_MAKE_PROGRAM}" clean > CreateUserManual.log 2>&1 7 | if [ $? -ne 0 ]; then 8 | echo Unable to clean project before building documentation 9 | exit 1 10 | fi 11 | 12 | echo Generating documentation 13 | "${CMAKE_MAKE_PROGRAM}" Documentation-PlusApp-UserManual >> CreateUserManual.log 2>&1 14 | if [ $? -ne 0 ]; then 15 | echo Unable to create documentation. See CreateUserManual.log 16 | exit 1 17 | fi 18 | 19 | echo Documentation available at: ${PLUS_EXECUTABLE_OUTPUT_PATH}/Doc 20 | exit 0 21 | -------------------------------------------------------------------------------- /DiagnosticTools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (PLUS_USE_OpenIGTLink) 2 | SET(_IGT_LIB OpenIGTLink) 3 | ENDIF() 4 | 5 | ADD_EXECUTABLE(DiagDataCollection DiagDataCollection.cxx) 6 | TARGET_LINK_LIBRARIES(DiagDataCollection PUBLIC vtkPlusDataCollection vtkPlusCommon ${_IGT_LIB}) 7 | GENERATE_HELP_DOC(DiagDataCollection) 8 | 9 | #-------------------------------------------------------------------------------------------- 10 | 11 | IF (PLUS_USE_OpenIGTLink) 12 | ADD_EXECUTABLE(TrackingDataServer TrackingDataServer.cxx) 13 | TARGET_LINK_LIBRARIES(TrackingDataServer PUBLIC vtkPlusCommon vtkPlusServer OpenIGTLink) 14 | GENERATE_HELP_DOC(TrackingDataServer) 15 | ENDIF() 16 | 17 | #-------------------------------------------------------------------------------------------- 18 | # Install 19 | IF(PLUSAPP_INSTALL_BIN_DIR) 20 | INSTALL(TARGETS DiagDataCollection 21 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 22 | COMPONENT RuntimeExecutables 23 | ) 24 | ENDIF() 25 | -------------------------------------------------------------------------------- /Documentation/AnalyticsFooter.html.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /Documentation/ApplicationDiagDataCollection.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \page ApplicationDiagDataCollection Data collection diagnostics (DiagDataCollection) 3 | 4 | Acquire raw, non-synchronized, non-interpolated tracking and video data and compute some basic metrics for diagnostics. 5 | In addition to the output on the screen two files are generated in the output directory containing the frame numbers and filtered and unfiltered timestamps (in [date]_[time].VideoBufferTimestamps.txt and [date]_[time>]TrackerBufferTimestamps.txt). 6 | 7 | \section ApplicationDiagDataCollectionExamples Examples 8 | 9 | ~~~ 10 | DiagDataCollection.exe --config-file=..\..\PlusLib\data\ConfigFiles\Test_PlusConfiguration_VideoNone_FakeTracker_PivotCalibration_fCal.xml --input-acq-time-length=10 11 | ~~~ 12 | 13 | \section ApplicationDiagDataCollectionHelp Command-line parameters reference 14 | 15 | \verbinclude "DiagDataCollectionHelp.txt" 16 | 17 | */ 18 | -------------------------------------------------------------------------------- /Documentation/ApplicationPlusServer.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \page ApplicationPlusServer PlusServer application 3 | 4 | PlusServer is an application that runs Plus functions and sends acquired data to remote 5 | clients through OpenIGTLink connection. Typical example is to use Plus for acquiring tracked 6 | ultrasound image slices and send them for real-time visualization to 3D Slicer. 7 | 8 | The server supports continuous data acquisition and sending and also on-request starting/stopping 9 | of recording, volume reconstruction, updating of transforms, saving of the modified device set 10 | configuration file, etc. Requests are received through OpenIGTLink commands. See more details at \subpage PlusServerCommands . 11 | 12 | \section ApplicationPlusServerUsage Usage 13 | 14 | The most convenient way to launch PlusServer is using PlusServerLauncher. 15 | After installing the Plus Applications package, the Plus Server Launcher can be found from the start menu. 16 | See more details at \subpage ApplicationPlusServerLauncher . 17 | 18 | \subsection ApplicationPlusServerUsageVisualization Visualization of acquired data 19 | 20 | To visualize the images and transforms broadcasted by the PlusServer use an application such as 3D Slicer: 21 | 22 | - Install and start 3D Slicer 23 | - Create a new connection in the OpenIGTLinkIF module: client, default port name (18944), and set it Active 24 | - Go to the Transforms module to see the transforms 25 | - Choose an input image in the slice viewer window to see the live image 26 | 27 | \subsection ApplicationPlusServerUsageCommandLine Command-line usage 28 | 29 | PlusServer can be also started from the command-line. The list of available command-line parameters are printed if the --help parameter is specified. 30 | 31 | Launch the command-line-only version of PlusServer (no graphical user interface): 32 | 33 | PlusServer --config-file=PlusServer.xml 34 | 35 | ~~~ 36 | 37 | --config-file=opt Configuration file name 38 | 39 | --connect Automatically connect after the 40 | application is started 41 | 42 | --device-set-configuration-dir=opt Device set configuration directory path 43 | 44 | --help Print this help. 45 | 46 | --verbose=opt Verbose level (1=error only, 2=warning, 47 | 3=info, 4=debug) 48 | ~~~ 49 | 50 | \section ApplicationPlusServerConfigSettings Configuration settings 51 | 52 | - \xmlElem \b PlusOpenIGTLinkServer 53 | - \xmlAtt ListeningPort Port number where the server listens for incoming connections. Typical value is 18944. \RequiredAtt 54 | - \xmlAtt OutputChannelId Name of the channel to get the data from. Must match the \c Id attribute value of one of the \c OutputChannel elements in a device. \RequiredAtt 55 | - \xmlAtt MaxNumberOfIgtlMessagesToSend Maximum number of messages to send to clients at each update. \OptionalAtt{100} 56 | - \xmlAtt MaxTimeSpentWithProcessingMs Maximum time spent with sending messages to clients at each update. \OptionalAtt{50} 57 | - \xmlAtt MissingInputGracePeriodSec This value defines for how long after initiating connection a the server should not report missing inputs as error. After the grace period expires, the server will report missing inputs as errors or warnings. \OptionalAtt{0} 58 | - \xmlAtt SendValidTransformsOnly If \c TRUE then only valid transforms will be sent. If \c FALSE then invalid messages are sent, too (if a transform is invalid then an identity matrix will be sent). \OptionalAtt{TRUE} 59 | - \xmlAtt SendColumnMajorTransforms If \c TRUE then transforms will be sent in column major format. If \c FALSE then transforms will be sent in row major format. \OptionalAtt{TRUE} 60 | - \xmlAtt NumberOfRetryAttempts The number of retry attempts to perform when a message cannot be sent before considering them disconnected \OptionalAtt{10} 61 | - \xmlAtt DelayBetweenRetryAttemptsSec The delay between each retry attempt. In combination with NumberOfRetryAttemps this determines how long to wait before considering a client disconnected. \OptionalAtt{0.05} 62 | - \xmlAtt DefaultClientSendTimeoutSec If set, this value is used to determine how long to wait before considering a pending send message a timeout. A value of 0 means no timeout. \OptionalAtt{0.5} 63 | - \xmlAtt DefaultClientReceiveTimeoutSec If set, this value is used to determine how long to wait before considering no network input as a timeout. A value of 0 means no timeout. \OptionalAtt{0.5} 64 | - \xmlAtt IgtlMessageCrcCheckEnabled If \c TRUE then incoming OpenIGTLink messages are only accepted if their CRC is valid. If \c FALSE then CRC is not checked. \OptionalAtt{FALSE} 65 | - \xmlAtt LogWarningOnNoDataAvailable If TRUE, a warning will be logged when no data is available yet. \OptionalAtt{TRUE} 66 | - \xmlAtt KeepAliveIntervalSec The time to wait between sending keep alive messages \OptionalAtt{0.25} 67 | - \xmlElem \b DefaultClientInfo 68 | - \xmlAtt TDATARequested For clients that have the TDATA message type requested, this parameter can control default sending of data on startup. \OptionalAtt{FALSE} 69 | - \xmlAtt TDATAResolution For TDATA messages, the minimum time between two frames. Use 0 for as fast as possible. If e.g. 50 ms is specified, the maximum update rate will be 20 Hz. \OptionalAtt{0} 70 | - \xmlElem \b MessageTypes 71 | - \xmlElem \b Message 72 | - \xmlAtt Type 73 | - \c IMAGE: standard OpenIGTLink message type, stores 3D image data (can be a single slice, includes position and orientation) 74 | - \c TRANSFORM: standard OpenIGTLink message type, stores 3D pose (position and orientation) data 75 | - \c POSITION: standard OpenIGTLink message type, stores 3D position data 76 | - \c TRACKEDFRAME: Plus tracked ultrasound frame, stores all frame fields (tool transforms, statuses, etc). Optionally, sent transforms can be customized using the \c TransformNames list. 77 | - \c USMESSAGE: MUSiiC tracked ultrasound frame, stores additional imaging information, such as transmit and sampling frequency, line density, steering angle 78 | - \c STRING: standard OpenIGTLink message type, stores a simple character string 79 | - \c VIDEO: standard OpenIGTLink message type, stores a compressed video frame 80 | - \xmlElem \b TransformNames 81 | - \xmlElem \b Transform 82 | - \xmlAtt Name 83 | - \xmlElem \b StringNames 84 | - \xmlElem \b String Name of the frame string that is sent as a STRING message. Any frame field (Timestamp, any status message, any frame fields) can be specified here. 85 | - \xmlElem \b ImageNames 86 | - \xmlElem \b Image 87 | - \xmlAtt Name Name of the image stream. It also defines the "From" frame of the transform embedded in the IGTL image message. 88 | - \xmlAtt EmbeddedTransformToFrame "To" frame of the transform embedded in the IGTL image message 89 | - \xmlElem \b VideoNames 90 | - \xmlElem \b Video 91 | - \xmlAtt Name Name of the image stream. It also defines the "From" frame of the transform embedded in the IGTL image message. 92 | - \xmlAtt EmbeddedTransformToFrame "To" frame of the transform embedded in the IGTL image message 93 | - \xmlElem \b Encoding 94 | - \xmlAtt FourCC FourCC value of the codec that is used to encode the image as a VideoMessage. Available types: I420: "I420", VP9:"VP90" \OptionalAtt{VP90} 95 | - \xmlAtt Lossless If TRUE, encoding will be performed losslessly if possible. \OptionalAtt{FALSE} 96 | - \xmlAtt MinKeyframeDistance The minimum required distance between encoded keyframes. \OptionalAtt{-1} 97 | - \xmlAtt MaxKeyframeDistance The maximum required distance between encoded keyframes. \OptionalAtt{-1} 98 | - \xmlAtt Speed The encoding speed for the encoder. \OptionalAtt{8} 99 | - \xmlAtt DeadlineMode The deadline mode for the encoder. Possible values: "REALTIME", "GOOD", "BEST". \OptionalAtt{REALTIME} 100 | - \xmlAtt RateControl The rate control mode for the encoder. Possible values: "CBR" (Constant bit rate), "VBR" (Variable bit rate), "CQ" (Constrained quality), "Q" (Constant Quality). \OptionalAtt{Q} 101 | - \xmlAtt TargetBitrate The target bitrate for the encoder. \OptionalAtt{-1} 102 | 103 | This is an example element that needs to be added to the PLUS configuration xml file to use PlusServer: 104 | 105 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | */ 125 | -------------------------------------------------------------------------------- /Documentation/ApplicationPlusServerLauncher.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \page ApplicationPlusServerLauncher PlusServerLauncher application 3 | 4 | The PlusServerLauncher provides graphical and network interfaces for controlling PlusServer instances. 5 | 6 | To start a PlusServer instance using PlusServerLauncher, select a configuration file (e.g., 7 | "PlusServer: Replay fCal phantom scan ...") and click "Launch server". 8 | 9 | \image html ApplicationPlusServerLauncher.png 10 | 11 | \section ApplicationPlusServerLauncherUsageCommandLine Command-line usage 12 | 13 | PlusServerLauncher can be also started from the command-line. The list of available command-line parameters are printed if the --help parameter is specified. 14 | 15 | Launch PlusServerLauncher and start a PlusServer instance with the last used device set and connect: 16 | 17 | PlusServerLauncher --connect 18 | 19 | Launch PlusServerLauncher and start PlusServer with a specified device set and connect: 20 | 21 | PlusServerLauncher --connect --config-file=PlusDeviceSet_Server_Sim_NwirePhantom.xml 22 | 23 | ~~~ 24 | 25 | --config-file=opt Configuration file name 26 | 27 | --connect Automatically connect after the 28 | application is started 29 | 30 | --device-set-configuration-dir=opt Device set configuration directory path 31 | 32 | --help Print this help. 33 | 34 | --port=opt OpenIGTLink port number where the 35 | launcher will listen for remote control 36 | requests. If set to -1 then no remote 37 | control server will be launched. Default 38 | = 18904. 39 | 40 | --verbose=opt Verbose level (1=error only, 2=warning, 41 | 3=info, 4=debug) 42 | ~~~ 43 | 44 | \section PlusServerLauncherRemote PlusServerLauncher remote control 45 | 46 | The PlusServerLauncher application can be controlled remotely using OpenIGTLink. 47 | By default, PlusServerLauncher listens for incoming remote control connections on port 18904. 48 | 49 | This can be changed by launching PlusServerLauncher with the port argument: 50 | 51 | PlusServerLauncher --port=12345 52 | 53 | Using the remote connection, several commands can be sent to PLus: 54 | - Start PlusServer instance 55 | - Stop PlusServer instance 56 | - Add config file 57 | - Subscribe/Unsubscribe to log messages 58 | 59 | In addition, the PLus will communicate several status messages to subscribed clients: 60 | - PlusServer instance started 61 | - PlusServer instance stopped 62 | - Log messages 63 | 64 | ______ 65 | 66 | \subsection PlusServerLauncherRemoteAcceptedCommands Accepted commands 67 | 68 | \subsubsection PlusServerLauncherRemoteCommandsGetConfigFiles GetConfigFiles 69 | 70 | Returns a list of semi-colon separated config file names. 71 | 72 | Command 73 | ~~~ 74 | Content: 75 | 76 | Metadata 77 | None 78 | ~~~ 79 | Response 80 | ~~~ 81 | Content: 82 | 83 | MetaData: 84 | ConfigFiles="ConfigFile1.xml;ConfigFile2.xml" 85 | Separator=";" 86 | ~~~ 87 | 88 | \subsubsection PlusServerLauncherRemoteCommandsAddConfigFile AddConfigFile 89 | 90 | Adds a new config file or updates an existing one of the same name 91 | 92 | Command 93 | ~~~ 94 | Content: 95 | 96 | MetaData: 97 | ConfigFileName="Name.xml" 98 | ConfigFileContent="Contents of config file" 99 | ~~~ 100 | Response 101 | ~~~ 102 | Content: 103 | 104 | MetaData: 105 | ConfigFileName="ActualName.xml" 106 | ~~~ 107 | 108 | \subsubsection PlusServerLauncherRemoteCommandsStartServer StartServer 109 | 110 | Starts a server with the specified filename. 111 | 112 | Command 113 | ~~~ 114 | Content: 115 | 116 | MetaData: 117 | ConfigFileName="Filename.xml" 118 | LogLevel="3" 119 | ~~~ 120 | Response 121 | ~~~ 122 | Content: 123 | 124 | 125 | 126 | MetaData: 127 | ConfigFileName="ActualName.xml" 128 | ~~~ 129 | 130 | \subsubsection PlusServerLauncherRemoteCommandsStopServer StopServer 131 | 132 | Stops a running server that is using a config file with the specified filename. 133 | 134 | Command 135 | ~~~ 136 | Content: 137 | 138 | MetaData: 139 | ConfigFileName="Filename.xml" 140 | ~~~ 141 | Response 142 | ~~~ 143 | Content: 144 | 145 | 146 | 147 | MetaData: 148 | ConfigFileName="Filename.xml" 149 | ~~~ 150 | 151 | \subsubsection PlusServerLauncherRemoteCommandsLogSubscribe LogSubscribe 152 | 153 | Subscribes a client to receive server log messages 154 | 155 | Command 156 | ~~~ 157 | Content: 158 | 159 | MetaData: 160 | None 161 | ~~~ 162 | Response 163 | ~~~ 164 | Content: 165 | 166 | MetaData: 167 | None 168 | ~~~ 169 | 170 | \subsubsection PlusServerLauncherRemoteCommandsLogUnsubscribe LogUnsubscribe 171 | 172 | Unsubscribes a client from receiving server log messages 173 | 174 | Command 175 | ~~~ 176 | Content: 177 | 178 | MetaData: 179 | None 180 | ~~~ 181 | Response 182 | ~~~ 183 | Content: 184 | 185 | MetaData: 186 | None 187 | ~~~ 188 | 189 | ______ 190 | 191 | \subsection PlusServerLauncherRemoteSentCommands Sent commands 192 | 193 | \subsubsection PlusServerLauncherRemoteCommandsLogMessage LogMessage 194 | 195 | Sent to connected clients whenever a message is logged by Plus. 196 | 197 | Command 198 | ~~~ 199 | Content: 200 | 202 | 203 | MetaData: 204 | Message="Log message contents" 205 | LogLevel="0" 206 | Origin="SERVER" 207 | ~~~ 208 | No response expected 209 | 210 | \subsubsection PlusServerLauncherRemoteCommandsServerStarted ServerStarted 211 | 212 | Sent to connected clients whenever a server is started. 213 | 214 | Command 215 | ~~~ 216 | Content: 217 | 219 | 220 | MetaData: 221 | ConfigFileName="Filename.xml" 222 | LogLevel="3" 223 | Servers="OutputChannelId:port;OutputChannelId2:port2" 224 | ~~~ 225 | No response expected 226 | 227 | \subsubsection PlusServerLauncherRemoteCommandsServerStopped ServerStopped 228 | 229 | Sent to connected clients whenever a server is started. 230 | 231 | Command 232 | ~~~ 233 | Content: 234 | 236 | 237 | MetaData: 238 | ConfigFileName="Filename.xml" 239 | ~~~ 240 | No response expected 241 | 242 | ______ 243 | 244 | \subsection PlusServerLauncherRemoteWidget PlusServerLauncher remote control from Slicer 245 | 246 | A graphical interface for remotely controlling PlusServerLauncher is included the PlusRemote module from the SlicerOpenIGTLink extension. 247 | To use the PlusRemote module: 248 | 1. Download Slicer >=4.10.2 249 | 2. Open Slicer 250 | 3. Navigate to the extension manager 251 | 4. Select "Install Extensions" and find the SlicerOpenIGTLink extension 252 | 5. After the download has completed, restart Slicer 253 | 6. PlusRemote should now be available in the list of modules 254 | 255 | To start a PlusServer instance from Slicer: 256 | 257 | Method 1: 258 | - Drag and drop a config file with the extension ".plus.xml" into Slicer 259 | 260 | Method 2: 261 | 1. Navigate to the PlusRemote module 262 | 2. Switch to the "Plus Launcher Control tab" 263 | 3. Create a new launcher node using the "Launcher node" selelctor 264 | 4. Specify the hostname and port of the PlusServerLauncher application 265 | 5. Load a config file to Slicer by dragging and any text file with the description "Text file" 266 | 6. Click the "Add server" button 267 | 7. Under the "Advanced" section, change the config file to the config file 268 | 8. Click the connect button under the "State" column in the table 269 | 270 | 271 | \image html PlusServerLauncherRemote.png 272 | 273 | 274 | */ 275 | -------------------------------------------------------------------------------- /Documentation/ApplicationPlusServerLauncher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/Documentation/ApplicationPlusServerLauncher.png -------------------------------------------------------------------------------- /Documentation/ApplicationPointSetExtractor.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \page ApplicationPointSetExtractor Point set extractor (PointSetExtractor) 3 | 4 | Extracts the tooltip positions of a selected tool (tpyically a stylus, but it can be any other tool) and saves it into a polygon file for visualization or further processing. Optionally it can show the pointset on the screen in 3D. It can be used for visualization of motion trajectories or for collecting a point cloud for surface reconstruction. 5 | 6 | \section ApplicationPointSetExtractorExamples Examples 7 | 8 | Output: points 9 | ~~~ 10 | PointSetExtractor --config-file=PlusDeviceSet_NwirePhantomFreehand_vtkPlusVolumeReconstructorTest2.xml --source-seq-file=NwirePhantomFreehand.mha --output-pointset-file=output.ply --reference-name=Tracker --stylus-name=Probe --display 11 | ~~~ 12 | \image html ApplicationPointSetExtractorPoint.png 13 | 14 | Output: spheres 15 | ~~~ 16 | PointSetExtractor.exe --config-file=PlusDeviceSet_NwirePhantomFreehand_vtkPlusVolumeReconstructorTest2.xml --source-seq-file=NwirePhantomFreehand.mha --output-surface-file=output.stl --reference-name=Tracker --stylus-name=Probe --add-spheres --radius=0.3 --display 17 | ~~~ 18 | \image html ApplicationPointSetExtractorSphere.png 19 | 20 | Output: tube 21 | ~~~ 22 | PointSetExtractor.exe --config-file=PlusDeviceSet_NwirePhantomFreehand_vtkPlusVolumeReconstructorTest2.xml --source-seq-file=NwirePhantomFreehand.mha --output-surface-file=output.stl --reference-name=Tracker --stylus-name=Probe --add-tube --display 23 | ~~~ 24 | \image html ApplicationPointSetExtractorTube.png 25 | 26 | \section ApplicationPointSetExtractorHelp Command-line parameters reference 27 | 28 | \verbinclude "PointSetExtractorHelp.txt" 29 | 30 | */ 31 | -------------------------------------------------------------------------------- /Documentation/ApplicationPointSetExtractorPoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/Documentation/ApplicationPointSetExtractorPoint.png -------------------------------------------------------------------------------- /Documentation/ApplicationPointSetExtractorSphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/Documentation/ApplicationPointSetExtractorSphere.png -------------------------------------------------------------------------------- /Documentation/ApplicationPointSetExtractorTube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/Documentation/ApplicationPointSetExtractorTube.png -------------------------------------------------------------------------------- /Documentation/ApplicationSpatialSensorFusion.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | \page ApplicationSpatialSensorFusion Spatial sensor fusion (SpatialSensorFusion) 3 | 4 | This tool can be used to compute orientation from raw accelerometer and gyroscope sensor 5 | measurement values. The orientation is computed using sensor fusion of the two sensors. 6 | The filtered tilt sensor provides less noisy measurement (compared to just using the accelerometer), 7 | doesn't suffer from drift around the down axis (like compared to IMU sensors do), and doesn't 8 | suffer from inaccuracies due to magnetic field distortion (like compared to MARG sensors do). 9 | 10 | \section ApplicationSpatialSensorFusionExamples Examples 11 | 12 | ~~~ 13 | SpatialSensorFusion --ahrs-algo=MADGWICK_IMU --ahrs-algo-gain 1.5 --initial-gain 1 --initial-repeated-frame-number=1000 --input-seq-file=C:/devel/_Nightly/PlusBuild-bin-vs9/PlusLib/data/TestImages/SpatialSensorFusionTestInput.mha" "--output-seq-file=C:/devel/_Nightly/PlusBuild-bin-vs9/PlusLib/data/TestImages/SpatialSensorFusionTestOutput.mha --baseline-seq-file=SpatialSensorFusionTestBaseline.mha --west-axis-index=1 14 | ~~~ 15 | 16 | \section ApplicationSpatialSensorFusionHelp Command-line parameters reference 17 | 18 | \verbinclude "SpatialSensorFusionHelp.txt" 19 | 20 | */ 21 | -------------------------------------------------------------------------------- /Documentation/ApplicationfCalCoordinateSystemDefinitions.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ApplicationfCalCoordinateSystemDefinitions Coordinate system definitions used by fCal 4 | 5 | Coordinate systems used in fCal: 6 | 7 | Reference frame name | Origin | Unit | Axes directions 8 | ----------------------|---------|-------|----------------- 9 | Phantom | fCal-2.x and fCal-3.x phantoms: inside end of the A5 hole on the front (see picture).| mm | X axis: from column A to B direction
Y axis: towards the back side of the phantom
Z axis: from row 4 to row 1 direction 10 | Reference | Origin of the marker that is attached to the calibration phantom | mm | as defined by the tracking system / marker manufacturer 11 | TransducerOrigin | Position of the pixel that is in the middle of the first line of the MF oriented image. In PLUS it's only used for approximate visualization of the transducer 3D model. | mm | Same as Image 12 | TransducerOriginPixel | Same as TransducerOrigin | pixel | Same as TransdrucerOrigin 13 | Tracker | \ref CommonCoordinateSystems "see common coordinate systems description" | - | - 14 | Stylus | \ref CommonCoordinateSystems "see common coordinate systems description" | - | - 15 | Probe | \ref CommonCoordinateSystems "see common coordinate systems description" | - | - 16 | StylusTip | \ref CommonCoordinateSystems "see common coordinate systems description" | - | - 17 | Image | \ref CommonCoordinateSystems "see common coordinate systems description" | - | - 18 | 19 | Coordinate systems overview sketch (3D Slicer compatible interactive 3D model of the figure below is available here): 20 | 21 | \image html CoordinateSystemDefinitionsfCal.png 22 | 23 | */ 24 | -------------------------------------------------------------------------------- /Documentation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF(BUILD_DOCUMENTATION) 2 | FIND_PACKAGE(Doxygen REQUIRED) 3 | ENDIF() 4 | 5 | IF(DOXYGEN_FOUND) 6 | IF(DOXYGEN_DOT_FOUND) 7 | # Set up help file format 8 | OPTION(PLUSAPP_DOCUMENTATION_SEARCH_SERVER_INDEXED "Search index for documentation is generated by th web server. Provides full-text search but only works on web servers." OFF) 9 | 10 | OPTION(DOCUMENTATION_GENERATE_XML "Generate intermediate XML documentation" OFF) 11 | SET(GENERATE_XML "NO") 12 | IF(DOCUMENTATION_GENERATE_XML) 13 | SET(GENERATE_XML "YES") 14 | ENDIF() 15 | 16 | SET(GENERATE_HTMLHELP "NO") 17 | SET(SEARCHENGINE "YES") 18 | SET(COMPRESSED_HELP_TARGET_FILE_EXT ".tar.gz") 19 | IF (PLUSAPP_DOCUMENTATION_SEARCH_SERVER_INDEXED) 20 | SET(SERVER_BASED_SEARCH "YES") 21 | ELSE() 22 | SET(SERVER_BASED_SEARCH "NO") 23 | ENDIF() 24 | IF(WIN32) 25 | SET(COMPRESSED_HELP_TARGET_FILE_EXT ".chm") 26 | IF (PLUSAPP_DOCUMENTATION_SEARCH_SERVER_INDEXED) 27 | # search indexing is turned off if HTMLHELP generation is enabled, so we have to disable it 28 | SET(GENERATE_HTMLHELP "NO") 29 | SET(SEARCHENGINE "YES") 30 | ELSE() 31 | SET(GENERATE_HTMLHELP "YES") 32 | SET(SEARCHENGINE "NO") 33 | ENDIF() 34 | ENDIF(WIN32) 35 | 36 | # Parameters for GenerateDoc.cmake 37 | SET(TARGET_NAME "UserManual") 38 | SET(UNCOMPRESSED_HELP_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}) 39 | SET(DOXYGEN_CONFIG_FILE ${UNCOMPRESSED_HELP_TARGET_DIR}/Doxyfile.txt) 40 | SET(CREATE_COMPRESSED_HELP "YES") 41 | SET(COMPRESSED_HELP_TARGET_DIR "${PLUS_EXECUTABLE_OUTPUT_PATH}/Doc") 42 | SET(COMPRESSED_HELP_TARGET_FILE "PlusApp-${TARGET_NAME}${COMPRESSED_HELP_TARGET_FILE_EXT}") 43 | # Other parameters 44 | SET(DOC_OUTPUT_FILE "${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}") 45 | SET(DOC_GENERATION_CMAKE_FILE ${UNCOMPRESSED_HELP_TARGET_DIR}/GenerateDoc.cmake) 46 | 47 | # If a Google Analytics tracking ID is set, configure and specify the modified footer file. 48 | # otherwise, default Doxygen footer will be used 49 | SET(FOOTER_FILE "") 50 | IF (PLUSAPP_DOCUMENTATION_GOOGLE_ANALYTICS_TRACKING_ID STREQUAL "") 51 | ELSE() 52 | SET(FOOTER_FILE ${UNCOMPRESSED_HELP_TARGET_DIR}/html/AnalyticsFooter.html) 53 | CONFIGURE_FILE( AnalyticsFooter.html.in 54 | ${FOOTER_FILE} 55 | ) 56 | ENDIF() 57 | 58 | # Generate doxygen configuration and generator file 59 | CONFIGURE_FILE( Doxyfile.txt.in 60 | ${DOXYGEN_CONFIG_FILE} 61 | ) 62 | CONFIGURE_FILE( 63 | ${CMAKE_CURRENT_SOURCE_DIR}/GenerateDoc.cmake.in 64 | ${DOC_GENERATION_CMAKE_FILE} 65 | @ONLY 66 | ) 67 | # Run doxygen as a custom command driven by a custom target. 68 | ADD_CUSTOM_COMMAND( 69 | OUTPUT ${DOC_OUTPUT_FILE} 70 | COMMAND ${CMAKE_COMMAND} -P "${DOC_GENERATION_CMAKE_FILE}" 71 | DEPENDS "${DOC_GENERATION_CMAKE_FILE}" 72 | "${DOXYGEN_CONFIG_FILE}" 73 | ) 74 | ELSE() 75 | MESSAGE( WARNING 76 | "DOCUMENTATION: GRAPHVIZ DOT TOOL NOT FOUND (http://www.graphviz.org/Download.php, required by Doxygen for diagram generation)- Documentation will not be created" 77 | ) 78 | ENDIF() 79 | ELSE() 80 | SET(DOC_OUTPUT_FILE "") 81 | SET(TARGET_NAME "Editing") 82 | ENDIF() 83 | 84 | # Build the list of dox files for convenient editing 85 | FILE(GLOB PlusAppDocumentation_DOXS ${CMAKE_CURRENT_SOURCE_DIR}/*.dox) 86 | FILE(GLOB PlusLibDocumentation_DOXS ${PLUSLIB_SOURCE_DIR}/src/Documentation/UserManual/*.dox) 87 | ADD_CUSTOM_TARGET(Documentation-PlusApp-${TARGET_NAME} 88 | DEPENDS ${DOC_OUTPUT_FILE} 89 | SOURCES ${PlusLibDocumentation_DOXS} ${PlusAppDocumentation_DOXS}) 90 | SET_TARGET_PROPERTIES(Documentation-PlusApp-${TARGET_NAME} PROPERTIES FOLDER Documentation) 91 | 92 | IF(BUILD_DOCUMENTATION) 93 | SET_TARGET_PROPERTIES(Documentation-PlusApp-${TARGET_NAME} PROPERTIES LABELS Documentation) 94 | ENDIF() -------------------------------------------------------------------------------- /Documentation/Calibration.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page Calibration Calibration 4 | 5 | # Overview 6 | 7 | Typically tracking and imaging devices require spatial and temporal calibration after they are set up. 8 | 9 | # Calibration using fCal 10 | 11 | Spatial calibration algorithms determine unknown transformations that remain constant after the system is set up. 12 | Typically these are transformations between the coordinate systems of an object (e.g., image slice, calibration phantom, stylus) 13 | and a tracking marker that is rigidly attached to that object. 14 | - \ref AlgorithmPivotCalibration is used for computing the transformation between the tip(`StylusTip`) of a pointer tool (a.k.a. stylus) 15 | and the marker that is attached to the tool (`Stylus`). 16 | - \ref AlgorithmPhantomRegistration determines the transformation between the calibration phantom's coordinate system (`Phantom`) 17 | and the attached marker's coordinate system (`Reference`). The method uses landmark registration: transformation between an object 18 | and the attached marker is computed by touching predefined positions on the object with a tracked stylus. 19 | - \ref AlgorithmProbeCalibration is used for determining the transformation between 20 | the coordinate system of the image (`Image`) and the marker that is attached to the US transducer (`Probe`). 21 | 22 | \ref AlgorithmTemporalCalibration determines time offset between data streams acquired by different devices. Temporal calibration 23 | is essential if data is acquired while tracked tools are moving, because then any temporal misalignment results in spatial errors. 24 | 25 | \ref ApplicationfCal implements all the above described calibration algorithms in a single application. 26 | 27 | # Calibration using SlicerIGT modules 28 | 29 | SlicerIGT extension of 3D Slicer contains a number of spatial calibration modules that allow 30 | computing transforms and using them in Plus. 31 | 32 | */ 33 | -------------------------------------------------------------------------------- /Documentation/DataAcquisitionProcessing.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page DataAcquisitionProcessing Data acquisition and processing 4 | 5 | - \subpage ProcedureTrackedUltrasoundRecording 6 | - \subpage ProcedureVolumeReconstruction 7 | - \subpage ProcedureStreamingToSlicer 8 | - \subpage ProcedureUltrasoundSimulation 9 | 10 | - \subpage ApplicationPlusServer 11 | 12 | 13 | */ 14 | -------------------------------------------------------------------------------- /Documentation/DoxygenLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /Documentation/Faq.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page Faq Frequently asked questions 4 | 5 | # How can I check if the coordinate systems are correctly specified? 6 | 7 | All the coordinate frames are defined by transforms between them. All transforms are specified in the \ref FileDeviceSetConfiguration . 8 | 9 | ## Specification of coordinate frames 10 | - Reference frame frame for the tracker devices are specified by \ref ToolReferenceFrame attribute of the \ref Device element. 11 | - Tracker tools defined in the \ref DataSources section of the configuration file 12 | 13 | Example: this section defines three tool coordinate frames (Probe, Reference, Stylus) and a tracker reference frame (Tracker) 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ## Coordinate frames computed by calibration algorithms 36 | 37 | Example: vtkPlusPivotCalibrationAlgo algorithm has two input coordinate frames and one frame that it defines (StylusTip) 38 | 39 | 44 | 45 | ## Custom coordinate frames defined in the CoordinateDefinitions section of the configuration file 46 | 47 | Example: this section defines the TransducerOrigin frame that is defined by a transform linked to the Image coordinate frame and defines an alias for the Tracker coordinate frame by binding it to the AscensionDevice frame using an identity matrix 48 | 49 | 50 | 53 | 56 | 57 | 58 | # Display of coordinate frames 59 | 60 | fCal can display any of the existing coordinate frames by attaching a displayed object (coordinate system axes, a surface model, image, etc.) to the frame. These are defined in the Rendering section of the configuration file. 61 | 62 | fCal application shows shows every object in its world coordinate system. This coordinate system is defined by the WorldCoordinateFrame attribute. 63 | 64 | Following objects can be visualized: 65 | - Axes: coordinate system axes (with the red arrow pointing to the +X, the green to the +Y and the blue to the +Z direction of the defined object coordinate frame) 66 | - Model: 3D model files are attached to each object using an STL file name (that is automatically searched for in the configuration directory, or can be defined using an absolute path) and a transform matrix that transforms the model points to the coordinate frame correctly (e.g., the stylus model is aligned so that its tip is at the origin and its body is on the -X axis). 67 | - Determining the ModelToObjectTransform matrix: In STL files the surface points are described in a coordinate system (Model) that is not necessary meaningful (e.g., the origin may be at one extreme surface point). Therefore an additional coordinate system (Object) can be specified that has its origin at a characteristic position (e.g., the tip of the stylus, or the middle of the transducer of the probe) and its axes are aligned with characteristic orientations of the object. To determine the ModelToObject transform, load the STL model into a 3D visualization application (such as Paraview) and retrieve the position of the characteristic point that you want to use as origin and use it in the translation component of the transformation matrix. Using the rotation component of the transformation matrix you can define arbitrary object axes orientations. 68 | - Image: the acquired US image slice 69 | 70 | Example: 71 | - The application shows every object relative to the Reference coordinate frame (that we defined as world) 72 | - 3D model of the probe is displayed in the custom TransducerOrigin coordinate frame 73 | - 3D model of the stylus model in the StylusTip coordinate frame 74 | - 3D model of the calibration phantom in the Phantom coordinate frame 75 | - The input image is displayed as an Image in the Image coordinate frame 76 | - The Probe coordinate frame is displayed with its three axes 77 | 78 | ~~~ 79 | 80 | 83 | 86 | 89 | 90 | 91 | 92 | ~~~ 93 | 94 | # How to determine the what hardware SDK versions are actually used by Plus 95 | 96 | The pre-built Plus binaries usually contain the latest hardware SDK. Run PlusVersion.exe to print the version of all the used hardware SDKs. 97 | 98 | # How to generate sequence metafile that contains ImageToReference transforms 99 | 100 | Use \ref ApplicationEditSequenceFile - see the examples. 101 | 102 | # What causes this error: "Angle difference between interpolated orientation is large, interpolation may be inaccurate"? 103 | 104 | This message indicates that the angle difference between two subsequent pose measurements is too large. 105 | 106 | Possible reasons: 107 | - tool is moved (rotated) too quickly: move the tools slower 108 | - acquisition rate is very low: increase AcquisitionRate attribute of the Device in the Device set configuration file 109 | - pose tracking sensor is damaged: can be confirmed by visualizing the tool position in 3D and check if it follows the actual motion of the tool 110 | 111 | \section Questions Any questions? 112 | 113 | To ask any questions, register at github.com and 114 | create a new discussion. 115 | 116 | */ 117 | -------------------------------------------------------------------------------- /Documentation/GenerateDoc.cmake.in: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # Apply settings 3 | 4 | set(DOXYGEN_CONFIG_FILE "@DOXYGEN_CONFIG_FILE@") 5 | set(UNCOMPRESSED_HELP_TARGET_DIR "@UNCOMPRESSED_HELP_TARGET_DIR@") 6 | set(CREATE_COMPRESSED_HELP "@CREATE_COMPRESSED_HELP@") 7 | set(COMPRESSED_HELP_TARGET_DIR "@COMPRESSED_HELP_TARGET_DIR@") 8 | set(COMPRESSED_HELP_TARGET_FILE "@COMPRESSED_HELP_TARGET_FILE@") 9 | 10 | # ---------------------------------------------------------------------------- 11 | # Generate documentation 12 | 13 | execute_process( 14 | COMMAND "@DOXYGEN_EXECUTABLE@" "${DOXYGEN_CONFIG_FILE}" 15 | WORKING_DIRECTORY ${UNCOMPRESSED_HELP_TARGET_DIR} 16 | RESULT_VARIABLE rv 17 | ) 18 | 19 | if(rv) 20 | message(FATAL_ERROR "error: Failed to generate documentation") 21 | endif() 22 | 23 | # ---------------------------------------------------------------------------- 24 | # Create the compressed help file (chm on Windows, tar.gz on other OS) 25 | 26 | if(CREATE_COMPRESSED_HELP) 27 | if(WIN32) 28 | if(EXISTS "${UNCOMPRESSED_HELP_TARGET_DIR}/html/${COMPRESSED_HELP_TARGET_FILE}") 29 | file(COPY "${UNCOMPRESSED_HELP_TARGET_DIR}/html/${COMPRESSED_HELP_TARGET_FILE}" DESTINATION ${COMPRESSED_HELP_TARGET_DIR}) 30 | message(STATUS "info: created '${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}'") 31 | else() 32 | message(STATUS "warning: could not create '${UNCOMPRESSED_HELP_TARGET_DIR}/html/${COMPRESSED_HELP_TARGET_FILE}'") 33 | endif() 34 | else() 35 | file(REMOVE "${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}") 36 | execute_process(COMMAND ${CMAKE_COMMAND} -E tar cfz ${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE} html 37 | WORKING_DIRECTORY ${UNCOMPRESSED_HELP_TARGET_DIR} 38 | RESULT_VARIABLE rv 39 | ) 40 | if(EXISTS "${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}") 41 | message(STATUS "info: created '${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}'") 42 | else() 43 | message(STATUS "warning: could not create '${COMPRESSED_HELP_TARGET_DIR}/${COMPRESSED_HELP_TARGET_FILE}'") 44 | endif() 45 | endif() 46 | endif() 47 | -------------------------------------------------------------------------------- /Documentation/MainPage.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \mainpage 4 | 5 | \section PlusAppIntro Introduction 6 | 7 | Plus (Public software Library for UltraSound) is an open-source software package for tracked ultrasound image acquisition, calibration, and processing. Plus applications include complete end-user software applications for spatial and temporal calibration (fCal) and real-time data acquisition, processing and streaming (PlusServer). For building complete image-guided therapy applications you can use the 3D Slicer and the SlicerIGT extension. 8 | 9 | Overview papers and presentations: 10 | - Paper published in IEEE-TBME 11 | - Technology overview presentation 12 | - Overview presentation with some clinical applications 13 | - Multi-channel architecture overview presentation 14 | 15 | \par Download 16 | 17 | Click here to download pre-compiled Plus applications releases. 18 | 19 | \par Tutorials 20 | 21 | The SlicerIGT website contains an extensive set of step-by-step tutorials for building image-guided therapy systems from readily-available components. 22 | 23 | \par How to cite 24 | 25 | Please cite the following paper when referring to Plus in your publication: 26 | 27 | Andras Lasso, Tamas Heffter, Adam Rankin, Csaba Pinter, Tamas Ungi, and Gabor Fichtinger, "PLUS: Open-source toolkit for ultrasound-guided intervention systems", IEEE Trans Biomed Eng. 2014 Oct;61(10):2527-37. doi: 10.1109/TBME.2014.2322864 28 | 29 |
30 | @@ARTICLE{Lasso2014a,
31 |   title = {PLUS: Open-source toolkit for ultrasound-guided intervention systems},
32 |   author = {Andras Lasso and Tamas Heffter and Adam Rankin and Csaba Pinter and Tamas Ungi and Gabor Fichtinger},
33 |   journal = {IEEE Transactions on Biomedical Engineering},
34 |   year = {2014},
35 |   month = {Oct},
36 |   number = {10},
37 |   pages = {2527-2537},
38 |   doi = {10.1109/TBME.2014.2322864},
39 |   pmid = {24833412},
40 |   url = {http://perk.cs.queensu.ca/contents/plus-open-source-toolkit-ultrasound-guided-intervention-systems}
41 | }
42 | 
43 | 44 | \par License 45 | 46 | Plus has a BSD-style license, which allows any kind of use for free. See more details in License.txt 47 | 48 | \par More information 49 | 50 | - All information about the Plus project is publicly available at www.plustoolkit.org. 51 | - Register at github.com and visit the PlusLib GitHub page to submit messages, bug reports, feature requests, and get email notifications. 52 | - Information for developers on building Plus, adding new devices, or contributing can be found at github.com. 53 | 54 | \par Additional resources 55 | 56 | - Plus 3D model catalog contains printable 3D models of tools and tracking fixtures. 57 | - pyIGTL contains a Python interface that can be used to receive send/receive live data from Plus in Python, and is installable using pip. 58 | - Plus Matlab Utils contains a MatLab interface to read data recorded by Plus and send/receive live data from Plus in Matlab. 59 | 60 | */ 61 | -------------------------------------------------------------------------------- /Documentation/PlusAppDoxygenStyle.css: -------------------------------------------------------------------------------- 1 | BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { 2 | font-family: Geneva, Arial, Helvetica, sans-serif; 3 | } 4 | BODY,TD { 5 | font-size: 110%; 6 | font-weight: bold 7 | } 8 | H1 { 9 | /*text-align: center;*/ 10 | font-size: 105%; 11 | font-weight: bold 12 | } 13 | H2 { 14 | font-size: 103%; 15 | font-weight: bold; 16 | font-style: italic 17 | } 18 | H3 { 19 | font-size: 100%; 20 | } 21 | 22 | div.image 23 | { 24 | /*position:inherit;*/ 25 | /*top:0px;*/ 26 | /*left:5px;*/ 27 | text-align: left; 28 | display:inline 29 | } 30 | div.image img[src="required.png"]{ 31 | /*position:relative;*/ 32 | width:14px; 33 | height: 14px; 34 | } 35 | div.image img[src="optional.png"]{ 36 | position:relative; 37 | width:8px; 38 | height: 8px; 39 | bottom:4px; 40 | } 41 | div.caption{ 42 | text-align: left; 43 | display:inline; 44 | font-weight:normal 45 | } -------------------------------------------------------------------------------- /Documentation/PlusServerLauncherRemote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/Documentation/PlusServerLauncherRemote.png -------------------------------------------------------------------------------- /Documentation/ProcedureStreamingToSlicer.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ProcedureStreamingToSlicer Streaming of live images and tracking data to 3D Slicer 4 | 5 | # Installation 6 | 7 | - Download and install the latest nightly PlusApp release (PlusApp-...-Win64.exe is recommended) 8 | - Download and Install 3D Slicer (64-bit nightly build is recommended) 9 | - Install the SlicerOpenIGTLink extension in 3D Slicer 10 | - Install the SlicerIGT extension in 3D Slicer 11 | 12 | # Show live images in 3D Slicer 13 | - In the Windows start menu in the Plus Applications ... folder open Plus Server Launcher 14 | - Choose your device set that describes according to your imaging device, for example use PlusServer: Media Foundation video capture device or PlusServer: Video for Windows video capture device for image acquisition from a webcam. Optionally click on the small edit icon on the left side of the device selector to customize the imaging parameters. Details for device setup can be found here 15 | - Click Launch server 16 | - In the Windows start menu in the Slicer ... folder open Slicer 17 | - Open the OpenIGTLinkIF module and click on the \c + button to create a new connection 18 | - Change the connection port to match the out corresponding "ListeningPort" in the Plus device file (for many configurations, the port is 18944), and click on the Active checkbox to start receiving data. The status of the connection should be "ON" 19 | - Open the View Controllers module and select Image_Reference in the listbox in the background image selector listbox (in the red slice's section, on the right side of the orientation selection listbox that shows Axial) 20 | - Open the VolumeResliceDriver module (if you don't see it, install the SlicerIGT extension), choose Image_Reference to drive the red slice and set the mode to Transverse 21 | 22 | # Show tracked tools in 3D Slicer 23 | - In the Windows start menu in the Plus Applications ... folder open Plus Server Launcher 24 | - Choose your device set that describes according to your imaging device, for example use PlusServer: Replay fCal phantom... device set for replaying a pre-recorded tracking data sequence. If you have access to a tracker you can connect a tracking device set (e.g., PlusServer: Ascension3DG tracker, PlusServer: NDI Aurora tracker, PlusServer: Claron MicronTracker tracker) and click on the small edit icon on the left side of the device selector to customize its parameters. 25 | - Click Launch server 26 | - In the Windows start menu in the Slicer ... folder open Slicer 27 | - Open the OpenIGTLinkIF module and click on the \c + button to create a new connection 28 | - Change the connection port to match the out corresponding "ListeningPort" in the Plus device file (for many configurations, the port is 18944), and click on the Active checkbox to start receiving data. The status of the connection should be "ON" 29 | - In the I/O Configuration section in the data tree open IGTLConnector, open IN, then click on the eye icon on the right side for the tools that you want to see in the 3D view 30 | - If you have STL models of your tools then you can load them into Slicer and assign the corresponding transform in the Transforms module 31 | 32 | # More information 33 | - SlicerIGT: tools in 3D Slicer for implementing image-guided intervention systems 34 | - Description and tutorial about the SlicerOpenIGTLink extension 35 | 36 | */ 37 | -------------------------------------------------------------------------------- /Documentation/ProcedureTrackedUltrasoundRecording.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ProcedureTrackedUltrasoundRecording Tracked ultrasound recording 4 | 5 | \section ProcedureTrackedUltrasoundRecordingGeneral General instructions 6 | - Start the fCal application (fCal.exe) 7 | - Select the device set, connect 8 | - Verify that the system is properly calibrated and the image depth is correct (e.g., by using a stylus and an image: verify that the stylus tip appears on the US image as a bright spot at exactly the same location as the stylus tip of the displayed surface model) 9 | - Switch to the "Capturing" tab 10 | - Click "Snapshot" to acquire a single frame / click "Record" to acquire a sequence of image frames 11 | - Click Save to save the acquired frames into a file 12 | 13 | \section ProcedureTrackedUltrasoundRecordingTips Tips & tricks 14 | 15 | - For easier triggering of point acquisition for phantom registration or starting/stopping calibration or capturing, we use a foot pedal. More specifically this model: 16 | http://www.scythe-usa.com/product/input/008/usbfootswitch_detail.html 17 | 18 | \section ProcedureTrackedUltrasoundRecordingRfAcquisition RF data acquisition 19 | 20 | Currently RF acquisition is supported for Ultrasonix scanners (through the Ulterius interface) and BK Medical ProFocus scanners (through CameraLink interface). 21 | 22 | When RF data is acquired in fCal a very simple RF->B-mode image conversion is performed and the converted B-mode image is displayed on the screen. The definition of scan conversion parameters are defined in UltrasoundImageOrientation.pptx. 23 | 24 | Note that currently only data collection is implemented in fCal, calibration is only supported in B-mode image acquisition mode. 25 | 26 | \subsection ProcedureTrackedUltrasoundRecordingRfAcquisitionUltrasonix Ultrasonix 27 | 28 | \subsubsection ProcedureTrackedUltrasoundRecordingRfAcquisitionUltrasonixTesting Testing the RF acquisition 29 | 30 | The simplest way to test if RF acquisition works is by running the following test: 31 | vtkPlusSonixVideoSourceTest1.exe --sonix-ip=130.15.7.20 --acq-mode=rf 32 | 33 | If the system is not in research mode or there is a popup window displayed in the Ultrasonix exam software then it may not be possible to switch into RF acquisition mode. Before attempting to acquire RF data in Plus test if you can actually acquire RF data in the exam software (you may need to click on the Research touchscreen button, RF touchscreen button and press the Update/RightMouse physical button to enable RF acquisition). 34 | 35 | \subsubsection ProcedureTrackedUltrasoundRecordingRfAcquisitionUltrasonixAcquiring Acquiring tracked RF data 36 | 37 | In the DataCollection and RfProcessing elements set the following attributes and child elements: 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 63 | 64 | 65 | 66 | 67 | 68 | It may be necessary to push the Update button on the ultrasound machine (the one that acts as roght mouse click in research mode; a spot with two arrows around it). 69 | 70 | \subsection ProcedureTrackedUltrasoundRecordingRfAcquisitionBk BK Medical 71 | 72 | \subsubsection ProcedureTrackedUltrasoundRecordingRfAcquisitionBkTesting Testing the RF acquisition 73 | 74 | The simplest way to test if RF acquisition works is by running the following test: 75 | vtkBkProFocusVideoSourceTest.exe --ini-file=BkSettings/IniFile.ini --show-bmode --show-sapera 76 | 77 | \subsubsection ProcedureTrackedUltrasoundRecordingRfAcquisitionBkAcquisring Acquiring tracked RF data 78 | 79 | In the DataCollection and RfProcessing elements set the following attributes and child elements: 80 | 81 | 82 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 97 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | */ 114 | -------------------------------------------------------------------------------- /Documentation/ProcedureUltrasoundSimulation.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ProcedureUltrasoundSimulation Ultrasound simulation 4 | 5 | See detailed description of the algorithm parameters at the \ref DeviceUsSimulator device page. 6 | 7 | \section UsSimulatorExample Example 8 | 9 | - Download the following files from https://github.com/PlusToolkit/PlusLibData/tree/master/ConfigFiles/ 10 | - PlusDeviceSet_Server_SimulatedUltrasound_3DSlicer.xml 11 | - SimulatedUltrasound_GelBlockModel_Reference.stl 12 | - SimulatedUltrasound_NeedleModel_NeedleTip.stl 13 | - SimulatedUltrasound_VesselModel_Reference.stl 14 | - SimulatedUltrasound_Scene.mrb 15 | - Download and install the latest nightly build of 3D Slicer and the SlicerOpenIGTLink and SlicerIGT extensions 16 | - Load the SimulatedUltrasound_Scene.mrb file into 3D Slicer 17 | - Open a Plus applications command prompt and run 18 | 19 | `PlusServer.exe --config-file=PlusDeviceSet_Server_SimulatedUltrasound_3DSlicer.xml` 20 | 21 | - In Slicer go to the Transforms module and modify the ProbeToTracker and NeedleToTracker transforms 22 | 23 | Watch on Youtube. 24 | 25 | \image html VascularUsSimScreenshot.png 26 | 27 | Related publications 28 | http://perk.cs.queensu.ca/contents/open-source-surface-mesh-based-ultrasound-guided-spinal-intervention-simulator 29 | 30 | */ 31 | -------------------------------------------------------------------------------- /Documentation/ProcedureVolumeReconstruction.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ProcedureVolumeReconstruction Volume reconstruction 4 | 5 | Volume reconstruction is the process of creating a 3D volume from many 2D image slices. 6 | Parameters of the volume reconstruction algorithm are described on the \ref AlgorithmVolumeReconstruction page. 7 | 8 | \section ProcedureVolumeReconstructionCommandLine Volume reconstruction using command-line application 9 | 10 | Use the \ref ApplicationVolumeReconstructor application. 11 | 12 | \section ProcedureVolumeReconstructionSlicer Volume reconstruction in 3D Slicer 13 | 14 | Use the PlusRemote module in 3D Slicer, avaiable in the SlicerOpenIGTLink extension. 15 | 16 | \section ProcedureVolumeReconstructionfCal Volume reconstruction using fCal 17 | 18 | \ref ApplicationfCal offers a graphical user interface to collect tracked ultrasound data 19 | and perform volume reconstruction. Currently fCal offers only very limited, simplified 20 | visualization (shows an isosurface corresponding to a single, hardcoded threshold value), 21 | so it is recommended to save the volume into a (.mha) file and visualize it in 3DSlicer. 22 | 23 | */ 24 | -------------------------------------------------------------------------------- /Documentation/ReportError.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page ReportError How to report an error 4 | 5 | # Software error 6 | 7 | If you encounter an error, please follow the following instructions to help us to find and fix it more quickly. 8 | - Try to reproduce the error and filter out what steps are really required for the error to occur 9 | - Create an issue on GitHub. 10 | - Describe exactly what steps you made before the error occurred 11 | - Describe what is the unexpected behaviour 12 | - Attach the log file to the ticket 13 | - It is located in the directory named Output inside the folder you executed the application 14 | - It is named [date]_[time]_PlusLog.txt 15 | - Choose the one that was created when you ran the application performing only the steps that really needed (see first step) 16 | - If needed for easier understanding, attach a screenshot. Use compressed format (like .png, .jpg, .gif). 17 | 18 | Thank you for helping to improve Plus! 19 | 20 | # Documentation error 21 | 22 | If you find a documentation error on the wiki then create an issue on GitHub. 23 | 24 | */ 25 | -------------------------------------------------------------------------------- /Documentation/Specifications.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page Specifications Specifications 4 | 5 | Commonly used specifications: 6 | - \subpage UltrasoundImageOrientation 7 | - \subpage CommonCoordinateSystems 8 | - \subpage ApplicationfCalCoordinateSystemDefinitions 9 | - \subpage TransformationMatrix 10 | - \subpage PlusServerCommands 11 | 12 | File formats: 13 | - \subpage FileDeviceSetConfiguration 14 | - \subpage FileApplicationConfiguration 15 | - \subpage FileSequenceFile 16 | - \subpage FileLog 17 | 18 | */ 19 | -------------------------------------------------------------------------------- /Documentation/Tools.dox: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page Tools Tools 4 | 5 | The following command-line tools can be executed by starting the Plus command prompt and entering the name of the tool executable file and parameters. 6 | 7 | Tool | Description 8 | ---------------------------------------------|-------------- 9 | \subpage ApplicationCreateSliceModels | Create 3D surface model showing 2D slice positions (for volume reconstruction troubleshooting) 10 | \subpage ApplicationDiagDataCollection | Diagnose data collection from devices 11 | \subpage ApplicationDrawClipRegion | Show clip rectangle and fan over ultrasound images 12 | \subpage ApplicationDrawScanLines | Show scanlines over scan-converted ultrasound images 13 | \subpage ApplicationEditSequenceFile | Edit sequence files (trim, merge, compress/uncompress, etc.) 14 | \subpage ApplicationEnhanceUsTrpSequence | Command line tool to use vtkPlusTransverseProcessEnhancer device on US image sequence mha file 15 | \subpage ApplicationExtractScanLines | Extract scan lines and write into rectangular images 16 | \subpage ApplicationfCal | Calibrate tracked ultrasound probe and tracked tools spatially and temporally 17 | \subpage ApplicationPlusServer | Acquire data from devices and broadcast through OpenIGTLink 18 | \subpage ApplicationPlusVersion | Print the version of Plus and all hardware SDKs 19 | \subpage ApplicationPointSetExtractor | Create 3D surface model (points or tube) from tool trajectory 20 | \subpage ApplicationProbeCalibration | Calibrate the ultrasound probe from pre-recorded data (compute ImageToProbe transform) 21 | \subpage ApplicationRfProcessor | Convert RF data to displayable B-mode images 22 | \subpage ApplicationScanConvert | Scan conversion to output geometrically correct images 23 | \subpage ApplicationSpatialSensorFusion | Compute orientation from accelerometer, gyroscope, and magnetometer measurements 24 | \subpage ApplicationTemporalCalibration | Compute time offset between two streams 25 | \subpage ApplicationTrackingTest | View tracker tool positions in 3D 26 | \subpage ApplicationViewSequenceFile | View sequence file frames in 3D 27 | \subpage ApplicationVolumeReconstructor | Reconstruct 3D ultrasound volume from 2D slices 28 | 29 | */ 30 | -------------------------------------------------------------------------------- /PlusAppConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # - Config file for the PlusApp package 2 | # It defines the following variables 3 | # PlusApp_INCLUDE_DIRS - include directories for PlusApp 4 | # PlusApp_LIBRARY_DIRS - library directories for PlusApp (normally not used!) 5 | # PlusApp_LIRARIES - list of targets exported by this package 6 | 7 | # Resolve needed dependencies 8 | SET(Qt5_DIR @Qt5_DIR@) 9 | FIND_PACKAGE(Qt5 REQUIRED COMPONENTS @PLUSAPP_QT_COMPONENTS@) 10 | SET(PlusLib_DIR @PlusLib_DIR@) 11 | FIND_PACKAGE(PlusLib REQUIRED PATHS "${PlusLib_DIR}/src" NO_MODULE) 12 | 13 | # Tell the user project where to find our headers and libraries 14 | SET(PlusApp_INCLUDE_DIRS "@PLUSAPP_INCLUDE_DIRS@") 15 | SET(PlusApp_LIBRARY_DIRS "@PLUSAPP_LIBRARY_DIRS@") 16 | SET(PlusApp_LIBRARIES "@PLUSAPP_LIBRARIES@") 17 | 18 | # Tell the user project where to find PlusApp use file 19 | SET(PlusApp_USE_FILE "@CMAKE_CURRENT_BINARY_DIR@/UsePlusApp.cmake" ) 20 | 21 | # Include targets generated by PlusApp (contains definitions for IMPORTED targets) 22 | include("@CMAKE_CURRENT_BINARY_DIR@/PlusAppLibraryTargets.cmake") 23 | 24 | -------------------------------------------------------------------------------- /PlusAppConfigVersion.cmake.in: -------------------------------------------------------------------------------- 1 | SET(PACKAGE_VERSION "@PLUSAPP_VERSION@") # Check whether the requested PACKAGE_FIND_VERSION is compatible IF("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") SET(PACKAGE_VERSION_COMPATIBLE FALSE) ELSE() SET(PACKAGE_VERSION_COMPATIBLE TRUE) IF ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") SET(PACKAGE_VERSION_EXACT TRUE) ENDIF() ENDIF() -------------------------------------------------------------------------------- /PlusConfig.xml.in: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /PlusServerLauncher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(PlusServerLauncher) 2 | 3 | # -------------------------------------------------------------------------- 4 | # Sources 5 | SET(PlusServerLauncher_SRCS 6 | PlusServerLauncherMain.cxx 7 | PlusServerLauncherMainWindow.cxx 8 | ) 9 | 10 | IF(WIN32) 11 | SET(PlusServerLauncher_SRCS 12 | ${PlusServerLauncher_SRCS} 13 | PlusServerLauncher.rc 14 | ) 15 | ENDIF() 16 | 17 | SET(PlusServerLauncher_UI_HDRS 18 | PlusServerLauncherMainWindow.h 19 | ) 20 | 21 | SET(PlusServerLauncher_UI_SRCS 22 | PlusServerLauncherMainWindow.ui 23 | ) 24 | 25 | SET(PlusServerLauncher_QT_Resources 26 | PlusServerLauncher.qrc 27 | ${PLUSLIB_WIDGETS_QRC} 28 | ) 29 | 30 | # -------------------------------------------------------------------------- 31 | # Build the library 32 | SET (PlusServerLauncher_LIBS 33 | Qt5::Widgets 34 | Qt5::Network 35 | vtkPlusCommon 36 | PlusWidgets 37 | vtkPlusServer 38 | ) 39 | IF(TARGET vtkRenderingGL2PS${VTK_RENDERING_BACKEND}) 40 | LIST(APPEND PlusServerLauncher_LIBS 41 | vtkRenderingGL2PS${VTK_RENDERING_BACKEND} 42 | ) 43 | ELSEIF(TARGET vtkRenderingGL2PS) 44 | LIST(APPEND PlusServerLauncher_LIBS 45 | vtkRenderingGL2PS 46 | ) 47 | ENDIF() 48 | 49 | IF(TARGET igtlioLogic) 50 | LIST(APPEND PlusServerLauncher_LIBS igtlioLogic) 51 | ENDIF() 52 | 53 | SET (APP_MODE MACOSX_BUNDLE) 54 | IF(WIN32) 55 | # Create a windowed application (do not show a console) 56 | SET (APP_MODE WIN32) 57 | ENDIF() 58 | 59 | AddPlusQt5Executable( PlusServerLauncher ${APP_MODE} 60 | ${PlusServerLauncher_SRCS} 61 | ${PlusServerLauncher_UI_HDRS} 62 | ${PlusServerLauncher_UI_SRCS} 63 | ${PlusServerLauncher_QT_Resources} 64 | ) 65 | SET_TARGET_PROPERTIES(PlusServerLauncher PROPERTIES COMPILE_DEFINTIIONS 66 | ${Qt5Widgets_COMPILE_DEFINITIONS} 67 | ${Qt5Network_COMPILE_DEFINITIONS} 68 | ) 69 | target_include_directories(PlusServerLauncher PRIVATE 70 | ${CMAKE_CURRENT_BINARY_DIR} 71 | ${CMAKE_CURRENT_SOURCE_DIR} 72 | ) 73 | TARGET_LINK_LIBRARIES( PlusServerLauncher PRIVATE ${PlusServerLauncher_LIBS} ) 74 | 75 | # -------------------------------------------------------------------------- 76 | # Install 77 | IF(PLUSAPP_INSTALL_BIN_DIR) 78 | INSTALL(TARGETS PlusServerLauncher 79 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 80 | COMPONENT RuntimeExecutables 81 | ) 82 | ENDIF() -------------------------------------------------------------------------------- /PlusServerLauncher/PlusServerLauncher.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/icon_ConnectLarge.ico 4 | Resources/icon_Edit.png 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PlusServerLauncher/PlusServerLauncher.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "Resources\icon_ConnectLarge.ico" -------------------------------------------------------------------------------- /PlusServerLauncher/PlusServerLauncherMain.cxx: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #include "PlusConfigure.h" 8 | 9 | #ifdef _WIN32 10 | #include 11 | #include 12 | #endif 13 | 14 | #include "vtksys/CommandLineArguments.hxx" 15 | #include "vtksys/SystemTools.hxx" 16 | #include "vtksys/Encoding.hxx" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "PlusServerLauncherMainWindow.h" 26 | 27 | #include "vtkXMLUtilities.h" 28 | 29 | #ifdef _WIN32 30 | 31 | class QMessageBoxResize: public QMessageBox 32 | { 33 | public: 34 | QMessageBoxResize() 35 | { 36 | setMouseTracking(true); 37 | setSizeGripEnabled(true); 38 | } 39 | private: 40 | virtual bool event(QEvent* e) 41 | { 42 | bool res = QMessageBox::event(e); 43 | switch (e->type()) 44 | { 45 | case QEvent::MouseMove: 46 | case QEvent::MouseButtonPress: 47 | { 48 | setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); 49 | if (QWidget* textEdit = findChild()) 50 | { 51 | textEdit->setMaximumHeight(QWIDGETSIZE_MAX); 52 | } 53 | } 54 | break; 55 | default: 56 | break; 57 | } 58 | return res; 59 | } 60 | }; 61 | 62 | //----------------------------------------------------------------------------- 63 | void DisplayMessage(QString msg, QString detail, bool isError) 64 | { 65 | QMessageBoxResize msgBox; 66 | if (isError) 67 | { 68 | msgBox.setIcon(QMessageBox::Critical); 69 | } 70 | 71 | // Set width to half of screen size 72 | QRect rec = QApplication::desktop()->screenGeometry(); 73 | QSpacerItem* horizontalSpacer = new QSpacerItem(0.5 * rec.width(), 0, QSizePolicy::Minimum, QSizePolicy::Fixed); 74 | QGridLayout* layout = (QGridLayout*)msgBox.layout(); 75 | layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount()); 76 | 77 | msgBox.setText(msg); 78 | if (!detail.isEmpty()) 79 | { 80 | msgBox.setDetailedText(detail); 81 | if (QWidget* textEdit = msgBox.findChild()) 82 | { 83 | QFont font; 84 | font.setFamily("Courier"); 85 | font.setFixedPitch(true); 86 | font.setPointSize(8); 87 | textEdit->setFont(font); 88 | } 89 | } 90 | msgBox.exec(); 91 | } 92 | 93 | #else 94 | 95 | //----------------------------------------------------------------------------- 96 | void DisplayMessage(QString msg, QString detail, bool isError) 97 | { 98 | if (isError) 99 | { 100 | QTextStream ts(stderr); 101 | ts << "ERROR: " << msg << "\n"; 102 | if (!detail.isEmpty()) 103 | { 104 | ts << detail << "\n"; 105 | } 106 | } 107 | else 108 | { 109 | QTextStream ts(stdout); 110 | ts << msg << "\n"; 111 | if (!detail.isEmpty()) 112 | { 113 | ts << detail << "\n"; 114 | } 115 | } 116 | } 117 | 118 | #endif 119 | 120 | //----------------------------------------------------------------------------- 121 | int appMain(int argc, char* argv[]) 122 | { 123 | QApplication app(argc, argv); 124 | 125 | bool printHelp(false); 126 | std::string deviceSetConfigurationDirectoryPath; 127 | std::string inputConfigFileName; 128 | bool autoConnect = false; 129 | int remoteControlServerPort = PlusServerLauncherMainWindow::RemoteControlServerPortUseDefault; 130 | 131 | if (argc > 1) 132 | { 133 | int verboseLevel = -1; 134 | 135 | vtksys::CommandLineArguments cmdargs; 136 | cmdargs.Initialize(argc, argv); 137 | 138 | bool printHelp(false); 139 | 140 | cmdargs.AddArgument("--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp, "Print this help."); 141 | cmdargs.AddArgument("--device-set-configuration-dir", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &deviceSetConfigurationDirectoryPath, "Device set configuration directory path"); 142 | cmdargs.AddArgument("--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName, "Configuration file name"); 143 | cmdargs.AddBooleanArgument("--connect", &autoConnect, "Automatically connect after the application is started"); 144 | cmdargs.AddArgument("--port", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &remoteControlServerPort, "OpenIGTLink port number where the launcher will listen for remote control requests. If set to -1 then no remote control server will be launched. Default = 18904."); 145 | cmdargs.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug)"); 146 | 147 | if (!cmdargs.Parse()) 148 | { 149 | QString cmdArgsString; 150 | for (int i = 0; i < argc; i++) 151 | { 152 | cmdArgsString.append(argv[i]); 153 | cmdArgsString.append(" "); 154 | } 155 | QString msg = QString("Problem parsing command-line argument [%1]: %2

Complete command line:
%3").arg(cmdargs.GetLastArgument() + 1).arg(argv[cmdargs.GetLastArgument() + 1]).arg(cmdArgsString); 156 | QString details; 157 | details.append("Command-line options:\n"); 158 | details.append(cmdargs.GetHelp()); 159 | DisplayMessage(msg, details, true); 160 | exit(EXIT_FAILURE); 161 | } 162 | 163 | if (printHelp) 164 | { 165 | QString msg; 166 | msg.append("Command-line options:

");
167 |       msg.append(cmdargs.GetHelp());
168 |       msg.append("
"); 169 | QString details; 170 | DisplayMessage(msg, details, false); 171 | exit(EXIT_SUCCESS); 172 | } 173 | 174 | if (!deviceSetConfigurationDirectoryPath.empty()) 175 | { 176 | vtkPlusConfig::GetInstance()->SetDeviceSetConfigurationDirectory(deviceSetConfigurationDirectoryPath.c_str()); 177 | } 178 | if (!inputConfigFileName.empty()) 179 | { 180 | vtkPlusConfig::GetInstance()->SetDeviceSetConfigurationFileName(inputConfigFileName.c_str()); 181 | } 182 | 183 | if (verboseLevel > -1) 184 | { 185 | vtkPlusLogger::Instance()->SetLogLevel(verboseLevel); 186 | } 187 | } 188 | 189 | // Start the application 190 | PlusServerLauncherMainWindow mainWindow(0, 0, autoConnect, remoteControlServerPort); 191 | if (mainWindow.GetHideOnStartup()) 192 | { 193 | mainWindow.hide(); 194 | } 195 | else 196 | { 197 | mainWindow.show(); 198 | } 199 | 200 | int retValue = app.exec(); 201 | return retValue; 202 | } 203 | 204 | #ifdef _WIN32 205 | 206 | int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 207 | { 208 | Q_UNUSED(hInstance); 209 | Q_UNUSED(hPrevInstance); 210 | Q_UNUSED(nShowCmd); 211 | 212 | // CommandLineToArgvW has no narrow-character version, so we get the arguments in wide strings 213 | // and then convert to regular string. 214 | int argc = 0; 215 | LPWSTR* argvStringW = CommandLineToArgvW(GetCommandLineW(), &argc); 216 | 217 | std::vector< const char* > argv(argc); // usual const char** array used in main() functions 218 | std::vector< std::string > argvString(argc); // this stores the strings that the argv pointers point to 219 | for (int i = 0; i < argc; i++) 220 | { 221 | argvString[i] = vtksys::Encoding::ToNarrow(argvStringW[i]); 222 | argv[i] = argvString[i].c_str(); 223 | } 224 | 225 | LocalFree(argvStringW); 226 | 227 | return appMain(argc, const_cast< char** >(&argv[0])); 228 | } 229 | 230 | #else 231 | 232 | int main(int argc, char* argv[]) 233 | { 234 | return appMain(argc, argv); 235 | } 236 | 237 | #endif 238 | -------------------------------------------------------------------------------- /PlusServerLauncher/PlusServerLauncherMainWindow.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __PlusServerLauncherMainWindow_h 8 | #define __PlusServerLauncherMainWindow_h 9 | 10 | #include "PlusConfigure.h" 11 | #include "ui_PlusServerLauncherMainWindow.h" 12 | 13 | // Qt includes 14 | #include 15 | #include 16 | #include 17 | 18 | // OpenIGTLinkIO includes 19 | #include 20 | #include 21 | #include 22 | 23 | class QComboBox; 24 | class QPlusDeviceSetSelectorWidget; 25 | class QProcess; 26 | class QTimer; 27 | class QWidget; 28 | class vtkPlusDataCollector; 29 | class vtkPlusOpenIGTLinkServer; 30 | class vtkIGSIOTransformRepository; 31 | 32 | //----------------------------------------------------------------------------- 33 | 34 | /*! 35 | \class PlusServerLauncherMainWindow 36 | \brief GUI application for starting an OpenIGTLink server with the selected device configuration file 37 | \ingroup PlusAppPlusServerLauncher 38 | */ 39 | class PlusServerLauncherMainWindow : public QMainWindow 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | enum 45 | { 46 | RemoteControlServerPortDisable = -1, 47 | RemoteControlServerPortUseDefault = 0 48 | }; 49 | static const int DEFAULT_REMOTE_CONTROL_SERVER_PORT = 18904; 50 | static const char* PLUS_SERVER_LAUNCHER_REMOTE_DEVICE_ID; 51 | 52 | /*! 53 | Constructor 54 | \param aParent parent 55 | \param aFlags widget flag 56 | \param remoteControlServerPort port number where launcher listens for remote control OpenIGTLink commands. 0 means use default port, -1 means do not start a remote control server. 57 | */ 58 | PlusServerLauncherMainWindow(QWidget* parent = 0, Qt::WindowFlags flags = 0, bool autoConnect = false, int remoteControlServerPort = RemoteControlServerPortUseDefault); 59 | ~PlusServerLauncherMainWindow(); 60 | 61 | bool GetHideOnStartup() const; 62 | 63 | protected slots: 64 | /*! 65 | Connect to devices described in the argument configuration file in response by clicking on the Connect button 66 | \param aConfigFile DeviceSet configuration file path and name 67 | */ 68 | void ConnectToDevicesByConfigFile(std::string); 69 | 70 | /*! Called whenever a key is pressed while the windows is active, used for intercepting the ESC key */ 71 | virtual void keyPressEvent(QKeyEvent* e); 72 | 73 | void StdOutMsgReceived(); 74 | 75 | void StdErrMsgReceived(); 76 | 77 | void ErrorReceived(QProcess::ProcessError); 78 | 79 | void ServerExecutableFinished(int returnCode, QProcess::ExitStatus status); 80 | 81 | void LogLevelChanged(); 82 | 83 | void LatestLogClicked(); 84 | 85 | void OpenLogFolderClicked(); 86 | 87 | static void OnRemoteControlServerEventReceived(vtkObject* caller, unsigned long eventId, void* clientdata, void* calldata); 88 | void OnClientDisconnectedEvent(); 89 | void OnCommandReceivedEvent(igtlioCommandPointer command); 90 | static void OnLogEvent(vtkObject* caller, unsigned long eventId, void* clientData, void* callData); 91 | 92 | void OnWritePermissionClicked(); 93 | 94 | void OnTimerTimeout(); 95 | 96 | void StopRemoteServerButtonClicked(); 97 | 98 | void SystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason); 99 | 100 | void SystemTrayMessageClicked(); 101 | 102 | protected: 103 | 104 | struct ServerInfo 105 | { 106 | ServerInfo() 107 | { 108 | this->ID = ""; 109 | this->Filename = ""; 110 | this->Process = nullptr; 111 | } 112 | ServerInfo(std::string filename, QProcess* process) 113 | { 114 | this->ID = vtksys::SystemTools::GetFilenameWithoutExtension(filename); 115 | this->Filename = filename; 116 | this->Process = process; 117 | } 118 | std::string ID; 119 | std::string Filename; 120 | QProcess* Process; 121 | }; 122 | 123 | protected: 124 | 125 | /*! Read the application configuration from the PlusConfig xml */ 126 | PlusStatus ReadConfiguration(); 127 | 128 | /*! Write the application configuration from the PlusConfig xml */ 129 | PlusStatus WriteConfiguration(); 130 | 131 | /*! Receive standard output or error and send it to the log */ 132 | void SendServerOutputToLogger(const QByteArray& strData); 133 | 134 | /*! Start server process, connect outputs to logger. Returns with true on success. */ 135 | bool StartServer(const QString& configFilePath, int logLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED); 136 | /*! Start server process from GUI */ 137 | bool LocalStartServer(); 138 | 139 | /*! Stop server process, disconnect outputs. Returns with true on success (shutdown on request was successful, without forcing). */ 140 | bool StopServer(const QString& configFilePath); 141 | bool LocalStopServer(); 142 | 143 | /*! Parse a given log line for salient information from the PlusServer */ 144 | void ParseContent(const std::string& message); 145 | 146 | /*! Send a command */ 147 | PlusStatus SendCommand(igtlioCommandPointer command); 148 | 149 | /*! Send a response to a command */ 150 | PlusStatus SendCommandResponse(igtlioCommandPointer command); 151 | 152 | /*! Incoming command handling functions */ 153 | void AddOrUpdateConfigFile(igtlioCommandPointer command); 154 | void GetConfigFiles(igtlioCommandPointer command); 155 | void RemoteStartServer(igtlioCommandPointer command); 156 | void RemoteStopServer(igtlioCommandPointer command); 157 | void GetRunningServers(igtlioCommandPointer command); 158 | void GetConfigFileContents(igtlioCommandPointer command); 159 | 160 | void LocalLog(vtkPlusLogger::LogLevelType level, const std::string& message); 161 | 162 | std::string GetServersFromConfigFile(std::string filename); 163 | 164 | void SendServerStartedCommand(ServerInfo info); 165 | void SendServerStoppedCommand(ServerInfo info); 166 | 167 | /*! Get the process for the specified config file */ 168 | ServerInfo GetServerInfoFromID(std::string id); 169 | ServerInfo GetServerInfoFromFilename(std::string filename); 170 | ServerInfo GetServerInfoFromProcess(QProcess* process); 171 | 172 | /*! Remove the process from the list of running servers */ 173 | PlusStatus RemoveServerProcess(QProcess* process); 174 | 175 | /*! Update the contents of the remote control table to reflect the current status */ 176 | void UpdateRemoteServerTable(); 177 | 178 | void ShowNotification(QString message, QString title="PlusServerLauncher"); 179 | 180 | protected: 181 | /*! Device set selector widget */ 182 | QPlusDeviceSetSelectorWidget* m_DeviceSetSelectorWidget; 183 | 184 | QMenu* m_SystemTrayMenu; 185 | QAction* m_SystemTrayShowAction; 186 | QAction* m_SystemTrayHideAction; 187 | QAction* m_SystemTrayQuitAction; 188 | QSystemTrayIcon* m_SystemTrayIcon; 189 | 190 | /*! PlusServer instances that are responsible for all data collection and network transfer */ 191 | std::deque m_ServerInstances; 192 | 193 | /*! List of active ports for PlusServers */ 194 | std::string m_Suffix; 195 | 196 | /*! Store local config file name */ 197 | std::string m_LocalConfigFile; 198 | 199 | /*! OpenIGTLink server that allows remote control of launcher (start/stop a PlusServer process, etc) */ 200 | int m_RemoteControlServerPort; 201 | vtkSmartPointer m_RemoteControlServerCallbackCommand; 202 | igtlioLogicPointer m_RemoteControlServerLogic; 203 | igtlioConnectorPointer m_RemoteControlServerConnector; 204 | vtkSmartPointer m_RemoteControlLogMessageCallbackCommand; 205 | 206 | QTimer* m_RemoteControlServerConnectorProcessTimer; 207 | 208 | std::set m_RemoteControlLogSubscribedClients; 209 | 210 | /*! Incomplete string received from PlusServer */ 211 | std::string m_LogIncompleteLine; 212 | 213 | void closeEvent(QCloseEvent* event) override; 214 | 215 | private: 216 | Ui::PlusServerLauncherMainWindow ui; 217 | }; 218 | 219 | #endif // __PlusServerLauncherMainWindow_h 220 | -------------------------------------------------------------------------------- /PlusServerLauncher/Resources/icon_ConnectLarge.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/PlusServerLauncher/Resources/icon_ConnectLarge.ico -------------------------------------------------------------------------------- /PlusServerLauncher/Resources/icon_Edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/PlusServerLauncher/Resources/icon_Edit.png -------------------------------------------------------------------------------- /PlusServerLauncher/Testing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Empty, no tests created yet -------------------------------------------------------------------------------- /PointSetExtractor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # PointSetExtractor 3 | SET(VTK_RENDERING_LIB "") 4 | IF(PLUS_RENDERING_ENABLED) 5 | SET(VTK_RENDERING_LIB ${PLUSAPP_VTK_PREFIX}Rendering${VTK_RENDERING_BACKEND}) 6 | ENDIF() 7 | 8 | ADD_EXECUTABLE(PointSetExtractor PointSetExtractor.cxx) 9 | SET_TARGET_PROPERTIES(PointSetExtractor PROPERTIES FOLDER Utilities) 10 | TARGET_LINK_LIBRARIES(PointSetExtractor PUBLIC 11 | vtkPlusCommon 12 | ${PLUSAPP_VTK_PREFIX}InteractionStyle 13 | ${PLUSAPP_VTK_PREFIX}RenderingFreeType 14 | ${PLUSAPP_VTK_PREFIX}FiltersCore 15 | ${PLUSAPP_VTK_PREFIX}FiltersSources 16 | ${PLUSAPP_VTK_PREFIX}IOPLY 17 | ${PLUSAPP_VTK_PREFIX}IOGeometry 18 | ${VTK_RENDERING_LIB} 19 | ) 20 | GENERATE_HELP_DOC(PointSetExtractor) 21 | 22 | # -------------------------------------------------------------------------- 23 | # Install 24 | IF(PLUSAPP_INSTALL_BIN_DIR) 25 | INSTALL(TARGETS PointSetExtractor 26 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 27 | COMPONENT RuntimeExecutables 28 | ) 29 | ENDIF() 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PlusApp 2 | Software applications that makes Plus library's data acquisition, calibration, and real-time streaming features available to end-users. 3 | 4 | ## Issues 5 | Submit issues [here](https://github.com/PlusToolkit/PlusLib/issues). 6 | 7 | ## Questions, feedback, or feature requests 8 | Create a discussion [here](https://github.com/PlusToolkit/PlusLib/discussions). -------------------------------------------------------------------------------- /SpatialSensorFusion/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # SpatialSensorFusion 3 | ADD_EXECUTABLE(SpatialSensorFusion SpatialSensorFusion.cxx) 4 | SET_TARGET_PROPERTIES(SpatialSensorFusion PROPERTIES FOLDER Utilities) 5 | TARGET_LINK_LIBRARIES(SpatialSensorFusion PUBLIC vtkxio vtkPlusCommon) 6 | GENERATE_HELP_DOC(SpatialSensorFusion) 7 | 8 | # -------------------------------------------------------------------------- 9 | # Install 10 | IF(PLUSAPP_INSTALL_BIN_DIR) 11 | INSTALL(TARGETS SpatialSensorFusion 12 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 13 | COMPONENT RuntimeExecutables 14 | ) 15 | ENDIF() 16 | 17 | # -------------------------------------------------------------------------- 18 | # Testing 19 | IF(BUILD_TESTING) 20 | ADD_SUBDIRECTORY(Testing) 21 | ENDIF() -------------------------------------------------------------------------------- /SpatialSensorFusion/Testing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Testing 2 | SET( TestDataDir ${PLUSLIB_DATA_DIR}/TestImages ) 3 | SET( ConfigFilesDir ${PLUSLIB_DATA_DIR}/ConfigFiles ) 4 | 5 | ADD_TEST(SpatialSensorFusionTest 6 | ${PLUS_EXECUTABLE_OUTPUT_PATH}/SpatialSensorFusion 7 | --ahrs-algo=MADGWICK_IMU 8 | --ahrs-algo-gain 1.5 9 | --initial-gain 1 10 | --initial-repeated-frame-number=1000 11 | --input-seq-file=${TestDataDir}/SpatialSensorFusionTestInput.igs.mha 12 | --output-seq-file=${TestDataDir}/SpatialSensorFusionTestOutput.igs.mha 13 | --baseline-seq-file=${TestDataDir}/SpatialSensorFusionTestBaseline.igs.mha 14 | --west-axis-index=1 15 | ) 16 | 17 | SET_TESTS_PROPERTIES( SpatialSensorFusionTest PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR;WARNING" ) -------------------------------------------------------------------------------- /UsePlusApp.cmake.in: -------------------------------------------------------------------------------- 1 | # 2 | # This module is provided as PLUSAPP_USE_FILE 3 | # It can be INCLUDEd in a project to load the needed compiler and linker 4 | # settings to use Plus library. 5 | # 6 | 7 | IF(NOT PLUSAPP_USE_FILE_INCLUDED) 8 | SET(PLUSAPP_USE_FILE_INCLUDED 1) 9 | 10 | ## Set PlusApp binary dir path 11 | SET(PlusApp_BINARY_DIR "@PlusApp_BINARY_DIR@" ) 12 | SET(PlusApp_SOURCE_DIR "@PlusApp_SOURCE_DIR@" ) 13 | 14 | # Add include directories needed to use PlusApp library 15 | INCLUDE_DIRECTORIES(@PLUSAPP_INCLUDE_DIRS@) 16 | 17 | # Add link directories needed to use Plus library 18 | LINK_DIRECTORIES(@PLUSAPP_LIBRARY_DIRS@) 19 | 20 | SET(PLUSAPP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@) 21 | 22 | ## Find SVN 23 | SET (SVN_FOUND @Subversion_FOUND@) 24 | IF (SVN_FOUND) 25 | SET( Subversion_SVN_EXECUTABLE "@PLUSAPP_SVN_EXECUTABLE@" CACHE INTERNAL "") 26 | ENDIF() 27 | ENDIF() -------------------------------------------------------------------------------- /Utilities/SetupForDevelopment.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Run this script to set up development with git. 4 | # For more information, see: 5 | # http://www.slicer.org/slicerWiki/index.php/Documentation/Labs/DevelopmentWithGit 6 | # 7 | 8 | printErrorAndExit() { 9 | echo 'Failure during git development setup' 1>&2 10 | echo '------------------------------------' 1>&2 11 | echo '' 1>&2 12 | echo "$@" 1>&2 13 | exit 1 14 | } 15 | 16 | # Make sure we are inside the repository. 17 | currentDir=$0 18 | if [ -n "$currentDir" ] 19 | then 20 | currentDir=`pwd` 21 | fi 22 | 23 | inPlusLib=`echo $currentDir | awk '/PlusLib$/ {print $currentDir}'` 24 | inUtil=`echo $currentDir | awk '/[uU]tilities$/ {print $currentDir}'` 25 | 26 | if [ -n "$inUtil" ] 27 | then 28 | cd .. 29 | fi 30 | 31 | if test -d .git/.git; then 32 | printErrorAndExit "The directory '.git/.git' exists, indicating a 33 | configuration error. 34 | 35 | Please 'rm -rf' this directory." 36 | fi 37 | 38 | # Make 'git pull' on master always use rebase. 39 | git config branch.master.rebase true 40 | 41 | # Make automatic and manual rebase operations to display a summary and stat 42 | # display of changes merged in the fast-forward operation. 43 | git config rebase.stat true 44 | 45 | gitDir=`git rev-parse --git-dir` 46 | 47 | setup_user() { 48 | read -ep "Please enter your full name, such as 'John Doe': " name 49 | echo "Setting name to '$name'" 50 | git config user.name "$name" 51 | read -ep "Please enter your email address, such as 'john@email.com': " email 52 | echo "Setting email address to '$email'" 53 | git config user.email "$email" 54 | } 55 | 56 | # Copy hooks 57 | echo cp Utilities/hooks/commit-msg $gitDir/hooks 58 | cp Utilities/hooks/commit-msg $gitDir/hooks 59 | 60 | if [ "$1" == "copyOnly" ]; then 61 | exit 0 62 | fi 63 | 64 | # Logic to introduce yourself to Git. 65 | gitName=$(git config user.name) 66 | gitEmail=$(git config user.email) 67 | if [ "$gitName" == "" ] || [ "$gitEmail" == "" ]; then 68 | setup_user 69 | fi 70 | 71 | # Loop until the user is happy with the authorship information 72 | for (( ; ; )) 73 | do 74 | # Display the final user information. 75 | gitName=$(git config user.name) 76 | gitEmail=$(git config user.email) 77 | echo "Your commits will have the following author: 78 | 79 | $gitName <$gitEmail> 80 | " 81 | read -ep "Is the author name and email address above correct? [Y/n] " correct 82 | if [ "$correct" == "n" ] || [ "$correct" == "N" ]; then 83 | setup_user 84 | else 85 | break 86 | fi 87 | done 88 | 89 | # Record the version of this setup so the developer can be notified that 90 | # this script and/or hooks have been modified. 91 | SetupForDevelopment_VERSION=1 92 | git config hooks.SetupForDevelopment ${SetupForDevelopment_VERSION} -------------------------------------------------------------------------------- /Utilities/hooks/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | test "" = "$(grep '^Signed-off-by: ' "$1" | 4 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 5 | echo >&2 Duplicate Signed-off-by lines. 6 | exit 1 7 | } 8 | 9 | exit 0 -------------------------------------------------------------------------------- /fCal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(fCal) 2 | 3 | # -------------------------------------------------------------------------- 4 | # Sources 5 | SET (fCal_SRCS 6 | fCalMain.cxx 7 | fCalMainWindow.cxx 8 | QPlusSegmentationParameterDialog.cxx 9 | vtkPlusVisualizationController.cxx 10 | vtkPlusDisplayableObject.cxx 11 | vtkPlusImageVisualizer.cxx 12 | vtkPlus3DObjectVisualizer.cxx 13 | PlusCaptureControlWidget.cxx 14 | QPlusChannelAction.cxx 15 | ) 16 | 17 | SET(fCal_Toolbox_SRCS 18 | Toolboxes/QConfigurationToolbox.cxx 19 | Toolboxes/QCapturingToolbox.cxx 20 | Toolboxes/QSpatialCalibrationToolbox.cxx 21 | Toolboxes/QTemporalCalibrationToolbox.cxx 22 | Toolboxes/QStylusCalibrationToolbox.cxx 23 | Toolboxes/QPhantomRegistrationToolbox.cxx 24 | Toolboxes/QVolumeReconstructionToolbox.cxx 25 | ) 26 | 27 | IF(WIN32) 28 | LIST(APPEND fCal.rc) 29 | ENDIF() 30 | 31 | SET (fCal_UI_HDRS 32 | fCalMainWindow.h 33 | QPlusSegmentationParameterDialog.h 34 | vtkPlusVisualizationController.h 35 | vtkPlusDisplayableObject.h 36 | vtkPlusImageVisualizer.h 37 | vtkPlus3DObjectVisualizer.h 38 | PlusCaptureControlWidget.h 39 | QPlusChannelAction.h 40 | ) 41 | 42 | SET (fCal_Toolbox_UI_HDRS 43 | Toolboxes/QAbstractToolbox.h 44 | Toolboxes/QConfigurationToolbox.h 45 | Toolboxes/QCapturingToolbox.h 46 | Toolboxes/QSpatialCalibrationToolbox.h 47 | Toolboxes/QTemporalCalibrationToolbox.h 48 | Toolboxes/QStylusCalibrationToolbox.h 49 | Toolboxes/QPhantomRegistrationToolbox.h 50 | Toolboxes/QVolumeReconstructionToolbox.h 51 | ) 52 | 53 | SET (fCal_UI_SRCS 54 | fCalMainWindow.ui 55 | Toolboxes/QConfigurationToolbox.ui 56 | Toolboxes/QCapturingToolbox.ui 57 | Toolboxes/QSpatialCalibrationToolbox.ui 58 | Toolboxes/QTemporalCalibrationToolbox.ui 59 | Toolboxes/QStylusCalibrationToolbox.ui 60 | Toolboxes/QPhantomRegistrationToolbox.ui 61 | Toolboxes/QVolumeReconstructionToolbox.ui 62 | QPlusSegmentationParameterDialog.ui 63 | PlusCaptureControlWidget.ui 64 | ) 65 | 66 | SET (fCal_QT_Resources 67 | fCal.qrc 68 | ) 69 | 70 | # -------------------------------------------------------------------------- 71 | # Build the library 72 | SET(fCal_LIBS 73 | Qt5::Widgets 74 | Qt5::Core 75 | Qt5::Xml 76 | PlusWidgets 77 | vtkPlusCommon 78 | itkvnl 79 | itkvnl_algo 80 | vtkPlusCalibration 81 | vtkPlusDataCollection 82 | vtkPlusVolumeReconstruction 83 | ) 84 | IF(TARGET ${PLUSAPP_VTK_PREFIX}RenderingGL2PS${VTK_RENDERING_BACKEND}) 85 | LIST(APPEND fCal_LIBS 86 | ${PLUSAPP_VTK_PREFIX}RenderingGL2PS${VTK_RENDERING_BACKEND} 87 | ) 88 | ELSEIF(TARGET vtkRenderingGL2PS) 89 | LIST(APPEND fCal_LIBS 90 | ${PLUSAPP_VTK_PREFIX}RenderingGL2PS 91 | ) 92 | ENDIF() 93 | 94 | IF (PLUS_USE_OpenIGTLink) 95 | LIST(APPEND fCal_LIBS OpenIGTLink) 96 | ENDIF() 97 | 98 | SET(APP_MODE MACOSX_BUNDLE) 99 | IF(WIN32) 100 | SET(APP_MODE WIN32) 101 | ENDIF() 102 | 103 | AddPlusQt5Executable(fCal ${APP_MODE} 104 | ${fCal_SRCS} 105 | ${fCal_Toolbox_SRCS} 106 | ${fCal_UI_HDRS} 107 | ${fCal_Toolbox_UI_HDRS} 108 | ${fCal_UI_SRCS} 109 | ${fCal_QT_Resources} 110 | ) 111 | SET_TARGET_PROPERTIES(fCal PROPERTIES COMPILE_DEFINTIIONS ${Qt5Widgets_DEFINITIONS}) 112 | IF(NOT VTK_VERSION VERSION_LESS 9.0.0) 113 | # vtk_module_autoinit is needed 114 | vtk_module_autoinit(TARGETS fCal MODULES ${VTK_LIBRARIES}) 115 | ENDIF() 116 | TARGET_LINK_LIBRARIES(fCal PUBLIC ${fCal_LIBS}) 117 | target_include_directories(fCal PUBLIC 118 | ${CMAKE_CURRENT_BINARY_DIR} 119 | ${CMAKE_CURRENT_SOURCE_DIR} 120 | ${CMAKE_CURRENT_SOURCE_DIR}/Toolboxes 121 | ) 122 | 123 | IF(NOT (MSVC OR ${CMAKE_GENERATOR} MATCHES "Xcode")) 124 | target_compile_options(fCal PRIVATE -ftemplate-depth=5000) 125 | ENDIF() 126 | 127 | source_group(Toolboxes FILES ${fCal_Toolbox_SRCS} ${fCal_Toolbox_UI_HDRS}) 128 | source_group("UI Files" FILES ${fCal_UI_SRCS}) 129 | 130 | # -------------------------------------------------------------------------- 131 | # Install 132 | IF(PLUSAPP_INSTALL_BIN_DIR) 133 | INSTALL(TARGETS fCal 134 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 135 | COMPONENT RuntimeExecutables 136 | ) 137 | ENDIF() 138 | 139 | # -------------------------------------------------------------------------- 140 | # Testing 141 | IF(BUILD_TESTING) 142 | ADD_SUBDIRECTORY(Testing) 143 | ENDIF() -------------------------------------------------------------------------------- /fCal/PlusCaptureControlWidget.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __CaptureControlWidget_h 8 | #define __CaptureControlWidget_h 9 | 10 | // Local includes 11 | #include "ui_PlusCaptureControlWidget.h" 12 | 13 | // PlusLib includes 14 | #include 15 | #include 16 | 17 | // Qt includes 18 | #include 19 | #include 20 | #include 21 | 22 | //----------------------------------------------------------------------------- 23 | 24 | /*! \class PlusCaptureControlWidget 25 | * \brief Control vtkPlusVirtualCapture devices 26 | * \ingroup PlusAppCaptureClient 27 | */ 28 | class PlusCaptureControlWidget : public QWidget 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | PlusCaptureControlWidget(QWidget* aParent); 34 | ~PlusCaptureControlWidget(); 35 | 36 | virtual void UpdateBasedOnState(); 37 | 38 | virtual double GetMaximumFrameRate() const; 39 | 40 | virtual void SetCaptureDevice(vtkPlusVirtualCapture& aDevice); 41 | 42 | virtual vtkPlusVirtualCapture* GetCaptureDevice() 43 | { 44 | return m_Device; 45 | } 46 | 47 | virtual void SetEnableCapturing(bool aCapturing); 48 | 49 | virtual void SaveFile(); 50 | 51 | virtual void Clear(); 52 | 53 | virtual bool CanSave() const; 54 | 55 | virtual bool CanRecord() const; 56 | 57 | protected: 58 | /*! 59 | * Saves recorded tracked frame list to file 60 | * \param aOutput Output file 61 | * \return Success flag 62 | */ 63 | PlusStatus SaveToMetafile(std::string aOutput); 64 | 65 | /*! 66 | * Save data to file 67 | */ 68 | PlusStatus WriteToFile(const QString& aFilename); 69 | 70 | /*! 71 | * Display a result icon for a set duration 72 | */ 73 | void SendStatusMessage(const std::string& aMessage); 74 | 75 | signals: 76 | void EmitStatusMessage(const std::string&); 77 | 78 | protected slots: 79 | /*! 80 | * Take snapshot (record the current frame only) 81 | */ 82 | void TakeSnapshot(); 83 | 84 | void StartStopButtonPressed(); 85 | 86 | void SaveButtonPressed(); 87 | 88 | void SaveAsButtonPressed(); 89 | 90 | void SamplingRateChanged(int aValue); 91 | 92 | void ClearButtonPressed(); 93 | 94 | protected: 95 | /*! device to interact with */ 96 | vtkPlusVirtualCapture* m_Device; 97 | 98 | protected: 99 | Ui::CaptureControlWidget ui; 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /fCal/QPlusChannelAction.cxx: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | // Local includes 8 | #include "QPlusChannelAction.h" 9 | 10 | //----------------------------------------------------------------------------- 11 | QPlusChannelAction::QPlusChannelAction(const QString& text, QObject* parent, bool aIsSeparator, vtkPlusChannel* ownerChannel) 12 | : QAction(text, parent) 13 | , m_IsSeparator(aIsSeparator) 14 | , m_OwnerChannel(ownerChannel) 15 | { 16 | } 17 | 18 | //----------------------------------------------------------------------------- 19 | void QPlusChannelAction::activated() 20 | { 21 | emit channelSelected(m_OwnerChannel); 22 | } -------------------------------------------------------------------------------- /fCal/QPlusChannelAction.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __QCustomAction_h 8 | #define __QCustomAction_h 9 | 10 | // PlusLib includes 11 | #include 12 | #include 13 | 14 | // Qt includes 15 | #include 16 | 17 | class QPlusChannelAction : public QAction 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | QPlusChannelAction(const QString& text, QObject* parent, bool aIsSeparator = false, vtkPlusChannel* ownerChannel = NULL); 23 | bool IsSeparator() 24 | { 25 | return m_IsSeparator; 26 | } 27 | 28 | public slots: 29 | void activated(); 30 | 31 | signals: 32 | void channelSelected(vtkPlusChannel* aChannel); 33 | 34 | private: 35 | bool m_IsSeparator; 36 | vtkPlusChannel* m_OwnerChannel; 37 | }; 38 | 39 | #endif // __QCustomAction_h -------------------------------------------------------------------------------- /fCal/Resources/icon_Apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Apply.png -------------------------------------------------------------------------------- /fCal/Resources/icon_DownArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_DownArrow.png -------------------------------------------------------------------------------- /fCal/Resources/icon_DownArrow.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_DownArrow.xcf -------------------------------------------------------------------------------- /fCal/Resources/icon_Edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Edit.png -------------------------------------------------------------------------------- /fCal/Resources/icon_HorizontalFlip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_HorizontalFlip.png -------------------------------------------------------------------------------- /fCal/Resources/icon_ImageControl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_ImageControl.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Import.png -------------------------------------------------------------------------------- /fCal/Resources/icon_ObjectMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_ObjectMode.png -------------------------------------------------------------------------------- /fCal/Resources/icon_OpenFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_OpenFile.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Pause.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Play.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Plug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Plug.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Plug.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Plug.xcf -------------------------------------------------------------------------------- /fCal/Resources/icon_PopOut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_PopOut.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Record.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Save.png -------------------------------------------------------------------------------- /fCal/Resources/icon_SaveAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_SaveAll.png -------------------------------------------------------------------------------- /fCal/Resources/icon_SaveAll.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_SaveAll.xcf -------------------------------------------------------------------------------- /fCal/Resources/icon_ShowDevices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_ShowDevices.png -------------------------------------------------------------------------------- /fCal/Resources/icon_ShowDevices.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_ShowDevices.xcf -------------------------------------------------------------------------------- /fCal/Resources/icon_Snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Snapshot.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Tools.png -------------------------------------------------------------------------------- /fCal/Resources/icon_Tools.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_Tools.xcf -------------------------------------------------------------------------------- /fCal/Resources/icon_fCal.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_fCal.ico -------------------------------------------------------------------------------- /fCal/Resources/icon_fCal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Resources/icon_fCal.png -------------------------------------------------------------------------------- /fCal/Testing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET( TestDataDir ${PLUSLIB_DATA_DIR}/TestImages ) 2 | SET( ConfigFilesDir ${PLUSLIB_DATA_DIR}/ConfigFiles ) 3 | 4 | # -------------------------------------------------------------------------- 5 | # SegmentationParameterDialogTest 6 | SET (SegmentationParameterDialogTest_LIBS 7 | Qt5::Widgets 8 | Qt5::Test 9 | PlusWidgets 10 | vtkPlusCommon 11 | vtkPlusCalibration 12 | vtkPlusDataCollection 13 | ) 14 | 15 | ADD_EXECUTABLE(SegmentationParameterDialogTest SegmentationParameterDialogTest.cxx) 16 | SET_TARGET_PROPERTIES(SegmentationParameterDialogTest PROPERTIES 17 | COMPILE_DEFINTIIONS ${Qt5Widgets_COMPILE_DEFINITIONS} 18 | FOLDER Tests 19 | ) 20 | TARGET_LINK_LIBRARIES(SegmentationParameterDialogTest PRIVATE ${SegmentationParameterDialogTest_LIBS}) 21 | 22 | # -------------------------------------------------------------------------- 23 | # Install 24 | IF(PLUSAPP_INSTALL_BIN_DIR) 25 | INSTALL(TARGETS SegmentationParameterDialogTest 26 | DESTINATION ${PLUSAPP_INSTALL_BIN_DIR} 27 | COMPONENT RuntimeExecutables 28 | ) 29 | ENDIF() 30 | 31 | ADD_TEST(SegmentationParameterDialogTest ${PLUS_EXECUTABLE_OUTPUT_PATH}/SegmentationParameterDialogTest) 32 | SET_TESTS_PROPERTIES( SegmentationParameterDialogTest PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR;WARNING" ) -------------------------------------------------------------------------------- /fCal/Testing/SegmentationParameterDialogTest.cxx: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #include 8 | #include 9 | 10 | class SegmentationParameterDialogTest : public QObject 11 | { 12 | Q_OBJECT 13 | private slots: 14 | void t1() 15 | { 16 | QVERIFY(true); 17 | } 18 | }; 19 | 20 | QTEST_MAIN(SegmentationParameterDialogTest) 21 | #include "SegmentationParameterDialogTest.moc" -------------------------------------------------------------------------------- /fCal/Toolboxes/QAbstractToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __QAbstractToolbox_h 8 | #define __QAbstractToolbox_h 9 | 10 | #include 11 | 12 | class fCalMainWindow; 13 | 14 | //----------------------------------------------------------------------------- 15 | 16 | enum ToolboxState 17 | { 18 | ToolboxState_Uninitialized = 0, 19 | ToolboxState_Idle, 20 | ToolboxState_InProgress, 21 | ToolboxState_StartupDelay, 22 | ToolboxState_Done, 23 | ToolboxState_Error 24 | }; 25 | 26 | //----------------------------------------------------------------------------- 27 | 28 | /*! \class QAbstractToolbox 29 | * \brief This class is the super class of all the toolboxes for standard handling 30 | * \ingroup PlusAppFCal 31 | */ 32 | class QAbstractToolbox 33 | { 34 | public: 35 | /*! \brief Constructor */ 36 | QAbstractToolbox(fCalMainWindow* aParentMainWindow) 37 | { 38 | m_BusyCursorSet = false; 39 | m_ParentMainWindow = aParentMainWindow; 40 | m_State = ToolboxState_Uninitialized; 41 | }; 42 | 43 | /*! \brief Destructor */ 44 | virtual ~QAbstractToolbox() { }; 45 | 46 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - pure virtual function */ 47 | virtual void RefreshContent() = 0; 48 | 49 | /*! \brief Load session data and update view when the toolbox is activated - pure virtual function */ 50 | virtual void OnActivated() = 0; 51 | 52 | /*! \brief Close session data when the toolbox is deactivated - pure virtual function */ 53 | virtual void OnDeactivated() = 0; 54 | 55 | 56 | /*! \brief Reset toolbox to initial state - virtual function */ 57 | virtual void Reset() 58 | { 59 | SetState(ToolboxState_Idle); 60 | }; 61 | 62 | /*! \brief Sets display mode (visibility of actors) according to the current state - pure virtual function */ 63 | virtual void SetDisplayAccordingToState() = 0; 64 | 65 | /*! 66 | * \brief Properly sets new toolbox state 67 | * \param aState New state of the toolbox 68 | */ 69 | void SetState(ToolboxState aState) 70 | { 71 | m_State = aState; 72 | SetDisplayAccordingToState(); 73 | }; 74 | 75 | /*! 76 | * \brief Get toolbox state 77 | * \return Current state 78 | */ 79 | ToolboxState GetState() 80 | { 81 | return m_State; 82 | }; 83 | 84 | void SetBusyCursor(bool busy) 85 | { 86 | if (!busy && m_BusyCursorSet) 87 | { 88 | QApplication::restoreOverrideCursor(); 89 | m_BusyCursorSet = false; 90 | } 91 | else if (busy && !m_BusyCursorSet) 92 | { 93 | QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); 94 | m_BusyCursorSet = true; 95 | } 96 | } 97 | 98 | protected: 99 | //! Main window object 100 | fCalMainWindow* m_ParentMainWindow; 101 | 102 | //! Toolbox state 103 | ToolboxState m_State; 104 | 105 | //! Helper for setting busy cursor instead of push/pop its state 106 | bool m_BusyCursorSet; 107 | }; 108 | 109 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QCapturingToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef CAPTURINGTOOLBOX_H 8 | #define CAPTURINGTOOLBOX_H 9 | 10 | // PlusLib includes 11 | #include 12 | 13 | // Local includes 14 | #include "QAbstractToolbox.h" 15 | #include "ui_QCapturingToolbox.h" 16 | 17 | // Qt includes 18 | #include 19 | 20 | class PlusCaptureControlWidget; 21 | class QGridLayout; 22 | class QScrollArea; 23 | class QSpacerItem; 24 | class QString; 25 | class QTimer; 26 | class vtkIGSIOTrackedFrameList; 27 | 28 | //----------------------------------------------------------------------------- 29 | 30 | /*! \class QCapturingToolbox 31 | * \brief Tracked frame capturing class 32 | * \ingroup PlusAppFCal 33 | */ 34 | class QCapturingToolbox : public QWidget, public QAbstractToolbox 35 | { 36 | Q_OBJECT 37 | 38 | public: 39 | /*! 40 | * Constructor 41 | * \param aParentMainWindow Parent main window 42 | * \param aFlags widget flag 43 | */ 44 | QCapturingToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 45 | 46 | /*! 47 | * Destructor 48 | */ 49 | ~QCapturingToolbox(); 50 | 51 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 52 | virtual void OnActivated(); 53 | 54 | /*! \brief Clear toolbox contents */ 55 | virtual void OnDeactivated(); 56 | 57 | /*! Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 58 | virtual void RefreshContent(); 59 | 60 | /*! \brief Reset toolbox to initial state - */ 61 | virtual void Reset(); 62 | 63 | /*! Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function */ 64 | void SetDisplayAccordingToState(); 65 | 66 | /*! Get recorded tracked frame list */ 67 | inline vtkIGSIOTrackedFrameList* GetRecordedFrames() { return m_RecordedFrames; } 68 | 69 | protected: 70 | /*! 71 | * Saves recorded tracked frame list to file 72 | * \param aOutput Output file 73 | * \return Success flag 74 | */ 75 | PlusStatus SaveToMetafile(std::string aOutput); 76 | 77 | /*! 78 | * Get the maximum frame rate from the video source. If there is none then the tracker 79 | * \return Maximum frame rate 80 | */ 81 | double GetMaximumFrameRate(); 82 | 83 | /*! 84 | * Actual clearing of frames 85 | */ 86 | void ClearRecordedFramesInternal(); 87 | /*! 88 | * Save data to file 89 | */ 90 | void WriteToFile(const QString& aFilename); 91 | 92 | /*! Get the sampling period length (in seconds). Frames are copied from the devices to the data collection buffer once in every sampling period. */ 93 | double GetSamplingPeriodSec(); 94 | 95 | /// Initialize the scroll area and any capture widgets 96 | void InitCaptureDeviceScrollArea(); 97 | 98 | protected slots: 99 | /*! 100 | * Take snapshot (record the current frame only) 101 | */ 102 | void TakeSnapshot(); 103 | 104 | /*! 105 | * Slot handling record button click 106 | */ 107 | void Record(); 108 | 109 | /*! 110 | * Slot handling stop button click (Record button becomes Stop after clicking) 111 | */ 112 | void Stop(); 113 | 114 | /*! 115 | * Slot handling clear recorded frames button click 116 | */ 117 | void ClearRecordedFrames(); 118 | 119 | /*! 120 | * Slot handling clear recorded frames button click 121 | */ 122 | void ClearAll(); 123 | 124 | /*! 125 | * Slot handling start/stop all capture devices 126 | */ 127 | void StartStopAll(); 128 | 129 | /*! 130 | * Slot handling Save button click 131 | */ 132 | void Save(); 133 | 134 | /*! 135 | * Slot handling Save As button click 136 | */ 137 | void SaveAs(); 138 | 139 | /*! 140 | * Slot handling Save As button click 141 | */ 142 | void SaveAll(); 143 | 144 | /*! 145 | * Slot handling value change of sampling rate slider 146 | * \param aValue Tick index (rightmost means record every frame, and each one to the left halves it) 147 | */ 148 | void SamplingRateChanged(int aValue); 149 | 150 | /*! 151 | * Record tracked frames (the recording timer calls it) 152 | */ 153 | void Capture(); 154 | 155 | /*! 156 | * Handle status message from any sub capture widgets 157 | */ 158 | void HandleStatusMessage(const std::string& aMessage); 159 | 160 | protected: 161 | /*! Recorded tracked frame list */ 162 | vtkIGSIOTrackedFrameList* m_RecordedFrames; 163 | 164 | /*! Timer triggering the */ 165 | QTimer* m_RecordingTimer; 166 | 167 | /*! Timestamp of last recorded frame (only frames that have more recent timestamp will be added) */ 168 | double m_RecordingLastAlreadyRecordedFrameTimestamp; 169 | 170 | /*! Desired timestamp of the next frame to be recorded */ 171 | double m_RecordingNextFrameToBeRecordedTimestamp; 172 | 173 | /*! Frame rate of the sampling */ 174 | const int m_SamplingFrameRate; 175 | 176 | /*! Requested frame rate (frames per second) */ 177 | double m_RequestedFrameRate; 178 | 179 | /*! Actual frame rate (frames per second) */ 180 | double m_ActualFrameRate; 181 | 182 | /*! 183 | Frame index of the first frame that is recorded in this segment (since pressed the record button). 184 | It is used when estimating the actual frame rate: frames that are acquired before this frame index (i.e., 185 | those that were acquired in a different recording segment) will not be taken into account in the actual 186 | frame rate computation. 187 | */ 188 | int m_RecordingFirstFrameIndexInThisSegment; 189 | 190 | /*! String to hold the last location of data saved */ 191 | std::string m_LastSaveLocation; 192 | 193 | /* Container holding capture widgets */ 194 | std::vector m_CaptureWidgets; 195 | 196 | QScrollArea* m_ScrollArea; 197 | 198 | QWidget* m_GridWidget; 199 | 200 | QGridLayout* m_GridLayout; 201 | 202 | protected: 203 | Ui::CapturingToolbox ui; 204 | }; 205 | 206 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QConfigurationToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef CONFIGURATIONTOOLBOX_H 8 | #define CONFIGURATIONTOOLBOX_H 9 | 10 | #include "ui_QConfigurationToolbox.h" 11 | 12 | #include "QAbstractToolbox.h" 13 | #include "PlusConfigure.h" 14 | 15 | #include 16 | 17 | class QPlusDeviceSetSelectorWidget; 18 | class QPlusToolStateDisplayWidget; 19 | class vtkPlusChannel; 20 | 21 | //----------------------------------------------------------------------------- 22 | 23 | /*! \class ConfigurationToolbox 24 | * \brief Configuration toolbox that handles device sets and common preferences of fCal 25 | * \ingroup PlusAppFCal 26 | */ 27 | class QConfigurationToolbox : public QWidget, public QAbstractToolbox 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | /*! 33 | * Constructor 34 | * \param aParentWindow Parent main window 35 | * \param aFlags widget flag 36 | */ 37 | QConfigurationToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 38 | 39 | /*! 40 | * Destructor 41 | */ 42 | ~QConfigurationToolbox(); 43 | 44 | /*! 45 | * Initialize toolbox 46 | */ 47 | virtual void OnActivated(); 48 | 49 | /*! 50 | * Finalize toolbox 51 | */ 52 | virtual void OnDeactivated(); 53 | 54 | /*! 55 | * Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function 56 | */ 57 | virtual void RefreshContent(); 58 | 59 | /*! 60 | * Refresh contents if tool display is detached 61 | */ 62 | void RefreshToolDisplayIfDetached(); 63 | 64 | /*! 65 | * Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function 66 | */ 67 | void SetDisplayAccordingToState(); 68 | 69 | /*! Update the toolstate display widget because the channel changed */ 70 | void ChannelChanged(vtkPlusChannel& aChannel); 71 | 72 | protected: 73 | /*! 74 | * Read fCal configuration 75 | * \param aConfig Root element of the configuration XML data element 76 | */ 77 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 78 | 79 | /*! Read wire pattern and add it to visualization */ 80 | PlusStatus ReadAndAddPhantomWiresToVisualization(); 81 | 82 | /*! 83 | * \brief Filters events if this object has been installed as an event filter for the watched object 84 | * \param obj object 85 | * \param ev event 86 | * \return if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false 87 | */ 88 | bool eventFilter(QObject* obj, QEvent* ev); 89 | 90 | /*! Select the channel */ 91 | PlusStatus SelectChannel(vtkPlusChannel*& aChannel, vtkXMLDataElement* fCalElement); 92 | 93 | /*! Update the size of the tool state display widget because its contents have changed */ 94 | void ToolStateWidgetResize(); 95 | 96 | signals: 97 | /*! 98 | * Executes operations needed after stopping the process 99 | * \param Enable/disable flag 100 | */ 101 | void SetToolboxesEnabled(bool); 102 | 103 | protected slots: 104 | /*! 105 | * Connect to devices described in the argument configuration file in response by clicking on the Connect button 106 | * \param aConfigFile DeviceSet configuration file path and name 107 | */ 108 | void ConnectToDevicesByConfigFile(std::string aConfigFile); 109 | 110 | /*! 111 | * Slot handling pop out toggle button state change 112 | * \param aOn True if toggled, false otherwise 113 | */ 114 | void PopOutToggled(bool aOn); 115 | 116 | /*! 117 | * Slot handling log level combobox item change 118 | * \param aLevel New log level 119 | */ 120 | void LogLevelChanged(int aLevel); 121 | 122 | /*! 123 | * Pops up open directory dialog and saves the selected one as image directory. It is the directory that contains the usually used input images (to act as home for relative paths in device set configuration files) 124 | */ 125 | void SelectImageDirectory(); 126 | 127 | /*! 128 | * Reset the tracker if it is connected 129 | */ 130 | void ResetTracker(); 131 | 132 | protected: 133 | /*! Device set selector widget */ 134 | QPlusDeviceSetSelectorWidget* m_DeviceSetSelectorWidget; 135 | 136 | /*! Tool state display widget */ 137 | QPlusToolStateDisplayWidget* m_ToolStateDisplayWidget; 138 | 139 | /*! Window that is created when tool state display widget is popped out */ 140 | QWidget* m_ToolStatePopOutWindow; 141 | 142 | /*! Flag indicating if tool state display widget is detached */ 143 | bool m_IsToolDisplayDetached; 144 | 145 | /*! String to hold the last location of data saved */ 146 | QString m_LastImageDirectoryLocation; 147 | 148 | protected: 149 | Ui::ConfigurationToolbox ui; 150 | }; 151 | 152 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QConfigurationToolbox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ConfigurationToolbox 4 | 5 | 6 | 7 | 0 8 | 0 9 | 166 10 | 257 11 | 12 | 13 | 14 | Configuration 15 | 16 | 17 | 18 | 4 19 | 20 | 21 | 0 22 | 23 | 24 | 4 25 | 26 | 27 | 0 28 | 29 | 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 0 37 | 48 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Qt::Vertical 46 | 47 | 48 | QSizePolicy::Fixed 49 | 50 | 51 | 52 | 158 53 | 12 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Qt::Horizontal 62 | 63 | 64 | 65 | 66 | 67 | 68 | 4 69 | 70 | 71 | 72 | 73 | Qt::Horizontal 74 | 75 | 76 | 77 | 40 78 | 20 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 23 88 | 23 89 | 90 | 91 | 92 | Pop out (or back) tool state window 93 | 94 | 95 | 96 | 97 | 98 | 99 | :/icons/Resources/icon_PopOut.png:/icons/Resources/icon_PopOut.png 100 | 101 | 102 | true 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 0 113 | 48 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Qt::Horizontal 122 | 123 | 124 | 125 | 126 | 127 | 128 | Qt::Vertical 129 | 130 | 131 | QSizePolicy::Expanding 132 | 133 | 134 | 135 | 20 136 | 12 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 0 148 | 0 149 | 150 | 151 | 152 | Log level: 153 | 154 | 155 | 156 | 157 | 158 | 159 | Qt::Horizontal 160 | 161 | 162 | 163 | 40 164 | 20 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 0 174 | 0 175 | 176 | 177 | 178 | Level of log entries that are displayed 179 | 180 | 181 | 1 182 | 183 | 184 | 185 | Error 186 | 187 | 188 | 189 | 190 | Warning 191 | 192 | 193 | 194 | 195 | Info 196 | 197 | 198 | 199 | 200 | Debug 201 | 202 | 203 | 204 | 205 | Trace 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | Directory that contains the usually used input images (to act as home for relative paths in device set configuration files) 216 | 217 | 218 | Image directory: 219 | 220 | 221 | 222 | 223 | 224 | 225 | 0 226 | 227 | 228 | 229 | 230 | 231 | 9 232 | 0 233 | 234 | 235 | 236 | Directory that contains the usually used input images (to act as home for relative paths in device set configuration files) 237 | 238 | 239 | true 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 1 248 | 0 249 | 250 | 251 | 252 | 253 | 23 254 | 23 255 | 256 | 257 | 258 | Qt::NoFocus 259 | 260 | 261 | Select other device set configuration directory 262 | 263 | 264 | 265 | 266 | 267 | 268 | :/icons/Resources/icon_OpenFile.png:/icons/Resources/icon_OpenFile.png 269 | 270 | 271 | 272 | 16 273 | 16 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /fCal/Toolboxes/QPhantomRegistrationToolbox.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PlusToolkit/PlusApp/012813ab87402e56e811912aa4e9a24027daae73/fCal/Toolboxes/QPhantomRegistrationToolbox.h -------------------------------------------------------------------------------- /fCal/Toolboxes/QSpatialCalibrationToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef SPATIALCALIBRATIONTOOLBOX_H 8 | #define SPATIALCALIBRATIONTOOLBOX_H 9 | 10 | #include "ui_QSpatialCalibrationToolbox.h" 11 | 12 | #include "QAbstractToolbox.h" 13 | #include "PlusConfigure.h" 14 | 15 | #include "PlusFidPatternRecognitionCommon.h" 16 | 17 | #include 18 | 19 | class vtkPlusProbeCalibrationAlgo; 20 | class PlusFidPatternRecognition; 21 | class vtkIGSIOTrackedFrameList; 22 | 23 | //----------------------------------------------------------------------------- 24 | 25 | /*! \class SpatialCalibrationToolbox 26 | * \brief Spatial calibration toolbox class 27 | * \ingroup PlusAppFCal 28 | */ 29 | class QSpatialCalibrationToolbox : public QWidget, public QAbstractToolbox 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | /*! 35 | * Constructor 36 | * \param aParentMainWindow Parent main window 37 | * \param aFlags widget flag 38 | */ 39 | QSpatialCalibrationToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 40 | 41 | /*! Destructor */ 42 | ~QSpatialCalibrationToolbox(); 43 | 44 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 45 | virtual void OnActivated(); 46 | 47 | /*! 48 | * Finalize toolbox 49 | */ 50 | virtual void OnDeactivated(); 51 | 52 | /*! \brief Reset toolbox to initial state - */ 53 | virtual void Reset(); 54 | 55 | /*! 56 | * Read freehand calibration configuration for fCal 57 | * \param aConfig Root element of the input device set configuration XML data 58 | */ 59 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 60 | 61 | /*! Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 62 | virtual void RefreshContent(); 63 | 64 | /*! Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function */ 65 | void SetDisplayAccordingToState(); 66 | 67 | protected: 68 | /*! 69 | * Determines if everything is OK to run spatial calibration 70 | * \return Ready flag 71 | */ 72 | bool IsReadyToStartSpatialCalibration(); 73 | 74 | /*! 75 | Prepares and shows the last segmented points from the current acquisition. 76 | If enable is false then segmented points are hidden (even if they were available). 77 | */ 78 | void DisplaySegmentedPoints(bool enable); 79 | 80 | /*! Set and save calibration results */ 81 | PlusStatus SetAndSaveResults(); 82 | 83 | void SetFreeHandStartupDelaySec(int freeHandStartupDelaySec) {m_FreeHandStartupDelaySec = freeHandStartupDelaySec;}; 84 | 85 | protected slots: 86 | 87 | /*! Start the delay startup timer*/ 88 | void StartDelayTimer(); 89 | 90 | /*! Delay before startup calibration*/ 91 | void DelayStartup(); 92 | 93 | /*! Acquire tracked frames and segment them. Runs calibration if acquisition is ready */ 94 | void DoCalibration(); 95 | 96 | /*! Slot handling open phantom registration button click */ 97 | void OpenPhantomRegistration(); 98 | 99 | /*! Open XML file containing segmentation parameters and read the contents */ 100 | void OpenSegmentationParameters(); 101 | 102 | /*! Edit segmentation parameters */ 103 | void EditSegmentationParameters(); 104 | 105 | /*! Slot handling start spatial calibration button click */ 106 | void StartCalibration(); 107 | 108 | /*! Slot handling cancel calibration event (button click or explicit call) */ 109 | void CancelCalibration(); 110 | 111 | protected: 112 | /*! Calibration algorithm */ 113 | vtkSmartPointer m_Calibration; 114 | 115 | /*! Pattern recognition algorithm */ 116 | PlusFidPatternRecognition* m_PatternRecognition; 117 | 118 | /*! Tracked frame data for spatial calibration */ 119 | vtkSmartPointer m_SpatialCalibrationData; 120 | 121 | /*! Tracked frame data for validation of spatial calibration */ 122 | vtkSmartPointer m_SpatialValidationData; 123 | 124 | /*! Delay time before start acquisition [s] */ 125 | int m_FreeHandStartupDelaySec; 126 | 127 | /*! Current time delayed before the acquisition [s] */ 128 | int m_StartupDelayRemainingTimeSec; 129 | 130 | /*! Timer before start acquisition*/ 131 | QTimer* m_StartupDelayTimer; 132 | 133 | /*! Timestamp of last recorded frame (the tracked frames acquired since this timestamp will be recorded) */ 134 | double m_LastRecordedFrameTimestamp; 135 | 136 | /*! Flag if cancel is requested */ 137 | bool m_CancelRequest; 138 | 139 | /*! Number of needed calibration images */ 140 | int m_NumberOfCalibrationImagesToAcquire; 141 | 142 | /*! Number of needed validation images */ 143 | int m_NumberOfValidationImagesToAcquire; 144 | 145 | /*! Number of segmented calibration images */ 146 | int m_NumberOfSegmentedCalibrationImages; 147 | 148 | /*! Number of segmented validation images */ 149 | int m_NumberOfSegmentedValidationImages; 150 | 151 | /*! Time interval between recording (sampling) cycles (in milliseconds) */ 152 | int m_RecordingIntervalMs; 153 | 154 | /*! Maximum time spent with processing (getting tracked frames, segmentation) per second (in milliseconds) */ 155 | int m_MaxTimeSpentWithProcessingMs; 156 | 157 | /*! Time needed to process one frame in the latest recording round (in milliseconds) */ 158 | int m_LastProcessingTimePerFrameMs; 159 | 160 | protected: 161 | Ui::SpatialCalibrationToolbox ui; 162 | 163 | }; 164 | 165 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QSpatialCalibrationToolbox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SpatialCalibrationToolbox 4 | 5 | 6 | 7 | 0 8 | 0 9 | 236 10 | 265 11 | 12 | 13 | 14 | Spatial calibration 15 | 16 | 17 | 18 | 4 19 | 20 | 21 | 0 22 | 23 | 24 | 4 25 | 26 | 27 | 0 28 | 29 | 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 0 37 | 0 38 | 39 | 40 | 41 | 42 | 75 43 | true 44 | 45 | 46 | 47 | ImageToProge transform is absent, spatial calibration needs to be performed. 48 | 49 | 50 | true 51 | 52 | 53 | 54 | 55 | 56 | 57 | Qt::Horizontal 58 | 59 | 60 | 61 | 62 | 63 | 64 | 2 65 | 66 | 67 | 68 | 69 | Import phantom registration result: 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 23 78 | 23 79 | 80 | 81 | 82 | Qt::NoFocus 83 | 84 | 85 | 86 | 87 | 88 | 89 | :/icons/Resources/icon_Import.png:/icons/Resources/icon_Import.png 90 | 91 | 92 | 93 | 16 94 | 16 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 6 105 | 106 | 107 | 108 | 109 | Pattern recognition parameters: 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 23 118 | 23 119 | 120 | 121 | 122 | Qt::NoFocus 123 | 124 | 125 | Import segmentation parameters 126 | 127 | 128 | 129 | 130 | 131 | 132 | :/icons/Resources/icon_Import.png:/icons/Resources/icon_Import.png 133 | 134 | 135 | 136 | 16 137 | 16 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 23 147 | 23 148 | 149 | 150 | 151 | Qt::NoFocus 152 | 153 | 154 | Show segmentation parameter editing dialog, in which segmentation parameters can be tested and changed 155 | 156 | 157 | 158 | 159 | 160 | 161 | :/icons/Resources/icon_Edit.png:/icons/Resources/icon_Edit.png 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | Qt::Vertical 171 | 172 | 173 | QSizePolicy::Fixed 174 | 175 | 176 | 177 | 158 178 | 12 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 75 188 | true 189 | 190 | 191 | 192 | Instructions 193 | 194 | 195 | true 196 | 197 | 198 | 199 | 200 | 201 | 202 | Qt::Vertical 203 | 204 | 205 | QSizePolicy::Fixed 206 | 207 | 208 | 209 | 158 210 | 12 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 4 219 | 220 | 221 | 222 | 223 | Qt::Horizontal 224 | 225 | 226 | 227 | 40 228 | 20 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | Start 237 | 238 | 239 | 240 | 241 | 242 | 243 | Qt::Horizontal 244 | 245 | 246 | 247 | 40 248 | 20 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | Qt::Vertical 259 | 260 | 261 | QSizePolicy::Fixed 262 | 263 | 264 | 265 | 20 266 | 4 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 75 276 | true 277 | 278 | 279 | 280 | 281 | 282 | 283 | true 284 | 285 | 286 | 287 | 288 | 289 | 290 | Results 291 | 292 | 293 | 294 | 295 | 296 | 297 | Qt::Vertical 298 | 299 | 300 | 301 | 158 302 | 40 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | -------------------------------------------------------------------------------- /fCal/Toolboxes/QStylusCalibrationToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __StylusCalibrationToolbox_h 8 | #define __StylusCalibrationToolbox_h 9 | 10 | #include "ui_QStylusCalibrationToolbox.h" 11 | 12 | #include "QAbstractToolbox.h" 13 | #include "PlusConfigure.h" 14 | 15 | #include 16 | #include 17 | 18 | class vtkPlusPivotCalibrationAlgo; 19 | class vtkMatrix4x4; 20 | 21 | //----------------------------------------------------------------------------- 22 | 23 | /*! \class StylusCalibrationToolbox 24 | * \brief Stylus calibration toolbox view class 25 | * \ingroup PlusAppFCal 26 | */ 27 | class QStylusCalibrationToolbox : public QWidget, public QAbstractToolbox 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | /*! 33 | * Constructor 34 | * \param aParentMainWindow Parent main window 35 | * \param aFlags Widget flags 36 | */ 37 | QStylusCalibrationToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 38 | 39 | /*! Destructor */ 40 | ~QStylusCalibrationToolbox(); 41 | 42 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 43 | virtual void OnActivated(); 44 | 45 | /*! 46 | * Finalize toolbox 47 | */ 48 | virtual void OnDeactivated(); 49 | 50 | /*! 51 | Read stylus calibration configuration for fCal 52 | \param aConfig Root element of the input device set configuration XML data 53 | */ 54 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 55 | 56 | /*! 57 | Refresh contents (e.g. GUI elements) of toolbox according to the state 58 | in the toolbox controller - implementation of a pure virtual function 59 | */ 60 | virtual void RefreshContent(); 61 | 62 | /*! 63 | Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function 64 | */ 65 | void SetDisplayAccordingToState(); 66 | 67 | /*! 68 | * Return pivot calibration algorithm object 69 | * \return Pivot calibration algorithm 70 | */ 71 | vtkPlusPivotCalibrationAlgo* GetPivotCalibrationAlgo(); 72 | 73 | protected slots: 74 | void StopCalibration(); 75 | void OnStartStopClicked(); 76 | 77 | /*! 78 | * Slot handling change of stylus calibration number of points 79 | * \param aLevel New number of points 80 | */ 81 | void NumberOfStylusCalibrationPointsChanged(int aNumberOfPoints); 82 | 83 | /*! 84 | * Acquire stylus position and add it to the algorithm (called by the acquisition timer in object visualizer) 85 | */ 86 | void OnDataAcquired(); 87 | 88 | protected: 89 | /*! Start calibration */ 90 | void StartCalibration(); 91 | void SetFreeHandStartupDelaySec(int freeHandStartupDelaySec); 92 | 93 | vtkSmartPointer m_PivotCalibration; 94 | int m_NumberOfPoints; 95 | int m_FreeHandStartupDelaySec; 96 | int m_CurrentPointNumber; 97 | QString m_StylusPositionString; 98 | vtkSmartPointer m_PreviousStylusToReferenceTransformMatrix; 99 | QTime m_CalibrationStartupDelayStartTime; 100 | 101 | protected: 102 | Ui::StylusCalibrationToolbox ui; 103 | 104 | }; 105 | 106 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QTemporalCalibrationToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef TEMPORALCALIBRATIONTOOLBOX_H 8 | #define TEMPORALCALIBRATIONTOOLBOX_H 9 | 10 | // Local includes 11 | #include "QAbstractToolbox.h" 12 | #include "ui_QTemporalCalibrationToolbox.h" 13 | 14 | // PlusLib includes 15 | #include 16 | #include 17 | #include 18 | 19 | // Qt includes 20 | #include 21 | #include 22 | 23 | // IGSIO includes 24 | #include 25 | 26 | class vtkContextView; 27 | class vtkPlusChannel; 28 | class vtkTable; 29 | class vtkIGSIOTrackedFrameList; 30 | 31 | //----------------------------------------------------------------------------- 32 | 33 | /*! \class TemporalCalibrationToolbox 34 | * \brief Temporal calibration toolbox class 35 | * \ingroup PlusAppFCal 36 | */ 37 | class QTemporalCalibrationToolbox : public QWidget, public QAbstractToolbox 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | /*! 43 | * Constructor 44 | * \param aParentMainWindow Parent main window 45 | * \param aFlags widget flag 46 | */ 47 | QTemporalCalibrationToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 48 | 49 | /*! Destructor */ 50 | ~QTemporalCalibrationToolbox(); 51 | 52 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 53 | virtual void OnActivated(); 54 | 55 | /*! 56 | * Finalize toolbox 57 | */ 58 | virtual void OnDeactivated(); 59 | 60 | /*! 61 | * Read freehand calibration configuration for fCal 62 | * \param aConfig Root element of the input device set configuration XML data 63 | */ 64 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 65 | 66 | /*! Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 67 | virtual void RefreshContent(); 68 | 69 | /*! Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function */ 70 | void SetDisplayAccordingToState(); 71 | 72 | protected: 73 | /*! 74 | * \brief Filters events if this object has been installed as an event filter for the watched object 75 | * \param obj object 76 | * \param ev event 77 | * \return if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false 78 | */ 79 | bool eventFilter(QObject* obj, QEvent* ev); 80 | 81 | /*! Prints a time value in sec as a string in msec */ 82 | static std::string GetTimeAsString(double timeSec); 83 | 84 | void SetFreeHandStartupDelaySec(int freeHandStartupDelaySec) {FreeHandStartupDelaySec = freeHandStartupDelaySec;}; 85 | void SegmentAndDisplayLine(igsioTrackedFrame& frame); 86 | 87 | protected slots: 88 | /*! Start the delay startup timer*/ 89 | void StartDelayTimer(); 90 | 91 | /*! Delay before startup calibration*/ 92 | void DelayStartup(); 93 | 94 | /*! Acquire tracked frames for temporal calibration and calls the algorithm when done */ 95 | void DoCalibration(); 96 | 97 | /*! Show/hide popup window with the plots in it when toggling the Show Plots button */ 98 | void ShowPlotsToggled(bool aOn); 99 | 100 | /*! Slot handling start temporal calibration button click */ 101 | void StartCalibration(); 102 | 103 | /*! Slot handling cancel calibration event (button click or explicit call) */ 104 | void CancelCalibration(); 105 | 106 | /*! Compute calibration results from the collected data and display the results */ 107 | void ComputeCalibrationResults(); 108 | 109 | /*! A signal combo box was changed */ 110 | void FixedSignalChanged(int newIndex); 111 | void MovingSignalChanged(int newIndex); 112 | 113 | /*! A source combo box was changed */ 114 | void FixedSourceChanged(int newIndex); 115 | void MovingSourceChanged(int newIndex); 116 | 117 | /*! When the user requests to save the calibration plots */ 118 | void OnSavePlotsRequested(); 119 | 120 | protected: 121 | /*! Tracked frame for tracking data for temporal calibration */ 122 | vtkSmartPointer TemporalCalibrationFixedData; 123 | /*! Tracked frame for video data for temporal calibration */ 124 | vtkSmartPointer TemporalCalibrationMovingData; 125 | /*! Delay time before start acquisition [s] */ 126 | int FreeHandStartupDelaySec; 127 | /*! Current time delayed before the acquisition [s] */ 128 | int StartupDelayRemainingTimeSec; 129 | /*! Timer before start acquisition*/ 130 | QTimer StartupDelayTimer; 131 | /*! Flag if cancel is requested */ 132 | bool CancelRequest; 133 | /*! Duration of the temporal calibration process in seconds */ 134 | int TemporalCalibrationDurationSec; 135 | /*! Timestamp of last recorded video item(items acquired since this timestamp will be recorded) */ 136 | double LastRecordedFixedItemTimestamp; 137 | /*! Timestamp of last recorded tracker item (items acquired since this timestamp will be recorded) */ 138 | double LastRecordedMovingItemTimestamp; 139 | /*! Time interval between recording (sampling) cycles (in milliseconds) */ 140 | int RecordingIntervalMs; 141 | /*! Time of starting temporal calibration*/ 142 | double StartTimeSec; 143 | /*! Saved tracker offset in case the temporal calibration is canceled or unsuccessful */ 144 | double PreviousFixedOffset; 145 | /*! Saved video offset in case the temporal calibration is canceled or unsuccessful */ 146 | double PreviousMovingOffset; 147 | /*! Metric table of video positions for temporal calibration */ 148 | vtkSmartPointer FixedPositionMetric; 149 | /*! Metric table of uncalibrated tracker positions for temporal calibration */ 150 | vtkSmartPointer UncalibratedMovingPositionMetric; 151 | /*! Metric table of calibrated tracker positions for temporal calibration */ 152 | vtkSmartPointer CalibratedMovingPositionMetric; 153 | /*! Window that is created/deleted when Show Plots button is toggled */ 154 | QWidget* TemporalCalibrationPlotsWindow; 155 | /*! Chart view for the uncalibrated plot */ 156 | vtkContextView* UncalibratedPlotContextView; 157 | /*! Chart view for the calibrated plot */ 158 | vtkContextView* CalibratedPlotContextView; 159 | 160 | vtkPlusChannel* FixedChannel; 161 | vtkPlusTemporalCalibrationAlgo::FRAME_TYPE FixedType; 162 | vtkPlusChannel* MovingChannel; 163 | vtkPlusTemporalCalibrationAlgo::FRAME_TYPE MovingType; 164 | 165 | igsioTransformName FixedValidationTransformName; 166 | igsioTransformName MovingValidationTransformName; 167 | 168 | vtkSmartPointer TemporalCalibrationAlgo; 169 | 170 | std::string RequestedFixedChannel; 171 | std::string RequestedMovingChannel; 172 | std::string RequestedFixedSource; 173 | std::string RequestedMovingSource; 174 | 175 | std::string LastSaveDirectory; 176 | QPushButton* SaveFileButton; 177 | 178 | vtkSmartPointer LineSegmenter; 179 | 180 | protected: 181 | Ui::TemporalCalibrationToolbox ui; 182 | }; 183 | 184 | #endif -------------------------------------------------------------------------------- /fCal/Toolboxes/QTemporalCalibrationToolbox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TemporalCalibrationToolbox 4 | 5 | 6 | 7 | 230 8 | 150 9 | 10 | 11 | 12 | Temporal Calibration 13 | 14 | 15 | 16 | 4 17 | 18 | 19 | 0 20 | 21 | 22 | 4 23 | 24 | 25 | 0 26 | 27 | 28 | 4 29 | 30 | 31 | 32 | 33 | 34 | 75 35 | true 36 | 37 | 38 | 39 | Temporal calibration is 0.0ms 40 | 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 49 | Qt::Horizontal 50 | 51 | 52 | 53 | 54 | 55 | 56 | Qt::Vertical 57 | 58 | 59 | QSizePolicy::Fixed 60 | 61 | 62 | 63 | 158 64 | 12 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 75 74 | true 75 | 76 | 77 | 78 | Instructions 79 | 80 | 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 88 | Qt::Vertical 89 | 90 | 91 | QSizePolicy::Fixed 92 | 93 | 94 | 95 | 158 96 | 12 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 0 108 | 0 109 | 110 | 111 | 112 | Fixed (offset=0) 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 0 121 | 0 122 | 123 | 124 | 125 | Moving (offset=x) 126 | 127 | 128 | 129 | 130 | 131 | 132 | false 133 | 134 | 135 | 136 | 137 | 138 | 139 | false 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | Qt::Vertical 155 | 156 | 157 | QSizePolicy::Fixed 158 | 159 | 160 | 161 | 20 162 | 12 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 4 171 | 172 | 173 | 174 | 175 | Qt::Horizontal 176 | 177 | 178 | 179 | 40 180 | 20 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | Start 189 | 190 | 191 | 192 | 193 | 194 | 195 | Qt::Horizontal 196 | 197 | 198 | 199 | 40 200 | 20 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | Show Plots 209 | 210 | 211 | true 212 | 213 | 214 | 215 | 216 | 217 | 218 | Qt::Horizontal 219 | 220 | 221 | 222 | 40 223 | 20 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | Qt::Vertical 234 | 235 | 236 | 237 | 158 238 | 40 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /fCal/Toolboxes/QVolumeReconstructionToolbox.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef VOLUMERECONSTRUCTIONTOOLBOX_H 8 | #define VOLUMERECONSTRUCTIONTOOLBOX_H 9 | 10 | #include "ui_QVolumeReconstructionToolbox.h" 11 | 12 | #include "QAbstractToolbox.h" 13 | #include "PlusConfigure.h" 14 | 15 | #include 16 | 17 | class vtkPlusVolumeReconstructor; 18 | class vtkImageData; 19 | 20 | //----------------------------------------------------------------------------- 21 | 22 | /*! \class VolumeReconstructionToolbox 23 | * \brief Volume reconstruction toolbox view class 24 | * \ingroup PlusAppFCal 25 | */ 26 | class QVolumeReconstructionToolbox : public QWidget, public QAbstractToolbox 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | /*! 32 | * Constructor 33 | * \param aParentMainWindow Parent main window 34 | * \param aFlags widget flag 35 | */ 36 | QVolumeReconstructionToolbox(fCalMainWindow* aParentMainWindow, Qt::WindowFlags aFlags = 0); 37 | 38 | /*! Destructor */ 39 | ~QVolumeReconstructionToolbox(); 40 | 41 | /*! \brief Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function */ 42 | virtual void OnActivated(); 43 | 44 | /*! 45 | * Finalize toolbox 46 | */ 47 | virtual void OnDeactivated(); 48 | 49 | /*! 50 | * Refresh contents (e.g. GUI elements) of toolbox according to the state in the toolbox controller - implementation of a pure virtual function 51 | */ 52 | virtual void RefreshContent(); 53 | 54 | /*! \brief Reset toolbox to initial state - */ 55 | virtual void Reset(); 56 | 57 | /*! 58 | * Sets display mode (visibility of actors) according to the current state - implementation of a pure virtual function 59 | */ 60 | void SetDisplayAccordingToState(); 61 | 62 | /*! 63 | * Add image file name to the list (usually when one is saved in Capturing toolbox) 64 | * \param aImageFileName Path and filename of the image 65 | */ 66 | void AddImageFileName(QString aImageFileName); 67 | 68 | protected: 69 | /*! 70 | * Reconstructs volume from input file 71 | * \return Success flag 72 | */ 73 | PlusStatus ReconstructVolumeFromInputImage(); 74 | 75 | /*! 76 | * Saves volume to file 77 | * \param aOutput Output file 78 | * \return Success flag 79 | */ 80 | PlusStatus SaveVolumeToFile(QString aOutput); 81 | 82 | /*! Display reconstructed volume in canvas */ 83 | void DisplayReconstructedVolume(); 84 | 85 | /*! 86 | * Populate image combobox from the image file name list and the unsaved data in Capturing toolbox if present 87 | */ 88 | void PopulateImageComboBox(); 89 | 90 | protected slots: 91 | /*! Slot handling open volume reconstruction config button click */ 92 | void OpenVolumeReconstructionConfig(); 93 | 94 | /*! Called when input image selection has been changed */ 95 | void InputImageChanged(int aItemIndex); 96 | 97 | /*! Slot handling open input image button click */ 98 | void OpenInputImage(); 99 | 100 | /*! Slot handling open reconstruct button click */ 101 | void Reconstruct(); 102 | 103 | /*! Slot handling open save button click */ 104 | void Save(); 105 | 106 | /*! Recompute the surface that is shown from the reconstructed volume when slider is moved */ 107 | void RecomputeContourFromReconstructedVolume(int aValue); 108 | 109 | protected: 110 | /*! Volume reconstructor instance */ 111 | vtkPlusVolumeReconstructor* m_VolumeReconstructor; 112 | 113 | /*! Reconstructed volume */ 114 | vtkImageData* m_ReconstructedVolume; 115 | 116 | /*! Flag indicating whether a volume reconstruction config file has been loaded successfully */ 117 | bool m_VolumeReconstructionConfigFileLoaded; 118 | 119 | /*! Flag indicating whether the volume reconstruction has been run */ 120 | bool m_VolumeReconstructionComplete; 121 | 122 | /*! Contouring threshold */ 123 | double m_ContouringThreshold; 124 | 125 | /*! String list containing the file names of the loaded images and the images that have been saved by Capturing toolbox */ 126 | QStringList m_ImageFileNames; 127 | 128 | /*! String to hold the last location of data saved */ 129 | QString m_LastSaveLocation; 130 | 131 | protected: 132 | Ui::VolumeReconstructionToolbox ui; 133 | }; 134 | 135 | #endif -------------------------------------------------------------------------------- /fCal/fCal.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Resources/icon_PopOut.png 4 | Resources/icon_HorizontalFlip.png 5 | Resources/icon_Save.png 6 | Resources/icon_Snapshot.png 7 | Resources/icon_SaveAll.png 8 | Resources/icon_ObjectMode.png 9 | Resources/icon_fCal.png 10 | Resources/icon_Import.png 11 | Resources/icon_Tools.png 12 | Resources/icon_ImageControl.png 13 | Resources/icon_Record.png 14 | Resources/icon_ShowDevices.png 15 | Resources/icon_DownArrow.png 16 | Resources/icon_OpenFile.png 17 | Resources/icon_Edit.png 18 | Resources/icon_Apply.png 19 | Resources/icon_Pause.png 20 | Resources/icon_Play.png 21 | 22 | 23 | -------------------------------------------------------------------------------- /fCal/fCal.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "Resources\icon_fCal.ico" -------------------------------------------------------------------------------- /fCal/fCalMain.cxx: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #include "fCalMainWindow.h" 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | QApplication app(argc, argv); 13 | 14 | fCalMainWindow mainWindow; 15 | mainWindow.showMaximized(); 16 | 17 | mainWindow.Initialize(); 18 | 19 | return app.exec(); 20 | } 21 | -------------------------------------------------------------------------------- /fCal/vtkPlus3DObjectVisualizer.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __vtk3DObjectVisualizer_h 8 | #define __vtk3DObjectVisualizer_h 9 | 10 | // Local includes 11 | #include "vtkPlusDisplayableObject.h" 12 | 13 | // PlusLib includes 14 | #include 15 | #include 16 | #include 17 | 18 | // VTK includes 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | //----------------------------------------------------------------------------- 29 | 30 | class vtkImageSliceMapper; 31 | 32 | /*! \class vtkPlus3DObjectVisualizer 33 | * \brief Class that manages the displaying of a 3D object visualization in a QT canvas element 34 | * \ingroup PlusAppCommonWidgets 35 | */ 36 | class vtkPlus3DObjectVisualizer : public vtkObject 37 | { 38 | public: 39 | vtkTypeMacro(vtkPlus3DObjectVisualizer, vtkObject); 40 | static vtkPlus3DObjectVisualizer* New(); 41 | 42 | /*! 43 | * Return a displayable object 44 | * \param aModelId Model ID of the object to return 45 | */ 46 | vtkPlusDisplayableObject* GetObjectById(const std::string& aModelId); 47 | 48 | /*! 49 | * Return a displayable object 50 | * \param aModelId Model ID of the object to return 51 | */ 52 | PlusStatus AddObject(vtkPlusDisplayableObject* displayableObject); 53 | 54 | /*! Clear displayable object vector */ 55 | PlusStatus ClearDisplayableObjects(); 56 | 57 | /*! 58 | * Show or hide all displayable objects 59 | * \param aOn Show if true, else hide 60 | */ 61 | PlusStatus ShowAllObjects(bool aOn); 62 | 63 | /* Return the actor of the volume actor */ 64 | vtkActor* GetVolumeActor(); 65 | 66 | /*! 67 | * Set the volume actor mapper 68 | * \param aContourMapper new mapper to use 69 | */ 70 | PlusStatus SetVolumeMapper(vtkPolyDataMapper* aContourMapper); 71 | 72 | /*! Set the slice number 73 | * \param sliceNumber the slice number to display 74 | */ 75 | PlusStatus SetSliceNumber(int number); 76 | 77 | /*! 78 | * Set the volume actor color 79 | * \param r red value 80 | * \param g green value 81 | * \param b blue value 82 | */ 83 | PlusStatus SetVolumeColor(double r, double g, double b); 84 | 85 | /*! 86 | * Show or hide a displayable object 87 | * \param aModelId Model ID of the object to work on 88 | * \param aOn Show if true, else hide 89 | */ 90 | PlusStatus ShowObjectById(const std::string& aModelId, bool aOn); 91 | 92 | /*! 93 | * Show or hide input points 94 | * \param aOn Show if true, else hide 95 | */ 96 | PlusStatus ShowInput(bool aOn); 97 | 98 | /*! 99 | * Set the actor color of the input polydata 100 | * \param r g b 101 | */ 102 | PlusStatus SetInputColor(double r, double g, double b); 103 | 104 | /*! 105 | * Show or hide result points 106 | * \param aOn Show if true, else hide 107 | */ 108 | PlusStatus ShowResult(bool aOn); 109 | 110 | /*! 111 | * Hide all tools, other models and the image from main canvas 112 | */ 113 | PlusStatus HideAll(); 114 | 115 | /*! 116 | * Read the active configuration file to create displayable objects 117 | */ 118 | PlusStatus ReadConfiguration(vtkXMLDataElement* aXMLElement); 119 | 120 | /*! 121 | * Update the displayable objects 122 | */ 123 | PlusStatus Update(); 124 | 125 | // Set/Get for member variables 126 | vtkRenderer* GetCanvasRenderer() const; 127 | vtkImageActor* GetImageActor() const; 128 | vtkSetObjectMacro(TransformRepository, vtkIGSIOTransformRepository); 129 | 130 | vtkSetMacro(WorldCoordinateFrame, std::string); 131 | vtkGetMacro(WorldCoordinateFrame, std::string); 132 | 133 | vtkGetMacro(VolumeID, std::string); 134 | 135 | void SetInputPolyData(vtkPolyData* aPolyData); 136 | void SetResultPolyData(vtkPolyData* aPolyData); 137 | 138 | PlusStatus SetChannel(vtkPlusChannel* channel); 139 | 140 | protected: 141 | void SetCanvasRenderer(vtkSmartPointer renderer); 142 | void SetImageActor(vtkSmartPointer imageActor); 143 | void SetInputActor(vtkSmartPointer inputActor); 144 | void SetResultActor(vtkSmartPointer resultActor); 145 | 146 | void SetResultGlyph(vtkSmartPointer glyph); 147 | vtkSmartPointer GetResultGlyph() const; 148 | 149 | void SetInputGlyph(vtkSmartPointer glyph); 150 | vtkSmartPointer GetInputGlyph() const; 151 | 152 | vtkSetMacro(VolumeID, std::string); 153 | vtkSetObjectMacro(SelectedChannel, vtkPlusChannel); 154 | 155 | protected: 156 | /*! List of displayable objects */ 157 | std::vector DisplayableObjects; 158 | 159 | /*! Renderer for the canvas */ 160 | vtkSmartPointer CanvasRenderer; 161 | 162 | /*! Canvas image actor */ 163 | vtkSmartPointer ImageActor; 164 | 165 | /*! Actor for displaying the input points in 3D */ 166 | vtkSmartPointer InputActor; 167 | 168 | /*! Slice mapper to enable slice selection */ 169 | vtkSmartPointer ImageMapper; 170 | 171 | /*! Glyph producer for result */ 172 | vtkSmartPointer InputGlyph; 173 | 174 | /*! Actor for displaying the result points (eg. stylus tip, segmented points) */ 175 | vtkSmartPointer ResultActor; 176 | 177 | /*! Glyph producer for result */ 178 | vtkSmartPointer ResultGlyph; 179 | 180 | /*! Name of the rendering world coordinate frame */ 181 | std::string WorldCoordinateFrame; 182 | 183 | /*! Name of the volume object ID */ 184 | std::string VolumeID; 185 | 186 | /*! Reference to Transform repository that stores and handles all transforms */ 187 | vtkIGSIOTransformRepository* TransformRepository; 188 | 189 | /*! Channel to visualize */ 190 | vtkPlusChannel* SelectedChannel; 191 | 192 | protected: 193 | vtkPlus3DObjectVisualizer(); 194 | virtual ~vtkPlus3DObjectVisualizer(); 195 | }; 196 | 197 | #endif //__vtk3DObjectVisualizer_h -------------------------------------------------------------------------------- /fCal/vtkPlusDisplayableObject.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __vtkDisplayableObject_h 8 | #define __vtkDisplayableObject_h 9 | 10 | // PlusLib includes 11 | #include 12 | 13 | // VTK includes 14 | #include 15 | #include 16 | 17 | class vtkProp3D; 18 | class vtkMapper; 19 | class vtkPolyData; 20 | class vtkPolyDataMapper; 21 | 22 | //----------------------------------------------------------------------------- 23 | 24 | /*! \class vtkPlusDisplayableObject 25 | * \brief Class that encapsulates the objects needed for visualizing a tool - the tool object, the actor, a flag indicating whether it is displayable 26 | * \ingroup PlusAppCommonWidgets 27 | */ 28 | class vtkPlusDisplayableObject : public vtkObject 29 | { 30 | public: 31 | vtkTypeMacro(vtkPlusDisplayableObject, vtkObject); 32 | static vtkPlusDisplayableObject* New(); 33 | 34 | /*! 35 | * New function that gets the type and instantiates the proper displayable object class 36 | * \param aType Type that is read from the DisplayabelObject element of the configuration (eg. "Model") 37 | */ 38 | static vtkPlusDisplayableObject* New(const char* aType); 39 | 40 | /*! Returns displayable status */ 41 | virtual bool IsDisplayable() = 0; 42 | 43 | /*! 44 | * Read displayable object configuration 45 | * \param aConfig DisplayableObject element from the input device set configuration (not the root as usually!) 46 | */ 47 | virtual PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 48 | 49 | public: 50 | vtkSetMacro(ObjectCoordinateFrame, std::string); 51 | vtkGetMacro(ObjectCoordinateFrame, std::string); 52 | 53 | void SetActor(vtkProp3D*); 54 | vtkGetObjectMacro(Actor, vtkProp3D); 55 | 56 | vtkSetMacro(Displayable, bool); 57 | vtkBooleanMacro(Displayable, bool); 58 | 59 | vtkSetMacro(LastOpacity, double); 60 | vtkGetMacro(LastOpacity, double); 61 | 62 | vtkSetMacro(ObjectId, std::string); 63 | vtkGetMacro(ObjectId, std::string); 64 | 65 | virtual void SetOpacity(double aOpacity) = 0; 66 | virtual double GetOpacity() = 0; 67 | 68 | protected: 69 | vtkPlusDisplayableObject(); 70 | virtual ~vtkPlusDisplayableObject(); 71 | 72 | protected: 73 | /* Object coordinate frame name */ 74 | std::string ObjectCoordinateFrame; 75 | 76 | /*! Id of the model, for lookup purposes */ 77 | std::string ObjectId; 78 | 79 | /*! Actor displaying the tool model */ 80 | vtkProp3D* Actor; 81 | 82 | /*! Flag that can disable displaying of this tool */ 83 | bool Displayable; 84 | 85 | /*! Previously set opacity */ 86 | double LastOpacity; 87 | }; 88 | 89 | //----------------------------------------------------------------------------- 90 | 91 | /*! \class vtkDisplayableImage 92 | * \brief Specialized vtkPlusDisplayableObject that displays an image 93 | * \ingroup PlusAppCommonWidgets 94 | */ 95 | class vtkDisplayableImage : public vtkPlusDisplayableObject 96 | { 97 | public: 98 | vtkTypeMacro(vtkDisplayableImage, vtkPlusDisplayableObject); 99 | static vtkDisplayableImage* New(); 100 | 101 | /*! Returns displayable status (true if displayable flag is on) */ 102 | bool IsDisplayable(); 103 | 104 | public: 105 | /*! Set opacity */ 106 | void SetOpacity(double aOpacity); 107 | /*! Get opacity */ 108 | double GetOpacity(); 109 | 110 | protected: 111 | vtkDisplayableImage(); 112 | virtual ~vtkDisplayableImage(); 113 | }; 114 | 115 | //----------------------------------------------------------------------------- 116 | 117 | /*! \class vtkDisplayableAxes 118 | * \brief Specialized vtkPlusDisplayableObject that displays axes of a coordinate system 119 | * \ingroup PlusAppCommonWidgets 120 | */ 121 | class vtkDisplayableAxes : public vtkPlusDisplayableObject 122 | { 123 | public: 124 | vtkTypeMacro(vtkDisplayableAxes, vtkPlusDisplayableObject); 125 | static vtkDisplayableAxes* New(); 126 | 127 | /*! Returns displayable status (true if displayable flag is on) */ 128 | bool IsDisplayable(); 129 | 130 | /*! Overridden set function for object coordinate frame that sets the axes name */ 131 | virtual void SetObjectCoordinateFrame(const char* objectCoordinateFrame); 132 | 133 | public: 134 | /*! Set opacity */ 135 | void SetOpacity(double aOpacity); 136 | /*! Get opacity */ 137 | double GetOpacity(); 138 | 139 | protected: 140 | vtkDisplayableAxes(); 141 | virtual ~vtkDisplayableAxes(); 142 | }; 143 | 144 | //----------------------------------------------------------------------------- 145 | 146 | /*! \class vtkDisplayablePolyData 147 | * \brief Specialized vtkPlusDisplayableObject that displays a poly data 148 | * \ingroup PlusAppCommonWidgets 149 | */ 150 | class vtkDisplayablePolyData : public vtkPlusDisplayableObject 151 | { 152 | public: 153 | vtkTypeMacro(vtkDisplayablePolyData, vtkPlusDisplayableObject); 154 | static vtkDisplayablePolyData* New(); 155 | 156 | /*! Returns displayable status (true if displayable flag is on and valid actor is present) */ 157 | bool IsDisplayable(); 158 | 159 | /*! Set color */ 160 | void SetColor(double aR, double aG, double aB); 161 | 162 | /* Get poly data */ 163 | vtkGetObjectMacro(PolyData, vtkPolyData); 164 | 165 | /* Set poly data */ 166 | virtual void SetPolyData(vtkPolyData* polyData); 167 | 168 | /* Set poly data mapper */ 169 | virtual void SetPolyDataMapper(vtkPolyDataMapper* aPolyDataMapper); 170 | 171 | /*! Appends a polydata to the already existing one */ 172 | PlusStatus AppendPolyData(vtkPolyData* aPolyData); 173 | 174 | public: 175 | /*! Set opacity */ 176 | void SetOpacity(double aOpacity); 177 | /*! Get opacity */ 178 | double GetOpacity(); 179 | 180 | protected: 181 | vtkDisplayablePolyData(); 182 | virtual ~vtkDisplayablePolyData(); 183 | 184 | protected: 185 | /*! Displayed poly data */ 186 | vtkPolyData* PolyData; 187 | }; 188 | 189 | //----------------------------------------------------------------------------- 190 | 191 | /*! \class vtkDisplayableModel 192 | * \brief Specialized vtkPlusDisplayableObject that displays a model 193 | * \ingroup PlusAppCommonWidgets 194 | */ 195 | class vtkDisplayableModel : public vtkDisplayablePolyData 196 | { 197 | public: 198 | vtkTypeMacro(vtkDisplayableModel, vtkDisplayablePolyData); 199 | static vtkDisplayableModel* New(); 200 | 201 | /*! 202 | * Read displayable object configuration 203 | * \param aConfig DisplayableObject element from the input device set configuration (not the root as usually!) 204 | */ 205 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 206 | 207 | public: 208 | /*! Set STL model file name */ 209 | vtkSetStringMacro(STLModelFileName); 210 | /*! Get STL model file name */ 211 | vtkGetStringMacro(STLModelFileName); 212 | 213 | /*! Get model to tool transform */ 214 | vtkGetObjectMacro(ModelToObjectTransform, vtkTransform); 215 | 216 | protected: 217 | /*! Set model to tool transform */ 218 | vtkSetObjectMacro(ModelToObjectTransform, vtkTransform); 219 | 220 | /*! Assemble and set default stylus model for stylus tool actor */ 221 | PlusStatus SetDefaultStylusModel(); 222 | 223 | protected: 224 | vtkDisplayableModel(); 225 | virtual ~vtkDisplayableModel(); 226 | 227 | protected: 228 | /*! Name of the STL file containing the 3D model of this tool */ 229 | char* STLModelFileName; 230 | 231 | /* Model to tool transform */ 232 | vtkTransform* ModelToObjectTransform; 233 | }; 234 | 235 | #endif -------------------------------------------------------------------------------- /fCal/vtkPlusImageVisualizer.h: -------------------------------------------------------------------------------- 1 | /*=Plus=header=begin====================================================== 2 | Program: Plus 3 | Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. 4 | See License.txt for details. 5 | =========================================================Plus=header=end*/ 6 | 7 | #ifndef __vtkImageVisualizer_h 8 | #define __vtkImageVisualizer_h 9 | 10 | // PlusLib includes 11 | #include 12 | #include 13 | #include 14 | 15 | // VTK includes 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class vtkXMLDataElement; 30 | class vtkLineSource; 31 | class vtkImageSliceMapper; 32 | 33 | //----------------------------------------------------------------------------- 34 | 35 | /*! \class ImageVisualizer 36 | * \brief Class that manages the displaying of a 2D image in a QT canvas element 37 | * \ingroup PlusAppCommonWidgets 38 | */ 39 | class vtkPlusImageVisualizer : public vtkObject 40 | { 41 | 42 | public: 43 | static vtkPlusImageVisualizer* New(); 44 | vtkTypeMacro(vtkPlusImageVisualizer, vtkObject); 45 | 46 | /*! Publicly available color for ROI */ 47 | static double ROI_COLOR[3]; 48 | 49 | /*! Read clipping rectangle parameters from XML */ 50 | PlusStatus ReadRoiConfiguration(vtkXMLDataElement* aXMLElement); 51 | 52 | /* Read rendering configuration 53 | * \param aConfig Root element of the device set configuration 54 | */ 55 | PlusStatus ReadConfiguration(vtkXMLDataElement* aConfig); 56 | 57 | /// Calculate and set camera parameters so that image fits canvas in image mode 58 | 59 | PlusStatus UpdateCameraPose(); 60 | 61 | /*! Show or hide the MF orientation markers 62 | * \param aEnable Show/Hide 63 | */ 64 | PlusStatus ShowOrientationMarkers(bool aShow); 65 | 66 | /*! Set the input source 67 | * \param aImage pointer to the image data to show 68 | */ 69 | void SetInputData(vtkImageData* aImage); 70 | 71 | /* Set the slice number of the data */ 72 | PlusStatus SetSliceNumber(int number); 73 | 74 | void SetResultPolyData(vtkPolyData* aResultPolyData); 75 | 76 | /*! Show or hide result points 77 | * \param aOn Show if true, else hide 78 | */ 79 | PlusStatus ShowResult(bool aOn); 80 | 81 | /// Hide all tools, other models and the image from main canvas 82 | 83 | PlusStatus HideAll(); 84 | 85 | /*! Set MF orientation in 2D mode 86 | * \param aNewOrientation The new MF orientation 87 | */ 88 | PlusStatus SetScreenRightDownAxesOrientation(US_IMAGE_ORIENTATION aOrientation = US_IMG_ORIENT_MF); 89 | 90 | /*! Add an actor to the list of screen aligned actors 91 | * \param aProp vtkProp3D to be managed 92 | */ 93 | PlusStatus AddScreenAlignedProp(vtkProp3D* aProp); 94 | 95 | /*! Remove an actor from the list of screen aligned actors 96 | * \param aProp vtkProp3D to be managed 97 | */ 98 | PlusStatus RemoveScreenAlignedProp(vtkProp3D* aProp); 99 | 100 | /*! Set the ROI region 101 | * \param xMin min x bounds of ROI 102 | * \param xMax max x bounds of ROI 103 | * \param yMin min y bounds of ROI 104 | * \param yMax max y bounds of ROI 105 | */ 106 | PlusStatus SetROIBounds(int xMin, int xMax, int yMin, int yMax); 107 | 108 | /*! Enable/disable ROI visualization 109 | * \param aEnable enable/disable flag 110 | */ 111 | PlusStatus EnableROI(bool aEnable); 112 | 113 | /*! Accept fiducial point information for displaying wire labels 114 | * \param aPointList x/y location for labels 115 | */ 116 | PlusStatus SetWireLabelPositions(vtkPoints* aPointList); 117 | 118 | /*! Enable/disable wire label visualization 119 | * \param aEnable enable/disable flag 120 | */ 121 | PlusStatus EnableWireLabels(bool aEnable); 122 | 123 | /// Control the image actor visibility 124 | vtkImageActor* GetImageActor(); 125 | 126 | /// Accessors 127 | vtkRenderer* GetCanvasRenderer(); 128 | 129 | /// Reset the visualization 130 | PlusStatus Reset(); 131 | 132 | void SetChannel(vtkPlusChannel* channel); 133 | 134 | // Utility functions 135 | PlusStatus SetResultColor(double r, double g, double b); 136 | PlusStatus SetResultOpacity(double aOpacity); 137 | 138 | // Line segmentation actor functions 139 | void SetLineSegmentationVisible(bool _arg); 140 | void SetLineSegmentationPoints(double startPoint_Image[2], double endPoint_Image[2]); 141 | 142 | protected: 143 | vtkPlusImageVisualizer(); 144 | ~vtkPlusImageVisualizer(); 145 | 146 | vtkSetObjectMacro(SelectedChannel, vtkPlusChannel); 147 | 148 | /// Initialize Orientation 3D Actors 149 | void InitializeOrientationMarkers(); 150 | 151 | // Initialize line segmentation 3D actors 152 | void InitializeLineSegmentationMarkers(); 153 | 154 | /// Initialize the ROI sources/actors 155 | void InitializeROIVisualization(); 156 | 157 | /// Calculate the correct orientation and position of the markers 158 | PlusStatus UpdateOrientationMarkerLabelling(); 159 | 160 | /// Clear list of screen-aligned actors, Also does memory cleanup 161 | PlusStatus ClearScreenAlignedActorList(); 162 | 163 | /// Update the position and orientation of actors to become screen aligned 164 | 165 | PlusStatus UpdateScreenAlignedActors(); 166 | 167 | /// Initialize the wire actors 168 | PlusStatus InitializeWireLabelVisualization(vtkXMLDataElement* aConfig); 169 | 170 | /// Clear the wire actors 171 | PlusStatus ClearWireLabelVisualization(); 172 | 173 | protected: 174 | /// Renderer for the canvas 175 | vtkSmartPointer CanvasRenderer; 176 | /// Canvas image actor 177 | vtkSmartPointer ImageActor; 178 | /// Image slice mapper of image actor 179 | vtkSmartPointer ImageMapper; 180 | /// Polydata holding the result points (eg. stylus tip, segmented points) 181 | vtkSmartPointer ResultPolyData; 182 | /// Actor for displaying the result points (eg. stylus tip, segmented points) 183 | vtkSmartPointer ResultActor; 184 | /// Glyph producer for result 185 | vtkSmartPointer ResultGlyph; 186 | /// Camera of the scene 187 | vtkSmartPointer ImageCamera; 188 | /// Assembly of actors for displaying the MF orientation 189 | vtkSmartPointer OrientationMarkerAssembly; 190 | /// Specific reference to the horizontal text actor 191 | vtkSmartPointer HorizontalOrientationTextActor; 192 | /// Specific reference to the vertical text actor 193 | vtkSmartPointer VerticalOrientationTextActor; 194 | /// The current horizontal orientation of the orientation markers 195 | double ScreenAlignedCurrentXRotation; 196 | /// The current vertical orientation of the orientation markers 197 | double ScreenAlignedCurrentYRotation; 198 | /// Record the current state of the marker orientation 199 | US_IMAGE_ORIENTATION CurrentMarkerOrientation; 200 | /// List of objects maintained by the visualizer to be screen aligned 201 | vtkSmartPointer ScreenAlignedProps; 202 | /// List of original positions of screen-aligned objects 203 | std::vector> ScreenAlignedPropOriginalPosition; 204 | /// Flag to hold value of show/hide ROI 205 | bool ShowROI; 206 | /// Assembly to hold all of the actors of the ROI for easy hide/show 207 | vtkSmartPointer ROIActorAssembly; 208 | /// Line source of left line (one side of the ROI rectangle) 209 | vtkSmartPointer LeftLineSource; 210 | /// Line source of top line (one side of the ROI rectangle) 211 | vtkSmartPointer TopLineSource; 212 | /// Line source of right line (one side of the ROI rectangle) 213 | vtkSmartPointer RightLineSource; 214 | /// Line source of bottom line (one side of the ROI rectangle) 215 | vtkSmartPointer BottomLineSource; 216 | /// Array holding the bounds of the ROI 217 | double RegionOfInterest[4]; 218 | /// The channel to visualize 219 | vtkPlusChannel* SelectedChannel; 220 | /// Vector to hold the actors for each wire 221 | std::vector> WireActors; 222 | /// Line visualization members 223 | vtkSmartPointer LineSegmentationLineSource; 224 | vtkSmartPointer LineSegmentationActor; 225 | }; 226 | 227 | #endif 228 | --------------------------------------------------------------------------------