# SlicerRT — Radiation Therapy extension for 3D Slicer. # Provides DICOM-RT import/export, dose volume histograms, contour # operations, and supports treatment planning workflows. # # Large extension (C++ modules); among the most-installed Slicer # extensions in oncology research labs. %global commit f57ccf38 %global longcommit f57ccf38fe72874dca844311557b1f997d21a98a %global slicer_inst %{_prefix}/lib/slicer %global slicer_subdir Slicer-5.12 %global snapdate 20260821 Name: 3dslicer-rt Version: 0 Release: 0.13.%{snapdate}git%{commit}%{?dist} Summary: Radiation Therapy extension for 3D Slicer License: BSD-3-Clause URL: https://github.com/SlicerRt/SlicerRt Source0: %{url}/archive/%{commit}/SlicerRt-%{commit}.tar.gz # DrrImageComputation uses a Beams header without declaring the include dir. Patch0: slicerrt-drr-beams-include.patch # Beams and ExternalBeamPlanning do the same with vtkIECTransformLogic.h. Patch1: slicerrt-beams-logic-include.patch # Qt 6 deletes QVariant(char*); the beam IDs need an explicit QString. Patch2: slicerrt-qt6-qvariant-id.patch # ctkLayoutManager.h needs QtXml; five modules reach it without linking it. Patch3: slicerrt-qtxml-layout-manager.patch # The constraint classes moc DoseType without the metatype declaration in scope. Patch4: slicerrt-metatype-dosetype-order.patch # Qt 6 removed QTime::start()/elapsed(); QElapsedTimer replaces them. Patch5: slicerrt-qelapsedtimer.patch BuildRequires: cmake >= 3.20 BuildRequires: ninja-build BuildRequires: gcc-c++ BuildRequires: 3dslicer-devel >= 5.12.3 BuildRequires: InsightToolkit5-devel >= 5.4.6 BuildRequires: vtk-devel >= 9.6 BuildRequires: dcmtk-devel BuildRequires: jsoncpp-devel BuildRequires: libcurl-devel BuildRequires: python3-devel BuildRequires: rapidjson-devel BuildRequires: SlicerExecutionModel-devel BuildRequires: vtkIECTransformLogic-devel # plastimatch: this was disabled in 0.2 because our plastimatch package shipped # binaries only. That is no longer true -- plastimatch-devel 1.10.0-12 ships the # headers and /usr/lib64/cmake/plastimatch/PlastimatchConfig.cmake -- so the # plastimatch-backed modules are on. Beams/ is not optional scenery: it returns # early when Plastimatch_FOUND is false, and DrrImageComputation includes # vtkMRMLRTBeamNode.h from it regardless. %bcond_without plastimatch %if %{with plastimatch} BuildRequires: plastimatch-devel %endif # Canonical Slicer-extension buildroot, grafted from 3dslicer-dmri.spec. # This spec predates the 5.12 retarget and was never built, so it carried # only a handful of BuildRequires -- find_package(Slicer) then failed inside # SlicerConfig.cmake:672 on find_package(RapidJSON), the first of ~38 missing. # Full Qt6 set find_package(Slicer)'s Qt check demands. BuildRequires: cmake(Qt6Core) BuildRequires: cmake(Qt6Gui) BuildRequires: cmake(Qt6Widgets) BuildRequires: cmake(Qt6Network) BuildRequires: cmake(Qt6Sql) BuildRequires: cmake(Qt6Svg) BuildRequires: cmake(Qt6Xml) BuildRequires: cmake(Qt6OpenGL) BuildRequires: cmake(Qt6OpenGLWidgets) BuildRequires: cmake(Qt6PrintSupport) BuildRequires: cmake(Qt6Multimedia) BuildRequires: cmake(Qt6MultimediaWidgets) BuildRequires: cmake(Qt6Core5Compat) BuildRequires: cmake(Qt6StateMachine) BuildRequires: cmake(Qt6WebEngineCore) BuildRequires: cmake(Qt6WebEngineWidgets) BuildRequires: cmake(Qt6WebChannel) BuildRequires: cmake(Qt6Qml) BuildRequires: cmake(Qt6Quick) BuildRequires: cmake(Qt6QuickWidgets) BuildRequires: cmake(Qt6Test) BuildRequires: cmake(Qt6UiTools) BuildRequires: qt6-qttools-devel BuildRequires: InsightToolkit5-vtk-devel BuildRequires: ctk-devel BuildRequires: qttesting-devel BuildRequires: vtkAddon-devel BuildRequires: qRestAPI-devel BuildRequires: python-pythonqt-devel BuildRequires: commontk-applauncher-devel BuildRequires: teem-devel Requires: 3dslicer >= 5.10.0 %description SlicerRT extends 3D Slicer with radiation-therapy-specific functionality: * DICOM-RT Structure Set, Dose, Plan, Image import/export * Dose volume histogram (DVH) computation * Contour comparison metrics (Dice, Hausdorff, mean surface distance) * Patient hierarchy for multi-modality oncology cases * Dose accumulation with deformable registration * Beam visualization and dose viewing Built on the plastimatch library and used widely in academic radiation oncology and dose research. %prep %autosetup -p1 -n SlicerRT-%{longcommit} # Interim: skip Slicer's extension CPack module. 3dslicer-devel is supposed to # ship extension_description.s4ext.in at lib/Utilities/Templates/Extensions/ # (3dslicer 5.12.3-4 step 5), but -4 packaged only the directories, so the # template is still missing and SlicerExtensionCPack still hard-fails. Drop # this sed once a 3dslicer that actually ships the file is in the repo. sed -i '/include(${Slicer_EXTENSION_CPACK})/d' CMakeLists.txt %build %cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING:BOOL=OFF \ -DSlicerRT_SUPERBUILD:BOOL=OFF \ `# SlicerExtensionCPack.cmake FATAL_ERRORs unless these point at real files.` \ `# It only runs when EXTENSION_NAME == PROJECT_NAME, which is true for` \ `# SlicerRT but not for the other extensions, so only this one needs them.` \ -DEXTENSION_README_FILE:FILEPATH=$PWD/README.md \ -DEXTENSION_LICENSE_FILE:FILEPATH=$PWD/LICENSE.txt \ `# Was %{_prefix}/lib/slicer-5.10.0/lib/cmake/Slicer -- a Slicer 5.10 layout` \ `# that has not existed since the 5.12 retarget. This spec was written then` \ `# and never built, so nothing ever caught it.` \ -DSlicer_DIR:PATH=%{slicer_inst}/lib/%{slicer_subdir} \ -DITK_DIR:PATH=%{_prefix}/lib/cmake/ITK-5.4 \ -DVTK_DIR:PATH=%{_libdir}/cmake/vtk \ %if %{with plastimatch} `# SlicerRT reads ${Plastimatch_DIR} -- mixed case. PLASTIMATCH_DIR was` \ `# never read, so find_package(Plastimatch ... NO_DEFAULT_PATH) searched` \ `# an empty PATHS list, Plastimatch_FOUND stayed false, and Beams/` \ `# returned early -- taking vtkMRMLRTBeamNode.h with it.` \ -DPlastimatch_DIR:PATH=%{_libdir}/cmake/plastimatch \ %endif -DCMAKE_SKIP_INSTALL_RPATH:BOOL=ON \ -DCMAKE_INSTALL_PREFIX:PATH=%{slicer_inst} %cmake_build %install %cmake_install %files %license License.txt 2>/dev/null || true %doc README.md %{slicer_inst}/lib/%{slicer_subdir}/qt-loadable-modules/*RT* %{slicer_inst}/lib/%{slicer_subdir}/qt-loadable-modules/*Dose* %{slicer_inst}/lib/%{slicer_subdir}/cli-modules/*DICOM*RT* %{slicer_inst}/share/%{slicer_subdir}/qt-loadable-modules/* %changelog * Thu Sep 03 2026 Morgan Hough - 0-0.13.20260821gitf57ccf38 - Add slicerrt-qelapsedtimer.patch: Qt 6 removed QTime::start() and QTime::elapsed(); QElapsedTimer keeps the same shape and is monotonic. * Thu Sep 03 2026 Morgan Hough - 0-0.12.20260821gitf57ccf38 - Add slicerrt-metatype-dosetype-order.patch: qSlicerAbstractConstraint mocs DoseType without Q_DECLARE_METATYPE in scope, and its moc sorts ahead of qSlicerAbstractObjective's in mocs_compilation.cpp. * Thu Sep 03 2026 Morgan Hough - 0-0.11.20260821gitf57ccf38 - Add slicerrt-qtxml-layout-manager.patch: ctkLayoutManager.h includes , and the five modules that reach it via qSlicerLayoutManager.h link nothing that carries QtXml. * Thu Sep 03 2026 Morgan Hough - 0-0.10.20260821gitf57ccf38 - Update to snapshot f57ccf38 (2026-08-21). Upstream commit 242cde10 (2026-06-09) ports the Isodose subject-hierarchy plugin to Slicer 5.12's strongly typed qSlicerTerminologyMetadata color API, which our 5.12.3 build requires; the old pin overrode the QMap overloads that are no longer virtual. - Regenerate slicerrt-qt6-qvariant-id.patch: still needed, and the new snapshot adds a seventh call site (bevButton). * Thu Sep 03 2026 Morgan Hough - 0-0.9.20260515gitcba32f11 - Add slicerrt-qt6-qvariant-id.patch: Qt 6 deletes QVariant(char*), so the six beam-ID setData/setProperty calls in qMRMLBeamsTableView need a QString. * Thu Sep 03 2026 Morgan Hough - 0-0.8.20260515gitcba32f11 - Add slicerrt-beams-logic-include.patch: Beams and both halves of ExternalBeamPlanning include vtkSlicerBeamsModuleLogic.h without declaring the vtkIECTransformLogic include directory it needs. * Wed Sep 02 2026 Morgan Hough - 0-0.7.20260515gitcba32f11 - Move the %%bcond_without plastimatch declaration above its first use. It sat ~45 lines below the '%%if %%{with plastimatch}' guarding the BuildRequires, so at that point the condition was undefined and plastimatch-devel was never pulled into the buildroot -- Plastimatch_DIR pointed at a directory that did not exist, find_package still failed, and Beams was still skipped. * Wed Sep 02 2026 Morgan Hough - 0-0.6.20260515gitcba32f11 - Enable the plastimatch bcond and pass Plastimatch_DIR with the case SlicerRT actually reads. The spec passed -DPLASTIMATCH_DIR; SlicerRT does find_package(Plastimatch QUIET PATHS ${Plastimatch_DIR} NO_DEFAULT_PATH), and CMake variables are case-sensitive, so it searched an empty path list. Plastimatch_FOUND stayed false, Beams/CMakeLists.txt returned early, and DrrImageComputation then could not find vtkMRMLRTBeamNode.h -- which is what the previous release chased as an include-path bug. - The bcond was added in 0.2 because plastimatch shipped no headers. It does now: plastimatch-devel 1.10.0-12 provides PlastimatchConfig.cmake. * Tue Sep 01 2026 Morgan Hough - 0-0.5.20260515gitcba32f11 - Add slicerrt-drr-beams-include.patch. vtkMRMLDrrImageComputationNode.cxx includes vtkMRMLRTBeamNode.h from Beams/MRML, but DrrImageComputation's INCLUDE_DIRECTORIES never listed it, so the build died with 'vtkMRMLRTBeamNode.h: No such file or directory'. RoomsEyeView/Logic and ExternalBeamPlanning already declare vtkSlicerBeamsModuleMRML_INCLUDE_DIRS; this matches them. * Sun Aug 23 2026 Morgan Hough - 0-0.4.20260515gitcba32f11 - Rebuild against VTK 9.7.0. VTK here installs unversioned sonames (libvtk*.so.1), so 9.7 replaces 9.6 in place and every consumer must be rebuilt or it fails at runtime with undefined symbols. - Complete the grafted Slicer-extension buildroot. find_package(Slicer) died in SlicerConfig.cmake:672 on find_package(RapidJSON): the graft from 3dslicer-dmri.spec had left out rapidjson-devel, jsoncpp-devel, libcurl-devel, python3-devel and SlicerExecutionModel-devel. Unrelated to VTK 9.7 -- this spec had simply never been built with the full set. - Set _SUPERBUILD=OFF and correct CMAKE_INSTALL_PREFIX. The extension CMakeLists default SUPERBUILD to ON, which makes the configure run ExternalProject_Add and try to git-clone its dependencies at build time -- impossible in a COPR/mock build, which has neither network nor git (Git_VERSION=''). The dependencies are already packaged, so the inner build is the right one. The install prefix AND the %files paths still pointed at the Slicer 5.10.0 layout that has not existed since the 5.12 retarget; both now use %%{slicer_inst}/%%{slicer_subdir}. - Drop include(${Slicer_EXTENSION_CPACK}) in %prep. It generates Extension-Manager packaging only, and against an installed Slicer it fails: the README/LICENSE vars it demands have no defaults, and the .s4ext template it configures is looked for under lib/Utilities/Templates while 3dslicer installs it under share/Slicer-5.12/Wizard/Templates. No install() rules are lost. - Drop the local workaround that deleted include(${Slicer_EXTENSION_CPACK}): 3dslicer 5.12.3-4 now installs extension_description.s4ext.in where the installed SlicerConfig looks for it, so the module works as intended and every extension benefits rather than each one patching around it. * Sun Aug 02 2026 Morgan Hough - 0-0.3.20260515gitcba32f11 - Graft the canonical Slicer-extension buildroot (~34 BuildRequires) from 3dslicer-dmri.spec. This spec predates the 5.12 retarget and was never built, so it carried only a handful; find_package(Slicer) then failed inside SlicerConfig.cmake:672 on find_package(RapidJSON) -- the first of the missing set, which also covers the full Qt6 component list, ITK/VTK/CTK/DCMTK devel, SlicerExecutionModel, PythonQt, qRestAPI, teem and vtkAddon. * Sun Aug 02 2026 Morgan Hough - 0-0.2.20260515gitcba32f11 - Point Slicer_DIR at the 5.12 layout (was a Slicer 5.10 path that has not existed since the retarget) and drop the unsatisfiable plastimatch-devel BuildRequires -- our plastimatch package ships binaries only, no headers. Gate PLASTIMATCH_DIR on a %%bcond so the plastimatch-backed modules can be turned on once plastimatch-devel exists. * Wed May 27 2026 Morgan Hough - 0-0.1.20260515gitcba32f11 - Initial COPR package tracking SlicerRt master. - Builds against stable 3dslicer-5.10.0 + plastimatch (from this COPR).