# 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.22.%{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 # 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} %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 # 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 # 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 * 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).