Name: acvd Version: 4.0 Release: 4%{?dist} Summary: Fast simplification and remeshing of 3D surface meshes (VTK-based) # CeCILL-B is a permissive BSD-like French free-software license (Fedora-allowed). License: CECILL-B URL: https://github.com/valette/ACVD Source0: %{url}/archive/refs/tags/v%{version}/ACVD-%{version}.tar.gz BuildRequires: cmake BuildRequires: ninja-build BuildRequires: gcc-c++ BuildRequires: chrpath BuildRequires: vtk-devel # IOMINC component requested by ACVD's find_package(VTK) BuildRequires: libminc-devel # OpenMP (optional acceleration in the remeshing examples; harmless for the libs) BuildRequires: libomp-devel # VTK cmake config resolves all module deps at find_package time BuildRequires: hdf5-devel json-devel jsoncpp-devel utf8cpp-devel fmt-devel BuildRequires: freetype-devel pugixml-devel PEGTL-devel libglvnd-devel BuildRequires: libtheora-devel libogg-devel libjpeg-turbo-devel libpng-devel BuildRequires: libtiff-devel fontconfig-devel expat-devel lz4-devel xz-devel BuildRequires: zlib-devel sqlite-devel libxml2-devel netcdf-devel proj-devel BuildRequires: tbb-devel libharu-devel gl2ps-devel double-conversion-devel BuildRequires: gdal-devel libpq-devel libX11-devel libXt-devel libGL-devel BuildRequires: cli11-devel boost-devel %description ACVD provides fast, high-quality simplification and isotropic/anisotropic remeshing of 3D triangular surface meshes, based on Approximated Centroidal Voronoi Diagrams (Valette et al.). It is built on top of VTK and provides the vtkSurface and vtkVolumeProcessing shared libraries plus a header-only discrete remeshing module, used by statistical-shape-modeling pipelines (e.g. ShapeWorks) for surface correspondence preprocessing. %package devel Summary: Development files for %{name} Requires: %{name}%{?_isa} = %{version}-%{release} Requires: vtk-devel %description devel Headers and CMake package configuration for developing against %{name} (ACVD: vtkSurface, vtkDiscreteRemeshing, vtkVolumeProcessing). %prep %autosetup -n ACVD-%{version} %build # ACVD's sources use unqualified cout/cin/cerr/endl with neither nor # `using namespace std` — they relied on transitive availability that newer VTK # headers / GCC 15 no longer provide. Force-include a small prelude that supplies # both, restoring the environment the code was written for. cat > _acvd_prelude.h <<'EOF' #include using namespace std; EOF export CXXFLAGS="%{optflags} -include $PWD/_acvd_prelude.h" # Library-only build: the bundled Examples produce many generically-named CLI # binaries (viewer, icp, sampleMesh, ...) that would collide in %{_bindir}; # downstreams (ShapeWorks) need only the libraries + headers + cmake config. # ACVD uses its own INSTALL_*_DIR vars (not CMAKE_INSTALL_LIBDIR), so set lib64. %cmake -GNinja \ -DBUILD_SHARED_LIBS:BOOL=ON \ -DBUILD_EXAMPLES:BOOL=OFF \ -DBUILD_DOCUMENTATION:BOOL=OFF \ -DINSTALL_LIB_DIR:PATH=%{_lib} \ -DINSTALL_INCLUDE_DIR:PATH=include \ -DINSTALL_CMAKE_DIR:PATH=%{_lib}/cmake/ACVD %cmake_build %install %cmake_install # Drop any build-tree RPATHs. find %{buildroot} -type f \( -name '*.so' -o -name '*.so.*' \) \ -exec chrpath --delete {} \; 2>/dev/null || : # ACVD's CMakeLists writes ONE ACVDConfig.cmake for both the build tree and the # install tree, so the installed copy hardcodes the absolute SOURCE paths of the # machine that built it: # set( ACVD_INCLUDE_DIRS "/builddir/build/BUILD/acvd-4.0-build/ACVD-4.0/Common; # ...;/DiscreteRemeshing;.../VolumeProcessing" ) # and then include_directories() on them. Those directories exist nowhere but the # builder, so every consumer of find_package(ACVD) silently gets include paths # pointing at nothing -- MITK's Modules/Remeshing failed with # "vtkIsotropicDiscreteRemeshing.h: No such file or directory" even though # acvd-devel ships that header (mitk 2026.06-12, object 3279 of 4406). # Point them at the installed layout instead. Kept as three entries because MITK # and ShapeWorks include these headers flat (), # not as . sed -i -E 's|^set\( *ACVD_INCLUDE_DIRS .*\)$|set( ACVD_INCLUDE_DIRS "%{_includedir}/ACVD/Common;%{_includedir}/ACVD/DiscreteRemeshing;%{_includedir}/ACVD/VolumeProcessing" )|' \ %{buildroot}%{_libdir}/cmake/ACVD/ACVDConfig.cmake grep -q '%{_includedir}/ACVD/DiscreteRemeshing' \ %{buildroot}%{_libdir}/cmake/ACVD/ACVDConfig.cmake \ || { echo "ERROR: ACVD_INCLUDE_DIRS rewrite did not apply"; exit 1; } ! grep -q '/builddir/' %{buildroot}%{_libdir}/cmake/ACVD/ACVDConfig.cmake \ || { echo "ERROR: build-tree paths still present in ACVDConfig.cmake"; exit 1; } # The INSTALLED headers have the same unqualified-cout/endl problem the %%build # prelude works around for ACVD's own compilation -- but that prelude is a build # flag, so it never reaches consumers. 8 headers, 149 sites, none of which # include . Any downstream that INSTANTIATES the templates (a plain # #include is not enough; the bodies only get diagnosed on instantiation) fails # with "'cout' was not declared in this scope [-Wtemplate-body]" -- MITK's # Modules/Remeshing hit exactly this, 35 errors, once the include path above was # fixed and the headers were finally reachable. # Qualify with std:: rather than injecting "using namespace std" into public # headers, which would leak into every consumer's translation units. The perl # lookbehinds skip already-qualified names and member accesses (x.cout, p->cout). _acvd_hdrs=$(grep -rlE '(^|[^:[:alnum:]_>.])(cout|cerr|cin|endl)[^[:alnum:]_]' \ %{buildroot}%{_includedir}/ACVD/ || :) for _h in $_acvd_hdrs; do perl -pi -e 's/(?])\b(cout|cerr|cin|endl)\b/std::$1/g' "$_h" grep -q '#include ' "$_h" \ || perl -0pi -e 's/^(#include)/#include \n$1/m' "$_h" done # Guards: the rewrite must have run, and must not have double-qualified anything. grep -q 'std::cout' %{buildroot}%{_includedir}/ACVD/Common/vtkUniformClustering.h \ || { echo "ERROR: ACVD header std:: qualification did not apply"; exit 1; } ! grep -rq 'std::std::' %{buildroot}%{_includedir}/ACVD/ \ || { echo "ERROR: double-qualified std::std:: in ACVD headers"; exit 1; } %files %license LICENSE.txt %doc Readme.md %{_libdir}/libvtkSurface.so.4.0* %{_libdir}/libvtkVolumeProcessing.so.4.0* %files devel %{_includedir}/ACVD/ %{_libdir}/libvtkSurface.so %{_libdir}/libvtkVolumeProcessing.so %{_libdir}/cmake/ACVD/ %changelog * Sun Aug 23 2026 Morgan Hough - 4.0-4 - 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. * Mon Aug 03 2026 Morgan Hough - 4.0-3 - Qualify cout/cerr/cin/endl with std:: in the INSTALLED headers and add the missing . %%build already force-includes a prelude supplying both, but that is a compiler flag for ACVD's own sources -- the headers ship unchanged, so every consumer inherits the problem. 8 headers, 149 sites, none including . A plain #include is not enough to trigger it: the template bodies are only diagnosed on instantiation, which is why this stayed hidden until MITK's Modules/Remeshing instantiated them and produced 35 "'cout' was not declared in this scope [-Wtemplate-body]" errors -- and only after 4.0-2 fixed the include path so the headers were reachable at all. std:: qualification rather than "using namespace std" in a public header, which would leak into every consumer. Verified inside the preserved mock chroot with MITK's own compile command: 35 errors -> COMPILE_OK. Should go upstream with the 4.0-2 config fix. * Mon Aug 03 2026 Morgan Hough - 4.0-2 - Rewrite ACVD_INCLUDE_DIRS in the installed ACVDConfig.cmake. ACVD generates a single config file for both its build tree and its install tree, so the shipped copy hardcoded the absolute source paths of the build machine (/builddir/build/BUILD/acvd-4.0-build/ACVD-4.0/{Common,DiscreteRemeshing, VolumeProcessing}) and then called include_directories() on them. Those exist nowhere but the builder, so every consumer of find_package(ACVD) got include directories pointing at nothing while the headers themselves were installed correctly under %%{_includedir}/ACVD/. MITK's Modules/Remeshing failed with "vtkIsotropicDiscreteRemeshing.h: No such file or directory" (mitk 2026.06-12, object 3279 of 4406) despite acvd-devel shipping that exact header. Two guards: the rewrite must apply, and no /builddir/ path may survive. Worth sending upstream -- the same config is wrong for every packager. * Wed Jun 18 2026 Morgan Hough - 4.0-1 - Initial package (stock upstream valette/ACVD v4.0). Library-only build (BUILD_EXAMPLES=OFF) against system VTK; provides vtkSurface / vtkVolumeProcessing / vtkDiscreteRemeshing for the ShapeWorks dependency chain.