From bf802eef35a41896fc4681e16f8debd523dc9f0b Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt Date: Tue, 5 May 2026 01:23:04 +0200 Subject: [PATCH 1/2] python3Packages.opensfm: unstable-2023-12-09 -> 0.5.1-unstable-2026-05-04 Changelog: https://github.com/mapillary/OpenSfM/blob/1dc5b95b5c8c4cadd653bdc9f6eb97c0ac1602ba/CHANGELOG.md --- .../0001-cmake-use-system-pybind11.patch | 20 ++ ...-cmake-find-system-distributed-gtest.patch | 51 ++-- .../0003-cmake-use-system-pybind11.patch | 161 ------------ ...x-scripts.patch => 0003-fix-scripts.patch} | 23 +- ...tils.h-conflicts-with-nixpkgs-pybind.patch | 86 ------- .../0005-fix-numpy-2-test-failures.patch | 239 ------------------ .../python-modules/opensfm/default.nix | 80 +++--- 7 files changed, 88 insertions(+), 572 deletions(-) create mode 100644 pkgs/development/python-modules/opensfm/0001-cmake-use-system-pybind11.patch delete mode 100644 pkgs/development/python-modules/opensfm/0003-cmake-use-system-pybind11.patch rename pkgs/development/python-modules/opensfm/{fix-scripts.patch => 0003-fix-scripts.patch} (54%) delete mode 100644 pkgs/development/python-modules/opensfm/0004-pybind_utils.h-conflicts-with-nixpkgs-pybind.patch delete mode 100644 pkgs/development/python-modules/opensfm/0005-fix-numpy-2-test-failures.patch diff --git a/pkgs/development/python-modules/opensfm/0001-cmake-use-system-pybind11.patch b/pkgs/development/python-modules/opensfm/0001-cmake-use-system-pybind11.patch new file mode 100644 index 000000000000..4d65c8407862 --- /dev/null +++ b/pkgs/development/python-modules/opensfm/0001-cmake-use-system-pybind11.patch @@ -0,0 +1,20 @@ +diff --git a/opensfm/src/CMakeLists.txt b/opensfm/src/CMakeLists.txt +index 88a7dd8..f755e8e 100644 +--- a/opensfm/src/CMakeLists.txt ++++ b/opensfm/src/CMakeLists.txt +@@ -58,6 +58,7 @@ if (OPENMP_FOUND) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() + ++find_package(pybind11 REQUIRED) + find_package(LAPACK) + find_package(SuiteSparse) + find_package(Eigen3 REQUIRED) +@@ -109,7 +110,6 @@ if(TARGET opencv_imgcodecs) + endif() + + ####### Third party libraries ####### +-add_subdirectory(third_party/pybind11) + add_subdirectory(third_party/akaze) + add_subdirectory(third_party/vlfeat) + diff --git a/pkgs/development/python-modules/opensfm/0002-cmake-find-system-distributed-gtest.patch b/pkgs/development/python-modules/opensfm/0002-cmake-find-system-distributed-gtest.patch index 27b87c0b2d09..1d3db15e8f83 100644 --- a/pkgs/development/python-modules/opensfm/0002-cmake-find-system-distributed-gtest.patch +++ b/pkgs/development/python-modules/opensfm/0002-cmake-find-system-distributed-gtest.patch @@ -1,57 +1,42 @@ -From 79577371be21df40f1f6d4a4fe3453be6df9e93c Mon Sep 17 00:00:00 2001 -From: Someone Serge -Date: Fri, 31 Dec 2021 10:03:25 +0200 -Subject: [PATCH 2/4] cmake: find system-distributed gtest - ---- - opensfm/src/CMakeLists.txt | 19 +++++++------------ - 1 file changed, 7 insertions(+), 12 deletions(-) - diff --git a/opensfm/src/CMakeLists.txt b/opensfm/src/CMakeLists.txt -index c85aa6fb..640d47a6 100644 +index f755e8e..3dd6cd2 100644 --- a/opensfm/src/CMakeLists.txt +++ b/opensfm/src/CMakeLists.txt -@@ -52,12 +52,14 @@ if (OPENMP_FOUND) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() - -+find_package(gflags REQUIRED) -+ - find_package(LAPACK) - find_package(SuiteSparse) +@@ -64,6 +64,7 @@ find_package(SuiteSparse) find_package(Eigen3 REQUIRED) find_package(Ceres) --find_package(Gflags REQUIRED) --find_package(Glog REQUIRED) -+find_package(glog REQUIRED) + find_package(Gflags REQUIRED) +find_package(GTest REQUIRED) - # Ceres2 exposes Ceres::ceres target. - # Ceres1 exposes just ceres. -@@ -100,20 +102,13 @@ option(OPENSFM_BUILD_TESTS "Build OpenSfM unit tests." on) + # Try to find glog using its native CMake config first (modern systems) + # Fall back to custom FindGlog.cmake for older systems (e.g., Ubuntu 20.04) +@@ -129,8 +130,6 @@ option(OPENSFM_BUILD_TESTS "Build OpenSfM unit tests." on) if (OPENSFM_BUILD_TESTS) enable_testing() - include_directories(third_party/gtest) - add_definitions(-DCERES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE}) -- + + # Gtest if old now and trigger these + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers") +@@ -138,18 +137,12 @@ if (OPENSFM_BUILD_TESTS) + "${CMAKE_CXX_FLAGS} -Wno-deprecated-copy-with-user-provided-copy" + ) + - add_library(gtest - third_party/gtest/gmock_gtest_all.cc - third_party/gtest/gmock_main.cc) - target_include_directories(gtest PRIVATE ${GFLAGS_INCLUDE_DIR}) - +- target_link_libraries(gtest PRIVATE glog::glog) +- set(TEST_MAIN test_main) add_library(${TEST_MAIN} testing_main.cc) target_link_libraries(${TEST_MAIN} - ${GFLAGS_LIBRARY} -- ${GLOG_LIBRARY} ++ gflags + glog::glog - gtest) -+ gflags -+ glog::glog -+ GTest::gtest) ++ GTest::gtest) endif() ####### OpenSfM libraries ####### --- -2.33.1 - diff --git a/pkgs/development/python-modules/opensfm/0003-cmake-use-system-pybind11.patch b/pkgs/development/python-modules/opensfm/0003-cmake-use-system-pybind11.patch deleted file mode 100644 index 2815886e7e18..000000000000 --- a/pkgs/development/python-modules/opensfm/0003-cmake-use-system-pybind11.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 36820fbab1abeeebd99f14e368093e0e3f934ca7 Mon Sep 17 00:00:00 2001 -From: Someone Serge -Date: Sat, 19 Feb 2022 02:37:54 +0200 -Subject: [PATCH 3/4] cmake: use system pybind11 - ---- - opensfm/src/CMakeLists.txt | 3 ++- - opensfm/src/bundle/CMakeLists.txt | 2 +- - opensfm/src/dense/CMakeLists.txt | 2 +- - opensfm/src/features/CMakeLists.txt | 1 - - opensfm/src/foundation/CMakeLists.txt | 1 - - opensfm/src/geo/CMakeLists.txt | 1 - - opensfm/src/geometry/CMakeLists.txt | 1 - - opensfm/src/map/CMakeLists.txt | 3 +-- - opensfm/src/robust/CMakeLists.txt | 1 - - opensfm/src/sfm/CMakeLists.txt | 1 - - 10 files changed, 5 insertions(+), 11 deletions(-) - -diff --git a/opensfm/src/CMakeLists.txt b/opensfm/src/CMakeLists.txt -index 640d47a6..6e391ffa 100644 ---- a/opensfm/src/CMakeLists.txt -+++ b/opensfm/src/CMakeLists.txt -@@ -54,6 +54,8 @@ endif() - - find_package(gflags REQUIRED) - -+find_package(pybind11 REQUIRED) -+ - find_package(LAPACK) - find_package(SuiteSparse) - find_package(Eigen3 REQUIRED) -@@ -82,7 +84,6 @@ else() - endif() - - ####### Third party libraries ####### --add_subdirectory(third_party/pybind11) - add_subdirectory(third_party/akaze) - add_subdirectory(third_party/vlfeat) - -diff --git a/opensfm/src/bundle/CMakeLists.txt b/opensfm/src/bundle/CMakeLists.txt -index 7cd9cf74..307e963a 100644 ---- a/opensfm/src/bundle/CMakeLists.txt -+++ b/opensfm/src/bundle/CMakeLists.txt -@@ -52,7 +52,7 @@ target_link_libraries(pybundle PRIVATE - bundle - geometry - foundation -- pybind11) -+) - set_target_properties(pybundle PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${opensfm_SOURCE_DIR}/.." - ) -diff --git a/opensfm/src/dense/CMakeLists.txt b/opensfm/src/dense/CMakeLists.txt -index cbebb5ea..2728749d 100644 ---- a/opensfm/src/dense/CMakeLists.txt -+++ b/opensfm/src/dense/CMakeLists.txt -@@ -23,7 +23,7 @@ endif() - - pybind11_add_module(pydense python/pybind.cc) - target_include_directories(pydense PRIVATE ${GLOG_INCLUDE_DIR}) --target_link_libraries(pydense PRIVATE dense foundation pybind11) -+target_link_libraries(pydense PRIVATE dense foundation) - set_target_properties(pydense PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${opensfm_SOURCE_DIR}/.." - ) -diff --git a/opensfm/src/features/CMakeLists.txt b/opensfm/src/features/CMakeLists.txt -index b131d30a..6db5b3f1 100644 ---- a/opensfm/src/features/CMakeLists.txt -+++ b/opensfm/src/features/CMakeLists.txt -@@ -22,7 +22,6 @@ target_link_libraries(pyfeatures - PRIVATE - features - foundation -- pybind11 - akaze - ) - set_target_properties(pyfeatures PROPERTIES -diff --git a/opensfm/src/foundation/CMakeLists.txt b/opensfm/src/foundation/CMakeLists.txt -index 40185227..9e0e45e7 100644 ---- a/opensfm/src/foundation/CMakeLists.txt -+++ b/opensfm/src/foundation/CMakeLists.txt -@@ -12,7 +12,6 @@ set(FOUNDATION_FILES - add_library(foundation ${FOUNDATION_FILES}) - target_link_libraries(foundation - PUBLIC -- pybind11 - ${OpenCV_LIBS} - ${OpenMP_libomp_LIBRARY} - Eigen3::Eigen -diff --git a/opensfm/src/geo/CMakeLists.txt b/opensfm/src/geo/CMakeLists.txt -index a9cbae02..75620d06 100644 ---- a/opensfm/src/geo/CMakeLists.txt -+++ b/opensfm/src/geo/CMakeLists.txt -@@ -29,7 +29,6 @@ target_link_libraries(pygeo - PRIVATE - geo - foundation -- pybind11 - ) - set_target_properties(pygeo PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${opensfm_SOURCE_DIR}/.." -diff --git a/opensfm/src/geometry/CMakeLists.txt b/opensfm/src/geometry/CMakeLists.txt -index e6dda2c2..51bfd6c5 100644 ---- a/opensfm/src/geometry/CMakeLists.txt -+++ b/opensfm/src/geometry/CMakeLists.txt -@@ -48,7 +48,6 @@ target_link_libraries(pygeometry - PRIVATE - geometry - foundation -- pybind11 - ) - set_target_properties(pygeometry PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${opensfm_SOURCE_DIR}/.." -diff --git a/opensfm/src/map/CMakeLists.txt b/opensfm/src/map/CMakeLists.txt -index b6f67bcd..f869aa4c 100644 ---- a/opensfm/src/map/CMakeLists.txt -+++ b/opensfm/src/map/CMakeLists.txt -@@ -20,7 +20,7 @@ set(MAP_FILES - add_library(map ${MAP_FILES}) - target_link_libraries(map - PUBLIC -- pybind11 -+ pybind11::module - Eigen3::Eigen - PRIVATE - geo -@@ -39,7 +39,6 @@ target_link_libraries(pymap - map - geometry - bundle -- pybind11 - ) - - if (OPENSFM_BUILD_TESTS) -diff --git a/opensfm/src/robust/CMakeLists.txt b/opensfm/src/robust/CMakeLists.txt -index ce70749f..40bdf7a4 100644 ---- a/opensfm/src/robust/CMakeLists.txt -+++ b/opensfm/src/robust/CMakeLists.txt -@@ -29,7 +29,6 @@ target_link_libraries(pyrobust - PRIVATE - robust - foundation -- pybind11 - ) - set_target_properties(pyrobust PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${opensfm_SOURCE_DIR}/.." -diff --git a/opensfm/src/sfm/CMakeLists.txt b/opensfm/src/sfm/CMakeLists.txt -index 98c28f41..7f56b791 100644 ---- a/opensfm/src/sfm/CMakeLists.txt -+++ b/opensfm/src/sfm/CMakeLists.txt -@@ -35,7 +35,6 @@ target_include_directories(pysfm PRIVATE ${GLOG_INCLUDE_DIR}) - target_link_libraries(pysfm - PRIVATE - foundation -- pybind11 - sfm - ) - set_target_properties(pysfm PROPERTIES --- -2.33.1 - diff --git a/pkgs/development/python-modules/opensfm/fix-scripts.patch b/pkgs/development/python-modules/opensfm/0003-fix-scripts.patch similarity index 54% rename from pkgs/development/python-modules/opensfm/fix-scripts.patch rename to pkgs/development/python-modules/opensfm/0003-fix-scripts.patch index 634820a32755..1e96bc21fc3e 100644 --- a/pkgs/development/python-modules/opensfm/fix-scripts.patch +++ b/pkgs/development/python-modules/opensfm/0003-fix-scripts.patch @@ -1,5 +1,5 @@ diff --git a/bin/opensfm b/bin/opensfm -index b5ee4b15..f05c0d1c 100755 +index b5ee4b1..f05c0d1 100755 --- a/bin/opensfm +++ b/bin/opensfm @@ -1,12 +1,6 @@ @@ -18,24 +18,11 @@ index b5ee4b15..f05c0d1c 100755 -"$PYTHON" "$DIR"/opensfm_main.py "$@" +exec "$DIR"/opensfm_main.py "$@" diff --git a/bin/opensfm_main.py b/bin/opensfm_main.py -index 31249e12..cc71560c 100755 +index b91abcf..531a492 100755 --- a/bin/opensfm_main.py +++ b/bin/opensfm_main.py -@@ -1,3 +1,5 @@ +@@ -1,3 +1,4 @@ +#!/usr/bin/env python -+ + # pyre-strict import sys - from os.path import abspath, join, dirname - -diff --git a/setup.py b/setup.py -index 1120717f..438a16db 100644 ---- a/setup.py -+++ b/setup.py -@@ -71,6 +71,7 @@ setuptools.setup( - scripts=[ - "bin/opensfm_run_all", - "bin/opensfm", -+ "bin/opensfm_main.py", - ], - package_data={ - "opensfm": [ + from os.path import abspath, dirname, join diff --git a/pkgs/development/python-modules/opensfm/0004-pybind_utils.h-conflicts-with-nixpkgs-pybind.patch b/pkgs/development/python-modules/opensfm/0004-pybind_utils.h-conflicts-with-nixpkgs-pybind.patch deleted file mode 100644 index f3cb2db00ecb..000000000000 --- a/pkgs/development/python-modules/opensfm/0004-pybind_utils.h-conflicts-with-nixpkgs-pybind.patch +++ /dev/null @@ -1,86 +0,0 @@ -From c35b110a83286e7413d7309eb218eb43b52f7d48 Mon Sep 17 00:00:00 2001 -From: Someone Serge -Date: Sat, 19 Feb 2022 14:36:12 +0200 -Subject: [PATCH 4/4] pybind_utils.h: conflicts with nixpkgs' pybind - ---- - opensfm/src/map/pybind_utils.h | 45 +++------------------------------- - 1 file changed, 3 insertions(+), 42 deletions(-) - -diff --git a/opensfm/src/map/pybind_utils.h b/opensfm/src/map/pybind_utils.h -index 817d1a16..3f98a2ab 100644 ---- a/opensfm/src/map/pybind_utils.h -+++ b/opensfm/src/map/pybind_utils.h -@@ -52,38 +52,6 @@ struct sfm_iterator_state { - }; - PYBIND11_NAMESPACE_END_(detail) - --/// Makes an python iterator over the keys (`.first`) of a iterator over pairs --/// from a first and past-the-end InputIterator. --template ()).second), -- typename... Extra> --iterator make_value_iterator(Iterator first, Sentinel last, Extra &&... extra) { -- typedef detail::sfm_iterator_state -- state; -- -- if (!detail::get_type_info(typeid(state), false)) { -- class_(handle(), "iterator", pybind11::module_local()) -- .def("__iter__", [](state &s) -> state & { return s; }) -- .def("__next__", -- [](state &s) -> KeyType { -- if (!s.first_or_done) -- ++s.it; -- else -- s.first_or_done = false; -- if (s.it == s.end) { -- s.first_or_done = true; -- throw stop_iteration(); -- } -- return (*s.it).second; -- }, -- std::forward(extra)..., Policy); -- } -- -- return cast(state{first, last, true}); --} -- - template ()).second)), -@@ -148,12 +116,13 @@ iterator make_ref_iterator(Iterator first, Sentinel last, Extra &&... extra) { - } - - /// Makes a python iterator from a first and past-the-end C++ InputIterator. --template ()), - typename... Extra> - iterator make_ptr_iterator(Iterator first, Sentinel last, Extra &&... extra) { -- typedef detail::iterator_state state; -+ typedef detail::iterator_state state; - - if (!detail::get_type_info(typeid(state), false)) { - class_(handle(), "iterator", pybind11::module_local()) -@@ -176,14 +145,6 @@ iterator make_ptr_iterator(Iterator first, Sentinel last, Extra &&... extra) { - return cast(state{first, last, true}); - } - --/// Makes an iterator over the keys (`.first`) of a stl map-like container --/// supporting `std::begin()`/`std::end()` --template --iterator make_value_iterator(Type &value, Extra &&... extra) { -- return make_value_iterator(std::begin(value), std::end(value), -- extra...); --} - template - iterator make_unique_ptr_value_iterator(Type &value, Extra &&... extra) { --- -2.33.1 - diff --git a/pkgs/development/python-modules/opensfm/0005-fix-numpy-2-test-failures.patch b/pkgs/development/python-modules/opensfm/0005-fix-numpy-2-test-failures.patch deleted file mode 100644 index 444471d37f4d..000000000000 --- a/pkgs/development/python-modules/opensfm/0005-fix-numpy-2-test-failures.patch +++ /dev/null @@ -1,239 +0,0 @@ -diff --git a/opensfm/exif.py b/opensfm/exif.py ---- a/opensfm/exif.py -+++ b/opensfm/exif.py -@@ -509,7 +509,7 @@ class EXIF: - ) - ) - -- if np.all(ypr) is not None: -+ if np.all(ypr != None): - ypr = np.radians(ypr) - - # Convert YPR --> OPK -diff --git a/opensfm/transformations.py b/opensfm/transformations.py ---- a/opensfm/transformations.py -+++ b/opensfm/transformations.py -@@ -232,7 +232,7 @@ def translation_from_matrix(matrix: numpy.ndarray) -> numpy.ndarray: - True - - """ -- return numpy.array(matrix, copy=False)[:3, 3].copy() -+ return numpy.asarray(matrix)[:3, 3].copy() - - - def reflection_matrix(point: numpy.ndarray, normal: numpy.ndarray) -> numpy.ndarray: -@@ -275,7 +275,7 @@ def reflection_from_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=False) -+ M = numpy.asarray(matrix, dtype=numpy.float64) - # normal: unit eigenvector corresponding to eigenvalue -1 - w, V = numpy.linalg.eig(M[:3, :3]) - i = numpy.where(abs(numpy.real(w) + 1.0) < 1e-8)[0] -@@ -339,7 +339,7 @@ def rotation_matrix( - M[:3, :3] = R - if point is not None: - # rotation not around origin -- point = numpy.array(point[:3], dtype=numpy.float64, copy=False) -+ point = numpy.asarray(point[:3], dtype=numpy.float64) - M[:3, 3] = point - numpy.dot(R, point) - return M - -@@ -359,7 +359,7 @@ def rotation_from_matrix( - True - - """ -- R = numpy.array(matrix, dtype=numpy.float64, copy=False) -+ R = numpy.asarray(matrix, dtype=numpy.float64) - R33 = R[:3, :3] - # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 - w, W = numpy.linalg.eig(R33.T) -@@ -444,7 +444,7 @@ def scale_from_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=False) -+ M = numpy.asarray(matrix, dtype=numpy.float64) - M33 = M[:3, :3] - factor = numpy.trace(M33) - 2.0 - try: -@@ -505,11 +505,11 @@ def projection_matrix( - - """ - M = numpy.identity(4) -- point = numpy.array(point[:3], dtype=numpy.float64, copy=False) -+ point = numpy.asarray(point[:3], dtype=numpy.float64) - normal = unit_vector(normal[:3]) - if perspective is not None: - # perspective projection -- perspective = numpy.array(perspective[:3], dtype=numpy.float64, copy=False) -+ perspective = numpy.asarray(perspective[:3], dtype=numpy.float64) - M[0, 0] = M[1, 1] = M[2, 2] = numpy.dot(perspective - point, normal) - M[:3, :3] -= numpy.outer(perspective, normal) - if pseudo: -@@ -522,7 +522,7 @@ def projection_matrix( - M[3, 3] = numpy.dot(perspective, normal) - elif direction is not None: - # parallel projection -- direction = numpy.array(direction[:3], dtype=numpy.float64, copy=False) -+ direction = numpy.asarray(direction[:3], dtype=numpy.float64) - scale = numpy.dot(direction, normal) - M[:3, :3] -= numpy.outer(direction, normal) / scale - M[:3, 3] = direction * (numpy.dot(point, normal) / scale) -@@ -569,7 +569,7 @@ def projection_from_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=False) -+ M = numpy.asarray(matrix, dtype=numpy.float64) - M33 = M[:3, :3] - w, V = numpy.linalg.eig(M) - i = numpy.where(abs(numpy.real(w) - 1.0) < 1e-8)[0] -@@ -726,7 +726,7 @@ def shear_from_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=False) -+ M = numpy.asarray(matrix, dtype=numpy.float64) - M33 = M[:3, :3] - # normal: cross independent eigenvectors corresponding to the eigenvalue 1 - w, V = numpy.linalg.eig(M33) -@@ -790,7 +790,7 @@ def decompose_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=True).T -+ M = numpy.asarray(matrix, dtype=numpy.float64, copy=True).T - if abs(M[3, 3]) < _EPS: - raise ValueError("M[3, 3] is zero") - M /= M[3, 3] -@@ -982,8 +982,8 @@ def affine_matrix_from_points( - More examples in superimposition_matrix() - - """ -- v0 = numpy.array(v0, dtype=numpy.float64, copy=True) -- v1 = numpy.array(v1, dtype=numpy.float64, copy=True) -+ v0 = numpy.asarray(v0, dtype=numpy.float64, copy=True) -+ v1 = numpy.asarray(v1, dtype=numpy.float64, copy=True) - - ndims = v0.shape[0] - if ndims < 2 or v0.shape[1] < ndims or v0.shape != v1.shape: -@@ -1099,8 +1099,8 @@ def superimposition_matrix( - True - - """ -- v0 = numpy.array(v0, dtype=numpy.float64, copy=False)[:3] -- v1 = numpy.array(v1, dtype=numpy.float64, copy=False)[:3] -+ v0 = numpy.asarray(v0, dtype=numpy.float64)[:3] -+ v1 = numpy.asarray(v1, dtype=numpy.float64)[:3] - return affine_matrix_from_points(v0, v1, shear=False, scale=scale, usesvd=usesvd) - - -@@ -1198,7 +1198,7 @@ def euler_from_matrix( - j = _NEXT_AXIS[i + parity] - k = _NEXT_AXIS[i - parity + 1] - -- M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:3, :3] -+ M = numpy.asarray(matrix, dtype=numpy.float64)[:3, :3] - if repetition: - sy = math.sqrt(M[i, j] * M[i, j] + M[i, k] * M[i, k]) - if sy > _EPS: -@@ -1329,7 +1329,7 @@ def quaternion_matrix(quaternion: numpy.ndarray) -> numpy.ndarray: - True - - """ -- q = numpy.array(quaternion, dtype=numpy.float64, copy=True) -+ q = numpy.asarray(quaternion, dtype=numpy.float64, copy=True) - n = numpy.dot(q, q) - if n < _EPS: - return numpy.identity(4) -@@ -1379,7 +1379,7 @@ def quaternion_from_matrix( - True - - """ -- M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:4, :4] -+ M = numpy.asarray(matrix, dtype=numpy.float64)[:4, :4] - if isprecise: - q = numpy.empty((4,)) - t = numpy.trace(M) -@@ -1460,7 +1460,7 @@ def quaternion_conjugate(quaternion: numpy.ndarray) -> numpy.ndarray: - True - - """ -- q = numpy.array(quaternion, dtype=numpy.float64, copy=True) -+ q = numpy.asarray(quaternion, dtype=numpy.float64, copy=True) - numpy.negative(q[1:], q[1:]) - return q - -@@ -1474,7 +1474,7 @@ def quaternion_inverse(quaternion: numpy.ndarray) -> numpy.ndarray: - True - - """ -- q = numpy.array(quaternion, dtype=numpy.float64, copy=True) -+ q = numpy.asarray(quaternion, dtype=numpy.float64, copy=True) - numpy.negative(q[1:], q[1:]) - return q / numpy.dot(q, q) - -@@ -1496,7 +1496,7 @@ def quaternion_imag(quaternion: numpy.ndarray) -> numpy.ndarray: - array([ 0., 1., 2.]) - - """ -- return numpy.array(quaternion[1:4], dtype=numpy.float64, copy=True) -+ return numpy.asarray(quaternion[1:4], dtype=numpy.float64, copy=True) - - - def quaternion_slerp( -@@ -1654,7 +1654,7 @@ def vector_norm( - 1.0 - - """ -- data = numpy.array(data, dtype=numpy.float64, copy=True) -+ data = numpy.asarray(data, dtype=numpy.float64, copy=True) - if out is None: - if data.ndim == 1: - return math.sqrt(numpy.dot(data, data)) -@@ -1697,13 +1697,13 @@ def unit_vector( - - """ - if out is None: -- data = numpy.array(data, dtype=numpy.float64, copy=True) -+ data = numpy.asarray(data, dtype=numpy.float64, copy=True) - if data.ndim == 1: - data /= math.sqrt(numpy.dot(data, data)) - return data - else: - if out is not data: -- out[:] = numpy.array(data, copy=False) -+ out[:] = numpy.asarray(data) - data = out - length = numpy.atleast_1d(numpy.sum(data * data, axis)) - numpy.sqrt(length, length) -@@ -1777,8 +1777,8 @@ def angle_between_vectors( - True - - """ -- v0 = numpy.array(v0, dtype=numpy.float64, copy=False) -- v1 = numpy.array(v1, dtype=numpy.float64, copy=False) -+ v0 = numpy.asarray(v0, dtype=numpy.float64) -+ v1 = numpy.asarray(v1, dtype=numpy.float64) - dot = numpy.sum(v0 * v1, axis=axis) - dot /= vector_norm(v0, axis=axis) * vector_norm(v1, axis=axis) - dot = numpy.clip(dot, -1.0, 1.0) -@@ -1826,9 +1826,9 @@ def is_same_transform(matrix0: numpy.ndarray, matrix1: numpy.ndarray) -> numpy.n - False - - """ -- matrix0 = numpy.array(matrix0, dtype=numpy.float64, copy=True) -+ matrix0 = numpy.asarray(matrix0, dtype=numpy.float64, copy=True) - matrix0 /= matrix0[3, 3] -- matrix1 = numpy.array(matrix1, dtype=numpy.float64, copy=True) -+ matrix1 = numpy.asarray(matrix1, dtype=numpy.float64, copy=True) - matrix1 /= matrix1[3, 3] - return numpy.allclose(matrix0, matrix1) - -@@ -1874,3 +1874,4 @@ if __name__ == "__main__": - - numpy.set_printoptions(suppress=True, precision=5) - doctest.testmod() -+ diff --git a/pkgs/development/python-modules/opensfm/default.nix b/pkgs/development/python-modules/opensfm/default.nix index 59bf764902dd..119c4a5d8917 100644 --- a/pkgs/development/python-modules/opensfm/default.nix +++ b/pkgs/development/python-modules/opensfm/default.nix @@ -3,8 +3,10 @@ stdenv, buildPythonPackage, fetchFromGitHub, + runCommand, + srcOnly, + bashNonInteractive, cmake, - opencv4, ceres-solver, suitesparse, metis, @@ -14,6 +16,9 @@ pybind11, numpy, pyyaml, + flask, + fpdf2, + opencv-python, lapack, gtest, gflags, @@ -22,46 +27,42 @@ networkx, pillow, exifread, - gpxpy, pyproj, python-dateutil, joblib, - repoze-lru, xmltodict, - distutils, cloudpickle, scipy, sphinx, matplotlib, - fpdf, + scikit-build-core, + ninja, }: -buildPythonPackage rec { +buildPythonPackage (finalAttrs: { pname = "opensfm"; - version = "unstable-2023-12-09"; + version = "0.5.1-unstable-2026-05-04"; pyproject = true; src = fetchFromGitHub { owner = "mapillary"; repo = "OpenSfM"; - rev = "7f170d0dc352340295ff480378e3ac37d0179f8e"; - sha256 = "sha256-l/HTVenC+L+GpMNnDgnSGZ7+Qd2j8b8cuTs3SmORqrg="; + rev = "1dc5b95b5c8c4cadd653bdc9f6eb97c0ac1602ba"; + sha256 = "sha256-K3+H8QSzTxIGAtYDGqOuJFTVaqk+B/R/MDMepJ/bRxY="; }; patches = [ + ./0001-cmake-use-system-pybind11.patch ./0002-cmake-find-system-distributed-gtest.patch - ./0003-cmake-use-system-pybind11.patch - ./0004-pybind_utils.h-conflicts-with-nixpkgs-pybind.patch - ./0005-fix-numpy-2-test-failures.patch # not upstreamed due to cla, but you're free upstream it -@pbsds - ./fix-scripts.patch + ./0003-fix-scripts.patch ]; postPatch = '' - substituteInPlace opensfm/src/CMakeLists.txt \ - --replace-fail "cmake_minimum_required(VERSION 3.0)" "cmake_minimum_required(VERSION 3.10)" - - rm opensfm/src/cmake/FindGlog.cmake + # devendor + rm opensfm/src/cmake/FindGlog.cmake # (ubuntu 20.04 fallback) rm opensfm/src/cmake/FindGflags.cmake + rm -rf opensfm/src/third_party/gtest + rm -rf opensfm/src/third_party/pybind11 # HAHOG is the default descriptor. # We'll test both HAHOG and SIFT because this is @@ -72,15 +73,20 @@ buildPythonPackage rec { # make opensfm correctly import glog headers export CXXFLAGS=-DGLOG_USE_GLOG_EXPORT - sed -i -e 's/^.*BuildDoc.*$//' setup.py + # we use the pyproject.toml + rm setup.py ''; - build-system = [ setuptools ]; + dontUseCmakeConfigure = true; + + build-system = [ + setuptools + scikit-build-core + ninja + ]; nativeBuildInputs = [ cmake - pkg-config - sphinx ]; buildInputs = [ @@ -93,41 +99,45 @@ buildPythonPackage rec { gtest glog pybind11 + bashNonInteractive # for patchShebangs ]; dependencies = [ numpy scipy pyyaml - opencv4.cxxdev + flask + fpdf2 + opencv-python networkx pillow matplotlib - fpdf exifread - gpxpy pyproj python-dateutil joblib - repoze-lru xmltodict cloudpickle ]; nativeCheckInputs = [ pytestCheckHook - distutils ]; - dontUseCmakeBuildDir = true; - cmakeFlags = [ - "-Bcmake_build" - "-Sopensfm/src" - ]; + # pyproject.toml has yet to enable the [project.scripts] + postInstall = '' + if [[ -d $out/bin ]]; then + echo >&2 "ERROR: $out/bin found, re-check our assumptions" + false + fi + install -Dt $out/bin -m +rwx bin/opensfm + install -Dt $out/bin -m +rwx bin/opensfm_run_all + install -Dt $out/bin -m +rwx bin/opensfm_main.py + ''; disabledTests = [ - "test_run_all" # Matplotlib issues. Broken integration is less useless than a broken build - "test_match_candidates_from_metadata_bow" # flaky + # flaky + "test_match_candidates_from_metadata_bow" ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ "test_reconstruction_incremental" @@ -143,8 +153,8 @@ buildPythonPackage rec { lib.maintainers.SomeoneSerge ]; license = lib.licenses.bsd2; - changelog = "https://github.com/mapillary/OpenSfM/blob/${src.rev}/CHANGELOG.md"; + changelog = "https://github.com/mapillary/OpenSfM/blob/${finalAttrs.src.rev}/CHANGELOG.md"; description = "Open source Structure-from-Motion pipeline from Mapillary"; homepage = "https://opensfm.org/"; }; -} +}) From 45b61eaae7445c3bb042557aebf8334ba07058e4 Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt Date: Tue, 5 May 2026 04:51:38 +0200 Subject: [PATCH 2/2] python3Packages.opensfm: add passthru.tests --- .../python-modules/opensfm/default.nix | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pkgs/development/python-modules/opensfm/default.nix b/pkgs/development/python-modules/opensfm/default.nix index 119c4a5d8917..2a7a13e7924c 100644 --- a/pkgs/development/python-modules/opensfm/default.nix +++ b/pkgs/development/python-modules/opensfm/default.nix @@ -146,6 +146,27 @@ buildPythonPackage (finalAttrs: { pythonImportsCheck = [ "opensfm" ]; + # https://opensfm.org/docs/using.html#quickstart + passthru.tests = lib.genAttrs' [ "berlin" "lund" ] ( + name: + lib.nameValuePair "integration-test-${name}" ( + runCommand "opensfm-integration-test-${name}" + { + nativeBuildInputs = [ finalAttrs.finalPackage ]; + } + '' + set -euo pipefail + opensfm --help + cp -r ${srcOnly finalAttrs.finalPackage}/data/${name} data + chmod -R +w data/ + bash -x $(command -v opensfm_run_all) data/ + if [[ -s data/camera_models.json && -s data/undistorted/reconstruction.json ]]; then + touch $out + fi + '' + ) + ); + meta = { broken = stdenv.hostPlatform.isDarwin; maintainers = [