diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..fa26aa59 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[bug]" +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Log** +If applicable, copy paste the relevant log output (please embed the text in a markdown code tag "```" ) + +**Desktop (please complete the following and other pertinent information):** + - OS: [e.g. win 10, osx, ] + - Version [e.g. 2019.1] + - Python version [e.g. 2.6] + - Qt/PySide version [e.g. 5.12.4] + - Binary version (if applicable) [e.g. 2019.1] + - Commit reference (if applicable) [e.g. 08ddbe2] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..52683c44 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[request]" +labels: feature request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..de3799ad --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ + +## Description + + + +## Features list + + + + +## Implementation remarks + + + diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..e33f1ed9 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 120 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: false +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: > + This issue is closed due to inactivity. Feel free to re-open if new information + is available. diff --git a/CHANGES.md b/CHANGES.md index 280838f9..c8773c2b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,40 @@ For algorithmic changes related to the photogrammetric pipeline, please refer to [AliceVision changelog](https://github.com/alicevision/AliceVision/blob/develop/CHANGES.md). + +## Release 2019.2.0 (2019.08.08) + +Based on [AliceVision 2.2.0](https://github.com/alicevision/AliceVision/tree/v2.2.0). + +Release Notes Summary: + + - Visualisation: New visualization module of the features extraction. [PR](https://github.com/alicevision/meshroom/pull/539), [New QtAliceVision](https://github.com/alicevision/QtAliceVision) + - Support for RAW image files. + - Texturing: Largely improve the Texturing quality. + - Texturing: Speed improvements. + - Texturing: Add support for UDIM. + - Meshing: Export the dense point cloud in Alembic. + - Meshing: New option to export the full raw dense point cloud (with all 3D points candidates before cut and filtering). + - Meshing: Adds an option to export color data per vertex and MeshFiltering correctly preserves colors. + +Full Release Notes: + + - Move to PySide2 / Qt 5.13 + - SfMDataIO: Change root nodes (XForms instead of untyped objects) of Alembic SfMData for better interoperability with other 3D graphics applications (in particular Blender and Houdini). + - Improve performance of log display and node status update. [PR](https://github.com/alicevision/meshroom/pull/466) [PR](https://github.com/alicevision/meshroom/pull/548) + - Viewer3D: Add support for vertex-colored meshes. [PR](https://github.com/alicevision/meshroom/pull/550) + - New pipeline input for meshroom_photogrammetry command line and minor fixes to the input arguments. [PR](https://github.com/alicevision/meshroom/pull/567) [PR](https://github.com/alicevision/meshroom/pull/577) + - New arguments to meshroom. [PR](https://github.com/alicevision/meshroom/pull/413) + - HDR: New HDR module for the fusion of multiple LDR images. + - PrepareDenseScene: Add experimental option to correct Exposure Values (EV) of input images to uniformize dataset exposures. + - FeatureExtraction: Include CCTag in the release binaries both on Linux and Windows. + - ConvertSfMFormat: Enable to use simple regular expressions in the image white list of the ConvertSfMFormat. This enables to filter out cameras based on their filename. + +For more details see all PR merged: https://github.com/alicevision/meshroom/milestone/9 +See [AliceVision 2.2.0 Release Notes](https://github.com/alicevision/AliceVision/blob/v2.2.0/CHANGES.md) +for more details about algorithmic changes. + + ## Release 2019.1.0 (2019.02.27) Based on [AliceVision 2.1.0](https://github.com/alicevision/AliceVision/tree/v2.1.0). diff --git a/CMakeLists.txt b/CMakeLists.txt index acae6127..2625faa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ set(QT_DIR "$ENV{QT_DIR}" CACHE STRING "Qt root directory") option(MR_BUILD_QTOIIO "Enable building of QtOIIO plugin" ON) option(MR_BUILD_QMLALEMBIC "Enable building of qmlAlembic plugin" ON) +option(MR_BUILD_QTALICEVISION "Enable building of qtAliceVision plugin" ON) if(CMAKE_BUILD_TYPE MATCHES Release) message(STATUS "Force CMAKE_INSTALL_DO_STRIP in Release") @@ -30,7 +31,6 @@ set(ALEMBIC_CMAKE_FLAGS -DAlembic_DIR:PATH=${ALICEVISION_ROOT}/lib64/cmake/Alembic -DILMBASE_ROOT=${ALICEVISION_ROOT} ) -set(QT_CMAKE_FLAGS -DCMAKE_PREFIX_PATH=${QT_DIR}) include(ExternalProject) @@ -44,7 +44,7 @@ include(GNUInstallDirs) # message(STATUS "QT_CMAKE_FLAGS: ${QT_CMAKE_FLAGS}") if(MR_BUILD_QTOIIO) -set(QTOIIO_TARGET qtoiio) +set(QTOIIO_TARGET qtOIIO) ExternalProject_Add(${QTOIIO_TARGET} GIT_REPOSITORY https://github.com/alicevision/QtOIIO GIT_TAG develop @@ -54,13 +54,13 @@ ExternalProject_Add(${QTOIIO_TARGET} SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/qtoiio BINARY_DIR ${BUILD_DIR}/qtoiio_build INSTALL_DIR ${CMAKE_INSTALL_PREFIX} - CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${OIIO_CMAKE_FLAGS} ${QT_CMAKE_FLAGS} -DCMAKE_INSTALL_PREFIX:PATH= + CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${OIIO_CMAKE_FLAGS} -DCMAKE_PREFIX_PATH:PATH=${QT_DIR} -DCMAKE_INSTALL_PREFIX:PATH= ) endif() if(MR_BUILD_QMLALEMBIC) -set(QMLALEMBIC_TARGET qmlalembic) +set(QMLALEMBIC_TARGET qmlAlembic) ExternalProject_Add(${QMLALEMBIC_TARGET} GIT_REPOSITORY https://github.com/alicevision/qmlAlembic GIT_TAG develop @@ -70,7 +70,22 @@ ExternalProject_Add(${QMLALEMBIC_TARGET} SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/qmlalembic BINARY_DIR ${BUILD_DIR}/qmlalembic_build INSTALL_DIR ${CMAKE_INSTALL_PREFIX} - CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${ALEMBIC_CMAKE_FLAGS} ${QT_CMAKE_FLAGS} -DCMAKE_INSTALL_PREFIX:PATH= + CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${ALEMBIC_CMAKE_FLAGS} -DCMAKE_PREFIX_PATH:PATH=${QT_DIR} -DCMAKE_INSTALL_PREFIX:PATH= + ) +endif() + +if(MR_BUILD_QTALICEVISION) +set(QTALICEVISION_TARGET qtAliceVision) +ExternalProject_Add(${QTALICEVISION_TARGET} + GIT_REPOSITORY https://github.com/alicevision/qtAliceVision + GIT_TAG develop + PREFIX ${BUILD_DIR} + BUILD_IN_SOURCE 0 + BUILD_ALWAYS 0 + SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/qtAliceVision + BINARY_DIR ${BUILD_DIR}/qtAliceVision_build + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + CONFIGURE_COMMAND ${CMAKE_COMMAND} ${CMAKE_CORE_BUILD_FLAGS} ${ALEMBIC_CMAKE_FLAGS} -DCMAKE_PREFIX_PATH:PATH=${QT_DIR}$${ALICEVISION_ROOT} -DCMAKE_INSTALL_PREFIX:PATH= ) endif() diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..06cbb2f8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team privately at alicevision-team@googlegroups.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct/ + +[homepage]: https://www.contributor-covenant.org diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e3f4e00f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,32 @@ +Contributing to Meshroom +=========================== + +Meshroom relies on a friendly and community-driven effort to create an open source photogrammetry solution. +In order to foster a friendly atmosphere where technical collaboration can flourish, +we recommend you to read the [code of conduct](CODE_OF_CONDUCT.md). + + +Contributing Workflow +--------------------- + +The contributing workflow relies on [Github Pull Requests](https://help.github.com/articles/using-pull-requests/). + +1. If it is an important change, we recommend you to discuss it on the mailing-list +before starting implementation. This ensure that the development is aligned with other +developpements already started and will be efficiently integrated. + +2. Create the corresponding issues. + +3. Create a branch and [draft a pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) "My new feature" so everyone can follow the development. +Explain the implementation in the PR description with links to issues. + +4. Implement the new feature(s). Add unit test if needed. +One feature per PR is ideal for review, but linked features can be part of the same PR. + +5. When it is ready for review, [mark the pull request as ready for review](https://help.github.com/en/articles/changing-the-stage-of-a-pull-request). + +6. The reviewers will look over the code and ask for changes, explain problems they found, +congratulate the author, etc. using the github comments. + +7. After approval, one of the developers with commit approval to the official main repository +will merge your fixes into the "develop" branch. diff --git a/Dockerfile b/Dockerfile index 93fb664b..4de93473 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG CUDA_TAG=7.0 ARG OS_TAG=7 -FROM alicevision:centos${OS_TAG}-cuda${CUDA_TAG} +FROM alicevision/alicevision:2.2.0-centos${OS_TAG}-cuda${CUDA_TAG} LABEL maintainer="AliceVision Team alicevision-team@googlegroups.com" # Execute with nvidia docker (https://github.com/nvidia/nvidia-docker/wiki/Installation-(version-2.0)) @@ -9,10 +9,11 @@ LABEL maintainer="AliceVision Team alicevision-team@googlegroups.com" ENV MESHROOM_DEV=/opt/Meshroom \ MESHROOM_BUILD=/tmp/Meshroom_build \ MESHROOM_BUNDLE=/opt/Meshroom_bundle \ - QT_DIR=/opt/qt/5.11.1/gcc_64 \ + QT_DIR=/opt/qt/5.13.0/gcc_64 \ PATH="${PATH}:${MESHROOM_BUNDLE}" -COPY . "${MESHROOM_DEV}" +# Workaround for qmlAlembic/qtAliceVision builds: fuse lib/lib64 folders +RUN cp -rf ${AV_INSTALL}/lib/* ${AV_INSTALL}/lib64 && rm -rf ${AV_INSTALL}/lib && ln -s ${AV_INSTALL}/lib64 ${AV_INSTALL}/lib # Install libs needed by Qt RUN yum install -y \ @@ -36,33 +37,35 @@ RUN yum install -y \ xcb-util-image # Install Python3 -RUN yum install -y centos-release-scl -RUN yum install -y rh-python36 +RUN yum install -y centos-release-scl && yum install -y rh-python36 + +COPY . "${MESHROOM_DEV}" + +WORKDIR "${MESHROOM_DEV}" # Install Meshroom requirements and freeze bundle -RUN source scl_source enable rh-python36 && cd "${MESHROOM_DEV}" && pip install -r dev_requirements.txt -r requirements.txt && python setup.py install_exe -d "${MESHROOM_BUNDLE}" && \ +RUN source scl_source enable rh-python36 && pip install -r dev_requirements.txt -r requirements.txt && python setup.py install_exe -d "${MESHROOM_BUNDLE}" && \ find ${MESHROOM_BUNDLE} -name "*Qt5Web*" -delete && \ find ${MESHROOM_BUNDLE} -name "*Qt5Designer*" -delete && \ - rm ${MESHROOM_BUNDLE}/lib/PySide2/libclang.so* && \ rm -rf ${MESHROOM_BUNDLE}/lib/PySide2/typesystems/ ${MESHROOM_BUNDLE}/lib/PySide2/examples/ ${MESHROOM_BUNDLE}/lib/PySide2/include/ ${MESHROOM_BUNDLE}/lib/PySide2/Qt/translations/ ${MESHROOM_BUNDLE}/lib/PySide2/Qt/resources/ && \ - rm ${MESHROOM_BUNDLE}/lib/PySide2/libQt5* && \ rm ${MESHROOM_BUNDLE}/lib/PySide2/QtWeb* && \ - rm ${MESHROOM_BUNDLE}/lib/PySide2/libicu* && \ - rm ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-lupdate ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-rcc ${MESHROOM_BUNDLE}/lib/PySide2/shiboken2 + rm ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-lupdate ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-rcc # Install Qt (to build plugins) WORKDIR /tmp/qt +# Qt version in specified in docker/qt-installer-noninteractive.qs RUN curl -LO http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run && \ chmod u+x qt-unified-linux-x64-online.run && \ ./qt-unified-linux-x64-online.run --verbose --platform minimal --script "${MESHROOM_DEV}/docker/qt-installer-noninteractive.qs" && \ rm ./qt-unified-linux-x64-online.run WORKDIR ${MESHROOM_BUILD} -# Temporary workaround for qmlAlembic build -RUN rm -rf "${AV_INSTALL}/lib" && ln -s "${AV_INSTALL}/lib64" "${AV_INSTALL}/lib" # Build Meshroom plugins RUN cmake "${MESHROOM_DEV}" -DALICEVISION_ROOT="${AV_INSTALL}" -DQT_DIR="${QT_DIR}" -DCMAKE_INSTALL_PREFIX="${MESHROOM_BUNDLE}/qtPlugins" +# RUN make -j8 qtOIIO +# RUN make -j8 qmlAlembic +# RUN make -j8 qtAliceVision RUN make -j8 && cd /tmp && rm -rf ${MESHROOM_BUILD} RUN mv "${AV_BUNDLE}" "${MESHROOM_BUNDLE}/aliceVision" diff --git a/Dockerfile_py2 b/Dockerfile_py2 new file mode 100644 index 00000000..4e277848 --- /dev/null +++ b/Dockerfile_py2 @@ -0,0 +1,74 @@ +ARG CUDA_TAG=7.0 +ARG OS_TAG=7 +FROM alicevision/alicevision:2.2.0-centos${OS_TAG}-cuda${CUDA_TAG} +LABEL maintainer="AliceVision Team alicevision-team@googlegroups.com" + +# Execute with nvidia docker (https://github.com/nvidia/nvidia-docker/wiki/Installation-(version-2.0)) +# docker run -it --runtime=nvidia meshroom + +ENV MESHROOM_DEV=/opt/Meshroom \ + MESHROOM_BUILD=/tmp/Meshroom_build \ + MESHROOM_BUNDLE=/opt/Meshroom_bundle \ + QT_DIR=/opt/qt/5.13.0/gcc_64 \ + PATH="${PATH}:${MESHROOM_BUNDLE}" + +# Workaround for qmlAlembic/qtAliceVision builds: fuse lib/lib64 folders +RUN cp -rf ${AV_INSTALL}/lib/* ${AV_INSTALL}/lib64 && rm -rf ${AV_INSTALL}/lib && ln -s ${AV_INSTALL}/lib64 ${AV_INSTALL}/lib + +# Install libs needed by Qt +RUN yum install -y \ + flex \ + fontconfig \ + freetype \ + glib2 \ + libICE \ + libX11 \ + libxcb \ + libXext \ + libXi \ + libXrender \ + libSM \ + libXt-devel \ + libGLU-devel \ + mesa-libOSMesa-devel \ + mesa-libGL-devel \ + mesa-libGLU-devel \ + xcb-util-keysyms \ + xcb-util-image + +# Install Python2 +RUN yum install -y python-devel && curl https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py && python /tmp/get-pip.py && pip install --upgrade pip + +COPY . "${MESHROOM_DEV}" + +WORKDIR "${MESHROOM_DEV}" + +# Install Meshroom requirements and freeze bundle +RUN pip install -r dev_requirements.txt -r requirements.txt && python setup.py install_exe -d "${MESHROOM_BUNDLE}" && \ + find ${MESHROOM_BUNDLE} -name "*Qt5Web*" -delete && \ + find ${MESHROOM_BUNDLE} -name "*Qt5Designer*" -delete && \ + rm -rf ${MESHROOM_BUNDLE}/lib/PySide2/typesystems/ ${MESHROOM_BUNDLE}/lib/PySide2/examples/ ${MESHROOM_BUNDLE}/lib/PySide2/include/ ${MESHROOM_BUNDLE}/lib/PySide2/Qt/translations/ ${MESHROOM_BUNDLE}/lib/PySide2/Qt/resources/ && \ + rm ${MESHROOM_BUNDLE}/lib/PySide2/QtWeb* && \ + rm ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-lupdate ${MESHROOM_BUNDLE}/lib/PySide2/pyside2-rcc + +# Install Qt (to build plugins) +WORKDIR /tmp/qt +# Qt version in specified in docker/qt-installer-noninteractive.qs +RUN curl -LO http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run && \ + chmod u+x qt-unified-linux-x64-online.run && \ + ./qt-unified-linux-x64-online.run --verbose --platform minimal --script "${MESHROOM_DEV}/docker/qt-installer-noninteractive.qs" && \ + rm ./qt-unified-linux-x64-online.run + +WORKDIR ${MESHROOM_BUILD} + +# Build Meshroom plugins +RUN cmake "${MESHROOM_DEV}" -DALICEVISION_ROOT="${AV_INSTALL}" -DQT_DIR="${QT_DIR}" -DCMAKE_INSTALL_PREFIX="${MESHROOM_BUNDLE}/qtPlugins" +# RUN make -j8 qtOIIO +# RUN make -j8 qmlAlembic +# RUN make -j8 qtAliceVision +RUN make -j8 && cd /tmp && rm -rf ${MESHROOM_BUILD} + +RUN mv "${AV_BUNDLE}" "${MESHROOM_BUNDLE}/aliceVision" +RUN rm -rf ${MESHROOM_BUNDLE}/aliceVision/share/doc ${MESHROOM_BUNDLE}/aliceVision/share/eigen3 ${MESHROOM_BUNDLE}/aliceVision/share/fonts ${MESHROOM_BUNDLE}/aliceVision/share/lemon ${MESHROOM_BUNDLE}/aliceVision/share/libraw ${MESHROOM_BUNDLE}/aliceVision/share/man/ aliceVision/share/pkgconfig + + diff --git a/INSTALL.md b/INSTALL.md index 3fd04ada..24756a48 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -36,6 +36,11 @@ pip install -r requirements.txt -r dev_requirements.txt ``` > Note: `dev_requirements` is only related to testing and packaging. It is not mandatory to run Meshroom. +### Qt/PySide +* PySide >= 5.12.2 +Warning: On Windows, the plugin AssimpSceneParser is missing from pre-built binaries, so you need to add it manually (from an older version for instance). +See https://bugreports.qt.io/browse/QTBUG-74535 + ### Qt Plugins Additional Qt plugins can be built to extend Meshroom UI features. They can be found on separate repositories, though they might get better integration in the future. @@ -55,3 +60,11 @@ This plugin also provides a QML Qt3D Entity to load depthmaps files stored in EX QT_PLUGIN_PATH=/path/to/QtOIIO/install QML2_IMPORT_PATH=/path/to/QtOIIO/install/qml ``` + +#### [QtAliceVision](https://github.com/alicevision/QtAliceVision) +Use AliceVision to load and visualize intermediate reconstruction files. +``` +QML2_IMPORT_PATH=/path/to/qtAliceVision/install/qml +``` + + diff --git a/README.md b/README.md index de4225d4..6fc97709 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ![Meshroom - 3D Reconstruction Software](/docs/logo/banner-meshroom.png) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2997/badge)](https://bestpractices.coreinfrastructure.org/projects/2997) + Meshroom is a free, open-source 3D Reconstruction Software based on the [AliceVision](https://github.com/alicevision/AliceVision) Photogrammetric Computer Vision framework. Learn more details about the pipeline on [AliceVision website](http://alicevision.github.io). diff --git a/bin/meshroom_photogrammetry b/bin/meshroom_photogrammetry index ffbd10ee..dae5183b 100755 --- a/bin/meshroom_photogrammetry +++ b/bin/meshroom_photogrammetry @@ -73,13 +73,16 @@ views, intrinsics = [], [] # Build image files list from inputImages arguments images = [f for f in args.inputImages if multiview.isImageFile(f)] -if os.path.isdir(args.input): - # args.input is a folder: extend images list with images in that folder - images += multiview.findImageFiles(args.input) -elif os.path.isfile(args.input) and os.path.splitext(args.input)[-1] in ('.json', '.sfm'): - # args.input is a sfmData file: setup pre-calibrated views and intrinsics - from meshroom.nodes.aliceVision.CameraInit import readSfMData - views, intrinsics = readSfMData(args.input) +if args.input: + if os.path.isdir(args.input): + # args.input is a folder: extend images list with images in that folder + images += multiview.findImageFiles(args.input) + elif os.path.isfile(args.input) and os.path.splitext(args.input)[-1] in ('.json', '.sfm'): + # args.input is a sfmData file: setup pre-calibrated views and intrinsics + from meshroom.nodes.aliceVision.CameraInit import readSfMData + views, intrinsics = readSfMData(args.input) + else: + raise RuntimeError(args.input + ': format not supported.') # initialize photogrammetry pipeline if args.pipeline: @@ -89,6 +92,9 @@ if args.pipeline: # reset graph inputs cameraInit.viewpoints.resetValue() cameraInit.intrinsics.resetValue() + # add views and intrinsics (if any) read from args.input + cameraInit.viewpoints.extend(views) + cameraInit.intrinsics.extend(intrinsics) if not graph.canComputeLeaves: raise RuntimeError("Graph cannot be computed. Check for compatibility issues.") @@ -101,9 +107,10 @@ else: graph = multiview.photogrammetry(inputViewpoints=views, inputIntrinsics=intrinsics, output=args.output) cameraInit = getOnlyNodeOfType(graph, 'CameraInit') -views, intrinsics = cameraInit.nodeDesc.buildIntrinsics(cameraInit, images) -cameraInit.viewpoints.value = views -cameraInit.intrinsics.value = intrinsics +if images: + views, intrinsics = cameraInit.nodeDesc.buildIntrinsics(cameraInit, images) + cameraInit.viewpoints.value = views + cameraInit.intrinsics.value = intrinsics if args.overrides: import io diff --git a/docker/qt-installer-noninteractive.qs b/docker/qt-installer-noninteractive.qs index 18224cd1..32d65cb1 100644 --- a/docker/qt-installer-noninteractive.qs +++ b/docker/qt-installer-noninteractive.qs @@ -46,14 +46,14 @@ Controller.prototype.ComponentSelectionPageCallback = function() { widget.deselectAll(); // widget.selectComponent("qt"); - // widget.selectComponent("qt.qt5.5111"); - widget.selectComponent("qt.qt5.5111.gcc_64"); - // widget.selectComponent("qt.qt5.5111.qtscript"); - // widget.selectComponent("qt.qt5.5111.qtscript.gcc_64"); - // widget.selectComponent("qt.qt5.5111.qtwebengine"); - // widget.selectComponent("qt.qt5.5111.qtwebengine.gcc_64"); - // widget.selectComponent("qt.qt5.5111.qtwebglplugin"); - // widget.selectComponent("qt.qt5.5111.qtwebglplugin.gcc_64"); + // widget.selectComponent("qt.qt5.5130"); + widget.selectComponent("qt.qt5.5130.gcc_64"); + // widget.selectComponent("qt.qt5.5130.qtscript"); + // widget.selectComponent("qt.qt5.5130.qtscript.gcc_64"); + // widget.selectComponent("qt.qt5.5130.qtwebengine"); + // widget.selectComponent("qt.qt5.5130.qtwebengine.gcc_64"); + // widget.selectComponent("qt.qt5.5130.qtwebglplugin"); + // widget.selectComponent("qt.qt5.5130.qtwebglplugin.gcc_64"); // widget.selectComponent("qt.tools"); gui.clickButton(buttons.NextButton); diff --git a/meshroom/__init__.py b/meshroom/__init__.py index 2a2fc4bb..7bda50a1 100644 --- a/meshroom/__init__.py +++ b/meshroom/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2019.1.0" +__version__ = "2019.2.0" __version_name__ = __version__ import os diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index 858820ef..0427b33f 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -1150,9 +1150,15 @@ def submitGraph(graph, submitter, toNodes=None): logging.info("Nodes to process: {}".format(edgesToProcess)) logging.info("Edges to process: {}".format(edgesToProcess)) - sub = meshroom.core.submitters.get(submitter, None) + sub = None + if submitter: + sub = meshroom.core.submitters.get(submitter, None) + elif len(meshroom.core.submitters) == 1: + # if only one submitter available use it + sub = meshroom.core.submitters.values()[0] if sub is None: - raise RuntimeError("Unknown Submitter : " + submitter) + raise RuntimeError("Unknown Submitter: '{submitter}'. Available submitters are: '{allSubmitters}'.".format( + submitter=submitter, allSubmitters=str(meshroom.core.submitters.keys()))) try: res = sub.submit(nodesToProcess, edgesToProcess, graph.filepath) diff --git a/meshroom/multiview.py b/meshroom/multiview.py index a6f8be38..1474b222 100644 --- a/meshroom/multiview.py +++ b/meshroom/multiview.py @@ -1,5 +1,5 @@ # Multiview pipeline version -__version__ = "2.1" +__version__ = "2.2" import os diff --git a/meshroom/nodes/aliceVision/LDRToHDR.py b/meshroom/nodes/aliceVision/LDRToHDR.py index 59529865..ad36c17d 100644 --- a/meshroom/nodes/aliceVision/LDRToHDR.py +++ b/meshroom/nodes/aliceVision/LDRToHDR.py @@ -7,13 +7,27 @@ class LDRToHDR(desc.CommandLineNode): commandLine = 'aliceVision_convertLDRToHDR {allParams}' inputs = [ - desc.File( - name='input', - label='Input', - description="List of LDR images or a folder containing them ", - value='', + desc.ListAttribute( + elementDesc=desc.File( + name='inputFolder', + label='Input File/Folder', + description="Folder containing LDR images", + value='', + uid=[0], + ), + name="input", + label="Input Files or Folders", + description='Folders containing LDR images.', + ), + desc.BoolParam( + name='fisheyeLens', + label='Fisheye Lens', + description="Enable if a fisheye lens has been used.\n " + "This will improve the estimation of the Camera's Response Function by considering only the pixels in the center of the image\n" + "and thus ignore undefined/noisy pixels outside the circle defined by the fisheye lens.", + value=True, uid=[0], - ), + ), desc.ChoiceParam( name='calibrationMethod', label='Calibration Method', @@ -21,62 +35,62 @@ class LDRToHDR(desc.CommandLineNode): " * linear \n" " * robertson \n" " * debevec \n" - " * beta: grossberg", + " * grossberg", values=['linear', 'robertson', 'debevec', 'grossberg'], value='linear', exclusive=True, uid=[0], - ), + ), desc.File( name='inputResponse', label='Input Response', description="external camera response file path to fuse all LDR images together.", value='', uid=[0], - ), + ), desc.StringParam( name='targetExposureImage', label='Target Exposure Image', - description="LDR image at the target exposure for the output HDR image to be centered.", + description="LDR image(s) name(s) at the target exposure for the output HDR image(s) to be centered.", value='', uid=[0], - ), + ), desc.ChoiceParam( name='calibrationWeight', label='Calibration Weight', - description="Weight function type (default, gaussian, triangle, plateau).", + description="Weight function used to calibrate camera response \n" + " * default (automatically selected according to the calibrationMethod) \n" + " * gaussian \n" + " * triangle \n" + " * plateau", value='default', values=['default', 'gaussian', 'triangle', 'plateau'], exclusive=True, uid=[0], - ), + ), desc.ChoiceParam( name='fusionWeight', label='Fusion Weight', - description="Weight function used to fuse all LDR images together (gaussian, triangle, plateau).", + description="Weight function used to fuse all LDR images together \n" + " * gaussian \n" + " * triangle \n" + " * plateau", value='gaussian', values=['gaussian', 'triangle', 'plateau'], exclusive=True, uid=[0], - ), + ), desc.FloatParam( - name='oversaturatedCorrection', - label='Oversaturated Correction', - description="Oversaturated correction for pixels oversaturated in all images: \n" + name='expandDynamicRange', + label='Expand Dynamic Range', + description="Correction of clamped high values in dynamic range: \n" " - use 0 for no correction \n" " - use 0.5 for interior lighting \n" " - use 1 for outdoor lighting", value=1, range=(0, 1, 0.1), uid=[0], - ), - desc.File( - name='recoverPath', - label='Recover Path', - description="Path to write recovered LDR image at the target exposure by applying inverse response on HDR image.", - value='', - uid=[0], - ), + ), desc.ChoiceParam( name='verboseLevel', label='Verbose Level', @@ -85,22 +99,30 @@ class LDRToHDR(desc.CommandLineNode): values=['fatal', 'error', 'warning', 'info', 'debug', 'trace'], exclusive=True, uid=[], - ), + ), + desc.File( + name='recoverPath', + label='Output Recovered Files', + description="(debug) Folder for recovered LDR images at target exposures.", + advanced=True, + value='', + uid=[], + ), ] outputs = [ desc.File( name='output', - label='Output', - description="Output HDR image path.", - value=desc.Node.internalFolder + 'hdr.exr', + label='Output Folder', + description="Output folder for HDR images", + value=desc.Node.internalFolder, uid=[], - ), + ), desc.File( name='outputResponse', label='Output Response', description="Output response function path.", - value=desc.Node.internalFolder + 'response.ods', + value=desc.Node.internalFolder + 'response.csv', uid=[], - ), + ), ] diff --git a/meshroom/ui/qml/Viewer3D/AlembicLoader.qml b/meshroom/ui/qml/Viewer3D/AlembicLoader.qml index dba80961..2b2fd74c 100644 --- a/meshroom/ui/qml/Viewer3D/AlembicLoader.qml +++ b/meshroom/ui/qml/Viewer3D/AlembicLoader.qml @@ -11,6 +11,7 @@ import Qt3D.Extras 2.1 AlembicEntity { id: root + property bool cameraPickingEnabled: true // filter out non-reconstructed cameras skipHidden: true @@ -52,9 +53,13 @@ AlembicEntity { }, ObjectPicker { id: cameraPicker - enabled: root.enabled - onClicked: _reconstruction.selectedViewId = camSelector.viewId - } + onPressed: pick.accepted = cameraPickingEnabled + onReleased: _reconstruction.selectedViewId = camSelector.viewId + }, + // Qt 5.13: binding cameraPicker.enabled to cameraPickerEnabled + // causes rendering issues when entity gets disabled. + // Use a scale to 0 to disable picking. + Transform { scale: cameraPickingEnabled ? 1 : 0 } ] } } diff --git a/meshroom/ui/qml/Viewer3D/MediaLibrary.qml b/meshroom/ui/qml/Viewer3D/MediaLibrary.qml index dd3ec84e..56af1866 100644 --- a/meshroom/ui/qml/Viewer3D/MediaLibrary.qml +++ b/meshroom/ui/qml/Viewer3D/MediaLibrary.qml @@ -275,7 +275,7 @@ Entity { components: [ ObjectPicker { - enabled: parent.enabled && pickingEnabled + enabled: mediaLoader.enabled && pickingEnabled hoverEnabled: false onPressed: root.pressed(pick) } diff --git a/meshroom/ui/qml/Viewer3D/MediaLoader.qml b/meshroom/ui/qml/Viewer3D/MediaLoader.qml index 9cf51ddd..936197a0 100644 --- a/meshroom/ui/qml/Viewer3D/MediaLoader.qml +++ b/meshroom/ui/qml/Viewer3D/MediaLoader.qml @@ -80,14 +80,13 @@ import Utils 1.0 id: abcLoaderEntityComponent MediaLoaderEntity { id: abcLoaderEntity - enabled: root.enabled Component.onCompleted: { var obj = Viewer3DSettings.abcLoaderComp.createObject(abcLoaderEntity, { 'source': source, 'pointSize': Qt.binding(function() { return 0.01 * Viewer3DSettings.pointSize }), 'locatorScale': Qt.binding(function() { return Viewer3DSettings.cameraScale }), - 'enabled': Qt.binding(function() { return root.enabled }) + 'cameraPickingEnabled': Qt.binding(function() { return root.enabled }) }); obj.statusChanged.connect(function() { diff --git a/requirements.txt b/requirements.txt index 7ad4de12..7daba766 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # runtime psutil>=5.6.3 enum34;python_version<"3.4" -PySide2==5.11.1 +PySide2==5.13.0 markdown==2.6.11 diff --git a/setup.py b/setup.py index 3a132728..4bbe3df2 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ class PlatformExecutable(Executable): build_exe_options = { # include dynamically loaded plugins "packages": ["meshroom.nodes", "meshroom.submitters"], - "include_files": ['COPYING.md'] + "include_files": ["CHANGES.md", "COPYING.md", "LICENSE-MPL2.md", "README.md"] } if platform.system() == PlatformExecutable.Linux: