diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c414bb7136d..50bca08573f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -276,6 +276,7 @@ jobs: run: | $ErrorActionPreference = 'Stop' python -m pip install -r python/requirements.txt + python -m pip install -r python/requirements_gui.txt python -m pip install -r python/requirements_jupyter_build.txt - name: Config @@ -399,7 +400,7 @@ jobs: $PIP_PKG_NAME=(Get-ChildItem open3d*-$py_tag-*.whl).Name } echo "Installing Open3D wheel $PIP_PKG_NAME in virtual environment..." - python -m pip install "$PIP_PKG_NAME" + python -m pip install "$PIP_PKG_NAME[gui,ml]" python -c "import open3d; print('Imported:', open3d)" python -c "import open3d; print('CUDA enabled: ', open3d.core.cuda.is_available())" diff --git a/3rdparty/README_SYCL.md b/3rdparty/README_SYCL.md index 5a6120f753a..bfa95a1376c 100644 --- a/3rdparty/README_SYCL.md +++ b/3rdparty/README_SYCL.md @@ -98,7 +98,7 @@ Open3D is designed to make use of the SYCL GPU devices. ## List of oneAPI Python packages -To make `pip install open3d` works out-of-the box on SYCL-enabled platforms, +To make `pip install open3d[gui,ml]` works out-of-the box on SYCL-enabled platforms, we can utilize runtime libraries released via PyPI. This feature needs to be implemented. diff --git a/CHANGELOG.md b/CHANGELOG.md index a0880065ba5..89cafd0c7ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Fix raycasting scene: Allow setting of number of threads that are used for building a raycasting scene * Fix Python bindings for CUDA device synchronization, voxel grid saving (PR #5425) * Support msgpack versions without cmake +* Introduce new optional dependencies support, allowing you to do `pip install open3d` with any of `gui`, `ml`, `tf`, `torch`, `all` such as `pip install open3d[gui,ml]` ## 0.13 diff --git a/README.md b/README.md index ced7235af9f..57ee584b866 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ Pre-built pip packages support Ubuntu 18.04+, macOS 10.15+ and Windows 10+ ```bash # Install -pip install open3d # or -pip install open3d-cpu # Smaller CPU only wheel on x86_64 Linux (v0.17+) +pip install open3d[gui,ml] # or +pip install open3d-cpu[gui,ml] # Smaller CPU only wheel on x86_64 Linux (v0.17+) # Verify installation python -c "import open3d as o3d; print(o3d.__version__)" diff --git a/cpp/pybind/make_install_pip_package.cmake b/cpp/pybind/make_install_pip_package.cmake index a5c9fcdd05c..b65ff8cc0cd 100644 --- a/cpp/pybind/make_install_pip_package.cmake +++ b/cpp/pybind/make_install_pip_package.cmake @@ -5,4 +5,4 @@ # it is guaranteed that there is only one wheel in ${PYTHON_PACKAGE_DST_DIR}/pip_package/*.whl file(GLOB WHEEL_FILE "${PYTHON_PACKAGE_DST_DIR}/pip_package/*.whl") execute_process(COMMAND ${Python3_EXECUTABLE} -m pip uninstall open3d --yes) -execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install ${WHEEL_FILE} -U) +execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install "${WHEEL_FILE}[gui,ml]" -U) diff --git a/cpp/pybind/make_python_package.cmake b/cpp/pybind/make_python_package.cmake index dee6e394d36..7ee237a069c 100644 --- a/cpp/pybind/make_python_package.cmake +++ b/cpp/pybind/make_python_package.cmake @@ -113,6 +113,7 @@ if (BUILD_JUPYTER_EXTENSION) # These will be installed when `pip install open3d`. execute_process(COMMAND ${CMAKE_COMMAND} -E cat ${PYTHON_PACKAGE_SRC_DIR}/requirements.txt + ${PYTHON_PACKAGE_SRC_DIR}/requirements_gui.txt ${PYTHON_PACKAGE_SRC_DIR}/requirements_jupyter_install.txt OUTPUT_VARIABLE ALL_REQUIREMENTS ) diff --git a/docker/Dockerfile.openblas b/docker/Dockerfile.openblas index aba9297a533..a7911a3e8a6 100644 --- a/docker/Dockerfile.openblas +++ b/docker/Dockerfile.openblas @@ -72,6 +72,7 @@ COPY ./python/requirements*.txt /root/Open3D/python/ RUN which python \ && python --version \ && python -m pip install -U -r /root/Open3D/python/requirements.txt \ + -r /root/Open3D/python/requirements_gui.txt \ -r /root/Open3D/python/requirements_build.txt \ -r /root/Open3D/python/requirements_test.txt diff --git a/docs/arm.rst b/docs/arm.rst index dddb894987d..dd857ee9a8a 100644 --- a/docs/arm.rst +++ b/docs/arm.rst @@ -9,7 +9,7 @@ we provide pre-compiled ARM64 wheels for Linux and macOS. Install the wheel by: .. code-block:: bash - pip install open3d + pip install open3d[gui,ml] python -c "import open3d; print(open3d.__version__)" # Test the legacy visualizer @@ -18,21 +18,21 @@ we provide pre-compiled ARM64 wheels for Linux and macOS. Install the wheel by: # Test the new GUI visualizer python -c "import open3d as o3d; c = o3d.geometry.TriangleMesh.create_box(); o3d.visualization.draw(c)" -+------------------------+----------------+---------------------+------------+----------------+ -| | Linux (OpenGL) | Linux (OpenGL ES) | macOS | Windows on ARM | -+========================+================+=====================+============+================+ -| ``pip install open3d`` | Yes | Yes | Yes | No | -+------------------------+----------------+---------------------+------------+----------------+ -| Compile from source | Yes | Yes | Yes | No | -+------------------------+----------------+---------------------+------------+----------------+ -| Visualizer and GUI | Yes | No | Yes | No | -+------------------------+----------------+---------------------+------------+----------------+ -| Non-GUI features | Yes | Yes | Yes | No | -+------------------------+----------------+---------------------+------------+----------------+ -| Special build flags | Not needed | ``-DBUILD_GUI=OFF`` | Not needed | N/A | -+------------------------+----------------+---------------------+------------+----------------+ -| Example device | Nvidia Jetson | Raspberry Pi 4 | M1 MacBook | Surface Pro X | -+------------------------+----------------+---------------------+------------+----------------+ ++--------------------------------+----------------+---------------------+------------+----------------+ +| | Linux (OpenGL) | Linux (OpenGL ES) | macOS | Windows on ARM | ++================================+================+=====================+============+================+ +| ``pip install open3d[gui,ml]`` | Yes | Yes | Yes | No | ++--------------------------------+----------------+---------------------+------------+----------------+ +| Compile from source | Yes | Yes | Yes | No | ++--------------------------------+----------------+---------------------+------------+----------------+ +| Visualizer and GUI | Yes | No | Yes | No | ++--------------------------------+----------------+---------------------+------------+----------------+ +| Non-GUI features | Yes | Yes | Yes | No | ++--------------------------------+----------------+---------------------+------------+----------------+ +| Special build flags | Not needed | ``-DBUILD_GUI=OFF`` | Not needed | N/A | ++--------------------------------+----------------+---------------------+------------+----------------+ +| Example device | Nvidia Jetson | Raspberry Pi 4 | M1 MacBook | Surface Pro X | ++--------------------------------+----------------+---------------------+------------+----------------+ Additional notes: @@ -107,7 +107,7 @@ TBB, Parallel STL, BLAS, LAPACK) may cause compatibility issues if they are not the same version as the one used by Open3D. If you only need the Python wheel, consider using the Docker build method or -install Open3D via ``pip install open3d`` directly. +install Open3D via ``pip install open3d[gui,ml]`` directly. Install dependencies ```````````````````` diff --git a/docs/docker.in.rst b/docs/docker.in.rst index 25714d0f5d8..4391ce5a908 100644 --- a/docs/docker.in.rst +++ b/docs/docker.in.rst @@ -42,7 +42,7 @@ Python applications looks like this: # Install Open3D from the PyPI repositories RUN python3 -m pip install --no-cache-dir --upgrade pip && \ - python3 -m pip install --no-cache-dir --upgrade open3d + python3 -m pip install --no-cache-dir --upgrade open3d[gui,ml] If you have an NVIDIA GPU and want to use it for computation (``CUDA``) or visualization, follow these `directions. diff --git a/docs/getting_started.in.rst b/docs/getting_started.in.rst index e3ff7529fa6..7747bc514a4 100644 --- a/docs/getting_started.in.rst +++ b/docs/getting_started.in.rst @@ -35,9 +35,13 @@ Pip (PyPI) .. code-block:: bash - pip install open3d # or - pip install open3d-cpu # Smaller CPU only wheel on x86_64 Linux (since v0.17+) + pip install open3d[gui,ml] # or + pip install open3d-cpu[gui,ml] # Smaller CPU only wheel on x86_64 Linux (since v0.17+) +.. note:: + Above will work for most purposes and aligns with behavior seen in `v0.17` and below. + Using anything under :mod:`open3d.visualization` will require ``[gui]`` where as + using anything under :mod:`open3d.ml` will require ``[ml]``. .. note:: Please upgrade your ``pip`` to a version >=20.3 to install Open3D in Linux, @@ -54,11 +58,11 @@ Pip (PyPI) .. code-block:: bash - pip3 install open3d + pip3 install open3d[gui,ml] # or - pip install --user open3d + pip install --user open3d[gui,ml] # or - python3 -m pip install --user open3d + python3 -m pip install --user open3d[gui,ml] Development version (pip) ------------------------- diff --git a/docs/tutorial/sensor/realsense.rst b/docs/tutorial/sensor/realsense.rst index b14f9e02474..b40d52b36e1 100644 --- a/docs/tutorial/sensor/realsense.rst +++ b/docs/tutorial/sensor/realsense.rst @@ -18,7 +18,7 @@ Install Open3D from PyPI (a virtual environment is recommended): .. code-block:: sh - pip install open3d + pip install open3d[gui,ml] Compile from source (C++) ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,8 +251,8 @@ during capture and performing it while reading the bad file instead. This is a complete C++ example that shows visualizing live capture and recording to a bag file. The recording can be paused / resumed with [SPACE]. Use [ESC] to -stop capture and quit. You can download the -`rs_default_config.json `_ +stop capture and quit. You can download the +`rs_default_config.json `_ and use this example to capture your own dataset:: make RealSenseRecorder diff --git a/python/open3d/__init__.py b/python/open3d/__init__.py index 6344140669f..7c4ba64e8fd 100644 --- a/python/open3d/__init__.py +++ b/python/open3d/__init__.py @@ -109,7 +109,14 @@ def _insert_pybind_names(skip_names=()): sys.modules.update(submodules) -import open3d.visualization +try: + import open3d.visualization +except ModuleNotFoundError: + warnings.warn( + "Open3D Python GUI Libraries not found. " + "Please make sure to install open3d[gui] if you wish to use " + "the open3d.visualization module.", RuntimeWarning) + _insert_pybind_names(skip_names=("ml",)) __version__ = "@PROJECT_VERSION@" @@ -142,10 +149,16 @@ def _insert_pybind_names(skip_names=()): if "OPEN3D_ML_ROOT" in os.environ: print("Using external Open3D-ML in {}".format(os.environ["OPEN3D_ML_ROOT"])) sys.path.append(os.environ["OPEN3D_ML_ROOT"]) -import open3d.ml -# Finally insert pybind names corresponding to ml -_insert_pybind_names() +try: + import open3d.ml + # Finally insert pybind names corresponding to ml + _insert_pybind_names() +except ModuleNotFoundError: + warnings.warn( + "Open3D Python ML Libraries not found. " + "Please make sure to install open3d[ml] if you wish to use " + "the open3d.ml module.", RuntimeWarning) def _jupyter_labextension_paths(): diff --git a/python/requirements.txt b/python/requirements.txt index 1affea6046d..1ef04f80f3b 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,5 +1,3 @@ numpy>=1.18.0 -dash>=2.6.0 -werkzeug>=2.2.3 nbformat==5.7.0 configargparse diff --git a/python/requirements_gui.txt b/python/requirements_gui.txt new file mode 100644 index 00000000000..817af47a1d5 --- /dev/null +++ b/python/requirements_gui.txt @@ -0,0 +1,2 @@ +dash>=2.6.0 +werkzeug>=2.2.3 \ No newline at end of file diff --git a/python/setup.py b/python/setup.py index 5e69df23932..c59d18a269a 100644 --- a/python/setup.py +++ b/python/setup.py @@ -9,6 +9,7 @@ import sys import platform import ctypes +from collections import defaultdict from setuptools import setup, find_packages from setuptools.command.install import install as _install from wheel.bdist_wheel import bdist_wheel as _bdist_wheel @@ -93,10 +94,44 @@ def finalize_options(self): with open("requirements.txt", "r") as f: install_requires = [line.strip() for line in f.readlines() if line] -# Read requirements for ML. +# Read extra requirements for GUI/ML/TF/Torch. +extra_requires = defaultdict(list) + +# GUI Deps +with open("requirements_gui.txt", "r") as f: + extra_requires["gui"] += [line.strip() for line in f.readlines() if line] + +# Make sure GUI deps is part of "all" +extra_requires["all"] += extra_requires["gui"] + if "@BUNDLE_OPEN3D_ML@" == "ON": + # ML Deps with open("@OPEN3D_ML_ROOT@/requirements.txt", "r") as f: - install_requires += [line.strip() for line in f.readlines() if line] + extra_requires["ml"] += [line.strip() for line in f.readlines() if line] + extra_requires["all"] += extra_requires["ml"] + + # ML + TF Deps + with open("@OPEN3D_ML_ROOT@/requirements-tensorflow.txt", "r") as f: + extra_requires["tf"] += extra_requires["ml"] + extra_requires["tf"] += [line.strip() for line in f.readlines() if line] + extra_requires["all"] += extra_requires["tf"] + + # ML + Torch Deps + if "@BUILD_CUDA_MODULE@" == "ON": + torch_reqs = "@OPEN3D_ML_ROOT@/requirements-torch-cuda.txt" + else: + torch_reqs = "@OPEN3D_ML_ROOT@/requirements-torch.txt" + with open(torch_reqs, "r") as f: + extra_requires["torch"] += extra_requires["ml"] + extra_requires["torch"] += [ + line.strip() + for line in f.readlines() + if line and not line.startswith("-") + ] + extra_requires["all"] += extra_requires["torch"] + +# Dedupe Extras w/ All +extra_requires["all"] = list(set(extra_requires["all"])) entry_points = { "console_scripts": ["open3d = @PYPI_PACKAGE_NAME@.tools.cli:main",] @@ -160,6 +195,7 @@ def finalize_options(self): python_requires=">=3.6", include_package_data=True, install_requires=install_requires, + extras_require=extra_requires, packages=find_packages(), entry_points=entry_points, zip_safe=False, diff --git a/util/ci_utils.sh b/util/ci_utils.sh index 887e507fff5..277ef6a9633 100644 --- a/util/ci_utils.sh +++ b/util/ci_utils.sh @@ -83,6 +83,7 @@ install_python_dependencies() { # TODO: modify other locations to use requirements.txt python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements.txt" + python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_gui.txt" if [[ "with-jupyter" =~ ^($options)$ ]]; then python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_jupyter_build.txt" fi @@ -262,7 +263,7 @@ test_wheel() { echo -n "Using pip: " python -m pip --version echo "Installing Open3D wheel $wheel_path in virtual environment..." - python -m pip install "$wheel_path" + python -m pip install "${wheel_path}[gui,ml]" python -c "import open3d; print('Installed:', open3d); print('BUILD_CUDA_MODULE: ', open3d._build_config['BUILD_CUDA_MODULE'])" python -c "import open3d; print('CUDA available: ', open3d.core.cuda.is_available())" echo @@ -392,6 +393,7 @@ install_docs_dependencies() { fi echo python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements.txt" + python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_gui.txt" python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_jupyter_build.txt" python -m pip install -r "${OPEN3D_SOURCE_ROOT}/docs/requirements.txt" }