# pymeshfix -- Python bindings (nanobind) for Marco Attene's MeshFix 2.1, which # repairs triangular surface meshes: fills holes, removes self-intersections # and degenerate faces, keeps the largest component. New to Fedora. # babelbrain's Step 1 (BabelDatasetPreps) runs pymeshfix.clean_from_file on # the skin and skull STLs it extracts from the SimNIBS head model, and the # import is unconditional. # # MeshFix is compiled in from src/ (it has no shared-library release; our # `meshfix` package builds the command-line tool from the same code). # Licence: every MeshFix source file is "dual-licensed": GPL v3 or later, or # a commercial licence from IMATI-GE / CNR. The Python layer is GPL-3.0 as # well (LICENSE). The pyproject classifier says AGPL; the LICENSE file and # every header say GPL, and the LICENSE file is what we ship. # scikit-build-core builds the extension via CMake and the debug sources are # not tracked into debugsourcefiles.list (empty -> FTBFS), as with # python-babelviscofdtd; disable the debug package. %global debug_package %{nil} %global pypi_name pymeshfix %global meshfix_version 2.1 Name: python-%{pypi_name} Version: 0.18.1 Release: 1%{?dist} Summary: Repair triangular surface meshes using MeshFix License: GPL-3.0-or-later URL: https://github.com/pyvista/pymeshfix Source0: %{pypi_source %{pypi_name}} # MeshFix passes already-formatted strings as printf formats; Fedora builds with # -Werror=format-security. Use fputs. (Same text, no format expansion.) Patch0: pymeshfix-format-security.patch BuildRequires: python3-devel BuildRequires: cmake BuildRequires: ninja-build BuildRequires: gcc-c++ # The build backend's own requirements (scikit-build-core, nanobind) come from # %%pyproject_buildrequires; nanobind's CMake config lives in the Python # package, which scikit-build-core finds through its cmake.prefix entry point. %global _description %{expand: pymeshfix wraps MeshFix, which takes a raw digitised polygon mesh and produces a clean mesh where all the occurrences of a specific set of "defects" are corrected: it fills holes, removes self-intersections and degenerate faces, and keeps the largest connected component. The result is a single manifold, watertight surface suitable for voxelisation and simulation. Works from NumPy arrays or STL/PLY files.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} Provides: bundled(meshfix) = %{meshfix_version} %description -n python3-%{pypi_name} %_description %prep %autosetup -p1 -n %{pypi_name}-%{version} # A stray CMakeCache.txt from the maintainer's checkout is in the sdist. rm -f CMakeCache.txt # Upstream caps requires-python at <3.15 because it had no 3.15 wheels yet; # the stable-ABI extension builds and imports on 3.15 (rawhide). sed -i 's/^requires-python = ">=3.10,<3.15"/requires-python = ">=3.10"/' pyproject.toml grep -q '^requires-python = ">=3.10"$' pyproject.toml %generate_buildrequires %pyproject_buildrequires -p %build %pyproject_wheel %install %pyproject_install # No PEP 639 License-File in the metadata; LICENSE is listed by hand. %pyproject_save_files -L %{pypi_name} %check # pymeshfix.examples downloads/loads sample meshes through pyvista (optional). %pyproject_check_import -e '%{pypi_name}.examples*' cd / # A unit cube with one face missing: MeshFix must close the hole, giving a # watertight mesh with 12 triangles and a consistent Euler characteristic. PYTHONPATH=%{buildroot}%{python3_sitearch} %{python3} -c ' import numpy as np, pymeshfix v = np.array([[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,1],[1,0,1],[1,1,1],[0,1,1]], float) f = np.array([[0,2,1],[0,3,2],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6]]) # -x face missing m = pymeshfix.MeshFix(v, f) m.repair() nv, nf = len(m.points), len(m.faces) assert nf == 12 and nv == 8, (nv, nf) # V - E + F = 2 for a closed genus-0 surface, with E = 3F/2 for a triangle mesh. assert nv - 3 * nf // 2 + nf == 2, (nv, nf) print("repaired cube:", nv, "vertices", nf, "faces")' %files -n python3-%{pypi_name} -f %{pyproject_files} %license LICENSE %doc README.rst %changelog * Sun Oct 11 2026 Morgan Hough - 0.18.1-1 - Initial package, for babelbrain Step 1 (skin/skull STL repair). - requires-python cap lifted for Python 3.15; stray CMakeCache.txt removed. - Patch0: fputs instead of printf(fms) in tmesh.cpp (-Werror=format-security).