# 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.25.%{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 # DesignerPlugins output lands under the install prefix; honour Slicer's flag. Patch6: slicerrt-designer-plugins-guard.patch # DoseComparison and ExternalBeamPlanning call SubjectHierarchy without linking it. Patch7: slicerrt-subjecthierarchy-link.patch # SlicerRT includes ITK's Eigen via , the bundled-only path. # Against InsightToolkit5 5.4.7-8 (ITK_USE_SYSTEM_EIGEN=ON) those headers live at # and the build fails. ITK ships itk_eigen.h for exactly this case: # ITK_EIGEN(x) resolves to whichever is correct, so the same source builds against # bundled or system Eigen. Six includes across five files; vtkMRMLRTBeamNode.h is # public, so this is API-visible for SlicerRT consumers. Upstreamable. Patch8: slicerrt-itk-eigen-portable.patch # PlmDrr/plastimatch_slicer_drr.cxx uses the pre-5.1 class-scope enum aliases # (itk::ImageIOBase::IOPixelType, IOComponentType and UCHAR/CHAR/.../DOUBLE), which ITK_LEGACY_REMOVE # deletes. InsightToolkit5 has had it on since python3-itk wrapping was enabled (-9 onward), so this # failed to compile on rawhide ("'IOPixelType' is not a member of 'itk::ImageIOBase'", 15 errors) and # would on every chroot at the next rebuild; f44/f45 only built because their last build predates it. # The modern spelling, itk::IOPixelEnum and itk::IOComponentEnum, is what SlicerExecutionModel's own # GetImageType() already takes, and compiles with or without legacy. Compile-checked against ITK # 5.4.7-19 with the legacy spelling as a control that fails. Whole-tree sweep: this is the only file # (13 lines). Upstreamable to SlicerRT. Patch9: slicerrt-itk-iocomponent-enum.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 >= 1.10.0-9 %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 >= 0.1.34-0.9 BuildRequires: teem-devel Requires: 3dslicer >= 5.10.0 # Six shipped .py files import SimpleITK, and nothing required python3-simpleitk. Requires: python3-simpleitk # PlmRegister.py does "import RegistrationLib" and subclasses RegistrationLib.RegistrationPlugin; that # package comes from the LandmarkRegistration extension and SlicerRT declares no dependency on it # (EXTENSION_DEPENDS "NA"), so the module failed to load with "No module named 'RegistrationLib'". Requires: 3dslicer-landmarkregistration # VTK freezes its soname at libvtk*.so.1 across all of 9.x, so the auto-generated # libvtkCommonCore.so.1 requires are satisfied by 9.5, 9.6 and 9.7 alike: a consumer # built against one installs cleanly against another and fails only at load. # %%vtk_abi comes from vtk-devel's macros.vtk, so this re-pins on every rebuild. Requires: vtk(abi) = %{?vtk_abi}%{!?vtk_abi:UNSET} # Pin the exact DCMTK snapshot this package was built against. dcmtk is packaged from git # HEAD and upstream's DCMTK_ABI_VERSION stays 20 across snapshots, so every snapshot installs # libdcm*.so.20 and rpm cannot tell them apart: a consumer built against one installs cleanly # against another and fails at load with undefined symbols (dcmqi on f45, with OverlapUtil). # %%dcmtk_abi comes from dcmtk-devel's macros.dcmtk, so it re-pins on every rebuild. The # missing-macro check is in %%build, not at parse time, for the reason spelled out at the vtk # pin in 3dslicer.spec: an SRPM parse has no buildroot. Requires: dcmtk(abi) = %{?dcmtk_abi}%{!?dcmtk_abi:UNSET} # itk(abi): ITK_LEGACY_REMOVE changes class layouts at unchanged sonames, so the itk_ver floor alone let a # consumer built against the removed state install over the present one (python3-simpleitk -11 on ITK -23 # returned all-zero images). Equality on the legacy-state token; see InsightToolkit5.spec. Requires: itk(abi) = %{?itk_abi}%{!?itk_abi:UNSET} %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 # Restore Qt plugin registration on 16 modules. Every qSlicer*Module.h here # declares its loadable-module IID as # # #ifdef Slicer_HAVE_QT5 # Q_PLUGIN_METADATA(IID "org.slicer.modules.loadable.qSlicerLoadableModule/1.0"); # #endif # # and our Slicer is Qt6: vtkSlicerConfigure.h ships "/* #undef Slicer_HAVE_QT5 */". # So the macro compiles out, moc emits no plugin registration, and the module # builds, links, installs and ships with no qt_plugin_instance symbol -- i.e. it # is not loadable as a Qt plugin at all. Nothing fails; the modules are simply # absent from Slicer at runtime. Measured on -0.17: 15 of 16 module plugins had # no entry symbol. The one that worked, DrrImageComputation, is the one module # written after the Qt5 era and so carries no guard. # # Removing the guard rather than defining Slicer_HAVE_QT5: that macro means # "Slicer is built against Qt5", which is false here, and other code reads it. # The headers are CRLF, hence the \r? in the pattern. find . -name 'qSlicer*Module.h' -exec sed -i \ -e '/^#ifdef Slicer_HAVE_QT5\r\?$/{N;N;s/^#ifdef Slicer_HAVE_QT5\r\?\n\(.*Q_PLUGIN_METADATA.*\)\n#endif\r\?$/\1/}' {} + %build # Pin the ITK layout state this build sees (see the Requires above). test -n "%{?itk_abi}" || { echo "ERROR: itk_abi undefined - needs InsightToolkit5-devel >= 5.4.7-24 (macros.itk)" >&2; exit 1; } # dcmtk_abi comes from dcmtk-devel's macros.dcmtk. Absent means the buildroot has a dcmtk-devel # that predates the snapshot, and the Requires above would carry the UNSET placeholder. test -n "%{?dcmtk_abi}" || { echo "ERROR: dcmtk_abi undefined - needs the dcmtk-devel that ships macros.dcmtk" >&2; exit 1; } # vtk_abi comes from vtk-devel's macros.vtk. Absent means BuildRequires: vtk-devel is # missing, and the Requires above would ship as the vacuous "vtk(abi) = UNSET". test -n "%{?vtk_abi}" || { echo "ERROR: vtk_abi undefined - add 'BuildRequires: vtk-devel'" >&2; exit 1; } %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 # SlicerRT installs its three plastimatch CLI modules (PlmDrr, PlmBspline, PlmLandwarp) into # /bin, but Slicer scans only lib//cli-modules, so they were never loaded: Slicer # logged "DrrImageComputation: dependency plastimatch_slicer_drr failed to be loaded" and the module # was missing. The binaries ran fine with the launcher's library path and --xml worked; they were # simply never found. Found by framework (module count 165 -> 168 when moved). The proper fix is the # install destination in SlicerRT's CMake; until that is located this moves them, and fails the build # if one is absent so an upstream layout change cannot silently put them back in the wrong place. clidir=%{buildroot}%{slicer_inst}/lib/%{slicer_subdir}/cli-modules install -d "$clidir" for m in plastimatch_slicer_drr plastimatch_slicer_bspline plastimatch_slicer_landwarp; do for f in "$m" "$m.xml"; do test -e "%{buildroot}%{slicer_inst}/bin/$f" \ || { echo "ERROR: $f is not in bin/ - SlicerRT's CLI install layout changed" >&2; exit 1; } mv "%{buildroot}%{slicer_inst}/bin/$f" "$clidir/$f" done done test -z "$(ls %{buildroot}%{slicer_inst}/bin 2>/dev/null | grep plastimatch_slicer)" \ || { echo "ERROR: plastimatch_slicer files left in bin/" >&2; exit 1; } # Generate the file list rather than glob by name. The previous %files used # qt-loadable-modules/*RT* and cli-modules/*DICOM*RT*: the first matches nothing # (the libraries are named ...DicomRt..., not ...RT...), the second matches # nothing because no cli-modules are installed at all, and between them the # hand-written globs missed about 60 of the 169 installed files. Slicer owns # every parent directory, so only files and symlinks are listed here. # Fail the build if any loadable module plugin lost its Qt entry symbol. The # %%prep sed above is the fix; this is what stops it regressing silently, which # is the whole character of this bug -- it produced a green build and a green # install and simply no modules. Widgets and SubjectHierarchy plugin libraries # are not Qt plugins themselves and are excluded. bad=0; checked=0 for so in $(find %{buildroot} -path '*qt-loadable-modules*' -name 'libqSlicer*Module.so'); do case "$so" in *ModuleWidgets.so|*Plugins.so) continue;; esac checked=$((checked+1)) nm -D --defined-only "$so" 2>/dev/null | grep -q qt_plugin_instance || { echo "ERROR: $(basename $so) exports no qt_plugin_instance - Qt plugin registration lost" >&2 bad=$((bad+1)); } done [ "$checked" -gt 0 ] || { echo "ERROR: found no loadable module plugins to check" >&2; exit 1; } [ "$bad" -eq 0 ] || { echo "ERROR: $bad of $checked module plugins are not loadable" >&2; exit 1; } echo "OK: all $checked loadable module plugins export qt_plugin_instance" ( cd %{buildroot} && find . \( -type f -o -type l \) | sed 's|^\.||' ) \ > %{_builddir}/slicerrt.files %files -f %{_builddir}/slicerrt.files %license LICENSE.txt %doc README.md %changelog * Tue Oct 06 2026 Morgan Hough - 0-0.25.20260821gitf57ccf38 - Pin the ITK layout state: Requires: itk(abi) = %%{itk_abi}, from InsightToolkit5-devel's macros.itk, plus a %%build guard. ITK -23 flipped ITK_LEGACY_REMOVE back off, which changes class layouts at unchanged sonames; this package was built against -10..-21 (legacy removed) and the itk_ver floor let it install over -23, giving silent wrong results or crashes. Rebuild against ITK >= 5.4.7-24. * Mon Oct 05 2026 Morgan Hough - 0-0.24.20260821gitf57ccf38 - Install plastimatch_slicer_{drr,bspline,landwarp} and their .xml into lib/Slicer-5.12/cli-modules instead of bin/. Slicer scans only cli-modules, so the three CLI modules were never loaded and Slicer logged "DrrImageComputation: dependency plastimatch_slicer_drr failed to be loaded". Root cause found by framework: the binaries ran and --xml worked, they were just never found; moving them took the module count 165 -> 168 and cleared the warning. This package had no cli-modules entries at all before. The build now fails if any of the six files is missing from bin/ or one is left behind. * Mon Oct 05 2026 Morgan Hough - 0-0.23.20260821gitf57ccf38 - Requires: python3-simpleitk (six shipped .py files import it) and 3dslicer-landmarkregistration (new package: PlmRegister.py imports RegistrationLib from it). Both were runtime failures at module load, "No module named 'SimpleITK'" and "No module named 'RegistrationLib'", found by framework in an offscreen launch of the served f44 set. python3-simpleitk was verified to clear the first; the second is fixed by the new package, which has not yet been tried inside a Slicer launch. * Mon Oct 05 2026 Morgan Hough - 0-0.22.20260821gitf57ccf38 - Pin the exact DCMTK snapshot: Requires: dcmtk(abi) = %%{dcmtk_abi}, from dcmtk-devel's macros.dcmtk, plus a %%build guard against the UNSET placeholder. dcmtk is now packaged from git HEAD (policy in dcmtk.spec) and upstream's DCMTK_ABI_VERSION stays 20 across snapshots, so rpm cannot tell snapshots apart by soname; this is the same mechanism as vtk(abi). - This release exists to be rebuilt against the snapshot; the pin means it cannot be installed against a different one. - Patch9: use itk::IOPixelEnum/IOComponentEnum in PlmDrr/plastimatch_slicer_drr.cxx. Found by the rawhide rebuild (15 compile errors); ITK_LEGACY_REMOVE casualty, would have failed everywhere at this rebuild. Whole SlicerRT tree swept: one file, 13 lines. * Fri Sep 25 2026 Morgan Hough - 0-0.21. - Rebuild for fedora-45-x86_64 against ITK 5.4.7-9. The published build there still references sonames ITK no longer ships, which pins ITK to 5.4.7-2 and blocks the whole Slicer stack on that chroot. Release bumped because COPR adds a sibling at an existing NVR and dnf then serves the oldest. * Sat Sep 19 2026 Morgan Hough - 0-0.20.20260821gitf57ccf38 - Regenerate slicerrt-itk-eigen-portable.patch against the tree with the eight earlier patches already applied. -0.19 failed in %%prep: the hunk for qSlicerAbstractConstraint.h was cut against the pristine tarball, but slicerrt-metatype-dosetype-order.patch inserts a comment block immediately after the include it uses as trailing context, so by the time this patch is applied ninth the context no longer matches. One hunk of six, rejected. - A patch has to be cut against the tree as it will be when rpm applies it, not against the upstream tarball, whenever it lands in a series that touches the same neighbourhood. Diagnosed by the t2 session, which reproduced the series locally rather than reading the reject file. * Fri Sep 18 2026 Morgan Hough - 0-0.19.20260821gitf57ccf38 - Add slicerrt-itk-eigen-portable.patch: replace six includes across five files with ITK's portable ITK_EIGEN() form. The bundled path does not exist against InsightToolkit5 5.4.7-8, which is built with ITK_USE_SYSTEM_EIGEN=ON. Found by the t2 session in the ITK consumer test rebuild (11002496); same class as the mitk -36 fix. - itk_eigen.h resolves ITK_EIGEN(x) to or as appropriate, so the patch is correct against bundled and system Eigen alike and is offered upstream rather than carried as a downstream workaround. * Tue Sep 15 2026 Morgan Hough - 0-0.18.20260821gitf57ccf38 - Restore Qt plugin registration on 15 of the 16 loadable modules, which have been shipping unloadable. Every qSlicer*Module.h here wraps its Q_PLUGIN_METADATA in "#ifdef Slicer_HAVE_QT5". Our Slicer is Qt6 and its vtkSlicerConfigure.h ships "/* #undef Slicer_HAVE_QT5 */", so the macro compiled out, moc emitted no plugin registration, and each module built, linked, installed and shipped with no qt_plugin_instance symbol -- present on disk, absent from Slicer, nothing reporting a problem anywhere. - The one module that worked, DrrImageComputation, is the only one written after the Qt5 era and so the only one with no guard. That is what identified the cause: all 17 headers declare the IID, 16 guard it, 15 of those ship broken (PinnacleDvfReader is not built). - Remove the guard rather than define Slicer_HAVE_QT5: that macro asserts the build is against Qt5, which is false, and other code reads it. - %%install now fails the build if any shipped module plugin lacks the entry symbol, and fails if it finds no modules to check at all. Verified as a detector against the -0.17 payload (15 of 16 flagged), against 3dslicer-igt (12 of 12 pass) and against an empty tree. - Swept every extension: only this package and 3dslicer-jupyter are affected. Core 3dslicer is 23 of 23 clean. * Tue Sep 08 2026 Morgan Hough - 0-0.16.20260821gitf57ccf38 - Add slicerrt-subjecthierarchy-link.patch. An ldd -r sweep of the installed stack found libvtkSlicerDoseComparisonModuleLogic.so with an undefined vtkSlicerSubjectHierarchyModuleLogic::AreNodesInSameBranch: the module calls the API without linking the library. ExternalBeamPlanning has the same defect but currently resolves transitively. * Thu Sep 03 2026 Morgan Hough - 0-0.15.20260821gitf57ccf38 - Everything now compiles (543/543); fix %%files, which never matched reality: * %%license took a shell fragment, so rpm looked for files named null, || and true. The file is LICENSE.txt, not License.txt. * qt-loadable-modules/*RT* matched nothing -- the libraries are named ...DicomRt..., not ...RT.... * cli-modules/*DICOM*RT* matched nothing -- no cli-modules are installed. Between them the globs missed about 60 of the 169 installed files, so use a generated file list as 3dslicer-igt does. * Thu Sep 03 2026 Morgan Hough - 0-0.14.20260821gitf57ccf38 - Add slicerrt-designer-plugins-guard.patch: Beams/Widgets built its Qt Designer plugin unconditionally, and the target's output directory derives from Slicer_BINARY_DIR, which is the install prefix here. ninja then failed with mkdir(/usr/lib/slicer/lib/Slicer-5.12/bin): Permission denied. * 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).