├── .devcontainer ├── Dockerfile ├── devcontainer.json ├── library-scripts │ └── common-debian.sh └── postCreateCommand.sh ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md └── workflows │ └── continuous_integration.yml ├── .gitignore ├── BUILD.md ├── CMakeLists.txt ├── COPYRIGHT.md ├── LICENSE ├── README.md ├── apps ├── CMakeLists.txt ├── DensifyPointCloud │ ├── CMakeLists.txt │ └── DensifyPointCloud.cpp ├── InterfaceCOLMAP │ ├── CMakeLists.txt │ ├── InterfaceCOLMAP.cpp │ └── endian.h ├── InterfaceMVSNet │ ├── CMakeLists.txt │ └── InterfaceMVSNet.cpp ├── InterfaceMetashape │ ├── CMakeLists.txt │ └── InterfaceMetashape.cpp ├── InterfaceOpenMVG │ ├── CMakeLists.txt │ └── InterfaceOpenMVG.cpp ├── InterfacePolycam │ ├── CMakeLists.txt │ └── InterfacePolycam.cpp ├── ReconstructMesh │ ├── CMakeLists.txt │ └── ReconstructMesh.cpp ├── RefineMesh │ ├── CMakeLists.txt │ └── RefineMesh.cpp ├── Tests │ ├── CMakeLists.txt │ ├── Tests.cpp │ └── data │ │ ├── images │ │ ├── 00000.jpg │ │ ├── 00001.jpg │ │ ├── 00002.jpg │ │ └── 00003.jpg │ │ └── scene.mvs ├── TextureMesh │ ├── CMakeLists.txt │ └── TextureMesh.cpp ├── TransformScene │ ├── CMakeLists.txt │ └── TransformScene.cpp └── Viewer │ ├── CMakeLists.txt │ ├── Camera.cpp │ ├── Camera.h │ ├── Common.cpp │ ├── Common.h │ ├── Image.cpp │ ├── Image.h │ ├── Scene.cpp │ ├── Scene.h │ ├── Viewer.cpp │ ├── Viewer.ico │ ├── Window.cpp │ └── Window.h ├── build ├── Modules │ ├── FindBREAKPAD.cmake │ ├── FindEigen3.cmake │ └── FindVCG.cmake ├── Templates │ ├── ConfigLocal.h.in │ ├── OpenMVSConfig.cmake.in │ └── cmake_uninstall.cmake.in └── Utils.cmake ├── docker ├── Dockerfile ├── QUICK_START.sh ├── README.md ├── buildFromScratch.cmd ├── buildFromScratch.sh └── buildInDocker.sh ├── docs └── CMakeLists.txt ├── libs ├── CMakeLists.txt ├── Common │ ├── AABB.h │ ├── AABB.inl │ ├── AutoEstimator.h │ ├── AutoPtr.h │ ├── CMakeLists.txt │ ├── Common.cpp │ ├── Common.h │ ├── Config.h │ ├── ConfigTable.cpp │ ├── ConfigTable.h │ ├── CriticalSection.h │ ├── EventQueue.cpp │ ├── EventQueue.h │ ├── FastDelegate.h │ ├── File.h │ ├── Filters.h │ ├── HalfFloat.h │ ├── Hash.h │ ├── Line.h │ ├── Line.inl │ ├── LinkLib.h │ ├── List.h │ ├── ListFIFO.h │ ├── Log.cpp │ ├── Log.h │ ├── MemFile.h │ ├── OBB.h │ ├── OBB.inl │ ├── Octree.h │ ├── Octree.inl │ ├── Plane.h │ ├── Plane.inl │ ├── Queue.h │ ├── Random.h │ ├── Ray.h │ ├── Ray.inl │ ├── Rotation.h │ ├── Rotation.inl │ ├── SML.cpp │ ├── SML.h │ ├── Sampler.inl │ ├── Semaphore.h │ ├── SharedPtr.h │ ├── Sphere.h │ ├── Sphere.inl │ ├── Streams.h │ ├── Strings.h │ ├── Thread.h │ ├── Timer.cpp │ ├── Timer.h │ ├── Types.cpp │ ├── Types.h │ ├── Types.inl │ ├── Util.cpp │ ├── Util.h │ ├── Util.inl │ ├── UtilCUDA.cpp │ ├── UtilCUDA.h │ └── UtilCUDADevice.h ├── IO │ ├── CMakeLists.txt │ ├── Common.cpp │ ├── Common.h │ ├── Image.cpp │ ├── Image.h │ ├── ImageBMP.cpp │ ├── ImageBMP.h │ ├── ImageDDS.cpp │ ├── ImageDDS.h │ ├── ImageJPG.cpp │ ├── ImageJPG.h │ ├── ImageJXL.cpp │ ├── ImageJXL.h │ ├── ImagePNG.cpp │ ├── ImagePNG.h │ ├── ImageSCI.cpp │ ├── ImageSCI.h │ ├── ImageTGA.cpp │ ├── ImageTGA.h │ ├── ImageTIFF.cpp │ ├── ImageTIFF.h │ ├── OBJ.cpp │ ├── OBJ.h │ ├── PLY.cpp │ ├── PLY.h │ ├── TinyXML2.cpp │ ├── TinyXML2.h │ ├── json.hpp │ └── tiny_gltf.h ├── MVS.h ├── MVS │ ├── CMakeLists.txt │ ├── CUDA │ │ ├── Camera.h │ │ └── Maths.h │ ├── Camera.cpp │ ├── Camera.h │ ├── Common.cpp │ ├── Common.h │ ├── DMapCache.cpp │ ├── DMapCache.h │ ├── DepthMap.cpp │ ├── DepthMap.h │ ├── Image.cpp │ ├── Image.h │ ├── Interface.h │ ├── Mesh.cpp │ ├── Mesh.h │ ├── PatchMatchCUDA.cpp │ ├── PatchMatchCUDA.cu │ ├── PatchMatchCUDA.h │ ├── PatchMatchCUDA.inl │ ├── Platform.cpp │ ├── Platform.h │ ├── PointCloud.cpp │ ├── PointCloud.h │ ├── PythonWrapper.cpp │ ├── RectsBinPack.cpp │ ├── RectsBinPack.h │ ├── Scene.cpp │ ├── Scene.h │ ├── SceneDensify.cpp │ ├── SceneDensify.h │ ├── SceneReconstruct.cpp │ ├── SceneRefine.cpp │ ├── SceneRefineCUDA.cpp │ ├── SceneTexture.cpp │ ├── SemiGlobalMatcher.cpp │ └── SemiGlobalMatcher.h └── Math │ ├── CMakeLists.txt │ ├── Common.cpp │ ├── Common.h │ ├── IBFS │ ├── IBFS.cpp │ ├── IBFS.h │ └── license.txt │ ├── LBP.h │ ├── LMFit │ ├── CHANGELOG │ ├── COPYING │ ├── lmmin.cpp │ └── lmmin.h │ ├── RobustNorms.h │ ├── RobustNorms.png │ ├── SimilarityTransform.cpp │ └── SimilarityTransform.h ├── scripts └── python │ ├── ImageSegmentation.py │ ├── ImportDMAPs.py │ ├── MvgMvsPipeline.py │ ├── MvgOptimizeSfM.py │ ├── MvsDMAP2TSDF.py │ ├── MvsReadDMAP.py │ ├── MvsReadMVS.py │ ├── MvsScalablePipeline.py │ └── MvsUtils.py └── vcpkg.json /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | ARG USERNAME=openmvs 4 | ARG USER_UID=1000 5 | ARG USER_GID=$USER_UID 6 | ARG INSTALL_ZSH="true" 7 | 8 | # Prepare and empty machine for building: 9 | RUN apt-get update -yq 10 | 11 | COPY .devcontainer/library-scripts/*.sh /tmp/library-scripts/ 12 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 13 | && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true"\ 14 | # 15 | # **************************************************************************** 16 | # * TODO: Add any additional OS packages you want included in the definition * 17 | # * here. We want to do this before cleanup to keep the "layer" small. * 18 | # **************************************************************************** 19 | # && apt-get -y install --no-install-recommends <your-package-list-here> \ 20 | # 21 | && apt-get -y install --no-install-recommends build-essential git cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev libglew-dev libglfw3-dev \ 22 | # Boost 23 | libboost-iostreams-dev libboost-program-options-dev libboost-system-dev libboost-serialization-dev \ 24 | # OpenCV 25 | libopencv-dev \ 26 | # CGAL 27 | libcgal-dev libcgal-qt5-dev \ 28 | && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts 29 | 30 | # Eigen 31 | RUN git clone https://gitlab.com/libeigen/eigen --branch 3.4 32 | RUN mkdir eigen_build 33 | RUN cd eigen_build &&\ 34 | cmake . ../eigen &&\ 35 | make && make install &&\ 36 | cd .. 37 | 38 | # VCGLib 39 | RUN git clone https://github.com/cdcseacave/VCG.git vcglib 40 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/cpp 3 | { 4 | "name": "OpenMVS", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | "context": ".." 8 | }, 9 | // Features to add to the dev container. More info: https://containers.dev/features. 10 | // "features": {}, 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [], 13 | // Use 'postCreateCommand' to run commands after the container is created. 14 | "postCreateCommand": "./.devcontainer/postCreateCommand.sh", 15 | // Configure tool-specific properties. 16 | "customizations": { 17 | "vscode": { 18 | "extensions": [ 19 | "ms-vscode.cpptools", 20 | "ms-vscode.cmake-tools", 21 | "twxs.cmake", 22 | "josetr.cmake-language-support-vscode" 23 | ] 24 | } 25 | }, 26 | "containerEnv": { 27 | "DISPLAY": "unix:0" 28 | }, 29 | "remoteEnv": { 30 | "PATH": "/usr/local/bin/OpenMVS:${containerEnv:PATH}" 31 | }, 32 | "mounts": [ 33 | "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached" 34 | ], 35 | "features": { 36 | "ghcr.io/devcontainers/features/sshd:1": { 37 | "version": "latest" 38 | } 39 | }, 40 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 41 | "remoteUser": "openmvs" 42 | } -------------------------------------------------------------------------------- /.devcontainer/postCreateCommand.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf openMVS_build && mkdir openMVS_build 4 | 5 | cd openMVS_build &&\ 6 | cmake .. -DCMAKE_BUILD_TYPE=Release -DVCG_ROOT=/vcglib 7 | 8 | # add below args for CUDA, refer docker/buildInDocker.sh for base container and additional stuff required 9 | # -DOpenMVS_USE_CUDA=ON -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs/ -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda/ -DCUDA_INCLUDE_DIRS=/usr/local/cuda/include/ -DCUDA_CUDART_LIBRARY=/usr/local/cuda/lib64 -DCUDA_NVCC_EXECUTABLE=/usr/local/cuda/bin/ 10 | 11 | # Install OpenMVS library 12 | make -j && sudo make install -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ensure shell scripts uses the correct line ending. 2 | Dockerfile eol=lf 3 | *.sh eol=lf 4 | *.bat eol=crlf 5 | *.cmd eol=crlf 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [cdcseacave] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. Use `Viewer` to verify/display the input/output. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/continuous_integration.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | run-name: ${{ github.actor }} is building OpenMVS 3 | 4 | on: 5 | push: 6 | branches: [master, develop] 7 | pull_request: 8 | branches: [master, develop] 9 | # Allows to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | env: 13 | CTEST_OUTPUT_ON_FAILURE: 1 14 | 15 | defaults: 16 | run: 17 | shell: bash 18 | 19 | jobs: 20 | build-tests: 21 | name: Build on ${{ matrix.os }} 22 | runs-on: ${{ matrix.os }} 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | os: [ubuntu-latest, macOS-latest, windows-latest] 27 | include: 28 | - os: windows-latest 29 | triplet: x64-windows-release 30 | build-type: Release 31 | - os: ubuntu-latest 32 | triplet: x64-linux-release 33 | build-type: Release 34 | - os: macos-latest 35 | triplet: arm64-osx 36 | build-type: Release 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v4 40 | 41 | - name: Restore artifacts, or setup vcpkg for building artifacts 42 | uses: lukka/run-vcpkg@v11 43 | with: 44 | vcpkgDirectory: '${{ github.workspace }}/vcpkg' 45 | vcpkgGitCommitId: 'ef7dbf94b9198bc58f45951adcf1f041fcbc5ea0' 46 | 47 | - name: Install Ubuntu dependencies 48 | if: matrix.os == 'ubuntu-latest' 49 | run: | 50 | sudo apt-get update -y 51 | sudo apt-get install -y autoconf-archive libxmu-dev libdbus-1-dev libxtst-dev libxi-dev libxinerama-dev libxcursor-dev xorg-dev libgl-dev libglu1-mesa-dev autoconf automake bison libtool libltdl-dev pkg-config ninja-build 52 | 53 | - name: Install macOS dependencies 54 | if: matrix.os == 'macOS-latest' 55 | run: | 56 | brew install automake autoconf autoconf-archive libtool ninja 57 | 58 | - name: Configure CMake for Windows 59 | if: matrix.os == 'windows-latest' 60 | run: | 61 | cmake -S . -B make -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} -DOpenMVS_USE_CUDA=OFF 62 | 63 | - name: Configure CMake for Ubuntu and macOS 64 | if: matrix.os != 'windows-latest' 65 | run: | 66 | cmake -S . -B make -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} -DOpenMVS_USE_CUDA=OFF -G Ninja 67 | 68 | - name: Build 69 | working-directory: ./make 70 | run: | 71 | rm -rf ../vcpkg/buildtrees 72 | rm -rf ../vcpkg/downloads 73 | cmake --build . --config ${{ matrix.build-type }} --parallel $(nproc) 74 | 75 | - name: Unit Tests 76 | working-directory: ./make 77 | run: | 78 | ctest -j$(nproc) --build-config ${{ matrix.build-type }} 79 | 80 | - name: Deploy Windows release 81 | if: matrix.os == 'windows-latest' 82 | uses: actions/upload-artifact@v4 83 | with: 84 | name: OpenMVS_Windows_Release_x64 85 | path: | 86 | ${{ github.workspace }}/make/bin/**/x64 87 | !${{ github.workspace }}/make/bin/**/*.exp 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Custom 31 | *.tmp 32 | .DS_Store 33 | CMakeSettings.json 34 | .vs/ 35 | .idea/ 36 | .vscode/ 37 | out/ 38 | bin*/ 39 | make*/ 40 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | ------------ 2 | Dependencies 3 | ------------ 4 | 5 | *OpenMVS* relies on a number of open source libraries, some optional, which are managed automatically by [vcpkg](https://github.com/Microsoft/vcpkg). For details on customizing the build process, see the build instructions. 6 | * [Eigen](http://eigen.tuxfamily.org) version 3.4 or higher 7 | * [OpenCV](http://opencv.org) version 2.4 or higher 8 | * [Ceres](http://ceres-solver.org) version 1.10 or higher (optional) 9 | * [CGAL](http://www.cgal.org) version 4.2 or higher 10 | * [Boost](http://www.boost.org) version 1.56 or higher 11 | * [VCG](http://vcg.isti.cnr.it/vcglib) 12 | * [CUDA](https://developer.nvidia.com/cuda-downloads) (optional) 13 | * [GLFW](http://www.glfw.org) (optional) 14 | 15 | ------------------ 16 | Build instructions 17 | ------------------ 18 | 19 | Required tools: 20 | * [CMake](http://www.cmake.org) 21 | * [git](https://git-scm.com) 22 | * C/C++ compiler like Visual Studio 2019, GCC or Clang 23 | 24 | The dependencies can be fetched and built automatically using `vcpkg` on all major platform, by setting the environment variable `VCPKG_ROOT` to point to its path or by using the `cmake` parameter `-DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake`. 25 | 26 | The latest pre-built stable binaries can be download from [here](https://github.com/cdcseacave/openMVS_sample/releases/latest). 27 | 28 | ``` 29 | #Clone OpenMVS 30 | git clone --recurse-submodules https://github.com/cdcseacave/openMVS.git 31 | 32 | #Make build directory: 33 | cd openMVS 34 | mkdir make 35 | cd make 36 | 37 | #Run CMake: 38 | cmake .. 39 | 40 | #Build: 41 | cmake --build . -j4 42 | 43 | #Install OpenMVS library (optional): 44 | cmake --install . 45 | ``` 46 | 47 | ------------------- 48 | Library usage 49 | ------------------- 50 | 51 | In order to use *OpenMVS* as a third-party library in your project, first compile it as described above or simply use `vcpgk`: 52 | ``` 53 | vcpkg install openmvs 54 | ``` 55 | 56 | Inside your project CMake script, use: 57 | ``` 58 | find_package(OpenMVS) 59 | if(OpenMVS_FOUND) 60 | include_directories(${OpenMVS_INCLUDE_DIRS}) 61 | add_definitions(${OpenMVS_DEFINITIONS}) 62 | endif() 63 | 64 | add_executable(your_project source_code.cpp) 65 | target_link_libraries(your_project PRIVATE OpenMVS::MVS) 66 | ``` 67 | 68 | ------------------- 69 | Python API 70 | ------------------- 71 | 72 | The Python API can be enable by setting the `OpenMVS_USE_PYTHON` option to `ON` when running `cmake`. The Python API is built as a shared library and can be used in any Python project. Example: 73 | ``` 74 | import pyOpenMVS 75 | 76 | def run_mvs(): 77 | # set the working folder; all files used next are relative to this folder (optional) 78 | pyOpenMVS.set_working_folder("folder/containing/the/scene") 79 | # create an empty scene 80 | scene = pyOpenMVS.Scene() 81 | # load a MVS scene from a file 82 | if not scene.load("scene.mvs"): 83 | print("ERROR: scene could not be loaded") 84 | return 85 | # estimate depth-maps and fuse them into a point-cloud 86 | if not scene.dense_reconstruction(): 87 | print("ERROR: could not dense reconstruct the scene") 88 | return 89 | scene.save_pointcloud("pointcloud.ply") 90 | # reconstruct a mesh from the point-cloud 91 | if not scene.reconstruct_mesh(): 92 | print("ERROR: could not reconstruct the mesh for this scene") 93 | return 94 | scene.save_mesh("mesh.ply") 95 | # refine the mesh using gradient descent optimization (optional) 96 | if not scene.refine_mesh(): 97 | print("ERROR: could not refine the mesh for this scene") 98 | return 99 | scene.save_mesh("refined_mesh.ply") 100 | # texture the mesh using the input images 101 | if not scene.texture_mesh(): 102 | print("ERROR: could not texture the mesh for this scene") 103 | return 104 | scene.save_mesh("textured_mesh.ply") 105 | 106 | if __name__ == "__main__": 107 | run_mvs() 108 | ``` 109 | -------------------------------------------------------------------------------- /COPYRIGHT.md: -------------------------------------------------------------------------------- 1 | ## OpenMVS License 2 | 3 | * __OpenMVS__<br /> 4 | [http://cdcseacave.github.io/openMVS](http://cdcseacave.github.io/openMVS) 5 | Copyright (c) OpenMVS authors 6 | Licensed under the [AGPL](http://opensource.org/licenses/AGPL-3.0) license. 7 | 8 | ## Included third parties license details 9 | 10 | This program includes works distributed under the terms of another license(s) and other copyright notice(s). 11 | 12 | * __SeaCave__<br /> 13 | Copyright (c) 2007 SEACAVE SRL. 14 | Licensed under a [Boost license](http://www.boost.org/users/license.html). 15 | 16 | * __histogram__<br /> 17 | Copyright (c) Jansson Consulting & Pierre Moulon. 18 | Licensed under the [MPL2 license](http://opensource.org/licenses/MPL-2.0). 19 | 20 | * __ACRANSAC__<br /> 21 | Copyright (c) Pierre Moulon. 22 | Licensed under the [MPL2 license](http://opensource.org/licenses/MPL-2.0). 23 | 24 | * __rectangle-bin-packing__<br /> 25 | [http://clb.demon.fi/projects/rectangle-bin-packing](http://clb.demon.fi/projects/rectangle-bin-packing) 26 | Copyright (c) Jukka Jylänki. 27 | Released to Public Domain, do whatever you want with it. 28 | 29 | * __ceres-solver__<br /> 30 | [http://ceres-solver.org](http://ceres-solver.org) 31 | Copyright 2015 Google Inc. All rights reserved. 32 | Licensed under the [New BSD license](http://ceres-solver.org/license.html). 33 | 34 | * __lmfit__<br /> 35 | [http://apps.jcns.fz-juelich.de/doku/sc/lmfit](http://apps.jcns.fz-juelich.de/doku/sc/lmfit) 36 | Copyright (c) Joachim Wuttke. 37 | Licensed under the [FreeBSD license](http://opensource.org/licenses/BSD-2-Clause). 38 | 39 | * __ibfs__<br /> 40 | [http://www.cs.tau.ac.il/~sagihed/ibfs](http://www.cs.tau.ac.il/~sagihed/ibfs) 41 | Copyright (c) Haim Kaplan and Sagi Hed. 42 | This software can be used for research purposes only. 43 | 44 | * __loopy-belief-propagation__<br /> 45 | [https://github.com/nmoehrle/mvs-texturing](https://github.com/nmoehrle/mvs-texturing) 46 | Copyright (c) Michael Waechter. 47 | Licensed under the [BSD 3-Clause license](http://opensource.org/licenses/BSD-3-Clause). 48 | 49 | * __eigen__<br /> 50 | [http://eigen.tuxfamily.org](http://eigen.tuxfamily.org) 51 | Copyright (c) Eigen authors. 52 | Distributed under the [MPL2 license](http://opensource.org/licenses/MPL-2.0). 53 | Compiled with EIGEN_MPL2_ONLY to ensure MPL2 compatible code. 54 | 55 | * __OpenCV__<br /> 56 | [http://opencv.org](http://opencv.org) 57 | Copyright (c) 2015, Itseez. 58 | Licensed under the [BSD license](http://opensource.org/licenses/bsd-license.php). 59 | 60 | * __Boost__<br /> 61 | [http://www.boost.org](http://www.boost.org) 62 | Copyright Beman Dawes, David Abrahams, 1998-2005. 63 | Copyright Rene Rivera 2004-2007. 64 | Licensed under a [Boost license](http://www.boost.org/users/license.html). 65 | 66 | * __CGAL__<br /> 67 | [http://www.cgal.org](http://www.cgal.org) 68 | Copyright (c) 1995-2015 The CGAL Project. All rights reserved. 69 | Licensed under the [GPL](http://www.gnu.org/copyleft/gpl.html)/[LGPL license](http://www.gnu.org/copyleft/lesser.html). 70 | 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenMVS: open Multi-View Stereo reconstruction library 2 | 3 | [](https://sketchfab.com/models/3aedcdd22c31447199c18dd9aec5d952/embed) 4 | 5 | ## Introduction 6 | 7 | [OpenMVS (Multi-View Stereo)](http://cdcseacave.github.io/openMVS) is a library for computer-vision scientists and especially targeted to the Multi-View Stereo reconstruction community. While there are mature and complete open-source projects targeting Structure-from-Motion pipelines (like [OpenMVG](https://github.com/openMVG/openMVG)) which recover camera poses and a sparse 3D point-cloud from an input set of images, there are none addressing the last part of the photogrammetry chain-flow. *OpenMVS* aims at filling that gap by providing a complete set of algorithms to recover the full surface of the scene to be reconstructed. The input is a set of camera poses plus the sparse point-cloud and the output is a textured mesh. The main topics covered by this project are: 8 | 9 | - **dense point-cloud reconstruction** for obtaining a complete and accurate as possible point-cloud 10 | - **mesh reconstruction** for estimating a mesh surface that explains the best the input point-cloud 11 | - **mesh refinement** for recovering all fine details 12 | - **mesh texturing** for computing a sharp and accurate texture to color the mesh 13 | 14 | See the complete [documentation](https://github.com/cdcseacave/openMVS/wiki) on wiki. 15 | 16 | ## Build 17 | 18 | See the [building](https://github.com/cdcseacave/openMVS/wiki/Building) wiki page. Windows, Ubuntu and MacOS x64 continuous integration status [](https://github.com/cdcseacave/openMVS/actions/workflows/continuous_integration.yml) 19 | Automatic Windows x64 binary builds can be found for each commit on its Artifacts page. 20 | 21 | ## Example 22 | 23 | See the usage [example](https://github.com/cdcseacave/openMVS/wiki/Usage) wiki page. 24 | 25 | ## License 26 | 27 | See the [copyright](https://github.com/cdcseacave/openMVS/blob/master/COPYRIGHT.md) file. 28 | 29 | ## Contact 30 | 31 | openmvs[AT]googlegroups.com 32 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add applications 2 | ADD_SUBDIRECTORY(InterfaceCOLMAP) 3 | ADD_SUBDIRECTORY(InterfaceMetashape) 4 | ADD_SUBDIRECTORY(InterfaceMVSNet) 5 | ADD_SUBDIRECTORY(InterfacePolycam) 6 | ADD_SUBDIRECTORY(DensifyPointCloud) 7 | ADD_SUBDIRECTORY(ReconstructMesh) 8 | ADD_SUBDIRECTORY(RefineMesh) 9 | ADD_SUBDIRECTORY(TextureMesh) 10 | ADD_SUBDIRECTORY(TransformScene) 11 | ADD_SUBDIRECTORY(Viewer) 12 | if(OpenMVS_ENABLE_TESTS) 13 | ADD_SUBDIRECTORY(Tests) 14 | endif() 15 | -------------------------------------------------------------------------------- /apps/DensifyPointCloud/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(DensifyPointCloud) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(DensifyPointCloud "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS DensifyPointCloud 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/InterfaceCOLMAP/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(InterfaceCOLMAP) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(InterfaceCOLMAP "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS InterfaceCOLMAP 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/InterfaceMVSNet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(InterfaceMVSNet) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(InterfaceMVSNet "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS InterfaceMVSNet 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/InterfaceMetashape/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(InterfaceMetashape) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(InterfaceMetashape "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS InterfaceMetashape 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/InterfaceOpenMVG/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(OpenMVG QUIET) 2 | IF (OPENMVG_FOUND) 3 | INCLUDE_DIRECTORIES(${OPENMVG_INCLUDE_DIRS}) 4 | add_definitions(-D_USE_OPENMVG) 5 | set(LIBS_DEPEND "MVS;${OPENMVG_LIBRARIES}") 6 | ELSE() 7 | set(LIBS_DEPEND "MVS") 8 | MESSAGE("OPENMVG_NOT FOUND : OpenMVG importer with JSON support will not be build") 9 | ENDIF() 10 | 11 | if(MSVC) 12 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "*.rc") 13 | else() 14 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 15 | endif() 16 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 17 | 18 | cxx_executable_with_flags(InterfaceOpenMVG "Apps" "${cxx_default}" "${LIBS_DEPEND};${OpenMVS_EXTRA_LIBS}" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 19 | 20 | # Install 21 | INSTALL(TARGETS InterfaceOpenMVG 22 | EXPORT OpenMVSTargets 23 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 24 | -------------------------------------------------------------------------------- /apps/InterfacePolycam/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(InterfacePolycam) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(InterfacePolycam "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS InterfacePolycam 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/ReconstructMesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(ReconstructMesh) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(ReconstructMesh "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS ReconstructMesh 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/RefineMesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(RefineMesh) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(RefineMesh "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS RefineMesh 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/Tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(Tests) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | ADD_DEFINITIONS(-D_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data/") 10 | 11 | cxx_executable_with_flags(Tests "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 12 | 13 | # Install 14 | INSTALL(TARGETS Tests 15 | EXPORT OpenMVSTargets 16 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 17 | -------------------------------------------------------------------------------- /apps/Tests/Tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Tests.cpp 3 | * 4 | * Copyright (c) 2014-2021 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #include "../../libs/MVS/Common.h" 33 | #include "../../libs/MVS/Scene.h" 34 | 35 | using namespace MVS; 36 | 37 | 38 | // D E F I N E S /////////////////////////////////////////////////// 39 | 40 | #define APPNAME _T("Tests") 41 | 42 | 43 | // S T R U C T S /////////////////////////////////////////////////// 44 | 45 | // test various algorithms independently 46 | bool UnitTests() 47 | { 48 | TD_TIMER_START(); 49 | if (!SEACAVE::cListTest<true>(100)) { 50 | VERBOSE("ERROR: cListTest failed!"); 51 | return false; 52 | } 53 | if (!SEACAVE::OctreeTest<double,2>(100)) { 54 | VERBOSE("ERROR: OctreeTest<double,2> failed!"); 55 | return false; 56 | } 57 | if (!SEACAVE::OctreeTest<float,3>(100)) { 58 | VERBOSE("ERROR: OctreeTest<float,3> failed!"); 59 | return false; 60 | } 61 | if (!SEACAVE::TestRayTriangleIntersection<float>(1000)) { 62 | VERBOSE("ERROR: TestRayTriangleIntersection<float> failed!"); 63 | return false; 64 | } 65 | if (!SEACAVE::TestRayTriangleIntersection<double>(1000)) { 66 | VERBOSE("ERROR: TestRayTriangleIntersection<double> failed!"); 67 | return false; 68 | } 69 | VERBOSE("All unit tests passed (%s)", TD_TIMER_GET_FMT().c_str()); 70 | return true; 71 | } 72 | 73 | 74 | // test MVS stages on a small sample dataset 75 | bool PipelineTest(bool verbose=false) 76 | { 77 | TD_TIMER_START(); 78 | #if 0 && defined(_USE_CUDA) 79 | // force CPU for testing even if CUDA is available 80 | SEACAVE::CUDA::desiredDeviceID = -2; 81 | #endif 82 | Scene scene; 83 | if (!scene.Load(MAKE_PATH("scene.mvs"))) { 84 | VERBOSE("ERROR: TestDataset failed loading the scene!"); 85 | return false; 86 | } 87 | OPTDENSE::init(); 88 | OPTDENSE::bRemoveDmaps = true; 89 | if (!scene.DenseReconstruction() || scene.pointcloud.GetSize() < 50000u) { 90 | VERBOSE("ERROR: TestDataset failed estimating dense point-cloud!"); 91 | return false; 92 | } 93 | if (verbose) 94 | scene.pointcloud.Save(MAKE_PATH("scene_dense.ply")); 95 | if (!scene.ReconstructMesh() || scene.mesh.faces.size() < 25000u) { 96 | VERBOSE("ERROR: TestDataset failed reconstructing the mesh!"); 97 | return false; 98 | } 99 | if (verbose) 100 | scene.mesh.Save(MAKE_PATH("scene_dense_mesh.ply")); 101 | constexpr float decimate = 0.7f; 102 | scene.mesh.Clean(decimate); 103 | if (!ISINSIDE(scene.mesh.faces.size(), 18000u, 30000u)) { 104 | VERBOSE("ERROR: TestDataset failed cleaning the mesh!"); 105 | return false; 106 | } 107 | #ifdef _USE_OPENMP 108 | TestMeshProjectionMT(scene.mesh, scene.images[1]); 109 | #endif 110 | if (!scene.TextureMesh(0, 0) || !scene.mesh.HasTexture()) { 111 | VERBOSE("ERROR: TestDataset failed texturing the mesh!"); 112 | return false; 113 | } 114 | if (verbose) 115 | scene.mesh.Save(MAKE_PATH("scene_dense_mesh_texture.ply")); 116 | VERBOSE("All pipeline stages passed (%s)", TD_TIMER_GET_FMT().c_str()); 117 | return true; 118 | } 119 | 120 | // test OpenMVS functionality 121 | int main(int argc, LPCTSTR* argv) 122 | { 123 | OPEN_LOG(); 124 | OPEN_LOGCONSOLE(); 125 | MVS::Initialize(APPNAME); 126 | WORKING_FOLDER = _DATA_PATH; 127 | INIT_WORKING_FOLDER; 128 | if (argc < 2 || std::atoi(argv[1]) == 0) { 129 | if (!UnitTests()) 130 | return EXIT_FAILURE; 131 | } else { 132 | if (!PipelineTest()) 133 | return EXIT_FAILURE; 134 | } 135 | MVS::Finalize(); 136 | CLOSE_LOGCONSOLE(); 137 | CLOSE_LOG(); 138 | return EXIT_SUCCESS; 139 | } 140 | /*----------------------------------------------------------------*/ 141 | -------------------------------------------------------------------------------- /apps/Tests/data/images/00000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Tests/data/images/00000.jpg -------------------------------------------------------------------------------- /apps/Tests/data/images/00001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Tests/data/images/00001.jpg -------------------------------------------------------------------------------- /apps/Tests/data/images/00002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Tests/data/images/00002.jpg -------------------------------------------------------------------------------- /apps/Tests/data/images/00003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Tests/data/images/00003.jpg -------------------------------------------------------------------------------- /apps/Tests/data/scene.mvs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Tests/data/scene.mvs -------------------------------------------------------------------------------- /apps/TextureMesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(TextureMesh) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(TextureMesh "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS TextureMesh 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/TransformScene/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | create_rc_files(TransformScene) 3 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 4 | else() 5 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 6 | endif() 7 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 8 | 9 | cxx_executable_with_flags(TransformScene "Apps" "${cxx_default}" "MVS" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 10 | 11 | # Install 12 | INSTALL(TARGETS TransformScene 13 | EXPORT OpenMVSTargets 14 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 15 | -------------------------------------------------------------------------------- /apps/Viewer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT VIEWER_NAME) 2 | set(VIEWER_NAME "Viewer") 3 | endif() 4 | 5 | # Find required packages 6 | FIND_PACKAGE(glad QUIET) 7 | if(glad_FOUND) 8 | MESSAGE(STATUS "GLAD ${glad_VERSION} found") 9 | else() 10 | MESSAGE("-- Can't find GLAD. Continuing without it.") 11 | RETURN() 12 | endif() 13 | FIND_PACKAGE(glfw3 QUIET) 14 | if(glfw3_FOUND) 15 | MESSAGE(STATUS "GLFW3 ${glfw3_VERSION} found") 16 | else() 17 | MESSAGE("-- Can't find GLFW3. Continuing without it.") 18 | RETURN() 19 | endif() 20 | 21 | # List sources files 22 | if(MSVC) 23 | create_rc_files(${VIEWER_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/Viewer.ico") 24 | FILE(GLOB LIBRARY_FILES_C "*.cpp" "${CMAKE_CURRENT_BINARY_DIR}/*.rc") 25 | else() 26 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 27 | endif() 28 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 29 | 30 | cxx_executable_with_flags(${VIEWER_NAME} "Apps" "${cxx_default}" "MVS;glad::glad;${GLFW_STATIC_LIBRARIES};${glfw3_LIBRARY};${GLFW3_LIBRARY};glfw" ${LIBRARY_FILES_C} ${LIBRARY_FILES_H}) 31 | 32 | # Manually set Common.h as the precompiled header 33 | IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) 34 | TARGET_PRECOMPILE_HEADERS(${VIEWER_NAME} PRIVATE "Common.h") 35 | endif() 36 | 37 | # Install 38 | INSTALL(TARGETS ${VIEWER_NAME} 39 | EXPORT OpenMVSTargets 40 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin) 41 | -------------------------------------------------------------------------------- /apps/Viewer/Camera.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Camera.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _VIEWER_CAMERA_H_ 33 | #define _VIEWER_CAMERA_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | 39 | // D E F I N E S /////////////////////////////////////////////////// 40 | 41 | 42 | // S T R U C T S /////////////////////////////////////////////////// 43 | 44 | namespace VIEWER { 45 | 46 | class Camera 47 | { 48 | public: 49 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW 50 | 51 | cv::Size size; 52 | AABB3d boxScene; 53 | Eigen::Vector3d centerScene; 54 | Eigen::Quaterniond rotation; 55 | Eigen::Vector3d center; 56 | double dist, radius; 57 | float fov, fovDef; 58 | float scaleF, scaleFDef; 59 | MVS::IIndex prevCamID, currentCamID, maxCamID; 60 | 61 | public: 62 | Camera(const AABB3d& _box=AABB3d(true), const Point3d& _center=Point3d::ZERO, float _scaleF=1, float _fov=40); 63 | 64 | void Reset(); 65 | void Resize(const cv::Size&); 66 | void SetFOV(float _fov); 67 | 68 | const cv::Size& GetSize() const { return size; } 69 | 70 | Eigen::Vector3d GetPosition() const; 71 | Eigen::Matrix3d GetRotation() const; 72 | Eigen::Matrix4d GetLookAt() const; 73 | 74 | void GetLookAt(Eigen::Vector3d& eye, Eigen::Vector3d& center, Eigen::Vector3d& up) const; 75 | void Rotate(const Eigen::Vector2d& pos, const Eigen::Vector2d& prevPos); 76 | void Translate(const Eigen::Vector2d& pos, const Eigen::Vector2d& prevPos); 77 | 78 | bool IsCameraViewMode() const { return prevCamID != currentCamID && currentCamID != NO_ID; } 79 | 80 | protected: 81 | void ProjectOnSphere(double radius, Eigen::Vector3d& p) const; 82 | }; 83 | /*----------------------------------------------------------------*/ 84 | 85 | } // namespace VIEWER 86 | 87 | #endif // _VIEWER_CAMERA_H_ 88 | -------------------------------------------------------------------------------- /apps/Viewer/Common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Common.cpp 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | // Source file that includes just the standard includes 33 | // Common.pch will be the pre-compiled header 34 | // Common.obj will contain the pre-compiled type information 35 | 36 | #include "Common.h" 37 | -------------------------------------------------------------------------------- /apps/Viewer/Common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _VIEWER_COMMON_H_ 33 | #define _VIEWER_COMMON_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #include "../../libs/MVS/Common.h" 39 | #include "../../libs/MVS/Scene.h" 40 | 41 | #define GLAD_GL_IMPLEMENTATION 42 | #include <glad/glad.h> 43 | #define GLFW_INCLUDE_NONE 44 | #include <GLFW/glfw3.h> 45 | 46 | 47 | // D E F I N E S /////////////////////////////////////////////////// 48 | 49 | 50 | // P R O T O T Y P E S ///////////////////////////////////////////// 51 | 52 | using namespace SEACAVE; 53 | 54 | namespace VIEWER { 55 | 56 | // the conversion matrix from OpenGL default coordinate system 57 | // to the camera coordinate system (NADIR orientation): 58 | // [ 1 0 0 0] * [ x ] = [ x ] 59 | // 0 -1 0 0 y -y 60 | // 0 0 -1 0 z -z 61 | // 0 0 0 1 1 1 62 | static const Eigen::Matrix4d gs_convert = [] { 63 | Eigen::Matrix4d tmp; tmp << 64 | 1, 0, 0, 0, 65 | 0, -1, 0, 0, 66 | 0, 0, -1, 0, 67 | 0, 0, 0, 1; 68 | return tmp; 69 | }(); 70 | 71 | /// given rotation matrix R and translation vector t, 72 | /// column-major matrix m is equal to: 73 | /// [ R11 R12 R13 t.x ] 74 | /// | R21 R22 R23 t.y | 75 | /// | R31 R32 R33 t.z | 76 | /// [ 0.0 0.0 0.0 1.0 ] 77 | // 78 | // World to Local 79 | inline Eigen::Matrix4d TransW2L(const Eigen::Matrix3d& R, const Eigen::Vector3d& t) 80 | { 81 | Eigen::Matrix4d m(Eigen::Matrix4d::Identity()); 82 | m.block(0,0,3,3) = R; 83 | m.block(0,3,3,1) = t; 84 | return m; 85 | } 86 | // Local to World 87 | // same as above, but with the inverse of the two 88 | inline Eigen::Matrix4d TransL2W(const Eigen::Matrix3d& R, const Eigen::Vector3d& t) 89 | { 90 | Eigen::Matrix4d m(Eigen::Matrix4d::Identity()); 91 | m.block(0,0,3,3) = R.transpose(); 92 | m.block(0,3,3,1) = -t; 93 | return m; 94 | } 95 | /*----------------------------------------------------------------*/ 96 | 97 | } // namespace MVS 98 | 99 | #endif // _VIEWER_COMMON_H_ 100 | -------------------------------------------------------------------------------- /apps/Viewer/Image.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Image.cpp 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #include "Common.h" 33 | #include "Image.h" 34 | 35 | using namespace VIEWER; 36 | 37 | 38 | // D E F I N E S /////////////////////////////////////////////////// 39 | 40 | 41 | // S T R U C T S /////////////////////////////////////////////////// 42 | 43 | Image::Image(MVS::IIndex _idx) 44 | : 45 | idx(_idx), 46 | texture(0) 47 | { 48 | } 49 | Image::~Image() 50 | { 51 | Release(); 52 | } 53 | 54 | void Image::Release() 55 | { 56 | if (IsValid()) { 57 | glDeleteTextures(1, &texture); 58 | texture = 0; 59 | } 60 | ReleaseImage(); 61 | } 62 | void Image::ReleaseImage() 63 | { 64 | if (IsImageValid()) { 65 | cv::Mat* const p(pImage); 66 | Thread::safeExchange(pImage.ptr, (int_t)IMG_NULL); 67 | delete p; 68 | } 69 | } 70 | 71 | void Image::SetImageLoading() 72 | { 73 | ASSERT(IsImageEmpty()); 74 | Thread::safeExchange(pImage.ptr, (int_t)IMG_LOADING); 75 | } 76 | void Image::AssignImage(cv::InputArray img) 77 | { 78 | ASSERT(IsImageLoading()); 79 | ImagePtrInt pImg(new cv::Mat(img.getMat())); 80 | if (pImg.pImage->cols%4 != 0) { 81 | // make sure the width is multiple of 4 (seems to be an OpenGL limitation) 82 | cv::resize(*pImg.pImage, *pImg.pImage, cv::Size((pImg.pImage->cols/4)*4, pImg.pImage->rows), 0, 0, cv::INTER_AREA); 83 | } 84 | Thread::safeExchange(pImage.ptr, pImg.ptr); 85 | } 86 | bool Image::TransferImage() 87 | { 88 | if (!IsImageValid()) 89 | return false; 90 | SetImage(*pImage); 91 | glfwPostEmptyEvent(); 92 | ReleaseImage(); 93 | return true; 94 | } 95 | 96 | void Image::SetImage(cv::InputArray img) 97 | { 98 | cv::Mat image(img.getMat()); 99 | glEnable(GL_TEXTURE_2D); 100 | // create texture 101 | glGenTextures(1, &texture); 102 | // select our current texture 103 | glBindTexture(GL_TEXTURE_2D, texture); 104 | // load texture 105 | width = image.cols; 106 | height = image.rows; 107 | ASSERT(image.channels() == 1 || image.channels() == 3); 108 | ASSERT(image.isContinuous()); 109 | glTexImage2D(GL_TEXTURE_2D, 110 | 0, image.channels(), 111 | width, height, 112 | 0, (image.channels() == 1) ? GL_LUMINANCE : GL_BGR, 113 | GL_UNSIGNED_BYTE, image.ptr<uint8_t>()); 114 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 115 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 116 | } 117 | void Image::GenerateMipmap() const { 118 | glBindTexture(GL_TEXTURE_2D, texture); 119 | glGenerateMipmap(GL_TEXTURE_2D); 120 | } 121 | void Image::Bind() const { 122 | glBindTexture(GL_TEXTURE_2D, texture); 123 | } 124 | /*----------------------------------------------------------------*/ 125 | -------------------------------------------------------------------------------- /apps/Viewer/Image.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Image.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _VIEWER_IMAGE_H_ 33 | #define _VIEWER_IMAGE_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | 39 | // D E F I N E S /////////////////////////////////////////////////// 40 | 41 | 42 | // S T R U C T S /////////////////////////////////////////////////// 43 | 44 | namespace VIEWER { 45 | 46 | class Image 47 | { 48 | public: 49 | typedef CLISTDEFIDX(Image,uint32_t) ImageArr; 50 | enum { 51 | IMG_NULL = 0, 52 | IMG_LOADING, 53 | IMG_VALID 54 | }; 55 | union ImagePtrInt { 56 | cv::Mat* pImage; 57 | int_t ptr; 58 | inline ImagePtrInt() : ptr(IMG_NULL) {} 59 | inline ImagePtrInt(cv::Mat* p) : pImage(p) {} 60 | inline operator cv::Mat* () const { return pImage; } 61 | inline operator cv::Mat*& () { return pImage; } 62 | }; 63 | 64 | public: 65 | MVS::IIndex idx; // image index in the current scene 66 | int width, height; 67 | GLuint texture; 68 | double opacity; 69 | ImagePtrInt pImage; 70 | 71 | public: 72 | Image(MVS::IIndex = NO_ID); 73 | ~Image(); 74 | 75 | void Release(); 76 | void ReleaseImage(); 77 | inline bool IsValid() const { return texture > 0; } 78 | inline bool IsImageEmpty() const { return pImage.ptr == IMG_NULL; } 79 | inline bool IsImageLoading() const { return pImage.ptr == IMG_LOADING; } 80 | inline bool IsImageValid() const { return pImage.ptr >= IMG_VALID; } 81 | 82 | void SetImageLoading(); 83 | void AssignImage(cv::InputArray); 84 | bool TransferImage(); 85 | 86 | void SetImage(cv::InputArray); 87 | void GenerateMipmap() const; 88 | void Bind() const; 89 | 90 | protected: 91 | }; 92 | typedef Image::ImageArr ImageArr; 93 | /*----------------------------------------------------------------*/ 94 | 95 | } // namespace VIEWER 96 | 97 | #endif // _VIEWER_IMAGE_H_ 98 | -------------------------------------------------------------------------------- /apps/Viewer/Scene.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Scene.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _VIEWER_SCENE_H_ 33 | #define _VIEWER_SCENE_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #include "Window.h" 39 | 40 | 41 | // D E F I N E S /////////////////////////////////////////////////// 42 | 43 | 44 | // S T R U C T S /////////////////////////////////////////////////// 45 | 46 | namespace VIEWER { 47 | 48 | class Scene 49 | { 50 | public: 51 | typedef MVS::PointCloud::Octree OctreePoints; 52 | typedef MVS::Mesh::Octree OctreeMesh; 53 | 54 | public: 55 | ARCHIVE_TYPE nArchiveType; 56 | String name; 57 | 58 | String sceneName; 59 | String geometryName; 60 | bool geometryMesh; 61 | MVS::Scene scene; 62 | Window window; 63 | ImageArr images; // scene photos 64 | ImageArr textures; // mesh textures 65 | 66 | OctreePoints octPoints; 67 | OctreeMesh octMesh; 68 | Point3fArr obbPoints; 69 | 70 | GLuint listPointCloud; 71 | CLISTDEF0IDX(GLuint,MVS::Mesh::TexIndex) listMeshes; 72 | 73 | // multi-threading 74 | static SEACAVE::EventQueue events; // internal events queue (processed by the working threads) 75 | static SEACAVE::Thread thread; // worker thread 76 | 77 | public: 78 | explicit Scene(ARCHIVE_TYPE _nArchiveType = ARCHIVE_MVS); 79 | ~Scene(); 80 | 81 | void Empty(); 82 | void Release(); 83 | void ReleasePointCloud(); 84 | void ReleaseMesh(); 85 | inline bool IsValid() const { return window.IsValid(); } 86 | inline bool IsOpen() const { return IsValid() && !scene.IsEmpty(); } 87 | inline bool IsOctreeValid() const { return !octPoints.IsEmpty() || !octMesh.IsEmpty(); } 88 | 89 | bool Init(const cv::Size&, LPCTSTR windowName, LPCTSTR fileName=NULL, LPCTSTR geometryFileName=NULL); 90 | bool Open(LPCTSTR fileName, LPCTSTR geometryFileName=NULL); 91 | bool Save(LPCTSTR fileName=NULL, bool bRescaleImages=false); 92 | bool Export(LPCTSTR fileName, LPCTSTR exportType=NULL) const; 93 | void CompilePointCloud(); 94 | void CompileMesh(); 95 | void CompileBounds(); 96 | void CropToBounds(); 97 | 98 | void Draw(); 99 | void Loop(); 100 | 101 | void Center(); 102 | void TogleSceneBox(); 103 | void CastRay(const Ray3&, int); 104 | protected: 105 | static void* ThreadWorker(void*); 106 | }; 107 | /*----------------------------------------------------------------*/ 108 | 109 | } // namespace VIEWER 110 | 111 | #endif // _VIEWER_SCENE_H_ 112 | -------------------------------------------------------------------------------- /apps/Viewer/Viewer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/apps/Viewer/Viewer.ico -------------------------------------------------------------------------------- /build/Modules/FindBREAKPAD.cmake: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # Find BREAKPAD Library 3 | #---------------------------------------------------------- 4 | # 5 | ## 1: Setup: 6 | # The following variables are optionally searched for defaults 7 | # BREAKPAD_DIR: Base directory of OpenCv tree to use. 8 | # 9 | ## 2: Variable 10 | # The following are set after configuration is done: 11 | # 12 | # BREAKPAD_FOUND 13 | # BREAKPAD_INCLUDE_DIRS 14 | # BREAKPAD_LIBS 15 | # BREAKPAD_DEFINITIONS 16 | # 17 | #---------------------------------------------------------- 18 | 19 | find_path(BREAKPAD_DIR "include/breakpad/client/minidump_file_writer.h" 20 | HINTS "${BREAKPAD_ROOT}" "$ENV{BREAKPAD_ROOT}" "$ENV{BREAKPAD_DIR}" 21 | PATHS "$ENV{PROGRAMFILES}" "$ENV{PROGRAMW6432}" "/usr" "/usr/local" "/usr/share" "/usr/local/share" "/usr/lib/cmake" "/usr/local/lib/cmake" "/usr/lib/x86_64-linux-gnu/cmake" 22 | PATH_SUFFIXES "BreakPad" "include" 23 | DOC "Root directory of BREAKPAD library") 24 | 25 | ##==================================================== 26 | ## Find BREAKPAD libraries 27 | ##---------------------------------------------------- 28 | if(EXISTS "${BREAKPAD_DIR}") 29 | 30 | ## Initiate the variable before the loop 31 | set(BREAKPAD_LIBS "") 32 | set(BREAKPAD_FOUND TRUE) 33 | 34 | ## Set all BREAKPAD component and their account into variables 35 | set(BREAKPAD_LIB_COMPONENTS common crash_generation_client crash_generation_server exception_handler) 36 | 37 | ## Loop over each internal component and find its library file 38 | foreach(LIBCOMP ${BREAKPAD_LIB_COMPONENTS}) 39 | 40 | find_library(BREAKPAD_${LIBCOMP}_LIBRARY_DEBUG NAMES "${LIBCOMP}" PATHS "${BREAKPAD_DIR}/lib${PACKAGE_LIB_SUFFIX_DBG}" NO_DEFAULT_PATH) 41 | find_library(BREAKPAD_${LIBCOMP}_LIBRARY_RELEASE NAMES "${LIBCOMP}" PATHS "${BREAKPAD_DIR}/lib${PACKAGE_LIB_SUFFIX_REL}" NO_DEFAULT_PATH) 42 | find_library(BREAKPAD_${LIBCOMP}_LIBRARY_ALL NAMES "${LIBCOMP}" PATH_SUFFIXES "breakpad") 43 | 44 | #Remove the cache value 45 | set(BREAKPAD_${LIBCOMP}_LIBRARY "" CACHE STRING "" FORCE) 46 | 47 | #both debug/release 48 | if(BREAKPAD_${LIBCOMP}_LIBRARY_DEBUG AND BREAKPAD_${LIBCOMP}_LIBRARY_RELEASE) 49 | set(BREAKPAD_${LIBCOMP}_LIBRARY debug ${BREAKPAD_${LIBCOMP}_LIBRARY_DEBUG} optimized ${BREAKPAD_${LIBCOMP}_LIBRARY_RELEASE} CACHE STRING "" FORCE) 50 | #only debug 51 | elseif(BREAKPAD_${LIBCOMP}_LIBRARY_DEBUG) 52 | set(BREAKPAD_${LIBCOMP}_LIBRARY ${BREAKPAD_${LIBCOMP}_LIBRARY_DEBUG} CACHE STRING "" FORCE) 53 | #only release 54 | elseif(BREAKPAD_${LIBCOMP}_LIBRARY_RELEASE) 55 | set(BREAKPAD_${LIBCOMP}_LIBRARY ${BREAKPAD_${LIBCOMP}_LIBRARY_RELEASE} CACHE STRING "" FORCE) 56 | #both debug/release 57 | elseif(BREAKPAD_${LIBCOMP}_LIBRARY_ALL) 58 | set(BREAKPAD_${LIBCOMP}_LIBRARY ${BREAKPAD_${LIBCOMP}_LIBRARY_ALL} CACHE STRING "" FORCE) 59 | #no library found 60 | else() 61 | message("BREAKPAD component NOT found: ${LIBCOMP}") 62 | set(BREAKPAD_FOUND FALSE) 63 | endif() 64 | 65 | #Add to the general list 66 | if(BREAKPAD_${LIBCOMP}_LIBRARY) 67 | set(BREAKPAD_LIBS ${BREAKPAD_LIBS} ${BREAKPAD_${LIBCOMP}_LIBRARY}) 68 | endif() 69 | 70 | endforeach() 71 | 72 | set(BREAKPAD_INCLUDE_DIRS "${BREAKPAD_DIR}/include" "${BREAKPAD_DIR}/include/breakpad") 73 | message(STATUS "BREAKPAD found (include: ${BREAKPAD_INCLUDE_DIRS})") 74 | 75 | else() 76 | 77 | package_report_not_found(BREAKPAD "Please specify BREAKPAD directory using BREAKPAD_ROOT env. variable") 78 | 79 | endif() 80 | ##==================================================== 81 | 82 | 83 | ##==================================================== 84 | if(BREAKPAD_FOUND) 85 | set(BREAKPAD_DIR "${BREAKPAD_DIR}" CACHE PATH "" FORCE) 86 | mark_as_advanced(BREAKPAD_DIR) 87 | endif() 88 | ##==================================================== 89 | -------------------------------------------------------------------------------- /build/Modules/FindEigen3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find Eigen3 lib 2 | # 3 | # This module supports requiring a minimum version, e.g. you can do 4 | # find_package(Eigen3 3.1.2) 5 | # to require version 3.1.2 or newer of Eigen3. 6 | # 7 | # Once done this will define 8 | # 9 | # EIGEN3_FOUND - system has eigen lib with correct version 10 | # EIGEN3_INCLUDE_DIR - the eigen include directory 11 | # EIGEN3_VERSION - eigen version 12 | # 13 | # and the following imported target: 14 | # 15 | # Eigen3::Eigen - The header-only Eigen library 16 | # 17 | # This module reads hints about search locations from 18 | # the following environment variables: 19 | # 20 | # EIGEN3_ROOT 21 | # EIGEN3_ROOT_DIR 22 | 23 | # Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org> 24 | # Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr> 25 | # Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 26 | # Redistribution and use is allowed according to the terms of the 2-clause BSD license. 27 | 28 | if(NOT Eigen3_FIND_VERSION) 29 | if(NOT Eigen3_FIND_VERSION_MAJOR) 30 | set(Eigen3_FIND_VERSION_MAJOR 2) 31 | endif() 32 | if(NOT Eigen3_FIND_VERSION_MINOR) 33 | set(Eigen3_FIND_VERSION_MINOR 91) 34 | endif() 35 | if(NOT Eigen3_FIND_VERSION_PATCH) 36 | set(Eigen3_FIND_VERSION_PATCH 0) 37 | endif() 38 | 39 | set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") 40 | endif() 41 | 42 | macro(_eigen3_check_version) 43 | file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) 44 | 45 | string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") 46 | set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") 47 | string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") 48 | set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") 49 | string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") 50 | set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") 51 | 52 | set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) 53 | if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) 54 | set(EIGEN3_VERSION_OK FALSE) 55 | else() 56 | set(EIGEN3_VERSION_OK TRUE) 57 | endif() 58 | 59 | if(NOT EIGEN3_VERSION_OK) 60 | 61 | message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " 62 | "but at least version ${Eigen3_FIND_VERSION} is required") 63 | endif() 64 | endmacro() 65 | 66 | if (EIGEN3_INCLUDE_DIR) 67 | 68 | # in cache already 69 | _eigen3_check_version() 70 | set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) 71 | set(Eigen3_FOUND ${EIGEN3_VERSION_OK}) 72 | 73 | else () 74 | 75 | # search first if an Eigen3Config.cmake is available in the system, 76 | # if successful this would set EIGEN3_INCLUDE_DIR and the rest of 77 | # the script will work as usual 78 | find_package(Eigen3 ${Eigen3_FIND_VERSION} NO_MODULE QUIET) 79 | 80 | if(NOT EIGEN3_INCLUDE_DIR) 81 | find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library 82 | HINTS 83 | ENV EIGEN3_ROOT 84 | ENV EIGEN3_ROOT_DIR 85 | PATHS 86 | ${CMAKE_INSTALL_PREFIX}/include 87 | ${KDE4_INCLUDE_DIR} 88 | PATH_SUFFIXES eigen3 eigen 89 | ) 90 | endif() 91 | 92 | if(EIGEN3_INCLUDE_DIR) 93 | _eigen3_check_version() 94 | endif() 95 | 96 | include(FindPackageHandleStandardArgs) 97 | find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) 98 | 99 | mark_as_advanced(EIGEN3_INCLUDE_DIR) 100 | 101 | endif() 102 | 103 | if(EIGEN3_FOUND AND NOT TARGET Eigen3::Eigen) 104 | add_library(Eigen3::Eigen INTERFACE IMPORTED) 105 | set_target_properties(Eigen3::Eigen PROPERTIES 106 | INTERFACE_INCLUDE_DIRECTORIES "${EIGEN3_INCLUDE_DIR}") 107 | endif() 108 | -------------------------------------------------------------------------------- /build/Modules/FindVCG.cmake: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # Find VCG Library 3 | #---------------------------------------------------------- 4 | 5 | find_path(VCG_DIR "vcg/complex/complex.h" 6 | HINTS "${VCG_ROOT}" "$ENV{VCG_ROOT}" 7 | PATHS "$ENV{PROGRAMFILES}" "$ENV{PROGRAMW6432}" "/usr" "/usr/local" "/usr/share" "/usr/local/share" "/usr/lib/x86_64-linux-gnu/cmake" 8 | PATH_SUFFIXES "vcg" "include" 9 | DOC "Root directory of VCG library") 10 | 11 | ##==================================================== 12 | ## Include VCG library 13 | ##---------------------------------------------------- 14 | if(EXISTS "${VCG_DIR}" AND NOT "${VCG_DIR}" STREQUAL "") 15 | set(VCG_FOUND TRUE) 16 | set(VCG_INCLUDE_DIRS ${VCG_DIR}) 17 | set(VCG_DIR "${VCG_DIR}" CACHE PATH "" FORCE) 18 | mark_as_advanced(VCG_DIR) 19 | set(VCG_INCLUDE_DIR ${VCG_DIR}) 20 | 21 | message(STATUS "VCG ${VCG_VERSION} found (include: ${VCG_INCLUDE_DIRS})") 22 | else() 23 | package_report_not_found(VCG "Please specify VCG directory using VCG_ROOT env. variable") 24 | endif() 25 | ##==================================================== 26 | -------------------------------------------------------------------------------- /build/Templates/ConfigLocal.h.in: -------------------------------------------------------------------------------- 1 | // OpenMVS version 2 | #define OpenMVS_MAJOR_VERSION ${OpenMVS_MAJOR_VERSION} 3 | #define OpenMVS_MINOR_VERSION ${OpenMVS_MINOR_VERSION} 4 | #define OpenMVS_PATCH_VERSION ${OpenMVS_PATCH_VERSION} 5 | 6 | // OpenMVS compiled as static or dynamic libs 7 | #cmakedefine BUILD_SHARED_LIBS 8 | 9 | // Define to 1 if exceptions are enabled 10 | #cmakedefine01 _HAS_EXCEPTIONS 11 | 12 | // Define to 1 if RTTI is enabled 13 | #cmakedefine01 _HAS_RTTI 14 | 15 | // OpenMP support 16 | #cmakedefine _USE_OPENMP 17 | 18 | // BREAKPAD support 19 | #cmakedefine _USE_BREAKPAD 20 | 21 | // Boost support 22 | #cmakedefine _USE_BOOST 23 | 24 | // Boost with Python support 25 | #cmakedefine _USE_BOOST_PYTHON 26 | 27 | // Eigen Matrix & Linear Algebra Library 28 | #cmakedefine _USE_EIGEN 29 | 30 | // CERES optimization library 31 | #cmakedefine _USE_CERES 32 | 33 | // JPEG codec 34 | #cmakedefine _USE_JPG 35 | 36 | // JPEG-XL codec 37 | #cmakedefine _USE_JXL 38 | 39 | // PNG codec 40 | #cmakedefine _USE_PNG 41 | 42 | // TIFF codec 43 | #cmakedefine _USE_TIFF 44 | 45 | // OpenCL support 46 | #cmakedefine _USE_OPENCL 47 | #cmakedefine _USE_OPENCL_STATIC 48 | #cmakedefine _USE_OPENCL_SVM 49 | 50 | // NVidia Cuda Runtime API 51 | #cmakedefine _USE_CUDA 52 | 53 | // Fast float to int support 54 | #cmakedefine _USE_FAST_FLOAT2INT 55 | 56 | // Fast INVSQRT support 57 | #cmakedefine _USE_FAST_INVSQRT 58 | 59 | // Fast CBRT support 60 | #cmakedefine _USE_FAST_CBRT 61 | 62 | // SSE support 63 | #cmakedefine _USE_SSE 64 | -------------------------------------------------------------------------------- /build/Templates/OpenMVSConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Configure file for the OpenMVS package, defining the following variables: 2 | # OpenMVS_INCLUDE_DIRS - include directories 3 | # OpenMVS_DEFINITIONS - definitions to be used 4 | # OpenMVS_LIBRARIES - libraries to link against 5 | # OpenMVS_BINARIES - binaries 6 | 7 | @PACKAGE_INIT@ 8 | 9 | set(OpenMVS_VERSION "@OpenMVS_VERSION@") 10 | 11 | # Compute paths 12 | set(OpenMVS_PREFIX "@CMAKE_INSTALL_PREFIX@") 13 | set(OpenMVS_CMAKE_DIR "@INSTALL_CMAKE_DIR_IN@") 14 | set(OpenMVS_INCLUDE_DIRS "@INSTALL_INCLUDE_DIR_IN@") 15 | 16 | set(OpenMVS_DEFINITIONS "@OpenMVS_DEFINITIONS@") 17 | 18 | # These are IMPORTED targets created by OpenMVSTargets.cmake 19 | set(OpenMVS_LIBRARIES MVS) 20 | set(OpenMVS_BINARIES InterfaceCOLMAP DensifyPointCloud ReconstructMesh RefineMesh TextureMesh) 21 | 22 | include("${CMAKE_CURRENT_LIST_DIR}/OpenMVSTargets.cmake") 23 | check_required_components("OpenMVS") 24 | -------------------------------------------------------------------------------- /build/Templates/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=ubuntu:24.04 2 | 3 | FROM $BASE_IMAGE 4 | 5 | ARG MASTER=0 6 | ARG USER_ID 7 | ARG GROUP_ID 8 | ARG CUDA=0 9 | 10 | COPY buildInDocker.sh /tmp/buildInDocker.sh 11 | RUN /tmp/buildInDocker.sh --cuda $CUDA --user_id $USER_ID --group_id $GROUP_ID --master $MASTER && rm /tmp/buildInDocker.sh 12 | 13 | USER user 14 | 15 | # Add binaries to path 16 | ENV PATH /usr/local/bin/OpenMVS:$PATH 17 | -------------------------------------------------------------------------------- /docker/QUICK_START.sh: -------------------------------------------------------------------------------- 1 | docker pull openmvs/openmvs-ubuntu:latest 2 | docker run -w /working -v $1:/working -it openmvs/openmvs-ubuntu:latest 3 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Building & running openMVS using Docker 3 | 4 | ## Quick start: 5 | 6 | 1. Make sure docker is installed on your local machine. 7 | 2. Run the 'easy start' script, using the *full local path* to the folder with your SFM input files (perhaps output from openMVG or COLMAP): 8 | 9 | ``` 10 | ./QUICK_START.sh /path/where/your/SFM/results/are 11 | ``` 12 | 13 | 3. This will put you in a directory (inside the Docker container) mounted to the local path you specified so that you can run openMVS binaries on your own SFM inputs. Enjoy! 14 | 15 | ## Build from scratch: 16 | 17 | You can also build the docker image from scratch based on the **Dockerfile** (perhaps with your own changes / modifications) using: 18 | 19 | ```sh 20 | ./buildFromScratch.sh --workspace /path/where/your/SFM/results/are 21 | # With CUDA support: 22 | ./buildFromScratch.sh --cuda --workspace /path/where/your/SFM/results/are 23 | # From master branch: 24 | ./buildFromScratch.sh --master --workspace /path/where/your/SFM/results/are 25 | ``` 26 | 27 | ## NOTES 28 | 29 | + This workflow is pinned to build from [openMVS 1.0](https://github.com/cdcseacave/openMVS/releases/tag/v1.0). To build from a different release, or build from the latest commit on master, open up the Dockerfile and comment/uncomment as directed. 30 | 31 | + Display is also supported inside docker. If there are any issues with `xauth` make sure to run `xhost +` on your host machine. 32 | 33 | + Running openMVS binaries can use a lot of memory (depending on the size of your data set/ imagery). Docker has a relatively small default memory setting (2Gb on Mac). You will probably want to increase this before you run any larger workflows. From Docker desktop on Mac for example, just open the Docker GUI, go to the *Advanced* tab and increase via the slider: 34 | 35 | ![alt text][dockerParam] 36 | 37 | [dockerParam]: https://i.stack.imgur.com/6iWiW.png "Recommend increasing memory to >4Gb" 38 | -------------------------------------------------------------------------------- /docker/buildFromScratch.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set WORKSPACE=%CD% 4 | 5 | set CUDA_BUILD_ARGS= 6 | set CUDA_RUNTIME_ARGS= 7 | set CUDA_CONTAINER_SUFFIX= 8 | set MASTER_ARGS= 9 | set DISPLAY_ARGS= 10 | 11 | :parse_args 12 | if "%~1" == "" goto build_image 13 | if "%~1" == "--cuda" ( 14 | set "CUDA_BUILD_ARGS=--build-arg CUDA=1 --build-arg BASE_IMAGE=nvidia/cuda:11.8.0-devel-ubuntu22.04" 15 | set "CUDA_RUNTIME_ARGS=--gpus all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics" 16 | set "CUDA_CONTAINER_SUFFIX=-cuda" 17 | shift 18 | goto parse_args 19 | ) 20 | if "%~1" == "--master" ( 21 | set "MASTER_ARGS=--build-arg MASTER=1" 22 | shift 23 | goto parse_args 24 | ) 25 | if "%~1" == "--workspace" ( 26 | set "WORKSPACE=%~2" 27 | shift 28 | shift 29 | goto parse_args 30 | ) 31 | if "%~1" == "--gui" ( 32 | set "XSOCK=\\.\pipe\X11-unix" 33 | set "XAUTH=%TEMP%\docker.xauth" 34 | set "DISPLAY_ARGS=-e ^"DISPLAY=%COMPUTERNAME%:0.0^" -v ^"%XAUTH%:%XAUTH%:rw^" -e ^"XAUTHORITY=%XAUTH%^"" 35 | shift 36 | goto parse_args 37 | ) 38 | echo Unknown argument: %~1 39 | exit /b 1 40 | 41 | :build_image 42 | echo Running with workspace: %WORKSPACE% 43 | 44 | docker build -t="openmvs-ubuntu%CUDA_CONTAINER_SUFFIX%" --build-arg "USER_ID=1001" --build-arg "GROUP_ID=1001" %CUDA_BUILD_ARGS% %MASTER_ARGS% . 45 | if errorlevel 1 exit /b 1 46 | 47 | docker run %CUDA_RUNTIME_ARGS% --entrypoint bash --ipc=host --shm-size=4gb -w /work -v "%WORKSPACE%:/work" %DISPLAY_ARGS% -it openmvs-ubuntu%CUDA_CONTAINER_SUFFIX% 48 | 49 | exit /b 0 50 | -------------------------------------------------------------------------------- /docker/buildFromScratch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Example use: 4 | # ./buildFromScratch.sh --cuda --master --workspace /home/username/datapath/ 5 | 6 | WORKSPACE=$(pwd) 7 | 8 | 9 | while [[ $# -gt 0 ]]; do 10 | key="$1" 11 | case $key in 12 | --cuda) 13 | CUDA_BUILD_ARGS="--build-arg CUDA=1 --build-arg BASE_IMAGE=nvidia/cuda:12.9.1-devel-ubuntu24.04" 14 | 15 | CUDA_RUNTIME_ARGS="--gpus all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics" 16 | 17 | CUDA_CONTAINER_SUFFIX="-cuda" 18 | shift 19 | ;; 20 | --master) 21 | MASTER_ARGS="--build-arg MASTER=1" 22 | shift 23 | ;; 24 | --workspace) 25 | WORKSPACE=$2 26 | shift 27 | shift 28 | ;; 29 | *) 30 | echo "Unknown argument: $key" 31 | exit 1 32 | ;; 33 | esac 34 | done 35 | 36 | # no need to do `xhost +` anymore 37 | XSOCK=/tmp/.X11-unix 38 | XAUTH=/tmp/.docker.xauth 39 | touch $XAUTH 40 | xauth nlist "$DISPLAY" | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - 41 | DISPLAY_ARGS="--volume=$XSOCK:$XSOCK:rw --volume=$XAUTH:$XAUTH:rw --env=XAUTHORITY=$XAUTH --env=DISPLAY=unix$DISPLAY" 42 | 43 | echo Running with workspace: "$WORKSPACE" 44 | 45 | docker build -t="openmvs-ubuntu$CUDA_CONTAINER_SUFFIX" --build-arg "USER_ID=$(id -u)" --build-arg "GROUP_ID=$(id -g)" $CUDA_BUILD_ARGS $MASTER_ARGS . 46 | docker run $CUDA_RUNTIME_ARGS --entrypoint bash --ipc=host --shm-size=4gb -w /work -v "$WORKSPACE:/work" $DISPLAY_ARGS -it openmvs-ubuntu$CUDA_CONTAINER_SUFFIX 47 | 48 | -------------------------------------------------------------------------------- /docker/buildInDocker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Parse arguments to see if --cuda was passed and equals 1 or --master was passed and equals 1 6 | while [[ $# -gt 0 ]]; do 7 | key="$1" 8 | case $key in 9 | --cuda) 10 | CUDA="$2" 11 | shift 12 | shift 13 | ;; 14 | --master) 15 | MASTER="$2" 16 | shift 17 | shift 18 | ;; 19 | --user_id) 20 | USER_ID="$2" 21 | shift 22 | shift 23 | ;; 24 | --group_id) 25 | GROUP_ID="$2" 26 | shift 27 | shift 28 | ;; 29 | *) 30 | echo "Unknown argument: $key" 31 | exit 1 32 | ;; 33 | esac 34 | done 35 | 36 | if [[ "$CUDA" == "1" ]]; then 37 | echo "Building with CUDA support" 38 | EIGEN_BUILD_ARG="-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda/" 39 | OPENMVS_BUILD_ARG="-DOpenMVS_USE_CUDA=ON -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs/ -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda/ -DCUDA_INCLUDE_DIRS=/usr/local/cuda/include/ -DCUDA_CUDART_LIBRARY=/usr/local/cuda/lib64 -DCUDA_NVCC_EXECUTABLE=/usr/local/cuda/bin/ -DCMAKE_CUDA_ARCHITECTURES=all -DEIGEN3_INCLUDE_DIR=/usr/local/include/eigen3" 40 | else 41 | echo "Building without CUDA support" 42 | EIGEN_BUILD_ARG="" 43 | OPENMVS_BUILD_ARG="-DOpenMVS_USE_CUDA=OFF" 44 | fi 45 | 46 | if [[ "$MASTER" == "1" ]]; then 47 | echo "Pulling from master branch" 48 | else 49 | echo "Pulling from develop branch" 50 | fi 51 | 52 | DEBIAN_FRONTEND=noninteractive apt-get update -yq 53 | 54 | DEBIAN_FRONTEND=noninteractive apt-get -yq install build-essential git cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev libglew-dev libglfw3-dev && rm -rf /var/lib/apt/lists/* 55 | 56 | # Eigen 57 | git clone https://gitlab.com/libeigen/eigen --branch 3.4 58 | mkdir eigen_build 59 | cd eigen_build &&\ 60 | cmake . ../eigen $EIGEN_BUILD_ARG &&\ 61 | make && make install &&\ 62 | cd .. && rm -rf eigen_build eigen 63 | 64 | # Boost 65 | DEBIAN_FRONTEND=noninteractive apt-get -yq install libboost-iostreams-dev libboost-program-options-dev libboost-system-dev libboost-serialization-dev 66 | 67 | # OpenCV 68 | DEBIAN_FRONTEND=noninteractive apt-get install -yq libopencv-dev 69 | 70 | # CGAL (dependencies not needed to (not) build CGAL, but for using some parts of it) 71 | DEBIAN_FRONTEND=noninteractive apt-get -yq install libboost-program-options-dev libboost-system-dev libboost-thread-dev libgmp-dev libmpfr-dev zlib1g-dev 72 | 73 | git clone https://github.com/cgal/cgal --branch=v6.0.1 74 | mkdir cgal_build 75 | cd cgal_build &&\ 76 | cmake . ../cgal &&\ 77 | make && make install &&\ 78 | cd .. && rm -rf cgal_build cgal 79 | 80 | 81 | 82 | # Python 83 | DEBIAN_FRONTEND=noninteractive apt-get -yq install python3-dev 84 | 85 | # VCGLib 86 | git clone https://github.com/cdcseacave/VCG.git vcglib 87 | 88 | # Build from stable openMVS release or the latest commit from the develop branch 89 | if [[ "$MASTER" == "1" ]]; then 90 | git clone https://github.com/cdcseacave/openMVS.git --branch master 91 | else 92 | git clone https://github.com/cdcseacave/openMVS.git --branch develop 93 | fi 94 | 95 | mkdir openMVS_build 96 | cd openMVS_build &&\ 97 | cmake . ../openMVS -DCMAKE_BUILD_TYPE=Release -DVCG_ROOT=/vcglib $OPENMVS_BUILD_ARG 98 | 99 | # Install OpenMVS library 100 | make -j4 &&\ 101 | make install &&\ 102 | cd .. && rm -rf openMVS_build vcglib 103 | 104 | # Set permissions such that the output files can be accessed by the current user (optional) 105 | echo "Setting permissions for user $USER_ID:$GROUP_ID" 106 | addgroup --gid $GROUP_ID user &&\ 107 | adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID user 108 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add documentation 2 | -------------------------------------------------------------------------------- /libs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add libraries 2 | ADD_SUBDIRECTORY(Common) 3 | ADD_SUBDIRECTORY(Math) 4 | ADD_SUBDIRECTORY(IO) 5 | ADD_SUBDIRECTORY(MVS) 6 | 7 | # Install 8 | INSTALL(FILES "MVS.h" DESTINATION "${INSTALL_INCLUDE_DIR}") 9 | -------------------------------------------------------------------------------- /libs/Common/AABB.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // AABB.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_AABB_H__ 9 | #define __SEACAVE_AABB_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | 18 | namespace SEACAVE { 19 | 20 | // S T R U C T S /////////////////////////////////////////////////// 21 | 22 | // Basic axis-aligned bounding-box class 23 | template <typename TYPE, int DIMS> 24 | class TAABB 25 | { 26 | STATIC_ASSERT(DIMS > 0 && DIMS <= 3); 27 | 28 | public: 29 | typedef TYPE Type; 30 | typedef Eigen::Matrix<TYPE,DIMS,1> POINT; 31 | typedef Eigen::Matrix<TYPE,DIMS,DIMS,Eigen::RowMajor> MATRIX; 32 | typedef Eigen::AlignedBox<TYPE,DIMS> ALIGNEDBOX; 33 | enum { numChildren = (2<<(DIMS-1)) }; 34 | enum { numCorners = (DIMS==1 ? 2 : (DIMS==2 ? 4 : 8)) }; // 2^DIMS 35 | enum { numScalar = (2*DIMS) }; 36 | 37 | POINT ptMin, ptMax; // box extreme points 38 | 39 | //--------------------------------------- 40 | 41 | inline TAABB() {} 42 | inline TAABB(bool); 43 | inline TAABB(const POINT& pt); 44 | inline TAABB(const POINT& _ptMin, const POINT& _ptMax); 45 | inline TAABB(const POINT& center, const TYPE& radius); 46 | inline TAABB(const ALIGNEDBOX& box); 47 | template <typename TPoint> 48 | inline TAABB(const TPoint* pts, size_t n); 49 | template <typename CTYPE> 50 | inline TAABB(const TAABB<CTYPE, DIMS>&); 51 | 52 | inline void Reset(); 53 | inline void Set(const POINT& pt); 54 | inline void Set(const POINT& _ptMin, const POINT& _ptMax); 55 | inline void Set(const POINT& center, const TYPE& radius); 56 | inline void Set(const ALIGNEDBOX& box); 57 | template <typename TPoint> 58 | inline void Set(const TPoint* pts, size_t n); 59 | 60 | inline bool IsEmpty() const; 61 | 62 | inline TAABB& Enlarge(TYPE); 63 | inline TAABB& EnlargePercent(TYPE); 64 | 65 | void InsertFull(const POINT&); 66 | void Insert(const POINT&); 67 | void Insert(const TAABB&); 68 | void BoundBy(const TAABB&); 69 | 70 | inline void Translate(const POINT&); 71 | inline void Transform(const MATRIX&); 72 | 73 | inline ALIGNEDBOX GetAlignedBox() const; 74 | 75 | inline POINT GetCenter() const; 76 | inline void GetCenter(POINT&) const; 77 | 78 | inline POINT GetSize() const; 79 | inline void GetSize(POINT&) const; 80 | 81 | inline void GetCorner(BYTE i, POINT&) const; 82 | inline POINT GetCorner(BYTE i) const; 83 | inline void GetCorners(POINT pts[numCorners]) const; 84 | 85 | bool Intersects(const TAABB&) const; 86 | bool IntersectsComplete(const TAABB&, TYPE) const; 87 | bool IntersectsComplete(const TAABB&) const; 88 | bool Intersects(const POINT&) const; 89 | bool IntersectsComplete(const POINT&, TYPE) const; 90 | bool IntersectsComplete(const POINT&) const; 91 | 92 | unsigned SplitBy(TYPE, int, TAABB [2]) const; 93 | unsigned SplitBy(const POINT&, TAABB [numChildren], unsigned&) const; 94 | 95 | inline TYPE& operator [] (BYTE i) { ASSERT(i<numScalar); return ptMin.data()[i]; } 96 | inline TYPE operator [] (BYTE i) const { ASSERT(i<numScalar); return ptMin.data()[i]; } 97 | 98 | friend std::ostream& operator << (std::ostream& st, const TAABB& obb) { 99 | st << obb.ptMin.transpose() << std::endl; 100 | st << obb.ptMax.transpose() << std::endl; 101 | return st; 102 | } 103 | friend std::istream& operator >> (std::istream& st, TAABB& obb) { 104 | st >> obb.ptMin; 105 | st >> obb.ptMax; 106 | return st; 107 | } 108 | 109 | #ifdef _USE_BOOST 110 | // implement BOOST serialization 111 | template<class Archive> 112 | void serialize(Archive& ar, const unsigned int /*version*/) { 113 | ar & ptMin; 114 | ar & ptMax; 115 | } 116 | #endif 117 | }; // class TAABB 118 | /*----------------------------------------------------------------*/ 119 | 120 | 121 | #include "AABB.inl" 122 | /*----------------------------------------------------------------*/ 123 | 124 | } // namespace SEACAVE 125 | 126 | #endif // __SEACAVE_AABB_H__ 127 | -------------------------------------------------------------------------------- /libs/Common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # List sources files 2 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 3 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 4 | 5 | cxx_library_with_type(Common "Libs" "" "${cxx_default}" 6 | ${LIBRARY_FILES_C} ${LIBRARY_FILES_H} 7 | ) 8 | 9 | # Manually set Common.h as the precompiled header 10 | IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) 11 | TARGET_PRECOMPILE_HEADERS(Common PRIVATE "Common.h") 12 | endif() 13 | 14 | # Link its dependencies 15 | TARGET_LINK_LIBRARIES(Common ${Boost_LIBRARIES} ${OpenCV_LIBS}) 16 | 17 | # Install 18 | SET_TARGET_PROPERTIES(Common PROPERTIES 19 | PUBLIC_HEADER "${LIBRARY_FILES_H}") 20 | INSTALL(TARGETS Common 21 | EXPORT OpenMVSTargets 22 | LIBRARY DESTINATION "${INSTALL_LIB_DIR}" 23 | ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 24 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 25 | PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/Common") 26 | -------------------------------------------------------------------------------- /libs/Common/Common.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Common.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // Source file that includes just the standard includes 9 | // Common.pch will be the pre-compiled header 10 | // Common.obj will contain the pre-compiled type information 11 | 12 | #include "Common.h" 13 | 14 | namespace SEACAVE { 15 | #if TD_VERBOSE == TD_VERBOSE_ON 16 | int g_nVerbosityLevel(2); 17 | #endif 18 | #if TD_VERBOSE == TD_VERBOSE_DEBUG 19 | int g_nVerbosityLevel(3); 20 | #endif 21 | 22 | String g_strWorkingFolder; 23 | String g_strWorkingFolderFull; 24 | } // namespace SEACAVE 25 | 26 | #ifdef _USE_BOOST 27 | #ifdef BOOST_NO_EXCEPTIONS 28 | #if (BOOST_VERSION / 100000) > 1 || (BOOST_VERSION / 100 % 1000) > 72 29 | #include <boost/assert/source_location.hpp> 30 | #endif 31 | namespace boost { 32 | void throw_exception(std::exception const & e) { 33 | VERBOSE("exception thrown: %s", e.what()); 34 | ASSERT("boost exception thrown" == NULL); 35 | exit(EXIT_FAILURE); 36 | } 37 | #if (BOOST_VERSION / 100000) > 1 || (BOOST_VERSION / 100 % 1000) > 72 38 | void throw_exception(std::exception const & e, boost::source_location const & loc) { 39 | std::ostringstream ostr; ostr << loc; 40 | VERBOSE("exception thrown at %s: %s", ostr.str().c_str(), e.what()); 41 | ASSERT("boost exception thrown" == NULL); 42 | exit(EXIT_FAILURE); 43 | } 44 | #endif 45 | } // namespace boost 46 | #endif 47 | #endif 48 | -------------------------------------------------------------------------------- /libs/Common/ConfigTable.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ConfigTable.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | #include "ConfigTable.h" 10 | 11 | using namespace SEACAVE; 12 | 13 | 14 | // D E F I N E S /////////////////////////////////////////////////// 15 | 16 | 17 | // S T R U C T S /////////////////////////////////////////////////// 18 | 19 | /*-----------------------------------------------------------* 20 | * CConfigTable class implementation * 21 | *-----------------------------------------------------------*/ 22 | 23 | /** 24 | * Constructor 25 | */ 26 | CConfigTable::CConfigTable(const String& name) : m_oSML(name), m_pParent(NULL) 27 | { 28 | m_oSML.SetFncItem(ItemInitData, ItemSaveData, ItemReleaseData); 29 | } 30 | 31 | /** 32 | * Destructor 33 | */ 34 | CConfigTable::~CConfigTable() 35 | { 36 | if (m_pParent) 37 | m_pParent->RemoveChild(*this); 38 | Release(); 39 | } 40 | /*----------------------------------------------------------------*/ 41 | 42 | /** 43 | * Released all used memory 44 | */ 45 | void CConfigTable::Release() 46 | { 47 | m_oSML.Release(); 48 | } 49 | /*----------------------------------------------------------------*/ 50 | 51 | 52 | /** 53 | * Create a new child 54 | */ 55 | void CConfigTable::Insert(const String& name) 56 | { 57 | SML* const pChildSML = new SML(name); 58 | pChildSML->SetFncItem(ItemInitData, ItemSaveData, ItemReleaseData); 59 | const IDX idx = m_oSML.InsertChild(pChildSML); 60 | // if child already exists, delete created node 61 | if (m_oSML.GetArrChildren()[idx] != pChildSML) 62 | delete pChildSML; 63 | } 64 | /*----------------------------------------------------------------*/ 65 | 66 | 67 | /** 68 | * Remove an existing child 69 | */ 70 | void CConfigTable::Remove(const String& name) 71 | { 72 | m_oSML.DestroyChild(name); 73 | } 74 | /*----------------------------------------------------------------*/ 75 | 76 | 77 | /** 78 | * Get the config table for the given child 79 | */ 80 | const SML& CConfigTable::GetConfig(const String& name) const 81 | { 82 | const LPSMLARR& arrSML = m_oSML.GetArrChildren(); 83 | const IDX idx = arrSML.FindFirst(&name, SML::CompareName); 84 | ASSERT(idx != LPSMLARR::NO_INDEX); 85 | return *arrSML[idx]; 86 | } // GetConfig 87 | SML& CConfigTable::GetConfig(const String& name) 88 | { 89 | const LPSMLARR& arrSML = m_oSML.GetArrChildren(); 90 | const IDX idx = arrSML.FindFirst(&name, SML::CompareName); 91 | ASSERT(idx != LPSMLARR::NO_INDEX); 92 | return *arrSML[idx]; 93 | } // GetConfig 94 | /*----------------------------------------------------------------*/ 95 | 96 | 97 | /** 98 | * Load the configuration from a file. 99 | */ 100 | bool CConfigTable::Load(const String& f) 101 | { 102 | return m_oSML.Load(f); 103 | } // Load 104 | bool CConfigTable::Load(ISTREAM& oStream) 105 | { 106 | return m_oSML.Load(oStream); 107 | } // Load 108 | /** 109 | * Write to a file the values of this node and its children. 110 | * Set to false the second parameter in order not to save the empty children. 111 | */ 112 | bool CConfigTable::Save(const String& f, SML::SAVEFLAG flags) const 113 | { 114 | return m_oSML.Save(f, flags); 115 | } // Save 116 | bool CConfigTable::Save(OSTREAM& oStream, SML::SAVEFLAG flags) const 117 | { 118 | return m_oSML.Save(oStream, flags); 119 | } // Save 120 | /*----------------------------------------------------------------*/ 121 | 122 | 123 | /** 124 | * Create and initialize a config item for the given SML entry. 125 | */ 126 | void STCALL CConfigTable::ItemInitData(const String& key, SMLVALUE& val, void*) 127 | { 128 | CFGITEM* pItem = new CFGITEM; 129 | pItem->name = key; 130 | val.data = pItem; 131 | } // ItemInitData 132 | /*----------------------------------------------------------------*/ 133 | 134 | /** 135 | * Save a config item for the given SML entry. Return false if this item should not be saved. 136 | */ 137 | bool STCALL CConfigTable::ItemSaveData(const SMLVALUE& val, void*) 138 | { 139 | const CFGITEM& item = *((const CFGITEM*)val.data); 140 | return !item.state.isSet(CFGITEM::TEMP); 141 | } // ItemSaveData 142 | /*----------------------------------------------------------------*/ 143 | 144 | /** 145 | * Release and destroy the config item for the given SML entry. 146 | */ 147 | void STCALL CConfigTable::ItemReleaseData(SMLVALUE& val, void*) 148 | { 149 | CFGITEM* pItem = (CFGITEM*)val.data; 150 | val.data = NULL; 151 | delete pItem; 152 | } // ItemReleaseData 153 | /*----------------------------------------------------------------*/ 154 | -------------------------------------------------------------------------------- /libs/Common/ConfigTable.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ConfigTable.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_CONFIGTABLE_H__ 9 | #define __SEACAVE_CONFIGTABLE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "SML.h" 15 | 16 | 17 | // D E F I N E S /////////////////////////////////////////////////// 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | typedef struct CFGITEM_TYPE { 25 | enum { 26 | NA = 0, // no special states available 27 | TEMP = (1 << 0), // this item lives only this instance and it will not be save 28 | }; 29 | Flags state; 30 | String name; 31 | String desc; 32 | String defval; 33 | StringArr vals; 34 | } CFGITEM; 35 | 36 | 37 | // P R O T O T Y P E S ///////////////////////////////////////////// 38 | 39 | /** 40 | * Configuration table interface. 41 | */ 42 | 43 | class GENERAL_API CConfigTable 44 | { 45 | public: 46 | CConfigTable(const String&); 47 | ~CConfigTable(); 48 | 49 | void Release(); 50 | 51 | // main methods 52 | void Insert(const String&); 53 | void Remove(const String&); 54 | const SML& GetConfig(const String&) const; 55 | SML& GetConfig(const String&); 56 | const SML& GetConfig() const { return m_oSML; } 57 | SML& GetConfig() { return m_oSML; } 58 | inline SMLVALUE& operator[] (const String& name) { return m_oSML[name]; } 59 | inline IDX InsertChild(CConfigTable& oCfg) { oCfg.SetParent(this); return m_oSML.InsertChild(&oCfg.m_oSML); } 60 | inline void RemoveChild(CConfigTable& oCfg) { oCfg.SetParent(NULL); m_oSML.RemoveChild(oCfg.m_oSML.GetName()); } 61 | 62 | // misc methods 63 | bool Load(const String&); 64 | bool Load(ISTREAM&); 65 | bool Save(const String&, SML::SAVEFLAG=SML::NONE) const; 66 | bool Save(OSTREAM&, SML::SAVEFLAG=SML::NONE) const; 67 | inline const String& GetName() const { return m_oSML.GetName(); } 68 | inline CConfigTable* GetParent() const { return m_pParent; } 69 | inline void SetParent(CConfigTable* pParent) { m_pParent = pParent; } 70 | static void STCALL ItemInitData(const String&, SMLVALUE&, void*); 71 | static bool STCALL ItemSaveData(const SMLVALUE&, void*); 72 | static void STCALL ItemReleaseData(SMLVALUE&, void*); 73 | 74 | private: 75 | SML m_oSML; 76 | CConfigTable* m_pParent; 77 | }; 78 | /*----------------------------------------------------------------*/ 79 | 80 | } // namespace SEACAVE 81 | 82 | #endif // __SEACAVE_CONFIGTABLE_H__ 83 | -------------------------------------------------------------------------------- /libs/Common/EventQueue.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // EventQueue.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | #include "EventQueue.h" 10 | 11 | using namespace SEACAVE; 12 | 13 | 14 | // D E F I N E S /////////////////////////////////////////////////// 15 | 16 | 17 | // S T R U C T S /////////////////////////////////////////////////// 18 | 19 | /*-----------------------------------------------------------* 20 | * EventQueue class implementation * 21 | *-----------------------------------------------------------*/ 22 | 23 | void EventQueue::Clear() 24 | { 25 | m_cs.Clear(); 26 | m_sem.Clear(); 27 | m_events.Empty(); 28 | } 29 | 30 | void EventQueue::AddEvent(Event* evt) 31 | { 32 | Lock l(m_cs); 33 | m_events.AddTail(evt); 34 | m_sem.Signal(); 35 | } 36 | void EventQueue::AddEventFirst(Event* evt) 37 | { 38 | Lock l(m_cs); 39 | m_events.AddHead(evt); 40 | m_sem.Signal(); 41 | } 42 | 43 | Event* EventQueue::GetEvent() 44 | { 45 | m_sem.Wait(); 46 | Lock l(m_cs); 47 | ASSERT(!m_events.IsEmpty()); 48 | return m_events.RemoveHead(); 49 | } 50 | Event* EventQueue::GetEvent(uint32_t millis) 51 | { 52 | if (!m_sem.Wait(millis)) 53 | return NULL; 54 | Lock l(m_cs); 55 | if (m_events.IsEmpty()) 56 | return NULL; 57 | return m_events.RemoveHead(); 58 | } 59 | Event* EventQueue::GetEventLast() 60 | { 61 | m_sem.Wait(); 62 | Lock l(m_cs); 63 | ASSERT(!m_events.IsEmpty()); 64 | return m_events.RemoveTail(); 65 | } 66 | Event* EventQueue::GetEventLast(uint32_t millis) 67 | { 68 | if (!m_sem.Wait(millis)) 69 | return NULL; 70 | Lock l(m_cs); 71 | if (m_events.IsEmpty()) 72 | return NULL; 73 | return m_events.RemoveTail(); 74 | } 75 | /*----------------------------------------------------------------*/ 76 | 77 | bool EventQueue::IsEmpty() const 78 | { 79 | Lock l(m_cs); 80 | return m_events.IsEmpty(); 81 | } 82 | 83 | uint_t EventQueue::GetSize() const 84 | { 85 | Lock l(m_cs); 86 | return m_events.GetSize(); 87 | } 88 | /*----------------------------------------------------------------*/ 89 | 90 | 91 | 92 | /*-----------------------------------------------------------* 93 | * EventThreadPool class implementation * 94 | *-----------------------------------------------------------*/ 95 | 96 | void EventThreadPool::stop() 97 | { 98 | ThreadPool::stop(); 99 | EventQueue::Clear(); 100 | } 101 | /*----------------------------------------------------------------*/ 102 | -------------------------------------------------------------------------------- /libs/Common/EventQueue.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // EventQueue.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_EVENTQUEUE_H__ 9 | #define __SEACAVE_EVENTQUEUE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Types.h" 15 | #include "CriticalSection.h" 16 | #include "Semaphore.h" 17 | 18 | 19 | // D E F I N E S /////////////////////////////////////////////////// 20 | 21 | 22 | namespace SEACAVE { 23 | 24 | // S T R U C T S /////////////////////////////////////////////////// 25 | 26 | class Event 27 | { 28 | public: 29 | Event(uint32_t _id) : id(_id) {} 30 | virtual ~Event() {} 31 | 32 | uint32_t GetID() const { return id; } 33 | 34 | virtual bool Run(void* /*pArgs*/ = NULL) { return true; } 35 | 36 | protected: 37 | const uint32_t id; 38 | }; 39 | typedef cQueue<Event*,Event*,0> EVENTQUEUE; 40 | 41 | 42 | /************************************************************************************** 43 | * Events Queue 44 | * -------------- 45 | * basic eventing mechanism 46 | * multi-thread safe 47 | **************************************************************************************/ 48 | 49 | class GENERAL_API EventQueue 50 | { 51 | public: 52 | EventQueue() {} 53 | ~EventQueue() {} 54 | 55 | void Clear(); // reset the state of the locks and empty the queue 56 | 57 | void AddEvent(Event*); //add a new event to the end of the queue 58 | void AddEventFirst(Event*); //add a new event to the beginning of the queue 59 | Event* GetEvent(); //block until an event arrives and get the first event pending in the queue 60 | Event* GetEvent(uint32_t millis); //block until an event arrives or time expires and get the first event pending in the queue 61 | Event* GetEventLast(); //block until an event arrives and get the last event pending in the queue 62 | Event* GetEventLast(uint32_t millis); //block until an event arrives or time expires and get the last event pending in the queue 63 | 64 | bool IsEmpty() const; //are there any events in the queue? 65 | uint_t GetSize() const; //number of events in the queue 66 | 67 | protected: 68 | Semaphore m_sem; 69 | mutable CriticalSection m_cs; 70 | EVENTQUEUE m_events; 71 | }; 72 | /*----------------------------------------------------------------*/ 73 | 74 | 75 | // basic event and thread pool 76 | class GENERAL_API EventThreadPool : public ThreadPool, public EventQueue 77 | { 78 | public: 79 | inline EventThreadPool() {} 80 | inline EventThreadPool(size_type nThreads) : ThreadPool(nThreads) {} 81 | inline EventThreadPool(size_type nThreads, Thread::FncStart pfnStarter, void* pData=NULL) : ThreadPool(nThreads, pfnStarter, pData) {} 82 | inline ~EventThreadPool() {} 83 | 84 | void stop(); //stop threads, reset locks state and empty event queue 85 | }; 86 | /*----------------------------------------------------------------*/ 87 | 88 | } // namespace SEACAVE 89 | 90 | #endif // __SEACAVE_EVENTQUEUE_H__ 91 | -------------------------------------------------------------------------------- /libs/Common/Line.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Line.h 3 | // 4 | // Copyright 2023 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_LINE_H__ 9 | #define __SEACAVE_LINE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | 18 | namespace SEACAVE { 19 | 20 | // S T R U C T S /////////////////////////////////////////////////// 21 | 22 | // Generic line class represented as two points 23 | template <typename TYPE, int DIMS> 24 | class TLine 25 | { 26 | STATIC_ASSERT(DIMS > 1 && DIMS <= 3); 27 | 28 | public: 29 | typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR; 30 | typedef Eigen::Matrix<TYPE,DIMS,1> POINT; 31 | typedef SEACAVE::TAABB<TYPE,DIMS> AABB; 32 | typedef SEACAVE::TRay<TYPE,DIMS> RAY; 33 | enum { numScalar = (2*DIMS) }; 34 | enum { numParams = numScalar-1 }; 35 | 36 | POINT pt1, pt2; // line description 37 | 38 | //--------------------------------------- 39 | 40 | inline TLine() {} 41 | inline TLine(const POINT& pt1, const POINT& pt2); 42 | template <typename CTYPE> 43 | inline TLine(const TLine<CTYPE,DIMS>&); 44 | 45 | inline void Set(const POINT& pt1, const POINT& pt2); 46 | 47 | int Optimize(const POINT*, size_t, int maxIters=100); 48 | template <typename RobustNormFunctor> 49 | int Optimize(const POINT*, size_t, const RobustNormFunctor& robust, int maxIters=100); 50 | 51 | inline TYPE GetLength() const; 52 | inline TYPE GetLengthSq() const; 53 | inline POINT GetCenter() const; 54 | inline VECTOR GetDir() const; 55 | inline VECTOR GetNormDir() const; 56 | inline RAY GetRay() const; 57 | 58 | inline bool IsSame(const TLine&, TYPE th) const; 59 | 60 | bool Intersects(const AABB& aabb) const; 61 | bool Intersects(const AABB& aabb, TYPE& t) const; 62 | 63 | inline TYPE DistanceSq(const POINT&) const; 64 | inline TYPE Distance(const POINT&) const; 65 | 66 | inline TYPE Classify(const POINT&) const; 67 | inline POINT ProjectPoint(const POINT&) const; 68 | 69 | inline TYPE& operator [] (BYTE i) { ASSERT(i<numScalar); return pt1.data()[i]; } 70 | inline TYPE operator [] (BYTE i) const { ASSERT(i<numScalar); return pt1.data()[i]; } 71 | 72 | #ifdef _USE_BOOST 73 | // implement BOOST serialization 74 | template<class Archive> 75 | void serialize(Archive& ar, const unsigned int /*version*/) { 76 | ar & pt1; 77 | ar & pt2; 78 | } 79 | #endif 80 | }; // class TLine 81 | /*----------------------------------------------------------------*/ 82 | 83 | template <typename TYPE, typename TYPEW=TYPE> 84 | struct FitLineOnline : FitPlaneOnline<TYPE,TYPEW,true> { 85 | template <typename TYPEE> TPoint3<TYPEE> GetLine(TLine<TYPEE,3>& line) const; 86 | }; 87 | /*----------------------------------------------------------------*/ 88 | 89 | 90 | #include "Line.inl" 91 | /*----------------------------------------------------------------*/ 92 | 93 | } // namespace SEACAVE 94 | 95 | #endif // __SEACAVE_LINE_H__ 96 | -------------------------------------------------------------------------------- /libs/Common/LinkLib.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // LinkLib.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_LINKLIB_H__ 9 | #define __SEACAVE_LINKLIB_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #ifdef _MSC_VER 15 | #else 16 | #include <dlfcn.h> 17 | #endif 18 | 19 | 20 | // D E F I N E S /////////////////////////////////////////////////// 21 | 22 | 23 | namespace SEACAVE { 24 | 25 | // S T R U C T S /////////////////////////////////////////////////// 26 | 27 | 28 | /************************************************************************************** 29 | * CLinkLib 30 | * --------------- 31 | * manage dynamic linked libraries 32 | **************************************************************************************/ 33 | 34 | class GENERAL_API CLinkLib 35 | { 36 | public: 37 | #ifdef _MSC_VER 38 | typedef HINSTANCE LibID; 39 | #else 40 | typedef void* LibID; 41 | #endif 42 | 43 | CLinkLib() : m_hLib(NULL) 44 | { 45 | } 46 | 47 | CLinkLib(const String& dllName) : m_hLib(NULL) 48 | { 49 | Load(dllName); 50 | } 51 | 52 | CLinkLib(const CLinkLib& lib) : m_hLib(lib.m_hLib) 53 | { 54 | ((CLinkLib&)lib).m_hLib = NULL; 55 | } 56 | 57 | ~CLinkLib() 58 | { 59 | Free(); 60 | } 61 | 62 | bool Load(const String& dllName) 63 | { 64 | Free(); 65 | #ifdef _MSC_VER 66 | m_hLib = LoadLibrary(dllName); 67 | #else 68 | m_hLib = dlopen(dllName, RTLD_NOW); 69 | #endif 70 | return (m_hLib != NULL); 71 | } 72 | 73 | void Free() 74 | { 75 | if (!IsLoaded()) 76 | return; 77 | #ifdef _MSC_VER 78 | FreeLibrary(m_hLib); 79 | #else 80 | dlclose(m_hLib); 81 | #endif 82 | m_hLib = NULL; 83 | } 84 | 85 | void* GetFunction(const String& funcName) const 86 | { 87 | #ifdef _MSC_VER 88 | return GetProcAddress(m_hLib, funcName); 89 | #else 90 | return dlsym(m_hLib, funcName); 91 | #endif 92 | } 93 | 94 | bool IsLoaded() const 95 | { 96 | return (m_hLib != NULL); 97 | } 98 | 99 | LibID GetLibID() const 100 | { 101 | return m_hLib; 102 | } 103 | 104 | protected: 105 | LibID m_hLib; 106 | }; 107 | /*----------------------------------------------------------------*/ 108 | 109 | } // namespace SEACAVE 110 | 111 | #endif // __SEACAVE_LINKLIB_H__ 112 | -------------------------------------------------------------------------------- /libs/Common/ListFIFO.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ListFIFO.h 3 | * 4 | * Copyright (c) 2014-2024 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #pragma once 33 | #ifndef _MVS_LISTFIFO_H_ 34 | #define _MVS_LISTFIFO_H_ 35 | 36 | 37 | // I N C L U D E S ///////////////////////////////////////////////// 38 | 39 | #include <list> 40 | #include <unordered_map> 41 | 42 | 43 | // S T R U C T S /////////////////////////////////////////////////// 44 | 45 | namespace SEACAVE { 46 | 47 | // Tracks accesses of some hash-able type T and records the least recently accessed. 48 | template<typename T> 49 | class ListFIFO { 50 | public: 51 | // add or move an key to the front 52 | void Put(const T& key) { 53 | const auto it = map.find(key); 54 | if (it != map.end()) { 55 | // if key exists, remove it from its current position 56 | order.erase(it->second); 57 | } 58 | // add the key to the front 59 | order.push_front(key); 60 | map[key] = order.begin(); 61 | } 62 | 63 | // remove and return the least used key (from the back) 64 | T Pop() { 65 | ASSERT(!IsEmpty()); 66 | const T leastUsed = order.back(); 67 | order.pop_back(); 68 | map.erase(leastUsed); 69 | return leastUsed; 70 | } 71 | 72 | // return the least used key (from the back) 73 | const T& Back() { 74 | ASSERT(!IsEmpty()); 75 | return order.back(); 76 | } 77 | 78 | // check if the list is empty 79 | bool IsEmpty() const { 80 | return order.empty(); 81 | } 82 | 83 | // get the size of the list 84 | size_t Size() const { 85 | return order.size(); 86 | } 87 | 88 | // return true if the key is in the list 89 | bool Contains(const T& key) const { 90 | return map.find(key) != map.end(); 91 | } 92 | 93 | // return the keys currently in cache 94 | const std::list<T>& GetCachedValues() const { 95 | return order; 96 | } 97 | 98 | // print the current order of elements 99 | void PrintOrder() const { 100 | std::cout << "Current order: "; 101 | for (const auto& element : order) { 102 | std::cout << element << " "; 103 | } 104 | std::cout << std::endl; 105 | } 106 | 107 | private: 108 | std::list<T> order; 109 | std::unordered_map<T, typename std::list<T>::iterator> map; 110 | }; 111 | /*----------------------------------------------------------------*/ 112 | 113 | } // namespace SEACAVE 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /libs/Common/OBB.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // OBB.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_OBB_H__ 9 | #define __SEACAVE_OBB_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | 18 | namespace SEACAVE { 19 | 20 | // S T R U C T S /////////////////////////////////////////////////// 21 | 22 | template <typename TYPE, int DIMS> 23 | class TAABB; 24 | 25 | template <typename TYPE, int DIMS> 26 | class TRay; 27 | 28 | // Basic oriented bounding-box class 29 | template <typename TYPE, int DIMS> 30 | class TOBB 31 | { 32 | STATIC_ASSERT(DIMS > 0 && DIMS <= 3); 33 | 34 | public: 35 | typedef TYPE Type; 36 | typedef Eigen::Matrix<TYPE,DIMS,1> POINT; 37 | typedef Eigen::Matrix<TYPE,DIMS,DIMS,Eigen::RowMajor> MATRIX; 38 | typedef SEACAVE::TAABB<TYPE,DIMS> AABB; 39 | typedef SEACAVE::TRay<TYPE,DIMS> RAY; 40 | typedef unsigned ITYPE; 41 | typedef Eigen::Matrix<ITYPE,DIMS,1> TRIANGLE; 42 | enum { numCorners = (DIMS==1 ? 2 : (DIMS==2 ? 4 : 8)) }; // 2^DIMS 43 | enum { numScalar = (5*DIMS) }; 44 | 45 | MATRIX m_rot; // rotation matrix from world to local (orthonormal axes) 46 | POINT m_pos; // translation from local to world (center-point) 47 | POINT m_ext; // bounding box extents in local (half axis length) 48 | 49 | //--------------------------------------- 50 | 51 | inline TOBB() {} 52 | inline TOBB(bool); 53 | inline TOBB(const AABB&); 54 | inline TOBB(const MATRIX& rot, const POINT& ptMin, const POINT& ptMax); 55 | inline TOBB(const POINT* pts, size_t n); 56 | inline TOBB(const POINT* pts, size_t n, const TRIANGLE* tris, size_t s); 57 | template <typename CTYPE> 58 | inline TOBB(const TOBB<CTYPE, DIMS>&); 59 | 60 | inline void Set(const AABB&); // build from AABB 61 | inline void Set(const MATRIX& rot, const POINT& ptMin, const POINT& ptMax); // build from rotation matrix from world to local, and local min/max corners 62 | inline void Set(const POINT* pts, size_t n); // build from points 63 | inline void Set(const POINT* pts, size_t n, const TRIANGLE* tris, size_t s); // build from triangles 64 | inline void Set(const MATRIX& C, const POINT* pts, size_t n); // build from covariance matrix 65 | inline void SetRotation(const MATRIX& C); // build rotation only from covariance matrix 66 | inline void SetBounds(const POINT* pts, size_t n); // build size and center only from given points 67 | 68 | inline void BuildBegin(); // start online build for computing the rotation 69 | inline void BuildAdd(const POINT&); // add a new point to the online build 70 | inline void BuildEnd(); // end online build for computing the rotation 71 | 72 | inline bool IsValid() const; 73 | 74 | inline TOBB& Enlarge(TYPE); 75 | inline TOBB& EnlargePercent(TYPE); 76 | 77 | inline void Translate(const POINT&); 78 | inline void Transform(const MATRIX&); 79 | 80 | inline POINT GetCenter() const; 81 | inline void GetCenter(POINT&) const; 82 | 83 | inline POINT GetSize() const; 84 | inline void GetSize(POINT&) const; 85 | 86 | inline void GetCorners(POINT pts[numCorners]) const; 87 | inline AABB GetAABB() const; 88 | 89 | inline TYPE GetVolume() const; 90 | 91 | bool Intersects(const POINT&) const; 92 | 93 | inline TYPE& operator [] (BYTE i) { ASSERT(i<numScalar); return m_rot.data()[i]; } 94 | inline TYPE operator [] (BYTE i) const { ASSERT(i<numScalar); return m_rot.data()[i]; } 95 | 96 | friend std::ostream& operator << (std::ostream& st, const TOBB& obb) { 97 | st << obb.m_rot << std::endl; 98 | st << obb.m_pos.transpose() << std::endl; 99 | st << obb.m_ext.transpose() << std::endl; 100 | return st; 101 | } 102 | friend std::istream& operator >> (std::istream& st, TOBB& obb) { 103 | st >> obb.m_rot; 104 | st >> obb.m_pos; 105 | st >> obb.m_ext; 106 | return st; 107 | } 108 | 109 | #ifdef _USE_BOOST 110 | // implement BOOST serialization 111 | template<class Archive> 112 | void serialize(Archive& ar, const unsigned int /*version*/) { 113 | ar & m_rot; 114 | ar & m_pos; 115 | ar & m_ext; 116 | } 117 | #endif 118 | }; // class TOBB 119 | /*----------------------------------------------------------------*/ 120 | 121 | 122 | #include "OBB.inl" 123 | /*----------------------------------------------------------------*/ 124 | 125 | } // namespace SEACAVE 126 | 127 | #endif // __SEACAVE_OBB_H__ 128 | -------------------------------------------------------------------------------- /libs/Common/SML.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // SML.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_SML_H__ 9 | #define __SEACAVE_SML_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Filters.h" 15 | 16 | 17 | // D E F I N E S /////////////////////////////////////////////////// 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | typedef struct SMLVALUE_TYPE { 25 | String val; //item's value 26 | void* data; //user data 27 | SMLVALUE_TYPE() : data(NULL) {} 28 | SMLVALUE_TYPE(const SMLVALUE_TYPE& r) : data(r.data) { ((SMLVALUE_TYPE&)r).data = NULL; } 29 | ~SMLVALUE_TYPE() { delete data; } 30 | } SMLVALUE; 31 | 32 | class SML; 33 | typedef SML* LPSML; 34 | typedef cList<LPSML, LPSML, 0, 8> LPSMLARR; 35 | 36 | //typedef cHashTable<SMLVALUE> SMLITEMMAP; 37 | typedef cMapWrap<String, SMLVALUE> SMLITEMMAP; 38 | 39 | /************************************************************************************** 40 | * Simple Markup Language 41 | * -------------- 42 | * fast and easy to use markup language; 43 | * contains a map of (name, value) pairs 44 | **************************************************************************************/ 45 | 46 | class GENERAL_API SML : public SMLITEMMAP 47 | { 48 | public: 49 | typedef void (STCALL *TFncInitItem)(const String&, SMLVALUE&, void*); 50 | typedef bool (STCALL *TFncSaveItem)(const SMLVALUE&, void*); 51 | typedef void (STCALL *TFncReleaseItem)(SMLVALUE&, void*); 52 | 53 | enum SAVEFLAG { 54 | NONE = 0, 55 | SAVEEMPTY = (1 << 0), //save empty children 56 | SORT = (1 << 1), //sort all entries alphabetically 57 | SORTINV = (1 << 2), //sort all entries inverse alphabetically 58 | }; 59 | 60 | public: 61 | SML(const String& =String()); 62 | ~SML(); 63 | 64 | void Release(); 65 | 66 | // main methods 67 | bool Load(const String&); 68 | bool Load(ISTREAM&); 69 | bool Save(const String&, SAVEFLAG=NONE) const; 70 | bool Save(OSTREAM&, SAVEFLAG=NONE) const; 71 | IDX CreateChild(const String& =String()); 72 | IDX CreateChildUnique(const String& =String()); 73 | IDX InsertChild(const LPSML); 74 | IDX InsertChildUnique(const LPSML); 75 | void RemoveChild(IDX); 76 | inline void RemoveChild(const String& name) { RemoveChild(GetChild(name)); } 77 | void DestroyChild(IDX); 78 | inline void DestroyChild(const String& name) { DestroyChild(GetChild(name)); } 79 | IDX GetChild(const String&) const; 80 | const SMLVALUE* GetValue(const String&) const; 81 | SMLVALUE& GetValue(const String&); 82 | const SMLVALUE& GetValue(IDX) const; 83 | inline SMLVALUE& operator[] (const String& key) { return GetValue(key); } 84 | 85 | // misc methods 86 | inline const String& GetName() const { return m_strName; } 87 | inline LPSML GetChild(IDX idx) const { return m_arrChildren[idx]; } 88 | inline const LPSMLARR& GetArrChildren() const { return m_arrChildren; } 89 | inline LPSMLARR& GetArrChildren() { return m_arrChildren; } 90 | void SetFncItem(TFncInitItem, TFncSaveItem, TFncReleaseItem, void* data=NULL); 91 | 92 | public: 93 | static int STCALL Compare(const void*, const void*); 94 | static int STCALL CompareName(const void*, const void*); 95 | 96 | private: 97 | typedef TokenInputStream<false> TokenIStream; 98 | 99 | bool ParseSection(TokenIStream&, MemFile&); 100 | bool ParseValues(MemFile&); 101 | bool SaveBracketize(OSTREAM&, const String&, SAVEFLAG) const; 102 | bool SaveIntern(OSTREAM&, const String&, SAVEFLAG) const; 103 | 104 | private: 105 | const String m_strName; // node name 106 | LPSMLARR m_arrChildren; // the array with all the sub-nodes 107 | TFncInitItem m_fncInitItem; // callback function used to initialize each item 108 | TFncSaveItem m_fncSaveItem; // callback function used to save each item 109 | TFncReleaseItem m_fncReleaseItem; // callback function used to release each item 110 | void* m_fncItemData; 111 | }; 112 | /*----------------------------------------------------------------*/ 113 | 114 | } // namespace SEACAVE 115 | 116 | #endif // __SEACAVE_SML_H__ 117 | -------------------------------------------------------------------------------- /libs/Common/Semaphore.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Semaphore.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_SEMAPHORE_H__ 9 | #define __SEACAVE_SEMAPHORE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Thread.h" 15 | 16 | #ifndef _MSC_VER 17 | #ifdef _SUPPORT_CPP11 18 | #include <mutex> 19 | #include <condition_variable> 20 | #else 21 | #include "CriticalSection.h" 22 | #include <sys/time.h> 23 | #endif 24 | #endif 25 | 26 | 27 | // D E F I N E S /////////////////////////////////////////////////// 28 | 29 | 30 | namespace SEACAVE { 31 | 32 | // S T R U C T S /////////////////////////////////////////////////// 33 | 34 | class Semaphore 35 | { 36 | #ifdef _MSC_VER 37 | public: 38 | Semaphore(unsigned count=0) { 39 | h = CreateSemaphore(NULL, count, MAXLONG, NULL); 40 | }; 41 | ~Semaphore() { 42 | CloseHandle(h); 43 | }; 44 | 45 | void Clear(unsigned count=0) { 46 | CloseHandle(h); 47 | h = CreateSemaphore(NULL, count, MAXLONG, NULL); 48 | } 49 | 50 | void Signal() { 51 | ReleaseSemaphore(h, 1, NULL); 52 | } 53 | void Signal(unsigned count) { 54 | ASSERT(count > 0); 55 | ReleaseSemaphore(h, count, NULL); 56 | } 57 | 58 | void Wait() { 59 | WaitForSingleObject(h, INFINITE); 60 | } 61 | bool Wait(uint32_t millis) { 62 | return WaitForSingleObject(h, millis) == WAIT_OBJECT_0; 63 | } 64 | 65 | protected: 66 | HANDLE h; 67 | 68 | #elif !defined(_SUPPORT_CPP11) 69 | // pthread implementation 70 | public: 71 | Semaphore(unsigned c=0) : count(c) { pthread_cond_init(&cond, NULL); } 72 | ~Semaphore() { pthread_cond_destroy(&cond); } 73 | 74 | void Clear(unsigned c=0) { 75 | cs.Clear(); 76 | pthread_cond_destroy(&cond); 77 | pthread_cond_init(&cond, NULL); 78 | count = c; 79 | } 80 | 81 | void Signal() { 82 | Lock l(cs); 83 | ++count; 84 | pthread_cond_signal(&cond); 85 | } 86 | void Signal(unsigned c) { 87 | ASSERT(c > 0); 88 | for (unsigned i=0; i<c; ++i) 89 | Signal(); 90 | } 91 | 92 | void Wait() { 93 | Lock l(cs); 94 | while (!count) 95 | pthread_cond_wait(&cond, &cs.getMutex()); 96 | --count; 97 | } 98 | bool Wait(uint32_t millis) { 99 | Lock l(cs); 100 | if (count == 0) { 101 | timeval timev; 102 | gettimeofday(&timev, NULL); 103 | millis += timev.tv_usec/1000; 104 | timespec t = { 105 | timev.tv_sec + (millis/1000), 106 | (millis%1000)*1000*1000 107 | }; 108 | pthread_cond_timedwait(&cond, &cs.getMutex(), &t); 109 | if (count == 0) 110 | return false; 111 | } 112 | --count; 113 | return true; 114 | } 115 | 116 | protected: 117 | pthread_cond_t cond; 118 | CriticalSection cs; 119 | unsigned count; 120 | 121 | #else 122 | // C++11 implementation 123 | public: 124 | Semaphore(unsigned c=0) : count(c) {} 125 | ~Semaphore() {} 126 | 127 | void Clear(unsigned c=0) { 128 | std::lock_guard<std::mutex> lock{mtx}; 129 | count = c; 130 | } 131 | 132 | void Signal() { 133 | std::lock_guard<std::mutex> lock{mtx}; 134 | ++count; 135 | cv.notify_one(); 136 | } 137 | void Signal(unsigned c) { 138 | ASSERT(c > 0); 139 | for (unsigned i=0; i<c; ++i) 140 | Signal(); 141 | } 142 | 143 | void Wait() { 144 | std::unique_lock<std::mutex> lock{mtx}; 145 | cv.wait(lock, [&] { return count > 0; }); 146 | --count; 147 | } 148 | bool Wait(uint32_t millis) { 149 | std::unique_lock<std::mutex> lock{mtx}; 150 | if (!cv.wait_for(lock, std::chrono::milliseconds(millis), [&] { return count > 0; })) 151 | return false; 152 | --count; 153 | return true; 154 | } 155 | 156 | protected: 157 | std::condition_variable cv; 158 | std::mutex mtx; 159 | unsigned count; 160 | #endif 161 | 162 | private: 163 | Semaphore(const Semaphore&); 164 | Semaphore& operator=(const Semaphore&); 165 | }; 166 | /*----------------------------------------------------------------*/ 167 | 168 | } // namespace SEACAVE 169 | 170 | #endif // __SEACAVE_SEMAPHORE_H__ 171 | -------------------------------------------------------------------------------- /libs/Common/Sphere.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Sphere.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_SPHERE_H__ 9 | #define __SEACAVE_SPHERE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | 18 | namespace SEACAVE { 19 | 20 | // S T R U C T S /////////////////////////////////////////////////// 21 | 22 | // Basic sphere class 23 | template <typename TYPE, int DIMS> 24 | class TSphere 25 | { 26 | STATIC_ASSERT(DIMS > 1 && DIMS <= 3); 27 | 28 | public: 29 | typedef TYPE Type; 30 | typedef Eigen::Matrix<TYPE,DIMS,1> POINT; 31 | 32 | POINT center; // sphere center point 33 | TYPE radius; // sphere radius 34 | 35 | //--------------------------------------- 36 | 37 | inline TSphere() {} 38 | inline TSphere(const POINT& c, TYPE r) : center(c), radius(r) {} 39 | inline TSphere(const POINT& p1, const POINT& p2, const POINT& p3); 40 | 41 | inline void Set(const POINT& c, TYPE r); 42 | inline void Set(const POINT& p1, const POINT& p2, const POINT& p3); 43 | 44 | inline void Enlarge(TYPE); 45 | inline void EnlargePercent(TYPE); 46 | 47 | inline GCLASS Classify(const POINT&) const; 48 | }; // class TSphere 49 | /*----------------------------------------------------------------*/ 50 | 51 | #include "Sphere.inl" 52 | /*----------------------------------------------------------------*/ 53 | 54 | } // namespace SEACAVE 55 | 56 | #endif // __SEACAVE_SPHERE_H__ 57 | -------------------------------------------------------------------------------- /libs/Common/Sphere.inl: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Sphere.inl 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | 9 | // D E F I N E S /////////////////////////////////////////////////// 10 | 11 | 12 | // S T R U C T S /////////////////////////////////////////////////// 13 | 14 | template <typename TYPE, int DIMS> 15 | inline TSphere<TYPE,DIMS>::TSphere(const POINT& p1, const POINT& p2, const POINT& p3) 16 | { 17 | Set(p1, p2, p3); 18 | } // constructor 19 | /*----------------------------------------------------------------*/ 20 | 21 | 22 | template <typename TYPE, int DIMS> 23 | inline void TSphere<TYPE,DIMS>::Set(const POINT& c, TYPE r) 24 | { 25 | center = c; 26 | radius = r; 27 | } 28 | template <typename TYPE, int DIMS> 29 | inline void TSphere<TYPE, DIMS>::Set(const POINT& p1, const POINT& p2, const POINT& p3) 30 | { 31 | // compute relative distances 32 | TYPE A((p1 - p2).squaredNorm()); 33 | TYPE B((p2 - p3).squaredNorm()); 34 | TYPE C((p3 - p1).squaredNorm()); 35 | 36 | // re-orient triangle (make A longest side) 37 | const POINT *a(&p3), *b(&p1), *c(&p2); 38 | if (B < C) std::swap(B, C), std::swap(b, c); 39 | if (A < B) std::swap(A, B), std::swap(a, b); 40 | 41 | // if obtuse 42 | if (B + C <= A) { 43 | // just use longest diameter 44 | radius = SQRT(A) / TYPE(2); 45 | center = (*b + *c) / TYPE(2); 46 | } else { 47 | // otherwise circumscribe (http://en.wikipedia.org/wiki/Circumscribed_circle) 48 | const TYPE cos_a(SQUARE(B + C - A) / (B*C*TYPE(4))); 49 | radius = SQRT(A / ((TYPE(1) - cos_a)*TYPE(4))); 50 | const POINT alpha(*a - *c), beta(*b - *c); 51 | const POINT alphaXbeta(alpha.cross(beta)); 52 | center = (beta * alpha.squaredNorm() - alpha * beta.squaredNorm()).cross(alphaXbeta) / 53 | (alphaXbeta.squaredNorm() * TYPE(2)) + *c; 54 | } 55 | } 56 | /*----------------------------------------------------------------*/ 57 | 58 | 59 | template <typename TYPE, int DIMS> 60 | inline void TSphere<TYPE,DIMS>::Enlarge(TYPE x) 61 | { 62 | radius += x; 63 | } 64 | template <typename TYPE, int DIMS> 65 | inline void TSphere<TYPE,DIMS>::EnlargePercent(TYPE x) 66 | { 67 | radius *= x; 68 | } // Enlarge 69 | /*----------------------------------------------------------------*/ 70 | 71 | 72 | // Classify point to sphere. 73 | template <typename TYPE, int DIMS> 74 | inline GCLASS TSphere<TYPE, DIMS>::Classify(const POINT& p) const 75 | { 76 | if ((center - p).squaredNorm() > SQUARE(radius)) 77 | return CULLED; 78 | return VISIBLE; 79 | } 80 | /*----------------------------------------------------------------*/ 81 | -------------------------------------------------------------------------------- /libs/Common/Timer.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Timer.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | #include "Timer.h" 10 | 11 | using namespace SEACAVE; 12 | 13 | 14 | // D E F I N E S /////////////////////////////////////////////////// 15 | 16 | 17 | // S T R U C T S /////////////////////////////////////////////////// 18 | 19 | /** 20 | * Constructor 21 | */ 22 | Timer::Timer(uint8_t nHH, uint8_t nMM) 23 | { 24 | m_fElapsedTime = 1.f; 25 | m_fTimeScale = 1.f; 26 | #ifdef FIX_FPS 27 | m_fCurrentFramesTime = 0.f; 28 | m_nCurrentFrames = 0; 29 | m_nLastSecFrames = 0; 30 | #endif // FIX_FPS 31 | 32 | // set clock 33 | m_fClock = 0.f; 34 | if (nHH > 23) 35 | nHH = 0; 36 | if (nMM > 59) 37 | nMM = 0; 38 | m_nHH = nHH; 39 | m_nMM = nMM; 40 | m_nSS = 0; 41 | 42 | m_nCrntTime = GetSysTime(); 43 | } // constructor 44 | /*----------------------------------------------------------------*/ 45 | 46 | 47 | Timer::~Timer() 48 | { 49 | } 50 | /*----------------------------------------------------------------*/ 51 | 52 | 53 | /** 54 | * Counts the actual time and adjusts clock. 55 | */ 56 | void Timer::Update() 57 | { 58 | const SysType timeNow = GetSysTime(); 59 | m_fElapsedTime = SysTime2Time(timeNow - m_nCrntTime); 60 | m_nCrntTime = timeNow; 61 | 62 | #ifdef FIX_FPS 63 | // compute FPS 64 | ++m_nCurrentFrames; 65 | if ((m_fCurrentFramesTime += m_fElapsedTime) >= 1.f) { 66 | m_nLastSecFrames = (uint32_t)((Type)m_nCurrentFrames/m_fCurrentFramesTime); 67 | m_fCurrentFramesTime = 0.f; 68 | m_nCurrentFrames = 0; 69 | } 70 | #endif // FIX_FPS 71 | 72 | // adjust clock by seconds passed 73 | m_fClock += (m_fElapsedTime * m_fTimeScale); 74 | if (m_fClock >= 1.f) { 75 | m_nSS++; 76 | m_fClock = 0.f; 77 | } 78 | if (m_nSS >= 60) { 79 | m_nMM++; 80 | m_nSS = 0; 81 | } 82 | if (m_nMM >= 60) { 83 | m_nHH++; 84 | m_nMM = 0; 85 | } 86 | if (m_nHH >= 24) 87 | m_nHH = 0; 88 | } // Update 89 | /*----------------------------------------------------------------*/ 90 | 91 | 92 | /** 93 | * Sets the clock to any given starting time. 94 | */ 95 | void Timer::SetClock(uint8_t nHH, uint8_t nMM) 96 | { 97 | // set clock 98 | if (nHH > 23) 99 | nHH = 0; 100 | if (nMM > 59) 101 | nMM = 0; 102 | 103 | m_nHH = nHH; 104 | m_nMM = nMM; 105 | } // SetClock 106 | /*----------------------------------------------------------------*/ 107 | 108 | 109 | /** 110 | * Gives you a time string with hours, minutes and seconds as return 111 | * and hours and/or minutes as reference parameters. 112 | */ 113 | LPTSTR Timer::GetClock(uint8_t* nHH, uint8_t* nMM, LPTSTR szChar) const 114 | { 115 | if (nHH != NULL) 116 | *nHH = m_nHH; 117 | if (nMM != NULL) 118 | *nMM = m_nMM; 119 | 120 | if (szChar == NULL) 121 | return NULL; 122 | 123 | _sntprintf(szChar, 32, "%.2d:%.2d:%.2d", m_nHH, m_nMM, m_nSS); 124 | return szChar; 125 | } // GetClock 126 | /*----------------------------------------------------------------*/ 127 | 128 | 129 | #ifdef TIMER_OLDSUPPORT 130 | // Check performance counter 131 | bool HasPerfCounter() 132 | { 133 | SysType nPerfCnt; 134 | return QueryPerformanceFrequency((LARGE_INTEGER*)&nPerfCnt) == TRUE; 135 | } 136 | const bool Timer::ms_bPerfFlag = HasPerfCounter(); 137 | /*----------------------------------------------------------------*/ 138 | #endif 139 | 140 | 141 | // Get system time factor used to convert to milliseconds 142 | Timer::Type GetSysTimeFactor() 143 | { 144 | #ifdef _MSC_VER 145 | Timer::SysType nPerfCnt; 146 | const BOOL bPerfFlag = QueryPerformanceFrequency((LARGE_INTEGER*)&nPerfCnt); 147 | #ifdef TIMER_OLDSUPPORT 148 | // either QueryPerformanceCounter or GetTickCount 149 | return (bPerfFlag ? 1000.f / nPerfCnt : 1.f); 150 | #else 151 | ASSERT(bPerfFlag); 152 | return 1000.f / nPerfCnt; 153 | #endif 154 | #else // _MSC_VER 155 | return 0.001f; 156 | #endif // _MSC_VER 157 | } 158 | const Timer::Type Timer::ms_fTimeFactor = GetSysTimeFactor(); 159 | /*----------------------------------------------------------------*/ 160 | 161 | Timer::Type Timer::GetTimeFactor() 162 | { 163 | return ms_fTimeFactor; 164 | } 165 | /*----------------------------------------------------------------*/ 166 | -------------------------------------------------------------------------------- /libs/Common/Timer.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Timer.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_TIMER_H__ 9 | #define __SEACAVE_TIMER_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | #ifdef _MSC_VER 18 | //#define TIMER_OLDSUPPORT 19 | #endif 20 | #define FIX_FPS 21 | 22 | 23 | namespace SEACAVE { 24 | 25 | // S T R U C T S /////////////////////////////////////////////////// 26 | 27 | class GENERAL_API Timer 28 | { 29 | public: 30 | typedef int64_t SysType; 31 | typedef float Type; 32 | 33 | public: 34 | Timer(uint8_t nHH=0, uint8_t nMM=0); 35 | ~Timer(); 36 | 37 | void Update(); 38 | 39 | void SetClock(uint8_t nHH, uint8_t nMM); 40 | LPTSTR GetClock(uint8_t* nHH, uint8_t* nMM, LPTSTR szChar) const; 41 | 42 | #ifdef FIX_FPS 43 | inline uint32_t GetFPS() const { return m_nLastSecFrames; } 44 | #else 45 | inline uint32_t GetFPS() const { return (uint32_t)(1.f / m_fElapsedTime); } 46 | #endif // FIX_FPS 47 | 48 | inline Type GetRealCurrent() const { return SysTime2Time(m_nCrntTime); } 49 | inline Type GetCurrent() const { return m_fTimeScale * SysTime2Time(m_nCrntTime); } 50 | inline Type GetRealElapsed() const { return m_fElapsedTime; } 51 | inline Type GetElapsed() const { return m_fTimeScale * m_fElapsedTime; } 52 | inline Type GetDelay(Type d) const { return m_fTimeScale * d; } 53 | inline Type GetScale() const { return m_fTimeScale; } 54 | inline void SetScale(Type fFactor) { m_fTimeScale = fFactor; } 55 | 56 | private: 57 | SysType m_nCrntTime; // current time 58 | Type m_fElapsedTime; // time elapsed since previous frame 59 | Type m_fTimeScale; // slowdown or speedup 60 | uint8_t m_nHH; // clock time hours 61 | uint8_t m_nMM; // clock time minutes 62 | uint8_t m_nSS; // clock time seconds 63 | Type m_fClock; // sum up milliseconds 64 | #ifdef FIX_FPS 65 | Type m_fCurrentFramesTime; // time elapsed for the current frames 66 | uint32_t m_nCurrentFrames; // counter of the current frames 67 | uint32_t m_nLastSecFrames; // counter of the frames in the last second 68 | #endif // FIX_FPS 69 | 70 | public: 71 | // get current time in system units 72 | static inline SysType GetSysTime() { 73 | #ifdef _MSC_VER 74 | #ifdef TIMER_OLDSUPPORT 75 | if (!ms_bPerfFlag) 76 | return GetTickCount(); 77 | #endif 78 | SysType nTime; 79 | QueryPerformanceCounter((LARGE_INTEGER*)&nTime); 80 | return nTime; 81 | #else 82 | timeval tv; 83 | gettimeofday(&tv, NULL); 84 | return (tv.tv_sec * 1000000) + tv.tv_usec; 85 | #endif // _MSC_VER 86 | } 87 | // get milliseconds scaling factor for time 88 | static Type GetTimeFactor(); 89 | // get current time in milliseconds 90 | static inline Type GetTimeMs() { 91 | return GetTimeFactor() * GetSysTime(); 92 | } 93 | // get current time in seconds 94 | static inline Type GetTime() { 95 | return 0.001f * GetTimeFactor() * GetSysTime(); 96 | } 97 | // convert given time to milliseconds 98 | static inline Type SysTime2TimeMs(SysType t) { 99 | return GetTimeFactor() * t; 100 | } 101 | // convert given time to seconds 102 | static inline Type SysTime2Time(SysType t) { 103 | return 0.001f * GetTimeFactor() * t; 104 | } 105 | 106 | protected: 107 | #ifdef TIMER_OLDSUPPORT 108 | static const bool ms_bPerfFlag; // flag for timer to use 109 | #endif 110 | static const Type ms_fTimeFactor; // milliseconds scaling factor for time 111 | }; 112 | /*----------------------------------------------------------------*/ 113 | 114 | 115 | class GENERAL_API AutoTimer 116 | { 117 | public: 118 | typedef Timer::Type Type; 119 | public: 120 | AutoTimer(Type& duration) : m_duration(duration) { m_duration = Timer::GetTime(); } 121 | ~AutoTimer() { m_duration = Timer::GetTime() - m_duration; } 122 | protected: 123 | Type& m_duration; 124 | }; 125 | 126 | class GENERAL_API AutoAddTimer 127 | { 128 | public: 129 | typedef Timer::Type Type; 130 | public: 131 | AutoAddTimer(Type& duration) : m_duration(duration) { m_lastTime = Timer::GetTime(); } 132 | ~AutoAddTimer() { m_duration += Timer::GetTime() - m_lastTime; } 133 | protected: 134 | Type& m_duration; 135 | Type m_lastTime; 136 | }; 137 | /*----------------------------------------------------------------*/ 138 | 139 | } // namespace SEACAVE 140 | 141 | #endif // __SEACAVE_TIMER_H__ 142 | -------------------------------------------------------------------------------- /libs/Common/Types.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Types.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | #include "Types.h" 10 | 11 | 12 | // D E F I N E S /////////////////////////////////////////////////// 13 | 14 | 15 | // S T R U C T S /////////////////////////////////////////////////// 16 | 17 | 18 | // G L O B A L S /////////////////////////////////////////////////// 19 | 20 | #ifndef _MSC_VER 21 | int _vscprintf(LPCSTR format, va_list pargs) { 22 | va_list argcopy; 23 | va_copy(argcopy, pargs); 24 | const int retval(vsnprintf(NULL, 0, format, argcopy)); 25 | va_end(argcopy); 26 | return retval; 27 | } 28 | #endif 29 | /*----------------------------------------------------------------*/ 30 | 31 | 32 | namespace SEACAVE { 33 | 34 | const ColorType<uint8_t>::value_type ColorType<uint8_t>::ONE(255); 35 | const ColorType<uint8_t>::alt_type ColorType<uint8_t>::ALTONE(1.f); 36 | 37 | const ColorType<uint32_t>::value_type ColorType<uint32_t>::ONE(255); 38 | const ColorType<uint32_t>::alt_type ColorType<uint32_t>::ALTONE(1.f); 39 | 40 | const ColorType<float>::value_type ColorType<float>::ONE(1.f); 41 | const ColorType<float>::alt_type ColorType<float>::ALTONE(255); 42 | 43 | const ColorType<double>::value_type ColorType<double>::ONE(1.0); 44 | const ColorType<double>::alt_type ColorType<double>::ALTONE(255); 45 | /*----------------------------------------------------------------*/ 46 | 47 | 48 | // print matrix 49 | template<typename TYPE> 50 | String cvMat2String(const TYPE* M, uint32_t rows, uint32_t cols, uint32_t step, LPCSTR format) { 51 | String str; 52 | char buf[32]; 53 | if (step == 0) 54 | step = rows; 55 | for (uint32_t i=0; i<rows; ++i) { 56 | const TYPE* Mi = M+i*step; 57 | for (uint32_t j=0; j<cols; ++j) { 58 | _sntprintf(buf, 32, format, Mi[j]); 59 | str += buf; 60 | } 61 | str += _T("\n"); 62 | } 63 | return str; 64 | } 65 | String cvMat2String(const cv::Mat& M, LPCSTR format) { 66 | switch (M.type()) { 67 | case CV_32F: return cvMat2String(M.ptr<float>(), (uint32_t)M.rows, (uint32_t)M.cols, (uint32_t)M.step1(), format); 68 | case CV_64F: return cvMat2String(M.ptr<double>(), (uint32_t)M.rows, (uint32_t)M.cols, (uint32_t)M.step1(), format); 69 | } 70 | return String(); 71 | } 72 | /*----------------------------------------------------------------*/ 73 | 74 | } // namespace SEACAVE 75 | 76 | 77 | // C L A S S ////////////////////////////////////////////////////// 78 | 79 | -------------------------------------------------------------------------------- /libs/Common/UtilCUDADevice.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // UtilCUDADevice.h 3 | // 4 | // Copyright 2024 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_CUDA_DEVICE_H__ 9 | #define __SEACAVE_CUDA_DEVICE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Config.h" 15 | 16 | // CUDA driver 17 | #include <cuda.h> 18 | 19 | // CUDA toolkit 20 | #include <cuda_runtime.h> 21 | 22 | #include <memory> 23 | 24 | 25 | // D E F I N E S /////////////////////////////////////////////////// 26 | 27 | #if __CUDA_ARCH__ > 0 28 | #define __CDC__CUDA__ARCH__ 1 29 | #else 30 | #undef __CDC__CUDA__ARCH__ 31 | #endif 32 | 33 | #ifndef VERBOSE 34 | #define DEFINE_VERBOSE 1 35 | #define VERBOSE(...) fprintf(stderr, __VA_ARGS__) 36 | #endif 37 | 38 | // check for CUDA errors following a CUDA call 39 | #define CUDA_CHECK(condition) SEACAVE::CUDA::checkCudaCall(condition) 40 | 41 | // check cudaGetLastError() for success 42 | #define CUDA_CHECK_LAST_ERROR CUDA_CHECK(cudaGetLastError()); 43 | 44 | 45 | // S T R U C T S /////////////////////////////////////////////////// 46 | 47 | namespace SEACAVE { 48 | 49 | namespace CUDA { 50 | 51 | inline void checkCudaCall(const cudaError_t error) { 52 | if (error == cudaSuccess) 53 | return; 54 | VERBOSE("CUDA error at %s:%d: %s (code %d)", __FILE__, __LINE__, cudaGetErrorString(error), error); 55 | ASSERT("CudaError" == NULL); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | // define smart pointers for CUDA stream 60 | struct CudaStreamDestructor { 61 | void operator()(cudaStream_t s) { 62 | if (s) 63 | CUDA_CHECK(cudaStreamDestroy(s)); 64 | } 65 | }; 66 | 67 | typedef std::unique_ptr<std::remove_pointer<cudaStream_t>::type, CudaStreamDestructor> CudaStreamPtr; 68 | inline CudaStreamPtr CreateStream() { 69 | cudaStream_t stream; 70 | CUDA_CHECK(cudaStreamCreate(&stream)); 71 | return CudaStreamPtr(stream, CudaStreamDestructor()); 72 | } 73 | 74 | typedef std::shared_ptr<std::remove_pointer<cudaStream_t>::type> CudaStreamSharedPtr; 75 | inline CudaStreamSharedPtr CreateSharedStream() { 76 | cudaStream_t stream; 77 | CUDA_CHECK(cudaStreamCreate(&stream)); 78 | return CudaStreamSharedPtr(stream, CudaStreamDestructor()); 79 | } 80 | /*----------------------------------------------------------------*/ 81 | 82 | } // namespace CUDA 83 | 84 | } // namespace SEACAVE 85 | 86 | #ifdef DEFINE_VERBOSE 87 | #undef DEFINE_VERBOSE 88 | #undef VERBOSE 89 | #endif 90 | 91 | #endif // __SEACAVE_CUDA_DEVICE_H__ 92 | -------------------------------------------------------------------------------- /libs/IO/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Macro to check pkg-config modules and produce a full-path library list 2 | macro(pkg_check_modules_fullpath_libs PREFIX MODULE_NAME) 3 | # Call pkg_check_modules 4 | pkg_check_modules(${PREFIX} REQUIRED IMPORTED_TARGET ${MODULE_NAME}) 5 | if(${PREFIX}_FOUND) 6 | set(${PREFIX}_FULLPATH_LIBRARIES "" PARENT_SCOPE) 7 | foreach(lib ${${PREFIX}_LIBRARIES}) 8 | set(lib_path "") 9 | set(lib_prefix "") 10 | set(lib_ext "") 11 | if(WIN32) 12 | set(lib_ext ".lib") 13 | else() 14 | set(lib_prefix "lib") 15 | set(lib_ext ".a") 16 | endif() 17 | # Skip system libraries like 'm' on Windows 18 | if(WIN32 AND (lib STREQUAL "m")) 19 | continue() 20 | endif() 21 | # If lib already has a path, use as is 22 | if(EXISTS "${lib_prefix}${lib}${lib_ext}") 23 | set(lib_path "${lib_prefix}${lib}${lib_ext}") 24 | else() 25 | foreach(dir ${${PREFIX}_LIBRARY_DIRS}) 26 | if(EXISTS "${dir}/${lib_prefix}${lib}${lib_ext}") 27 | set(lib_path "${dir}/${lib_prefix}${lib}${lib_ext}") 28 | break() 29 | endif() 30 | endforeach() 31 | endif() 32 | if(NOT lib_path STREQUAL "") 33 | list(APPEND ${PREFIX}_FULLPATH_LIBRARIES "${lib_path}") 34 | else() 35 | list(APPEND ${PREFIX}_FULLPATH_LIBRARIES "${lib}") 36 | endif() 37 | endforeach() 38 | set(${PREFIX}_FULLPATH_LIBRARIES "${${PREFIX}_FULLPATH_LIBRARIES}" PARENT_SCOPE) 39 | message(STATUS "Found ${MODULE_NAME}: ${${PREFIX}_VERSION} libs: ${${PREFIX}_FULLPATH_LIBRARIES}") 40 | else() 41 | set(${PREFIX}_FULLPATH_LIBRARIES "" PARENT_SCOPE) 42 | message(STATUS "${MODULE_NAME} not found, support will be disabled") 43 | endif() 44 | endmacro() 45 | 46 | # Find required packages 47 | FIND_PACKAGE(PNG QUIET) 48 | if(PNG_FOUND) 49 | INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIRS}) 50 | ADD_DEFINITIONS(${PNG_DEFINITIONS}) 51 | SET(_USE_PNG TRUE CACHE INTERNAL "") 52 | else() 53 | SET(PNG_LIBRARIES "") 54 | endif() 55 | FIND_PACKAGE(JPEG QUIET) 56 | if(JPEG_FOUND) 57 | INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) 58 | ADD_DEFINITIONS(${JPEG_DEFINITIONS}) 59 | SET(_USE_JPG TRUE CACHE INTERNAL "") 60 | else() 61 | SET(JPEG_LIBRARIES "") 62 | endif() 63 | FIND_PACKAGE(PkgConfig REQUIRED) 64 | pkg_check_modules_fullpath_libs(JPEGXL libjxl) 65 | if(JPEGXL_FOUND) 66 | SET(_USE_JXL TRUE CACHE INTERNAL "") 67 | set(JPEGXL_LIBRARIES ${JPEGXL_FULLPATH_LIBRARIES}) 68 | else() 69 | SET(JPEGXL_LIBRARIES "") 70 | endif() 71 | FIND_PACKAGE(TIFF QUIET) 72 | if(TIFF_FOUND) 73 | INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) 74 | ADD_DEFINITIONS(${TIFF_DEFINITIONS}) 75 | SET(_USE_TIFF TRUE CACHE INTERNAL "") 76 | else() 77 | SET(TIFF_LIBRARIES "") 78 | endif() 79 | 80 | # List sources files 81 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 82 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 83 | 84 | cxx_library_with_type(IO "Libs" "" "${cxx_default}" 85 | ${LIBRARY_FILES_C} ${LIBRARY_FILES_H} 86 | ) 87 | 88 | # Manually set Common.h as the precompiled header 89 | IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) 90 | TARGET_PRECOMPILE_HEADERS(IO PRIVATE "Common.h") 91 | endif() 92 | 93 | # Link its dependencies 94 | TARGET_LINK_LIBRARIES(IO Common ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${JPEGXL_LIBRARIES} ${TIFF_LIBRARIES} ${EXIV2_LIBS}) 95 | 96 | # Install 97 | SET_TARGET_PROPERTIES(IO PROPERTIES 98 | PUBLIC_HEADER "${LIBRARY_FILES_H}") 99 | INSTALL(TARGETS IO 100 | EXPORT OpenMVSTargets 101 | LIBRARY DESTINATION "${INSTALL_LIB_DIR}" 102 | ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 103 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 104 | PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/IO") 105 | -------------------------------------------------------------------------------- /libs/IO/Common.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Common.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // Source file that includes just the standard includes 9 | // Common.pch will be the pre-compiled header 10 | // Common.obj will contain the pre-compiled type information 11 | 12 | #include "Common.h" 13 | -------------------------------------------------------------------------------- /libs/IO/Common.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Common.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __IO_COMMON_H__ 9 | #define __IO_COMMON_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #if defined(IO_EXPORTS) && !defined(Common_EXPORTS) 15 | #define Common_EXPORTS 16 | #endif 17 | 18 | #include "../Common/Common.h" 19 | 20 | #ifndef IO_API 21 | #define IO_API GENERAL_API 22 | #endif 23 | #ifndef IO_TPL 24 | #define IO_TPL GENERAL_TPL 25 | #endif 26 | 27 | #define _IMAGE_BMP // add BMP support 28 | #define _IMAGE_TGA // add TGA support 29 | #define _IMAGE_DDS // add DDS support 30 | #ifdef _USE_PNG 31 | #define _IMAGE_PNG // add PNG support 32 | #endif 33 | #ifdef _USE_JPG 34 | #define _IMAGE_JPG // add JPG support 35 | #endif 36 | #ifdef _USE_JXL 37 | #define _IMAGE_JXL // add JpegXL support 38 | #endif 39 | #ifdef _USE_TIFF 40 | #define _IMAGE_TIFF // add TIFF support 41 | #endif 42 | 43 | #include "ImageSCI.h" 44 | #ifdef _IMAGE_BMP 45 | #include "ImageBMP.h" 46 | #endif 47 | #ifdef _IMAGE_TGA 48 | #include "ImageTGA.h" 49 | #endif 50 | #ifdef _IMAGE_DDS 51 | #include "ImageDDS.h" 52 | #endif 53 | #ifdef _IMAGE_PNG 54 | #include "ImagePNG.h" 55 | #endif 56 | #ifdef _IMAGE_JPG 57 | #include "ImageJPG.h" 58 | #endif 59 | #ifdef _IMAGE_TIFF 60 | #include "ImageTIFF.h" 61 | #endif 62 | #ifdef _IMAGE_JXL 63 | #include "ImageJXL.h" 64 | #endif 65 | #include "PLY.h" 66 | #include "OBJ.h" 67 | /*----------------------------------------------------------------*/ 68 | 69 | #endif // __IO_COMMON_H__ 70 | -------------------------------------------------------------------------------- /libs/IO/Image.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Image.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGE_H__ 9 | #define __SEACAVE_IMAGE_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | #define LT_IMAGE CImage::ms_nLogType 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | // All formats are listed from left to right, most-significant bit to least-significant bit. 25 | // For example, PF_A8R8G8B8 is ordered from the most-significant bit channel A (alpha), 26 | // to the least-significant bit channel B (blue). When traversing image data, the data is 27 | // stored in memory on a little-endian machine from least-significant bit to most-significant bit, 28 | // which means that the channel order in memory is from least-significant bit (blue) to 29 | // most-significant bit (alpha). 30 | typedef enum PIXELFORMAT_TYPE { 31 | PF_UNKNOWN = 0, 32 | // gray 33 | PF_A8, 34 | PF_GRAY8, 35 | PF_GRAY32F, // 1 channel, 32-bit float (depth map) 36 | // uncompressed RGB 37 | PF_R5G6B5, 38 | PF_R8G8B8, 39 | PF_R8G8B8A8, 40 | PF_A8R8G8B8, 41 | // uncompressed BGR 42 | PF_B8G8R8, 43 | PF_B8G8R8A8, 44 | PF_A8B8G8R8, 45 | // compressed 46 | PF_DXT1 = 128, 47 | PF_DXT2, 48 | PF_DXT3, 49 | PF_DXT4, 50 | PF_DXT5, 51 | PF_3DC, 52 | } PIXELFORMAT; 53 | 54 | class IO_API CImage 55 | { 56 | DECLARE_LOG(); 57 | 58 | public: 59 | enum IMCREATE { 60 | READ, 61 | WRITE 62 | }; 63 | typedef uint32_t Size; 64 | 65 | CImage() {} 66 | virtual ~CImage() {} 67 | 68 | virtual HRESULT Reset(Size width, Size height, PIXELFORMAT pixFormat, Size levels = 1, bool bAllocate = false); 69 | virtual HRESULT Reset(LPCTSTR szFileName, IMCREATE mode); 70 | virtual HRESULT Reset(IOSTREAMPTR& pStream); 71 | virtual void Close(); 72 | 73 | virtual HRESULT ReadHeader(); 74 | virtual HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 75 | 76 | virtual HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 77 | virtual HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 78 | 79 | const IOSTREAMPTR& GetStream() const { return m_pStream; } 80 | IOSTREAMPTR& GetStream() { return m_pStream; } 81 | BYTE* GetData() const { return m_data; } 82 | BYTE*& GetData() { return m_data; } 83 | size_t GetDataSize() const { return m_lineWidth * m_dataHeight; } 84 | Size GetWidth() const { return m_width; } 85 | Size GetHeight() const { return m_height; } 86 | Size GetDataWidth() const { return m_dataWidth; } 87 | Size GetDataHeight() const { return m_dataHeight; } 88 | Size GetStride() const { return m_stride; } 89 | Size GetLineWidth() const { return m_lineWidth; } 90 | BYTE GetNumLevels() const { return m_numLevels; } 91 | PIXELFORMAT GetFormat() const { return m_format; } 92 | bool FormatHasAlpha() const { return FormatHasAlpha(m_format); } 93 | const String& GetFileName() const { return m_fileName; } 94 | String& GetFileName() { return m_fileName; } 95 | 96 | Size GetDataSizes(Size mipLevel, Size& width, Size& height) const; 97 | 98 | static Size GetStride(PIXELFORMAT); //in bits 99 | static bool FormatHasAlpha(PIXELFORMAT); 100 | static bool FilterFormat(void*, PIXELFORMAT, Size, const void*, PIXELFORMAT, Size, Size nSzize); 101 | static void FlipRB24(uint8_t* data, Size size, Size stride); 102 | static void CopyFlipRB24(uint8_t* pDst, const uint8_t* pSrc, Size size, Size strideDst, Size strideSrc); 103 | 104 | static CImage* Create(LPCTSTR szName, IMCREATE mode); 105 | 106 | #ifndef _RELEASE 107 | void Dump(LPCTSTR szFileName); 108 | #endif 109 | 110 | protected: 111 | IOSTREAMPTR m_pStream; // stream used to read/write the image data 112 | CAutoPtrArr<BYTE> m_data; // image's data buffer 113 | Size m_width; // image width in pixels 114 | Size m_height; // image height in pixels 115 | Size m_dataWidth; // image's data width including mipmaps 116 | Size m_dataHeight; // image's data height 117 | Size m_stride; // bytes per pixel 118 | Size m_lineWidth; // image canvas width in bytes 119 | PIXELFORMAT m_format; // image format (pixel type) 120 | BYTE m_numLevels; // number of mipmap levels (0 = auto-generate) 121 | BYTE m_level; // index of the mipmap level currently reading 122 | String m_fileName; // image's file name 123 | }; // class CImage 124 | typedef CSharedPtr<CImage> IMAGEPTR; 125 | /*----------------------------------------------------------------*/ 126 | 127 | } // namespace SEACAVE 128 | 129 | #endif // __SEACAVE_IMAGE_H__ 130 | -------------------------------------------------------------------------------- /libs/IO/ImageBMP.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageBMP.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGEBMP_H__ 9 | #define __SEACAVE_IMAGEBMP_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Image.h" 15 | 16 | 17 | namespace SEACAVE { 18 | 19 | // S T R U C T S /////////////////////////////////////////////////// 20 | 21 | class IO_API CImageBMP : public CImage 22 | { 23 | public: 24 | CImageBMP(); 25 | virtual ~CImageBMP(); 26 | 27 | HRESULT ReadHeader(); 28 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 29 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 30 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 31 | }; // class CImageBMP 32 | /*----------------------------------------------------------------*/ 33 | 34 | } // namespace SEACAVE 35 | 36 | #endif // __SEACAVE_IMAGEBMP_H__ 37 | -------------------------------------------------------------------------------- /libs/IO/ImageDDS.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageDDS.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGEDDS_H__ 9 | #define __SEACAVE_IMAGEDDS_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Image.h" 15 | 16 | 17 | namespace SEACAVE { 18 | 19 | // S T R U C T S /////////////////////////////////////////////////// 20 | 21 | class IO_API CImageDDS : public CImage 22 | { 23 | public: 24 | CImageDDS(); 25 | virtual ~CImageDDS(); 26 | 27 | HRESULT ReadHeader(); 28 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 29 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 30 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 31 | }; // class CImageDDS 32 | /*----------------------------------------------------------------*/ 33 | 34 | } // namespace SEACAVE 35 | 36 | #endif // __SEACAVE_IMAGEDDS_H__ 37 | -------------------------------------------------------------------------------- /libs/IO/ImageJPG.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageJPG.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGEJPG_H__ 9 | #define __SEACAVE_IMAGEJPG_H__ 10 | 11 | 12 | // D E F I N E S /////////////////////////////////////////////////// 13 | 14 | 15 | // I N C L U D E S ///////////////////////////////////////////////// 16 | 17 | #include "Image.h" 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | class IO_API CImageJPG : public CImage 25 | { 26 | public: 27 | CImageJPG(); 28 | virtual ~CImageJPG(); 29 | 30 | void Close(); 31 | 32 | HRESULT ReadHeader(); 33 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 34 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 35 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 36 | 37 | protected: 38 | void* m_state; 39 | }; // class CImageJPG 40 | /*----------------------------------------------------------------*/ 41 | 42 | } // namespace SEACAVE 43 | 44 | #endif // __SEACAVE_IMAGEJPG_H__ 45 | -------------------------------------------------------------------------------- /libs/IO/ImageJXL.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageJXL.h 3 | // 4 | // Copyright 2025 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGEJXL_H__ 9 | #define __SEACAVE_IMAGEJXL_H__ 10 | 11 | 12 | // D E F I N E S /////////////////////////////////////////////////// 13 | 14 | 15 | // I N C L U D E S ///////////////////////////////////////////////// 16 | 17 | #include "Image.h" 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | class IO_API CImageJXL : public CImage 25 | { 26 | public: 27 | CImageJXL(); 28 | virtual ~CImageJXL(); 29 | 30 | void Close(); 31 | 32 | HRESULT ReadHeader(); 33 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 34 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 35 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 36 | 37 | protected: 38 | void* m_state; // placeholder for JpegXL decoder/encoder state 39 | }; // class CImageJXL 40 | /*----------------------------------------------------------------*/ 41 | 42 | } // namespace SEACAVE 43 | 44 | #endif // __SEACAVE_IMAGEJXL_H__ 45 | -------------------------------------------------------------------------------- /libs/IO/ImagePNG.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImagePNG.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGEPNG_H__ 9 | #define __SEACAVE_IMAGEPNG_H__ 10 | 11 | 12 | // D E F I N E S /////////////////////////////////////////////////// 13 | 14 | 15 | // I N C L U D E S ///////////////////////////////////////////////// 16 | 17 | #include "Image.h" 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | class IO_API CImagePNG : public CImage 25 | { 26 | public: 27 | CImagePNG(); 28 | virtual ~CImagePNG(); 29 | 30 | void Close(); 31 | 32 | HRESULT ReadHeader(); 33 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 34 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 35 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 36 | 37 | protected: 38 | void* m_png_ptr; 39 | void* m_info_ptr; 40 | bool bRead; 41 | }; // class CImagePNG 42 | /*----------------------------------------------------------------*/ 43 | 44 | } // namespace SEACAVE 45 | 46 | #endif // __SEACAVE_IMAGEPNG_H__ 47 | -------------------------------------------------------------------------------- /libs/IO/ImageSCI.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageSCI.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | #include "ImageSCI.h" 10 | 11 | using namespace SEACAVE; 12 | 13 | 14 | // D E F I N E S /////////////////////////////////////////////////// 15 | 16 | #define IMAGE_SCI_TYPE 0x494353 //"SCI" = 3 bytes 17 | #define IMAGE_SCI_VERSION 1 //1 byte 18 | #define IMAGE_SCI_HEADER ((DWORD)((((DWORD)IMAGE_SCI_VERSION)<<24)|(DWORD)IMAGE_SCI_TYPE)) //"SCI"+ver = 4 bytes 19 | 20 | 21 | // S T R U C T S /////////////////////////////////////////////////// 22 | 23 | typedef struct SCIINFOHEADER_TYPE { 24 | uint32_t dwHeader; 25 | uint16_t shWidth; 26 | uint16_t shHeight; 27 | uint8_t byFormat; 28 | uint8_t byLevels; 29 | uint8_t byReserved1; 30 | uint8_t byReserved2; 31 | } SCIINFOHEADER; 32 | 33 | 34 | CImageSCI::CImageSCI() 35 | { 36 | } // Constructor 37 | 38 | CImageSCI::~CImageSCI() 39 | { 40 | } // Destructor 41 | /*----------------------------------------------------------------*/ 42 | 43 | 44 | HRESULT CImageSCI::ReadHeader() 45 | { 46 | // read header 47 | ((ISTREAM*)m_pStream)->setPos(0); 48 | SCIINFOHEADER sciInfo; 49 | m_pStream->read(&sciInfo, sizeof(SCIINFOHEADER)); 50 | if (sciInfo.dwHeader != IMAGE_SCI_HEADER) { 51 | LOG(LT_IMAGE, "error: invalid SCI image"); 52 | return _INVALIDFILE; 53 | } 54 | m_width = sciInfo.shWidth; 55 | m_height = sciInfo.shHeight; 56 | m_numLevels = sciInfo.byLevels; 57 | m_level = 0; 58 | m_format = (PIXELFORMAT)sciInfo.byFormat; 59 | m_stride = GetStride(m_format); 60 | m_lineWidth = GetDataSizes(0, m_dataWidth, m_dataHeight); 61 | return _OK; 62 | } // ReadHeader 63 | /*----------------------------------------------------------------*/ 64 | 65 | 66 | HRESULT CImageSCI::WriteHeader(PIXELFORMAT imageFormat, Size width, Size height, BYTE numLevels) 67 | { 68 | // write header 69 | CImage::WriteHeader(imageFormat, width, height, numLevels); 70 | ((OSTREAM*)m_pStream)->setPos(0); 71 | const SCIINFOHEADER sciInfo = {IMAGE_SCI_HEADER, (uint16_t)m_width, (uint16_t)m_height, (uint8_t)m_format, m_numLevels, 0, 0}; 72 | if (sizeof(SCIINFOHEADER) != m_pStream->write(&sciInfo, sizeof(SCIINFOHEADER))) { 73 | LOG(LT_IMAGE, "error: failed writing the SCI image"); 74 | return _INVALIDFILE; 75 | } 76 | return _OK; 77 | } // WriteHeader 78 | /*----------------------------------------------------------------*/ 79 | -------------------------------------------------------------------------------- /libs/IO/ImageSCI.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageSCI.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGESCI_H__ 9 | #define __SEACAVE_IMAGESCI_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Image.h" 15 | 16 | 17 | namespace SEACAVE { 18 | 19 | // S T R U C T S /////////////////////////////////////////////////// 20 | 21 | class IO_API CImageSCI : public CImage 22 | { 23 | public: 24 | CImageSCI(); 25 | virtual ~CImageSCI(); 26 | 27 | HRESULT ReadHeader(); 28 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 29 | }; // class CImageSCI 30 | /*----------------------------------------------------------------*/ 31 | 32 | } // namespace SEACAVE 33 | 34 | #endif // __SEACAVE_IMAGESCI_H__ 35 | -------------------------------------------------------------------------------- /libs/IO/ImageTGA.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageTGA.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #include "Common.h" 9 | 10 | #ifdef _IMAGE_TGA 11 | #include "ImageTGA.h" 12 | 13 | using namespace SEACAVE; 14 | 15 | 16 | // D E F I N E S /////////////////////////////////////////////////// 17 | 18 | #pragma pack(push, 1) 19 | typedef struct TGAINFOHEADER_TYPE { 20 | BYTE byIDLength; // ID length 21 | BYTE byCMType; // Color map type 22 | BYTE byType; // Image type 23 | struct { // Color map specifications 24 | uint16_t shCMIdx; // First entry index, offset into the color map table 25 | uint16_t shCMLength; // Color map length, number of entries 26 | BYTE byCMBPP; // Color map entry size, number of bits per pixel 27 | }; 28 | struct { // Image specifications 29 | uint16_t shXOrigin; // X-origin, absolute coordinate of lower-left corner for displays where origin is at the lower left 30 | uint16_t shYOrigin; // Y-origin, as for X-origin 31 | uint16_t shWidth; // Image width, width in pixels 32 | uint16_t shHeight; // Image height, width in pixels 33 | BYTE byBPP; // Pixel depth, bits per pixel 34 | union { 35 | BYTE byAlphaInfo; // Image descriptor, bits 3-0 give the alpha channel depth, bits 4-5 give direction 36 | struct { 37 | BYTE byAlphaBPP : 3;// alpha channel depth 38 | BYTE bMirrored : 1;// alpha channel depth 39 | BYTE bFlipped : 1;// alpha channel depth 40 | BYTE : 0;// Force alignment to next boundary. 41 | }; 42 | }; 43 | }; 44 | } TGAINFOHEADER; 45 | #pragma pack(pop) 46 | 47 | 48 | 49 | // S T R U C T S /////////////////////////////////////////////////// 50 | 51 | CImageTGA::CImageTGA() 52 | { 53 | } // Constructor 54 | 55 | CImageTGA::~CImageTGA() 56 | { 57 | } // Destructor 58 | /*----------------------------------------------------------------*/ 59 | 60 | 61 | HRESULT CImageTGA::ReadHeader() 62 | { 63 | // read header 64 | ((ISTREAM*)m_pStream)->setPos(0); 65 | TGAINFOHEADER tgaInfo; 66 | m_pStream->read(&tgaInfo, sizeof(TGAINFOHEADER)); 67 | if (tgaInfo.byCMType != 0) { // paletted images not supported 68 | LOG(LT_IMAGE, "error: invalid TGA image"); 69 | return _INVALIDFILE; 70 | } 71 | 72 | m_dataWidth = m_width = tgaInfo.shWidth; 73 | m_dataHeight = m_height = tgaInfo.shHeight; 74 | m_numLevels = 0; 75 | m_level = 0; 76 | 77 | // get the format 78 | m_stride = (tgaInfo.byBPP>>3); 79 | switch (tgaInfo.byType) 80 | { 81 | case 2: //uncompressed, true-color image 82 | case 3: //uncompressed, black-and-white image 83 | m_format = (m_stride == 3 ? PF_R8G8B8 : PF_R8G8B8A8); 84 | m_bRLE = false; 85 | break; 86 | //case 10://run-length encoded, true-color image and 87 | // m_format = IF_3DC; 88 | // m_bRLE = true; 89 | // break; 90 | default: 91 | ASSERT(0); 92 | LOG(LT_IMAGE, "error: unsupported TGA image"); 93 | return _INVALIDFILE; 94 | } 95 | 96 | m_lineWidth = m_width * m_stride; 97 | 98 | // read the id stuff, not using seeking to be able to use non seekable sources 99 | if (tgaInfo.byIDLength) { 100 | CAutoPtrArr<uint8_t> const buffer(new uint8_t[tgaInfo.byIDLength]); 101 | m_pStream->read(buffer, tgaInfo.byIDLength); 102 | } 103 | 104 | return _OK; 105 | } // ReadHeader 106 | /*----------------------------------------------------------------*/ 107 | 108 | 109 | HRESULT CImageTGA::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, Size lineWidth) 110 | { 111 | // read data 112 | if (dataFormat == m_format && nStride == m_stride) { 113 | // read image directly to the data buffer 114 | (BYTE*&)pData += (m_height-1)*lineWidth; 115 | for (Size j=0; j<m_height; ++j, (uint8_t*&)pData-=lineWidth) 116 | if (m_lineWidth != m_pStream->read(pData, m_lineWidth)) 117 | return _INVALIDFILE; 118 | } else { 119 | // read image to a buffer and convert it 120 | CAutoPtrArr<uint8_t> const buffer(new uint8_t[m_lineWidth]); 121 | for (Size j=0; j<m_height; ++j) { 122 | if (m_lineWidth != m_pStream->read(buffer, m_lineWidth)) 123 | return _INVALIDFILE; 124 | if (!FilterFormat((BYTE*)pData+(m_height-j-1)*lineWidth, dataFormat, nStride, buffer, m_format, m_stride, m_width)) 125 | return _FAIL; 126 | } 127 | } 128 | return _OK; 129 | } // ReadData 130 | /*----------------------------------------------------------------*/ 131 | 132 | 133 | HRESULT CImageTGA::WriteHeader(PIXELFORMAT imageFormat, Size width, Size height, BYTE numLevels) 134 | { 135 | return _FAIL; 136 | } // WriteHeader 137 | /*----------------------------------------------------------------*/ 138 | 139 | 140 | HRESULT CImageTGA::WriteData(void* pData, PIXELFORMAT dataFormat, Size nStride, Size lineWidth) 141 | { 142 | return _FAIL; 143 | } // WriteData 144 | /*----------------------------------------------------------------*/ 145 | 146 | #endif // _IMAGE_TGA 147 | -------------------------------------------------------------------------------- /libs/IO/ImageTGA.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageTGA.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGETGA_H__ 9 | #define __SEACAVE_IMAGETGA_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #include "Image.h" 15 | 16 | 17 | namespace SEACAVE { 18 | 19 | // S T R U C T S /////////////////////////////////////////////////// 20 | 21 | class IO_API CImageTGA : public CImage 22 | { 23 | public: 24 | CImageTGA(); 25 | virtual ~CImageTGA(); 26 | 27 | HRESULT ReadHeader(); 28 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 29 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 30 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 31 | 32 | protected: 33 | bool m_bRLE; 34 | }; // class CImageTGA 35 | /*----------------------------------------------------------------*/ 36 | 37 | } // namespace SEACAVE 38 | 39 | #endif // __SEACAVE_IMAGETGA_H__ 40 | -------------------------------------------------------------------------------- /libs/IO/ImageTIFF.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // ImageTIFF.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_IMAGETIFF_H__ 9 | #define __SEACAVE_IMAGETIFF_H__ 10 | 11 | 12 | // D E F I N E S /////////////////////////////////////////////////// 13 | 14 | 15 | // I N C L U D E S ///////////////////////////////////////////////// 16 | 17 | #include "Image.h" 18 | 19 | 20 | namespace SEACAVE { 21 | 22 | // S T R U C T S /////////////////////////////////////////////////// 23 | 24 | class IO_API CImageTIFF : public CImage 25 | { 26 | public: 27 | CImageTIFF(); 28 | virtual ~CImageTIFF(); 29 | 30 | void Close(); 31 | 32 | HRESULT ReadHeader(); 33 | HRESULT ReadData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 34 | HRESULT WriteHeader(PIXELFORMAT, Size width, Size height, BYTE numLevels); 35 | HRESULT WriteData(void*, PIXELFORMAT, Size nStride, Size lineWidth); 36 | 37 | protected: 38 | void* m_state; 39 | }; // class CImageTIFF 40 | /*----------------------------------------------------------------*/ 41 | 42 | } // namespace SEACAVE 43 | 44 | #endif // __SEACAVE_IMAGETIFF_H__ 45 | -------------------------------------------------------------------------------- /libs/IO/OBJ.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // OBJ.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __SEACAVE_OBJ_H__ 9 | #define __SEACAVE_OBJ_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | 15 | // D E F I N E S /////////////////////////////////////////////////// 16 | 17 | 18 | namespace SEACAVE { 19 | 20 | // S T R U C T S /////////////////////////////////////////////////// 21 | 22 | // OBJ model files parser. 23 | // 24 | // The OBJ file format is a simple data-format that represents 3D geometry alone — 25 | // namely, the position of each vertex, the UV position of each texture coordinate 26 | // vertex, vertex normals, and the faces that make each polygon defined as a list of 27 | // vertices, and texture vertices. Vertices are stored in a counter-clockwise order 28 | // by default, making explicit declaration of face normals unnecessary. 29 | 30 | class IO_API ObjModel { 31 | public: 32 | typedef Pixel32F Color; 33 | 34 | // represents a material lib of an OBJ model 35 | struct MaterialLib { 36 | // represents a Lambertian material 37 | struct Material { 38 | String name; 39 | String diffuse_name; 40 | Image8U3 diffuse_map; 41 | Color Kd; 42 | 43 | Material() : Kd(Color::WHITE) {} 44 | Material(const String& _name) : name(_name), Kd(Color::WHITE) {} 45 | Material(const Image8U3& _diffuse_map, const Color& _Kd=Color::WHITE); 46 | 47 | // Makes sure the image is loaded for the diffuse map 48 | bool LoadDiffuseMap(); 49 | }; 50 | 51 | typedef std::vector<Material> Materials; 52 | 53 | Materials materials; 54 | 55 | MaterialLib(); 56 | 57 | // Saves the material lib to a .mtl file and all textures of its materials with the given prefix name 58 | bool Save(const String& prefix, bool texLossless=false) const; 59 | // Loads the material lib from a .mtl file and all textures of its materials with the given file name 60 | bool Load(const String& fileName); 61 | }; 62 | 63 | typedef Point3f Vertex; 64 | typedef Point2f TexCoord; 65 | typedef Point3f Normal; 66 | 67 | typedef uint32_t Index; 68 | 69 | struct Face { 70 | Index vertices[3]; 71 | Index texcoords[3]; 72 | Index normals[3]; 73 | }; 74 | 75 | struct Group { 76 | String material_name; 77 | std::vector<Face> faces; 78 | }; 79 | 80 | typedef std::vector<Vertex> Vertices; 81 | typedef std::vector<TexCoord> TexCoords; 82 | typedef std::vector<Normal> Normals; 83 | typedef std::vector<Group> Groups; 84 | 85 | protected: 86 | Vertices vertices; 87 | TexCoords texcoords; 88 | Normals normals; 89 | Groups groups; 90 | MaterialLib material_lib; 91 | 92 | public: 93 | ObjModel() {} 94 | 95 | // Saves the obj model to an .obj file, its material lib and the materials with the given file name 96 | bool Save(const String& fileName, unsigned precision=6, bool texLossless=false) const; 97 | // Loads the obj model from an .obj file, its material lib and the materials with the given file name 98 | bool Load(const String& fileName); 99 | 100 | // Creates a new group with the given material name 101 | Group& AddGroup(const String& material_name); 102 | // Retrieves a material from the library based on its name 103 | MaterialLib::Material* GetMaterial(const String& name); 104 | 105 | MaterialLib& get_material_lib() { return material_lib; } 106 | Vertices& get_vertices() { return vertices; } 107 | TexCoords& get_texcoords() { return texcoords; } 108 | Normals& get_normals() { return normals; } 109 | Groups& get_groups() { return groups; } 110 | }; 111 | /*----------------------------------------------------------------*/ 112 | 113 | } // namespace SEACAVE 114 | 115 | #endif // __SEACAVE_OBJ_H__ 116 | -------------------------------------------------------------------------------- /libs/MVS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MVS.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_MVS_H_ 33 | #define _MVS_MVS_H_ 34 | 35 | 36 | // D E F I N E S /////////////////////////////////////////////////// 37 | 38 | #define OpenMVS_VERSION_AT_LEAST(x,y,z) \ 39 | (OpenMVS_MAJOR_VERSION>x || (OpenMVS_MAJOR_VERSION==x && \ 40 | (OpenMVS_MINOR_VERSION>y || (OpenMVS_MINOR_VERSION==y && OpenMVS_PATCH_VERSION>=z)))) 41 | 42 | 43 | // I N C L U D E S ///////////////////////////////////////////////// 44 | 45 | #include "ConfigLocal.h" 46 | #include "Common/Common.h" 47 | #include "IO/Common.h" 48 | #include "Math/Common.h" 49 | #include "MVS/Common.h" 50 | #include "MVS/Scene.h" 51 | 52 | 53 | #endif // _MVS_MVS_H_ 54 | -------------------------------------------------------------------------------- /libs/MVS/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Find required packages 2 | FIND_PACKAGE(CGAL REQUIRED) 3 | if(CGAL_FOUND) 4 | include_directories(${CGAL_INCLUDE_DIRS}) 5 | add_definitions(${CGAL_DEFINITIONS}) 6 | link_directories(${CGAL_LIBRARY_DIRS}) 7 | endif() 8 | 9 | FIND_PACKAGE(VCG REQUIRED) 10 | if(VCG_FOUND) 11 | include_directories(${VCG_INCLUDE_DIRS}) 12 | add_definitions(${VCG_DEFINITIONS}) 13 | endif() 14 | 15 | set(CERES_LIBS "") 16 | if(OpenMVS_USE_CERES) 17 | FIND_PACKAGE(Ceres) 18 | if(CERES_FOUND) 19 | include_directories(${CERES_INCLUDE_DIRS}) 20 | add_definitions(${CERES_DEFINITIONS}) 21 | else() 22 | set(OpenMVS_USE_CERES OFF) 23 | message("-- Can't find CERES. Continuing without it.") 24 | endif() 25 | endif() 26 | 27 | # List sources files 28 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 29 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 30 | if(_USE_CUDA) 31 | FILE(GLOB LIBRARY_FILES_CUDA "*.cu") 32 | LIST(APPEND LIBRARY_FILES_C ${LIBRARY_FILES_CUDA}) 33 | endif() 34 | FILE(GLOB CUDA_LIBRARY_FILES_C "CUDA/*.cpp") 35 | FILE(GLOB CUDA_LIBRARY_FILES_H "CUDA/*.h" "CUDA/*.inl") 36 | if(_USE_CUDA) 37 | FILE(GLOB CUDA_LIBRARY_FILES_CUDA "CUDA/*.cu") 38 | LIST(APPEND CUDA_LIBRARY_FILES_C ${CUDA_LIBRARY_FILES_CUDA}) 39 | endif() 40 | SOURCE_GROUP("CUDA" FILES ${CUDA_LIBRARY_FILES_C} ${CUDA_LIBRARY_FILES_H}) 41 | 42 | GET_FILENAME_COMPONENT(PATH_PythonWrapper_cpp ${CMAKE_CURRENT_SOURCE_DIR}/PythonWrapper.cpp ABSOLUTE) 43 | LIST(REMOVE_ITEM LIBRARY_FILES_C "${PATH_PythonWrapper_cpp}") 44 | 45 | cxx_library_with_type(MVS "Libs" "" "${cxx_default}" 46 | ${LIBRARY_FILES_C} ${LIBRARY_FILES_H} 47 | ${CUDA_LIBRARY_FILES_C} ${CUDA_LIBRARY_FILES_H} 48 | ) 49 | 50 | # Manually set Common.h as the precompiled header 51 | IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) 52 | TARGET_PRECOMPILE_HEADERS(MVS PRIVATE "Common.h") 53 | endif() 54 | 55 | # Link its dependencies 56 | TARGET_LINK_LIBRARIES(MVS PRIVATE Common Math IO CGAL::CGAL ${CERES_LIBRARIES} ${OpenMVS_EXTRA_LIBS}) 57 | 58 | if(OpenMVS_USE_PYTHON) 59 | # Create the Python wrapper 60 | cxx_library_with_type(pyOpenMVS "Libs" "SHARED" "${cxx_default}" 61 | ${PATH_PythonWrapper_cpp} 62 | ) 63 | # Link its dependencies 64 | if(_USE_CUDA) 65 | SET_TARGET_PROPERTIES(pyOpenMVS PROPERTIES CUDA_ARCHITECTURES "50;72;75") 66 | endif() 67 | TARGET_LINK_LIBRARIES(pyOpenMVS PRIVATE MVS ${OpenMVS_EXTRA_LIBS}) 68 | # Suppress prefix "lib" because Python does not allow this prefix 69 | SET_TARGET_PROPERTIES(pyOpenMVS PROPERTIES PREFIX "") 70 | # Install 71 | INSTALL(TARGETS pyOpenMVS DESTINATION "${PYTHON_INSTALL_PATH}") 72 | endif() 73 | 74 | # Install 75 | SET_TARGET_PROPERTIES(MVS PROPERTIES 76 | PUBLIC_HEADER "${LIBRARY_FILES_H}") 77 | INSTALL(TARGETS MVS 78 | EXPORT OpenMVSTargets 79 | LIBRARY DESTINATION "${INSTALL_LIB_DIR}" 80 | ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 81 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 82 | PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/MVS") 83 | -------------------------------------------------------------------------------- /libs/MVS/Camera.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/libs/MVS/Camera.cpp -------------------------------------------------------------------------------- /libs/MVS/Common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Common.cpp 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | // Source file that includes just the standard includes 33 | // Common.pch will be the pre-compiled header 34 | // Common.obj will contain the pre-compiled type information 35 | 36 | #include "Common.h" 37 | #include "Mesh.h" 38 | 39 | using namespace MVS; 40 | 41 | void MVS::Initialize(LPCTSTR appname, unsigned nMaxThreads, int nProcessPriority) { 42 | // initialize thread options 43 | Process::setCurrentProcessPriority((Process::Priority)nProcessPriority); 44 | #ifdef _USE_OPENMP 45 | if (nMaxThreads != 0) 46 | omp_set_num_threads(nMaxThreads); 47 | #endif 48 | 49 | #ifdef _USE_BREAKPAD 50 | // initialize crash memory dumper 51 | MiniDumper::Create(appname, WORKING_FOLDER); 52 | #endif 53 | 54 | // initialize random number generator 55 | Util::Init(); 56 | } 57 | 58 | void MVS::Finalize() { 59 | #if TD_VERBOSE != TD_VERBOSE_OFF 60 | // print memory statistics 61 | Util::LogMemoryInfo(); 62 | #endif 63 | 64 | #ifdef _USE_CUDA 65 | // release static CUDA kernels before CUDA context is destroyed 66 | Mesh::kernelComputeFaceNormal.Release(); 67 | #endif 68 | } 69 | /*----------------------------------------------------------------*/ 70 | -------------------------------------------------------------------------------- /libs/MVS/Common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_COMMON_H_ 33 | #define _MVS_COMMON_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #if defined(MVS_EXPORTS) && !defined(Common_EXPORTS) 39 | #define Common_EXPORTS 40 | #endif 41 | 42 | #include "../Common/Common.h" 43 | #include "../IO/Common.h" 44 | #include "../Math/Common.h" 45 | 46 | #ifndef MVS_API 47 | #define MVS_API GENERAL_API 48 | #endif 49 | #ifndef MVS_TPL 50 | #define MVS_TPL GENERAL_TPL 51 | #endif 52 | 53 | 54 | // D E F I N E S /////////////////////////////////////////////////// 55 | 56 | 57 | // P R O T O T Y P E S ///////////////////////////////////////////// 58 | 59 | using namespace SEACAVE; 60 | 61 | #define _USE_OPENCV 62 | #define _DISABLE_NO_ID 63 | #include "Interface.h" 64 | 65 | namespace MVS { 66 | 67 | // Initialize / close the library; should be called at the beginning and end of the program 68 | void Initialize(LPCTSTR appname, unsigned nMaxThreads=0, int nProcessPriority=0); 69 | void Finalize(); 70 | /*----------------------------------------------------------------*/ 71 | 72 | } // namespace MVS 73 | 74 | #endif // _MVS_COMMON_H_ 75 | -------------------------------------------------------------------------------- /libs/MVS/DMapCache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DMapCache.cpp 3 | * 4 | * Copyright (c) 2014-2024 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #include "Common.h" 33 | #include "DMapCache.h" 34 | 35 | using namespace MVS; 36 | 37 | 38 | // S T R U C T S /////////////////////////////////////////////////// 39 | 40 | DMapCache::DMapCache(DepthDataArr& _arrDepthData, unsigned _loadFlags, size_t _max_memory_bytes) 41 | : 42 | loadFlags(_loadFlags), arrDepthData(_arrDepthData), 43 | maxMemory(_max_memory_bytes), disabledMaxMemory(0), usedMemory(0), 44 | skipMemoryCheckIdxImage(NO_ID), numImageRead(0) 45 | { 46 | } 47 | 48 | void DMapCache::SetMaxMemory(size_t max_memory_bytes) { 49 | maxMemory = max_memory_bytes; 50 | ASSERT(skipMemoryCheckIdxImage == NO_ID); 51 | Eject(); 52 | } 53 | 54 | bool DMapCache::UseImage(IIndex idxImage) const { 55 | ASSERT(idxImage < arrDepthData.size()); 56 | std::lock_guard<std::mutex> guard(mutex); 57 | ASSERT(arrDepthData[idxImage].IsValid()); 58 | if (!arrDepthData[idxImage].IsEmpty()) { 59 | fifo.Put(idxImage); 60 | return false; 61 | } 62 | mutex.unlock(); 63 | const String fileName(ComposeDepthFilePath(arrDepthData[idxImage].GetView().GetID(), "dmap")); 64 | while (!std::filesystem::is_regular_file(static_cast<const std::string&>(fileName))) 65 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 66 | arrDepthData[idxImage].Load(fileName, loadFlags); 67 | ASSERT(!arrDepthData[idxImage].IsEmpty()); 68 | mutex.lock(); 69 | ++numImageRead; 70 | usedMemory += arrDepthData[idxImage].GetMemorySize(); 71 | fifo.Put(idxImage); 72 | Eject(); 73 | return true; 74 | } 75 | 76 | IIndexArr DMapCache::GetCachedImageIndices(bool ordered) const { 77 | std::lock_guard<std::mutex> guard(mutex); 78 | IIndexArr cachedImageIndices; 79 | FOREACH(idxImage, arrDepthData) 80 | if (!arrDepthData[idxImage].IsEmpty()) 81 | cachedImageIndices.push_back(idxImage); 82 | if (ordered) 83 | cachedImageIndices.Sort(); 84 | return cachedImageIndices; 85 | } 86 | 87 | bool DMapCache::IsImageCached(IIndex idxImage) const { 88 | return fifo.Contains(idxImage); 89 | } 90 | 91 | void DMapCache::ClearCache() { 92 | std::lock_guard<std::mutex> guard(mutex); 93 | skipMemoryCheckIdxImage = NO_ID; 94 | while (!IsEmpty()) 95 | EjectOldest(); 96 | } 97 | 98 | size_t DMapCache::ComputeUsedMemory() const { 99 | std::lock_guard<std::mutex> guard(mutex); 100 | size_t computedUsedMemory = 0; 101 | for (const auto& depthData : arrDepthData) 102 | if (!depthData.IsEmpty()) 103 | computedUsedMemory += depthData.GetMemorySize(); 104 | ASSERT(computedUsedMemory == usedMemory); 105 | return computedUsedMemory; 106 | } 107 | 108 | bool DMapCache::Eject() const { 109 | if (maxMemory == 0) 110 | return true; 111 | while (usedMemory > maxMemory) { 112 | if (!EjectOldest()) 113 | return false; 114 | } 115 | return true; 116 | } 117 | 118 | bool DMapCache::EjectOldest() const { 119 | ASSERT(!fifo.IsEmpty()); 120 | if (fifo.Back() == skipMemoryCheckIdxImage) 121 | return false; 122 | const IIndex idxImage = fifo.Pop(); 123 | usedMemory -= arrDepthData[idxImage].GetMemorySize(); 124 | // release the depth-data; no need to save the depth-data to disk as it is already saved 125 | arrDepthData[idxImage].Release(); 126 | return true; 127 | } 128 | /*----------------------------------------------------------------*/ 129 | -------------------------------------------------------------------------------- /libs/MVS/DMapCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DMapCache.h 3 | * 4 | * Copyright (c) 2014-2024 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #pragma once 33 | #ifndef _MVS_DMAPCACHE_H_ 34 | #define _MVS_DMAPCACHE_H_ 35 | 36 | 37 | // I N C L U D E S ///////////////////////////////////////////////// 38 | 39 | #include "DepthMap.h" 40 | #include "../Common/ListFIFO.h" 41 | 42 | 43 | // S T R U C T S /////////////////////////////////////////////////// 44 | 45 | namespace MVS { 46 | 47 | // Caches depth-maps to disk. 48 | class DMapCache { 49 | public: 50 | explicit DMapCache(DepthDataArr& arrDepthData, unsigned loadFlags, size_t max_memory_bytes); 51 | 52 | // check if the list is empty 53 | bool IsEmpty() const { ASSERT((usedMemory == 0) == fifo.IsEmpty()); return fifo.IsEmpty(); } 54 | 55 | // set the maximum memory usage (in bytes) 56 | void SetMaxMemory(size_t max_memory_bytes = 0/*unlimited*/); 57 | 58 | // enable/disable memory usage 59 | void DisableMemoryCheck() { disabledMaxMemory = maxMemory; maxMemory = 0; } 60 | void EnableMemoryCheck() { if (disabledMaxMemory) { maxMemory = disabledMaxMemory; disabledMaxMemory = 0; Eject(); } } 61 | 62 | // skip memory check if this image index is to be ejected 63 | void SkipMemoryCheckIdxImage(IIndex idxImage = NO_ID) { skipMemoryCheckIdxImage = idxImage; } 64 | 65 | // ensure the depth-data is loaded and mark it as recently used: 66 | // return true if the image was loaded from disk 67 | bool UseImage(IIndex idxImage) const; 68 | 69 | // get the image indices loaded in cache. 70 | IIndexArr GetCachedImageIndices(bool ordered = false) const; 71 | 72 | // return true if the key is in the cache 73 | bool IsImageCached(IIndex idxImage) const; 74 | 75 | // get the number of times images were read from disk 76 | uint32_t GetNumImageReads() const { return numImageRead; } 77 | 78 | // eject all images from the cache 79 | void ClearCache(); 80 | 81 | // get the current memory usage (in bytes) 82 | size_t GetUsedMemory() const { return usedMemory; } 83 | size_t ComputeUsedMemory() const; 84 | 85 | private: 86 | // eject the least recently used images if the cache size is above max-limit 87 | bool Eject() const; 88 | // eject the least recently used image 89 | bool EjectOldest() const; 90 | 91 | private: 92 | unsigned loadFlags; 93 | DepthDataArr& arrDepthData; 94 | 95 | // maximum and used memory (in bytes) 96 | size_t maxMemory, disabledMaxMemory; 97 | mutable size_t usedMemory; 98 | 99 | // index of the image to skip memory check 100 | IIndex skipMemoryCheckIdxImage; 101 | 102 | // guard access to variables that are dynamically loaded from disk 103 | mutable std::mutex mutex; 104 | 105 | // track which images are last accessed 106 | mutable ListFIFO<IIndex> fifo; 107 | 108 | // number of times images were read from disk (debug only) 109 | mutable uint32_t numImageRead; 110 | }; 111 | /*----------------------------------------------------------------*/ 112 | 113 | } // namespace MVS 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /libs/MVS/PatchMatchCUDA.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PatchMatchCUDA.h 3 | * 4 | * Copyright (c) 2014-2021 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_PATCHMATCHCUDA_H_ 33 | #define _MVS_PATCHMATCHCUDA_H_ 34 | 35 | #ifdef _USE_CUDA 36 | 37 | 38 | // I N C L U D E S ///////////////////////////////////////////////// 39 | 40 | #include "SceneDensify.h" 41 | #include "PatchMatchCUDA.inl" 42 | 43 | 44 | // D E F I N E S /////////////////////////////////////////////////// 45 | 46 | 47 | // S T R U C T S /////////////////////////////////////////////////// 48 | 49 | namespace MVS { 50 | 51 | } // namespace MVS 52 | 53 | #endif // _USE_CUDA 54 | 55 | #endif // _MVS_PATCHMATCHCUDA_H_ 56 | -------------------------------------------------------------------------------- /libs/MVS/PatchMatchCUDA.inl: -------------------------------------------------------------------------------- 1 | /* 2 | * PatchMatchCUDA.inl 3 | * 4 | * Copyright (c) 2014-2021 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_PATCHMATCHCUDA_INL_ 33 | #define _MVS_PATCHMATCHCUDA_INL_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #include "CUDA/Camera.h" 39 | 40 | // OpenCV 41 | #include <opencv2/core.hpp> 42 | #include <opencv2/imgproc.hpp> 43 | 44 | 45 | // D E F I N E S /////////////////////////////////////////////////// 46 | 47 | 48 | // S T R U C T S /////////////////////////////////////////////////// 49 | 50 | namespace MVS { 51 | 52 | struct DepthData; 53 | 54 | namespace CUDA { 55 | 56 | class PatchMatch { 57 | public: 58 | struct Params { 59 | int nNumViews = 5; 60 | int nEstimationIters = 3; 61 | float fDepthMin = 0.f; 62 | float fDepthMax = 100.f; 63 | int nInitTopK = 3; 64 | bool bGeomConsistency = false; 65 | bool bLowResProcessed = false; 66 | float fThresholdKeepCost = 0; 67 | }; 68 | 69 | public: 70 | PatchMatch(int device=0); 71 | ~PatchMatch(); 72 | 73 | void Init(bool bGeomConsistency); 74 | void Release(); 75 | 76 | void EstimateDepthMap(DepthData&); 77 | 78 | float4 GetPlaneHypothesis(const int index); 79 | float GetCost(const int index); 80 | 81 | private: 82 | void ReleaseCUDA(); 83 | void AllocatePatchMatchCUDA(const cv::Mat1f& image); 84 | void AllocateImageCUDA(size_t i, const cv::Mat1f& image, bool bInitImage, bool bInitDepthMap); 85 | void RunCUDA(float* ptrCostMap=NULL, uint32_t* ptrViewsMap=NULL); 86 | 87 | public: 88 | Params params; 89 | 90 | std::vector<cv::Mat1f> images; 91 | std::vector<Camera> cameras; 92 | std::vector<cudaTextureObject_t> textureImages; 93 | std::vector<cudaTextureObject_t> textureDepths; 94 | Point4* depthNormalEstimates; 95 | 96 | Camera *cudaCameras; 97 | std::vector<cudaArray_t> cudaImageArrays; 98 | std::vector<cudaArray_t> cudaDepthArrays; 99 | cudaTextureObject_t* cudaTextureImages; 100 | cudaTextureObject_t* cudaTextureDepths; 101 | Point4* cudaDepthNormalEstimates; 102 | float* cudaLowDepths; 103 | float* cudaDepthNormalCosts; 104 | curandState* cudaRandStates; 105 | uint32_t* cudaSelectedViews; 106 | }; 107 | /*----------------------------------------------------------------*/ 108 | 109 | } // namespace CUDA 110 | 111 | } // namespace MVS 112 | 113 | #endif // _MVS_PATCHMATCHCUDA_INL_ 114 | -------------------------------------------------------------------------------- /libs/MVS/Platform.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Platform.cpp 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #include "Common.h" 33 | #include "Platform.h" 34 | 35 | using namespace MVS; 36 | 37 | 38 | // D E F I N E S /////////////////////////////////////////////////// 39 | 40 | 41 | // S T R U C T S /////////////////////////////////////////////////// 42 | 43 | // return the normalized absolute camera pose 44 | Platform::Camera Platform::GetCamera(uint32_t cameraID, uint32_t poseID) const 45 | { 46 | const Camera& camera = cameras[cameraID]; 47 | const Pose& pose = poses[poseID]; 48 | // add the relative camera pose to the platform 49 | Camera cam; 50 | cam.K = camera.K; 51 | cam.R = camera.R*pose.R; 52 | cam.C = pose.R.t()*camera.C+pose.C; 53 | return cam; 54 | } // GetCamera 55 | /*----------------------------------------------------------------*/ 56 | -------------------------------------------------------------------------------- /libs/MVS/Platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Platform.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_PLATFORM_H_ 33 | #define _MVS_PLATFORM_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #include "Camera.h" 39 | 40 | 41 | // D E F I N E S /////////////////////////////////////////////////// 42 | 43 | 44 | // S T R U C T S /////////////////////////////////////////////////// 45 | 46 | namespace MVS { 47 | 48 | // a mobile platform with cameras attached to it 49 | class MVS_API Platform 50 | { 51 | public: 52 | // structure describing a normalized camera mounted on a platform 53 | typedef CameraIntern Camera; 54 | typedef CLISTDEF0IDX(Camera,uint32_t) CameraArr; 55 | 56 | // structure describing a pose along the trajectory of a platform 57 | struct Pose { 58 | RMatrix R; // platform's rotation matrix 59 | CMatrix C; // platform's translation vector in the global coordinate system 60 | #ifdef _USE_BOOST 61 | template <class Archive> 62 | void serialize(Archive& ar, const unsigned int /*version*/) { 63 | ar & R; 64 | ar & C; 65 | } 66 | #endif 67 | }; 68 | typedef CLISTDEF0IDX(Pose,uint32_t) PoseArr; 69 | 70 | public: 71 | String name; // platform's name 72 | CameraArr cameras; // cameras mounted on the platform 73 | PoseArr poses; // trajectory of the platform 74 | 75 | public: 76 | inline Platform() {} 77 | 78 | Camera GetCamera(uint32_t cameraID, uint32_t poseID) const; 79 | 80 | #ifdef _USE_BOOST 81 | // implement BOOST serialization 82 | template <class Archive> 83 | void serialize(Archive& ar, const unsigned int /*version*/) { 84 | ar & name; 85 | ar & cameras; 86 | ar & poses; 87 | } 88 | #endif 89 | }; 90 | typedef MVS_API CLISTDEFIDX(Platform,uint32_t) PlatformArr; 91 | /*----------------------------------------------------------------*/ 92 | 93 | } // namespace MVS 94 | 95 | #endif // _MVS_PLATFORM_H_ 96 | -------------------------------------------------------------------------------- /libs/MVS/SceneDensify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SceneDensify.h 3 | * 4 | * Copyright (c) 2014-2015 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _MVS_SCENEDENSIFY_H_ 33 | #define _MVS_SCENEDENSIFY_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | #include "SemiGlobalMatcher.h" 39 | 40 | 41 | // S T R U C T S /////////////////////////////////////////////////// 42 | 43 | namespace MVS { 44 | 45 | // Forward declarations 46 | class MVS_API Scene; 47 | #ifdef _USE_CUDA 48 | namespace CUDA { 49 | class PatchMatch; 50 | } // namespace CUDA 51 | #endif // _USE_CUDA 52 | 53 | // structure used to compute all depth-maps 54 | class MVS_API DepthMapsData 55 | { 56 | public: 57 | DepthMapsData(Scene& _scene); 58 | ~DepthMapsData(); 59 | 60 | bool SelectViews(DepthData& depthData); 61 | bool InitViews(DepthData& depthData, IIndex idxNeighbor, IIndex numNeighbors, bool loadImages, int loadDepthMaps); 62 | bool InitDepthMap(DepthData& depthData); 63 | bool EstimateDepthMap(IIndex idxImage, int nGeometricIter); 64 | 65 | bool RemoveSmallSegments(DepthData& depthData); 66 | bool GapInterpolation(DepthData& depthData); 67 | 68 | void EstimateNormalMaps(); 69 | 70 | bool AdjustConfidenceFast(DepthData& depthData, const IIndexArr& idxNeighbors); 71 | bool AdjustConfidence(DepthData& depthDataRef, const IIndexArr& idxNeighbors); 72 | void MergeDepthMaps(PointCloud& pointcloud, bool bEstimateColor, bool bEstimateNormal); 73 | void FuseDepthMaps(PointCloud& pointcloud, bool bEstimateColor, bool bEstimateNormal); 74 | void DenseFuseDepthMaps(PointCloud& pointcloud, bool bEstimateColor, bool bEstimateNormal); 75 | 76 | static DepthData ScaleDepthData(const DepthData& inputDeptData, float scale); 77 | 78 | protected: 79 | static void* STCALL ScoreDepthMapTmp(void*); 80 | static void* STCALL EstimateDepthMapTmp(void*); 81 | static void* STCALL EndDepthMapTmp(void*); 82 | 83 | public: 84 | Scene& scene; 85 | 86 | DepthDataArr arrDepthData; 87 | 88 | // used internally to estimate the depth-maps 89 | Image8U::Size prevDepthMapSize; // remember the size of the last estimated depth-map 90 | Image8U::Size prevDepthMapSizeTrg; // ... same for target image 91 | DepthEstimator::MapRefArr coords; // map pixel index to zigzag matrix coordinates 92 | DepthEstimator::MapRefArr coordsTrg; // ... same for target image 93 | 94 | #ifdef _USE_CUDA 95 | // used internally to estimate the depth-maps using CUDA 96 | CAutoPtr<MVS::CUDA::PatchMatch> pmCUDA; 97 | #endif // _USE_CUDA 98 | }; 99 | /*----------------------------------------------------------------*/ 100 | 101 | struct MVS_API DenseDepthMapData { 102 | Scene& scene; 103 | IIndexArr images; 104 | IIndexArr neighborsMap; 105 | DepthMapsData depthMaps; 106 | volatile Thread::safe_t idxImage; 107 | SEACAVE::EventQueue events; // internal events queue (processed by the working threads) 108 | Semaphore sem; 109 | CAutoPtr<Util::Progress> progress; 110 | int nEstimationGeometricIter; 111 | int nFusionMode; 112 | STEREO::SemiGlobalMatcher sgm; 113 | 114 | DenseDepthMapData(Scene& _scene, int _nFusionMode=0); 115 | ~DenseDepthMapData(); 116 | 117 | void SignalCompleteDepthmapFilter(); 118 | }; 119 | /*----------------------------------------------------------------*/ 120 | 121 | } // namespace MVS 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /libs/Math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(".") 2 | 3 | # List sources files 4 | FILE(GLOB LIBRARY_FILES_C "*.cpp") 5 | FILE(GLOB LIBRARY_FILES_H "*.h" "*.inl") 6 | 7 | FILE(GLOB IBFS_LIBRARY_FILES_C "IBFS/*.cpp") 8 | FILE(GLOB IBFS_LIBRARY_FILES_H "IBFS/*.h" "IBFS/*.inl") 9 | SOURCE_GROUP("IBFS" FILES ${IBFS_LIBRARY_FILES_C} ${IBFS_LIBRARY_FILES_H}) 10 | 11 | FILE(GLOB LMFit_LIBRARY_FILES_C "LMFit/*.cpp") 12 | FILE(GLOB LMFit_LIBRARY_FILES_H "LMFit/*.h" "LMFit/*.inl") 13 | SOURCE_GROUP("LMFit" FILES ${LMFit_LIBRARY_FILES_C} ${LMFit_LIBRARY_FILES_H}) 14 | 15 | cxx_library_with_type(Math "Libs" "" "${cxx_default}" 16 | ${LIBRARY_FILES_C} ${LIBRARY_FILES_H} 17 | ${IBFS_LIBRARY_FILES_C} ${IBFS_LIBRARY_FILES_H} 18 | ${LMFit_LIBRARY_FILES_C} ${LMFit_LIBRARY_FILES_H} 19 | ) 20 | 21 | # Manually set Common.h as the precompiled header 22 | IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) 23 | TARGET_PRECOMPILE_HEADERS(Math PRIVATE "Common.h") 24 | endif() 25 | 26 | # Link its dependencies 27 | TARGET_LINK_LIBRARIES(Math Common) 28 | 29 | # Install 30 | INSTALL(FILES ${LIBRARY_FILES_H} DESTINATION "${INSTALL_INCLUDE_DIR}/Math") 31 | INSTALL(FILES ${IBFS_LIBRARY_FILES_H} DESTINATION "${INSTALL_INCLUDE_DIR}/Math/IBFS") 32 | INSTALL(FILES ${LMFit_LIBRARY_FILES_H} DESTINATION "${INSTALL_INCLUDE_DIR}/Math/LMFit") 33 | INSTALL(TARGETS Math 34 | EXPORT OpenMVSTargets 35 | LIBRARY DESTINATION "${INSTALL_LIB_DIR}" 36 | ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 37 | RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 38 | PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/Math") 39 | -------------------------------------------------------------------------------- /libs/Math/Common.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Common.cpp 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | // Source file that includes just the standard includes 9 | // Common.pch will be the pre-compiled header 10 | // Common.obj will contain the pre-compiled type information 11 | 12 | #include "Common.h" 13 | -------------------------------------------------------------------------------- /libs/Math/Common.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | // Common.h 3 | // 4 | // Copyright 2007 cDc@seacave 5 | // Distributed under the Boost Software License, Version 1.0 6 | // (See http://www.boost.org/LICENSE_1_0.txt) 7 | 8 | #ifndef __MATH_COMMON_H__ 9 | #define __MATH_COMMON_H__ 10 | 11 | 12 | // I N C L U D E S ///////////////////////////////////////////////// 13 | 14 | #if defined(Math_EXPORTS) && !defined(Common_EXPORTS) 15 | #define Common_EXPORTS 16 | #endif 17 | 18 | #include "../Common/Common.h" 19 | 20 | #ifndef MATH_API 21 | #define MATH_API GENERAL_API 22 | #endif 23 | #ifndef MATH_TPL 24 | #define MATH_TPL GENERAL_TPL 25 | #endif 26 | 27 | #include "LMFit/lmmin.h" 28 | #include "RobustNorms.h" 29 | 30 | 31 | // D E F I N E S /////////////////////////////////////////////////// 32 | 33 | 34 | // P R O T O T Y P E S ///////////////////////////////////////////// 35 | 36 | using namespace SEACAVE; 37 | 38 | #endif // __MATH_COMMON_H__ 39 | -------------------------------------------------------------------------------- /libs/Math/IBFS/license.txt: -------------------------------------------------------------------------------- 1 | /* 2 | ######################################################### 3 | # # 4 | # IBFSGraph - Software for solving # 5 | # Maximum s-t Flow / Minimum s-t Cut # 6 | # using the IBFS algorithm # 7 | # # 8 | # http://www.cs.tau.ac.il/~sagihed/ibfs/ # 9 | # # 10 | # Haim Kaplan (haimk@cs.tau.ac.il) # 11 | # Sagi Hed (sagihed@post.tau.ac.il) # 12 | # # 13 | ######################################################### 14 | 15 | This software implements the IBFS (Incremental Breadth First Search) maximum flow algorithm from 16 | "Maximum flows by incremental breadth-first search" 17 | Andrew V. Goldberg, Sagi Hed, Haim Kaplan, Robert E. Tarjan, and Renato F. Werneck. 18 | In Proceedings of the 19th European conference on Algorithms, ESA'11, pages 457-468. 19 | ISBN 978-3-642-23718-8 20 | 2011 21 | 22 | Copyright Haim Kaplan (haimk@cs.tau.ac.il) and Sagi Hed (sagihed@post.tau.ac.il) 23 | 24 | ########### 25 | # LICENSE # 26 | ########### 27 | This software can be used for research purposes only. 28 | If you use this software for research purposes, you should cite the aforementioned paper 29 | in any resulting publication and appropriately credit it. 30 | 31 | If you require another license, please contact the above. 32 | 33 | */ 34 | -------------------------------------------------------------------------------- /libs/Math/LMFit/COPYING: -------------------------------------------------------------------------------- 1 | The package lmfit is distributed under the FreeBSD License: 2 | 3 | -- 4 | Copyright (c) 1980-1999 University of Chicago, 5 | as operator of Argonne National Laboratory 6 | Copyright (c) 2004-2013 Joachim Wuttke, Forschungszentrum Juelich GmbH 7 | 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | - Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | - Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | This software is provided by the copyright holders and contributors "as is" 20 | and any express or implied warranties, including, but not limited to, the 21 | implied warranties of merchantability and fitness for a particular purpose 22 | are disclaimed. In no event shall the copyright holder or contributors 23 | be liable for any direct, indirect, incidental, special, exemplary, or 24 | consequential damages (including, but not limited to, procurement of 25 | substitute goods or services; loss of use, data, or profits; or business 26 | interruption) however caused and on any theory of liability, whether in 27 | contract, strict liability, or tort (including negligence or otherwise) 28 | arising in any way out of the use of this software, even if advised of the 29 | possibility of such damage. 30 | -- 31 | -------------------------------------------------------------------------------- /libs/Math/LMFit/lmmin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Project: LevenbergMarquardtLeastSquaresFitting 3 | * 4 | * File: lmmin.h 5 | */ 6 | 7 | #ifndef LMMIN_H 8 | #define LMMIN_H 9 | 10 | 11 | /** Compact high-level interface. **/ 12 | 13 | /* Collection of control (input) parameters. */ 14 | typedef struct { 15 | double ftol; /* relative error desired in the sum of squares. */ 16 | double xtol; /* relative error between last two approximations. */ 17 | double gtol; /* orthogonality desired between fvec and its derivs. */ 18 | double epsilon; /* step used to calculate the jacobian, or 0 for user provided jacobian. */ 19 | double stepbound; /* initial bound to steps in the outer loop. */ 20 | int maxcall; /* maximum number of iterations. */ 21 | int scale_diag; /* UNDOCUMENTED, TESTWISE automatic diag rescaling? */ 22 | #ifdef LMFIT_PRINTOUT 23 | int printflags; /* OR'ed to produce more noise */ 24 | #endif 25 | } lm_control_struct; 26 | 27 | /* Collection of status (output) parameters. */ 28 | typedef struct { 29 | double fnorm; /* norm of the residue vector fvec. */ 30 | int nfev; /* actual number of iterations. */ 31 | int info; /* status (index for lm_infmsg and lm_shortmsg). */ 32 | } lm_status_struct; 33 | 34 | /* Recommended control parameter settings. */ 35 | extern const lm_control_struct lm_control_double; 36 | extern const lm_control_struct lm_control_float; 37 | 38 | #ifdef LMFIT_PRINTOUT 39 | /* Standard monitoring routine. */ 40 | void lm_printout_std( int n_par, const double *par, int m_dat, 41 | const void *data, const double *fvec, 42 | int printflags, int iflag, int iter, int nfev ); 43 | #endif 44 | 45 | /* Refined calculation of Eucledian norm, typically used in printout routine. */ 46 | double lm_enorm( int, const double * ); 47 | 48 | /* The actual minimization. */ 49 | void lmmin( int n_par, double *par, int m_dat, const void *data, 50 | void (*evaluate) (const double *par, int m_dat, const void *data, 51 | double *fvec, double *fjac, int *info), 52 | const lm_control_struct *control, lm_status_struct *status 53 | #ifdef LMFIT_PRINTOUT 54 | , void (*printout) (int n_par, const double *par, int m_dat, 55 | const void *data, const double *fvec, 56 | int printflags, int iflag, int iter, int nfev) = NULL 57 | #endif 58 | ); 59 | 60 | 61 | /** Legacy low-level interface. **/ 62 | 63 | /* Alternative to lm_minimize, allowing full control, and read-out 64 | of auxiliary arrays. For usage, see implementation of lmmin. */ 65 | void lm_lmdif( int m, int n, double *x, double *fvec, double ftol, 66 | double xtol, double gtol, int maxfev, double epsfcn, 67 | double *diag, int mode, double factor, int& info, int& nfev, 68 | double *fjac, int *ipvt, double *qtf, double *wa1, 69 | double *wa2, double *wa3, double *wa4, 70 | void (*evaluate) (const double *par, int m_dat, const void *data, 71 | double *fvec, double *fjac, int *info), 72 | const void *data 73 | #ifdef LMFIT_PRINTOUT 74 | , void (*printout) (int n_par, const double *par, int m_dat, 75 | const void *data, const double *fvec, 76 | int printflags, int iflag, int iter, int nfev), 77 | int printflags 78 | #endif 79 | ); 80 | 81 | extern const char *lm_infmsg[]; 82 | extern const char *lm_shortmsg[]; 83 | 84 | 85 | #endif /* LMMIN_H */ 86 | -------------------------------------------------------------------------------- /libs/Math/RobustNorms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdcseacave/openMVS/4adfadd9f8ae8a5a2d07ba9e0bff4ce562c3e1a9/libs/Math/RobustNorms.png -------------------------------------------------------------------------------- /libs/Math/SimilarityTransform.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SimilarityTransform.cpp 3 | * 4 | * Copyright (c) 2014-2022 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #include "Common.h" 33 | #include "SimilarityTransform.h" 34 | 35 | 36 | // D E F I N E S /////////////////////////////////////////////////// 37 | 38 | 39 | // S T R U C T S /////////////////////////////////////////////////// 40 | 41 | // find the similarity transform that best aligns the given two sets of corresponding 3D points 42 | bool SEACAVE::SimilarityTransform(const CLISTDEF0(Point3)& points, const CLISTDEF0(Point3)& pointsRef, Matrix4x4& transform) 43 | { 44 | ASSERT(points.size() == pointsRef.size()); 45 | typedef Eigen::Matrix<REAL,3,Eigen::Dynamic> PointsVec; 46 | PointsVec p(3, points.size()); 47 | PointsVec pRef(3, pointsRef.size()); 48 | FOREACH(i, points) { 49 | p.col(i) = static_cast<const Point3::EVec&>(points[i]); 50 | pRef.col(i) = static_cast<const Point3::EVec&>(pointsRef[i]); 51 | } 52 | transform = Eigen::umeyama(p, pRef); 53 | return true; 54 | } // SimilarityTransform 55 | /*----------------------------------------------------------------*/ 56 | 57 | void SEACAVE::DecomposeSimilarityTransform(const Matrix4x4& transform, Matrix3x3& R, Point3& t, REAL& s) 58 | { 59 | const Eigen::Transform<REAL,3,Eigen::Affine,Eigen::RowMajor> T(static_cast<const Matrix4x4::EMat&>(transform)); 60 | Eigen::Matrix<REAL,3,3> rotation, scaling; 61 | T.computeRotationScaling(&rotation, &scaling); 62 | R = rotation; 63 | t = T.translation(); 64 | s = scaling.diagonal().mean(); 65 | } // DecomposeSimilarityTransform 66 | /*----------------------------------------------------------------*/ 67 | -------------------------------------------------------------------------------- /libs/Math/SimilarityTransform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SimilarityTransform.h 3 | * 4 | * Copyright (c) 2014-2022 SEACAVE 5 | * 6 | * Author(s): 7 | * 8 | * cDc <cdc.seacave@gmail.com> 9 | * 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Affero General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Affero General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Affero General Public License 22 | * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 | * 24 | * 25 | * Additional Terms: 26 | * 27 | * You are required to preserve legal notices and author attributions in 28 | * that material or in the Appropriate Legal Notices displayed by works 29 | * containing it. 30 | */ 31 | 32 | #ifndef _SEACAVE_SIMILARITY_TRANSFORM_H_ 33 | #define _SEACAVE_SIMILARITY_TRANSFORM_H_ 34 | 35 | 36 | // I N C L U D E S ///////////////////////////////////////////////// 37 | 38 | 39 | // D E F I N E S /////////////////////////////////////////////////// 40 | 41 | 42 | // S T R U C T S /////////////////////////////////////////////////// 43 | 44 | namespace SEACAVE { 45 | 46 | // find the similarity transform that best aligns the given two sets of corresponding 3D points 47 | bool SimilarityTransform(const CLISTDEF0(Point3)& points, const CLISTDEF0(Point3)& pointsRef, Matrix4x4& transform); 48 | 49 | // decompose similarity transform into rotation, translation and scale 50 | void DecomposeSimilarityTransform(const Matrix4x4& transform, Matrix3x3& R, Point3& t, REAL& s); 51 | /*----------------------------------------------------------------*/ 52 | 53 | } // namespace SEACAVE 54 | 55 | #endif // _SEACAVE_SIMILARITY_TRANSFORM_H_ 56 | -------------------------------------------------------------------------------- /scripts/python/MvgOptimizeSfM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- encoding: utf-8 -*- 3 | """ 4 | This script is for comparing the poses stored in an OpenMVS project to the poses optimized by OpenMVG 5 | 6 | usage: run 'MvgOptimizeSfM.py' in a sub-folder to the OpenMVS project folder containing 7 | 'scene.mvs' and images stored in 'images' folder; structure ex: 8 | 9 | -OpenMVS_project 10 | -images 11 | -scene.mvs 12 | -mvg 13 | -run script here 14 | """ 15 | 16 | import os 17 | import sys 18 | import subprocess 19 | 20 | if sys.platform.startswith('win'): 21 | PATH_DELIM = ';' 22 | else: 23 | PATH_DELIM = ':' 24 | 25 | # add this script's directory to PATH 26 | os.environ['PATH'] += PATH_DELIM + os.path.dirname(os.path.abspath(__file__)) 27 | 28 | # add current directory to PATH 29 | os.environ['PATH'] += PATH_DELIM + os.getcwd() 30 | 31 | 32 | def whereis(afile): 33 | """ 34 | return directory in which afile is, None if not found. Look in PATH 35 | """ 36 | if sys.platform.startswith('win'): 37 | cmd = "where" 38 | else: 39 | cmd = "which" 40 | try: 41 | ret = subprocess.run([cmd, afile], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True) 42 | return os.path.split(ret.stdout.decode())[0] 43 | except subprocess.CalledProcessError: 44 | return None 45 | 46 | 47 | def launch(cmdline): 48 | # Launch the current step 49 | print('Cmd: ' + ' '.join(cmdline)) 50 | try: 51 | pStep = subprocess.Popen(cmdline) 52 | pStep.wait() 53 | if pStep.returncode != 0: 54 | return 55 | except KeyboardInterrupt: 56 | sys.exit('\r\nProcess canceled by user, all files remains') 57 | 58 | 59 | # Try to find openMVG and openMVS binaries in PATH 60 | OPENMVG_BIN = whereis("openMVG_main_SfMInit_ImageListing") 61 | OPENMVS_BIN = whereis("ReconstructMesh") 62 | 63 | # Ask user for openMVG and openMVS directories if not found 64 | if not OPENMVG_BIN: 65 | OPENMVG_BIN = input("openMVG binary folder?\n") 66 | if not OPENMVS_BIN: 67 | OPENMVS_BIN = input("openMVS binary folder?\n") 68 | 69 | launch([os.path.join(OPENMVS_BIN, 'InterfaceCOLMAP'), '../scene.mvs', '-o', '../gt_dense_cameras.camera']) 70 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_SfMInit_ImageListingFromKnownPoses'), '-i', '../images', '-g', '../gt_dense_cameras', '-t', '1', '-o', '.']) 71 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_ComputeFeatures'), '-i', 'sfm_data.json', '-o', '.']) 72 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_ComputeMatches'), '-i', 'sfm_data.json', '-o', '.', '-m', '1']) 73 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_ComputeStructureFromKnownPoses'), '-i', 'sfm_data.json', '-m', '.', '-o', 'sfm_data_struct.bin', '-b']) 74 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_ComputeSfM_DataColor'), '-i', 'sfm_data_struct.bin', '-o', 'scene.ply']) 75 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_openMVG2openMVS'), '-i', 'sfm_data_struct.bin', '-o', 'scene.mvs', '-d', 'images']) 76 | launch([os.path.join(OPENMVS_BIN, 'InterfaceCOLMAP'), 'scene.mvs', '-o', 'cameras.camera']) 77 | launch([os.path.join(OPENMVG_BIN, 'openMVG_main_evalQuality'), '-i', '..', '-c', 'sfm_data_struct.bin', '-o', 'compare']) 78 | -------------------------------------------------------------------------------- /scripts/python/MvsReadDMAP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- encoding: utf-8 -*- 3 | ''' 4 | Example usage of MvsUtils.py for reading DMAP file content. 5 | 6 | usage: MvsReadDMAP.py [-h] [--input INPUT] [--output OUTPUT] 7 | ''' 8 | 9 | from argparse import ArgumentParser 10 | from concurrent.futures import ProcessPoolExecutor 11 | from glob import glob 12 | from MvsUtils import loadDMAP 13 | import numpy as np 14 | import os 15 | import pyvips 16 | 17 | def exportDMAPContent(dmap_path): 18 | dmap = loadDMAP(dmap_path) 19 | 20 | basename = os.path.splitext(os.path.basename(dmap['file_name']))[0] 21 | 22 | pyvips.Image.new_from_array(np.uint8(dmap['depth_map'] * (1 / dmap['depth_max']) * 255)).write_to_file('%s_depth_map.png' % basename) 23 | if dmap['has_normal']: 24 | pyvips.Image.new_from_array(np.uint8((dmap['normal_map'] @ -dmap['R'] + 1) * 0.5 * 255)).write_to_file('%s_normal_map.png' % basename) 25 | if dmap['has_conf']: 26 | pyvips.Image.new_from_array(np.uint8(dmap['confidence_map'] * (1 / dmap['confidence_map'].max()) * 255)).write_to_file('%s_confidence_map.png' % basename) 27 | 28 | def main(): 29 | parser = ArgumentParser() 30 | parser.add_argument('-i', '--input', type=str, required=True, help='Path to the DMAP file directory') 31 | parser.add_argument('-t', '--threads', type=int, default=int(os.cpu_count() * 0.5) - 1, help='Number of parallel computations') 32 | parser.add_argument('-o', '--output', type=str, required=True, help='Path to the output directory') 33 | args = parser.parse_args() 34 | 35 | dmap_paths = glob(os.path.join(args.input, '*.dmap')) 36 | 37 | os.makedirs(args.output, exist_ok = True) 38 | os.chdir(args.output) 39 | 40 | with ProcessPoolExecutor(max_workers=args.threads) as executor: 41 | executor.map(exportDMAPContent, dmap_paths) 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /scripts/python/MvsReadMVS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- encoding: utf-8 -*- 3 | ''' 4 | Example usage of MvsUtils.py for reading MVS interface archive content. 5 | 6 | usage: MvsReadMVS.py [-h] [--input INPUT] [--output OUTPUT] 7 | ''' 8 | 9 | from argparse import ArgumentParser 10 | import json 11 | from MvsUtils import loadMVSInterface 12 | import os 13 | 14 | def main(): 15 | parser = ArgumentParser() 16 | parser.add_argument('-i', '--input', type=str, required=True, help='Path to the MVS interface archive') 17 | parser.add_argument('-o', '--output', type=str, required=True, help='Path to the output json file') 18 | args = parser.parse_args() 19 | 20 | mvs = loadMVSInterface(args.input) 21 | 22 | for platform_index in range(len(mvs['platforms'])): 23 | for camera_index in range(len(mvs['platforms'][platform_index]['cameras'])): 24 | camera = mvs['platforms'][platform_index]['cameras'][camera_index] 25 | image_max = max(camera['width'], camera['height']) 26 | fx = camera['K'][0][0] / image_max 27 | fy = camera['K'][1][1] / image_max 28 | poses_size = len(camera['poses']) 29 | print('Camera model loaded: platform {}; camera {}; f {:.3f}x{:.3f}; poses {}'.format(platform_index, camera_index, fx, fy, poses_size)) 30 | 31 | os.makedirs(os.path.dirname(args.output), exist_ok = True) 32 | 33 | with open(args.output, 'w') as file: 34 | json.dump(mvs, file, indent=2) 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openmvs", 3 | "version": "2.3.0", 4 | "description": "OpenMVS: open Multi-View Stereo reconstruction library", 5 | "homepage": "https://cdcseacave.github.io/openMVS", 6 | "dependencies": [ 7 | "boost-iostreams", 8 | "boost-program-options", 9 | "boost-serialization", 10 | "boost-system", 11 | "boost-throw-exception", 12 | { 13 | "name": "cgal", 14 | "default-features": false 15 | }, 16 | "eigen3", 17 | "libjxl", 18 | "libpng", 19 | { 20 | "name": "opencv", 21 | "features": [ 22 | "eigen", 23 | "jpegxl", 24 | "openexr" 25 | ] 26 | }, 27 | "pkgconf", 28 | "tiff", 29 | "vcglib", 30 | "zlib" 31 | ], 32 | "features": { 33 | "viewer": { 34 | "description": "Viewer support in OpenMVS", 35 | "dependencies": [ 36 | "glad", 37 | "glfw3" 38 | ] 39 | }, 40 | "cuda": { 41 | "description": "CUDA support for OpenMVS", 42 | "dependencies": [ 43 | "cuda" 44 | ] 45 | }, 46 | "python": { 47 | "description": "Python bindings for OpenMVS", 48 | "dependencies": [ 49 | "boost-python" 50 | ] 51 | } 52 | } 53 | } 54 | --------------------------------------------------------------------------------