diff --git a/.gitignore b/.gitignore index a739a68fd..367fdfe6e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,12 +10,15 @@ launch.json # Ignore generated files /build /cmake_build +/third_party_install +/third_party_build /doc/build /dist /OpenSfM.egg-info .cache .pytest_cache eval +/.env # Viewer node_modules diff --git a/.gitmodules b/.gitmodules index 219b530e7..2b488bf4b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,21 @@ [submodule "opensfm/src/third_party/pybind11"] path = opensfm/src/third_party/pybind11 url = https://github.com/pybind/pybind11.git +[submodule "opensfm/src/third_party/gflags"] + path = opensfm/src/third_party/gflags + url = https://github.com/gflags/gflags.git +[submodule "opensfm/src/third_party/glog"] + path = opensfm/src/third_party/glog + url = https://github.com/google/glog.git +[submodule "opensfm/src/third_party/eigen"] + path = opensfm/src/third_party/eigen + url = https://gitlab.com/libeigen/eigen.git +[submodule "opensfm/src/third_party/ceres-solver"] + path = opensfm/src/third_party/ceres-solver + url = https://github.com/ceres-solver/ceres-solver.git +[submodule "opensfm/src/third_party/SuiteSparse"] + path = opensfm/src/third_party/SuiteSparse + url = https://github.com/DrTimothyAldenDavis/SuiteSparse.git +[submodule "opensfm/src/third_party/tbb"] + path = opensfm/src/third_party/tbb + url = https://github.com/oneapi-src/oneTBB.git diff --git a/Dockerfile b/Dockerfile index 75de8b3cf..7bba4c59e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,168 @@ +#FROM quay.io/pypa/manylinux2014_x86_64 FROM ubuntu:20.04 +ENV PLAT=manylinux_2_31_x86_64 ARG DEBIAN_FRONTEND=noninteractive +ARG TWINE_USERNAME +ARG TWINE_PASSWORD +ENV TWINE_USERNAME=$TWINE_USERNAME +ENV TWINE_PASSWORD=$TWINE_PASSWORD + +#RUN apt-get update \ +# && apt-get install -y \ +# build-essential \ +# cmake \ +# git \ +# libeigen3-dev \ +# libopencv-dev \ +# libceres-dev \ +# python3-dev \ +# python3-numpy \ +# python3-opencv \ +# python3-pip \ +# python3-pyproj \ +# python3-scipy \ +# python3-yaml \ +# curl \ +# && apt-get clean \ +# && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + + +#RUN yum install -y opencv opencv-devel \ +# blas-devel \ +# lapack-devel \ +# metis-devel \ +# tbb-devel \ +# wget \ +# openblas-devel \ +# atlas-devel \ +# suitesparse-devel -# Install apt-getable dependencies RUN apt-get update \ && apt-get install -y \ - build-essential \ - cmake \ - git \ - libeigen3-dev \ - libopencv-dev \ - libceres-dev \ python3-dev \ python3-numpy \ python3-opencv \ python3-pip \ - python3-pyproj \ - python3-scipy \ - python3-yaml \ - curl \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + libblas-dev \ + liblapack-dev \ + libmetis-dev \ + libtbb-dev \ + wget \ + libopenblas-dev \ + libatlas-base-dev \ + git \ + cmake \ + build-essential \ + libsuitesparse-dev \ + curl + +RUN mkdir /source +WORKDIR /source +RUN git clone https://github.com/gflags/gflags.git +WORKDIR /source/gflags/ +RUN git checkout tags/v2.2.2 +RUN mkdir /source/gflags/build/ +WORKDIR /source/gflags/build/ +RUN cmake -DCMAKE_CXX_FLAGS="-fPIC" .. +RUN make -j8 +RUN make install + +WORKDIR /source +RUN git clone https://github.com/google/glog.git +WORKDIR /source/glog +RUN git checkout tags/v0.6.0 +RUN mkdir /source/glog/build/ +WORKDIR /source/glog/build/ +RUN cmake .. +RUN make -j8 +RUN make install + +WORKDIR /source +RUN git clone https://gitlab.com/libeigen/eigen.git +WORKDIR /source/eigen/ +RUN git checkout tags/3.4.0 +RUN mkdir build +WORKDIR /source/eigen/build/ +RUN cmake .. +RUN make install + +#RUN yum install -y lzip +#WORKDIR /source +#RUN wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.lz +#RUN tar -xf gmp-6.3.0.tar.lz +#WORKDIR /source/gmp-6.3.0 +#RUN ./configure +#RUN make +#RUN make install +# +#WORKDIR /source +#RUN wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz +#RUN tar -xf mpfr-4.2.1.tar.xz +#WORKDIR /source/mpfr-4.2.1 +#RUN ./configure +#RUN make +#RUN make install + +#WORKDIR /source +#RUN git clone https://github.com/DrTimothyAldenDavis/SuiteSparse.git +#WORKDIR /source/SuiteSparse +#RUN git checkout tags/v7.7.0 +#WORKDIR /source/SuiteSparse/build/ +#RUN cmake .. -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so -DLAPACK_LIBRARIES=/usr/lib64/liblapack.so +#RUN cmake --build . +#RUN cmake install + +#WORKDIR /source +#RUN git clone https://github.com/google/googletest.git +#WORKDIR /source/googletest +#RUN git checkout tags/release-1.8.1 +#RUN mkdir build +#WORKDIR /source/googletest/build +#RUN cmake .. +#RUN make -j4 +#RUN make install + +WORKDIR /source +RUN git clone https://github.com/ceres-solver/ceres-solver.git +WORKDIR /source/ceres-solver +RUN git checkout tags/2.0.0 +RUN mkdir build +WORKDIR /source/ceres-solver/build/ +RUN cmake .. +RUN make -j8 +RUN make install + +WORKDIR /source +RUN git clone https://github.com/NixOS/patchelf.git +WORKDIR /source/patchelf/ +RUN git checkout tags/0.16.0 +RUN ./bootstrap.sh +RUN ./configure +RUN make +RUN make install + +RUN apt-get install -y liblzma-dev libssl-dev libopencv-dev +RUN apt-get install -y libncurses-dev libffi-dev libreadline6-dev libbz2-dev libsqlite3-dev -COPY . /source/OpenSfM +WORKDIR $SFM_DIR +RUN curl https://pyenv.run | bash +RUN /root/.pyenv/bin/pyenv install 3.9.9 +RUN /root/.pyenv/bin/pyenv global 3.9.9 +ENV PATH=$PATH:/root/.pyenv/versions/3.9.9/bin/ +RUN python -m pip install --upgrade pip -WORKDIR /source/OpenSfM +ENV WHEEL_DIR=/source/wheelhouse +ENV SFM_DIR=/source/OpenSfM +COPY . $SFM_DIR -RUN pip3 install -r requirements.txt && \ - python3 setup.py build +WORKDIR $SFM_DIR +RUN rm -rf cmake_build +RUN /root/.pyenv/versions/3.9.9/bin/pip install -r requirements.txt +RUN /root/.pyenv/versions/3.9.9/bin/pip wheel $SFM_DIR --no-deps -w $WHEEL_DIR +RUN ls /source/wheelhouse/*.whl | xargs -n 1 -I {} auditwheel repair {} --plat $PLAT -w $WHEEL_DIR +RUN cd ${WHEEL_DIR} && rm -rf *-linux*whl +RUN /root/.pyenv/versions/3.9.9/bin/pip install opensfm --no-index -f $WHEEL_DIR +RUN python -c "import opensfm" +RUN ls /source/wheelhouse/*.whl | xargs -n 1 -I {} python -m twine upload --repository-url "http://pypi.artichoke-labs.ai" {} diff --git a/README.md b/README.md index 727f3af23..ccd58c6b2 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ OpenSfM is a Structure from Motion library written in Python. The library serves Checkout this [blog post with more demos](http://blog.mapillary.com/update/2014/12/15/sfm-preview.html) +## MacOS Install + `brew install qt pyqt boost` ## Getting Started diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..e4ba520cb --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,15 @@ +version: '3.9' + +services: + opensfm: + platform: linux/amd64 + build: + context: . + dockerfile: Dockerfile + args: + - TWINE_USERNAME + - TWINE_PASSWORD + image: artichoke/opensfm + environment: + - TWINE_USERNAME + - TWINE_PASSWORD diff --git a/opensfm/src/CMakeLists.txt b/opensfm/src/CMakeLists.txt index c85aa6fb4..bd8e29799 100644 --- a/opensfm/src/CMakeLists.txt +++ b/opensfm/src/CMakeLists.txt @@ -36,6 +36,10 @@ endif() # For compiling VLFeat add_definitions(-DVL_DISABLE_AVX) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + # message(STATUS "Detected ARM architecture") + add_definitions( -DVL_DISABLE_SSE2 ) +endif() # Use the version of vlfeat in ./src/third_party/vlfeat add_definitions(-DINPLACE_VLFEAT) diff --git a/opensfm/src/third_party/SuiteSparse b/opensfm/src/third_party/SuiteSparse new file mode 160000 index 000000000..24e8e2bdd --- /dev/null +++ b/opensfm/src/third_party/SuiteSparse @@ -0,0 +1 @@ +Subproject commit 24e8e2bdddc43b98d66268b6d97f21b3229f5374 diff --git a/opensfm/src/third_party/ceres-solver b/opensfm/src/third_party/ceres-solver new file mode 160000 index 000000000..399cda773 --- /dev/null +++ b/opensfm/src/third_party/ceres-solver @@ -0,0 +1 @@ +Subproject commit 399cda773035d99eaf1f4a129a666b3c4df9d1b1 diff --git a/opensfm/src/third_party/eigen b/opensfm/src/third_party/eigen new file mode 160000 index 000000000..eeac81b8c --- /dev/null +++ b/opensfm/src/third_party/eigen @@ -0,0 +1 @@ +Subproject commit eeac81b8c067763e811d1dd7f19fe91640834f82 diff --git a/opensfm/src/third_party/gflags b/opensfm/src/third_party/gflags new file mode 160000 index 000000000..e171aa2d1 --- /dev/null +++ b/opensfm/src/third_party/gflags @@ -0,0 +1 @@ +Subproject commit e171aa2d15ed9eb17054558e0b3a6a413bb01067 diff --git a/opensfm/src/third_party/glog b/opensfm/src/third_party/glog new file mode 160000 index 000000000..b33e3bad4 --- /dev/null +++ b/opensfm/src/third_party/glog @@ -0,0 +1 @@ +Subproject commit b33e3bad4c46c8a6345525fd822af355e5ef9446 diff --git a/opensfm/src/third_party/tbb b/opensfm/src/third_party/tbb new file mode 160000 index 000000000..427c252e0 --- /dev/null +++ b/opensfm/src/third_party/tbb @@ -0,0 +1 @@ +Subproject commit 427c252e0bb9e191767a62d8a744b21950c343f6 diff --git a/requirements.txt b/requirements.txt index 0d50b21ef..0e1d26748 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,23 @@ -cloudpickle==0.4.0 -exifread==2.1.2 -flask==2.3.2 -fpdf2==2.4.6 -joblib==0.14.1 +cloudpickle>=0.4.0 +exifread>=2.1.2 +flask>=2.3.2 +fpdf2>=2.4.6 +joblib>=0.14.1 matplotlib networkx==2.5 -numpy>=1.19 +numpy Pillow>=8.1.1 pyproj>=1.9.5.1 -pytest==3.0.7 +pytest>=3.0.7 python-dateutil>=2.7 -pyyaml==5.4 -scipy>=1.10.0 -Sphinx==4.2.0 +pyyaml>=6.0 +scipy +sphinx==4.2.0 six -xmltodict==0.10.2 +xmltodict>=0.10.2 wheel -opencv-python==4.5.1.48 ; sys_platform == "win32" +opencv-python>=4.10.0 ; sys_platform == "win32" opencv-python ; sys_platform == "linux" +twine +sphinx +auditwheel==6.0.0 \ No newline at end of file diff --git a/setup.py b/setup.py index 96620d3b2..f7b44ed4f 100644 --- a/setup.py +++ b/setup.py @@ -2,14 +2,59 @@ import multiprocessing import os +import platform import subprocess import sys +from pathlib import Path +from shutil import copytree, rmtree import setuptools +from setuptools.command.install import install from sphinx.setup_command import BuildDoc from wheel.bdist_wheel import bdist_wheel -VERSION = (0, 5, 2) + +VERSION = (0, 5, 2, "post22") + +THIRD_PARTY_INSTALL_DIR = Path(__file__).parent / "third_party_install" +THIRD_PARTY_BUILD_DIR = Path(__file__).parent / "third_party_build" +THIRD_PARTY_SOURCE_DIR = Path(__file__).parent / "opensfm/src/third_party" +THIRD_PARTY_BUILD_DIR.mkdir(exist_ok=True) +LIB_DIR = THIRD_PARTY_INSTALL_DIR / "usr/local/lib" +INCLUDE_DIR = THIRD_PARTY_INSTALL_DIR / "usr/local/include" + +SHARE_DIR = THIRD_PARTY_INSTALL_DIR / "usr/local/share" +SHARED_CMAKE_DIR = THIRD_PARTY_INSTALL_DIR / "usr/local/lib/cmake/" + +CMAKE_PREFIX_PATH = ( + f'-DCMAKE_PREFIX_PATH={SHARED_CMAKE_DIR};' + f'{SHARE_DIR};' + f'{SHARE_DIR}/eigen3;' + f'{INCLUDE_DIR};' + f'{INCLUDE_DIR}/eigen3;' + f'{LIB_DIR};' + f'{THIRD_PARTY_BUILD_DIR};' + f'{THIRD_PARTY_BUILD_DIR / "SuiteSparse"}; ' +) +CMAKE_OSX_SYSROOT = '-DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/' + +os.environ['LDFLAGS'] = f'-L/opt/homebrew/Cellar/libomp/18.1.6/lib' +os.environ['C_INCLUDE_PATH'] = f'/opt/homebrew/Cellar/libomp/18.1.6/include/' +os.environ['CPLUS_INCLUDE_PATH'] = f'/opt/homebrew/Cellar/libomp/18.1.6/include/:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/include/c++/v1/' + + +def _is_apple_silicon() -> bool: + + if platform.system() == 'Darwin': + if platform.machine() == 'arm64': + return True + return False + + +if _is_apple_silicon(): + os.environ['arch'] = 'arm64' + +# def version_str(version): @@ -24,23 +69,213 @@ def finalize_options(self): self.root_is_pure = False -def configure_c_extension(): - """Configure cmake project to C extension.""" - print( - f"Configuring for python {sys.version_info.major}.{sys.version_info.minor}..." +class InstallPlatlib(install): + def finalize_options(self): + install.finalize_options(self) + self.install_lib = self.install_platlib + + +def install_gflag(install_dir: Path): + gflags_build_dir = THIRD_PARTY_BUILD_DIR / "gflags" + gflag_source_dir = Path(__file__).parent.joinpath("opensfm/src/third_party/gflags/") + if not gflags_build_dir.exists(): + gflags_build_dir.mkdir() + cmake_command = [ + 'cmake', + CMAKE_OSX_SYSROOT, + '-DCMAKE_CXX_FLAGS="-fPIC"', + gflag_source_dir + ] + subprocess.check_call( + cmake_command, + cwd=gflags_build_dir.as_posix(), + env=os.environ, ) - os.makedirs("cmake_build", exist_ok=True) + + subprocess.check_call(["make", "-j8"], cwd=gflags_build_dir.as_posix()) + subprocess.check_call(["make", f"DESTDIR={install_dir}", "install"], cwd=gflags_build_dir.as_posix()) + + +def install_glog(install_dir: Path): + glog_build_dir = THIRD_PARTY_BUILD_DIR / "glog" + glog_source_dir = THIRD_PARTY_SOURCE_DIR / "glog" + + if not glog_build_dir.exists(): + glog_build_dir.mkdir() + + cmake_command = [ + 'cmake', + CMAKE_OSX_SYSROOT, + CMAKE_PREFIX_PATH, + glog_source_dir.as_posix() + ] + + subprocess.check_call( + cmake_command, + cwd=glog_build_dir.as_posix(), + env=os.environ, + ) + subprocess.check_call(["make", "-j8"], cwd=glog_build_dir.as_posix()) + subprocess.check_call(["make", f"DESTDIR={install_dir}", "install"], cwd=glog_build_dir.as_posix()) + + +def install_eigen(install_dir: Path): + eigen_build_dir = THIRD_PARTY_BUILD_DIR / "eigen" + eigen_source_dir = THIRD_PARTY_SOURCE_DIR / "eigen" + + if not eigen_build_dir.exists(): + eigen_build_dir.mkdir() + + cmake_command = [ + 'cmake', + CMAKE_OSX_SYSROOT, + CMAKE_PREFIX_PATH, + eigen_source_dir.as_posix(), + ] + + + subprocess.check_call( + cmake_command, + cwd=eigen_build_dir.as_posix(), + env=os.environ, + ) + subprocess.check_call(["make", f"DESTDIR={install_dir}", "install"], cwd=eigen_build_dir.as_posix()) + + +def install_tbb(): + tbb_source_dir = THIRD_PARTY_SOURCE_DIR / "tbb" + tbb_build_dir = THIRD_PARTY_BUILD_DIR / "tbb" + tbb_build_lib = tbb_build_dir / 'lib' + tbb_build_include = tbb_build_dir / 'include' + + make_command = [] + make_command.extend(['make']) + subprocess.check_call( + make_command, + cwd=tbb_source_dir.as_posix(), + env=os.environ, + ) + tbb_potential_dirs = list(tbb_source_dir.rglob("libtbb*")) + if len(tbb_potential_dirs) == 0: + raise RuntimeError('Could not find tbb lib') + tbb_libb_dir = tbb_potential_dirs[0].parent + print(f'Found tbb lib dir: {tbb_libb_dir}') + if tbb_build_lib.exists(): + rmtree(tbb_build_lib) + if tbb_build_include.exists(): + rmtree(tbb_build_include) + + copytree(tbb_libb_dir, tbb_build_lib) + copytree(tbb_source_dir.joinpath("include"), tbb_build_include) + os.environ['TBB_ROOT'] = tbb_build_dir.as_posix() + os.environ['LD_LIBRARY_PATH'] = f"{tbb_build_lib.as_posix()}:{os.environ.get('LD_LIBRARY_PATH', '')}" + os.environ['LIBRARY_PATH'] = f"{tbb_build_lib.as_posix()}:{os.environ.get('LD_LIBRARY_PATH', '')}" + os.environ['C_INCLUDE_PATH'] = f"{tbb_build_include}:{os.environ.get('C_INCLUDE_PATH', '')}" + os.environ['CPLUS_INCLUDE_PATH'] = f"{tbb_build_include}:{os.environ.get('CPLUS_INCLUDE_PATH', '')}" + + +def install_suitesparse(install_dir: Path): + suitesparse_build_dir = THIRD_PARTY_BUILD_DIR / "SuiteSparse" + suitesparse_source_dir = THIRD_PARTY_SOURCE_DIR / "SuiteSparse" + suitesparse_build_lib = suitesparse_build_dir / 'lib' + suitesparse_build_include = suitesparse_build_dir / 'include' + + if not suitesparse_build_dir.exists(): + suitesparse_build_dir.mkdir() + + subprocess.check_call( + [ + "make", + '-j8' + ], + cwd=suitesparse_source_dir.as_posix() + ) + subprocess.check_call( + [ + "make", + 'local' + ], + cwd=suitesparse_source_dir.as_posix() + ) + subprocess.check_call(["make", f"DESTDIR={install_dir}", "install"], cwd=suitesparse_source_dir.as_posix()) + + if suitesparse_build_lib.exists(): + rmtree(suitesparse_build_lib) + if suitesparse_build_include.exists(): + rmtree(suitesparse_build_include) + + copytree(suitesparse_source_dir / "lib", suitesparse_build_lib) + copytree(suitesparse_source_dir.joinpath("include"), suitesparse_build_include) + + +def install_ceres(install_dir: Path): + ceres_build_dir = THIRD_PARTY_BUILD_DIR / "ceres_solver" + ceres_source_dir = THIRD_PARTY_SOURCE_DIR / "ceres-solver" + if not ceres_build_dir.exists(): + ceres_build_dir.mkdir() + + cmake_command = [ + 'cmake', + CMAKE_OSX_SYSROOT, + CMAKE_PREFIX_PATH, + f'-DSUITESPARSE_LIBRARY_DIR_HINTS={install_dir}', + f'-DSUITESPARSE_INCLUDE_DIRS={THIRD_PARTY_BUILD_DIR / "SuiteSparse/include/"}', + f'-DSUITESPARSE_LIBRARY_DIRS={THIRD_PARTY_BUILD_DIR / "SuiteSparse/lib/"}', + f'-DSUITESPARSE_LIBRARIES={THIRD_PARTY_BUILD_DIR / "SuiteSparse/lib/"}', + # f'-DTBB_ROOT={os.environ["TBB_ROOT"]}', + + ceres_source_dir.as_posix() + ] + subprocess.check_call( + cmake_command, + cwd=ceres_build_dir.as_posix() + ) + subprocess.check_call(["make", "-j8"], cwd=ceres_build_dir.as_posix()) + subprocess.check_call(["make", f"DESTDIR={install_dir}", "install"], cwd=ceres_build_dir.as_posix(), env=os.environ) + + +def install_opensfm(install_dir: Path): + + if not install_dir.exists(): + install_dir.mkdir() + cmake_command = [ "cmake", + CMAKE_OSX_SYSROOT, + CMAKE_PREFIX_PATH, + f'-DEigen3_DIR={INCLUDE_DIR}/eigen3', "../opensfm/src", "-DPYTHON_EXECUTABLE=" + sys.executable, ] + if sys.platform == "win32": cmake_command += [ "-DVCPKG_TARGET_TRIPLET=x64-windows", "-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake", ] - subprocess.check_call(cmake_command, cwd="cmake_build") + subprocess.check_call( + cmake_command, + cwd=install_dir.as_posix(), + # env=os.environ + ) + + +def configure_c_extension(): + """Configure cmake project to C extension.""" + print( + f"Configuring for python {sys.version_info.major}.{sys.version_info.minor}..." + ) + + if platform.system() == 'Darwin': + # Third party install + install_gflag(THIRD_PARTY_INSTALL_DIR) + install_glog(THIRD_PARTY_INSTALL_DIR) + install_eigen(THIRD_PARTY_INSTALL_DIR) + install_tbb() + install_suitesparse(THIRD_PARTY_INSTALL_DIR) + install_ceres(THIRD_PARTY_INSTALL_DIR) + + install_opensfm(Path(__file__).parent / "cmake_build") def build_c_extension(): @@ -59,6 +294,10 @@ def build_c_extension(): configure_c_extension() build_c_extension() +install_requires = [] +with open("requirements.txt") as f: + install_requires = f.read().splitlines() + setuptools.setup( name="opensfm", version=version_str(VERSION), @@ -73,8 +312,28 @@ def build_c_extension(): license="BSD", packages=setuptools.find_packages(), scripts=[ + "bin/import_colmap.py", + "bin/opensfm.bat", + "bin/plot_features", + "bin/plot_tracks", + "bin/create_calibrtion_pattern", + "bin/import_video", + "bin/opensfm_main.py", + "bin/plot_gcp.py", + "bin/run_bundler", + "bin/export_geojson", + "bin/iterative_self_calibration", "bin/opensfm_run_all", + "bin/plot_inliers", + "bin/update_geotag", + "bin/export_gps", + "bin/migrate_undistort.sh", + "bin/opensfm_run_all.bat", + "bin/plot_matches.py", + "bin/import_bundler", "bin/opensfm", + "bin/plot_depthmaps", + "bin/plot_submodels_gps", ], package_data={ "opensfm": [ @@ -96,6 +355,7 @@ def build_c_extension(): cmdclass={ "bdist_wheel": platform_bdist_wheel, "build_doc": BuildDoc, + "install": InstallPlatlib, }, command_options={ "build_doc": { @@ -106,4 +366,5 @@ def build_c_extension(): "build_dir": ("setup.py", "build/doc"), } }, + install_requires=install_requires )