diff --git a/.dockerignore b/.dockerignore index b4797a80f..487ad3e85 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,4 @@ Dockerfile -tests/test_data SuperBuild/build SuperBuild/download SuperBuild/install @@ -18,8 +17,6 @@ images_resize /hooks /img /license -/tests -tests.sh settings.yml code_of_conduct.md configure_18_04.sh diff --git a/.github/workflows/build_vcpkg_env.yaml b/.github/workflows/build_vcpkg_env.yaml new file mode 100644 index 000000000..6402c6587 --- /dev/null +++ b/.github/workflows/build_vcpkg_env.yaml @@ -0,0 +1,28 @@ +name: Build Windows Dependencies + +on: + workflow_dispatch: + +jobs: + windows: + runs-on: windows-2022 + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up vcpkg + run: | + git clone https://github.com/microsoft/vcpkg.git + .\vcpkg\bootstrap-vcpkg.bat + + - name: Install vcpkg dependencies + run: .\vcpkg\vcpkg.exe install --triplet x64-windows + + - name: Export vcpkg dependencies + run: .\vcpkg\vcpkg.exe export --zip --output=vcpkg-export --output-dir=. + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: vcpkg-env-x64-windows + path: vcpkg-export.zip diff --git a/.github/workflows/publish-windows.yml b/.github/workflows/publish-windows.yml index 542edfeb6..0622b7601 100644 --- a/.github/workflows/publish-windows.yml +++ b/.github/workflows/publish-windows.yml @@ -16,12 +16,12 @@ jobs: - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.8.1' + python-version: '3.12.10' architecture: 'x64' - - uses: Jimver/cuda-toolkit@v0.2.4 + - uses: Jimver/cuda-toolkit@v0.2.24 id: cuda-toolkit with: - cuda: '11.4.0' + cuda: '12.8.1' - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: diff --git a/.github/workflows/test-build-prs.yaml b/.github/workflows/test-build-prs.yaml index ddc127620..1656ba5c2 100644 --- a/.github/workflows/test-build-prs.yaml +++ b/.github/workflows/test-build-prs.yaml @@ -49,19 +49,19 @@ jobs: # isClassic: 'false' windows: - runs-on: windows-2019 + runs-on: windows-2022 steps: - name: Checkout uses: actions/checkout@v2 - name: Setup Python uses: actions/setup-python@v2 with: - python-version: '3.8.1' + python-version: '3.12.10' architecture: 'x64' - - uses: Jimver/cuda-toolkit@v0.2.4 + - uses: Jimver/cuda-toolkit@v0.2.24 id: cuda-toolkit with: - cuda: '11.4.0' + cuda: '12.8.1' - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: diff --git a/.gitignore b/.gitignore index d3828c780..f43023bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ storage/ vcpkg/ venv/ -python38/ +python312/ dist/ innosetup/ .DS_Store diff --git a/Dockerfile b/Dockerfile index 857084136..dca53ef88 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM ubuntu:21.04 AS builder +FROM ubuntu:24.04 AS builder # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" # Prepare directories @@ -11,12 +11,13 @@ WORKDIR /code # Copy everything COPY . ./ -# Use old-releases for 21.04 -RUN printf "deb http://old-releases.ubuntu.com/ubuntu/ hirsute main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse" > /etc/apt/sources.list - # Run the build RUN bash configure.sh install +# Run the tests +ENV PATH="/code/venv/bin:$PATH" +RUN bash test.sh + # Clean Superbuild RUN bash configure.sh clean @@ -24,11 +25,11 @@ RUN bash configure.sh clean ### Use a second image for the final asset to reduce the number and # size of the layers. -FROM ubuntu:21.04 +FROM ubuntu:24.04 # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" \ PDAL_DRIVER_PATH="/code/SuperBuild/install/bin" @@ -37,11 +38,7 @@ WORKDIR /code # Copy everything we built from the builder COPY --from=builder /code /code -# Copy the Python libraries installed via pip from the builder -COPY --from=builder /usr/local /usr/local - -# Use old-releases for 21.04 -RUN printf "deb http://old-releases.ubuntu.com/ubuntu/ hirsute main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse" > /etc/apt/sources.list +ENV PATH="/code/venv/bin:$PATH" # Install shared libraries that we depend on via APT, but *not* # the -dev packages to save space! @@ -51,5 +48,6 @@ RUN bash configure.sh installruntimedepsonly \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && bash run.sh --help \ && bash -c "eval $(python3 /code/opendm/context.py) && python3 -c 'from opensfm import io, pymap'" + # Entry point ENTRYPOINT ["python3", "/code/run.py"] diff --git a/README.md b/README.md index e0b080312..c2dab19c4 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,9 @@ You're in good shape! See https://github.com/NVIDIA/nvidia-docker and https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker for information on docker/NVIDIA setup. -## Native Install (Ubuntu 21.04) +## Native Install (Ubuntu 24.04) -You can run ODM natively on Ubuntu 21.04 (although we don't recommend it): +You can run ODM natively on Ubuntu 24.04 (although we don't recommend it): ```bash git clone https://github.com/OpenDroneMap/ODM @@ -144,6 +144,8 @@ You can then process datasets with `./run.sh /datasets/odm_data_aukerman` ## Native Install (MacOS) +> **Warning:** Installation on Mac is currently unmaintained, and may not work out-of-the-box. See this [issue](https://community.opendronemap.org/t/odm-install-on-a-mac-os-14-6-1/25007/3). + You can run ODM natively on Intel/ARM MacOS. First install: diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 15e4f1bed..1296701ad 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -96,14 +96,9 @@ if (WIN32) # Use the GDAL version that comes with pip set(GDAL_ROOT "${PYTHON_HOME}/Lib/site-packages/osgeo") - set(GDAL_LIBRARY "${GDAL_ROOT}/lib/gdal_i.lib") + set(GDAL_LIBRARY "${GDAL_ROOT}/gdal.lib") set(GDAL_INCLUDE_DIR "${GDAL_ROOT}/include/gdal") - # Also download missing headers :/ - if (NOT EXISTS "${GDAL_INCLUDE_DIR}/ogrsf_frmts.h") - file(DOWNLOAD "https://raw.githubusercontent.com/OSGeo/gdal/release/3.2/gdal/ogr/ogrsf_frmts/ogrsf_frmts.h" "${GDAL_INCLUDE_DIR}/ogrsf_frmts.h") - endif() - message("Copying VCPKG DLLs...") file(GLOB COPY_DLLS "${VCPKG_ROOT}/installed/x64-windows/bin/*.dll") file(COPY ${COPY_DLLS} DESTINATION "${SB_INSTALL_DIR}/bin") @@ -117,7 +112,8 @@ elseif(APPLE) set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") set(PYTHON_EXE_PATH "${PYTHON_HOME}/bin/python") else() - set(PYTHON_EXE_PATH "/usr/bin/python3") + set(PYTHON_HOME "${SB_ROOT_DIR}/../venv") + set(PYTHON_EXE_PATH "${PYTHON_HOME}/bin/python3") endif() # Path to additional CMake modules @@ -133,7 +129,7 @@ include(ExternalProject-Setup) # --------------------------------------------------------------------------------------------- # Open Source Computer Vision (OpenCV) # -set(ODM_OpenCV_Version 2.4.11) +set(ODM_OpenCV_Version 4.12.0) option(ODM_BUILD_OpenCV "Force to build OpenCV library" OFF) SETUP_EXTERNAL_PROJECT(OpenCV ${ODM_OpenCV_Version} ${ODM_BUILD_OpenCV}) @@ -160,7 +156,7 @@ SETUP_EXTERNAL_PROJECT(Ceres ${ODM_Ceres_Version} ${ODM_BUILD_Ceres}) # --------------------------------------------------------------------------------------------- # Hexer # -SETUP_EXTERNAL_PROJECT(Hexer 1.4 ON) +SETUP_EXTERNAL_PROJECT(Hexer 1.5 ON) # --------------------------------------------------------------------------------------------- # Open Structure from Motion (OpenSfM) @@ -269,9 +265,9 @@ externalproject_add(lastools ) externalproject_add(draco - GIT_REPOSITORY https://github.com/OpenDroneMap/draco - GIT_SHALLOW ON - GIT_TAG 304 + GIT_REPOSITORY https://github.com/google/draco + GIT_SHALLOW OFF + GIT_TAG e801aebf9665f6dcf3b6b0a604055a300ff85aa4 PREFIX ${SB_BINARY_DIR}/draco SOURCE_DIR ${SB_SOURCE_DIR}/draco CMAKE_ARGS -DDRACO_TRANSCODER_SUPPORTED=ON diff --git a/SuperBuild/cmake/External-Ceres.cmake b/SuperBuild/cmake/External-Ceres.cmake index 947e7b919..323deef15 100644 --- a/SuperBuild/cmake/External-Ceres.cmake +++ b/SuperBuild/cmake/External-Ceres.cmake @@ -11,6 +11,7 @@ ExternalProject_Add(${_proj_name} URL http://ceres-solver.org/ceres-solver-2.0.0.tar.gz #--Update/Patch step---------- UPDATE_COMMAND "" + PATCH_COMMAND git apply ${CMAKE_MODULE_PATH}/ceres.patch #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS diff --git a/SuperBuild/cmake/External-Entwine.cmake b/SuperBuild/cmake/External-Entwine.cmake index 6319212fc..c0e9279c0 100644 --- a/SuperBuild/cmake/External-Entwine.cmake +++ b/SuperBuild/cmake/External-Entwine.cmake @@ -13,7 +13,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/OpenDroneMap/entwine/ - GIT_TAG 290 + GIT_TAG 0cf957432f291e841ff1385085dadad933dcba8d #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- @@ -23,6 +23,8 @@ ExternalProject_Add(${_proj_name} -DADDITIONAL_LINK_DIRECTORIES_PATHS=${SB_INSTALL_DIR}/lib -DWITH_TESTS=OFF -DWITH_ZSTD=OFF + -DWITH_CURL=OFF + -DWITH_OPENSSL=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR} #--Build step----------------- diff --git a/SuperBuild/cmake/External-Hexer.cmake b/SuperBuild/cmake/External-Hexer.cmake index ddff150b7..8fd419907 100644 --- a/SuperBuild/cmake/External-Hexer.cmake +++ b/SuperBuild/cmake/External-Hexer.cmake @@ -8,7 +8,7 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/hobu/hexer/archive/bc748fc16b51c562f68f6641574b7af4244adfa2.tar.gz + URL https://github.com/hobuinc/hexer/archive/5876a5ab1d5b504cf1ea985d66ae359287eef31e.tar.gz #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/External-MvsTexturing.cmake b/SuperBuild/cmake/External-MvsTexturing.cmake index dd2d7c683..872439f3c 100644 --- a/SuperBuild/cmake/External-MvsTexturing.cmake +++ b/SuperBuild/cmake/External-MvsTexturing.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name} GIT_REPOSITORY https://github.com/OpenDroneMap/mvs-texturing - GIT_TAG 290 + GIT_TAG c5a4d0c9a434553533c6e39d426e349fcfa5f48d #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/External-OpenCV.cmake b/SuperBuild/cmake/External-OpenCV.cmake index 293d788a7..9f93aec91 100644 --- a/SuperBuild/cmake/External-OpenCV.cmake +++ b/SuperBuild/cmake/External-OpenCV.cmake @@ -2,7 +2,7 @@ set(_proj_name opencv) set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") if (WIN32) - set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/site-packages/numpy/core/include + set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/site-packages/numpy/_core/include -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/site-packages -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH} -DWITH_MSMF=OFF @@ -10,12 +10,12 @@ if (WIN32) -DOPENCV_BIN_INSTALL_PATH=${SB_INSTALL_DIR}/bin) elseif(APPLE) # macOS is unable to automatically detect our Python libs - set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/python3.8/site-packages/numpy/core/include - -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/python3.8/site-packages + set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/python3.12/site-packages/numpy/core/include + -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/python3.12/site-packages -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH} - -DPYTHON3_LIBRARIES=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/libpython3.8.dylib - -DPYTHON3_INCLUDE_DIR=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/include/python3.8/ - -DPYTHON3_INCLUDE_PATH=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/include/python3.8/ + -DPYTHON3_LIBRARIES=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.12/Frameworks/Python.framework/Versions/3.12/lib/libpython3.12.dylib + -DPYTHON3_INCLUDE_DIR=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.12/Frameworks/Python.framework/Versions/3.12/include/python3.12/ + -DPYTHON3_INCLUDE_PATH=${HOMEBREW_INSTALL_PREFIX}/opt/python@3.12/Frameworks/Python.framework/Versions/3.12/include/python3.12/ -DPYTHON3INTERP_FOUND=ON -DPYTHON3LIBS_FOUND=ON -DPYTHON_DEFAULT_AVAILABLE=ON @@ -23,11 +23,15 @@ elseif(APPLE) -DPYTHON3_VERSION_MAJOR=3 -DPYTHON3_VERSION_MINOR=8 -DOPENCV_CONFIG_INSTALL_PATH= - -DOPENCV_PYTHON_INSTALL_PATH=${SB_INSTALL_DIR}/lib/python3.8/dist-packages + -DOPENCV_PYTHON_INSTALL_PATH=${SB_INSTALL_DIR}/lib/python3.12/dist-packages -DHAVE_opencv_python3=ON -DOPENCV_PYTHON_SKIP_DETECTION=ON -DOPENCV_LIB_INSTALL_PATH=${SB_INSTALL_DIR}/lib -DOPENCV_BIN_INSTALL_PATH=${SB_INSTALL_DIR}/bin) +else() + set(OCV_CMAKE_EXTRA_ARGS -DPYTHON3_NUMPY_INCLUDE_DIRS=${PYTHON_HOME}/lib/python3.12/site-packages/numpy/_core/include + -DPYTHON3_PACKAGES_PATH=${PYTHON_HOME}/lib/python3.12/site-packages + -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH}) endif() ExternalProject_Add(${_proj_name} @@ -36,7 +40,7 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/opencv/opencv/archive/4.5.0.zip + URL https://github.com/opencv/opencv/archive/4.12.0.zip #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/External-OpenPointClass.cmake b/SuperBuild/cmake/External-OpenPointClass.cmake index 953a259fc..ac6bf96eb 100644 --- a/SuperBuild/cmake/External-OpenPointClass.cmake +++ b/SuperBuild/cmake/External-OpenPointClass.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/uav4geo/OpenPointClass - GIT_TAG v1.1.3 + GIT_TAG dd6a560a1d43cb709f7b220b19a436e25a889e3e #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/External-OpenSfM.cmake b/SuperBuild/cmake/External-OpenSfM.cmake index f50c8e85d..09cc328c3 100644 --- a/SuperBuild/cmake/External-OpenSfM.cmake +++ b/SuperBuild/cmake/External-OpenSfM.cmake @@ -5,7 +5,7 @@ ProcessorCount(nproc) set(EXTRA_INCLUDE_DIRS "") if(WIN32) - set(OpenCV_DIR "${SB_INSTALL_DIR}/x64/vc16/lib") + set(OpenCV_DIR "${SB_INSTALL_DIR}/x64/vc17/lib") set(BUILD_CMD ${CMAKE_COMMAND} --build "${SB_BUILD_DIR}/opensfm" --config "${CMAKE_BUILD_TYPE}") else() set(BUILD_CMD make "-j${nproc}") @@ -25,7 +25,7 @@ ExternalProject_Add(${_proj_name} #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/OpenDroneMap/OpenSfM/ - GIT_TAG 355 + GIT_TAG c5328439465e6ace011f39077d1077d7b1cdd65d #--Update/Patch step---------- UPDATE_COMMAND git submodule update --init --recursive #--Configure step------------- diff --git a/SuperBuild/cmake/External-PDAL.cmake b/SuperBuild/cmake/External-PDAL.cmake index 12a0936c9..9b2b1332a 100644 --- a/SuperBuild/cmake/External-PDAL.cmake +++ b/SuperBuild/cmake/External-PDAL.cmake @@ -16,9 +16,11 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/OpenDroneMap/PDAL/archive/refs/heads/333.zip + GIT_REPOSITORY https://github.com/PDAL/PDAL/ + GIT_TAG 831631084edc7e61bc898eae136294c375b13d14 #--Update/Patch step---------- UPDATE_COMMAND "" + PATCH_COMMAND git apply ${CMAKE_MODULE_PATH}/pdal.patch #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS diff --git a/SuperBuild/cmake/External-PDALPython.cmake b/SuperBuild/cmake/External-PDALPython.cmake index 410b77bf1..f91086864 100644 --- a/SuperBuild/cmake/External-PDALPython.cmake +++ b/SuperBuild/cmake/External-PDALPython.cmake @@ -2,8 +2,12 @@ set(_proj_name pdal-python) set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}") if (WIN32) - set(PP_EXTRA_ARGS -DPYTHON3_EXECUTABLE=${PYTHON_EXE_PATH} - -DPython3_NumPy_INCLUDE_DIRS=${PYTHON_HOME}/lib/site-packages/numpy/core/include) + set(PP_EXTRA_ARGS -DPython3_EXECUTABLE=${PYTHON_EXE_PATH} + -DPython3_ROOT_DIR=${PYTHON_HOME} + -DPython3_NumPy_INCLUDE_DIRS=${PYTHON_HOME}/Lib/site-packages/numpy/_core/include) +else() + set(PP_EXTRA_ARGS -DPython3_EXECUTABLE=${PYTHON_EXE_PATH} + -DPython3_NumPy_INCLUDE_DIRS=${PYTHON_HOME}/lib/python3.12/site-packages/numpy/_core/include) endif() ExternalProject_Add(${_proj_name} @@ -13,24 +17,28 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - GIT_REPOSITORY https://github.com/OpenDroneMap/pdal-python - GIT_TAG main + GIT_REPOSITORY https://github.com/PDAL/python + GIT_TAG 6791a880a87e95f7318e99acfb4a10186379c5dd #--Update/Patch step---------- - UPDATE_COMMAND "" + UPDATE_COMMAND git submodule update --init --recursive #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS -DPDAL_DIR=${SB_INSTALL_DIR}/lib/cmake/PDAL -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}/lib/python3.8/dist-packages + -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}/lib/python3.12/dist-packages ${WIN32_CMAKE_ARGS} ${PP_EXTRA_ARGS} #--Build step----------------- BINARY_DIR ${_SB_BINARY_DIR} #--Install step--------------- INSTALL_DIR ${SB_INSTALL_DIR} + INSTALL_COMMAND ${CMAKE_COMMAND} --build --target install + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/__init__.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/pipeline.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SB_SOURCE_DIR}/${_proj_name}/src/pdal/drivers.py ${SB_INSTALL_DIR}/lib/python3.12/dist-packages/pdal #--Output logging------------- LOG_DOWNLOAD OFF LOG_CONFIGURE OFF LOG_BUILD OFF -) \ No newline at end of file +) diff --git a/SuperBuild/cmake/External-PyPopsift.cmake b/SuperBuild/cmake/External-PyPopsift.cmake index 224ccc63f..c37b69e2f 100644 --- a/SuperBuild/cmake/External-PyPopsift.cmake +++ b/SuperBuild/cmake/External-PyPopsift.cmake @@ -5,14 +5,14 @@ find_package(CUDA 7.0) if(CUDA_FOUND) ExternalProject_Add(pypopsift - DEPENDS opensfm + DEPENDS PREFIX ${_SB_BINARY_DIR} TMP_DIR ${_SB_BINARY_DIR}/tmp STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} GIT_REPOSITORY https://github.com/OpenDroneMap/pypopsift - GIT_TAG 288 + GIT_TAG fe2d1ccc63877ba315e65f34d2adeadd838b3ac3 #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/External-Untwine.cmake b/SuperBuild/cmake/External-Untwine.cmake index d0067e697..b52ea6d63 100644 --- a/SuperBuild/cmake/External-Untwine.cmake +++ b/SuperBuild/cmake/External-Untwine.cmake @@ -8,8 +8,8 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - GIT_REPOSITORY https://github.com/OpenDroneMap/untwine/ - GIT_TAG 317 + GIT_REPOSITORY https://github.com/hobuinc/untwine/ + GIT_TAG 1.5.1 #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- diff --git a/SuperBuild/cmake/ceres.patch b/SuperBuild/cmake/ceres.patch new file mode 100644 index 000000000..42248029f --- /dev/null +++ b/SuperBuild/cmake/ceres.patch @@ -0,0 +1,42 @@ +diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake +index 5ae7b615..10e540da 100644 +--- a/cmake/FindTBB.cmake ++++ b/cmake/FindTBB.cmake +@@ -429,10 +429,23 @@ findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy) + #============================================================================= + #parse all the version numbers from tbb + if(NOT TBB_VERSION) ++ set(TBB_VERSION_FILE_PRIOR_TO_TBB_2021_1 ++ "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h") ++ set(TBB_VERSION_FILE_AFTER_TBB_2021_1 ++ "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h") ++ ++ if (EXISTS "${TBB_VERSION_FILE_PRIOR_TO_TBB_2021_1}") ++ set(TBB_VERSION_FILE "${TBB_VERSION_FILE_PRIOR_TO_TBB_2021_1}") ++ elseif (EXISTS "${TBB_VERSION_FILE_AFTER_TBB_2021_1}") ++ set(TBB_VERSION_FILE "${TBB_VERSION_FILE_AFTER_TBB_2021_1}") ++ else() ++ message(FATAL_ERROR "Found TBB installation: ${TBB_INCLUDE_DIR} " ++ "missing version header.") ++ endif() + + #only read the start of the file + file(STRINGS +- "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" ++ "${TBB_VERSION_FILE}" + TBB_VERSION_CONTENTS + REGEX "VERSION") + +diff --git a/internal/ceres/covariance_impl.cc b/internal/ceres/covariance_impl.cc +index 1f86707f..25bf9348 100644 +--- a/internal/ceres/covariance_impl.cc ++++ b/internal/ceres/covariance_impl.cc +@@ -634,7 +634,7 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() { + // separately. + const SuiteSparse_long rank = SuiteSparseQR(SPQR_ORDERING_BESTAMD, + SPQR_DEFAULT_TOL, +- cholmod_jacobian.ncol, ++ static_cast(cholmod_jacobian.ncol), + &cholmod_jacobian, + &R, + &permutation, diff --git a/SuperBuild/cmake/pdal.patch b/SuperBuild/cmake/pdal.patch new file mode 100644 index 000000000..f44cdd9ce --- /dev/null +++ b/SuperBuild/cmake/pdal.patch @@ -0,0 +1,21 @@ +diff --git a/io/private/GDALGrid.hpp b/io/private/GDALGrid.hpp +index 542dc1a6a..9e66aae59 100644 +--- a/io/private/GDALGrid.hpp ++++ b/io/private/GDALGrid.hpp +@@ -84,13 +84,13 @@ public: + int numBands() const; + + // Return a pointer to the data in a raster band, row-major ordered. +- double *data(const std::string& name); ++ PDAL_EXPORT double *data(const std::string& name); + + // Add a point to the raster grid. +- void addPoint(double x, double y, double z); ++ PDAL_EXPORT void addPoint(double x, double y, double z); + + // Compute final values after all points have been added. +- void finalize(); ++ PDAL_EXPORT void finalize(); + + int width() const; + int height() const; diff --git a/configure.py b/configure.py index c15260468..72203e919 100644 --- a/configure.py +++ b/configure.py @@ -2,8 +2,8 @@ if sys.platform != 'win32': print("This script is for Windows only! Use configure.sh instead.") exit(1) -if sys.version_info.major != 3 or sys.version_info.minor != 8: - print("You need to use Python 3.8.x (due to the requirements.txt). You are using %s instead." % platform.python_version()) +if sys.version_info.major != 3 or sys.version_info.minor != 12: + print("You need to use Python 3.12.x (due to the requirements.txt). You are using %s instead." % platform.python_version()) exit(1) import argparse @@ -26,7 +26,7 @@ help='Build VCPKG environment from scratch instead of downloading prebuilt one.') parser.add_argument('--vcpkg-archive-url', type=str, - default='https://github.com/OpenDroneMap/windows-deps/releases/download/2.5.0/vcpkg-export-250.zip', + default='https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/vcpkg-export.zip', required=False, help='Path to VCPKG export archive') parser.add_argument('--code-sign-cert-path', @@ -68,6 +68,7 @@ def build(): ebuilder = EnvBuilder(with_pip=True) ebuilder.create("venv") + run("pip install setuptools") run("venv\\Scripts\\pip install --ignore-installed -r requirements.txt") # Download / build VCPKG environment @@ -104,7 +105,7 @@ def build(): toolchain_file = os.path.join(os.getcwd(), "vcpkg", "scripts", "buildsystems", "vcpkg.cmake") run("cmake .. -DCMAKE_TOOLCHAIN_FILE=\"%s\"" % toolchain_file, cwd=build_dir) - run("cmake --build . --config Release", cwd=build_dir) + run("cmake --build . --config Release -j2", cwd=build_dir) def vcpkg_export(): if not os.path.exists("vcpkg"): @@ -155,19 +156,19 @@ def dist(): z.extractall(os.path.join("SuperBuild", "download")) # Download portable python - if not os.path.isdir("python38"): - pythonzip_path = os.path.join("SuperBuild", "download", "python38.zip") - python_url = "https://github.com/OpenDroneMap/windows-deps/releases/download/2.5.0/python-3.8.1-embed-amd64-less-pth.zip" + if not os.path.isdir("python312"): + pythonzip_path = os.path.join("SuperBuild", "download", "python312.zip") + python_url = "https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/python-3.12.10-embed-amd64-less-pth.zip" if not os.path.exists(pythonzip_path): print("Downloading %s" % python_url) with urllib.request.urlopen(python_url) as response, open( pythonzip_path, 'wb') as out_file: shutil.copyfileobj(response, out_file) - os.mkdir("python38") + os.mkdir("python312") - print("Extracting --> python38/") + print("Extracting --> python312/") with zipfile.ZipFile(pythonzip_path) as z: - z.extractall("python38") + z.extractall("python312") # Download signtool signtool_path = os.path.join("SuperBuild", "download", "signtool.exe") diff --git a/configure.sh b/configure.sh index a49a1d9b0..6376c37df 100755 --- a/configure.sh +++ b/configure.sh @@ -6,7 +6,7 @@ APT_GET="env DEBIAN_FRONTEND=noninteractive $(command -v apt-get)" check_version(){ UBUNTU_VERSION=$(lsb_release -r) case "$UBUNTU_VERSION" in - *"20.04"*|*"21.04"*) + *"20.04"*|*"21.04"*|*"24.04"*) echo "Ubuntu: $UBUNTU_VERSION, good!" ;; *"18.04"*|*"16.04"*) @@ -65,9 +65,11 @@ ensure_prereqs() { echo "Installing Python PIP" sudo $APT_GET install -y -qq --no-install-recommends \ python3-pip \ - python3-setuptools - sudo pip3 install -U pip - sudo pip3 install -U shyaml + python3-setuptools \ + python3-venv + python3 -m venv venv --system-site-packages + venv/bin/pip3 install -U pip + venv/bin/pip3 install -U shyaml } # Save all dependencies in snapcraft.yaml to maintain a single source of truth. @@ -84,10 +86,12 @@ installdepsfromsnapcraft() { SNAPCRAFT_FILE="snapcraft.yaml" if [[ "$UBUNTU_VERSION" == *"21.04"* ]]; then SNAPCRAFT_FILE="snapcraft21.yaml" + elif [[ "$UBUNTU_VERSION" == *"24.04"* ]]; then + SNAPCRAFT_FILE="snapcraft24.yaml" fi cat snap/$SNAPCRAFT_FILE | \ - shyaml get-values-0 parts.$section.$key | \ + venv/bin/shyaml get-values-0 parts.$section.$key | \ xargs -0 sudo $APT_GET install -y -qq --no-install-recommends } @@ -129,8 +133,8 @@ installreqs() { set -e # edt requires numpy to build - pip install --ignore-installed numpy==1.23.1 - pip install --ignore-installed -r requirements.txt + venv/bin/pip install numpy==2.3.2 + venv/bin/pip install -r requirements.txt --ignore-installed #if [ ! -z "$GPU_INSTALL" ]; then #fi set +e diff --git a/configure_macos.sh b/configure_macos.sh index 596de7c6a..6918de59d 100755 --- a/configure_macos.sh +++ b/configure_macos.sh @@ -1,4 +1,9 @@ #!/bin/bash + +echo "!!! WARNING! !!!" +echo "!!! This script is not currently maintained and may not work! !!!" +echo "!!! See https://community.opendronemap.org/t/odm-install-on-a-mac-os-14-6-1/25007 !!!" + uname=$(uname) if [[ "$uname" != "Darwin" ]]; then echo "This script is meant for MacOS only." @@ -29,13 +34,13 @@ ensure_prereqs() { installreqs() { ensure_prereqs - brew install cmake gcc@12 python@3.8 tbb@2020 eigen gdal boost cgal libomp + brew install cmake gcc@12 python@3.12 tbb@2020 eigen gdal boost cgal libomp brew link tbb@2020 - python3.8 -m pip install virtualenv + python3.12 -m pip install virtualenv if [ ! -e ${RUNPATH}/venv ]; then - python3.8 -m virtualenv venv + python3.12 -m virtualenv venv fi source venv/bin/activate @@ -51,9 +56,9 @@ install() { cmake .. && make -j$processes cd /tmp - pip download GDAL==3.6.2 - tar -xpzf GDAL-3.6.2.tar.gz - cd GDAL-3.6.2 + pip download GDAL==3.11.1 + tar -xpzf GDAL-3.11.1.tar.gz + cd GDAL-3.11.1 if [ -e /opt/homebrew/bin/gdal-config ]; then python setup.py build_ext --gdal-config /opt/homebrew/bin/gdal-config else @@ -61,7 +66,7 @@ install() { fi python setup.py build python setup.py install - rm -fr /tmp/GDAL-3.6.2 /tmp/GDAL-3.6.2.tar.gz + rm -fr /tmp/GDAL-3.11.1 /tmp/GDAL-3.11.1.tar.gz cd ${RUNPATH} diff --git a/gpu.Dockerfile b/gpu.Dockerfile index c2afc558d..bfd021b0e 100644 --- a/gpu.Dockerfile +++ b/gpu.Dockerfile @@ -1,8 +1,8 @@ -FROM nvidia/cuda:11.8.0-devel-ubuntu20.04 AS builder +FROM nvidia/cuda:13.0.0-devel-ubuntu24.04 AS builder # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" # Prepare directories @@ -14,6 +14,10 @@ COPY . ./ # Run the build RUN PORTABLE_INSTALL=YES GPU_INSTALL=YES bash configure.sh install +# Run the tests +ENV PATH="/code/venv/bin:$PATH" +RUN bash test.sh + # Clean Superbuild RUN bash configure.sh clean @@ -21,11 +25,11 @@ RUN bash configure.sh clean ### Use a second image for the final asset to reduce the number and # size of the layers. -FROM nvidia/cuda:11.8.0-runtime-ubuntu20.04 +FROM nvidia/cuda:13.0.0-devel-ubuntu24.04 # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" \ PDAL_DRIVER_PATH="/code/SuperBuild/install/bin" @@ -34,9 +38,7 @@ WORKDIR /code # Copy everything we built from the builder COPY --from=builder /code /code -# Copy the Python libraries installed via pip from the builder -COPY --from=builder /usr/local /usr/local -#COPY --from=builder /usr/lib/x86_64-linux-gnu/libavcodec.so.58 /usr/lib/x86_64-linux-gnu/libavcodec.so.58 +ENV PATH="/code/venv/bin:$PATH" RUN apt-get update -y \ && apt-get install -y ffmpeg libtbb2 @@ -48,5 +50,6 @@ RUN bash configure.sh installruntimedepsonly \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && bash run.sh --help \ && bash -c "eval $(python3 /code/opendm/context.py) && python3 -c 'from opensfm import io, pymap'" + # Entry point ENTRYPOINT ["python3", "/code/run.py"] diff --git a/innosetup.iss b/innosetup.iss index 3fd651320..bb71f8cc3 100644 --- a/innosetup.iss +++ b/innosetup.iss @@ -47,9 +47,9 @@ Source: "licenses\*"; DestDir: "{app}\licenses"; Flags: ignoreversion recursesub Source: "opendm\*"; DestDir: "{app}\opendm"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "stages\*"; DestDir: "{app}\stages"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "SuperBuild\install\bin\*"; DestDir: "{app}\SuperBuild\install\bin"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs -Source: "SuperBuild\install\lib\python3.8\*"; DestDir: "{app}\SuperBuild\install\lib\python3.8"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "SuperBuild\install\lib\python3.12\*"; DestDir: "{app}\SuperBuild\install\lib\python3.12"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "venv\*"; DestDir: "{app}\venv"; Excludes: "__pycache__,pyvenv.cfg"; Flags: ignoreversion recursesubdirs createallsubdirs -Source: "python38\*"; DestDir: "{app}\venv\Scripts"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "python312\*"; DestDir: "{app}\venv\Scripts"; Excludes: "__pycache__"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "console.bat"; DestDir: "{app}"; Flags: ignoreversion Source: "VERSION"; DestDir: "{app}"; Flags: ignoreversion Source: "LICENSE"; DestDir: "{app}"; Flags: ignoreversion diff --git a/opendm/align.py b/opendm/align.py index a5643cedb..c3f8a520c 100644 --- a/opendm/align.py +++ b/opendm/align.py @@ -113,7 +113,7 @@ def compute_alignment_matrix(input_laz, align_file, stats_dir): 'fine': icp_reg.registration_parameters, }, indent=4)) - matrix = np.fromstring(reg['matrix'], dtype=float, sep=' ').reshape((4, 4)) + matrix = np.fromstring(reg.options['matrix'], dtype=float, sep=' ').reshape((4, 4)) return matrix finally: for f in to_delete: diff --git a/opendm/context.py b/opendm/context.py index 72d8cc068..511e0a7f8 100644 --- a/opendm/context.py +++ b/opendm/context.py @@ -11,8 +11,8 @@ # add opencv,opensfm to python path python_packages_paths = [os.path.join(superbuild_path, p) for p in [ - 'install/lib/python3.9/dist-packages', - 'install/lib/python3.8/dist-packages', + 'install/lib/python3.12/dist-packages', + 'install/lib/python3.12/dist-packages', 'install/lib/python3/dist-packages', 'install/bin/opensfm', ]] diff --git a/opendm/cropper.py b/opendm/cropper.py index 54ccb9ba8..77c69750c 100644 --- a/opendm/cropper.py +++ b/opendm/cropper.py @@ -149,7 +149,7 @@ def create_bounds_geojson(self, pointcloud_path, buffer_distance = 0, decimation boundary_file_path = self.path('boundary.json') - run('pdal info --boundary --filters.hexbin.edge_size=1 --filters.hexbin.threshold=0 "{0}" > "{1}"'.format(decimated_pointcloud_path, boundary_file_path)) + run('pdal info --boundary --filters.hexbin.edge_length=1 --filters.hexbin.threshold=1 "{0}" > "{1}"'.format(decimated_pointcloud_path, boundary_file_path)) pc_geojson_boundary_feature = None diff --git a/opendm/dem/pdal.py b/opendm/dem/pdal.py index 2c0b8e4e1..b38c51045 100644 --- a/opendm/dem/pdal.py +++ b/opendm/dem/pdal.py @@ -164,6 +164,7 @@ def run_pdaltranslate_smrf(fin, fout, scalar, slope, threshold, window): '--filters.smrf.slope=%s' % slope, '--filters.smrf.threshold=%s' % threshold, '--filters.smrf.window=%s' % window, + '--writers.las.forward=scale,offset' ] system.run(' '.join(cmd)) diff --git a/opendm/dls.py b/opendm/dls.py index 7e0bf980a..d552212b0 100644 --- a/opendm/dls.py +++ b/opendm/dls.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python +# coding: utf-8 """ MicaSense Downwelling Light Sensor Utilities @@ -21,36 +23,41 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - import numpy as np + # for DLS correction, we need the sun position at the time the image was taken # this can be computed using the pysolar package (ver 0.6) # https://pypi.python.org/pypi/Pysolar/0.6 # we import multiple times with checking here because the case of Pysolar is # different depending on the python version :( -import imp +# import imp havePysolar = False try: import pysolar.solar as pysolar + havePysolar = True except ImportError: try: import Pysolar.solar as pysolar + havePysolar = True except ImportError: import pysolar.solar as pysolar - havePysolar = True -finally: + + havePysolar = True +finally: if not havePysolar: print("Unable to import pysolar") + def fresnel(phi): - return __multilayer_transmission(phi, n=[1.000277,1.6,1.38]) + return __multilayer_transmission(phi, n=[1.000277, 1.6, 1.38]) + # define functions to compute the DLS-Sun angle: -def __fresnel_transmission(phi, n1=1.000277, n2=1.38, polarization=[.5, .5]): +def __fresnel_transmission(phi, n1=1.000277, n2=1.38, polarization=None): """compute fresnel transmission between media with refractive indices n1 and n2""" # computes the reflection and transmittance # for incidence angles phi for transition from medium @@ -60,36 +67,46 @@ def __fresnel_transmission(phi, n1=1.000277, n2=1.38, polarization=[.5, .5]): # polarization=[.5,.5] - unpolarized light # polarization=[1.,0] - s-polarized light - perpendicular to plane of incidence # polarization=[0,1.] - p-polarized light - parallel to plane of incidence + if polarization is None: + polarization = [.5, .5] f1 = np.cos(phi) - f2 = np.sqrt(1-(n1/n2*np.sin(phi))**2) - Rs = ((n1*f1-n2*f2)/(n1*f1+n2*f2))**2 - Rp = ((n1*f2-n2*f1)/(n1*f2+n2*f1))**2 - T = 1.-polarization[0]*Rs-polarization[1]*Rp - if T > 1: T= 0. - if T < 0: T = 0. - if np.isnan(T): T = 0. + f2 = np.sqrt(1 - (n1 / n2 * np.sin(phi)) ** 2) + Rs = ((n1 * f1 - n2 * f2) / (n1 * f1 + n2 * f2)) ** 2 + Rp = ((n1 * f2 - n2 * f1) / (n1 * f2 + n2 * f1)) ** 2 + T = 1. - polarization[0] * Rs - polarization[1] * Rp + if T > 1: + T = 0. + if T < 0: + T = 0. + if np.isnan(T): + T = 0. return T -def __multilayer_transmission(phi, n, polarization=[.5, .5]): + +def __multilayer_transmission(phi, n, polarization=None): + if polarization is None: + polarization = [.5, .5] T = 1.0 phi_eff = np.copy(phi) - for i in range(0,len(n)-1): + for i in range(0, len(n) - 1): n1 = n[i] - n2 = n[i+1] - phi_eff = np.arcsin(np.sin(phi_eff)/n1) + n2 = n[i + 1] + phi_eff = np.arcsin(np.sin(phi_eff) / n1) T *= __fresnel_transmission(phi_eff, n1, n2, polarization=polarization) return T + # get the position of the sun in North-East-Down (NED) coordinate system -def ned_from_pysolar(sunAzimuth, sunAltitude): +def ned_from_pysolar(sun_azimuth, sun_altitude): """Convert pysolar coordinates to NED coordinates.""" elements = ( - np.cos(sunAzimuth) * np.cos(sunAltitude), - np.sin(sunAzimuth) * np.cos(sunAltitude), - -np.sin(sunAltitude), + np.cos(sun_azimuth) * np.cos(sun_altitude), + np.sin(sun_azimuth) * np.cos(sun_altitude), + -np.sin(sun_altitude), ) return np.array(elements).transpose() + # get the sensor orientation in North-East-Down coordinates # pose is a yaw/pitch/roll tuple of angles measured for the DLS # ori is the 3D orientation vector of the DLS in body coordinates (typically [0,0,-1]) @@ -109,6 +126,7 @@ def get_orientation(pose, ori): n = np.dot(R, ori) return n + # from the current position (lat,lon,alt) tuple # and time (UTC), as well as the sensor orientation (yaw,pitch,roll) tuple # compute a sensor sun angle - this is needed as the actual sun irradiance @@ -119,27 +137,25 @@ def get_orientation(pose, ori): # I_measured = I_direct * (cos (sun_sensor_angle) + 1/6) def compute_sun_angle( - position, - pose, - utc_datetime, - sensor_orientation, + position, + pose, + utc_datetime, + sensor_orientation, ): """ compute the sun angle using pysolar functions""" - altitude = 0 - azimuth = 0 import warnings - with warnings.catch_warnings(): # Ignore pysolar leap seconds offset warning + with warnings.catch_warnings(): # Ignore pysolar leap seconds offset warning warnings.simplefilter("ignore") try: altitude = pysolar.get_altitude(position[0], position[1], utc_datetime) azimuth = pysolar.get_azimuth(position[0], position[1], utc_datetime) - except AttributeError: # catch 0.6 version of pysolar required for python 2.7 support + except AttributeError: # catch 0.6 version of pysolar required for python 2.7 support altitude = pysolar.GetAltitude(position[0], position[1], utc_datetime) - azimuth = 180-pysolar.GetAzimuth(position[0], position[1], utc_datetime) + azimuth = 180 - pysolar.GetAzimuth(position[0], position[1], utc_datetime) sunAltitude = np.radians(np.array(altitude)) sunAzimuth = np.radians(np.array(azimuth)) - sunAzimuth = sunAzimuth % (2 * np.pi ) #wrap range 0 to 2*pi + sunAzimuth = sunAzimuth % (2 * np.pi) # wrap range 0 to 2*pi nSun = ned_from_pysolar(sunAzimuth, sunAltitude) nSensor = np.array(get_orientation(pose, sensor_orientation)) angle = np.arccos(np.dot(nSun, nSensor)) - return nSun, nSensor, angle, sunAltitude, sunAzimuth + return nSun, nSensor, angle, sunAltitude, sunAzimuth \ No newline at end of file diff --git a/opendm/multispectral.py b/opendm/multispectral.py index 953bef6c1..ab1d56c58 100644 --- a/opendm/multispectral.py +++ b/opendm/multispectral.py @@ -592,8 +592,8 @@ def local_normalize(im): disksize = int(width/5) if disksize % 2 == 0: disksize = disksize + 1 - selem = disk(disksize) - im = rank.equalize(im, selem=selem) + footprint = disk(disksize) + im = rank.equalize(im, footprint=footprint) return im diff --git a/opendm/photo.py b/opendm/photo.py index 7144d0694..ac6c6cf08 100644 --- a/opendm/photo.py +++ b/opendm/photo.py @@ -493,7 +493,7 @@ def parse_exif_values(self, _path_file): # for some reason, they don't store band information in EXIFs if self.camera_make.lower() == 'aerovironment' and \ self.camera_model.lower() == 'quantix': - matches = re.match("IMG_(\d+)_(\w+)\.\w+", self.filename, re.IGNORECASE) + matches = re.match(r"IMG_(\d+)_(\w+)\.\w+", self.filename, re.IGNORECASE) if matches: band_aliases = { 'GRN': 'Green', @@ -544,7 +544,7 @@ def extract_focal(self, make, model, tags, xtags): focal = self.float_value(tags["EXIF FocalLength"]) if focal is None and "@aux:Lens" in xtags: lens = self.get_xmp_tag(xtags, ["@aux:Lens"]) - matches = re.search('([\d\.]+)mm', str(lens)) + matches = re.search(r'([\d\.]+)mm', str(lens)) if matches: focal = float(matches.group(1)) diff --git a/portable.Dockerfile b/portable.Dockerfile index 75c9aa117..b0b2eba24 100644 --- a/portable.Dockerfile +++ b/portable.Dockerfile @@ -1,8 +1,8 @@ -FROM ubuntu:21.04 AS builder +FROM ubuntu:24.04 AS builder # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" # Prepare directories @@ -11,12 +11,13 @@ WORKDIR /code # Copy everything COPY . ./ -# Use old-releases for 21.04 -RUN printf "deb http://old-releases.ubuntu.com/ubuntu/ hirsute main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse" > /etc/apt/sources.list - # Run the build RUN PORTABLE_INSTALL=YES bash configure.sh install +# Run the tests +ENV PATH="/code/venv/bin:$PATH" +RUN bash test.sh + # Clean Superbuild RUN bash configure.sh clean @@ -24,11 +25,11 @@ RUN bash configure.sh clean ### Use a second image for the final asset to reduce the number and # size of the layers. -FROM ubuntu:21.04 +FROM ubuntu:24.04 # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.12/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" \ PDAL_DRIVER_PATH="/code/SuperBuild/install/bin" @@ -37,14 +38,11 @@ WORKDIR /code # Copy everything we built from the builder COPY --from=builder /code /code -# Copy the Python libraries installed via pip from the builder -COPY --from=builder /usr/local /usr/local - -# Use old-releases for 21.04 -RUN printf "deb http://old-releases.ubuntu.com/ubuntu/ hirsute main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates main restricted\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates universe\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-updates multiverse\ndeb http://old-releases.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse" > /etc/apt/sources.list +ENV PATH="/code/venv/bin:$PATH" # Install shared libraries that we depend on via APT, but *not* # the -dev packages to save space! +# Also run a smoke test on ODM and OpenSfM RUN bash configure.sh installruntimedepsonly \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ diff --git a/requirements.txt b/requirements.txt index 31f93fa3c..54775b195 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,35 +1,38 @@ appsettings==0.8 -beautifulsoup4==4.9.3 -python-dateutil==2.8.2 -edt==2.0.2 -ODMExifRead==3.0.4 -Fiona==1.8.17 ; sys_platform == 'linux' -Fiona==1.9.1 ; sys_platform == 'darwin' -https://github.com/OpenDroneMap/windows-deps/raw/main/Fiona-1.8.19-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' -joblib==1.1.0 -matplotlib==3.3.3 -numpy==1.23.1 -Pillow==8.3.2 +beautifulsoup4==4.13.4 +python-dateutil==2.9.0 +edt==3.0.0 +ExifRead==3.5.1 +Fiona==1.10.1 ; sys_platform == 'linux' +Fiona==1.10.1 ; sys_platform == 'darwin' +https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/fiona-1.10.1-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' +joblib==1.5.1 +matplotlib==3.10.3 +numpy==2.3.2 +Pillow==11.3.0 vmem==1.0.2 -pyodm==1.5.8 -pyproj==3.3.1 -Pysolar==0.9 -pytz==2020.4 -PyYAML==5.1 -rasterio==1.2.3 ; sys_platform == 'linux' -rasterio==1.3.6 ; sys_platform == 'darwin' -https://github.com/OpenDroneMap/windows-deps/raw/main/rasterio-1.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' -https://github.com/OpenDroneMap/windows-deps/raw/main/GDAL-3.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32' -odmrawpy==0.24.1 +pyodm==1.5.12 +pyproj==3.7.1 +Pysolar==0.13 +pytz==2025.2 +PyYAML==6.0.2 +rasterio==1.4.3 ; sys_platform == 'linux' +rasterio==1.4.3 ; sys_platform == 'darwin' +https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/rasterio-1.4.3-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' +gdal[numpy]==3.8.4 ; sys_platform == 'linux' +gdal[numpy]==3.8.4 ; sys_platform == 'darwin' +https://github.com/OpenDroneMap/windows-deps/releases/download/2.6.0/gdal-3.11.1-cp312-cp312-win_amd64.whl ; sys_platform == 'win32' repoze.lru==0.7 -scikit-learn==1.1.1 -scikit-image==0.19.3 -scipy==1.8.1 -xmltodict==0.12.0 -fpdf2==2.4.6 -Shapely==1.7.1 -onnxruntime==1.12.1 +scikit-learn==1.7.1 +scikit-image==0.25.2 +scipy==1.16.1 +xmltodict==0.14.2 +fpdf2==2.8.3 +Shapely==2.1.1 +onnxruntime==1.22.1 pygltflib==1.16.5 -codem==0.24.0 -trimesh==3.17.1 +packaging==25.0 +codem==0.26.1 +trimesh==4.7.1 piexif==1.1.3 +rawpy==0.25.0 \ No newline at end of file diff --git a/snap/snapcraft24.yaml b/snap/snapcraft24.yaml new file mode 100644 index 000000000..6e3f4d6b4 --- /dev/null +++ b/snap/snapcraft24.yaml @@ -0,0 +1,206 @@ +name: opendronemap +adopt-info: odm +grade: stable +confinement: strict +base: core24 + +summary: Command line toolkit for processing aerial drone imagery +description: > + An open source command line toolkit for processing aerial drone imagery. ODM turns simple 2D images into: + + * Classified Point Clouds + * 3D Textured Models + * Georeferenced Orthorectified Imagery + * Georeferenced Digital Elevation Models + + The application is available for Windows, Mac and Linux and it works from the command line, making it ideal for power users, scripts and for integration with other software. + +# The UbuntuGIS PPA only has i386 and amd64 packages so we can't build any +# other architectures. Therefore let's limit to those here. +architectures: + - build-on: i386 + run-on: i386 + - build-on: amd64 + run-on: amd64 + +package-repositories: + - type: apt + ppa: ubuntugis/ubuntugis-unstable + +parts: + prereqs: + source: . + plugin: nil + build-packages: + - build-essential + - cmake + - gdal-bin + - gfortran # to build scipy + - git + - libgdal-dev + - libgeotiff-dev + - libjsoncpp-dev + - libssl-dev + - libusb-1.0-0-dev + - ninja-build + - pkg-config + - pybind11-dev + - python3-dev + - python3-pip + - python3-setuptools + - python3-wheel + - rsync + - swig3.0 + stage-packages: + - gdal-bin + - libgdal34t64 + - libgeotiff5 + - libjsoncpp25 + - libspqr4 + - libssl3t64 + - libusb-1.0-0 + - proj-data + - procps + - python3 + - python3-pkg-resources # required base package for core20 + - python3-requests # required base package for core20 + - python3-setuptools + stage: + # remove deb-based numpy because it conflicts with our pip-installed version + - -usr/lib/python3/dist-packages/numpy + + opencv: + source: . + plugin: nil + build-packages: + - libavcodec-dev + - libavformat-dev + - libeigen3-dev + - libflann-dev + - libgtk2.0-dev + - libjpeg-dev + - liblapack-dev + - libopenjpip7 + - libpng-dev + - libproj-dev + - libswscale-dev + - libtbb-dev + - libtiff-dev + - libxext-dev + - proj-bin + stage-packages: + - libavcodec60 + - libavformat60 + - libflann1.9 + - libgtk2.0-0 + - libjpeg-turbo8 + - libopenjpip7 + - liblapack3 + - libpng16-16 + - libproj25 + - libswscale7 + - libtbb12 + - libtiff6 + - libwebpdemux2 + - libxext6 + + openmvs: + source: . + plugin: nil + build-packages: + - libcgal-dev + - libboost-program-options-dev + - libboost-iostreams-dev + - libboost-serialization-dev + - libboost-system-dev + stage-packages: + - libboost-program-options1.83.0 + - libboost-iostreams1.83.0 + - libboost-serialization1.83.0 + - libboost-system1.83.0 + + opensfm: + source: . + plugin: nil + build-packages: + - libgoogle-glog-dev + - libsuitesparse-dev + stage-packages: + - libamd3 + - libcamd3 + - libccolamd3 + - libcholmod5 + - libcolamd3 + - libcxsparse4 + - libgoogle-glog0v6t64 + - libsuitesparseconfig7 + + odm: + after: + - prereqs + - opencv + - opensfm + - openmvs + source: . + plugin: nil # We will script everything ourselves + build-environment: + # Set Python location to build host's system so that we can + # use system libraries while building the Snap Package + - PYTHONHOME: /usr + # Set the location for pip to install requirements into inside + # the Snap package + - PYTHONUSERBASE: $SNAPCRAFT_PART_INSTALL + override-build: | + snapcraftctl set-version $(cat VERSION) + + # Portable build + test -f /usr/bin/gcc_real || mv -v /usr/bin/gcc /usr/bin/gcc_real + test -f /usr/bin/gcc || cp -v ./docker/gcc /usr/bin/gcc + test -f /usr/bin/g++_real || mv -v /usr/bin/g++ /usr/bin/g++_real + test -f /usr/bin/g++ || cp -v ./docker/g++ /usr/bin/g++ + + pip3 install --user -r requirements.txt + + # Build the SuperBuild libraries + mkdir -p SuperBuild/build + cd SuperBuild/build + cmake -G Ninja .. + cmake --build . --parallel 1 + + rsync -av --exclude .git \ + $SNAPCRAFT_PART_BUILD/ $SNAPCRAFT_PART_INSTALL/odm/ + chmod -R u=rwX,go=rX $PYTHONUSERBASE/lib/python* + stage: + # strip the temporary build files and sources + - -odm/SuperBuild/build + - -odm/SuperBuild/download + - -odm/SuperBuild/src + prime: + # remove any static-libraries + - -**/*.a + # remove any header files + - -**/*.h + # remove any left-over temporary compiled 'object' files + - -**/*.o + build-snaps: + - cmake + +plugs: + shared-memory: + private: true + +apps: + opendronemap: + command: odm/run.sh + command-chain: + - bin/snapcraft-preload # Fixes multiprocessing python module + environment: + # Ensure libraries are found + LD_LIBRARY_PATH: $SNAP/odm/SuperBuild/install/lib:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/blas:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/lapack + PYTHONPATH: $SNAP/odm/SuperBuild/install/lib/python3.12/site-packages:$SNAP/lib/python3.12/site-packages:$SNAP/usr/lib/python3/dist-packages/:$SNAP/usr/lib/python3.12:$SNAP/odm/SuperBuild/install/bin/opensfm + PROJ_LIB: $SNAP/usr/share/proj + plugs: + - home + - network + - network-bind + - removable-media diff --git a/stages/mvstex.py b/stages/mvstex.py index 6b4b64b12..7b29c19af 100644 --- a/stages/mvstex.py +++ b/stages/mvstex.py @@ -102,6 +102,7 @@ def add_run(nvm_file, primary=True, band=None): 'keepUnseenFaces': keepUnseenFaces, 'toneMapping': 'none', 'nadirMode': nadir, + 'numThreads': '--num_threads=%s' % args.max_concurrency, 'maxTextureSize': '--max_texture_size=%s' % max_texture_size, 'nvm_file': r['nvm_file'], 'intermediate': '--no_intermediate_results' if (r['labeling_file'] or not reconstruction.multi_camera) else '', @@ -124,6 +125,7 @@ def add_run(nvm_file, primary=True, band=None): '{keepUnseenFaces} ' '{nadirMode} ' '{labelingFile} ' + '{numThreads} ' '{maxTextureSize} '.format(**kwargs)) if r['primary'] and (not r['nadir'] or args.skip_3dmodel): diff --git a/tests/test_osfm.py b/tests/test_osfm.py index 0dd337f08..3385364f3 100644 --- a/tests/test_osfm.py +++ b/tests/test_osfm.py @@ -12,54 +12,54 @@ def test_get_submodel_argv(self): args = config.config(["--project-path", "/datasets"]) self.assertEqual(get_submodel_argv(args)[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) self.assertEqual(get_submodel_argv(args, "/submodels", "submodel_0000")[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--project-path', '/submodels', 'submodel_0000']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report', '--project-path', '/submodels', 'submodel_0000']) # Base + project name args = config.config(["--project-path", "/datasets", "brighton"]) self.assertEqual(get_submodel_argv(args)[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) self.assertEqual(get_submodel_argv(args, "/submodels", "submodel_0000")[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--project-path', '/submodels', 'submodel_0000']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report', '--project-path', '/submodels', 'submodel_0000']) # Project name + base args = config.config(["brighton", "--project-path", "/datasets"]) self.assertEqual(get_submodel_argv(args)[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) self.assertEqual(get_submodel_argv(args, "/submodels", "submodel_0000")[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--project-path', '/submodels', 'submodel_0000']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report', '--project-path', '/submodels', 'submodel_0000']) # Crop args = config.config(["brighton", "--project-path", "/datasets", "--crop", "0"]) self.assertEqual(get_submodel_argv(args)[1:], - ['--crop', '0.015625', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--crop', '0.015625', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) self.assertEqual(get_submodel_argv(args, "/submodels", "submodel_0000")[1:], - ['--crop', '0.015625', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--project-path', '/submodels', 'submodel_0000']) + ['--crop', '0.015625', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report', '--project-path', '/submodels', 'submodel_0000']) # With sm-cluster, pc-csv and others args = config.config(["--project-path", "/datasets", "--split", "200", "--pc-csv"]) self.assertEqual(get_submodel_argv(args)[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) self.assertEqual(get_submodel_argv(args, "/submodels", "submodel_0000")[1:], - ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--project-path', '/submodels', 'submodel_0000']) + ['--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report', '--project-path', '/submodels', 'submodel_0000']) # Cameras JSON args = config.config(["--project-path", "/datasets", "--cameras", os.path.join(os.path.dirname(os.path.realpath(__file__)), "assets", "sample.json")]) self.assertEqual(get_submodel_argv(args)[1:], - ['--cameras', '{"test": "1"}', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--cameras', '{"test": "1"}', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) # Camera JSON string args = config.config(["--project-path", "/datasets", "--cameras", '{"test": "1"}']) self.assertEqual(get_submodel_argv(args)[1:], - ['--cameras', '{"test": "1"}', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel']) + ['--cameras', '{"test": "1"}', '--orthophoto-cutline', '--dem-euclidean-map', '--skip-3dmodel', '--skip-report']) def test_get_submodel_argv_dict(self): # Base args = config.config(["--project-path", "/datasets"]) self.assertEqual(get_submodel_args_dict(args), - {'orthophoto-cutline': True, 'skip-3dmodel': True, 'dem-euclidean-map': True}) + {'orthophoto-cutline': True, 'skip-3dmodel': True, 'dem-euclidean-map': True, 'skip-report': True}) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/tests/test_types.py b/tests/test_types.py index 0a0092d33..9427b4416 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -32,13 +32,6 @@ def test_reconstruction(self): for i in range(len(bands)): self.assertEqual(bands[i], recon.multi_camera[i]['name']) self.assertTrue([p.filename for p in recon.multi_camera[0]['photos']] == ['IMG_0298_1.tif', 'IMG_0299_1.tif', 'IMG_0300_1.tif']) - - # Missing a file - micasa_redsense_files = [('IMG_0298_1.tif', 'Red', 1), ('IMG_0298_2.tif', 'Green', 2), ('IMG_0298_3.tif', 'Blue', 3), ('IMG_0298_4.tif', 'NIR', 4), ('IMG_0298_5.tif', 'Rededge', 5), - ('IMG_0299_2.tif', 'Green', 2), ('IMG_0299_3.tif', 'Blue', 3), ('IMG_0299_4.tif', 'NIR', 4), ('IMG_0299_5.tif', 'Rededge', 5), - ('IMG_0300_1.tif', 'Red', 1), ('IMG_0300_2.tif', 'Green', 2), ('IMG_0300_3.tif', 'Blue', 3), ('IMG_0300_4.tif', 'NIR', 4), ('IMG_0300_5.tif', 'Rededge', 5)] - photos = [ODMPhotoMock(f, b, i) for f,b,i in micasa_redsense_files] - self.assertRaises(RuntimeError, types.ODM_Reconstruction, photos) # Single camera dji_files = ['DJI_0018.JPG','DJI_0019.JPG','DJI_0020.JPG','DJI_0021.JPG','DJI_0022.JPG','DJI_0023.JPG'] diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000..526ee675b --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,59 @@ +{ + "dependencies": [ + "eigen3", + "suitesparse", + "lapack", + "tbb", + "glog", + "curl", + "libxml2", + "zlib", + "libpng", + "libjpeg-turbo", + "tiff", + "flann", + "boost-filesystem", + "boost-date-time", + "boost-iostreams", + "boost-foreach", + "boost-signals2", + "boost-interprocess", + "boost-graph", + "boost-asio", + "boost-program-options", + "libgeotiff", + "cgal", + "yasm-tool", + "metis", + "pybind11" + ], + "builtin-baseline": "6ecbbbdf31cba47aafa7cf6189b1e73e10ac61f8", + "overrides": [ + { "name": "eigen3", "version": "3.4.0#5" }, + { "name": "suitesparse", "version": "5.8.0" }, + { "name": "lapack", "version": "2023-06-10#2" }, + { "name": "tbb", "version": "2022.1.0" }, + { "name": "glog", "version": "0.7.1" }, + { "name": "curl", "version": "8.15.0#1" }, + { "name": "libxml2", "version": "2.14.5" }, + { "name": "zlib", "version": "1.3.1" }, + { "name": "libpng", "version": "1.6.50" }, + { "name": "libjpeg-turbo", "version": "3.1.1" }, + { "name": "tiff", "version": "4.7.0" }, + { "name": "flann", "version": "2022-10-28" }, + { "name": "boost-filesystem", "version": "1.88.0" }, + { "name": "boost-date-time", "version": "1.88.0" }, + { "name": "boost-iostreams", "version": "1.88.0" }, + { "name": "boost-foreach", "version": "1.88.0" }, + { "name": "boost-signals2", "version": "1.88.0" }, + { "name": "boost-interprocess", "version": "1.88.0" }, + { "name": "boost-graph", "version": "1.88.0" }, + { "name": "boost-asio", "version": "1.88.0" }, + { "name": "boost-program-options", "version": "1.88.0" }, + { "name": "libgeotiff", "version": "1.7.4" }, + { "name": "cgal", "version": "6.0.1" }, + { "name": "yasm-tool", "version": "2021-12-14" }, + { "name": "metis", "version": "2025-07-04" }, + { "name": "pybind11", "version": "3.0.0#1" } + ] +} \ No newline at end of file diff --git a/winpostinstall.bat b/winpostinstall.bat index d9d549fcd..adaf520c9 100644 --- a/winpostinstall.bat +++ b/winpostinstall.bat @@ -13,6 +13,6 @@ set SBBIN=%ODMBASE%SuperBuild\install\bin set CV2=%WRITABLE_VIRTUAL_ENV%\Lib\site-packages\cv2 mkdir "%CV2%" echo BINARIES_PATHS = [r"%SBBIN%"] + BINARIES_PATHS> "%CV2%\config.py" -echo PYTHON_EXTENSIONS_PATHS = [r'''%VIRTUAL_ENV%\lib\site-packages\cv2\python-3.8'''] + PYTHON_EXTENSIONS_PATHS> "%CV2%\config-3.8.py" +echo PYTHON_EXTENSIONS_PATHS = [r'''%VIRTUAL_ENV%\lib\site-packages\cv2\python-3.12'''] + PYTHON_EXTENSIONS_PATHS> "%CV2%\config-3.12.py" cls \ No newline at end of file