Full Code of alicevision/Meshroom for AI

develop 796e610a8654 cached
343 files
2.4 MB
637.2k tokens
2151 symbols
1 requests
Download .txt
Showing preview only (2,543K chars total). Download the full file or copy to clipboard to get everything.
Repository: alicevision/Meshroom
Branch: develop
Commit: 796e610a8654
Files: 343
Total size: 2.4 MB

Directory structure:
gitextract_yg7v1w9_/

├── .codecov.yml
├── .git-blame-ignore-revs
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── question_help.md
│   ├── pull_request_template.md
│   ├── stale.yml
│   └── workflows/
│       └── continuous-integration.yml
├── .gitignore
├── .readthedocs.yaml
├── CHANGES.md
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── COPYING.md
├── INSTALL.md
├── INSTALL_PLUGINS.md
├── LICENSE-MPL2.md
├── NODE_DEVELOPMENT.md
├── README.md
├── RELEASING.md
├── WINDOWS_EXE.md
├── bin/
│   ├── meshroom_batch
│   ├── meshroom_compute
│   ├── meshroom_createChunks
│   ├── meshroom_newNodeType
│   ├── meshroom_statistics
│   ├── meshroom_status
│   └── meshroom_submit
├── dev_requirements.txt
├── docker/
│   ├── Dockerfile_rocky
│   ├── Dockerfile_rocky_deps
│   ├── Dockerfile_ubuntu
│   ├── Dockerfile_ubuntu_deps
│   ├── build-all.sh
│   ├── build-rocky.sh
│   ├── build-ubuntu.sh
│   ├── extract-rocky.sh
│   └── extract-ubuntu.sh
├── docs/
│   ├── .gitignore
│   ├── Makefile
│   ├── README.md
│   ├── make.bat
│   ├── requirements.txt
│   └── source/
│       ├── _ext/
│       │   ├── __init__.py
│       │   ├── fetch_md.py
│       │   ├── meshroom_doc.py
│       │   └── utils.py
│       ├── _templates/
│       │   └── autosummary/
│       │       ├── class.rst
│       │       └── module.rst
│       ├── api.rst
│       ├── changes.rst
│       ├── conf.py
│       ├── index.rst
│       └── install.rst
├── localfarm/
│   ├── __init__.py
│   ├── localFarm.py
│   ├── localFarmBackend.py
│   ├── localFarmLauncher.py
│   └── test.py
├── meshroom/
│   ├── __init__.py
│   ├── common/
│   │   ├── PySignal.py
│   │   ├── __init__.py
│   │   ├── core.py
│   │   ├── deprecated.py
│   │   └── qt.py
│   ├── core/
│   │   ├── __init__.py
│   │   ├── attribute.py
│   │   ├── cgroup.py
│   │   ├── desc/
│   │   │   ├── __init__.py
│   │   │   ├── attribute.py
│   │   │   ├── computation.py
│   │   │   ├── geometryAttribute.py
│   │   │   ├── node.py
│   │   │   └── shapeAttribute.py
│   │   ├── evaluation.py
│   │   ├── exception.py
│   │   ├── fileUtils.py
│   │   ├── graph.py
│   │   ├── graphIO.py
│   │   ├── keyValues.py
│   │   ├── mtyping.py
│   │   ├── node.py
│   │   ├── nodeFactory.py
│   │   ├── plugins.py
│   │   ├── stats.py
│   │   ├── submitter.py
│   │   ├── taskManager.py
│   │   ├── test.py
│   │   └── utils.py
│   ├── env.py
│   ├── multiview.py
│   ├── nodes/
│   │   ├── __init__.py
│   │   └── general/
│   │       ├── Backdrop.py
│   │       ├── CopyFiles.py
│   │       ├── InputFile.py
│   │       └── __init__.py
│   ├── submitters/
│   │   ├── __init__.py
│   │   └── localFarmSubmitter.py
│   └── ui/
│       ├── __init__.py
│       ├── __main__.py
│       ├── app.py
│       ├── commands.py
│       ├── components/
│       │   ├── __init__.py
│       │   ├── clipboard.py
│       │   ├── csvData.py
│       │   ├── edge.py
│       │   ├── filepath.py
│       │   ├── geom2D.py
│       │   ├── logLinesModel.py
│       │   ├── messaging.py
│       │   ├── scene3D.py
│       │   ├── scriptEditor.py
│       │   ├── shapes/
│       │   │   ├── __init__.py
│       │   │   ├── shapeFile.py
│       │   │   ├── shapeFilesHelper.py
│       │   │   └── shapeViewerHelper.py
│       │   └── thumbnail.py
│       ├── graph.py
│       ├── palette.py
│       ├── qml/
│       │   ├── AboutDialog.qml
│       │   ├── Application.qml
│       │   ├── Charts/
│       │   │   ├── ChartViewCheckBox.qml
│       │   │   ├── ChartViewLegend.qml
│       │   │   ├── InteractiveChartView.qml
│       │   │   └── qmldir
│       │   ├── Controls/
│       │   │   ├── ColorChart.qml
│       │   │   ├── ColorSelector.qml
│       │   │   ├── DelegateSelectionBox.qml
│       │   │   ├── DelegateSelectionLine.qml
│       │   │   ├── DirectionalLightPane.qml
│       │   │   ├── ExifOrientedViewer.qml
│       │   │   ├── ExpandableGroup.qml
│       │   │   ├── FilterComboBox.qml
│       │   │   ├── FloatingPane.qml
│       │   │   ├── Group.qml
│       │   │   ├── IntSelector.qml
│       │   │   ├── KeyValue.qml
│       │   │   ├── MScrollBar.qml
│       │   │   ├── MSplitView.qml
│       │   │   ├── MessageDialog.qml
│       │   │   ├── NodeActions.qml
│       │   │   ├── Panel.qml
│       │   │   ├── SearchBar.qml
│       │   │   ├── SelectionBox.qml
│       │   │   ├── SelectionLine.qml
│       │   │   ├── StatusBar.qml
│       │   │   ├── StatusMessages.qml
│       │   │   ├── TabPanel.qml
│       │   │   ├── TextFileViewer.qml
│       │   │   └── qmldir
│       │   ├── DialogsFactory.qml
│       │   ├── GraphEditor/
│       │   │   ├── AttributeControls/
│       │   │   │   ├── Choice.qml
│       │   │   │   └── ChoiceMulti.qml
│       │   │   ├── AttributeEditor.qml
│       │   │   ├── AttributeItemDelegate.qml
│       │   │   ├── AttributePin.qml
│       │   │   ├── Backdrop.qml
│       │   │   ├── ChunksListView.qml
│       │   │   ├── CompatibilityBadge.qml
│       │   │   ├── CompatibilityManager.qml
│       │   │   ├── Edge.qml
│       │   │   ├── GraphEditor.qml
│       │   │   ├── GraphEditorSettings.qml
│       │   │   ├── Node.qml
│       │   │   ├── NodeChunks.qml
│       │   │   ├── NodeDocumentation.qml
│       │   │   ├── NodeEditor.qml
│       │   │   ├── NodeFileBrowser.qml
│       │   │   ├── NodeLog.qml
│       │   │   ├── NodeStatistics.qml
│       │   │   ├── NodeStatus.qml
│       │   │   ├── ScriptEditor.qml
│       │   │   ├── StatViewer.qml
│       │   │   ├── TaskManager.qml
│       │   │   └── qmldir
│       │   ├── Homepage.qml
│       │   ├── ImageGallery/
│       │   │   ├── ImageBadge.qml
│       │   │   ├── ImageDelegate.qml
│       │   │   ├── ImageGallery.qml
│       │   │   ├── ImageGridView.qml
│       │   │   ├── ImageListView.qml
│       │   │   ├── IntrinsicDisplayDelegate.qml
│       │   │   ├── IntrinsicsIndicator.qml
│       │   │   ├── SensorDBDialog.qml
│       │   │   └── qmldir
│       │   ├── MaterialIcons/
│       │   │   ├── MLabel.qml
│       │   │   ├── MaterialIcons.qml
│       │   │   ├── MaterialLabel.qml
│       │   │   ├── MaterialToolButton.qml
│       │   │   ├── MaterialToolLabel.qml
│       │   │   ├── MaterialToolLabelButton.qml
│       │   │   ├── generate_material_icons.py
│       │   │   └── qmldir
│       │   ├── Shapes/
│       │   │   ├── Editor/
│       │   │   │   ├── Items/
│       │   │   │   │   ├── ShapeAttributeItem.qml
│       │   │   │   │   ├── ShapeDataItem.qml
│       │   │   │   │   ├── ShapeFileItem.qml
│       │   │   │   │   ├── ShapeListAttributeItem.qml
│       │   │   │   │   └── Utils/
│       │   │   │   │       └── ItemHeader.qml
│       │   │   │   ├── ShapeEditor.qml
│       │   │   │   └── ShapeEditorItem.qml
│       │   │   ├── Viewer/
│       │   │   │   ├── Layers/
│       │   │   │   │   ├── BaseLayer.qml
│       │   │   │   │   ├── CircleLayer.qml
│       │   │   │   │   ├── LineLayer.qml
│       │   │   │   │   ├── PointLayer.qml
│       │   │   │   │   ├── RectangleLayer.qml
│       │   │   │   │   ├── TextLayer.qml
│       │   │   │   │   └── Utils/
│       │   │   │   │       └── Handle.qml
│       │   │   │   ├── ShapeViewer.qml
│       │   │   │   ├── ShapeViewerAttributeLayer.qml
│       │   │   │   ├── ShapeViewerAttributeLoader.qml
│       │   │   │   └── ShapeViewerLayer.qml
│       │   │   └── qmldir
│       │   ├── Utils/
│       │   │   ├── Clipboard.qml
│       │   │   ├── Colors.qml
│       │   │   ├── ExifOrientation.qml
│       │   │   ├── ExpressionTextField.qml
│       │   │   ├── Filepath.qml
│       │   │   ├── Scene3DHelper.qml
│       │   │   ├── SortFilterDelegateModel.qml
│       │   │   ├── Transformations3DHelper.qml
│       │   │   ├── errorHandler.js
│       │   │   ├── format.js
│       │   │   ├── qmldir
│       │   │   └── request.js
│       │   ├── Viewer/
│       │   │   ├── CameraResponseGraph.qml
│       │   │   ├── CircleGizmo.qml
│       │   │   ├── ColorCheckerEntity.qml
│       │   │   ├── ColorCheckerPane.qml
│       │   │   ├── ColorCheckerViewer.qml
│       │   │   ├── FeaturesInfoOverlay.qml
│       │   │   ├── FeaturesViewer.qml
│       │   │   ├── FloatImage.qml
│       │   │   ├── HdrImageToolbar.qml
│       │   │   ├── ImageMetadataView.qml
│       │   │   ├── LensDistortionToolbar.qml
│       │   │   ├── MFeatures.qml
│       │   │   ├── MSfMData.qml
│       │   │   ├── MTracks.qml
│       │   │   ├── PanoramaToolbar.qml
│       │   │   ├── PanoramaViewer.qml
│       │   │   ├── PhongImageViewer.qml
│       │   │   ├── PhongImageViewerToolbar.qml
│       │   │   ├── SequencePlayer.qml
│       │   │   ├── SfmGlobalStats.qml
│       │   │   ├── SfmStatsView.qml
│       │   │   ├── TestAliceVisionPlugin.qml
│       │   │   ├── TextViewer.qml
│       │   │   ├── Viewer2D.qml
│       │   │   └── qmldir
│       │   ├── Viewer3D/
│       │   │   ├── BoundingBox.qml
│       │   │   ├── DefaultCameraController.qml
│       │   │   ├── DepthMapLoader.qml
│       │   │   ├── EntityWithGizmo.qml
│       │   │   ├── EnvironmentMapEntity.qml
│       │   │   ├── Grid3D.qml
│       │   │   ├── ImageOverlay.qml
│       │   │   ├── Inspector3D.qml
│       │   │   ├── Locator3D.qml
│       │   │   ├── MaterialSwitcher.qml
│       │   │   ├── Materials/
│       │   │   │   ├── SphericalHarmonicsEffect.qml
│       │   │   │   ├── SphericalHarmonicsMaterial.qml
│       │   │   │   ├── WireframeEffect.qml
│       │   │   │   ├── WireframeMaterial.qml
│       │   │   │   └── shaders/
│       │   │   │       ├── SphericalHarmonics.frag
│       │   │   │       ├── SphericalHarmonics.vert
│       │   │   │       ├── robustwireframe.frag
│       │   │   │       └── robustwireframe.vert
│       │   │   ├── MediaCache.qml
│       │   │   ├── MediaLibrary.qml
│       │   │   ├── MediaLoader.qml
│       │   │   ├── MediaLoaderEntity.qml
│       │   │   ├── MeshingBoundingBox.qml
│       │   │   ├── SfMTransformGizmo.qml
│       │   │   ├── SfmDataLoader.qml
│       │   │   ├── TrackballGizmo.qml
│       │   │   ├── TransformGizmo.qml
│       │   │   ├── TransformGizmoPicker.qml
│       │   │   ├── Viewer3D.qml
│       │   │   ├── Viewer3DSettings.qml
│       │   │   ├── ViewpointCamera.qml
│       │   │   └── qmldir
│       │   ├── WorkspaceView.qml
│       │   └── main.qml
│       ├── scene.py
│       └── utils.py
├── requirements.txt
├── setup.py
├── setupInitScriptUnix.py
├── setupInitScriptWindows.py
├── start.bat
├── start.sh
└── tests/
    ├── __init__.py
    ├── appendTextAndFiles.mg
    ├── conftest.py
    ├── nodes/
    │   ├── __init__.py
    │   └── test/
    │       ├── Color.py
    │       ├── GroupAttributes.py
    │       ├── InputDynamicOutputs.py
    │       ├── NestedTest.py
    │       ├── Position.py
    │       ├── __init__.py
    │       ├── appendFiles.py
    │       ├── appendText.py
    │       └── ls.py
    ├── plugins/
    │   └── meshroom/
    │       ├── pluginA/
    │       │   ├── PluginAInputInitNode.py
    │       │   ├── PluginAInputNode.py
    │       │   ├── PluginANodeA.py
    │       │   ├── PluginANodeB.py
    │       │   └── __init__.py
    │       ├── pluginB/
    │       │   ├── PluginBNodeA.py
    │       │   ├── PluginBNodeB.py
    │       │   └── __init__.py
    │       ├── pluginC/
    │       │   ├── PluginCNodeA.py
    │       │   └── __init__.py
    │       ├── pluginSubmitter/
    │       │   ├── PluginSubmitter.py
    │       │   └── __init__.py
    │       └── sharedTemplate.mg
    ├── test_attributeChoiceParam.py
    ├── test_attributeDescDefaults.py
    ├── test_attributeKeyValues.py
    ├── test_attributeLambda.py
    ├── test_attributeShape.py
    ├── test_attributes.py
    ├── test_compatibility.py
    ├── test_compute.py
    ├── test_graph.py
    ├── test_graphIO.py
    ├── test_groupAttributes.py
    ├── test_invalidation.py
    ├── test_listAttribute.py
    ├── test_model.py
    ├── test_nodeAttributeChangedCallback.py
    ├── test_nodeAttributesFormatting.py
    ├── test_nodeCallbacks.py
    ├── test_nodeCommandLineFormatting.py
    ├── test_nodeDynamicOutputs.py
    ├── test_nodes.py
    ├── test_pipeline.py
    ├── test_plugins.py
    ├── test_submit.py
    └── utils.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .codecov.yml
================================================
# Codecov configuration for Meshroom
# This configuration prevents CI from failing due to small coverage decreases
# while maintaining quality standards

codecov:
  # Require CI to pass before processing results
  require_ci_to_pass: yes

coverage:
  status:
    project:
      default:
        # Allow coverage to drop by up to 1% without failing
        threshold: 1%
        # Set a minimum target coverage (adjust based on your current ~77%)
        target: 75%
        # Only check coverage on lines that are coverable
        base: auto
        # Ignore if no coverage files are uploaded
        if_no_uploads: error
        # Don't fail if coverage file not found
        if_not_found: success
        # Fail if CI failed
        if_ci_failed: error
        # Only run on these branches
        branches:
          - develop
          - master
          - main

    patch:
      default:
        # For new code, allow 2% threshold since new features may need refactoring
        threshold: 2%
        # New code should aim for 70% coverage (lower than overall project)
        target: 70%
        # Only run patch coverage on pull requests
        only_pulls: true
        if_no_uploads: error
        if_not_found: success
        if_ci_failed: error

  precision: 2
  round: down
  range: "70...95"

# Ignore certain files/directories that should not affect coverage
ignore:
  - "setup.py"
  - "docs/"
  - "scripts/"
  - "bin/"
  - "localfarm/"  # For now ignore localfarm as it has no coverage yet
  - "meshroom/submitters/"


================================================
FILE: .git-blame-ignore-revs
================================================
# Linting: Harmonize docstrings and comments
039e0620ad05d673a2ef9aa501e9a509219671c9
# Linting: Remove all trailing whitespaces
2c2b067f072856f2579c644b5f7858da0275be3c
# [core] attribute: Apply linting
b8c173ddd490dc3bf28b193697d675e44616c6f5
# Linting: Remove trailing whitespaces
04a425decc1b80f0c67e8c4c98c0062d73836684
# [core] Linting: Remove all trailing whitespaces
8be302115edca60c93b1e97de3f457d91c271666
# [tests] Linting: Remove trailing whitespaces
5fe886b6b08fa19082dc0e1bf837fa34c2e2de2d
# [core] Linting: Remove remaining trailing whitespaces
a44537b65a7c53c89c16e71ae207f37fa6554832
# Linting: Fix E203, E225, E231, E261, E302, E303 and W292 warnings
1b5664c8cc54c55fae58a5be9bf63e9af2f5af95
# [ui] Linting: Remove all trailing whitespaces
18d7f609b1a5cd7c43f970770374b649019c1e73
# [core] Linting: Fix import order
aae05532b2409e3bd4c119646afc08656a916cb4
# [core] Linting: Remove all trailing whitespaces
81394d7def1fcbc08cbc2a8721bc1f0a86fe8cc6
# [desc] Linting: Remove trailing whitespaces
0a2ab8cab4f79191b0e7364416701ba561e75b6a
# [desc] Linting: Fix order of the imported modules
adf67e33533a75f5b280e0ee3fc0ece82307199e
# [build] `setup.py`: Use double quotes everywhere
571de38ef1a9e72e6c1d2a997b60de5bd3caa5bf
# [bin] `meshroom_batch`: Minor clean-up in the file
15d9ecd888faa7216cfc5d97d473f5717a3118a3
# [core] Linting following CI's flake8 report
9b4bd68d5aa9e5c3af5e4bfc4fe6aae06437ca88
# [tests] Linting following CI's flake8 report
9b6549cc1dd525658080303f7ad453bd4ec10f52
# [GraphEditor] Indentation fix
87c0cef605e4ef2b359d7e678155e79b65b2e762
# [qt6][qml] Clean-up code and harmonize comments
5a0b1c0c9547b0d00f3f10fae6994d6d8ea0b45e
# [nodes] Linting: Clean-up files
4c0409f573c2694325b104c2686a1532f95cb9bc
# Linting: Clean-up files
41e885d9ff38cd55772722376d5ef80ff908c559
# [Viewer] SequencePlayer: Clean-up: Harmonize syntax
42157809b90f5f6b275aa8ff9d7310c384ea395a
# [Viewer] Clean-up: Harmonize syntax for the Viewer2D
9af65092b9e881c828430f54a73fb4522bc1e370
# [nodes] Harmonize the use of trailing commas across all the nodes
61a8dcd4e2878f80b2f320f2b1c3c9b41e999b82
# [nodes] Clean-up: Harmonize nodes' descriptions
f2d67706511954aa3e1c026ecc858beb8c08f938
# [qml] Clean-up: Harmonize syntax across all files
e463f0dce2455f47d5b066f9e9434ed94b2b282f
# [GraphEditor] Clean-up: Harmonize syntax across all files
e9d80611c7fe185623e5f276a41b7f2de23cb6fe
# [ImageGallery] Clean-up: Harmonize syntax across all files
2bdf061d2e49f3e1513a59922dc33e69f68552cf
# [Controls] Clean-up: Harmonize syntax across all files
2908aa94a3eda2de71f8c5e6cec8cd78280bbb09
# [Charts] Clean-up: Harmonize syntax across all files
856641bc9dc25271062dc94a66da4c08e00f88d1
# [Utils] Clean-up: Harmonize syntax across all files
8313e42d8c70e2494277e338ef8fd38824270231
# [Viewer] Clean-up: Harmonize syntax across all files
13b8266d14783a4c595c8b731c54fc9c61adfa92
# [Viewer3D] Clean-up: Harmonize syntax across all files
9d2974d2823fe5d6f400eb4658f67d0306b11ac8


================================================
FILE: .github/FUNDING.yml
================================================
github: [alicevision]
custom: ['https://alicevision.org/association/#donate']


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
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, ]
 - Python version [e.g. 2.6]
 - Qt/PySide version [e.g. 6.8.2]
 - Meshroom version: please specify if you are using a release version or your own build
   - Binary version (if applicable) [e.g. 2023.3.0]
   - Commit reference (if applicable) [e.g. 08ddbe2]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
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 am always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you have considered**
A clear and concise description of any alternative solutions or features you have considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/question_help.md
================================================
---
name: Question or help needed
about: Ask question or for help for issues not related to program failures (e.g. "where I can find this feature", "my dataset is not reconstructed properly", "which parameter setting shall I use" etc...)
title: "[question]"
labels: type:question
assignees: ''

---

**Describe the problem**
A clear and concise description of what the problem is.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Dataset**
If applicable, add a link or *few* images to help better understand where the problem may come from.

**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, ]
 - Python version [e.g. 2.6]
 - Qt/PySide version [e.g. 6.8.2]
 - Meshroom version: please specify if you are using a release version or your own build
   - Binary version (if applicable) [e.g. 2023.3.0]
   - Commit reference (if applicable) [e.g. 08ddbe2]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/pull_request_template.md
================================================
<!-- Checklist before submission:

 - I have read the [contribution guidelines](../CONTRIBUTING.md).
 - I have updated the documentation, if applicable.
 - I have ensured that the change is tested somewhere.
 - I have followed the prevailing code style (for history readability and limit conflicts for maintenance).

-->
## Description



## Features list

<!--
- [ ] Feature one. Fix #XXX
- [ ] Improve something else
- [ ] Connect to #3 (to declare link to issues without closing it when the PR is merged).
- [X] Add "X" when it is done.
-->


## Implementation remarks


<!--
Explain main implementation choices.
It is also the right place to ask for feedback and help when you hesitate on the implementation.
-->


================================================
FILE: .github/stale.yml
================================================
# 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:
  - "do not close"
  - "feature request"
  - "scope:doc"
  - "new feature"
  - "bug"
# 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.


================================================
FILE: .github/workflows/continuous-integration.yml
================================================
name: Continuous Integration

on:
  push:
    branches:
      - master
      - develop
    # Skip jobs when only documentation files are changed
    paths-ignore:
      - '**.md'
      - '**.rst'
      - 'docs/**'
  pull_request:
    paths-ignore:
      - '**.md'
      - '**.rst'
      - 'docs/**'

env:
  CI: True
  PYTHONPATH: ${{ github.workspace }}

jobs:
  build-linux:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [ 3.11 ]

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install flake8 pytest pytest-cov
        pip install -r requirements.txt -r dev_requirements.txt --timeout 45
    - name: Lint with flake8
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      run: |
        pytest tests/
        pytest --cov --cov-report=xml --junitxml=junit.xml
    - name: Upload results to Codecov
      uses: codecov/codecov-action@v5
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
    - name: Upload test results to Codecov
      if: ${{ !cancelled() }}
      uses: codecov/test-results-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
    - name: Set up Python 3.9 - meshroom_compute test
      uses: actions/setup-python@v4
      with:
        python-version: 3.9
    - name: Install dependencies (Python 3.9) - meshroom_compute test
      run: |
        python3.9 -m pip install --upgrade pip
        python3.9 -m pip install -r requirements.txt --timeout 45
    - name: Run imports - meshroom_compute test
      run: |
        python3.9 bin/meshroom_compute -h

  build-windows:
    runs-on: windows-latest
    strategy:
      matrix:
        python-version: [ 3.11 ]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          pip install -r requirements.txt -r dev_requirements.txt --timeout 45
      - name: Lint with flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
      - name: Test with pytest
        run: |
          pytest tests/
      - name: Set up Python 3.9 - meshroom_compute test
        uses: actions/setup-python@v4
        with:
          python-version: 3.9
      - name: Install dependencies (Python 3.9) - meshroom_compute test
        run: |
          python3 -m pip install --upgrade pip
          python3 -m pip install -r requirements.txt --timeout 45
      - name: Run imports - meshroom_compute test
        run: |
          python3 bin/meshroom_compute -h


================================================
FILE: .gitignore
================================================
# temporary files
*~
# vim
.*.swp
# emacs
*.flc
\#*\#
.\#*
# xemacs
# MacOS
.DS_Store
# Windows
Thumbs.db
# vscode
.vscode

# python
*.pyc
*.pyo
__pycache__

# backup files
*.json
!*Config.json

# datas or personal files
/data
/scripts
/build
/dist
/dl

# virtual environment
/venv

# tests
/.tests
/.pytest_cache

# IDEs folders
*.qmlproject*
/nbproject
.idea
.cache
.nfs*

*.qmlc
*.jsc

# QtCreator project files
*.cflags
*.cxxflags
*.creator*
*.files
*.includes

*.dll

*.lib

install/qml/AliceVision/qmldir

run.bat


================================================
FILE: .readthedocs.yaml
================================================
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Build HTML documentation with Sphinx
sphinx:
  builder: html
  configuration: docs/source/conf.py

# Python requirements
python:
  install:
    - requirements: requirements.txt
    - requirements: dev_requirements.txt
    - requirements: docs/requirements.txt


================================================
FILE: CHANGES.md
================================================
# Meshroom Changelog

For algorithmic changes related to the photogrammetric pipeline, 
please refer to [AliceVision changelog](https://github.com/alicevision/AliceVision/blob/develop/CHANGES.md).

## Meshroom 2025.1.0 (2025/08/18)

Meshroom has now become a node-based visual programming toolbox for creating, managing, and executing complex data processing pipelines, with a new plugin architecture.
Standard computer vision pipelines such as photogrammetry, camera tracking, HDR panorama, Lidar Meshing, Raw image files conversion and color calibration are now unified within the AliceVision plugin, featuring numerous improvements and optimizations.
Additionally, new AI-powered capabilities include a semantic segmentation plugin and a collection of open-source extensions available via the new MeshroomHub: https://github.com/meshroomHub. This platform enables Gaussian Splatting, monocular depth estimation, and other exploratory features, welcoming developer contributions to expand and enhance these capabilities for upcoming releases.

### Highlights

#### Meshroom New Features

- **Advanced Plugin Architecture**: Dedicated sub-process isolation for Python nodes with independent local environments
- **Integrated Development Tools**:
  - Built-in Python script editor
  - Node’s source code hot-reload for rapid node development iterations
- **Enhanced GraphEditor**:
  - Dynamic output attributes enabling new workflow usages
  - New InputNode type enabling interactive evaluation without explicit computation
  - Multiple edge disconnection methods and node colorization for better user experience
  - Node notifications to attribute changes
- **Enhanced 2D Viewer**:
  - Initial timeline integration with sequence playback controls
  - New Reflectance Transformation Imaging (RTI) Viewer: Interactive visualization of albedo and normal maps with real-time lighting control
  - New Home Page: featuring pipeline templates and quick access to recent projects.

#### AliceVision Plugin New Features

- New Pipelines
  - **Color Calibration**: Automated color correction from color charts
  - **Raw to EXR conversion**: Professional image format processing
  - **Object Reconstruction**: Targeted reconstruction with automatic object segmentation
  - **Turntable Object Reconstruction**: Streamlined workflow for rotating object capture
  - **360° Object Reconstruction**: Reconstruction of complete dual-sided scanning
  - **LiDAR Processing**: Native E57 file import with integrated mesh generation
  - **Multi-View Photometric Stereo**: Advanced surface detail reconstruction with multiple light sources for each viewpoint.
- Pipelines Improvements
  - **Camera Tracking pipeline**: improved stability and reliability
  - **Introduced experimental fine-grained pipelines** for increased modularity and workflow flexibility
- Core Enhancements
  - **Python Bindings Integration**: Enhanced AliceVision accessibility with native Python support for streamlined Machine Learning workflows

#### New MrSegmentation Plugin

AI segmentation nodes that identify and isolate image objects using natural language prompts, enabling intuitive content-aware processing through foundation models.

#### MeshroomHub Plugins

We're excited to introduce new experimental Machine Learning plugins available on [MeshroomHub](https://github.com/meshroomHub).
These plugins showcase the future of Meshroom workflows, though they currently require developer setup and cannot be installed through the user interface yet.
- mrGSplat: Gaussian Splat optimization and rendering
- mrDepthEstimation: Monocular depth inference
- mrDenseMotion: Optical flow estimation
- mrRoma: Dense deep feature matching
- mrIntrinsicImageDecomposition: Albedo, normals, and material extraction
- mrDeblurring: Video deblurring
- mrGeolocation: GPS extraction and geographic models download

Based on [AliceVision 3.3.0](https://github.com/alicevision/AliceVision/tree/v3.3.0).

### Major Features

- Add an "E57" importer node [PR](https://github.com/alicevision/Meshroom/pull/2308)
- First node for Lidar Meshing [PR](https://github.com/alicevision/Meshroom/pull/2324)
- New InputNode for nodes without computation and support for all param types in output (and no more limited to File type) [PR](https://github.com/alicevision/Meshroom/pull/2364)
- [core] New dynamic output attributes [PR](https://github.com/alicevision/Meshroom/pull/2432)
- First Homepage [PR](https://github.com/alicevision/Meshroom/pull/2452)
- Qt6.6.3 / PySide6.6.3.1 upgrade [PR](https://github.com/alicevision/Meshroom/pull/2599)
- New MultiView Photometric Stereo pipeline and new sfmFilter node [PR](https://github.com/alicevision/Meshroom/pull/2582)
- [ui] Python Script Editor Improvements [PR](https://github.com/alicevision/Meshroom/pull/2587)
- New local isolated computation for python nodes [PR](https://github.com/alicevision/Meshroom/pull/2703)
- New Plugin Architecture for Node Registration [PR](https://github.com/alicevision/Meshroom/pull/2733)
- [ui]: Introduction of multiple ways to remove Node Edges [PR](https://github.com/alicevision/Meshroom/pull/2644)
- [core] Runtime-specific environments support [PR](https://github.com/alicevision/Meshroom/pull/2747)
- [Photometric Stereo] MultiView fusion in Texturing [PR](https://github.com/alicevision/Meshroom/pull/2243)
- Add a Python ScriptEditor in the GraphEditor tab [PR](https://github.com/alicevision/Meshroom/pull/2456)

### Features

- Custom loader for .pc.ply point clouds [PR](https://github.com/alicevision/Meshroom/pull/2346)
- Lidar nodes [PR](https://github.com/alicevision/Meshroom/pull/2365)
- [ui] Viewer2D: Display lighting circle with auto detected sphere [PR](https://github.com/alicevision/Meshroom/pull/2413)
- [ui] RGBA shortcuts for Image Viewer [PR](https://github.com/alicevision/Meshroom/pull/2425)
- [ui] Shortcuts in Viewer2D and SequencePlayer [PR](https://github.com/alicevision/Meshroom/pull/2430)
- [ui] node time computation and chunks count in node editor header [PR](https://github.com/alicevision/Meshroom/pull/1867)
- [core/ui] Load image sequence from node's output in SequencePlayer [PR](https://github.com/alicevision/Meshroom/pull/2375)
- [core] Forward the onAttributeChanged notification to all linked attributes [PR](https://github.com/alicevision/Meshroom/pull/2453)
- add 3de undistortion models [PR](https://github.com/alicevision/Meshroom/pull/2446)
- [GraphEditor] Base `ChoiceParam` model on attribute instead of description [PR](https://github.com/alicevision/Meshroom/pull/2494)
- [core] Reference the attribute's instance type in its description [PR](https://github.com/alicevision/Meshroom/pull/2493)
- [ui] Improve command line help message [PR](https://github.com/alicevision/Meshroom/pull/2518)
- Added Pre and Post process functions on the Base Node [PR](https://github.com/alicevision/Meshroom/pull/2539)
- [ui] Add and improve multiple UI tools for Photometric stereo [PR](https://github.com/alicevision/Meshroom/pull/2444)
- Refactor Node selection for better UX and performance [PR](https://github.com/alicevision/Meshroom/pull/2605)
- New SfMColorizing Node [PR](https://github.com/alicevision/Meshroom/pull/2610)
- Update sfm pipeline to accept meshes [PR](https://github.com/alicevision/Meshroom/pull/2642)
- Enable Fitting of selected Nodes in the Graph Editor when Fit is invoked  [PR](https://github.com/alicevision/Meshroom/pull/2652)
- Add relative paths to nodes as variables [PR](https://github.com/alicevision/Meshroom/pull/2629)
- Node to inject survey points in the SFM [PR](https://github.com/alicevision/Meshroom/pull/2696)
- [ui] AttributeEditor: Feature/attribute navigation buttons [PR](https://github.com/alicevision/Meshroom/pull/2716)
- [ui] Homepage: Project can be removed with right click [PR](https://github.com/alicevision/Meshroom/pull/2724)
- [ui] Viewer2D: Add the pixel (x,y) values in the toolbar (editable) [PR](https://github.com/alicevision/Meshroom/pull/2723)
- [ui] AttributeEditor: Allow displaying attibute in corresponding viewport  [PR](https://github.com/alicevision/Meshroom/pull/2722)
- Update to Qt/PySide 6.8.3 [PR](https://github.com/alicevision/Meshroom/pull/2692)
- Add a "ConvertDistortion" node [PR](https://github.com/alicevision/Meshroom/pull/2353)
- [ui] Sync SequencePlayer and Viewer3D [PR](https://github.com/alicevision/Meshroom/pull/2360)
- Viewer3D: Adjust bounding-box by moving faces [PR](https://github.com/alicevision/Meshroom/pull/2385)
- [core/ui] Add support for PushButton attribute [PR](https://github.com/alicevision/Meshroom/pull/2382)
- First version of For Loop implementation [PR](https://github.com/alicevision/Meshroom/pull/2504)
- Generate depthmaps from sfmData and mesh [PR](https://github.com/alicevision/Meshroom/pull/2556)
- [ui] Use the improved Sequence Player and enable it by default [PR](https://github.com/alicevision/Meshroom/pull/2557)
- [AttributePin] Add tooltip to display type of attribute [PR](https://github.com/alicevision/Meshroom/pull/2527)
- [core/ui] "Exposed" property added to attributeDesc [PR](https://github.com/alicevision/Meshroom/pull/2528)
- Extract more metadata using exifTool [PR](https://github.com/alicevision/Meshroom/pull/2645)
- Add equirectangular camera model in `CameraInit` [PR](https://github.com/alicevision/Meshroom/pull/2630)
- Fix: Improve large project file loading performance [PR](https://github.com/alicevision/Meshroom/pull/2665)
- UI: Redesign ChoiceParam UI component [PR](https://github.com/alicevision/Meshroom/pull/2656)
- Create new pipeline for testing modular sfm [PR](https://github.com/alicevision/Meshroom/pull/2664)
- [ui] Graph Editor Update: Quick Node Coloring with the Color Selector Tool [PR](https://github.com/alicevision/Meshroom/pull/2604)
- [doc] README.md: Add DeepWiki link, the AI documentation you can talk to [PR](https://github.com/alicevision/Meshroom/pull/2792)

### Other Improvements

- Start Development 2024.1.0 [PR](https://github.com/alicevision/Meshroom/pull/2268)
- ImageSegmentation: add an option to choose between cpu and gpu [PR](https://github.com/alicevision/Meshroom/pull/2267)
- [Viewer] Display error labels when an image cannot be loaded [PR](https://github.com/alicevision/Meshroom/pull/2250)
- [MaterialIcons] Add script to generate the list of available MaterialIcons and update it [PR](https://github.com/alicevision/Meshroom/pull/2247)
- Add option to keep input filename in imageSegmentation [PR](https://github.com/alicevision/Meshroom/pull/2288)
- Add camera color spaces [PR](https://github.com/alicevision/Meshroom/pull/2251)
- [docker] Fix link to download `libassimpsceneimport.so` in Docker images [PR](https://github.com/alicevision/Meshroom/pull/2310)
- Added PLY to list of supported files in 3D viewer [PR](https://github.com/alicevision/Meshroom/pull/2316)
- E57 importer is now generating multiple sfmData [PR](https://github.com/alicevision/Meshroom/pull/2318)
- Added semantic logic to display multiple 3d objects [PR](https://github.com/alicevision/Meshroom/pull/2320)
- [submitters] Update SimpleFarm configuration tags [PR](https://github.com/alicevision/Meshroom/pull/2348)
- [ui] drag&drop: common behavior for graph editor and image gallery [PR](https://github.com/alicevision/Meshroom/pull/2342)
- [core] Add new type of ChoiceParam that changes dynamically [PR](https://github.com/alicevision/Meshroom/pull/2350)
- [ui] Add new FilterComboBox for ChoiceParam attributes [PR](https://github.com/alicevision/Meshroom/pull/2358)
- [core/ui] Hide output attributes flagged for visualisation [PR](https://github.com/alicevision/Meshroom/pull/2369)
- Update ripple constraints [PR](https://github.com/alicevision/Meshroom/pull/2374)
- Hide disabled File attributes and their connections [PR](https://github.com/alicevision/Meshroom/pull/1925)
- [ui] Sequence Player UX improvements (fps, slider, frame) [PR](https://github.com/alicevision/Meshroom/pull/2362)
- [core] BugFix : Upgrade of Dynamic Choice Param fixed [PR](https://github.com/alicevision/Meshroom/pull/2380)
- [ui] Bounding Box are usable in other nodes, not only Meshing [PR](https://github.com/alicevision/Meshroom/pull/2391)
- [ui] Cut option available in GraphEditor [PR](https://github.com/alicevision/Meshroom/pull/2399)
- [core] Set internal attributes when copy/pasting nodes [PR](https://github.com/alicevision/Meshroom/pull/2390)
- [ImageGallery] Display CameraInit label and defaultLabel to avoid confusion [PR](https://github.com/alicevision/Meshroom/pull/2383)
- [GraphEditor] Internal Custom Color Picker disabled when node is locked [PR](https://github.com/alicevision/Meshroom/pull/2384)
- Bump requests from 2.27.1 to 2.32.0 [PR](https://github.com/alicevision/Meshroom/pull/2405)
- [ui] Selected node header set to base color [PR](https://github.com/alicevision/Meshroom/pull/2401)
- [ui] Remove intrinsic if not used by any viewpoint [PR](https://github.com/alicevision/Meshroom/pull/2395)
- [ui] Right click on text element in AttributeEditor open Copy/Paste menu [PR](https://github.com/alicevision/Meshroom/pull/2366)
- [ui] Fix BoundingBox visibility icon because of mapping name [PR](https://github.com/alicevision/Meshroom/pull/2386)
- Add track coordinates [PR](https://github.com/alicevision/Meshroom/pull/2406)
- [ui] Conversion of relative paths to absolute ones [PR](https://github.com/alicevision/Meshroom/pull/2412)
- [core] Compare last saved date before saving to prevent overwrite [PR](https://github.com/alicevision/Meshroom/pull/2414)
- Fix 3D Viewer zooming problem [PR](https://github.com/alicevision/Meshroom/pull/2379)
- [ui] Use ExportAnimatedCamera output for image overlay in Viewer3D [PR](https://github.com/alicevision/Meshroom/pull/2398)
- [GraphEditor] Eye on displayable node even if not computed [PR](https://github.com/alicevision/Meshroom/pull/2427)
- [ui] Add "large" option to multiline string param [PR](https://github.com/alicevision/Meshroom/pull/2437)
- [ui] Auto Update CameraInit when displaying node [PR](https://github.com/alicevision/Meshroom/pull/2431)
- Fix compatibility upgrade issue [PR](https://github.com/alicevision/Meshroom/pull/2436)
- Depth map filter: display normals if enabled [PR](https://github.com/alicevision/Meshroom/pull/2442)
- [ui] do not use native dialog [PR](https://github.com/alicevision/Meshroom/pull/2439)
- File export ordering [PR](https://github.com/alicevision/Meshroom/pull/2440)
- [SequencePlayer] Fetching option added [PR](https://github.com/alicevision/Meshroom/pull/2415)
- Provide access to the current frame from the graph [PR](https://github.com/alicevision/Meshroom/pull/2443)
- Update ripple with "cuda" instead of "gpu" [PR](https://github.com/alicevision/Meshroom/pull/2448)
- Provide access to the path of the currently displayed frame [PR](https://github.com/alicevision/Meshroom/pull/2449)
- [Viewer] Fix all QML errors on the Sequence Player [PR](https://github.com/alicevision/Meshroom/pull/2451)
- Remove plugin loading from core __init__ [PR](https://github.com/alicevision/Meshroom/pull/2458)
- [ui] Sequence Player UI Modifications [PR](https://github.com/alicevision/Meshroom/pull/2445)
- [ui] Add MESHROOM_USE_SEQUENCE_PLAYER environment variable [PR](https://github.com/alicevision/Meshroom/pull/2463)
- Display ION container version in Meshroom  [PR](https://github.com/alicevision/Meshroom/pull/2468)
- Compute or Submit selected nodes [PR](https://github.com/alicevision/Meshroom/pull/2459)
- Add new SfMExpanding node [PR](https://github.com/alicevision/Meshroom/pull/2416)
- Add squeeze option [PR](https://github.com/alicevision/Meshroom/pull/2466)
- [Viewer] Current frame for Sequence should not be set during changes of Image Gallery [PR](https://github.com/alicevision/Meshroom/pull/2472)
- Remove some computers even for normal tasks [PR](https://github.com/alicevision/Meshroom/pull/2479)
- [GraphEditor] Implementation of Recompute Button [PR](https://github.com/alicevision/Meshroom/pull/2473)
- [core] Attribute: Directly access description's type in `getType()` [PR](https://github.com/alicevision/Meshroom/pull/2490)
- [Viewer] Update error values for QtAV's `EStatus` enum [PR](https://github.com/alicevision/Meshroom/pull/2491)
- [GraphEditor] Improve visibility of chunks in progress bar [PR](https://github.com/alicevision/Meshroom/pull/2507)
- [ui] Correctly lose focus on `StringParam` when clicking outside of its text field [PR](https://github.com/alicevision/Meshroom/pull/2512)
- Multiple shots: Align and merge multiple SfM from feature matches [PR](https://github.com/alicevision/Meshroom/pull/2484)
- Homepage Quick Adjustments [PR](https://github.com/alicevision/Meshroom/pull/2520)
- Add locks for intrinsics [PR](https://github.com/alicevision/Meshroom/pull/2517)
- sfmTransform: Add option to lineup camera motion with object/lidar given an external camera pose [PR](https://github.com/alicevision/Meshroom/pull/2524)
- [ui] Open project from browser in homepage & quick adjustments [PR](https://github.com/alicevision/Meshroom/pull/2525)
- [ui] Minor UI modifications [PR](https://github.com/alicevision/Meshroom/pull/2530)
- [ui] Fix click on Category in Node Menu to keep the nodes displayed [PR](https://github.com/alicevision/Meshroom/pull/2526)
- [core] Simplify attribute invalidation in nodes' descriptions [PR](https://github.com/alicevision/Meshroom/pull/2523)
- UI Changes [PR](https://github.com/alicevision/Meshroom/pull/2531)
- [AttributeItemDelegate] Position the attribute description tooltip [PR](https://github.com/alicevision/Meshroom/pull/2532)
- [ui] Add View Image Gallery Parameter [PR](https://github.com/alicevision/Meshroom/pull/2541)
- [core] Simplify node descriptions [PR](https://github.com/alicevision/Meshroom/pull/2538)
- Use export distortion and new segmentation node in templates [PR](https://github.com/alicevision/Meshroom/pull/2549)
- Add wireframe for Qt6 [PR](https://github.com/alicevision/Meshroom/pull/2561)
- Change picking behavior for qt6 upgrade [PR](https://github.com/alicevision/Meshroom/pull/2564)
- [qt6] Fix 8Bits image viewer zoom/fit [PR](https://github.com/alicevision/Meshroom/pull/2565)
- [blender] Adapt `ScenePreview`'s Blender script to pixel ratio [PR](https://github.com/alicevision/Meshroom/pull/2572)
- Update panorama display [PR](https://github.com/alicevision/Meshroom/pull/2573)
- Fix attribute value change propagation and callback handling [PR](https://github.com/alicevision/Meshroom/pull/2586)
- Tracking pipelines segmentation update [PR](https://github.com/alicevision/Meshroom/pull/2583)
- [qt6]|Viewer3D] Fix mouse for camera controller [PR](https://github.com/alicevision/Meshroom/pull/2566)
- Discard attribute changed callbacks during graph loading [PR](https://github.com/alicevision/Meshroom/pull/2598)
- Split `meshroom.core.desc` module into a package with submodules [PR](https://github.com/alicevision/Meshroom/pull/2592)
- [ui] Minor UI stabilization fixes for Qt 6 [PR](https://github.com/alicevision/Meshroom/pull/2606)
- [ui] Fix field of view functions for tall images [PR](https://github.com/alicevision/Meshroom/pull/2609)
- [Viewer3D] Apply the pixel aspect ratio for the Frame Overlay [PR](https://github.com/alicevision/Meshroom/pull/2533)
- [ui] Improve Search Bar component [PR](https://github.com/alicevision/Meshroom/pull/2581)
- [BugFix] File save dialog now requires a valid filename [PR](https://github.com/alicevision/Meshroom/pull/2602)
- [GraphEditor] AttributeItemDelegate: Use MaterialLabel for uncomputed attributes [PR](https://github.com/alicevision/Meshroom/pull/2616)
- CI: add codecov [PR](https://github.com/alicevision/Meshroom/pull/2618)
- Sfm Bootstraping parameterization [PR](https://github.com/alicevision/Meshroom/pull/2619)
- Fix Qt6-induced issues [PR](https://github.com/alicevision/Meshroom/pull/2620)
- [ui] GraphEditor: Address Key Event Conflicts in Node Menu [PR](https://github.com/alicevision/Meshroom/pull/2622)
- [ui] Add Validation for Save file path accessibility [PR](https://github.com/alicevision/Meshroom/pull/2625)
- [ui] NodeEditor: Addressed Tab Retention when switching Node selection [PR](https://github.com/alicevision/Meshroom/pull/2624)
- Add support for QML debugging/profiling [PR](https://github.com/alicevision/Meshroom/pull/2623)
- [GraphEditor] Fix injections into signal handlers with JS functions [PR](https://github.com/alicevision/Meshroom/pull/2627)
- [ui] "About" dialog: Fix some display issues [PR](https://github.com/alicevision/Meshroom/pull/2640)
- Update version number and copyrights [PR](https://github.com/alicevision/Meshroom/pull/2639)
- SelectionBox: Fixed the offset on the selection box highlight appearing in the Graph Editor when dragging to select Nodes [PR](https://github.com/alicevision/Meshroom/pull/2647)
- [ui] Moved Auto-Layout Depth Settings under Graph Editor Menu [PR](https://github.com/alicevision/Meshroom/pull/2646)
- Enable merge of multiple sfmDatas [PR](https://github.com/alicevision/Meshroom/pull/2654)
- [ui][fix] Edge: Fixing an issue with mouse event on Custom EdgeMouseArea causing Crash [PR](https://github.com/alicevision/Meshroom/pull/2650)
- [ui] Refactor the access to the list of recent project files [PR](https://github.com/alicevision/Meshroom/pull/2637)
- Mask processing node [PR](https://github.com/alicevision/Meshroom/pull/2658)
- Export Maya .mel Script  [PR](https://github.com/alicevision/Meshroom/pull/2617)
- Refactor Graph de/serialization [PR](https://github.com/alicevision/Meshroom/pull/2612)
- Node: Propagate attribute change via `valueChanged` signal [PR](https://github.com/alicevision/Meshroom/pull/2657)
- [qml] Fix QML warnings related to chunks [PR](https://github.com/alicevision/Meshroom/pull/2673)
- Add maya scene export [PR](https://github.com/alicevision/Meshroom/pull/2674)
- NodeAPI: Trigger node creation callback only for explicit new node creation [PR](https://github.com/alicevision/Meshroom/pull/2671)
- [ui] app: Register components to QML before instantiating the engine [PR](https://github.com/alicevision/Meshroom/pull/2676)
- [ui] Application: fix save-as dialog not working properly (Qt6.7+) [PR](https://github.com/alicevision/Meshroom/pull/2683)
- [GraphEditor] Only display "Pipelines" menu when templates are available [PR](https://github.com/alicevision/Meshroom/pull/2678)
- [qml] Fix QML warnings when dropping project files into the Graph Editor [PR](https://github.com/alicevision/Meshroom/pull/2680)
- Export USD Node [PR](https://github.com/alicevision/Meshroom/pull/2667)
- [ui] AttributeEditor: Generic TextField param editor improvements [PR](https://github.com/alicevision/Meshroom/pull/2686)
- ChoiceParam: add option to serialize overriden values [PR](https://github.com/alicevision/Meshroom/pull/2682)
- [core] Node: Status should be `NONE` when there is no chunk [PR](https://github.com/alicevision/Meshroom/pull/2695)
- Move nodes and templates to AliceVision's repository [PR](https://github.com/alicevision/Meshroom/pull/2697)
- Remove internal and no longer used files [PR](https://github.com/alicevision/Meshroom/pull/2711)
- Modernize to python 3.9 using flynt and pyupgrade [PR](https://github.com/alicevision/Meshroom/pull/2710)
- [doc] README: Clarified distinction between Meshroom engine, user interface, and plugins [PR](https://github.com/alicevision/Meshroom/pull/2718)
- Use shutil to load nvidia-smi [PR](https://github.com/alicevision/Meshroom/pull/2721)
- [ui] Viewer2D can display the content of tracks files [PR](https://github.com/alicevision/Meshroom/pull/2720)
- [ui] [fix] Attribute: Fix the qml warnings on intrisincs [PR](https://github.com/alicevision/Meshroom/pull/2739)
- [ui] Application: Use CamelCase and disable tooltips when menus are disabled [PR](https://github.com/alicevision/Meshroom/pull/2742)
- ListAttribute: fix methods not considering connected attribute's value [PR](https://github.com/alicevision/Meshroom/pull/2660)
- [fix] remove targetSize in viewer2d which was removed in qtAliceVision [PR](https://github.com/alicevision/Meshroom/pull/2746)
- [ui] Homepage: Update logos of sponsors [PR](https://github.com/alicevision/Meshroom/pull/2729)
- [ui] Rework of MessageDialog for CompatibilityManager and SensorDBDialog [PR](https://github.com/alicevision/Meshroom/pull/2537)
- [qml] Fix some minor QML warnings [PR](https://github.com/alicevision/Meshroom/pull/2756)
- Add support for `ALICEVISION_LIBPATH` environment variable [PR](https://github.com/alicevision/Meshroom/pull/2757)
- [docker] minor updates [PR](https://github.com/alicevision/Meshroom/pull/2765)
- [core] plugins: Add support for virtual environments on Windows [PR](https://github.com/alicevision/Meshroom/pull/2768)
- [core] Adding rangeBlocksCount to `Parallelization` [PR](https://github.com/alicevision/Meshroom/pull/2767)
- Bump requests from 2.32.0 to 2.32.4 [PR](https://github.com/alicevision/Meshroom/pull/2743)
- Fix colorHueComponent slider background [PR](https://github.com/alicevision/Meshroom/pull/2788)
- [core] plugins: Look recursively for "lib" directories in Linux venv [PR](https://github.com/alicevision/Meshroom/pull/2777)
- [core] plugins: Virtual environments should be named "venv" instead of having the plugin's name [PR](https://github.com/alicevision/Meshroom/pull/2793)
- [qml] Minor UI fixes [PR](https://github.com/alicevision/Meshroom/pull/2783)
- [qml] Use native FileDialogs [PR](https://github.com/alicevision/Meshroom/pull/2784)
- Set the default environment variables for the color chart detection models [PR](https://github.com/alicevision/Meshroom/pull/2796)
- [ui] Remove the `Live Reconstruction` and `Augment Reconstruction` features [PR](https://github.com/alicevision/Meshroom/pull/2786)
- Improve behaviour when dropping folders [PR](https://github.com/alicevision/Meshroom/pull/2797)
- [core] plugins: Load plugin's configuration file upon its initialisation [PR](https://github.com/alicevision/Meshroom/pull/2778)
- [core] plugins: Downgrade the log level when loading the config file [PR](https://github.com/alicevision/Meshroom/pull/2798)

### Bugfixes

- Fix duplicated icon in MaterialIcons [PR](https://github.com/alicevision/Meshroom/pull/2277)
- Correctly delete thread pools when exiting Meshroom with Python 3.9 [PR](https://github.com/alicevision/Meshroom/pull/2286)
- [Viewer] Viewer: Fix various issues with the 2D Viewer [PR](https://github.com/alicevision/Meshroom/pull/2283)
- Use the correct response file to display the graph of the Camera Response Function [PR](https://github.com/alicevision/Meshroom/pull/2282)
- Update `ListAttributes` identically when removing edges or nodes [PR](https://github.com/alicevision/Meshroom/pull/2280)
- Upgrade intrinsics for distortion [PR](https://github.com/alicevision/Meshroom/pull/2349)
- [ui] Correctly display images from node outputs even if there is no `CameraInit` node [PR](https://github.com/alicevision/Meshroom/pull/2363)
- [ui] Scroll available in FilterComboBox [PR](https://github.com/alicevision/Meshroom/pull/2376)
- [Viewer] fix lens distortion viewer status when switching between projects [PR](https://github.com/alicevision/Meshroom/pull/2377)
- [ui] Fix drag and drop of heavy number of frames [PR](https://github.com/alicevision/Meshroom/pull/2378)
- SequencePlayer: Forbid "selecting" an invalid frame number [PR](https://github.com/alicevision/Meshroom/pull/2388)
- [ui] Prevent Feature Points to display on external images [PR](https://github.com/alicevision/Meshroom/pull/2389)
- [ui/core] Fix get latest SfM node for previz [PR](https://github.com/alicevision/Meshroom/pull/2396)
- [nodes/ui] Fix ExportAnimatedCamera outputs for ScenePreview use [PR](https://github.com/alicevision/Meshroom/pull/2420)
- [fix] Various fixes [PR](https://github.com/alicevision/Meshroom/pull/2419)
- Prevent updates of the latest SfM node when the graph's topology is dirty [PR](https://github.com/alicevision/Meshroom/pull/2435)
- [Utils] `getTimeStr`: Round up the number of minutes correctly [PR](https://github.com/alicevision/Meshroom/pull/2254)
- [ui] Graph: Connect all chunks when setting a graph for the first time [PR](https://github.com/alicevision/Meshroom/pull/2454)
- [core] Exclude edges from `InputNode` nodes in `dfsToProcess` [PR](https://github.com/alicevision/Meshroom/pull/2455)
- [core] Values of ChoiceParam should be a list, Error message added for initialisation [PR](https://github.com/alicevision/Meshroom/pull/2469)
- Some fixes for dynamic output attributes [PR](https://github.com/alicevision/Meshroom/pull/2470)
- [ui] Fix local computation of subgraphs for unsaved projects [PR](https://github.com/alicevision/Meshroom/pull/2471)
- [ui] Fix Camera Init Group Index should stay the same at adding or removing CameraInit events [PR](https://github.com/alicevision/Meshroom/pull/2474)
- [Viewer2D] Only reset index of currentFrame if the currentFrame is after max of frameRange [PR](https://github.com/alicevision/Meshroom/pull/2480)
- [ui] setSfm only depends on nodes with category "sfm" and CameraInit should be set only if it is different from the current one [PR](https://github.com/alicevision/Meshroom/pull/2476)
- [GraphEditor] AttributeItemDelegate: Return valid component for `PushButton` [PR](https://github.com/alicevision/Meshroom/pull/2482)
- Initialize `core` plugins at different moments [PR](https://github.com/alicevision/Meshroom/pull/2487)
- [ui] app: Correctly reload list of available templates [PR](https://github.com/alicevision/Meshroom/pull/2499)
- [core] Catch exception for calls to optional descriptor method on node creation [PR](https://github.com/alicevision/Meshroom/pull/2500)
- [ui] Improve sequence display [PR](https://github.com/alicevision/Meshroom/pull/2502)
- [ui] GraphEditor.newNodeMenu: fix unstable menu height [PR](https://github.com/alicevision/Meshroom/pull/2511)
- [ui] Add proper distinction between the main window and the application [PR](https://github.com/alicevision/Meshroom/pull/2521)
- [ui] Fix function evaluations in invalid QML context and minor fixes [PR](https://github.com/alicevision/Meshroom/pull/2519)
- Fix Several Compatibility Nodes Operations [PR](https://github.com/alicevision/Meshroom/pull/2506)
- [main] Fix imagesFolder variable in order to save when gallery is not empty [PR](https://github.com/alicevision/Meshroom/pull/2535)
- [bin] Import correct `Graph` objects for `meshroom_batch` [PR](https://github.com/alicevision/Meshroom/pull/2536)
- Fix homepage SplitViews [PR](https://github.com/alicevision/Meshroom/pull/2545)
- [core] Check provided template folder exists before attempting to load it [PR](https://github.com/alicevision/Meshroom/pull/2552)
- [img] Remove incorrect sRGB profile from UiO logo [PR](https://github.com/alicevision/Meshroom/pull/2555)
- [ui] multiple fixes related to split view and node status checks [PR](https://github.com/alicevision/Meshroom/pull/2568)
- [ui] Various minor UI fixes [PR](https://github.com/alicevision/Meshroom/pull/2563)
- [core] Node: Do not automatically upgrade unknown nodes in templates [PR](https://github.com/alicevision/Meshroom/pull/2558)
- [GraphEditor] Node: Check if unexposed `ListAttributes` contain links [PR](https://github.com/alicevision/Meshroom/pull/2578)
- [GraphEditor] Edge: Correctly update the `EdgeMouseArea` when moving nodes [PR](https://github.com/alicevision/Meshroom/pull/2613)
- Fix projects disappearing from the list of recent projects [PR](https://github.com/alicevision/Meshroom/pull/2615)
- [ImageGallery] Intrinsics table: Always fully instantiate the model before populating it [PR](https://github.com/alicevision/Meshroom/pull/2655)
- [ui] Graph: In minimal refresh, do not poll files for chunks run locally [PR](https://github.com/alicevision/Meshroom/pull/2672)
- Fix Meshroom App CLI `latest` option [PR](https://github.com/alicevision/Meshroom/pull/2675)
- [bin] `meshroom_batch`: Stop using removed `defaultCacheFolder` [PR](https://github.com/alicevision/Meshroom/pull/2715)
- [desc] Import `CREATE_NEW_PROCESS_GROUP` flag from `subprocess` [PR](https://github.com/alicevision/Meshroom/pull/2719)
- [ui] Reconstruction: Restore the `Slot` status of the `clear` method [PR](https://github.com/alicevision/Meshroom/pull/2732)
- [core] attribute: Fix `hasOutputConnections` for ListAttributes [PR](https://github.com/alicevision/Meshroom/pull/2731)
- Fix elapsed time when there is only one chunk [PR](https://github.com/alicevision/Meshroom/pull/2734)
- bugfix ExecMode status [PR](https://github.com/alicevision/Meshroom/pull/2737)
- [ui] Update node status when modified [PR](https://github.com/alicevision/Meshroom/pull/2738)
- [ui] [fix] MediaLibrary: Check if the model.source is actually an Attribute… [PR](https://github.com/alicevision/Meshroom/pull/2736)
- [ui] [fix] Viewer2D: Failure on MousePosition on some edge cases [PR](https://github.com/alicevision/Meshroom/pull/2741)
- [core] Templates test: Remove outdated `unregisterNodeType` import [PR](https://github.com/alicevision/Meshroom/pull/2750)
- [ui] GraphEditor fix: Remove useless link between height and implicitHeight [PR](https://github.com/alicevision/Meshroom/pull/2749)
- [core] Templates test: Access node descriptor from `NodePlugin` object [PR](https://github.com/alicevision/Meshroom/pull/2751)
- [core] Stop checking for templates in "pipelines" folder [PR](https://github.com/alicevision/Meshroom/pull/2752)
- [ui] [fix] Viewer2D: using the keyboard shortcuts (r,g,b,a) break the channelBox combobox [PR](https://github.com/alicevision/Meshroom/pull/2753)
- [ui] Reconstruction: Fix setup of temporary `CameraInit` nodes [PR](https://github.com/alicevision/Meshroom/pull/2762)
- [core] [fix] Fix camera see through not working when multiple cameraInit and image overlay dind't display anythind [PR](https://github.com/alicevision/Meshroom/pull/2761)
- [core] desc.node: Ensure all paths are sent to the command line as POSIX strings [PR](https://github.com/alicevision/Meshroom/pull/2760)
- [ui] Nodes: Update the deprecated import of QGraphicEffects. [PR](https://github.com/alicevision/Meshroom/pull/2755)
- [ui] Import images: Fix that trying to import images twic, the dialog… [PR](https://github.com/alicevision/Meshroom/pull/2763)
- Meshing: boundingBox working with qt6 [PR](https://github.com/alicevision/Meshroom/pull/2766)
- Fix manual frame selection in viewer 2D [PR](https://github.com/alicevision/Meshroom/pull/2769)
- [ui] app: Correctly evaluate env vars that enable/disable components [PR](https://github.com/alicevision/Meshroom/pull/2772)
- Fix for QFontDatabase crash on exit [PR](https://github.com/alicevision/Meshroom/pull/2776)
- [ui] Add project to recent projects when dropping a file [PR](https://github.com/alicevision/Meshroom/pull/2483)
- [ui] fix: Overlay image does not work on pipeline "Photogrametry experimental"  [PR](https://github.com/alicevision/Meshroom/pull/2780)
- [core] Parallelization: the cmdline suffix should be at the end [PR](https://github.com/alicevision/Meshroom/pull/2794)

### CI, Documentation and Build

- Add environment variable for the CI [PR](https://github.com/alicevision/Meshroom/pull/2492)
- Adding new tutorial [PR](https://github.com/alicevision/Meshroom/pull/2546)
- [ci] Use GitHub's workflows for the Windows CI instead of appveyor [PR](https://github.com/alicevision/Meshroom/pull/2551)
- [ci] Codecov: enable support for test run reports [PR](https://github.com/alicevision/Meshroom/pull/2659)
- change git clone link to use https link in "get the project" [PR](https://github.com/alicevision/Meshroom/pull/2700)
- [ci] Update Python version from 3.9.13 to 3.11 [PR](https://github.com/alicevision/Meshroom/pull/2758)
- [docker] Add Dockerfiles for Rocky 9 and handle Qt 6 installation [PR](https://github.com/alicevision/Meshroom/pull/2626)
- [doc] Update `INSTALL.md` and `README.md` files [PR](https://github.com/alicevision/Meshroom/pull/2787)
- [build] Fixes for the generation of Meshroom's executable [PR](https://github.com/alicevision/Meshroom/pull/2770)
- [doc] README.md: Add DeepWiki link, the AI documentation you can talk to [PR](https://github.com/alicevision/Meshroom/pull/2792)

### Contributors

[cbentejac](https://github.com/cbentejac), [demoulinv](https://github.com/demoulinv), [dependabot[bot]](https://github.com/apps/dependabot), [dyster](https://github.com/dyster), [elyasbny](https://github.com/elyasbny), [emmanuel-ferdman](https://github.com/emmanuel-ferdman), [fabiencastan](https://github.com/fabiencastan), [gregoire-dl](https://github.com/gregoire-dl), [jmelou](https://github.com/jmelou), [Just-Kiel](https://github.com/Just-Kiel), [mh0g](https://github.com/mh0g), [natowi](https://github.com/natowi), [nicolas-lambert-tc](https://github.com/nicolas-lambert-tc), [sbrood](https://github.com/sbrood), [servantftransperfect](https://github.com/servantftransperfect), [Sh1r0Yaksha](https://github.com/Sh1r0Yaksha), [waaake](https://github.com/waaake), [yann-lty](https://github.com/yann-lty)

## Meshroom 2023.3.0 (2023/12/07)

Based on [AliceVision 3.2.0](https://github.com/alicevision/AliceVision/tree/v3.2.0).

### Major Features

- New node for semantic image segmentation [PR](https://github.com/alicevision/Meshroom/pull/2076)
- Support pixel aspect ratio (no UI) [PR](https://github.com/alicevision/Meshroom/pull/2079)
- Noise reduction in HDR merging [PR](https://github.com/alicevision/Meshroom/pull/2072)

### Features

- [ui] 2D viewer: image sequence player [PR](https://github.com/alicevision/Meshroom/pull/1989)
- [bin] meshroom_batch: support multiple init nodes [PR](https://github.com/alicevision/Meshroom/pull/2137)
- [nodes] StructureFromMotion: Automatic alignment of the 3D reconstruction [PR](https://github.com/alicevision/Meshroom/pull/2199)
- New node for intrinsics and rig calibration using a multiview acquisition of a checkerboard [PR](https://github.com/alicevision/Meshroom/pull/2171)
- New Nodal Camera Tracking pipeline [PR](https://github.com/alicevision/Meshroom/pull/2200)
- Manage LCP in imageProcessing [PR](https://github.com/alicevision/Meshroom/pull/2042)
- [Viewer3D] Add slider to display cameras based on their resection IDs [PR](https://github.com/alicevision/Meshroom/pull/2235)

### Other Improvements

- Start Development 2023.3 [PR](https://github.com/alicevision/Meshroom/pull/2085)
- Node to split reconstructed and not reconstructed cameras [PR](https://github.com/alicevision/Meshroom/pull/1974)
- [core] Execute command line from node folder [PR](https://github.com/alicevision/Meshroom/pull/2093)
- [core] Add brackets option for GroupAttribute [PR](https://github.com/alicevision/Meshroom/pull/2094)
- Update Qt version to 5.15.2 [PR](https://github.com/alicevision/Meshroom/pull/1882)
- [pipelines] Panorama: Publish the panorama preview [PR](https://github.com/alicevision/Meshroom/pull/2106)
- [nodes] HDR Fusion: Correctly detect the number of brackets when there are several intrinsics [PR](https://github.com/alicevision/Meshroom/pull/2104)
- [nodes] ImageSegmentation: use ChoiceParam instead of ListAttribute for validClasses [PR](https://github.com/alicevision/Meshroom/pull/2109)
- [Panorama] Enforce priors after estimation [PR](https://github.com/alicevision/Meshroom/pull/1926)
- tolerant bracket size selection [PR](https://github.com/alicevision/Meshroom/pull/2113)
- [nodes] HDR Fusion: Do not send `nbBrackets` parameter to the command line when the bracket detection is automatic [PR](https://github.com/alicevision/Meshroom/pull/2117)
- [nodes] Remove limits on outliers for brackets detection [PR](https://github.com/alicevision/Meshroom/pull/2118)
- [nodes] LdrToHdrSampling: Exclude outliers from size computation [PR](https://github.com/alicevision/Meshroom/pull/2119)
- [nodes] HDR Fusion: Select group with largest bracket number in case of equality [PR](https://github.com/alicevision/Meshroom/pull/2121)
- [nodes] new exportLevels option in PanoramaPostProcessing [PR](https://github.com/alicevision/Meshroom/pull/2133)
- [ui] GraphEditor: Minor UI changes [PR](https://github.com/alicevision/Meshroom/pull/2125)
- [pipelines] publish downscaled panorama levels [PR](https://github.com/alicevision/Meshroom/pull/2147)
- [nodes] HDR Fusion: Use the same bracket detection as in AliceVision [PR](https://github.com/alicevision/Meshroom/pull/2154)
- AttributeEditor: Flag attributes with invalid values [PR](https://github.com/alicevision/Meshroom/pull/2141)
- [pipelines] Add colors for CameraTracking and Photog+CamTrack templates [PR](https://github.com/alicevision/Meshroom/pull/2114)
- [pipelines] add ImageSegmentation node to tracking pipelines [PR](https://github.com/alicevision/Meshroom/pull/2164)
- Camera exposure update [PR](https://github.com/alicevision/Meshroom/pull/2159)
- PanoramaInit: remove fake dependency [PR](https://github.com/alicevision/Meshroom/pull/2110)
- [nodes] Masking: Handle file extensions for masks and mask inversion for `ImageSegmentation` [PR](https://github.com/alicevision/Meshroom/pull/2165)
- [nodes] KeyframeSelection: Add `minBlockSize` param for multi-threading [PR](https://github.com/alicevision/Meshroom/pull/2161)
- [nodes] KeyframeSelection: Add support for masks [PR](https://github.com/alicevision/Meshroom/pull/2167)
- KeyframeSelection: Flag `outputExtension` attribute when it is set to "none" for video inputs [PR](https://github.com/alicevision/Meshroom/pull/2163)
- [blender] apply masks to scene preview [PR](https://github.com/alicevision/Meshroom/pull/2170)
- Add automatic method for HDR calibration [PR](https://github.com/alicevision/Meshroom/pull/2169)
- Multiple UI Improvements [PR](https://github.com/alicevision/Meshroom/pull/2173)
- [ui] FloatImageViewer: adapt resolution to zoom [PR](https://github.com/alicevision/Meshroom/pull/2148)
- [nodes] StructureFromMotion: Add new `logIntermediateSteps` parameter [PR](https://github.com/alicevision/Meshroom/pull/2182)
- sfm bootstraping [PR](https://github.com/alicevision/Meshroom/pull/2011)
- [nodes] PanoramaPostProcessing: Add attributes to change the outputs' names [PR](https://github.com/alicevision/Meshroom/pull/2193)
- [nodes] Meshing: expose minVis param [PR](https://github.com/alicevision/Meshroom/pull/2196)
- [ui] SequencePlayer: minor adjustments (fps, icon, play) [PR](https://github.com/alicevision/Meshroom/pull/2197)
- [pipelines] Rename Nodal Tracking to Nodal Camera Tracking [PR](https://github.com/alicevision/Meshroom/pull/2207)
- [nodes] DepthMap: increase size of blocks [PR](https://github.com/alicevision/Meshroom/pull/2203)
- [ui] ImageGallery: Add "Remove All Images" menu to clear all images [PR](https://github.com/alicevision/Meshroom/pull/2221)
- [bin] `meshroom_batch`: Add support for relative input and output paths [PR](https://github.com/alicevision/Meshroom/pull/2218)
- [pipelines] CamTrack: Add new template without calibration and update some parameters [PR](https://github.com/alicevision/Meshroom/pull/2216)
- Input color space setting [PR](https://github.com/alicevision/Meshroom/pull/2219)
- Use new SfmDataEntity plugin instead of AlembicEntity [PR](https://github.com/alicevision/Meshroom/pull/2208)
- [Viewer3D] Remove AlembicLoader file [PR](https://github.com/alicevision/Meshroom/pull/2228)
- [pipelines] CamTrack: Update default params for keyframes SfM [PR](https://github.com/alicevision/Meshroom/pull/2227)
- [pipelines] PhotogAndCamTrack: Disable automatic alignment in SfM [PR](https://github.com/alicevision/Meshroom/pull/2238)
- Automatic reorientation [PR](https://github.com/alicevision/Meshroom/pull/2236)
- Minor code clean-up and QML warning and error fixes [PR](https://github.com/alicevision/Meshroom/pull/2226)
- Add ancestor images info in view [PR](https://github.com/alicevision/Meshroom/pull/2242)
- [Viewer3D] Connect any change of the selected view ID to the SfmDataLoader [PR](https://github.com/alicevision/Meshroom/pull/2237)
- New utility nodes to create camera rigs and merge two sfmData [PR](https://github.com/alicevision/Meshroom/pull/2214)
- [pipelines] Add image segmentation to the Nodal Camera Tracking template [PR](https://github.com/alicevision/Meshroom/pull/2266)

### Bugfixes

- QML: Fix minor coercion error and warning [PR](https://github.com/alicevision/Meshroom/pull/2107)
- [ScenePreview] fix: 1st chunk was computing all views [PR](https://github.com/alicevision/Meshroom/pull/2108)
- [bin] meshroom_batch: Save the graph once it has been all set up and resolved [PR](https://github.com/alicevision/Meshroom/pull/2095)
- [nodes] HDR Fusion: Fix bracket detection [PR](https://github.com/alicevision/Meshroom/pull/2143)
- [core] Preserve edges by recreating all the nodes during UID evaluation [PR](https://github.com/alicevision/Meshroom/pull/2127)
- [bin] `meshroom_batch`: Fix input parsing for Windows [PR](https://github.com/alicevision/Meshroom/pull/2188)
- [nodes] ImageSegmentation: increase GPU requirements [PR](https://github.com/alicevision/Meshroom/pull/2195)
- [ui] ImageGallery: Disable "Visualize HDR" button after clearing images [PR](https://github.com/alicevision/Meshroom/pull/2180)
- [ui] Check for the existence of the `poses` key in SfM JSON files before accessing it [PR](https://github.com/alicevision/Meshroom/pull/2190)
- [nodes] CameraInit: fix tooltip focal is in mm [PR](https://github.com/alicevision/Meshroom/pull/2202)
- [ui] Viewer2D: various orientation fixes [PR](https://github.com/alicevision/Meshroom/pull/2212)
- [ui] ImageGallery: Use commands to set SfM attributes through the Image Gallery [PR](https://github.com/alicevision/Meshroom/pull/2220)
- [ui] Preserve last `CameraInit` index when updating the CameraInits list [PR](https://github.com/alicevision/Meshroom/pull/2145)
- [ui] Don't load a node's output in the 3DViewer if it has no 3D output [PR](https://github.com/alicevision/Meshroom/pull/2230)
- [pipelines] Photogrammetry Draft: Add a `PrepareDenseScene` node to the template [PR](https://github.com/alicevision/Meshroom/pull/2232)
- [Viewer3D] Bind the display status of the resection groups to QtAliceVision [PR](https://github.com/alicevision/Meshroom/pull/2257)
- [core] Only update the running chunk to `STOPPED` when stopping computations [PR](https://github.com/alicevision/Meshroom/pull/2258)

### CI, Build and Documentation

- Update build-ubuntu.sh [PR](https://github.com/alicevision/Meshroom/pull/1951)
- Set `ALICEVISION_SEMANTIC_SEGMENTATION_MODEL` variable during the initialisation [PR](https://github.com/alicevision/Meshroom/pull/2090)
- [build] Remove references to QmlAlembic in the build process [PR](https://github.com/alicevision/Meshroom/pull/2131)

### Contributors

[almarouk](https://github.com/almarouk), [cbentejac](https://github.com/cbentejac), [demoulinv](https://github.com/demoulinv), [fabiencastan](https://github.com/fabiencastan), [gregoire-dl](https://github.com/gregoire-dl), [mugulmd](https://github.com/mugulmd), [rakhnin](https://github.com/rakhnin), [servantftechnicolor](https://github.com/servantftechnicolor)


## Meshroom 2023.2.0 (2023/06/26)

Based on [AliceVision 3.1.0](https://github.com/alicevision/AliceVision/tree/v3.1.0).

### Major Features

- New Photometric Stereo nodes [PR](https://github.com/alicevision/Meshroom/pull/1853)
- [nodes] New CheckerboardDetection node [PR](https://github.com/alicevision/Meshroom/pull/1869)
- [nodes] Split360Images: support for SfMData file input and output [PR](https://github.com/alicevision/Meshroom/pull/1939)
- [sfmTransform] add auto mode [PR](https://github.com/alicevision/Meshroom/pull/1954)
- [nodes] DepthMap: New option for multi-resolution similarity estimation and optimizations [PR](https://github.com/alicevision/Meshroom/pull/1984)
- [nodes] Distortion calibration [PR](https://github.com/alicevision/Meshroom/pull/1986)
- Add a template for the HDR fusion [PR](https://github.com/alicevision/Meshroom/pull/2032)
- [pipelines] new CameraTracking pipeline [PR](https://github.com/alicevision/Meshroom/pull/2033)
- [pipelines] new photogrammetry and camera tracking pipeline [PR](https://github.com/alicevision/Meshroom/pull/2041)

### Features

- StructureFromMotion: Add new inputs parameters [PR](https://github.com/alicevision/Meshroom/pull/1980)
- [panorama] option to build contact sheet [PR](https://github.com/alicevision/Meshroom/pull/1945)
- Stitching color space [PR](https://github.com/alicevision/Meshroom/pull/1937)
- Add compression option for exr and jpg images [PR](https://github.com/alicevision/Meshroom/pull/1972)
- Add rec709 color space options [PR](https://github.com/alicevision/Meshroom/pull/1978)
- [nodes] rewrite RenderAnimatedCamera [PR](https://github.com/alicevision/Meshroom/pull/2030)
- [core] Detect and handle UID conflicts when loading a graph [PR](https://github.com/alicevision/Meshroom/pull/2059)

### Other Improvements

- Start Development Version 2023.2.0 [PR](https://github.com/alicevision/Meshroom/pull/1953)
- [core] Correctly parse status in version names when it exists [PR](https://github.com/alicevision/Meshroom/pull/1966)
- [tests] TemplatesVersion: Add message when compatibility assertion is raised [PR](https://github.com/alicevision/Meshroom/pull/1964)
- [ui] add new patterns to load images in viewer2D [PR](https://github.com/alicevision/Meshroom/pull/1975)
- [nodes] KeyframeSelection: Add support for SfMData files as inputs and outputs [PR](https://github.com/alicevision/Meshroom/pull/1967)
- [panorama] Panorama preview size [PR](https://github.com/alicevision/Meshroom/pull/1944)
- add trackbuilder node [PR](https://github.com/alicevision/Meshroom/pull/1987)
- [submitters] propagate REZ_PROD_PACKAGES_PATH environment variable [PR](https://github.com/alicevision/Meshroom/pull/1992)
- HDR images naming [PR](https://github.com/alicevision/Meshroom/pull/1999)
- [nodes] StructureFromMotion: new nbOutliersThreshold attribute [PR](https://github.com/alicevision/Meshroom/pull/2014)
- [ui] Reflect changes made in QtAliceVision refactorize PR [PR](https://github.com/alicevision/Meshroom/pull/1924)
- Exposure and format adjustment [PR](https://github.com/alicevision/Meshroom/pull/1983)
- [nodes] SfMTransform: add alignGround option [PR](https://github.com/alicevision/Meshroom/pull/2020)
- [nodes] ScenePreview: use base image name for naming output [PR](https://github.com/alicevision/Meshroom/pull/2035)
- [nodes] KeyframeSelection: Set a dynamic size for the node [PR](https://github.com/alicevision/Meshroom/pull/2039)
- KeyframeSelection: Add new parameter value to disable the export of keyframes [PR](https://github.com/alicevision/Meshroom/pull/2036)
- Viewer2D: Dynamically update the list of viewable outputs [PR](https://github.com/alicevision/Meshroom/pull/2044)
- [ui] ImageGallery: Display the name of the active `CameraInit` group [PR](https://github.com/alicevision/Meshroom/pull/2046)
- [nodes] StereoPhotometry: Fix some labels and descriptions [PR](https://github.com/alicevision/Meshroom/pull/2034)
- [ui] Display an icon on nodes that have viewable outputs [PR](https://github.com/alicevision/Meshroom/pull/2047)
- [ui] Display an icon on nodes that have viewable 3D outputs [PR](https://github.com/alicevision/Meshroom/pull/2052)
- [pipelines] cameraTracking: change StructureFromMotion parameters [PR](https://github.com/alicevision/Meshroom/pull/2055)
- [nodes] Harmonize and improve nodes descriptions  [PR](https://github.com/alicevision/Meshroom/pull/2063)
- [blender] preview: use cycles render engine [PR](https://github.com/alicevision/Meshroom/pull/2064)
- [blender] preview: occlusions in wireframe shading [PR](https://github.com/alicevision/Meshroom/pull/2071)

### Bugfixes, Build and Documentation

- [doc] RELEASING: Add example command to generate the release note [PR](https://github.com/alicevision/Meshroom/pull/1990)
- [core] Stats: Retrieve and set the GPU name if it is found [PR](https://github.com/alicevision/Meshroom/pull/1996)
- [bin] Fix all the scripts that had errors [PR](https://github.com/alicevision/Meshroom/pull/1995)
- [ui] ImageGallery: Reset viewpoints and intrinsics when removing all the images [PR](https://github.com/alicevision/Meshroom/pull/2031)
- [nodes] CameraInit: access intrinsic properties safely [PR](https://github.com/alicevision/Meshroom/pull/2040)
- [blender] preview: handle background image not found [PR](https://github.com/alicevision/Meshroom/pull/2045)
- Bump requests from 2.22.0 to 2.31.0 [PR](https://github.com/alicevision/Meshroom/pull/2018)
- [blender] preview: clear loaded images to avoid memory leak [PR](https://github.com/alicevision/Meshroom/pull/2053)
- Fix submit through simpleFarm [PR](https://github.com/alicevision/Meshroom/pull/2054)
- [ui] thumbnails: fallback if thumbnailDir could not be created [PR](https://github.com/alicevision/Meshroom/pull/2057)
- [core] fix transitive reduction when submitting graph [PR](https://github.com/alicevision/Meshroom/pull/2058)
- [doc] Update readme for custom pipelines and nodes [PR](https://github.com/alicevision/Meshroom/pull/2009)
- [core] Include the node's type in the UID computation [PR](https://github.com/alicevision/Meshroom/pull/2038)
- [doc] INSTALL: Add info about the sphere detection model [PR](https://github.com/alicevision/Meshroom/pull/2067)
- [blender] preview: use Freestyle for line art shading [PR](https://github.com/alicevision/Meshroom/pull/2074)
- Set `ALICEVISION_SPHERE_DETECTION_MODEL` variable during the initialisation [PR](https://github.com/alicevision/Meshroom/pull/2083)

### Contributors

[almarouk](https://github.com/almarouk), [cbentejac](https://github.com/cbentejac), [demoulinv](https://github.com/demoulinv), [earlywill](https://github.com/earlywill), [erikjwaxx](https://github.com/erikjwaxx), [fabiencastan](https://github.com/fabiencastan), [Garoli](https://github.com/Garoli), [gregoire-dl](https://github.com/gregoire-dl), [ICIbrahim](https://github.com/ICIbrahim), [jmelou](https://github.com/jmelou), [mugulmd](https://github.com/mugulmd), [serguei-k](https://github.com/serguei-k), [servantftechnicolor](https://github.com/servantftechnicolor), [simogasp](https://github.com/simogasp)


## Meshroom 2023.1.0 (2023/03/22)

Based on [AliceVision 3.0.0](https://github.com/alicevision/AliceVision/tree/v3.0.0).

### Release Notes Summary

- Major improvements of the depth map quality, performances and scalability. The full resolution can now be computed on most of the standard GPUs.
- FeatureExtraction is now using DSP-SIFT by default for the 3D Reconstruction pipeline.
- Capacity to create panoramas with very high resolutions using a limited amount of memory.
- Enhanced interpretation of RAW images, including new support for Adobe Digital Camera Profile and Lens Camera Profiles databases (if installed on your workstation).
- Improved color management with OCIO support and more options to export in various colorspaces including ACEScg.
- New graph templates enabling users to create custom pipelines.
- Expose a new experimental pipeline for Camera Tracking.
- Improved GraphEditor with copy-paste and multi-selection.
- Improved ImageGallery with thumbnails cache and search options.
- 2D Viewer is now using floating-point images by default.
- And a very large amount of UI improvements and bug fixes.

### Main Features

- [nodes] DepthMap: depth map improvements [PR](https://github.com/alicevision/Meshroom/pull/1818)
- Integration of AprilTag library according to issue #1179 and AliceVision pull request #950 [PR](https://github.com/alicevision/Meshroom/pull/1180)
- [nodes] add gps option to SfMTransform [PR](https://github.com/alicevision/Meshroom/pull/1477)
- [ui] add support for selecting multiple nodes at once [PR](https://github.com/alicevision/Meshroom/pull/1227)
- Image Gallery: Add a menu to set the StructureFromMotion initial pair from the gallery [PR](https://github.com/alicevision/Meshroom/pull/1936)
- Texturing Color Space [PR](https://github.com/alicevision/Meshroom/pull/1933)
- Add support for Lens Camera Profiles (LCP) [PR](https://github.com/alicevision/Meshroom/pull/1771)
- RAW advanced processing [PR](https://github.com/alicevision/Meshroom/pull/1918)
- Add new file watcher behaviours [PR](https://github.com/alicevision/Meshroom/pull/1812)
- Add internal attributes in "Notes" tab [PR](https://github.com/alicevision/Meshroom/pull/1744)
- New nodes for large memory use in panoramas [PR](https://github.com/alicevision/Meshroom/pull/1819)
- [ui] Thumbnail cache [PR](https://github.com/alicevision/Meshroom/pull/1861)
- [nodes] new SfMTriangulation node [PR](https://github.com/alicevision/Meshroom/pull/1842)
- Color management for RAW images [PR](https://github.com/alicevision/Meshroom/pull/1718)
- [ui] image gallery search bar [PR](https://github.com/alicevision/Meshroom/pull/1816)
- [ui] Viewer 2D: enable the HDR viewer by default [PR](https://github.com/alicevision/Meshroom/pull/1793)
- [ui] Improve the manipulator of the panorama viewer [PR](https://github.com/alicevision/Meshroom/pull/1707)
- Color space management [PR](https://github.com/alicevision/Meshroom/pull/1792)
- Show generated images in 2D viewer when double-clicking on node [PR](https://github.com/alicevision/Meshroom/pull/1776)
- [ui] Elapsed time indicators in log [PR](https://github.com/alicevision/Meshroom/pull/1787)
- [nodes] SfMTransform: add auto_from_cameras_x_axis [PR](https://github.com/alicevision/Meshroom/pull/1390)
- Graph Editor: Support copy/paste of selected nodes and scene import [PR](https://github.com/alicevision/Meshroom/pull/1758)
- [Feature Matching] Add an option to remove matches without enough motion [PR](https://github.com/alicevision/Meshroom/pull/1740)
- Output in ACES or ACEScg color space [PR](https://github.com/alicevision/Meshroom/pull/1681)
- Use project files to define pipelines [PR](https://github.com/alicevision/Meshroom/pull/1727)
- [nodes] StructureFromMotion: Add option computeStructureColor [PR](https://github.com/alicevision/Meshroom/pull/1635)
- [core] add env var to load nodes from multiple folders [PR](https://github.com/alicevision/Meshroom/pull/1616)
- Depth map refactoring [PR](https://github.com/alicevision/Meshroom/pull/680)
- Draft Reconstruction pipeline [PR](https://github.com/alicevision/Meshroom/pull/1489)
- [ui] Add filters to image gallery [PR](https://github.com/alicevision/Meshroom/pull/1500)
- [nodes] New node "RenderAnimatedCamera" using blender API [PR](https://github.com/alicevision/Meshroom/pull/1432)
- New node to import known poses for various file formats [PR](https://github.com/alicevision/Meshroom/pull/1475)
- New ImageMasking and MeshMasking nodes [PR](https://github.com/alicevision/Meshroom/pull/1483)
- Create Split360Images Node [PR](https://github.com/alicevision/Meshroom/pull/1464)
- New lens distortion calibration node [PR](https://github.com/alicevision/Meshroom/pull/1403)
- New experimental camera tracking pipeline [PR](https://github.com/alicevision/Meshroom/pull/1379)
- [multiview] New pipeline "Photogrammetry and Camera Tracking" [PR](https://github.com/alicevision/Meshroom/pull/1429)
- [nodes] KeyframeSelection: Rework the node and add parameters for new selection methods [PR](https://github.com/alicevision/Meshroom/pull/1880)


### Other Improvements

- [nodes] ImageProcessing: Add and hide the fringing correction in the LCP [PR](https://github.com/alicevision/Meshroom/pull/1930)
- Update highlight mode description in imageProcessing node [PR](https://github.com/alicevision/Meshroom/pull/1928)
- [ui] Prompt a warning dialog when attempting to submit an unsaved project [PR](https://github.com/alicevision/Meshroom/pull/1927)
- [panorama] force pyramid levels count in compositing [PR](https://github.com/alicevision/Meshroom/pull/1919)
- [ui] Add a new advanced menu action to load templates like regular projects [PR](https://github.com/alicevision/Meshroom/pull/1920)
- [panorama] New option to disable compositing tiling [PR](https://github.com/alicevision/Meshroom/pull/1916)
- [sfmtransform] Transformation parameter availability [PR](https://github.com/alicevision/Meshroom/pull/1876)
- Apply DCP metadata in imageProcessing [PR](https://github.com/alicevision/Meshroom/pull/1879)
- [ui] FeaturesViewer: track endpoints [PR](https://github.com/alicevision/Meshroom/pull/1838)
- LdrToHdrMerge node: Add a checkbox enabling the manual setting of the reference bracket for HDR merging [PR](https://github.com/alicevision/Meshroom/pull/1849)
- [ui] Display nodes computed in another Meshroom instance as "Computed Externally" [PR](https://github.com/alicevision/Meshroom/pull/1862)
- [ui] Use the location of the most recently imported images as the base folder for the "Import Images" dialog [PR](https://github.com/alicevision/Meshroom/pull/1864)
- [ui] GraphEditor: use maxZoom to fit on nodes [PR](https://github.com/alicevision/Meshroom/pull/1865)
- [ui] Viewer2D: support all Exif orientation tags [PR](https://github.com/alicevision/Meshroom/pull/1857)
- Use DCP by default if the database is set and create errors on missing DCP files [PR](https://github.com/alicevision/Meshroom/pull/1863)
- [ui] Load 3D Depth Map: minor improvements [PR](https://github.com/alicevision/Meshroom/pull/1852)
- [ui] Checkbox to enable/disable 8-bit viewer [PR](https://github.com/alicevision/Meshroom/pull/1858)
- Add Ripple submitter [PR](https://github.com/alicevision/Meshroom/pull/1844)
- [ui] ImageGallery: Increase the GridView's cache capacity [PR](https://github.com/alicevision/Meshroom/pull/1855)
- [ui] Reorganize the "File" menu [PR](https://github.com/alicevision/Meshroom/pull/1856)
- [nodes] rename: remove "utils" from executables names [PR](https://github.com/alicevision/Meshroom/pull/1848)
- [ui] Integrate QtOIIO into QtAliceVision [PR](https://github.com/alicevision/Meshroom/pull/1831)
- Add nl means denoising open cv in image processing node [PR](https://github.com/alicevision/Meshroom/pull/1719)
- [core] Add cgroups support to meshroom [PR](https://github.com/alicevision/Meshroom/pull/1836)
- Remove support for Python 2 [PR](https://github.com/alicevision/Meshroom/pull/1837)
- [submitters] Add an option to update the job title on submitters [PR](https://github.com/alicevision/Meshroom/pull/1824)
- [ui] GraphEditor: create new pipelines with the node menu [PR](https://github.com/alicevision/Meshroom/pull/1833)
- [bin] meshroom_batch: allow passing list of values to param overrides [PR](https://github.com/alicevision/Meshroom/pull/1811)
- [ui] ImageGallery: update the Viewer2D correctly when the GridView's current item changes [PR](https://github.com/alicevision/Meshroom/pull/1823)
- [ui] keyboard shortcut: press tab to open node menu [PR](https://github.com/alicevision/Meshroom/pull/1813)
- Update bounding box display to use the correct geometric frame [PR](https://github.com/alicevision/Meshroom/pull/1805)
- [ui] Paste nodes at the center of the Graph Editor when it does not contain the mouse [PR](https://github.com/alicevision/Meshroom/pull/1788)
- Use most recent project as base folder for file dialogs [PR](https://github.com/alicevision/Meshroom/pull/1778)
- [ui] Restrain the "copy/paste nodes" shortcuts to the GraphEditor [PR](https://github.com/alicevision/Meshroom/pull/1782)
- [core] Set the "template" flag to "false" when saving a project as a regular file [PR](https://github.com/alicevision/Meshroom/pull/1777)
- [ui] Display computation time for "running" or "finished" nodes [PR](https://github.com/alicevision/Meshroom/pull/1764)
- Removed duplicated call to findnodes [PR](https://github.com/alicevision/Meshroom/pull/1767)
- Add dedicated "minimal" mode for templates [PR](https://github.com/alicevision/Meshroom/pull/1754)
- [ui] Reduce confusion when qml loading fails [PR](https://github.com/alicevision/Meshroom/pull/1728)
- [ui] Update intrinsics table when switching between groups [PR](https://github.com/alicevision/Meshroom/pull/1755)
- [bin] batch: allow to set params inside groups [PR](https://github.com/alicevision/Meshroom/pull/1665)
- [camerainit] update parameters to use focal in mm [PR](https://github.com/alicevision/Meshroom/pull/1652)
- [bin] newNodeType: update [PR](https://github.com/alicevision/Meshroom/pull/1630)
- [minor] renderfarm submission with rez [PR](https://github.com/alicevision/Meshroom/pull/1629)
- [ui] widgets visibility options [PR](https://github.com/alicevision/Meshroom/pull/1545)
- [bin] Avoid multi-threading in non-interactive computation [PR](https://github.com/alicevision/Meshroom/pull/1553)
- [nodes] Mesh*: use file extension to choose the file format [PR](https://github.com/alicevision/Meshroom/pull/1524)
- Upgrade Texturing node and add multiples mesh file types [PR](https://github.com/alicevision/Meshroom/pull/1508)
- Optical center relative to the image center [PR](https://github.com/alicevision/Meshroom/pull/1509)
- [core] Improve project files upgrade [PR](https://github.com/alicevision/Meshroom/pull/1503)
- [ui] Add a clear images button  [PR](https://github.com/alicevision/Meshroom/pull/1467)
- [ui] highlight the edge that will be deleted [PR](https://github.com/alicevision/Meshroom/pull/1434)
- Update 2d viewer for new Track drawing mode of QtAliceVision  [PR](https://github.com/alicevision/Meshroom/pull/1435)
- Add cli script to start Meshroom on Windows [PR](https://github.com/alicevision/Meshroom/pull/1169)
- Allow replacing edges [PR](https://github.com/alicevision/Meshroom/pull/1355)
- No cmd line range arguments if we have only a single chunk [PR](https://github.com/alicevision/Meshroom/pull/1426)
- [nodes] ExportAnimatedCameras: new sfmDataFilter parameter [PR](https://github.com/alicevision/Meshroom/pull/1428)
- Node highlight radius [PR](https://github.com/alicevision/Meshroom/pull/1357)

### Bug Fixes, Build and Documentation

- [ui] Fix conditions on which the prompt asking the user to save a project before submitting it to the render farm relies [PR](https://github.com/alicevision/Meshroom/pull/1942)
- [ui] ImageGallery: Allow image drop if the active group is not computing [PR](https://github.com/alicevision/Meshroom/pull/1941)
- [ui] Viewer2D: fix displayed metadata [PR](https://github.com/alicevision/Meshroom/pull/1915)
- [setup] add all scripts in bin/ as executables [PR](https://github.com/alicevision/Meshroom/pull/1419)
- Add a unit test to check the node versions of templates [PR](https://github.com/alicevision/Meshroom/pull/1799)
- [nodes] Split360Images: update attributes to software version 2.0 [PR](https://github.com/alicevision/Meshroom/pull/1935)
- [ci] upgrade github actions rules [PR](https://github.com/alicevision/Meshroom/pull/1834)
- Update INSTALL.md [PR](https://github.com/alicevision/Meshroom/pull/1803)
- [docs] Python documentation generation using Sphinx [PR](https://github.com/alicevision/Meshroom/pull/1794)
- Documentation update : how to use Meshroom without building AliceVision [PR](https://github.com/alicevision/Meshroom/pull/1487)
- [pipelines] Panorama: Fix inputs of the "Publish" nodes [PR](https://github.com/alicevision/Meshroom/pull/1922)
- [nodes] ExportAnimatedCameras: fix output params labels [PR](https://github.com/alicevision/Meshroom/pull/1911)
- [nodes] PanoramaWarping: remove obsolete image output attributes [PR](https://github.com/alicevision/Meshroom/pull/1914)
- Fix the documentation related to Panorama nodes [PR](https://github.com/alicevision/Meshroom/pull/1917)
- Fix missing Publish nodes in templates [PR](https://github.com/alicevision/Meshroom/pull/1903)
- [ui] Intrinsics: Fix warnings and exceptions [PR](https://github.com/alicevision/Meshroom/pull/1898)
- [ui] fix thumbnail cache bugs [PR](https://github.com/alicevision/Meshroom/pull/1893)
- [ImageGallery] Match the filter selection with the gallery's display [PR](https://github.com/alicevision/Meshroom/pull/1899)
- [ui] fix "Sync Camera with Image Selection" [PR](https://github.com/alicevision/Meshroom/pull/1888)
- Fix exceptions raised when accessing attributes that either do not exist or are not associated to a graph [PR](https://github.com/alicevision/Meshroom/pull/1889)
- fix(sec): upgrade psutil to 5.6.7 [PR](https://github.com/alicevision/Meshroom/pull/1843)
- [ui] Fix all "TypeError" QML warnings [PR](https://github.com/alicevision/Meshroom/pull/1839)
- [ui] Viewer2D: fix minor issues [PR](https://github.com/alicevision/Meshroom/pull/1829)
- Fix crash when importing images with non-ascii characters in their filepath [PR](https://github.com/alicevision/Meshroom/pull/1809)
- Fix and prevent mismatches between an attribute's type and its default value's type [PR](https://github.com/alicevision/Meshroom/pull/1784)
- Fix various typos [PR](https://github.com/alicevision/Meshroom/pull/1768)
- [ui] ImageGallery: fix some minor issues [PR](https://github.com/alicevision/Meshroom/pull/1766)
- [core] fix logging of nodes loading [PR](https://github.com/alicevision/Meshroom/pull/1748)
- Fix node duplication/removal behaviour [PR](https://github.com/alicevision/Meshroom/pull/1738)
- [ui] Fix offset between the mouse's position and the tip of the edge when connecting two nodes [PR](https://github.com/alicevision/Meshroom/pull/1732)
- Fix compatibility with Python 3 [PR](https://github.com/alicevision/Meshroom/pull/1734)
- Fix stats [PR](https://github.com/alicevision/Meshroom/pull/1704)
- [ui] ImageGallery: fix missing function changeCurrentIndex [PR](https://github.com/alicevision/Meshroom/pull/1679)
- [UI] StatViewer: fix displayed unit [PR](https://github.com/alicevision/Meshroom/pull/1547)
- [ui] fix uvCenterOffset [PR](https://github.com/alicevision/Meshroom/pull/1551)
- Fix meshroom_batch [PR](https://github.com/alicevision/Meshroom/pull/1521)
- Fix incompatibility with recent cx_Freeze [PR](https://github.com/alicevision/Meshroom/pull/1480)
- [bin] meshroom_batch: fix typo in pipeline names [PR](https://github.com/alicevision/Meshroom/pull/1377)
- Removing `io_counters` from the ProcStatatistics [PR](https://github.com/alicevision/Meshroom/pull/1374)
- Fix NameError [PR](https://github.com/alicevision/Meshroom/pull/1312)
- [ui] Image Gallery: Fix the display of the intrinsics table with temporary CameraInit nodes [PR](https://github.com/alicevision/Meshroom/pull/1934)
- [ui] Correctly update the Viewer 2D when there are temporary CameraInit nodes [PR](https://github.com/alicevision/Meshroom/pull/1931)
- [ui] Clear Images: Request a graph update after resetting the viewpoints and intrinsics [PR](https://github.com/alicevision/Meshroom/pull/1929)
- [ui] Improve "Clear Images" action's behaviour and performance [PR](https://github.com/alicevision/Meshroom/pull/1897)
- [Viewer] Load and unload the SfMStats components explicitly every time they are shown and hidden  [PR](https://github.com/alicevision/Meshroom/pull/1912)
- [ui] Drag&Drop: Use a pool of threads for asynchronous intrinsics computations [PR](https://github.com/alicevision/Meshroom/pull/1896)
- [nodes] CameraInit: upgrade version following the parameters changes [PR](https://github.com/alicevision/Meshroom/pull/1874)
- [ui] app: temporary workaround for qInstallMessageHandler [PR](https://github.com/alicevision/Meshroom/pull/1873)
- [ui] ImageGallery: fix the DB path in the "Edit Sensor Database" dialog [PR](https://github.com/alicevision/Meshroom/pull/1860)
- [ui] Correctly determine if a graph is being computed locally and update nodes' statuses accordingly [PR](https://github.com/alicevision/Meshroom/pull/1832)
- [nodes] CameraInit: all intrinsics parameters should invalidate [PR](https://github.com/alicevision/Meshroom/pull/1747)
- [ci] add bug to the list of tag to skip the stale check [PR](https://github.com/alicevision/Meshroom/pull/1745)
- Fix various typos in the source code [PR](https://github.com/alicevision/Meshroom/pull/1606)
- Update ion startup [PR](https://github.com/alicevision/Meshroom/pull/1815)
- New script to launch meshroom under ion environment [PR](https://github.com/alicevision/Meshroom/pull/1783)
- [doc] fix the bibtex [PR](https://github.com/alicevision/Meshroom/pull/1537)
- [doc] readme: add citation [PR](https://github.com/alicevision/Meshroom/pull/1520)

### Contributors

Thanks to [Fabien Servant](https://github.com/servantftechnicolor), [Gregoire De Lillo](https://github.com/gregoire-dl), [Vincent Demoulin](https://github.com/demoulinv), [Thomas Zorroche](https://github.com/Thomas-Zorroche), [Povilas Kanapickas](https://github.com/p12tic), [Simone Gasparini](https://github.com/simogasp), [Candice Bentejac](https://github.com/cbentejac), [Loic Vital](https://github.com/mugulmd), [Charles Johnson](https://github.com/ChemicalXandco), [Jean Melou](https://github.com/jmelou), [Matthieu Hog](https://github.com/mh0g), [Simon Schuette](https://github.com/natowi), [Ludwig Chieng](https://github.com/ludchieng), [Vincent Scavinner](https://github.com/vscav), [Nils Landrodie](https://github.com/N0Ls), [Stella Tan](https://github.com/tanstella) for the major contributions.

Other release contributors:
[asoftbird](https://github.com/asoftbird), [DanielDelaporus](https://github.com/DanielDelaporus), [DataBeaver](https://github.com/DataBeaver), [elektrokokke](https://github.com/elektrokokke), [fabiencastan](https://github.com/fabiencastan), [Garoli](https://github.com/Garoli), [ghost](https://github.com/ghost), [hammady](https://github.com/hammady), [luzpaz](https://github.com/luzpaz), [MakersF](https://github.com/MakersF), [pen4](https://github.com/pen4), [remmel](https://github.com/remmel), [wolfgangp](https://github.com/wolfgangp)



## Release 2021.1.0 (2021/02/26)

Based on [AliceVision 2.4.0](https://github.com/alicevision/AliceVision/tree/v2.4.0).

### Release Notes Summary

 - [panorama] PanoramaCompositing: new algorithm with tiles to deal with large panoramas [PR](https://github.com/alicevision/meshroom/pull/1173)
 - [feature] Improve robustness of sift features extraction on challenging images: update default values, add new filtering and add dsp-sift variation [PR](https://github.com/alicevision/meshroom/pull/1164)
 - [ui] Improve Graph Editor UX with better visualization of nodes connections, the ability to accumulate nodes to compute locally or the ability to compute multiple branches in parallel on renderfarm with a new locking system per node, etc. [PR](https://github.com/alicevision/meshroom/pull/612)
 - [nodes] Meshing: improve mesh quality with a new post-processing. Cells empty/full status are filtered by solid angle ratio to favor smoothness. [PR](https://github.com/alicevision/meshroom/pull/1274)
 - [nodes] MeshFiltering: smoothing & filtering on subset of the geometry [PR](https://github.com/alicevision/meshroom/pull/1272)
 - [ui] Viewer: fix gain/gamma behavior and use non-linear sliders [PR](https://github.com/alicevision/meshroom/pull/1092)

### Other Improvements and Bug Fixes

 - [core] taskManager: downgrade status per chunk [PR](https://github.com/alicevision/meshroom/pull/1210)
 - [core] Improve graph dependencies: dependencies to an input parameter is not a real dependency [PR](https://github.com/alicevision/meshroom/pull/1182)
 - [nodes] Meshing: Add `addMaskHelperPoints` option [PR](https://github.com/alicevision/meshroom/pull/1273)
 - [nodes] Meshing: More control on graph cut post processing [PR](https://github.com/alicevision/meshroom/pull/1284)
 - [nodes] Meshing: new cells filtering by solid angle ratio [PR](https://github.com/alicevision/meshroom/pull/1274)
 - [nodes] Meshing: add seed and voteFilteringForWeaklySupportedSurfaces [PR](https://github.com/alicevision/meshroom/pull/1268)
 - [nodes] Add some mesh utilities nodes [PR](https://github.com/alicevision/meshroom/pull/1271)
 - [nodes] SfmTransform: new from_center_camera [PR](https://github.com/alicevision/meshroom/pull/1281)
 - [nodes] Panorama: new options to init with known poses [PR](https://github.com/alicevision/meshroom/pull/1230)
 - [nodes] FeatureMatching: add cross verification [PR](https://github.com/alicevision/meshroom/pull/1276)
 - [nodes] ExportAnimatedCamera: New option to export undistort maps in EXR format [PR](https://github.com/alicevision/meshroom/pull/1229)
 - [nodes] new wip node `LightingEstimation` to estimate spherical harmonics from normal map and albedo [PR](https://github.com/alicevision/meshroom/pull/390)
 - [nodes] CameraInit: add a boolean for white balance use [PR](https://github.com/alicevision/meshroom/pull/1162)
 - [ui] fix error on live reconstruction [PR](https://github.com/alicevision/meshroom/pull/1145)
 - [ui] init saveAs folder [PR](https://github.com/alicevision/meshroom/pull/1099)
 - [ui] add link to online documentation in 'Help' menu [PR](https://github.com/alicevision/meshroom/pull/1279)
 - [ui] New node menu categories [PR](https://github.com/alicevision/meshroom/pull/1278)


## Release 2020.1.1 (2020/10/14)

Based on [AliceVision 2.3.1](https://github.com/alicevision/AliceVision/tree/v2.3.1).

 - [core] Fix crashes on process statistics (windows-only) [PR](https://github.com/alicevision/meshroom/pull/1096)


## Release 2020.1.0 (2020/10/09)

Based on [AliceVision 2.3.0](https://github.com/alicevision/AliceVision/tree/v2.3.0).

### Release Notes Summary

 - [nodes] New Panorama Stitching nodes with support for fisheye lenses [PR](https://github.com/alicevision/meshroom/pull/639) [PR](https://github.com/alicevision/meshroom/pull/808)
 - [nodes] HDR: Largely improved HDR calibration, including new LdrToHdrSampling for optimal sample selection [PR](https://github.com/alicevision/meshroom/pull/808) [PR](https://github.com/alicevision/meshroom/pull/1016) [PR](https://github.com/alicevision/meshroom/pull/990)
 - [ui] Viewer3D: Input bounding box (Meshing) & manual transformation (SfMTransform) thanks to a new 3D Gizmo [PR](https://github.com/alicevision/meshroom/pull/978)
 - [ui] Sync 3D camera with image selection [PR](https://github.com/alicevision/meshroom/pull/633) 
 - [ui] New HDR (floating point) Image Viewer [PR](https://github.com/alicevision/meshroom/pull/795)
 - [ui] Ability to load depth maps into 2D and 3D Viewers [PR](https://github.com/alicevision/meshroom/pull/769) [PR](https://github.com/alicevision/meshroom/pull/657) 
 - [ui] New features overlay in Viewer2D allows to display tracks and landmarks [PR](https://github.com/alicevision/meshroom/pull/873) [PR](https://github.com/alicevision/meshroom/pull/1001)
 - [ui] Add SfM statistics [PR](https://github.com/alicevision/meshroom/pull/873)
 - [ui] Visual interface for node resources usage [PR](https://github.com/alicevision/meshroom/pull/564)
 - [nodes] Coordinate system alignment to specific markers or between scenes [PR](https://github.com/alicevision/meshroom/pull/652)
 - [nodes] New Sketchfab upload node [PR](https://github.com/alicevision/meshroom/pull/712)
 - [ui] Dynamic Parameters: add a new 'enabled' property to node's attributes [PR](https://github.com/alicevision/meshroom/pull/1007) [PR](https://github.com/alicevision/meshroom/pull/1027)
 - [ui] Viewer: add Camera Response Function display [PR](https://github.com/alicevision/meshroom/pull/1020) [PR](https://github.com/alicevision/meshroom/pull/1041)
 - [ui] UI improvements in the Viewer2D and ImageGallery [PR](https://github.com/alicevision/meshroom/pull/823)
 - [bin] Improve Meshroom command line [PR](https://github.com/alicevision/meshroom/pull/759) [PR](https://github.com/alicevision/meshroom/pull/632)
 - [nodes] New ImageProcessing node [PR](https://github.com/alicevision/meshroom/pull/839) [PR](https://github.com/alicevision/meshroom/pull/970) [PR](https://github.com/alicevision/meshroom/pull/941)
 - [nodes] `FeatureMatching` Add `fundamental_with_distortion` option [PR](https://github.com/alicevision/meshroom/pull/931)
 - [multiview] Declare more recognized image file extensions [PR](https://github.com/alicevision/meshroom/pull/965)
 - [multiview] More generic metadata support [PR](https://github.com/alicevision/meshroom/pull/957)

### Other Improvements and Bug Fixes

 - [nodes] CameraInit: New viewId generation and selection of allowed intrinsics [PR](https://github.com/alicevision/meshroom/pull/973)
 - [core] Avoid error during project load on border cases [PR](https://github.com/alicevision/meshroom/pull/991)
 - [core] Compatibility : Improve list of groups update [PR](https://github.com/alicevision/meshroom/pull/791)
 - [core] Invalidation hooks [PR](https://github.com/alicevision/meshroom/pull/732)
 - [core] Log manager for Python based nodes [PR](https://github.com/alicevision/meshroom/pull/631)
 - [core] new Node Update Hooks mechanism [PR](https://github.com/alicevision/meshroom/pull/733)
 - [core] Option to make chunks optional [PR](https://github.com/alicevision/meshroom/pull/778)
 - [nodes] Add methods in ImageMatching and features in StructureFromMotion and FeatureMatching [PR](https://github.com/alicevision/meshroom/pull/768)
 - [nodes] FeatureExtraction: add maxThreads argument [PR](https://github.com/alicevision/meshroom/pull/647) 
 - [nodes] Fix python nodes being blocked by log [PR](https://github.com/alicevision/meshroom/pull/783)
 - [nodes] ImageProcessing: add new option to fix non finite pixels [PR](https://github.com/alicevision/meshroom/pull/1057)
 - [nodes] Meshing: simplify input depth map folders [PR](https://github.com/alicevision/meshroom/pull/951)
 - [nodes] PanoramaCompositing: add a new graphcut option to improve seams [PR](https://github.com/alicevision/meshroom/pull/1026)
 - [nodes] PanoramaCompositing: option to select the percentage of upscaled pixels [PR](https://github.com/alicevision/meshroom/pull/1049)
 - [nodes] PanoramaInit: add debug circle detection option [PR](https://github.com/alicevision/meshroom/pull/1069)
 - [nodes] PanoramaInit: New parameter to set an extra image rotation to each camera declared the input xml [PR](https://github.com/alicevision/meshroom/pull/1046)
 - [nodes] SfmTransfer: New option to transfer intrinsics parameters [PR](https://github.com/alicevision/meshroom/pull/1053)
 - [nodes] StructureFromMotion: Add features’s scale as an option [PR](https://github.com/alicevision/meshroom/pull/822) [PR](https://github.com/alicevision/meshroom/pull/817)
 - [nodes] Texturing: add options for retopoMesh & reorganise options [PR](https://github.com/alicevision/meshroom/pull/571)
 - [nodes] Texturing: put downscale to 2 by default [PR](https://github.com/alicevision/meshroom/pull/1048)
 - [sfm] Add option to include 'unknown' feature types in ConvertSfMFormat, needed to be used on dense point cloud from the Meshing node [PR](https://github.com/alicevision/meshroom/pull/584)
 - [ui] Automatically update layout when needed [PR](https://github.com/alicevision/meshroom/pull/989)
 - [ui] Avoid crash in 3D with large panoramas [PR](https://github.com/alicevision/meshroom/pull/1061)
 - [ui] Fix graph axes naming for ram statistics [PR](https://github.com/alicevision/meshroom/pull/1033)
 - [ui] NodeEditor: minor improvements with single tab group and status table [PR](https://github.com/alicevision/meshroom/pull/637)
 - [ui] Viewer3D: Display equirectangular images as environment maps [PR](https://github.com/alicevision/meshroom/pull/731) 
 - [windows] Fix open recent broken on windows and remove unnecessary warnings [PR](https://github.com/alicevision/meshroom/pull/940)

### Build, CI, Documentation

 - [build] Fix cxFreeze version for Python 2.7 compatibility [PR](https://github.com/alicevision/meshroom/pull/634)
 - [ci] Add github Actions [PR](https://github.com/alicevision/meshroom/pull/1051)
 - [ci] AppVeyor: Update build environment and save artifacts [PR](https://github.com/alicevision/meshroom/pull/875)
 - [ci] Travis: Update environment, remove Python 2.7 & add 3.8 [PR](https://github.com/alicevision/meshroom/pull/874)
 - [docker] Clean Dockerfiles [PR](https://github.com/alicevision/meshroom/pull/1054)
 - [docker] Move to PySide2 / Qt 5.14.1
 - [docker] Fix some packaging issues of the release 2019.2.0 [PR](https://github.com/alicevision/meshroom/pull/627)
 - [github] Add exemptLabels [PR](https://github.com/alicevision/meshroom/pull/801)
 - [github] Add issue templates [PR](https://github.com/alicevision/meshroom/pull/579)
 - [github] Add template for questions / help only  [PR](https://github.com/alicevision/meshroom/pull/629)
 - [github] Added automatic stale detection and closing for issues [PR](https://github.com/alicevision/meshroom/pull/598)
 - [python] Import ABC from collections.abc [PR](https://github.com/alicevision/meshroom/pull/983)

For more details see all PR merged: https://github.com/alicevision/meshroom/milestone/10

See [AliceVision 2.3.0 Release Notes](https://github.com/alicevision/AliceVision/blob/v2.3.0/CHANGES.md) for more details about algorithmic changes.


## 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).

Release Notes Summary:
 - 3D Viewer: Load and compare multiple assets with cache mechanism and improved navigation
 - Display camera intrinsic information extracted from metadata analysis
 - Easier access to a more complete sensor database with a more reliable camera model matching algorithm.
 - Attribute Editor: Hide advanced/experimental parameters by default to improve readability and simplify access to the most useful, high-level settings.  Advanced users can still enable them to have full access to internal thresholds.
 - Graph Editor: Improved set of contextual tools with `duplicate`/`remove`/`delete data` actions with `From Here` option.
 - Nodes: Homogenization of inputs / outputs parameters
 - Meshing: Better, faster and configurable estimation of the space to reconstruct based on the sparse point cloud (new option `estimateSpaceFromSfM`). Favors high-density areas and helps removing badly defined ones.
 - Draft Meshing (no CUDA required): the result of the sparse reconstruction can now be directly meshed to get a 3D model preview without computing the depth maps.
 - MeshFiltering: Now keeps all reconstructed parts by default.
 - StructureFromMotion: Add support for rig of cameras
 - Support for reconstruction with projected light patterns and texturing with another set of images

Full Release Notes:
 - Viewer3D: New Trackball camera manipulator for improved navigation in the scene
 - Viewer3D: New library system to load multiple 3D objects of the same type simultaneously, simplifying results comparisons
 - Viewer3D: Add media loading overlay with BusyIndicator
 - Viewer3D: Points and cameras size are now configurable via dedicated sliders.
 - CameraInit: Add option to lock specific cameras intrinsics (if you have high-quality internal calibration information)
 - StructureFromMotion: Triangulate points if the input scene contains valid camera poses and intrinsics without landmarks
 - PrepareDenseScene: New `imagesFolders` option to override input images. This enables to use images with light patterns projected for SfM and MVS parts and do the Texturing with another set of images.
 - NodeLog: Cross-platform monospace display
 - Remove `CameraConnection` and `ExportUndistortedImages` nodes
 - Multi-machine parallelization of `PrepareDenseScene`
 - Meshing: Add option `estimateSpaceFromSfM` and observation angles check to better estimate the bounding box of the reconstruction and avoid useless reconstruction of the environment
 - Console: Filter non silenced, inoffensive warnings from QML + log Qt messages via Python logging
 - Command line (meshroom_photogrammetry): Add --pipeline parameter to use a pre-configured pipeline graph
 - Command line (meshroom_photogrammetry): Add possibility to provide pre-calibrated intrinsics.
 - Command line (meshroom_compute): Provide `meshroom_compute` executable in packaged release.
 - Image Gallery: Display Camera Intrinsics initialization status with detailed explanation, edit Sensor Database dialog, advanced menu to display view UIDs
 - StructureFromMotion: Expose advanced estimator parameters
 - FeatureMatching: Expose advanced estimator parameters
 - DepthMap: New option `exportIntermediateResults` disabled by default, so less data storage by default than before.
 - DepthMap: Use multiple GPUs by default if available and add `nbGPUs` param to limit it
 - Meshing: Add option `addLandmarksToTheDensePointCloud`
 - SfMTransform: New option to align on one specific camera
 - Graph Editor: Consistent read-only mode when computing, that can be unlocked in advanced settings
 - Graph Editor: Improved Node Menu: "duplicate"/"remove"/"delete data" with "From Here" accessible on the same entry via an additional button
 - Graph Editor: Confirmation popup before deleting node data
 - Graph Editor: Add "Clear Pending Status" action at Graph level
 - Graph Editor: Solo media in 3D viewer with Ctrl + double click on node/attribute
 - Param Editor: Fix several bugs related to attributes edition
 - Scene Compatibility: Improves detection of deeper compatibility issues, by adding an additional recursive (taking List/GroupAttributes children into account) exact description matching test when de-serializing a Node.

See [AliceVision 2.1.0 Release Notes](https://github.com/alicevision/AliceVision/blob/v2.1.0/CHANGES.md)
for more details about algorithmic changes.


## Release 2018.1.0 (2018.08.09)

 First release of Meshroom.  
 Based on [AliceVision 2.0.0](https://github.com/alicevision/AliceVision/tree/v2.0.0).


================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.12)
project(meshroom LANGUAGES C CXX)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type for Meshroom plugins" FORCE)
endif()

set(ALICEVISION_ROOT "$ENV{ALICEVISION_ROOT}" CACHE STRING "AliceVision root dir")
set(QT_DIR "$ENV{QT_DIR}" CACHE STRING "Qt root directory")

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")
    set(CMAKE_INSTALL_DO_STRIP ON)
else()
    set(CMAKE_INSTALL_DO_STRIP OFF)
endif()

set(CMAKE_CORE_BUILD_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_INSTALL_DO_STRIP=${CMAKE_INSTALL_DO_STRIP})

set(ALEMBIC_CMAKE_FLAGS
  -DAlembic_DIR:PATH=${ALICEVISION_ROOT}/lib/cmake/Alembic
  -DImath_DIR=${ALICEVISION_ROOT}/lib/cmake/Imath
)


include(ExternalProject)
# ==============================================================================
# GNUInstallDirs CMake module
# - Define GNU standard installation directories
# - Provides install directory variables as defined by the GNU Coding Standards.
# ==============================================================================
include(GNUInstallDirs)

# message(STATUS "QT_CMAKE_FLAGS: ${QT_CMAKE_FLAGS}")

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}$<SEMICOLON>${ALICEVISION_ROOT} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> <SOURCE_DIR>
      )
endif()



================================================
FILE: CODE_OF_CONDUCT.md
================================================
# 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


================================================
FILE: CONTRIBUTING.md
================================================
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](/docs/logo/contributing.png)

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.


================================================
FILE: COPYING.md
================================================
## Meshroom License

Meshroom is licensed under the [MPL2 license](LICENSE-MPL2.md).

## Third parties licenses

 * __AliceVision__  
   [https://github.com/alicevision/AliceVision](https://github.com/alicevision/AliceVision)  
   Copyright (c) 2018 AliceVision contributors.  
   Distributed under the [MPL2 license](https://opensource.org/licenses/MPL-2.0).
   See [COPYING](https://github.com/alicevision/AliceVision/blob/develop/COPYING.md) for full third parties licenses.

 * __Python__  
   [https://www.python.org](https://www.python.org)  
   Copyright (c) 2001-2018 Python Software Foundation.  
   Distributed under the [PSFL V2 license](https://www.python.org/download/releases/2.7/license/).

 * __Qt/PySide6__
   [https://www.qt.io](https://www.qt.io)  
   Copyright (C) 2018 The Qt Company Ltd and other contributors.  
   Distributed under the [LGPL V3 license](https://opensource.org/licenses/LGPL-3.0).

 * __QtAliceVision__  
   [https://github.com/alicevision/QtAliceVision](https://github.com/alicevision/QtAliceVision)  
   Copyright (c) 2018 AliceVision contributors.  
   Distributed under the [MPL2 license](https://opensource.org/licenses/MPL-2.0).


================================================
FILE: INSTALL.md
================================================
# Meshroom Installation
This guide will help you setup a development environment to launch and contribute to Meshroom.

## Table of Contents

1. [Use prebuilt release](#use-prebuilt-release)
2. [Installation from source code](#installation-from-source-code)
    1. [Install minimal dependencies](#install-minimal-dependencies)
        1. [Python environment](#python-environment)
        2. [Qt/PySide](#qtpyside)
    2. [Install dependencies](#install-dependencies)
        1. [AliceVision](#alicevision)
        2. [QtAliceVision](#qtalicevision)
    3. [Install plugins](#install-plugins)
        1. [mrSegmentation plugin](#mrsegmentation-plugin)
        2. [MeshroomHub](#meshroomhub)
    4. [Start Meshroom](#start-meshroom)
3. [Adding custom nodes, templates and plugins](#adding-custom-nodes-templates-and-plugins)
    1. [Custom nodes](#custom-nodes)
    2. [Custom templates](#custom-templates)
    3. [Custom plugins](#custom-plugins)


## Use prebuilt release 

To quickly run Meshroom without setting up a development environment, follow these simple steps:

1. **Download the prebuilt binaries**:
    * Visit the [Releases](https://github.com/alicevision/meshroom/releases) page.
    * Download the latest release that is suitable for your operating system.
2. **Extract the archive**:
    * On Windows: right-click on the .zip file and select "Extract All", or run `unzip Meshroom-x.y.z.zip` in a terminal.
    * On Linux: in a terminal, run `tar -xzvf Meshroom.x.y.z.tar.gz`.
3. **Run Meshroom**: in the extracted folder, double-click on the "Meshroom" executable to launch it.

## Installation from source code

Get the source code and install runtime requirements:
```bash
git clone --recursive https://github.com/alicevision/Meshroom.git
cd meshroom
```

### Install minimal dependencies

To use Meshroom nodal system without any visualization option, you can rely on a minimal set of dependencies.


#### Python environment

* Windows: Python 3 (>=3.9)
* Linux: Python 3 (>=3.9)

To install all the requirements for runtime, development and packaging, simply run:
```bash
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.

> [!NOTE]
> It is recommended to use a [virtual Python environment](https://docs.python.org/3.9/library/venv.html), like `python -m venv meshroom_venv`.


#### Qt/PySide

* PySide >= 6.7

> [!WARNING]
> For PySide 6.8.0 and over, the following error may occur when leaving Meshroom's homepage: `Cannot load /path/to/pip/install/PySide6/qml/QtQuick/Scene3D/qtquickscene3dplugin.dll: specified module cannot be found`.
> This is caused by Qt63DQuickScene3D.dll which seems to be missing from the pip distribution, but can be retrieved from a standard Qt installation. 
> On recent Linux systems such as Ubuntu 25, this can be resolved by installing `libqt63dquickscene3d6` using the package manager.
> Alternatively:
> - On Windows, the DLL for MSVC2022_64 can be directly downloaded [here](https://drive.google.com/uc?export=download&id=1vhPDmDQJJfM_hBD7KVqRfh8tiqTCN7Jv). It then needs to be placed in `/path/to/pip/install/PySide6`.
> - On Linux, the .so (here, Rocky9-based) can be directly downloaded [here](https://drive.google.com/uc?export=download&id=1dq7rm_Egc-sQF6j6_E55f60INyxt1ega). It then needs to be placed in `/path/to/pip/install/PySide6/Qt/qml/QtQuick/Scene3D`.


### Install dependencies

You can install AliceVision to get access to 3D Computer Vision and Machine Learning nodes and pipelines. Additionally, you can install QtAliceVision to get access to Image and 3D data visualization within Meshroom.

#### AliceVision

[AliceVision](https://github.com/alicevision/AliceVision)'s binaries must be in the path while running Meshroom.

The easiest way is to download prebuild binaries from the release. You can download a [Release](https://github.com/alicevision/AliceVision/releases) or extract files from a recent AliceVision build on [Dockerhub](https://hub.docker.com/r/alicevision/alicevision).

Alternatively, you can build AliceVision manually from the source code by following this [guide](https://github.com/alicevision/AliceVision/blob/develop/INSTALL.md).

Then add the `bin` and `lib` folders into your `PATH` (and `LD_LIBRARY_PATH` on Linux/macOS) environment variables.

The following environment variable must always be set with the location of AliceVision's install directory:
```
ALICEVISION_ROOT=/path/to/AliceVision/install/directory
```

AliceVision provides nodes and templates for Meshroom, which need to be declared to Meshroom with the following environment variables:
```
MESHROOM_NODES_PATH={ALICEVISION_ROOT}/share/meshroom
MESHROOM_PIPELINE_TEMPLATES_PATH={ALICEVISION_ROOT}/share/meshroom
```

Meshroom also relies on [specific files provided with AliceVision](https://github.com/alicevision/AliceVision/blob/develop/INSTALL.md#environment-variables-to-set-for-meshroom), set through environment variables.
If these variables are not set, Meshroom will by default look for them in `{ALICEVISION_ROOT}/share/aliceVision`.

> [!NOTE]
> You may need to checkout the corresponding Meshroom version/tag to avoid versions incompatibilities.


#### QtAliceVision

[QtAliceVision](https://github.com/alicevision/QtAliceVision), an additional Qt plugin, can be built to extend Meshroom UI features.

Note that it is optional but highly recommended.

This plugin uses AliceVision to load and visualize intermediate reconstruction files and OpenImageIO as backend to read images (including RAW/EXR).
It also adds support for Alembic file loading in Meshroom's 3D viewport, which allows to visualize sparse reconstruction results (point clouds and cameras).

```
QML2_IMPORT_PATH=/path/to/QtAliceVision/install/qml
QT_PLUGIN_PATH=/path/to/QtAliceVision/install
```


### Install plugins

#### mrSegmentation plugin

Some templates provided by AliceVision contain nodes that are not packaged with AliceVision.
These nodes are part of the mrSegmentation plugin, which can be found [here](https://github.com/MeshroomHub/mrSegmentation).

To build and install mrSegmentation, follow this [guide](https://github.com/MeshroomHub/mrSegmentation/blob/main/INSTALL.md).

For mrSegmentation nodes to be correctly detected by Meshroom, the following environment variable should be set:
```
MESHROOM_PLUGINS_PATH=/path/to/mrSegmentation
```

#### MeshroomHub

You can find many experimental Machine Learning plugins on [MeshroomHub](https://github.com/meshroomHub).


### Start Meshroom

 - __Launch the User Interface__

```bash
# Windows
set PYTHONPATH=%CD% && python meshroom/ui
# Linux/macOS
PYTHONPATH=$PWD python meshroom/ui
```

On Ubuntu, you may have conflicts between native drivers and mesa drivers. In that case, you need to force usage of native drivers by adding them to the LD_LIBRARY_PATH:
`LD_LIBRARY_PATH=/usr/lib/nvidia-340 PYTHONPATH=$PWD python meshroom/ui`
You may need to adjust the folder `/usr/lib/nvidia-340` with the correct driver version.

 - __Launch a 3D reconstruction in command line__

```bash
# Windows: set PYTHONPATH=%CD% &&
# Linux/macOS: PYTHONPATH=$PWD
python bin/meshroom_batch --input INPUT_IMAGES_FOLDER --output OUTPUT_FOLDER
```

## Adding custom nodes, templates and plugins

In addition to the nodes and templates provided by Meshroom and AliceVision, custom ones can be created, loaded by, and used in Meshroom.

### Custom nodes

Nodes need to be provided to Meshroom as Python modules, using the `MESHROOM_NODES_PATH` environment variable.

For example, to add a set of three custom nodes (`CustomNodeA`, `CustomNodeB` and `CustomNodeC`) to Meshroom, a Python
module containing these nodes must be created:
```
├── folderA
│   ├── customNodes
│   │   ├── __init__.py
│   │   ├── CustomNodeA.py
│   │   ├── CustomNodeB.py
│   │   └── CustomNodeC.py
├── folderB
```

Its containing folder must then be added to `MESHROOM_NODES_PATH`:
- On Windows:
  ```
  set MESHROOM_NODES_PATH=/path/to/folderA;%MESHROOM_NODES_PATH%
  ```
- On Linux:
  ```
  export MESHROOM_NODES_PATH=/path/to/folderA:$MESHROOM_NODES_PATH
  ```

> [!NOTE]
> A valid Meshroom node is a Python file that contains a class inheriting `meshroom.core.desc.BaseNode`.
> Before loading a node, Meshroom checks whether its description (the content of its class) is valid.
> If it is not, the node is rejected with an error log describing which part is invalid.

### Custom templates

The list of pipelines can also be enriched with custom templates, that are declared to Meshroom with the environment
variable `MESHROOM_PIPELINE_TEMPLATES_PATH`.

For example, if a couple of custom templates are saved in a folder "customTemplates", the variable should be set as follows:
- On Windows:
  ```
  set MESHROOM_PIPELINE_TEMPLATES_PATH=/path/to/customTemplate;%MESHROOM_PIPELINE_TEMPLATES_PATH%
  ```
- On Linux:
  ```
  export MESHROOM_PIPELINE_TEMPLATES_PATH=/path/to/customTemplates:$MESHROOM_PIPELINE_TEMPLATES_PATH
  ```

> [!TIP]
> A template can be a Meshroom graph of any type, but it is generally expected to be a graph saved in "minimal mode".
> In "minimal mode", the .mg file only contains, for each node of the graph, the attributes that have non-default values.
> To save a graph in "minimal mode", use the `File > Advanced > Save As Template` menu.

### Custom plugins

To add and use custom plugins with Meshroom, follow [**INSTALL_PLUGINS.md**](INSTALL_PLUGINS.md).


================================================
FILE: INSTALL_PLUGINS.md
================================================
# Meshroom plugins installation

Plugins are collections of nodes and templates with their own dependencies. Plugin maintainers have flexibility in organizing their code, as Meshroom only requires a few directories to recognize nodes and pipelines.

## Required Structure

- **Meshroom folder**: All plugin nodes and templates must be placed within a `./meshroom/` directory
- **Configuration file (optional)**: `./meshroom/config.json` file allows to define custom environment variables for the plugin  
- **Virtual environment (optional)**: If you have specific dependencies, you can create a virtual environment named "venv" in a folder and this Python will be used when computing the node.

## Example Structure

For a plugin named "customPlugin", Meshroom expects this layout:
```
├── customPlugin/                # Plugin root folder
│   ├── meshroom/                # Meshroom nodes and pipelines
│   │   ├── customNodes1/        # Set of nodes
│   │   │   ├── __init__.py      # Required to be a python module
│   │   │   ├── NodeA.py
│   │   │   ├── NodeB.py
│   │   ├── customNodes2/        # Another set of nodes if needed
│   │   │   ├── __init__.py
│   │   │   ├── NodeC.py
│   │   │   ├── NodeD.py
│   │   ├── customTemplate1.mg   # Ready-to-use pipeline templates
│   │   ├── customTemplate2.mg
│   │   ├── config.json          # Optional plugin configuration file
│   ├── venv/                    # Optional virtual environment with installed dependencies
│   └── ...                      # Custom code (any structure)
```

## Loading the Plugin

The "customPlugin" will be loaded automatically when Meshroom starts by setting the `MESHROOM_PLUGINS_PATH` environment variable:
- On Windows:
  ```
  set MESHROOM_PLUGINS_PATH=/path/to/customPlugin;%MESHROOM_PLUGINS_PATH%
  ```
- On Linux:
  ```
  export MESHROOM_PLUGINS_PATH=/path/to/customPlugin:$MESHROOM_PLUGINS_PATH
  ```


================================================
FILE: LICENSE-MPL2.md
================================================
Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to
    the creation of, or owns Covered Software.

1.2. "Contributor Version"
    means the combination of the Contributions of others (if any) used
    by a Contributor and that particular Contributor's Contribution.

1.3. "Contribution"
    means Covered Software of a particular Contributor.

1.4. "Covered Software"
    means Source Code Form to which the initial Contributor has attached
    the notice in Exhibit A, the Executable Form of such Source Code
    Form, and Modifications of such Source Code Form, in each case
    including portions thereof.

1.5. "Incompatible With Secondary Licenses"
    means

    (a) that the initial Contributor has attached the notice described
        in Exhibit B to the Covered Software; or

    (b) that the Covered Software was made available under the terms of
        version 1.1 or earlier of the License, but not also under the
        terms of a Secondary License.

1.6. "Executable Form"
    means any form of the work other than Source Code Form.

1.7. "Larger Work"
    means a work that combines Covered Software with other material, in 
    a separate file or files, that is not Covered Software.

1.8. "License"
    means this document.

1.9. "Licensable"
    means having the right to grant, to the maximum extent possible,
    whether at the time of the initial grant or subsequently, any and
    all of the rights conveyed by this License.

1.10. "Modifications"
    means any of the following:

    (a) any file in Source Code Form that results from an addition to,
        deletion from, or modification of the contents of Covered
        Software; or

    (b) any new file in Source Code Form that contains any Covered
        Software.

1.11. "Patent Claims" of a Contributor
    means any patent claim(s), including without limitation, method,
    process, and apparatus claims, in any patent Licensable by such
    Contributor that would be infringed, but for the grant of the
    License, by the making, using, selling, offering for sale, having
    made, import, or transfer of either its Contributions or its
    Contributor Version.

1.12. "Secondary License"
    means either the GNU General Public License, Version 2.0, the GNU
    Lesser General Public License, Version 2.1, the GNU Affero General
    Public License, Version 3.0, or any later versions of those
    licenses.

1.13. "Source Code Form"
    means the form of the work preferred for making modifications.

1.14. "You" (or "Your")
    means an individual or a legal entity exercising rights under this
    License. For legal entities, "You" includes any entity that
    controls, is controlled by, or is under common control with You. For
    purposes of this definition, "control" means (a) the power, direct
    or indirect, to cause the direction or management of such entity,
    whether by contract or otherwise, or (b) ownership of more than
    fifty percent (50%) of the outstanding shares or beneficial
    ownership of such entity.

2. License Grants and Conditions
--------------------------------

2.1. Grants

Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:

(a) under intellectual property rights (other than patent or trademark)
    Licensable by such Contributor to use, reproduce, make available,
    modify, display, perform, distribute, and otherwise exploit its
    Contributions, either on an unmodified basis, with Modifications, or
    as part of a Larger Work; and

(b) under Patent Claims of such Contributor to make, use, sell, offer
    for sale, have made, import, and otherwise transfer either its
    Contributions or its Contributor Version.

2.2. Effective Date

The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.

2.3. Limitations on Grant Scope

The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:

(a) for any code that a Contributor has removed from Covered Software;
    or

(b) for infringements caused by: (i) Your and any other third party's
    modifications of Covered Software, or (ii) the combination of its
    Contributions with other software (except as part of its Contributor
    Version); or

(c) under Patent Claims infringed by Covered Software in the absence of
    its Contributions.

This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).

2.4. Subsequent Licenses

No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).

2.5. Representation

Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.

2.6. Fair Use

This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.

2.7. Conditions

Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.

3. Responsibilities
-------------------

3.1. Distribution of Source Form

All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.

3.2. Distribution of Executable Form

If You distribute Covered Software in Executable Form then:

(a) such Covered Software must also be made available in Source Code
    Form, as described in Section 3.1, and You must inform recipients of
    the Executable Form how they can obtain a copy of such Source Code
    Form by reasonable means in a timely manner, at a charge no more
    than the cost of distribution to the recipient; and

(b) You may distribute such Executable Form under the terms of this
    License, or sublicense it under different terms, provided that the
    license for the Executable Form does not attempt to limit or alter
    the recipients' rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).

3.4. Notices

You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.

4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------

If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.

5. Termination
--------------

5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.

************************************************************************
*                                                                      *
*  6. Disclaimer of Warranty                                           *
*  -------------------------                                           *
*                                                                      *
*  Covered Software is provided under this License on an "as is"       *
*  basis, without warranty of any kind, either expressed, implied, or  *
*  statutory, including, without limitation, warranties that the       *
*  Covered Software is free of defects, merchantable, fit for a        *
*  particular purpose or non-infringing. The entire risk as to the     *
*  quality and performance of the Covered Software is with You.        *
*  Should any Covered Software prove defective in any respect, You     *
*  (not any Contributor) assume the cost of any necessary servicing,   *
*  repair, or correction. This disclaimer of warranty constitutes an   *
*  essential part of this License. No use of any Covered Software is   *
*  authorized under this License except under this disclaimer.         *
*                                                                      *
************************************************************************

************************************************************************
*                                                                      *
*  7. Limitation of Liability                                          *
*  --------------------------                                          *
*                                                                      *
*  Under no circumstances and under no legal theory, whether tort      *
*  (including negligence), contract, or otherwise, shall any           *
*  Contributor, or anyone who distributes Covered Software as          *
*  permitted above, be liable to You for any direct, indirect,         *
*  special, incidental, or consequential damages of any character      *
*  including, without limitation, damages for lost profits, loss of    *
*  goodwill, work stoppage, computer failure or malfunction, or any    *
*  and all other commercial damages or losses, even if such party      *
*  shall have been informed of the possibility of such damages. This   *
*  limitation of liability shall not apply to liability for death or   *
*  personal injury resulting from such party's negligence to the       *
*  extent applicable law prohibits such limitation. Some               *
*  jurisdictions do not allow the exclusion or limitation of           *
*  incidental or consequential damages, so this exclusion and          *
*  limitation may not apply to You.                                    *
*                                                                      *
************************************************************************

8. Litigation
-------------

Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.

9. Miscellaneous
----------------

This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.

10. Versions of the License
---------------------------

10.1. New Versions

Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.

10.2. Effect of New Versions

You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.

10.3. Modified Versions

If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses

If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice
-------------------------------------------

  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------

  This Source Code Form is "Incompatible With Secondary Licenses", as
  defined by the Mozilla Public License, v. 2.0.


================================================
FILE: NODE_DEVELOPMENT.md
================================================
# Meshroom Node Development


## Node Creation

This guide shows how to implement three common Meshroom node types: Python-based `Node`, external-executable `CommandLineNode`, and non-computational `InputNode`.

### 1. Node (Pure Python)

Use `desc.Node` when your logic runs in Python.
Implement `process(self, node)` to produce outputs.

#### Example: Generate a file

```python
from meshroom.core import desc

class GenerateFile(desc.Node):
    category = "Custom"
    inputs = [
        desc.File(name="input", label="Input", description="", value=""),
        desc.IntParam(name="count", label="Count", description="", value=1),
    ]
    outputs = [
        desc.File(name="output", label="Output", description="", value="{nodeCacheFolder}/out.txt"),
    ]

    def process(self, node):
        # Implement your computation logic here
        with open(node.output.value, "w") as f:
            f.write(f"Processed {node.input.value} ({node.count.value})\n")
```
In this example, the path of the output file is an expression that will always be up-to-date in Meshroom and the corresponding file will be created by the node's computation.

#### Example: Compute values

```python
class AddInt(desc.Node):
    category = "Custom"
    inputs = [
        desc.IntParam(name="a", label="Count", description="", value=1),
        desc.IntParam(name="b", label="Count", description="", value=2),
    ]
    outputs = [
        # Dynamic output value
        desc.IntParam(name="outputInt", label="Count", description="", value=None),
    ]

    def process(self, node):
        # Implement your logic here; set output attributes.
        node.outputInt.value = node.a.value + node.b.value
```
In this example, the output param value will ve valid in Meshroom only at the end of the node computation.


### 2. CommandLineNode (external executable)

Use `desc.CommandLineNode` to wrap an external binary. Define a `commandLine` template with `{variable}` placeholders. Meshroom expands it via `buildCommandLine(chunk)` and executes the result.

#### Example

```python
from meshroom.core import desc

class MyCmdNode(desc.CommandLineNode):
    commandLine = "mytool --input {inputValue} --output {outputValue}"

    inputs = [
        desc.File(name="input", label="Input", description="", value=""),
    ]
    outputs = [
        desc.File(name="output", label="Output", description="", value="{nodeCacheFolder}/out.txt"),
    ]
```

### 3. InputNode (non-computational placeholder)

Use `desc.InputNode` for nodes that only hold data and do not run computation.

#### Example: Input Node

```python
from meshroom.core import desc

class MyInputNode(desc.InputNode):
    category = "Custom"
    inputs = [
        desc.File(name="file", label="File", description="", value=""),
    ]
```

#### Example: Input Node with Initialization

The InitNodes could be combined with `desc.InitNode` to implement `initialize` for command line batching or initialization from drag&drop.

```python
from meshroom.core import desc

class MyInputNode(desc.InputNode, desc.InitNode):
    category = "Custom"
    inputs = [
        desc.File(name="file", label="File", description="", value=""),
    ]

    def initialize(self, node, inputs, recursiveInputs):
        # Populate attributes from command-line inputs.
        if inputs:
            node.file.value = inputs[0]
```


## Attribute Types Available in Meshroom Nodes

Meshroom provides several attribute types you can use in a node’s `inputs` and `outputs`. They are defined in `meshroom.core.desc` and organized into basic parameters, compound containers, geometry helpers, and shape annotations.

### Basic Parameters

| Type | Description | Common Options |
|------|-------------|----------------|
| `BoolParam` | Boolean toggle. | `value` (bool) |
| `IntParam` | Integer with optional range. | `range=(min, max, step)` |
| `FloatParam` | Floating-point with optional range. | `range=(min, max, step)` |
| `StringParam` | Free-form string. | `value` (str) |
| `File` | File or directory path. | `value` (str) |
| `ChoiceParam` | Single or multiple selection from a list. | `values=[...]`, `exclusive` |
| `ColorParam` | RGBA color. | `value` (list/tuple) |
| `PushButtonParam` | Action button in UI; no stored value. | N/A |

### Compound Containers

| Type | Description | Key Args |
|------|-------------|----------|
| `ListAttribute` | Homogeneous list of elements defined by `elementDesc`. | `elementDesc`, `joinChar` |
| `GroupAttribute` | Fixed collection of heterogeneous child attributes (`items`). | `items`, `joinChar` |

Both inherit from `Attribute` and support nesting (lists of groups, groups with lists).

#### Example: Parameter Types

```python
from meshroom.core import desc

class ParameterTypesSample(desc.Node):
    category = "Custom"
    inputs = [
        desc.BoolParam(name="boolParam", label="Boolean", description="", value=False),
        desc.IntParam(name="intParam", label="Integer", description="", value=10, range=(0, 100, 1)),
        desc.FloatParam(name="floatParam", label="Float", description="", value=3.14, range=(0.0, 10.0, 0.1)),
        desc.StringParam(name="stringParam", label="String", description="", value="default"),
        desc.File(name="fileParam", label="File", description="", value=""),
        desc.ChoiceParam(name="choiceParam", label="Choice", description="", value="opt1", values=["opt1", "opt2", "opt3"], exclusive=True),
        desc.ColorParam(name="colorParam", label="Color", description="", value=[1.0, 0.0, 0.0, 1.0]),
        desc.PushButtonParam(name="buttonParam", label="Button", description=""),
        desc.ListAttribute(
            name="fileList",
            label="File List",
            description="",
            elementDesc=desc.File(name="file", label="File", description="", value=""),
            joinChar=" "
        ),
        desc.GroupAttribute(
            name="inputGroup",
            label="Input Group",
            description="Group with bool, int, string and file",
            items=[
                desc.BoolParam(name="groupBool", label="Boolean", description="", value=True),
                desc.IntParam(name="groupInt", label="Integer", description="", value=42, range=(0, 100, 1)),
                desc.StringParam(name="groupString", label="String", description="", value="groupValue"),
                desc.File(name="groupFile", label="File", description="", value="")
            ]
        )
    ]
    outputs = [
        desc.File(name="outputFile", label="Output File", description="", value="{nodeCacheFolder}/output.txt")
    ]

    def process(self, node):
        with open(node.outputFile.value, "w") as f:
            f.write(f"{node.boolParam.value},{node.intParam.value},{node.floatParam.value},{node.stringParam.value},{node.fileParam.value},{node.choiceParam.value},{node.colorParam.value},{len(node.fileList.value)},{node.inputGroup.groupBool.value},{node.inputGroup.groupInt.value},{node.inputGroup.groupString.value},{node.inputGroup.groupFile.value}\n")
```

### Geometry Helpers

Convenient groups for 2D geometry, built from `GroupAttribute` and `FloatParam`:

| Type | Fields | Example |
|------|--------|---------|
| `Size2d` | `width`, `height` (float) | `Size2d(name="sz", ..., width=1920, height=1080)` |
| `Vec2d` | `x`, `y` (float) | `Vec2d(name="vec", ..., x=0.0, y=1.0)` |


### Attribute Properties

- **Name**: Used to access attributes from script.
- **Label**: Label used for the display in the Node Editor.
- **Description**: Tooltip used in the Node Editor.
- **Range constraints**: `IntParam` and `FloatParam` accept `range=(min, max, step)` to bound values.
- **Enabled**: Parameters can be enabled or disabled dynamically (using a lamda).
- **Advanced**: Parameters can be declared as advanced parameters, so they are hidden by default but could be activated in the UI for experts or developpers.
- **Exposed** in the GraphEditor: Files are exposed in the nodal view by default, other type are hidden by default, but it can be customized per attribute.
- **Dynamic outputs**: Set `value=None` in an output attribute to mark it as dynamically computed.
- **Keyable attributes**: Enable per-key values (e.g., per-view) with `keyable=True` and `keyType`. Supported on basic params and shapes.
- **JoinChar**: Controls string serialization for `ListAttribute` and `GroupAttribute` when used in command lines.


### Advanced: Shape Parameters

Used for UI overlays/annotations; they support `keyable` per-view values:

| Type | Description | Example |
|------|-------------|---------|
| `Point2d` | 2D point (`x`, `y`). | `Point2d(name="pt", ...)` |
| `Line2d` | 2D line defined by two points. | `Line2d(name="ln", ...)` |
| `Rectangle` | Axis-aligned rectangle. | `Rectangle(name="rect", ...)` |
| `Circle` | Circle with center and radius. | `Circle(name="c", ...)` |
| `ShapeList` | List of a single shape type (`shape`). | `ShapeList(name="pts", shape=Point2d(...))` |


## Node Descriptor Properties

| Property | Type | Description | Default |
|----------|------|-------------|---------|
| Class documentation | str | Detailed description of the node's purpose | "" |
| `category` | str | Organizational category in the node library | "Other" |
| `cpu` | Level or callable | CPU resource requirement level | Level.NORMAL |
| `ram` | Level or callable | Memory resource requirement level | Level.NORMAL |
| `gpu` | Level or callable | GPU resource requirement level | Level.NONE |
| `size` | Size object | Parallelization size configuration | StaticNodeSize(1) |
| `parallelization` | Parallelization | Chunk division settings | None |

### Example: Basic Node with Properties

```python
class SampleNode(desc.Node):
    """This is the Node documentation that will be available in the Node Editor."""

    category = "Custom Node Category"  # Used in the UI to group nodes in the menu
    size = desc.DynamicNodeSize("inputFiles")  # Size used to define the number of chunks for parallelization

    # Resource levels (`cpu`, `gpu`, `ram`) are used for farm scheduling on suitable hardware
    cpu = Level.NORMAL  # Need standard amount of CPU
    ram = Level.HIGH  # Requires large amount of RAM
    gpu = Level.NONE  # Do not need GPU
```

Resource levels can also be set as callables receiving a node instance, allowing them to be
determined dynamically based on the node's input parameters:

```python
class SampleNode(desc.Node):
    # Dynamically require a GPU based on an input parameter
    gpu = lambda node: desc.Level.INTENSIVE if node.attribute("useGpu").value else desc.Level.NONE
```

The resolved value for a node instance is accessible via the `cpu`, `gpu`, and `ram` properties
on the node object (e.g. `node.cpu`, `node.gpu`, `node.ram`).


## Parallelizing a Node

Meshroom enables node parallelization by splitting work into independent chunks that can be distributed on multiple workstations on compute farm. Configure parallelization by setting `size` and `parallelization` properties on your node descriptor.

### Configuration

#### Size Strategies
- **StaticNodeSize**: Fixed number of tasks
- **DynamicNodeSize**: Size based on an input attribute (list length or linked node size)
- **MultiDynamicNodeSize**: Sum of sizes from multiple input attributes
- **callable**: A callable (e.g. a lambda) receiving the node instance: `lambda node: node.sizeInput.value`

#### Parallelization Settings
Set `parallelization` to control chunk division:
- `blockSize`: Items per chunk
- `staticNbBlocks`: Fixed number of chunks (alternative to blockSize)

### Implementation Examples

#### CommandLineNode with Static Parallelization
```python
class MyParallelCmd(desc.CommandLineNode):
    commandLine = "mytool --input {inputValue} --output {outputValue}"
    commandLineRange = "--range {rangeStart} {rangeEnd}"  # Specific way to precise the range to compute on the command line
    
    size = desc.StaticNodeSize(100)  # 100 items total
    parallelization = desc.Parallelization(blockSize=10)  # 10 chunks of 10 items
```

#### Node with Dynamic Size
```python
class MyParallelNode(desc.Node):
    size = desc.DynamicNodeSize("inputList")  # Size matches list length
    parallelization = desc.Parallelization(blockSize=3)  # Create a chunk every 3 elements in the list
    
    def processChunk(self, chunk):
        # Process chunk.range.iteration
        pass
```

### Range and Chunk Behavior

Each chunk receives a `Range` object with:
- `iteration`: Chunk index
- `start`/`end`: Item indices for this chunk
- `blockSize`: Items per chunk
- `nbBlocks`: Total chunks

For `CommandLineNode`, range placeholders are automatically injected into `commandLineRange` when `node.isParallelized` and `node.size > 1`.


## Installation

See [INSTALL_PLUGINS.md](./INSTALL_PLUGINS.md)



================================================
FILE: README.md
================================================
# ![Meshroom - 3D Reconstruction Software](/docs/logo/banner-meshroom.png)

Meshroom is an open-source, node-based visual programming framework—a flexible toolbox for creating, managing, and executing complex data processing pipelines.

Meshroom uses a nodal system where each node represents a specific operation, and output attributes can seamlessly feed into subsequent steps. When a node’s attribute is modified, only the affected downstream nodes are invalidated, while cached intermediate results are reused to minimize unnecessary computation.

Meshroom supports both local and distributed execution, enabling efficient parallel processing on render farms.
It also includes interactive widgets for visualizing images and 3D data. Official releases come with built-in plugins for computer vision and machine learning tasks.

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/alicevision/Meshroom)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2997/badge)](https://bestpractices.coreinfrastructure.org/projects/2997)
[![Build status](https://github.com/alicevision/Meshroom/actions/workflows/continuous-integration.yml/badge.svg?branch=develop)](https://github.com/alicevision/Meshroom/actions/workflows/continuous-integration.yml)


# Get the project

You can [download pre-compiled binaries for the latest release](https://github.com/alicevision/meshroom/releases).

If you want to build it yourself, see [**INSTALL.md**](INSTALL.md) to setup the project and pre-requisites.

To use Meshroom with custom plugins, see [**INSTALL_PLUGINS.md**](INSTALL_PLUGINS.md).


# Concepts

- **Graph**: A collection of interconnected nodes that defines the sequence of operations to represent your complete data processing workflow.
- **Nodes**: The fundamental building blocks, each performing a specific task. Nodes are connected through edges that represent the flow of data between them.
- **Attributes**: Parameters that control how each node behaves. When an attribute is modified, it triggers the invalidation of all connected downstream nodes while preserving cached intermediate results.
- **Templates**: Ready-to-use pipeline configurations provided by plugins. You can customize existing templates or create and save your own.
- **Local / Renderfarm**: Choose between local processing or distributed computation on render farms. You can monitor progress, review logs, track resource consumption, and use both modes simultaneously as Meshroom manages node locking during external computation.
- **Custom Plugins**: Extend Meshroom's capabilities by creating your own nodes in Python or by integrating external command-line tools.


# User Interface

The Meshroom UI is divided into several key areas:
 - **Graph Editor**: The central area where nodes are placed and connected to form a processing pipeline.
 - **Node Editor**: It contains multiple tabs with:
   - **Attributes**: Displays the attributes and parameters of the selected node.
   - **Log**: Displays execution logs and error messages.
   - **Statistics**: Displays resource consumption
   - **Status**: Display some technical information on the node (workstation, start/end time, etc.)
   - **Documentation**: Node Documentation.
   - **Notes**: Change label or put some notes on the node to know why it’s used in this graph.
 - **2D & 3D Viewer**: Visualizes the output of certain nodes.
 - **Image Gallery**: Visualize the list of input files.


# Manual and Tutorials
 - [Meshroom Manual](https://meshroom-manual.readthedocs.io)
 - [Meshroom FAQ](https://github.com/alicevision/meshroom/wiki)


# Plugins bundled by default

## AliceVision Plugin

[AliceVision Website](http://alicevision.org)

[AliceVision Repository](https://github.com/alicevision/AliceVision)

AliceVision provides state-of-the-art 3D Computer Vision and Machine Learning algorithms that analyze and understand image content to transform collections of regular 2D photographs into detailed 3D models, camera positions, and scene geometry. Born from collaboration between academia and industry, it delivers research-grade algorithms with production-level robustness and quality.
The AliceVision plugin offers comprehensive pipelines for:
- **3D Reconstruction** from multi-view images ([pipeline overview](http://alicevision.github.io/#photogrammetry), [results on Sketchfab](http://sketchfab.com/AliceVision))
- **Camera Tracking** for camera motion estimation
- **HDR Fusion** from multi-bracketed photography
- **Panorama Stitching** including fisheye support and motorized head systems
- **Photometric Stereo** for geometric reconstruction from a single view with multiple lightings
- **Multi-View Photometric Stereo** combining photogrammetry with photometric stereo


## Segmentation Plugin

[MrSegmentation](https://github.com/meshroomHub/mrSegmentation): A set of nodes for AI-powered image segmentation from natural language prompts. The plugin leverages foundation models to automatically identify and isolate specific objects or regions in images based on textual descriptions, enabling intuitive content-aware processing workflows.


# Other plugins

See [MeshroomHub](https://github.com/meshroomHub) for more plugins.

## DepthEstimation Plugin

[MrDepthEstimation](https://github.com/meshroomHub/mrDepthEstimation): A set of nodes for AI-based monocular depth estimation from image sequences. The plugin leverages deep learning models to predict depth information from single images, enabling depth estimation in new scenarios.


## RoMa Plugin

[MrRoma](https://github.com/meshroomHub/mrRoma): A set of nodes for RoMa (robust dense feature matching).
The plugin leverages foundation models to provide pixel-dense correspondence estimation with reliable certainty maps, enabling robust matching even under extreme variations in scale, illumination, viewpoint, and texture.


## GSplat Plugin

[MrGSplat](https://github.com/meshroomHub/mrGSplat): A set of nodes for 3D Gaussian Splatting reconstruction. The plugin integrates seamlessly with AliceVision's photogrammetry pipeline, allowing users to create Gaussian splat representations from multi-view images and to render new viewpoints.


## Research Plugin

[Meshroom Research](https://github.com/meshroomHub/MeshroomResearch)
A research-oriented plugin for evaluating and benchmarking cutting-edge Machine Learning algorithms in 3D Computer Vision. The plugin provides experimental nodes and evaluation frameworks to test new methodologies, compare algorithm performance, and validate research innovations before integration into production pipelines.


## MicMac Plugin

[MeshroomMicMac](https://github.com/alicevision/MeshroomMicMac)
An exploratory plugin integrating MicMac's photogrammetric algorithms into Meshroom workflows. MicMac is a mature open-source photogrammetric software developed by the National Institute of Geographic and Forestry Information (French Mapping Agency, IGN) and the National School of Geographic Sciences (ENSG) within the LASTIG lab, offering specialized tools for surveying and mapping applications. While the plugin does not yet support Meshroom's full invalidation system, it provides fully functional pipelines for users seeking MicMac's specific photogrammetric capabilities.


## Geolocation Plugin

[MrGeolocation](https://github.com/meshroomHub/mrGeolocation)
A plugin for geospatial integration that extracts GPS data from photographs and downloads contextual geographic information. The plugin automatically places 3D reconstructions within their real-world geographical environment by retrieving worldwide 2D maps (OpenStreetMap), global elevation models (NASA datasets), and high-resolution 3D Lidar models where available (France via IGN open data). This enables accurate georeferencing and contextual visualization of photogrammetric reconstructions.


# License

The project is released under MPLv2, see [**COPYING.md**](COPYING.md).


# Citation
  ```
  @inproceedings{alicevision2021,
    title={{A}liceVision {M}eshroom: An open-source {3D} reconstruction pipeline},
    author={Carsten Griwodz and Simone Gasparini and Lilian Calvet and Pierre Gurdjos and Fabien Castan and Benoit Maujean and Gregoire De Lillo and Yann Lanthony},
    booktitle={Proceedings of the 12th ACM Multimedia Systems Conference - {MMSys '21}},
    doi = {10.1145/3458305.3478443},
    publisher = {ACM Press},
    year = {2021}
  }
  ```


# Contributing
We welcome contributions! Check out our [Contribution Guidelines](CONTRIBUTING.md) to get started. Whether you are a developer, designer, or documentation enthusiast, there is a place for you in the Meshroom community.


# Contact

Use the public mailing-list to ask questions or request features. It is also a good place for informal discussions like sharing results, interesting related technologies or publications: [forum@alicevision.org](https://groups.google.com/g/alicevision)

You can also contact the core team privately on: [team@alicevision.org](mailto:team@alicevision.org).


================================================
FILE: RELEASING.md
================================================

### Versioning

Version = MAJOR (>=1 year), MINOR (>= 1 month), PATCH

Version Status = Develop / Release


### Git

Branches
    develop: active development branch
    master: latest release
    vMAJOR.MINOR: release branch

Tags
    vMAJOR.MINOR.PATCH: tag for each release


### Release Process

 - Prepare the AliceVision release: https://github.com/alicevision/AliceVision
 - Update INSTALL.md and requirements.txt if needed
 - Source code
   - Create branch from develop: "rcMAJOR.MINOR"
   - Modify version in code, version status to RELEASE (meshroom/__init__.py)
   - Update the version of all the templates so their version corresponds to the release
   - Create Release note (using https://github.com/cbentejac/github-generate-release-note)
     - ```
	   ./github-generate-release-note.py -o alicevision -r Meshroom -m "Meshroom MAJOR.MINOR.PATCH" --highlights majorFeature feature --label-include bugfix ci,scope:doc,scope:build -s updated-asc
	   ```
   - PR to develop: "Release MAJOR.MINOR"
 - Build
   - Build docker & push to dockerhub
   - Build windows
 - Git
   - Merge "rcMAJOR.MINOR" into "develop"
   - Push "develop" into "master"
   - Create branch: vMAJOR.MINOR
   - Create tag: vMAJOR.MINOR.PATCH on Meshroom, qtAliceVision
   - Create branch from develop: "startMAJOR.MINOR"
 - Upload binaries on fosshub
 - Fill up Github release note
 - Prepare "develop" for new developments
   - Upgrade MINOR and reset version status to Develop
   - PR to develop: "Start Development MAJOR.MINOR"
 - Communication
   - Email on mailing-list: alicevision@googlegroups.com
   - Message on linkedin: https://www.linkedin.com/groups/13573776
   - Message on twitter: https://twitter.com/alicevision_org

### Upgrade a Release with a PATCH version

 - Source code
   - Create branch from rcMAJOR.MINOR: "rcMAJOR.MINOR.PATCH"
   - Cherry-pick specific commits or rebase required PR
   - Modify version in code
   - Update release note
 - Build step
 - Uploads
 - Github release note
 - Email on mailing-list



================================================
FILE: WINDOWS_EXE.md
================================================
# Meshroom executable generation on Windows

This describes how to generate Meshroom's executable on Windows. This does not include any plugin, only Meshroom itself.

## Set helper environment variables

```bash
set SRC_ROOT=/path/to/Meshroom/repository
set PYTHON=/path/to/Python/Python311/python.exe
set RELEASE_VERSION=2026.x.x
set MESHROOM_EXE_DIR=/path/to/Meshroom-%RELEASE_VERSION%
```

## Meshroom build

### Prepare environment

```bash
cd %SRC_ROOT%
%PYTHON% -m venv venv
call venv\Scripts\activate.bat
pip install -r requirements.txt -r dev_requirements.txt
```

### Executable generation

```bash
python setup.py install_exe -d %MESHROOM_EXE_DIR%
deactivate
```

> [!IMPORTANT]
> PySide6 >= 6.8.0 misses a DLL in its pip installation. If it is not manually added, Meshroom will run into the following error when attempting to leave the homepage and displaying the application:
> `Cannot load /path/to/pip/install/PySide6/qml/QtQuick/Scene3D/qtquickscene3dplugin.dll: specified module cannot be found`.
> The missing DLL is Qt63DQuickScene3D.dll and can be downloaded [here](https://drive.google.com/uc?export=download&id=1vhPDmDQJJfM_hBD7KVqRfh8tiqTCN7Jv) (for MSVC2022_64). Alternatively, it can be retrieved from any Qt local installation.
> It needs to be placed in `%MESHROOM_EXE_DIR%/lib/PySide6`.

### Clean the packages

Get rid of all the things that are unnecessary for Meshroom. This will lighten the final package.

```bash
cd %MESHROOM_EXE_DIR%/lib/PySide6
del /s /q Qt6Web*.dll Qt6Designer*.dll *.exe
rmdir /s /q resources translations typesystems examples include
```


================================================
FILE: bin/meshroom_batch
================================================
#!/usr/bin/env python
import argparse
import json
import logging
import os
import re
import sys

import meshroom.core.graph
from meshroom.common import strtobool
from meshroom import setupEnvironment, logStringToPython

def parseInitInputs(inputs: list[str]) -> dict[str, str]:
    """Utility method for parsing the input and inputRecursive arguments.
    Args:
        inputs: Command line values in format 'nodeName=value' or just 'value' to set it on all init nodes

    Returns:
        Dict mapping node names (or empty string if it applies to all) to their input values

    Raises:
        ValueError: If input format is invalid
    """
    mapInputs = {}
    for inp in inputs:
        # Stop after the first occurrence
        inputGroup = inp.split('=', 1)
        nodeName = inputGroup[0] if len(inputGroup) == 2 else ""
        nodeInputs = inputGroup[-1].split(',')
        mapInputs[nodeName] = [os.path.abspath(path) for path in nodeInputs]
    return mapInputs


setupEnvironment()

meshroom.core.initPipelines()

parser = argparse.ArgumentParser(
    prog='meshroom_batch',
    description='Launch a Meshroom pipeline from command line.',
    add_help=True,
    formatter_class=argparse.RawTextHelpFormatter,
    epilog='''
Examples:
  1. Process a pipeline in command line:
     meshroom_batch -p cameraTracking -i /input/path -o /output/path -s /path/to/store/the/project.mg

  2. Submit a pipeline on renderfarm:
     meshroom_batch -p cameraTracking -i /input/path -o /output/path -s /path/to/store/the/project.mg --submit

  See "meshroom_compute -h" to compute an existing project from command line.

Additional Resources:
  Website:      https://alicevision.org
  Manual:       https://meshroom-manual.readthedocs.io
  Forum:        https://groups.google.com/g/alicevision
  Tutorials:    https://www.youtube.com/c/AliceVisionOrg
  Contribute:   https://github.com/alicevision/Meshroom
''')


general_group = parser.add_argument_group('General Options')
general_group.add_argument(
    '-i', '--input', 
    metavar='FILE FOLDER NODEINSTANCE=FILE,FOLDER,...', 
    type=str,
    nargs='*',
    default=[],
    help='Input files and folders to process. '
         'When multiple Init Nodes exist in the pipeline, inputs are applied to all by default. '
         'To target a specific Init Node, use the format Node1=input1,input2 Node2=input3')

general_group.add_argument(
    '-I', '--inputRecursive',
    metavar='FOLDER FOLDER_2 NODEINSTANCE=FOLDER,FOLDER_2,...',
    type=str,
    nargs='*',
    default=[],
    help='Recursively scan these directories for input files.')

general_group.add_argument(
    '-p', '--pipeline',
    metavar='FILE.mg / PIPELINE',
    type=str,
    default=os.environ.get('MESHROOM_DEFAULT_PIPELINE', 'photogrammetry'),
    help='Template pipeline among those listed or a Meshroom file containing a custom pipeline '
         'to run on input images:\n' +
         '\n'.join(['    - ' + p for p in meshroom.core.pipelineTemplates]))

general_group.add_argument(
    '-o', '--output', 
    metavar='FOLDER COPYFILES_INSTANCE=FOLDER',
    type=str,
    required=False,
    nargs='*',
    help='Output folder for copying results. '
         'Sets output folder for all CopyFiles nodes, or target specific nodes using COPYFILES_INSTANCE=FOLDER.')

general_group.add_argument(
    '-s', '--save', metavar='FILE', type=str, required=False,
    help='Save the configured Meshroom graph to a project file. It will setup the cache folder accordingly. ')

general_group.add_argument(
    '--submit', help='Submit on renderfarm instead of local computation.',
    action='store_true')

general_group.add_argument(
    '-v', '--verbose',
    help='Set the verbosity level for logging:\n'
         '  - fatal: Show only critical errors.\n'
         '  - error: Show errors only.\n'
         '  - warning: Show warnings and errors.\n'
         '  - info: Show standard informational messages.\n'
         '  - debug: Show detailed debug information.\n'
         '  - trace: Show all messages, including trace-level details.',
    default=os.environ.get('MESHROOM_VERBOSE', 'warning'),
    choices=['fatal', 'error', 'warning', 'info', 'debug', 'trace'])

advanced_group = parser.add_argument_group('Advanced Options')
advanced_group.add_argument(
    '--overrides', metavar='SETTINGS', type=str, default=None,
    help='A JSON file containing the graph parameters override.')

advanced_group.add_argument(
    '--paramOverrides', metavar='NODETYPE:param=value NODEINSTANCE.param=value', type=str, default=None, nargs='*',
    help='Override specific parameters directly from the command line (by node type or by node names).')

advanced_group.add_argument(
    '--compute', metavar='<yes/no>', type=lambda x: bool(strtobool(x)), default=True, required=False,
    help='You can set it to <no/false/0> to disable the computation.')

advanced_group.add_argument(
    '--toNode', metavar='NODE', type=str, nargs='*',
    default=None,
    help='Process the node(s) with its dependencies.')

advanced_group.add_argument(
    '--forceStatus', help='Force computation if status is RUNNING or SUBMITTED.',
    action='store_true')
advanced_group.add_argument(
    '--forceCompute', help='Compute in all cases even if already computed.',
    action='store_true')

advanced_group.add_argument(
    "--submitLabel",
    type=str,
    default=os.environ.get('MESHROOM_SUBMIT_LABEL', '[Meshroom] {projectName}'),
    help="Label of a node when submitted on renderfarm.")

advanced_group.add_argument(
    '--submitter',
    type=str,
    default='Tractor',
    help='Execute job with a specific submitter.')

args = parser.parse_args()

logging.getLogger().setLevel(logStringToPython[args.verbose])

meshroom.core.initPlugins()
meshroom.core.initNodes()

graph = meshroom.core.graph.Graph(name=args.pipeline)

with meshroom.core.graph.GraphModification(graph):
    # initialize template pipeline
    loweredPipelineTemplates = {k.lower(): v for k, v in meshroom.core.pipelineTemplates.items()}
    if args.pipeline.lower() in loweredPipelineTemplates:
        graph.initFromTemplate(loweredPipelineTemplates[args.pipeline.lower()],
                               copyOutputs=True if args.output else False)
    else:
        # custom pipeline
        graph.initFromTemplate(args.pipeline, copyOutputs=True if args.output else False)

    if args.input:
        # get init nodes
        initNodes = graph.findInitNodes()
        initNodesNames = [n.getName() for n in initNodes]

        # parse inputs for each init node
        mapInput = parseInitInputs(args.input)

        # parse recursive inputs for each init node
        mapInputRecursive = parseInitInputs(args.inputRecursive)

        # check that input nodes exist in the pipeline template
        for nodeName in mapInput.keys() | mapInputRecursive.keys():
            if nodeName and nodeName not in initNodesNames:
                raise RuntimeError(f"Failed to find the Init Node '{nodeName}' in your pipeline.\nAvailable Init Nodes: {initNodesNames}")

        # feed inputs (recursive and non-recursive paths) to corresponding init nodes
        for initNode in initNodes:
            nodeName = initNode.getName()
            if nodeName not in mapInput | mapInputRecursive and \
               "" not in mapInput | mapInputRecursive:
                continue

            # Retrieve input per node and inputs for all init node types
            input = mapInput.get(nodeName, []) + mapInput.get("", [])
            # Retrieve recursive inputs
            inputRec = mapInputRecursive.get(nodeName, []) + mapInputRecursive.get("", [])
            initNode.nodeDesc.initialize(initNode, input, inputRec)

    if not graph.canComputeLeaves:
        raise RuntimeError("Graph cannot be computed. Check for compatibility issues.")

    if args.verbose:
        graph.setVerbose(args.verbose)

    if args.output:
        # The output folders for CopyFiles nodes can be set as follows:
        # - for each node, the output folder is specified following the
        #   "CopyFiles_name=/output/folder/path" convention.
        # - a path is provided without specifying which CopyFiles node should be set with it:
        #   all the CopyFiles nodes will be set with it.
        # - some CopyFiles nodes have their path specified, and another path is provided
        #   without specifying a node: all CopyFiles nodes with dedicated will have their own
        #   output folders set, and those which have not been specified will be set with the
        #   other path.
        # - some CopyFiles nodes have their output folder specified while others do not: all
        #   the nodes with specified folders will use the provided values, and those without
        #   any will be set with the output folder of the first specified CopyFiles node.
        # - several output folders are provided without specifying any node: the last one will
        #   be used to set all the CopyFiles nodes' output folders.

        # Check that there is at least one CopyFiles node
        copyNodes = graph.nodesOfType('CopyFiles')
        if len(copyNodes) == 0:
            raise RuntimeError('meshroom_batch requires a pipeline graph with at least ' +
                               'one CopyFiles node, none found.')

        reExtract = re.compile(r'(\w+)=(.*)')  # NodeName=value
        globalCopyPath = ''
        for p in args.output:
            result = reExtract.match(p)
            if not result:  # If the argument is only a path, set it for the global path
                globalCopyPath = p
                continue

            node, value = result.groups()
            for i, n in enumerate(copyNodes):  # Find the correct CopyFiles node in the list
                if n.name == node:  # If found, set the value, and remove it from the list
                    n.output.value = value
                    copyNodes.pop(i)
                    if globalCopyPath == '':  # Fallback in case some nodes would have no path
                        globalCopyPath = value
                    break

        for n in copyNodes:  # Set the remaining CopyPath nodes with the global path
            n.output.value = globalCopyPath
    else:
        print(f'No output set, results will be available in the cache folder: "{graph.cacheDir}"')

    if args.overrides:
        with open(args.overrides, encoding='utf-8', errors='ignore') as f:
            data = json.load(f)
            for nodeName, overrides in data.items():
                for attrName, value in overrides.items():
                    graph.findNode(nodeName).attribute(attrName).value = value

    if args.paramOverrides:
        print("\n")
        reExtract = re.compile(r'(\w+)([:.])(\w[\w.]*)=(.*)')
        for p in args.paramOverrides:
            result = reExtract.match(p)
            if not result:
                raise ValueError('Invalid param override: ' + str(p))
            node, t, param, value = result.groups()
            if t == ':':
                nodesOfType = graph.nodesOfType(node)
                if not nodesOfType:
                    raise ValueError(f'No node with the type "{node}" in the scene.')
                for n in nodesOfType:
                    print(f'Overrides {node}.{param}={value}')
                    n.attribute(param).value = value
            elif t == '.':
                print(f'Overrides {node}.{param}={value}')
                graph.findNode(node).attribute(param).value = value
            else:
                raise ValueError('Invalid param override: ' + str(p))
        print("\n")

if args.save:
    graph.save(args.save)
    print(f'File successfully saved: "{args.save}"')

# find end nodes (None will compute all graph)
toNodes = graph.findNodes(args.toNode) if args.toNode else None

if args.submit:
    meshroom.core.initSubmitters()
    if not args.save:
        raise ValueError('Need to save the project to file to submit on renderfarm.')
    # submit on renderfarm
    meshroom.core.graph.submit(args.save, args.submitter, toNode=args.toNode,
                               submitLabel=args.submitLabel)
elif args.compute:
    # find end nodes (None will compute all graph)
    toNodes = graph.findNodes(args.toNode) if args.toNode else None
    # start computation
    meshroom.core.graph.executeGraph(graph, toNodes=toNodes, forceCompute=args.forceCompute,
                                     forceStatus=args.forceStatus)


================================================
FILE: bin/meshroom_compute
================================================
#!/usr/bin/env python
import argparse
import logging
import os
import sys
from typing import NoReturn

try:
    import meshroom
except Exception:
    # If meshroom module is not in the PYTHONPATH, add our root using the relative path
    import pathlib
    meshroomRootFolder = pathlib.Path(__file__).parent.parent.resolve()
    sys.path.append(meshroomRootFolder)
    import meshroom
meshroom.setupEnvironment()

import meshroom.core
import meshroom.core.graph
from meshroom.core.node import Status


parser = argparse.ArgumentParser(description='Execute a Graph of processes.')
parser.add_argument('graphFile', metavar='GRAPHFILE.mg', type=str,
                    help='Filepath to a graph file.')
parser.add_argument('--node', metavar='NODE_NAME', type=str,
                    help='Process the node. It will generate an error if the dependencies are not already computed.')
parser.add_argument('--toNode', metavar='NODE_NAME', type=str,
                    help='Process the node with its dependencies.')
parser.add_argument('--inCurrentEnv', help='Execute process in current env without creating a dedicated runtime environment.',
                    action='store_true')
parser.add_argument('--forceStatus', help='Force computation if status is RUNNING or SUBMITTED.',
                    action='store_true')
parser.add_argument('--forceCompute', help='Compute in all cases even if already computed.',
                    action='store_true')
parser.add_argument('--extern', help='Use this option when you compute externally after submission to a render farm from meshroom.',
                    action='store_true')
parser.add_argument('--cache', metavar='FOLDER', type=str,
                    default=None,
                    help='Override the cache folder')
parser.add_argument('-v', '--verbose',
                    help='Set the verbosity level for logging:\n'
                            '  - fatal: Show only critical errors.\n'
                            '  - error: Show errors only.\n'
                            '  - warning: Show warnings and errors.\n'
                            '  - info: Show standard informational messages.\n'
                            '  - debug: Show detailed debug information.\n'
                            '  - trace: Show all messages, including trace-level details.',
                    default=os.environ.get('MESHROOM_VERBOSE', 'info'),
                    choices=['fatal', 'error', 'warning', 'info', 'debug', 'trace'])

parser.add_argument('-i', '--iteration', type=int,
                    default=-1, help='')

args = parser.parse_args()

# Setup the verbose level
if args.extern:
    # For extern computation, we want to focus on the node computation log.
    # So, we avoid polluting the log with general warning about plugins, versions of nodes in file, etc.
    logging.getLogger().setLevel(level=logging.ERROR)
else:
    logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose])

meshroom.core.initPlugins()
meshroom.core.initNodes()
meshroom.core.initSubmitters()

graph = meshroom.core.graph.loadGraph(args.graphFile)
if args.cache:
    graph.cacheDir = args.cache
graph.update()


def killRunningJob(node) -> NoReturn:
    """ Kills current job and try to avoid job restarting """
    jobInfo = node.nodeStatus.jobInfo
    submitterName = jobInfo.get("submitterName")
    if not submitterName:
        sys.exit(meshroom.MeshroomExitStatus.ERROR_NO_RETRY)
    from meshroom.core import submitters
    for subName, sub in submitters.items():
        if submitterName == subName:
            sub.killRunningJob()
            break
    sys.exit(meshroom.MeshroomExitStatus.ERROR_NO_RETRY)


if args.node:
    node = graph.findNode(args.node)
    node.updateStatusFromCache()
    submittedStatuses = [Status.RUNNING]

    if node.isCompatibilityNode:
        print(f'{node.name} is in Compatibility Mode and cannot be computed.')
        print(f'Compatibility issue: {node.issueDetails}')
        sys.exit(1)

    # Execute the node
    if not args.extern:
        # If running as "extern", the task is supposed to have the status SUBMITTED.
        # If not running as "extern", the SUBMITTED status should generate a warning.
        submittedStatuses.append(Status.SUBMITTED)

    if args.iteration >= 0 and not node._chunksCreated:
        print(f"Error: Computing chunk {args.iteration} of node {node} before chunks have been created. " \
              f"See file: \"{node.nodeStatusFile}\".")
        sys.exit(-1)

    if node.isInputNode:
        print(f"InputNode: No computation to do.")
        sys.exit(0)

    if not args.forceStatus and not args.forceCompute:
        if args.iteration != -1:
            chunks = [node.chunks[args.iteration]]
        else:
            chunks = node.chunks
        for chunk in chunks:
            if chunk.status.status in submittedStatuses:
                # Particular case for the local isolated, the node status is set to RUNNING by the submitter directly.
                # We ensure that no other instance has started to compute, by checking that the computeSessionUid is empty.
                if chunk.node.getMrNodeType() == meshroom.core.MrNodeType.NODE and \
                    not chunk.status.computeSessionUid and node._nodeStatus.submitterSessionUid:
                    continue
                print(f'Warning: Node is already submitted with status "{chunk.status.status.name}". See file: "{chunk.statusFile}". ExecMode: {chunk.status.execMode.name}, computeSessionUid: {chunk.status.computeSessionUid}, submitterSessionUid: {node._nodeStatus.submitterSessionUid}')
                # sys.exit(-1)

    if args.extern:
        # Restore the log level
        logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose])

    node.prepareLogger(args.iteration)
    node.preprocess()
    if args.iteration != -1:
        chunk = node.chunks[args.iteration]
        if chunk._status.status == Status.STOPPED:
            print(f"Chunk {chunk}: status is STOPPED")
            killRunningJob(node)
        chunk.process(args.forceCompute, args.inCurrentEnv)
    else:
        if node.nodeStatus.status == Status.STOPPED:
            print(f"Node {node}: status is STOPPED")
            killRunningJob(node)
        node.createChunks()
        node.process(args.forceCompute, args.inCurrentEnv)
    node.postprocess()
    node.restoreLogger()
else:
    if args.iteration != -1:
        print('Error: "--iteration" only makes sense when used with "--node".')
        sys.exit(-1)
    toNodes = None
    if args.toNode:
        toNodes = graph.findNodes([args.toNode])

    meshroom.core.graph.executeGraph(graph, toNodes=toNodes, forceCompute=args.forceCompute, forceStatus=args.forceStatus)


================================================
FILE: bin/meshroom_createChunks
================================================
#!/usr/bin/env python

"""
This is a script used to wrap the process of processing a node on the farm
It will handle chunk creation and create all the jobs for these chunks
If the submitter cannot create chunks, then it will process the chunks serially
in the current process
"""

import argparse
import logging
import os
import sys
try:
    import meshroom
except Exception:
    # If meshroom module is not in the PYTHONPATH, add our root using the relative path
    import pathlib
    meshroomRootFolder = pathlib.Path(__file__).parent.parent.resolve()
    sys.path.append(meshroomRootFolder)
    import meshroom
meshroom.setupEnvironment()

import meshroom.core
import meshroom.core.graph
from meshroom.core import submitters
from meshroom.core.submitter import SubmitterOptionsEnum
from meshroom.core.node import Status


parser = argparse.ArgumentParser(description='Execute a Graph of processes.')
parser.add_argument('graphFile', metavar='GRAPHFILE.mg', type=str,
                    help='Filepath to a graph file.')

parser.add_argument('--submitter', type=str, required=True,
                    help='Name of the submitter used to create the job.')
parser.add_argument('--node', metavar='NODE_NAME', type=str, required=True,
                    help='Process the node. It will generate an error if the dependencies are not already computed.')
parser.add_argument('--inCurrentEnv', help='Execute process in current env without creating a dedicated runtime environment.',
                    action='store_true')
parser.add_argument('--forceStatus', help='Force computation if status is RUNNING or SUBMITTED.',
                    action='store_true')
parser.add_argument('--forceCompute', help='Compute in all cases even if already computed.',
                    action='store_true')
parser.add_argument('--extern', help='Use this option when you compute externally after submission to a render farm from meshroom.',
                    action='store_true')
parser.add_argument('--cache', metavar='FOLDER', type=str,
                    default=None,
                    help='Override the cache folder')
parser.add_argument('-v', '--verbose',
                    help='Set the verbosity level for logging:\n'
                            '  - fatal: Show only critical errors.\n'
                            '  - error: Show errors only.\n'
                            '  - warning: Show warnings and errors.\n'
                            '  - info: Show standard informational messages.\n'
                            '  - debug: Show detailed debug information.\n'
                            '  - trace: Show all messages, including trace-level details.',
                    default=os.environ.get('MESHROOM_VERBOSE', 'info'),
                    choices=['fatal', 'error', 'warning', 'info', 'debug', 'trace'])

args = parser.parse_args()

# For extern computation, we want to focus on the node computation log.
# So, we avoid polluting the log with general warning about plugins, versions of nodes in file, etc.
logging.getLogger().setLevel(level=logging.INFO)

meshroom.core.initPlugins()
meshroom.core.initNodes()
meshroom.core.initSubmitters()  # Required to spool child job

graph = meshroom.core.graph.loadGraph(args.graphFile)
if args.cache:
    graph.cacheDir = args.cache
graph.update()

# Execute the node
node = graph.findNode(args.node)
submittedStatuses = [Status.RUNNING]

# Find submitter
submitter = None
# It's required if we want to spool chunks on different machines
for subName, sub in submitters.items():
    if args.submitter == subName:
        submitter = sub
        break

if node._nodeStatus.status in (Status.STOPPED, Status.KILLED):
    logging.error("Node status is STOPPED or KILLED.")
    if submitter:
        submitter.killRunningJob()
    sys.exit(meshroom.MeshroomExitStatus.ERROR_NO_RETRY)

if not node._chunksCreated:
    # Create node chunks
    # Once created we don't have to do it again even if we relaunch the job
    node.createChunks()
    # Set the chunks statuses
    for chunk in node._chunks:
        if args.forceCompute or chunk._status.status != Status.SUCCESS:
            hasChunkToLaunch = True
            chunk._status.setNode(node)
            chunk._status.initExternSubmit()
            chunk.upgradeStatusFile()

# Get chunks to process in the current process
chunksToProcess = []
if submitter:
    if not submitter._options.includes(SubmitterOptionsEnum.EDIT_TASKS):
        chunksToProcess = node.chunks
else:
    # Cannot retrieve job -> execute process serially
    chunksToProcess = node.chunks

logging.info(f"[MeshroomCreateChunks] Chunks to process here : {chunksToProcess}")

if not args.forceStatus and not args.forceCompute:
    for chunk in chunksToProcess:
        if chunk.status.status in submittedStatuses:
            # Particular case for the local isolated, the node status is set to RUNNING by the submitter directly.
            # We ensure that no other instance has started to compute, by checking that the sessicomputeSessionUidonUid is empty.
            if chunk.node.getMrNodeType() == meshroom.core.MrNodeType.NODE and \
                not chunk.status.computeSessionUid and node._nodeStatus.submitterSessionUid:
                continue
            logging.warning(
                f"[MeshroomCreateChunks] Node is already submitted with status " \
                f"\"{chunk.status.status.name}\". See file: \"{chunk.statusFile}\". " \
                f"ExecMode: {chunk.status.execMode.name}, computeSessionUid: {chunk.status.computeSessionUid}, " \
                f"submitterSessionUid: {node._nodeStatus.submitterSessionUid}")

if chunksToProcess:
    node.prepareLogger()
    node.preprocess()
    for chunk in chunksToProcess:
        logging.info(f"[MeshroomCreateChunks] process chunk {chunk}")
        chunk.process(args.forceCompute, args.inCurrentEnv)
    node.postprocess()
    node.restoreLogger()
else:
    logging.info(f"[MeshroomCreateChunks] -> create job to process chunks {[c for c in node.chunks]}")
    submitter.createChunkTask(node, graphFile=args.graphFile, cache=args.cache, 
                              forceStatus=args.forceStatus, forceCompute=args.forceCompute)

# Restore the log level
logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose])


================================================
FILE: bin/meshroom_newNodeType
================================================
#!/usr/bin/env python

import argparse
import os
import re
import sys
import shlex
from pprint import pprint

def trim(s):
    """
    All repetition of any kind of space is replaced by a single space
    and remove trailing space at beginning or end.
    """
    # regex to replace all space groups by a single space
    # use split() to remove trailing space at beginning/end
    return re.sub(r'\s+', ' ', s).strip()


def quotesForStrings(valueStr):
    """
    Return the input string with quotes if it cannot be cast into another builtin type.
    """
    v = valueStr
    try:
        int(valueStr)
    except ValueError:
        try:
            float(valueStr)
        except ValueError:
            if "'" in valueStr:
                v = f"'''{valueStr}'''"
            else:
                v = f"'{valueStr}'"
    return v

def convertToLabel(name):
    camelCaseToLabel = re.sub('()([A-Z][a-z]*?)', r'\1 \2', name)
    snakeToLabel = ' '.join(word.capitalize() for word in camelCaseToLabel.split('_'))
    snakeToLabel = ' '.join(word.capitalize() for word in snakeToLabel.split(' '))
    return snakeToLabel

def is_int(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

def is_float(s):
    try:
        float(s)
        return True
    except ValueError:
        return False


parser = argparse.ArgumentParser(description='Create a new Node Type')
parser.add_argument('node', metavar='NODE_NAME', type=str,
                    help='New node name')
parser.add_argument('bin', metavar='CMDLINE', type=str,
                    default=None,
                    help='Input executable')
parser.add_argument('--output', metavar='DIR', type=str,
                    default=os.path.dirname(__file__),
                    help='Output plugin folder')
parser.add_argument('--parser', metavar='PARSER', type=str,
                    default='boost',
                    help='Select the parser adapted for your command line: {boost,cmdLineLib,basic}.')
parser.add_argument("--force", help="Allows to overwrite the output plugin file.",
                    action="store_true")

args = parser.parse_args()

inputCmdLineDoc = None
soft = "{nodeType}"
if args.bin:
    soft = args.bin
    import subprocess
    proc = subprocess.Popen(args=shlex.split(args.bin) + ['--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    inputCmdLineDoc = stdout if stdout else stderr
elif sys.stdin.isatty():
    inputCmdLineDoc = ''.join([line for line in sys.stdin])

if not inputCmdLineDoc:
    print('No input documentation.')
    print(f'Usage: YOUR_COMMAND --help | {os.path.splitext(__file__)[0]}')
    sys.exit(-1)


fileStr = '''import sys
from meshroom.core import desc


class __COMMANDNAME__(desc.CommandLineNode):
    commandLine = '__SOFT__ {allParams}'
'''.replace('__COMMANDNAME__', args.node).replace('__SOFT__', soft)


print(inputCmdLineDoc)

args_re = None
if args.parser == 'boost':
    args_re = re.compile(
        r'^\s+'  # space(s)
        r'(?:-(?P<argShortName>\w+)\|?)?'  # potential argument short name
        r'\s*\[?'  # potential '['
        r'\s*--(?P<argLongName>\w+)'  # argument long name
        r'(?:\s*\])?' # potential ']'
        r'(?:\s+(?P<arg>\w+)?)?'  # potential arg
        r'(?:\s+\(\=(?P<defaultValue>.+)\))?'  # potential default value
        r'\s+(?P<descriptionFirst>.*?)\n'  # end of the line
        r'(?P<descriptionNext>(?:\s+[^-\s].+?\n)*)'  # next documentation lines
        , re.MULTILINE)
elif args.parser == 'cmdLineLib':
    args_re = re.compile(
        '^'
        r'\[' # '['
        r'-(?P<argShortName>\w+)'  # argument short name
        r'\|'
        r'--(?P<argLongName>\w+)'  # argument long name
        r'(?:\s+(?P<arg>\w+)?)?'  # potential arg
        r'\]' # ']'
        r'()' # no default value
        r'(?P<descriptionFirst>.*?)?\n' # end of the line
        r'(?P<descriptionNext>(?:[^\[\w].+?\n)*)' # next documentation lines
        , re.MULTILINE)
elif args.parser == 'basic':
    args_re = re.compile(r'()--(?P<argLongName>\w+)()()()()')
else:
    print(f'Error: Unknown input parser "{args.parser}"')
    sys.exit(-1)

choiceValues1_re = re.compile(r'\* (?P<value>\w+):')
choiceValues2_re = re.compile(r'\((?P<value>.+?)\)')
choiceValues3_re = re.compile(r'\{(?P<value>.+?)\}')

cmdLineArgs = args_re.findall(inputCmdLineDoc.decode('utf-8'))

print('='*80)
pprint(cmdLineArgs)

outputNodeStr = ''
inputNodeStr = ''

for cmdLineArg in cmdLineArgs:
    shortName = cmdLineArg[0]
    longName = cmdLineArg[1]
    if
Download .txt
gitextract_yg7v1w9_/

├── .codecov.yml
├── .git-blame-ignore-revs
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── question_help.md
│   ├── pull_request_template.md
│   ├── stale.yml
│   └── workflows/
│       └── continuous-integration.yml
├── .gitignore
├── .readthedocs.yaml
├── CHANGES.md
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── COPYING.md
├── INSTALL.md
├── INSTALL_PLUGINS.md
├── LICENSE-MPL2.md
├── NODE_DEVELOPMENT.md
├── README.md
├── RELEASING.md
├── WINDOWS_EXE.md
├── bin/
│   ├── meshroom_batch
│   ├── meshroom_compute
│   ├── meshroom_createChunks
│   ├── meshroom_newNodeType
│   ├── meshroom_statistics
│   ├── meshroom_status
│   └── meshroom_submit
├── dev_requirements.txt
├── docker/
│   ├── Dockerfile_rocky
│   ├── Dockerfile_rocky_deps
│   ├── Dockerfile_ubuntu
│   ├── Dockerfile_ubuntu_deps
│   ├── build-all.sh
│   ├── build-rocky.sh
│   ├── build-ubuntu.sh
│   ├── extract-rocky.sh
│   └── extract-ubuntu.sh
├── docs/
│   ├── .gitignore
│   ├── Makefile
│   ├── README.md
│   ├── make.bat
│   ├── requirements.txt
│   └── source/
│       ├── _ext/
│       │   ├── __init__.py
│       │   ├── fetch_md.py
│       │   ├── meshroom_doc.py
│       │   └── utils.py
│       ├── _templates/
│       │   └── autosummary/
│       │       ├── class.rst
│       │       └── module.rst
│       ├── api.rst
│       ├── changes.rst
│       ├── conf.py
│       ├── index.rst
│       └── install.rst
├── localfarm/
│   ├── __init__.py
│   ├── localFarm.py
│   ├── localFarmBackend.py
│   ├── localFarmLauncher.py
│   └── test.py
├── meshroom/
│   ├── __init__.py
│   ├── common/
│   │   ├── PySignal.py
│   │   ├── __init__.py
│   │   ├── core.py
│   │   ├── deprecated.py
│   │   └── qt.py
│   ├── core/
│   │   ├── __init__.py
│   │   ├── attribute.py
│   │   ├── cgroup.py
│   │   ├── desc/
│   │   │   ├── __init__.py
│   │   │   ├── attribute.py
│   │   │   ├── computation.py
│   │   │   ├── geometryAttribute.py
│   │   │   ├── node.py
│   │   │   └── shapeAttribute.py
│   │   ├── evaluation.py
│   │   ├── exception.py
│   │   ├── fileUtils.py
│   │   ├── graph.py
│   │   ├── graphIO.py
│   │   ├── keyValues.py
│   │   ├── mtyping.py
│   │   ├── node.py
│   │   ├── nodeFactory.py
│   │   ├── plugins.py
│   │   ├── stats.py
│   │   ├── submitter.py
│   │   ├── taskManager.py
│   │   ├── test.py
│   │   └── utils.py
│   ├── env.py
│   ├── multiview.py
│   ├── nodes/
│   │   ├── __init__.py
│   │   └── general/
│   │       ├── Backdrop.py
│   │       ├── CopyFiles.py
│   │       ├── InputFile.py
│   │       └── __init__.py
│   ├── submitters/
│   │   ├── __init__.py
│   │   └── localFarmSubmitter.py
│   └── ui/
│       ├── __init__.py
│       ├── __main__.py
│       ├── app.py
│       ├── commands.py
│       ├── components/
│       │   ├── __init__.py
│       │   ├── clipboard.py
│       │   ├── csvData.py
│       │   ├── edge.py
│       │   ├── filepath.py
│       │   ├── geom2D.py
│       │   ├── logLinesModel.py
│       │   ├── messaging.py
│       │   ├── scene3D.py
│       │   ├── scriptEditor.py
│       │   ├── shapes/
│       │   │   ├── __init__.py
│       │   │   ├── shapeFile.py
│       │   │   ├── shapeFilesHelper.py
│       │   │   └── shapeViewerHelper.py
│       │   └── thumbnail.py
│       ├── graph.py
│       ├── palette.py
│       ├── qml/
│       │   ├── AboutDialog.qml
│       │   ├── Application.qml
│       │   ├── Charts/
│       │   │   ├── ChartViewCheckBox.qml
│       │   │   ├── ChartViewLegend.qml
│       │   │   ├── InteractiveChartView.qml
│       │   │   └── qmldir
│       │   ├── Controls/
│       │   │   ├── ColorChart.qml
│       │   │   ├── ColorSelector.qml
│       │   │   ├── DelegateSelectionBox.qml
│       │   │   ├── DelegateSelectionLine.qml
│       │   │   ├── DirectionalLightPane.qml
│       │   │   ├── ExifOrientedViewer.qml
│       │   │   ├── ExpandableGroup.qml
│       │   │   ├── FilterComboBox.qml
│       │   │   ├── FloatingPane.qml
│       │   │   ├── Group.qml
│       │   │   ├── IntSelector.qml
│       │   │   ├── KeyValue.qml
│       │   │   ├── MScrollBar.qml
│       │   │   ├── MSplitView.qml
│       │   │   ├── MessageDialog.qml
│       │   │   ├── NodeActions.qml
│       │   │   ├── Panel.qml
│       │   │   ├── SearchBar.qml
│       │   │   ├── SelectionBox.qml
│       │   │   ├── SelectionLine.qml
│       │   │   ├── StatusBar.qml
│       │   │   ├── StatusMessages.qml
│       │   │   ├── TabPanel.qml
│       │   │   ├── TextFileViewer.qml
│       │   │   └── qmldir
│       │   ├── DialogsFactory.qml
│       │   ├── GraphEditor/
│       │   │   ├── AttributeControls/
│       │   │   │   ├── Choice.qml
│       │   │   │   └── ChoiceMulti.qml
│       │   │   ├── AttributeEditor.qml
│       │   │   ├── AttributeItemDelegate.qml
│       │   │   ├── AttributePin.qml
│       │   │   ├── Backdrop.qml
│       │   │   ├── ChunksListView.qml
│       │   │   ├── CompatibilityBadge.qml
│       │   │   ├── CompatibilityManager.qml
│       │   │   ├── Edge.qml
│       │   │   ├── GraphEditor.qml
│       │   │   ├── GraphEditorSettings.qml
│       │   │   ├── Node.qml
│       │   │   ├── NodeChunks.qml
│       │   │   ├── NodeDocumentation.qml
│       │   │   ├── NodeEditor.qml
│       │   │   ├── NodeFileBrowser.qml
│       │   │   ├── NodeLog.qml
│       │   │   ├── NodeStatistics.qml
│       │   │   ├── NodeStatus.qml
│       │   │   ├── ScriptEditor.qml
│       │   │   ├── StatViewer.qml
│       │   │   ├── TaskManager.qml
│       │   │   └── qmldir
│       │   ├── Homepage.qml
│       │   ├── ImageGallery/
│       │   │   ├── ImageBadge.qml
│       │   │   ├── ImageDelegate.qml
│       │   │   ├── ImageGallery.qml
│       │   │   ├── ImageGridView.qml
│       │   │   ├── ImageListView.qml
│       │   │   ├── IntrinsicDisplayDelegate.qml
│       │   │   ├── IntrinsicsIndicator.qml
│       │   │   ├── SensorDBDialog.qml
│       │   │   └── qmldir
│       │   ├── MaterialIcons/
│       │   │   ├── MLabel.qml
│       │   │   ├── MaterialIcons.qml
│       │   │   ├── MaterialLabel.qml
│       │   │   ├── MaterialToolButton.qml
│       │   │   ├── MaterialToolLabel.qml
│       │   │   ├── MaterialToolLabelButton.qml
│       │   │   ├── generate_material_icons.py
│       │   │   └── qmldir
│       │   ├── Shapes/
│       │   │   ├── Editor/
│       │   │   │   ├── Items/
│       │   │   │   │   ├── ShapeAttributeItem.qml
│       │   │   │   │   ├── ShapeDataItem.qml
│       │   │   │   │   ├── ShapeFileItem.qml
│       │   │   │   │   ├── ShapeListAttributeItem.qml
│       │   │   │   │   └── Utils/
│       │   │   │   │       └── ItemHeader.qml
│       │   │   │   ├── ShapeEditor.qml
│       │   │   │   └── ShapeEditorItem.qml
│       │   │   ├── Viewer/
│       │   │   │   ├── Layers/
│       │   │   │   │   ├── BaseLayer.qml
│       │   │   │   │   ├── CircleLayer.qml
│       │   │   │   │   ├── LineLayer.qml
│       │   │   │   │   ├── PointLayer.qml
│       │   │   │   │   ├── RectangleLayer.qml
│       │   │   │   │   ├── TextLayer.qml
│       │   │   │   │   └── Utils/
│       │   │   │   │       └── Handle.qml
│       │   │   │   ├── ShapeViewer.qml
│       │   │   │   ├── ShapeViewerAttributeLayer.qml
│       │   │   │   ├── ShapeViewerAttributeLoader.qml
│       │   │   │   └── ShapeViewerLayer.qml
│       │   │   └── qmldir
│       │   ├── Utils/
│       │   │   ├── Clipboard.qml
│       │   │   ├── Colors.qml
│       │   │   ├── ExifOrientation.qml
│       │   │   ├── ExpressionTextField.qml
│       │   │   ├── Filepath.qml
│       │   │   ├── Scene3DHelper.qml
│       │   │   ├── SortFilterDelegateModel.qml
│       │   │   ├── Transformations3DHelper.qml
│       │   │   ├── errorHandler.js
│       │   │   ├── format.js
│       │   │   ├── qmldir
│       │   │   └── request.js
│       │   ├── Viewer/
│       │   │   ├── CameraResponseGraph.qml
│       │   │   ├── CircleGizmo.qml
│       │   │   ├── ColorCheckerEntity.qml
│       │   │   ├── ColorCheckerPane.qml
│       │   │   ├── ColorCheckerViewer.qml
│       │   │   ├── FeaturesInfoOverlay.qml
│       │   │   ├── FeaturesViewer.qml
│       │   │   ├── FloatImage.qml
│       │   │   ├── HdrImageToolbar.qml
│       │   │   ├── ImageMetadataView.qml
│       │   │   ├── LensDistortionToolbar.qml
│       │   │   ├── MFeatures.qml
│       │   │   ├── MSfMData.qml
│       │   │   ├── MTracks.qml
│       │   │   ├── PanoramaToolbar.qml
│       │   │   ├── PanoramaViewer.qml
│       │   │   ├── PhongImageViewer.qml
│       │   │   ├── PhongImageViewerToolbar.qml
│       │   │   ├── SequencePlayer.qml
│       │   │   ├── SfmGlobalStats.qml
│       │   │   ├── SfmStatsView.qml
│       │   │   ├── TestAliceVisionPlugin.qml
│       │   │   ├── TextViewer.qml
│       │   │   ├── Viewer2D.qml
│       │   │   └── qmldir
│       │   ├── Viewer3D/
│       │   │   ├── BoundingBox.qml
│       │   │   ├── DefaultCameraController.qml
│       │   │   ├── DepthMapLoader.qml
│       │   │   ├── EntityWithGizmo.qml
│       │   │   ├── EnvironmentMapEntity.qml
│       │   │   ├── Grid3D.qml
│       │   │   ├── ImageOverlay.qml
│       │   │   ├── Inspector3D.qml
│       │   │   ├── Locator3D.qml
│       │   │   ├── MaterialSwitcher.qml
│       │   │   ├── Materials/
│       │   │   │   ├── SphericalHarmonicsEffect.qml
│       │   │   │   ├── SphericalHarmonicsMaterial.qml
│       │   │   │   ├── WireframeEffect.qml
│       │   │   │   ├── WireframeMaterial.qml
│       │   │   │   └── shaders/
│       │   │   │       ├── SphericalHarmonics.frag
│       │   │   │       ├── SphericalHarmonics.vert
│       │   │   │       ├── robustwireframe.frag
│       │   │   │       └── robustwireframe.vert
│       │   │   ├── MediaCache.qml
│       │   │   ├── MediaLibrary.qml
│       │   │   ├── MediaLoader.qml
│       │   │   ├── MediaLoaderEntity.qml
│       │   │   ├── MeshingBoundingBox.qml
│       │   │   ├── SfMTransformGizmo.qml
│       │   │   ├── SfmDataLoader.qml
│       │   │   ├── TrackballGizmo.qml
│       │   │   ├── TransformGizmo.qml
│       │   │   ├── TransformGizmoPicker.qml
│       │   │   ├── Viewer3D.qml
│       │   │   ├── Viewer3DSettings.qml
│       │   │   ├── ViewpointCamera.qml
│       │   │   └── qmldir
│       │   ├── WorkspaceView.qml
│       │   └── main.qml
│       ├── scene.py
│       └── utils.py
├── requirements.txt
├── setup.py
├── setupInitScriptUnix.py
├── setupInitScriptWindows.py
├── start.bat
├── start.sh
└── tests/
    ├── __init__.py
    ├── appendTextAndFiles.mg
    ├── conftest.py
    ├── nodes/
    │   ├── __init__.py
    │   └── test/
    │       ├── Color.py
    │       ├── GroupAttributes.py
    │       ├── InputDynamicOutputs.py
    │       ├── NestedTest.py
    │       ├── Position.py
    │       ├── __init__.py
    │       ├── appendFiles.py
    │       ├── appendText.py
    │       └── ls.py
    ├── plugins/
    │   └── meshroom/
    │       ├── pluginA/
    │       │   ├── PluginAInputInitNode.py
    │       │   ├── PluginAInputNode.py
    │       │   ├── PluginANodeA.py
    │       │   ├── PluginANodeB.py
    │       │   └── __init__.py
    │       ├── pluginB/
    │       │   ├── PluginBNodeA.py
    │       │   ├── PluginBNodeB.py
    │       │   └── __init__.py
    │       ├── pluginC/
    │       │   ├── PluginCNodeA.py
    │       │   └── __init__.py
    │       ├── pluginSubmitter/
    │       │   ├── PluginSubmitter.py
    │       │   └── __init__.py
    │       └── sharedTemplate.mg
    ├── test_attributeChoiceParam.py
    ├── test_attributeDescDefaults.py
    ├── test_attributeKeyValues.py
    ├── test_attributeLambda.py
    ├── test_attributeShape.py
    ├── test_attributes.py
    ├── test_compatibility.py
    ├── test_compute.py
    ├── test_graph.py
    ├── test_graphIO.py
    ├── test_groupAttributes.py
    ├── test_invalidation.py
    ├── test_listAttribute.py
    ├── test_model.py
    ├── test_nodeAttributeChangedCallback.py
    ├── test_nodeAttributesFormatting.py
    ├── test_nodeCallbacks.py
    ├── test_nodeCommandLineFormatting.py
    ├── test_nodeDynamicOutputs.py
    ├── test_nodes.py
    ├── test_pipeline.py
    ├── test_plugins.py
    ├── test_submit.py
    └── utils.py
Download .txt
SYMBOL INDEX (2151 symbols across 107 files)

FILE: docs/source/_ext/fetch_md.py
  class Relinker (line 21) | class Relinker(SparseNodeVisitor):
    method relink (line 23) | def relink(self, node, base_dir):
    method visit_image (line 34) | def visit_image(self, node):
  class FetchMd (line 38) | class FetchMd(Directive):
    method run (line 42) | def run(self):
  function setup (line 57) | def setup(app):

FILE: docs/source/_ext/meshroom_doc.py
  class MeshroomDoc (line 21) | class MeshroomDoc(Directive):
    method parse_args (line 25) | def parse_args(self):
    method run (line 30) | def run(self):
  function setup (line 60) | def setup(app):

FILE: docs/source/_ext/utils.py
  function md_to_docutils (line 10) | def md_to_docutils(text):
  function get_link_key (line 20) | def get_link_key(node):

FILE: localfarm/localFarm.py
  class LocalFarmEngine (line 25) | class LocalFarmEngine:
    method __init__ (line 28) | def __init__(self, root):
    method connect (line 32) | def connect(self):
    method _call (line 46) | def _call(self, method, **params):
    method submit_job (line 73) | def submit_job(self, job: Job):
    method create_additional_task (line 95) | def create_additional_task(self, jid, tid, task):
    method get_job_info (line 102) | def get_job_info(self, jid):
    method pause_job (line 106) | def pause_job(self, jid):
    method unpause_job (line 110) | def unpause_job(self, jid):
    method interrupt_job (line 114) | def interrupt_job(self, jid):
    method restart_job (line 118) | def restart_job(self, jid):
    method restart_error_tasks (line 122) | def restart_error_tasks(self, jid):
    method stop_task (line 126) | def stop_task(self, jid, tid):
    method skip_task (line 130) | def skip_task(self, jid, tid):
    method restart_task (line 134) | def restart_task(self, jid, tid):
    method list_jobs (line 138) | def list_jobs(self) -> list:
    method get_job_status (line 142) | def get_job_status(self, jid: int) -> dict:
    method get_job_errors (line 148) | def get_job_errors(self, jid: int) -> str:
    method ping (line 152) | def ping(self):
  class Task (line 161) | class Task:
    method __init__ (line 162) | def __init__(self, name, command, metadata=None, env=None):
    method __repr__ (line 169) | def __repr__(self):
    method __hash__ (line 172) | def __hash__(self):
  class Job (line 176) | class Job:
    method __init__ (line 177) | def __init__(self, name):
    method setEngine (line 184) | def setEngine(self, engine: LocalFarmEngine):
    method addTask (line 187) | def addTask(self, task):
    method addTaskDependency (line 192) | def addTaskDependency(self, task: Task, dependsOn: Task):
    method getTaskDependencies (line 205) | def getTaskDependencies(self, task):
    method getRootTasks (line 208) | def getRootTasks(self) -> List[Task]:
    method hasCycle (line 215) | def hasCycle(self) -> bool:
    method tasksDFS (line 238) | def tasksDFS(self) -> Generator[Task]:
    method submit (line 264) | def submit(self, engine: LocalFarmEngine = None):
  function test (line 273) | def test():

FILE: localfarm/localFarmBackend.py
  class Status (line 39) | class Status(Enum):
  class Task (line 50) | class Task:
    method __init__ (line 51) | def __init__(self, jid: str, tid: str, label: str, command: str, metad...
    method to_dict (line 70) | def to_dict(self):
  class Job (line 86) | class Job:
    method __init__ (line 87) | def __init__(self, jid: str, label: str, farmRoot: PathLike, maxParall...
    method to_dict (line 102) | def to_dict(self):
    method errorLogs (line 115) | def errorLogs(self):
    method rootTasks (line 123) | def rootTasks(self):
    method addTaskDependency (line 126) | def addTaskDependency(self, parentTask: Task, childTask: Task):
    method canStartTask (line 130) | def canStartTask(self, task: Task):
    method getNextTaskToProcess (line 137) | def getNextTaskToProcess(self):
    method start (line 157) | def start(self):
    method updateStatusFromTasks (line 163) | def updateStatusFromTasks(self):
    method interrupt (line 172) | def interrupt(self):
    method restart (line 183) | def restart(self):
    method restartErrorTasks (line 187) | def restartErrorTasks(self):
    method resume (line 193) | def resume(self):
    method stopTask (line 201) | def stopTask(self, tid):
    method skipTask (line 211) | def skipTask(self, tid):
    method restartTask (line 221) | def restartTask(self, tid):
  class LocalFarmEngine (line 236) | class LocalFarmEngine:
    method __init__ (line 237) | def __init__(self, root: PathLike, maxParallel: int = FARM_MAX_PARALLE...
    method start (line 253) | def start(self):
    method signalHandler (line 278) | def signalHandler(self, signum, frame):
    method taskRunner (line 282) | def taskRunner(self):
    method processJobs (line 292) | def processJobs(self):
    method startTask (line 342) | def startTask(self, task: Task):
    method finishTask (line 380) | def finishTask(self, task: Task, returncode: int):
    method cleanup (line 392) | def cleanup(self):
    method create_job (line 414) | def create_job(self, name):
    method create_task (line 428) | def create_task(self, jid, name, command, metadata, dependencies, env=...
    method expand_task (line 447) | def expand_task(self, jid, name, command, metadata, parentTid, env=None):
    method submit_job (line 470) | def submit_job(self, jid):
    method get_job_info (line 486) | def get_job_info(self, jid):
    method get_job_errors (line 494) | def get_job_errors(self, jid):
    method pause_job (line 502) | def pause_job(self, jid):
    method unpause_job (line 511) | def unpause_job(self, jid):
    method interrupt_job (line 519) | def interrupt_job(self, jid):
    method restart_job (line 527) | def restart_job(self, jid):
    method restart_error_tasks (line 535) | def restart_error_tasks(self, jid):
    method stop_task (line 543) | def stop_task(self, jid, tid):
    method skip_task (line 554) | def skip_task(self, jid, tid):
    method restart_task (line 565) | def restart_task(self, jid, tid):
    method list_jobs (line 576) | def list_jobs(self):
  class LocalFarmRequestHandler (line 585) | class LocalFarmRequestHandler(BaseRequestHandler):
    method __init__ (line 588) | def __init__(self, backend, *args, **kwargs):
    method pid (line 593) | def pid(self):
    method handle (line 596) | def handle(self):
  function main (line 632) | def main(root):

FILE: localfarm/localFarmLauncher.py
  class FarmLauncher (line 16) | class FarmLauncher:
    method __init__ (line 17) | def __init__(self, root=None):
    method clean (line 23) | def clean(self):
    method start (line 35) | def start(self):
    method stop (line 67) | def stop(self):
    method restart (line 94) | def restart(self):
    method getJobsInfo (line 100) | def getJobsInfo(self):
    method status (line 113) | def status(self, allInfo=False):
    method is_running (line 140) | def is_running(self):
    method getFarmPid (line 151) | def getFarmPid(self):
  function main (line 161) | def main(root, command):

FILE: localfarm/test.py
  class TestLocalFarm (line 11) | class TestLocalFarm:
    method __init__ (line 12) | def __init__(self, farmPath):
    method prepare (line 16) | def prepare(self):
    method createTask (line 20) | def createTask(self, job: Job, i: int, sleepTime=2, dependencies: List...
    method expandTask (line 28) | def expandTask(self, jid, tid, n=2):
    method getTasksByStatus (line 33) | def getTasksByStatus(self, jid: int):
    method run (line 43) | def run(self):
    method finish (line 82) | def finish(self):
  function test (line 87) | def test():

FILE: meshroom/__init__.py
  class VersionStatus (line 7) | class VersionStatus(Enum):
  function addTraceLevel (line 47) | def addTraceLevel():
  class MeshroomExitStatus (line 78) | class MeshroomExitStatus(IntEnum):
  function setupEnvironment (line 89) | def setupEnvironment(backend=Backend.STANDALONE):

FILE: meshroom/common/PySignal.py
  class Signal (line 19) | class Signal:
    method __init__ (line 24) | def __init__(self):
    method __call__ (line 30) | def __call__(self, *args, **kwargs):
    method emit (line 33) | def emit(self, *args, **kwargs):
    method connect (line 84) | def connect(self, slot):
    method disconnect (line 108) | def disconnect(self, slot):
    method clear (line 137) | def clear(self):
    method block (line 141) | def block(self, isBlocked):
    method sender (line 145) | def sender(self):
  class ClassSignal (line 154) | class ClassSignal:
    method __get__ (line 161) | def __get__(self, instance, owner):
    method __set__ (line 169) | def __set__(self, instance, value):
  class SignalFactory (line 173) | class SignalFactory(dict):
    method register (line 178) | def register(self, name, *slots):
    method deregister (line 190) | def deregister(self, name):
    method emit (line 197) | def emit(self, signalName, *args, **kwargs):
    method connect (line 205) | def connect(self, signalName, slot):
    method block (line 214) | def block(self, signals=None, isBlocked=True):
  class ClassSignalFactory (line 237) | class ClassSignalFactory:
    method __get__ (line 244) | def __get__(self, instance, owner):
    method __set__ (line 253) | def __set__(self, instance, value):
    method register (line 256) | def register(self, name):

FILE: meshroom/common/__init__.py
  class Backend (line 11) | class Backend(Enum):
  function init (line 27) | def init(backend):
  function strtobool (line 37) | def strtobool(val: str):

FILE: meshroom/common/core.py
  class CoreDictModel (line 4) | class CoreDictModel:
    method __init__ (line 6) | def __init__(self, keyAttrName, **kwargs):
    method __len__ (line 10) | def __len__(self):
    method __bool__ (line 13) | def __bool__(self):
    method __iter__ (line 16) | def __iter__(self):
    method keys (line 20) | def keys(self):
    method items (line 23) | def items(self):
    method values (line 26) | def values(self):
    method objects (line 30) | def objects(self):
    method get (line 33) | def get(self, key):
    method getr (line 40) | def getr(self, key):
    method add (line 48) | def add(self, obj):
    method rename (line 54) | def rename(self, oldKey: str, newKey: str):
    method pop (line 70) | def pop(self, key):
    method remove (line 74) | def remove(self, obj):
    method clear (line 78) | def clear(self):
    method update (line 81) | def update(self, objects):
    method reset (line 85) | def reset(self, objects):
  class CoreListModel (line 90) | class CoreListModel:
    method __init__ (line 91) | def __init__(self, parent=None):
    method __iter__ (line 94) | def __iter__(self):
    method __len__ (line 97) | def __len__(self):
    method __getitem__ (line 100) | def __getitem__(self, idx):
    method values (line 103) | def values(self):
    method setObjectList (line 106) | def setObjectList(self, iterable):
    method at (line 110) | def at(self, idx):
    method append (line 113) | def append(self, obj):
    method extend (line 116) | def extend(self, iterable):
    method indexOf (line 119) | def indexOf(self, obj):
    method removeAt (line 122) | def removeAt(self, idx, count=1):
    method remove (line 125) | def remove(self, obj):
    method clear (line 128) | def clear(self):
    method insert (line 131) | def insert(self, index, iterable):
  function CoreSlot (line 135) | def CoreSlot(*args, **kwargs):
  class CoreProperty (line 143) | class CoreProperty(property):
    method __init__ (line 144) | def __init__(self, ptype, fget=None, fset=None, **kwargs):
  class CoreObject (line 148) | class CoreObject:
    method __init__ (line 150) | def __init__(self, parent=None, *args, **kwargs):
    method __del__ (line 156) | def __del__(self):
    method parent (line 159) | def parent(self):

FILE: meshroom/common/deprecated.py
  function depreciateParam (line 7) | def depreciateParam(paramToDepreciate, msg):

FILE: meshroom/common/qt.py
  class QObjectListModel (line 5) | class QObjectListModel(QtCore.QAbstractListModel):
    method __init__ (line 15) | def __init__(self, keyAttrName='', parent=None):
    method roleNames (line 27) | def roleNames(self):
    method __iter__ (line 30) | def __iter__(self):
    method keys (line 34) | def keys(self):
    method items (line 37) | def items(self):
    method __len__ (line 40) | def __len__(self):
    method __bool__ (line 43) | def __bool__(self):
    method __getitem__ (line 46) | def __getitem__(self, index):
    method data (line 52) | def data(self, index, role):
    method rowCount (line 63) | def rowCount(self, parent):
    method objectList (line 69) | def objectList(self):
    method values (line 73) | def values(self):
    method setObjectList (line 76) | def setObjectList(self, objects):
    method objects (line 96) | def objects(self):
    method get (line 100) | def get(self, key):
    method getr (line 108) | def getr(self, key):
    method add (line 116) | def add(self, obj):
    method pop (line 119) | def pop(self, key):
    method append (line 128) | def append(self, obj):
    method extend (line 132) | def extend(self, iterable):
    method insert (line 140) | def insert(self, i, toInsert):
    method at (line 156) | def at(self, i):
    method replace (line 160) | def replace(self, i, obj):
    method rename (line 170) | def rename(self, oldKey: str, newKey: str):
    method move (line 188) | def move(self, fromIndex, toIndex):
    method removeAt (line 203) | def removeAt(self, i, count=1):
    method remove (line 216) | def remove(self, obj):
    method takeAt (line 222) | def takeAt(self, i):
    method clear (line 233) | def clear(self):
    method update (line 244) | def update(self, objects):
    method reset (line 247) | def reset(self, objects):
    method contains (line 251) | def contains(self, obj):
    method indexOf (line 258) | def indexOf(self, matchObj, fromIndex=0, positive=True):
    method lastIndexOf (line 268) | def lastIndexOf(self, matchObj, fromIndex=-1, positive=True):
    method size (line 281) | def size(self):
    method isEmpty (line 286) | def isEmpty(self):
    method _referenceItem (line 290) | def _referenceItem(self, item):
    method index (line 305) | def index(self, row: int, column: int = 0, parent=QtCore.QModelIndex()):
    method _dereferenceItem (line 313) | def _dereferenceItem(self, item):
    method onRequestDeletion (line 330) | def onRequestDeletion(self, item):
  class QTypedObjectListModel (line 339) | class QTypedObjectListModel(QObjectListModel):
    method __init__ (line 343) | def __init__(self, keyAttrName="name", T=QtCore.QObject, parent=None):
    method data (line 361) | def data(self, index, role):
    method roleForName (line 369) | def roleForName(self, name):
    method _referenceItem (line 373) | def _referenceItem(self, item):
  class SortedModelByReference (line 380) | class SortedModelByReference(QtCore.QSortFilterProxyModel):
    method __init__ (line 384) | def __init__(self, parent):
    method setReference (line 388) | def setReference(self, iterable):
    method reference (line 393) | def reference(self):
    method lessThan (line 396) | def lessThan(self, left, right):
    method sort (line 405) | def sort(self):

FILE: meshroom/core/__init__.py
  function hashValue (line 39) | def hashValue(value) -> str:
  function add_to_path (line 46) | def add_to_path(p):
  function loadClasses (line 57) | def loadClasses(folder: str, packageName: str, classType: type) -> list[...
  function loadClassesNodes (line 145) | def loadClassesNodes(folder: str, packageName: str) -> list[NodePlugin]:
  function loadClassesSubmitters (line 163) | def loadClassesSubmitters(folder: str, packageName: str) -> list[BaseSub...
  class Version (line 181) | class Version:
    method __init__ (line 186) | def __init__(self, *args):
    method __repr__ (line 207) | def __repr__(self):
    method __neg__ (line 210) | def __neg__(self):
    method __len__ (line 213) | def __len__(self):
    method __eq__ (line 216) | def __eq__(self, other):
    method __lt__ (line 228) | def __lt__(self, other):
    method __le__ (line 240) | def __le__(self, other):
    method toComponents (line 253) | def toComponents(versionName):
    method name (line 277) | def name(self):
    method major (line 282) | def major(self):
    method minor (line 287) | def minor(self):
    method micro (line 294) | def micro(self):
  function moduleVersion (line 301) | def moduleVersion(moduleName: str, default=None):
  function nodeVersion (line 314) | def nodeVersion(nodeDesc: desc.Node, default=None):
  function loadNodes (line 327) | def loadNodes(folder, packageName) -> list[NodePlugin]:
  function loadAllNodes (line 336) | def loadAllNodes(folder) -> list[Plugin]:
  function loadPluginFolder (line 351) | def loadPluginFolder(folder) -> list[Plugin]:
  function loadPluginsFolder (line 370) | def loadPluginsFolder(folder):
  function registerSubmitter (line 381) | def registerSubmitter(s: BaseSubmitter):
  function loadSubmitters (line 387) | def loadSubmitters(folder, packageName) -> list[BaseSubmitter]:
  function loadAllSubmitters (line 395) | def loadAllSubmitters(folder) -> list[BaseSubmitter]:
  function loadPipelineTemplates (line 405) | def loadPipelineTemplates(folder: str):
  function initNodes (line 414) | def initNodes():
  function initSubmitters (line 424) | def initSubmitters():
  function initPipelines (line 438) | def initPipelines():
  function initPlugins (line 448) | def initPlugins():
  function initRezPlugins (line 463) | def initRezPlugins():

FILE: meshroom/core/attribute.py
  function attributeFactory (line 24) | def attributeFactory(description: str, value, isOutput: bool, node, root...
  class Attribute (line 51) | class Attribute(BaseObject):
    method isLinkExpression (line 60) | def isLinkExpression(value) -> bool:
    method __init__ (line 67) | def __init__(self, node, attributeDesc: desc.Attribute, isOutput: bool...
    method _getFullName (line 93) | def _getFullName(self) -> str:
    method _getRootName (line 100) | def _getRootName(self) -> str:
    method asLinkExpr (line 111) | def asLinkExpr(self) -> str:
    method requestGraphUpdate (line 117) | def requestGraphUpdate(self):
    method requestNodeUpdate (line 122) | def requestNodeUpdate(self):
    method executeValue (line 128) | def executeValue(self, value):
    method _initValue (line 147) | def _initValue(self):
    method _getEvalValue (line 160) | def _getEvalValue(self):
    method _getValue (line 180) | def _getValue(self):
    method _setValue (line 190) | def _setValue(self, value):
    method _getKeyValues (line 228) | def _getKeyValues(self):
    method _handleLinkValue (line 238) | def _handleLinkValue(self, value) -> bool:
    method _applyExpr (line 262) | def _applyExpr(self):
    method resetToDefaultValue (line 300) | def resetToDefaultValue(self):
    method getDefaultValue (line 310) | def getDefaultValue(self):
    method getSerializedValue (line 332) | def getSerializedValue(self):
    method getPrimitiveValue (line 344) | def getPrimitiveValue(self, exportDefault=True):
    method getValueStr (line 347) | def getValueStr(self, withQuotes=True) -> str:
    method validateValue (line 372) | def validateValue(self, value):
    method upgradeValue (line 378) | def upgradeValue(self, exportedValue):
    method _isDefault (line 384) | def _isDefault(self):
    method _isValid (line 390) | def _isValid(self):
    method _is2dDisplayable (line 405) | def _is2dDisplayable(self) -> bool:
    method _is3dDisplayable (line 414) | def _is3dDisplayable(self) -> bool:
    method _isTextDisplayable (line 428) | def _isTextDisplayable(self) -> bool:
    method uid (line 442) | def uid(self) -> str:
    method updateInternals (line 469) | def updateInternals(self):
    method _getEnabled (line 476) | def _getEnabled(self) -> bool:
    method _setEnabled (line 486) | def _setEnabled(self, v):
    method _isLink (line 492) | def _isLink(self) -> bool:
    method _getInputLink (line 498) | def _getInputLink(self, recursive=False) -> Attribute:
    method _getOutputLinks (line 510) | def _getOutputLinks(self) -> list[Attribute]:
    method _getAllInputLinks (line 519) | def _getAllInputLinks(self) -> list[Attribute]:
    method _getAllOutputLinks (line 528) | def _getAllOutputLinks(self) -> list[Attribute]:
    method _hasAnyInputLinks (line 534) | def _hasAnyInputLinks(self) -> bool:
    method _hasAnyOutputLinks (line 543) | def _hasAnyOutputLinks(self) -> bool:
    method _getFlatStaticChildren (line 552) | def _getFlatStaticChildren(self) -> list[Attribute]:
    method _validateIncomingConnection (line 560) | def _validateIncomingConnection(self, connectingAttribute: Attribute) ...
    method connectTo (line 573) | def connectTo(self, dstAttribute: Attribute) -> tuple[list[list[Attrib...
    method disconnectEdge (line 598) | def disconnectEdge(self):
    method _onKeyValuesChanged (line 621) | def _onKeyValuesChanged(self):
    method _onValueChanged (line 632) | def _onValueChanged(self):
    method matchText (line 636) | def matchText(self, text: str) -> bool:
    method validateIncomingConnection (line 640) | def validateIncomingConnection(self, connectingAttribute: Attribute) -...
  function raiseIfLink (line 732) | def raiseIfLink(func):
  class PushButtonParam (line 743) | class PushButtonParam(Attribute):
    method __init__ (line 744) | def __init__(self, node, attributeDesc: desc.PushButtonParam, isOutput...
    method clicked (line 749) | def clicked(self):
  class ChoiceParam (line 753) | class ChoiceParam(Attribute):
    method __init__ (line 755) | def __init__(self, node, attributeDesc: desc.ChoiceParam, isOutput: bool,
    method __len__ (line 760) | def __len__(self):
    method getValues (line 763) | def getValues(self):
    method setValues (line 768) | def setValues(self, values):
    method validateValue (line 775) | def validateValue(self, value):
    method _conformValue (line 785) | def _conformValue(self, val):
    method _setValue (line 792) | def _setValue(self, value):
    method getSerializedValue (line 802) | def getSerializedValue(self):
  class ListAttribute (line 817) | class ListAttribute(Attribute):
    method __init__ (line 819) | def __init__(self, node, attributeDesc: desc.ListAttribute, isOutput: ...
    method __len__ (line 823) | def __len__(self):
    method __iter__ (line 828) | def __iter__(self):
    method at (line 831) | def at(self, idx):
    method index (line 839) | def index(self, item):
    method append (line 843) | def append(self, value):
    method extend (line 847) | def extend(self, values):
    method insert (line 851) | def insert(self, index, value):
    method remove (line 863) | def remove(self, index, count=1):
    method _initValue (line 880) | def _initValue(self):
    method _setValue (line 884) | def _setValue(self, value):
    method _applyExpr (line 899) | def _applyExpr(self):
    method resetToDefaultValue (line 907) | def resetToDefaultValue(self):
    method getDefaultValue (line 912) | def getDefaultValue(self) -> list:
    method getSerializedValue (line 916) | def getSerializedValue(self):
    method getPrimitiveValue (line 922) | def getPrimitiveValue(self, exportDefault=True):
    method getValueStr (line 929) | def getValueStr(self, withQuotes=True) -> str:
    method upgradeValue (line 941) | def upgradeValue(self, exportedValues):
    method uid (line 960) | def uid(self):
    method updateInternals (line 970) | def updateInternals(self):
    method _getAllInputLinks (line 976) | def _getAllInputLinks(self) -> list[Attribute]:
    method _getAllOutputLinks (line 986) | def _getAllOutputLinks(self) -> list[Attribute]:
    method _hasAnyInputLinks (line 996) | def _hasAnyInputLinks(self) -> bool:
    method _hasAnyOutputLinks (line 1004) | def _hasAnyOutputLinks(self) -> bool:
  class GroupAttribute (line 1023) | class GroupAttribute(Attribute):
    method __init__ (line 1025) | def __init__(self, node, attributeDesc: desc.GroupAttribute, isOutput:...
    method __getattr__ (line 1029) | def __getattr__(self, key):
    method _initValue (line 1039) | def _initValue(self):
    method _getValue (line 1049) | def _getValue(self):
    method _setValue (line 1053) | def _setValue(self, exportedValue):
    method _applyExpr (line 1071) | def _applyExpr(self):
    method resetToDefaultValue (line 1079) | def resetToDefaultValue(self):
    method getDefaultValue (line 1084) | def getDefaultValue(self):
    method getSerializedValue (line 1088) | def getSerializedValue(self):
    method getPrimitiveValue (line 1094) | def getPrimitiveValue(self, exportDefault=True):
    method getValueStr (line 1101) | def getValueStr(self, withQuotes=True):
    method upgradeValue (line 1122) | def upgradeValue(self, exportedValue):
    method uid (line 1141) | def uid(self):
    method updateInternals (line 1152) | def updateInternals(self):
    method _getFlatStaticChildren (line 1158) | def _getFlatStaticChildren(self) -> list[Attribute]:
    method _validateIncomingConnection (line 1169) | def _validateIncomingConnection(self, connectingAttribute: Attribute) ...
    method _hasMatchingStructure (line 1177) | def _hasMatchingStructure(self, otherAttribute: Attribute) -> bool:
    method connectTo (line 1203) | def connectTo(self, dstAttribute: GroupAttribute) -> tuple[list[list[A...
    method childAttribute (line 1233) | def childAttribute(self, key: str) -> Attribute:
    method matchText (line 1250) | def matchText(self, text: str) -> bool:
  class GeometryAttribute (line 1261) | class GeometryAttribute(GroupAttribute):
    method __init__ (line 1266) | def __init__(self, node, attributeDesc: desc.Geometry, isOutput: bool,...
    method _setValue (line 1271) | def _setValue(self, exportedValue):
    method resetToDefaultValue (line 1277) | def resetToDefaultValue(self):
    method upgradeValue (line 1283) | def upgradeValue(self, exportedValue):
    method getSerializedValue (line 1290) | def getSerializedValue(self):
    method getValueAsDict (line 1295) | def getValueAsDict(self) -> dict:
    method _hasKeyableChilds (line 1316) | def _hasKeyableChilds(self) -> bool:
    method _getNbObservations (line 1323) | def _getNbObservations(self) -> int:
    method _getObservationKeys (line 1335) | def _getObservationKeys(self) -> list:
    method hasObservation (line 1348) | def hasObservation(self, key: str) -> bool:
    method removeObservation (line 1360) | def removeObservation(self, key: str):
    method setObservation (line 1376) | def setObservation(self, key: str, observation: Variant):
    method getObservation (line 1396) | def getObservation(self, key: str) -> Variant:
  class ShapeAttribute (line 1430) | class ShapeAttribute(GroupAttribute):
    method __init__ (line 1435) | def __init__(self, node, attributeDesc: desc.Shape, isOutput: bool, ro...
    method _initValue (line 1441) | def _initValue(self):
    method getSerializedValue (line 1453) | def getSerializedValue(self):
    method getShapeAsDict (line 1458) | def getShapeAsDict(self) -> dict:
    method _getVisible (line 1475) | def _getVisible(self) -> bool:
    method _setVisible (line 1481) | def _setVisible(self, visible: bool):
    method _getUserName (line 1488) | def _getUserName(self) -> str:
    method _getUserColor (line 1494) | def _getUserColor(self) -> str:
    method _onShapeChanged (line 1501) | def _onShapeChanged(self):
    method _onGeometryChanged (line 1509) | def _onGeometryChanged(self):
  class ShapeListAttribute (line 1533) | class ShapeListAttribute(ListAttribute):
    method __init__ (line 1538) | def __init__(self, node, attributeDesc: desc.ShapeList, isOutput: bool...
    method getGeometriesAsDict (line 1542) | def getGeometriesAsDict(self):
    method getShapesAsDict (line 1548) | def getShapesAsDict(self):
    method _getVisible (line 1554) | def _getVisible(self) -> bool:
    method _setVisible (line 1562) | def _setVisible(self, visible: bool):

FILE: meshroom/core/cgroup.py
  function getCgroupMemorySize (line 7) | def getCgroupMemorySize():
  function parseNumericList (line 47) | def parseNumericList(numericListString):
  function getCgroupCpuCount (line 64) | def getCgroupCpuCount():

FILE: meshroom/core/desc/attribute.py
  function convertToLabel (line 15) | def convertToLabel(name: str) -> str:
  class ValueTypeErrors (line 47) | class ValueTypeErrors(Enum):
  class Attribute (line 59) | class Attribute(BaseObject):
    method __init__ (line 63) | def __init__(self, name, label, description, value, advanced, semantic...
    method getInstanceType (line 88) | def getInstanceType(self):
    method validateValue (line 94) | def validateValue(self, value):
    method validateKeyValues (line 103) | def validateKeyValues(self, keyValues):
    method checkValueTypes (line 112) | def checkValueTypes(self):
    method matchDescription (line 122) | def matchDescription(self, value, strict=True):
  class ListAttribute (line 180) | class ListAttribute(Attribute):
    method __init__ (line 183) | def __init__(self, elementDesc, name, label=None, description=None, gr...
    method getInstanceType (line 196) | def getInstanceType(self):
    method validateValue (line 201) | def validateValue(self, value):
    method checkValueTypes (line 218) | def checkValueTypes(self):
    method matchDescription (line 221) | def matchDescription(self, value, strict=True):
  class GroupAttribute (line 235) | class GroupAttribute(Attribute):
    method __init__ (line 238) | def __init__(self, items, name, label=None, description=None, group="a...
    method getInstanceType (line 253) | def getInstanceType(self):
    method validateValue (line 258) | def validateValue(self, value):
    method checkValueTypes (line 292) | def checkValueTypes(self):
    method matchDescription (line 310) | def matchDescription(self, value, strict=True):
    method retrieveChildrenInvalidations (line 334) | def retrieveChildrenInvalidations(self):
  class Param (line 346) | class Param(Attribute):
    method __init__ (line 349) | def __init__(self, name, label, description, value, commandLineGroup, ...
  class File (line 359) | class File(Attribute):
    method __init__ (line 363) | def __init__(self, name, label=None, description=None, value=None, gro...
    method validateValue (line 373) | def validateValue(self, value):
    method checkValueTypes (line 381) | def checkValueTypes(self):
  class BoolParam (line 391) | class BoolParam(Param):
    method __init__ (line 395) | def __init__(self, name, label=None, description=None, value=None, key...
    method validateValue (line 407) | def validateValue(self, value):
    method checkValueTypes (line 418) | def checkValueTypes(self):
  class IntParam (line 426) | class IntParam(Param):
    method __init__ (line 430) | def __init__(self, name, label=None, description=None, value=None, ran...
    method validateValue (line 444) | def validateValue(self, value):
    method checkValueTypes (line 454) | def checkValueTypes(self):
  class FloatParam (line 466) | class FloatParam(Param):
    method __init__ (line 470) | def __init__(self, name, label=None, description=None, value=None, ran...
    method validateValue (line 483) | def validateValue(self, value):
    method checkValueTypes (line 492) | def checkValueTypes(self):
  class PushButtonParam (line 504) | class PushButtonParam(Param):
    method __init__ (line 508) | def __init__(self, name, label=None, description=None, group="allParam...
    method getInstanceType (line 519) | def getInstanceType(self):
    method validateValue (line 524) | def validateValue(self, value):
    method checkValueTypes (line 527) | def checkValueTypes(self):
  class ChoiceParam (line 531) | class ChoiceParam(Param):
    method __init__ (line 550) | def __init__(self, name: str, label=None, description=None, value=None...
    method getInstanceType (line 574) | def getInstanceType(self):
    method conformValue (line 579) | def conformValue(self, value):
    method validateValue (line 585) | def validateValue(self, value):
    method checkValueTypes (line 605) | def checkValueTypes(self):
  class StringParam (line 632) | class StringParam(Param):
    method __init__ (line 636) | def __init__(self, name, label=None, description=None, value=None, gro...
    method validateValue (line 649) | def validateValue(self, value):
    method checkValueTypes (line 657) | def checkValueTypes(self):
  class ColorParam (line 665) | class ColorParam(Param):
    method __init__ (line 669) | def __init__(self, name, label=None, description=None, value=None, gro...
    method validateValue (line 679) | def validateValue(self, value):
    method checkValueTypes (line 688) | def checkValueTypes(self):

FILE: meshroom/core/desc/computation.py
  class Level (line 7) | class Level(IntEnum):
  class Range (line 15) | class Range:
    method __init__ (line 16) | def __init__(self, iteration=0, blockSize=0, fullSize=0, nbBlocks=0):
    method start (line 23) | def start(self):
    method effectiveBlockSize (line 27) | def effectiveBlockSize(self):
    method end (line 32) | def end(self):
    method last (line 36) | def last(self):
    method toDict (line 39) | def toDict(self):
    method __repr__ (line 51) | def __repr__(self):
  class Parallelization (line 55) | class Parallelization:
    method __init__ (line 56) | def __init__(self, staticNbBlocks=0, blockSize=0):
    method getSizes (line 60) | def getSizes(self, node):
    method getRange (line 74) | def getRange(self, node, iteration):
    method getRanges (line 78) | def getRanges(self, node):
  class DynamicNodeSize (line 86) | class DynamicNodeSize(object):
    method __init__ (line 93) | def __init__(self, param):
    method __call__ (line 96) | def __call__(self, node):
  class MultiDynamicNodeSize (line 109) | class MultiDynamicNodeSize(object):
    method __init__ (line 115) | def __init__(self, params):
    method __call__ (line 123) | def __call__(self, node):
  class StaticNodeSize (line 136) | class StaticNodeSize(object):
    method __init__ (line 140) | def __init__(self, size):
    method __call__ (line 143) | def __call__(self, node):

FILE: meshroom/core/desc/geometryAttribute.py
  class Geometry (line 4) | class Geometry(GroupAttribute):
    method __init__ (line 9) | def __init__(self, items, name, label=None, description=None, commandL...
    method getInstanceType (line 16) | def getInstanceType(self):
  class Size2d (line 25) | class Size2d(Geometry):
    method __init__ (line 29) | def __init__(self, name, label=None, description=None, width=None, hei...
  class Vec2d (line 45) | class Vec2d(Geometry):
    method __init__ (line 49) | def __init__(self, name, label=None, description=None, x=None, y=None,...

FILE: meshroom/core/desc/node.py
  class ExitCleanup (line 26) | class ExitCleanup:
    method __init__ (line 31) | def __init__(self):
    method addSubprocess (line 35) | def addSubprocess(self, process):
    method exit (line 39) | def exit(self, signum, frame):
  class MrNodeType (line 53) | class MrNodeType(enum.Enum):
  class InternalAttributesFactory (line 62) | class InternalAttributesFactory:
    method getInternalAttributes (line 152) | def getInternalAttributes(cls, mrNodeType: MrNodeType) -> list[Attribu...
  class BaseNode (line 165) | class BaseNode(object):
    method __init__ (line 188) | def __init__(self):
    method getMrNodeType (line 193) | def getMrNodeType(self):
    method resolvedCpu (line 197) | def resolvedCpu(cls, node):
    method resolvedGpu (line 206) | def resolvedGpu(cls, node):
    method resolvedRam (line 215) | def resolvedRam(cls, node):
    method resolvedSize (line 224) | def resolvedSize(cls, node):
    method upgradeAttributeValues (line 241) | def upgradeAttributeValues(self, attrValues, fromVersion):
    method onNodeCreated (line 245) | def onNodeCreated(cls, node):
    method update (line 252) | def update(cls, node):
    method postUpdate (line 263) | def postUpdate(cls, node):
    method preprocess (line 273) | def preprocess(self, node):
    method postprocess (line 281) | def postprocess(self, node):
    method process (line 289) | def process(self, node):
    method processChunk (line 292) | def processChunk(self, chunk):
    method executeChunkCommandLine (line 298) | def executeChunkCommandLine(self, chunk, cmd, env=None):
    method stopProcess (line 362) | def stopProcess(self, chunk):
  class InputNode (line 391) | class InputNode(BaseNode):
    method __init__ (line 398) | def __init__(self):
    method getMrNodeType (line 401) | def getMrNodeType(self):
    method processChunk (line 404) | def processChunk(self, chunk):
    method process (line 407) | def process(self, node):
  class BackdropNode (line 410) | class BackdropNode(BaseNode):
    method __init__ (line 417) | def __init__(self):
    method getMrNodeType (line 420) | def getMrNodeType(self):
    method processChunk (line 423) | def processChunk(self, chunk):
    method process (line 426) | def process(self, node):
  class Node (line 430) | class Node(BaseNode):
    method __init__ (line 434) | def __init__(self):
    method getMrNodeType (line 437) | def getMrNodeType(self):
    method processChunkInEnvironment (line 440) | def processChunkInEnvironment(self, chunk):
  class CommandLineNode (line 455) | class CommandLineNode(BaseNode):
    method __init__ (line 463) | def __init__(self):
    method getMrNodeType (line 466) | def getMrNodeType(self):
    method buildCommandLine (line 469) | def buildCommandLine(self, chunk) -> str:
    method processChunk (line 489) | def processChunk(self, chunk):
  class AVCommandLineNode (line 496) | class AVCommandLineNode(CommandLineNode):
    method __init__ (line 502) | def __init__(self):
    method buildCommandLine (line 519) | def buildCommandLine(self, chunk) -> str:
  class InitNode (line 525) | class InitNode(object):
    method __init__ (line 526) | def __init__(self):
    method initialize (line 529) | def initialize(self, node, inputs, recursiveInputs):
    method resetAttributes (line 541) | def resetAttributes(self, node, attributeNames):
    method extendAttributes (line 553) | def extendAttributes(self, node, attributesDict):
    method setAttributes (line 566) | def setAttributes(self, node, attributesDict):

FILE: meshroom/core/desc/shapeAttribute.py
  class Shape (line 3) | class Shape(GroupAttribute):
    method __init__ (line 8) | def __init__(self, geometryItems, name, label, description, commandLin...
    method getInstanceType (line 24) | def getInstanceType(self):
  class ShapeList (line 32) | class ShapeList(ListAttribute):
    method __init__ (line 37) | def __init__(self, shape: Shape, name, label, description, commandLine...
    method getInstanceType (line 44) | def getInstanceType(self):
  class Point2d (line 52) | class Point2d(Shape):
    method __init__ (line 56) | def __init__(self, name, label, description, keyable=False, keyType=None,
  class Line2d (line 70) | class Line2d(Shape):
    method __init__ (line 74) | def __init__(self, name, label, description, keyable=False, keyType=None,
  class Rectangle (line 88) | class Rectangle(Shape):
    method __init__ (line 92) | def __init__(self, name, label, description, keyable=False, keyType=None,
  class Circle (line 108) | class Circle(Shape):
    method __init__ (line 112) | def __init__(self, name, label, description, keyable=False, keyType=None,

FILE: meshroom/core/evaluation.py
  class MathEvaluator (line 6) | class MathEvaluator:
    method _validate_ast (line 34) | def _validate_ast(self, node):
    method evaluate (line 43) | def evaluate(self, expr: str):

FILE: meshroom/core/exception.py
  class MeshroomException (line 4) | class MeshroomException(Exception):
  class GraphException (line 9) | class GraphException(MeshroomException):
  class InvalidEdgeError (line 14) | class InvalidEdgeError(GraphException):
    method __init__ (line 16) | def __init__(self, srcAttrName: str, dstAttrName: str, msg: str) -> None:
  class GraphCompatibilityError (line 20) | class GraphCompatibilityError(GraphException):
    method __init__ (line 28) | def __init__(self, filepath, issues: dict[str, str]) -> None:
  class UnknownNodeTypeError (line 35) | class UnknownNodeTypeError(GraphException):
    method __init__ (line 39) | def __init__(self, nodeType, msg=None):
  class NodeUpgradeError (line 45) | class NodeUpgradeError(GraphException):
    method __init__ (line 46) | def __init__(self, nodeName, details=None):
  class GraphVisitMessage (line 53) | class GraphVisitMessage(GraphException):
  class StopGraphVisit (line 58) | class StopGraphVisit(GraphVisitMessage):
  class StopBranchVisit (line 63) | class StopBranchVisit(GraphVisitMessage):
  class CyclicDependencyError (line 68) | class CyclicDependencyError(GraphVisitMessage):

FILE: meshroom/core/fileUtils.py
  function getFileElements (line 8) | def getFileElements(inputFilePath: str):
  function getViewElements (line 32) | def getViewElements(vp):
  function replacePatterns (line 45) | def replacePatterns(input, pattern, replacements):
  function resolvePath (line 56) | def resolvePath(input, outputTemplate: str) -> str:

FILE: meshroom/core/graph.py
  class MyJSONEncoder (line 32) | class MyJSONEncoder(DefaultJSONEncoder):  # declare a new one with Enum ...
    method default (line 33) | def default(self, obj):
  function GraphModification (line 43) | def GraphModification(graph):
  class Edge (line 65) | class Edge(BaseObject):
    method __init__ (line 67) | def __init__(self, src, dst, parent=None):
    method src (line 74) | def src(self):
    method dst (line 78) | def dst(self):
  class Visitor (line 90) | class Visitor:
    method __init__ (line 95) | def __init__(self, reverse, dependenciesOnly):
    method discoverVertex (line 107) | def discoverVertex(self, u, g):
    method examineEdge (line 111) | def examineEdge(self, e, g):
    method treeEdge (line 115) | def treeEdge(self, e, g):
    method backEdge (line 122) | def backEdge(self, e, g):
    method forwardOrCrossEdge (line 126) | def forwardOrCrossEdge(self, e, g):
    method finishEdge (line 133) | def finishEdge(self, e, g):
    method finishVertex (line 140) | def finishVertex(self, u, g):
  function changeTopology (line 149) | def changeTopology(func):
  function blockNodeCallbacks (line 166) | def blockNodeCallbacks(func):
  function generateTempProjectFilepath (line 181) | def generateTempProjectFilepath(tmpFolder=None):
  class Graph (line 194) | class Graph(BaseObject):
    method __init__ (line 210) | def __init__(self, name: str = "", parent: BaseObject = None):
    method clear (line 230) | def clear(self):
    method _clearGraphContent (line 235) | def _clearGraphContent(self):
    method fileFeatures (line 244) | def fileFeatures(self):
    method isLoading (line 249) | def isLoading(self):
    method isSaving (line 254) | def isSaving(self):
    method load (line 259) | def load(self, filepath: PathLike):
    method initFromTemplate (line 270) | def initFromTemplate(self, filepath: PathLike, copyOutputs: bool = Fal...
    method _loadGraphData (line 294) | def _loadGraphData(filepath: PathLike) -> dict:
    method _deserialize (line 301) | def _deserialize(self, graphData: dict):
    method _normalizeGraphContent (line 338) | def _normalizeGraphContent(self, graphData: dict, fileVersion: Version...
    method _deserializeNode (line 359) | def _deserializeNode(self, nodeData: dict, nodeName: str, fromGraph: "...
    method _getNodeTypeVersionFromHeader (line 372) | def _getNodeTypeVersionFromHeader(self, nodeType: str, default: Option...
    method _evaluateUidConflicts (line 376) | def _evaluateUidConflicts(self, graphContent: dict):
    method importGraphContentFromFile (line 424) | def importGraphContentFromFile(self, filepath: PathLike) -> list[Node]:
    method importGraphContent (line 437) | def importGraphContent(self, graph: "Graph") -> list[Node]:
    method updateEnabled (line 477) | def updateEnabled(self):
    method updateEnabled (line 481) | def updateEnabled(self, enabled):
    method _addNode (line 489) | def _addNode(self, node, uniqueName):
    method addNode (line 505) | def addNode(self, node, uniqueName=None):
    method renameNode (line 516) | def renameNode(self, node: Node, newName: str):
    method copyNode (line 540) | def copyNode(self, srcNode: Node, withEdges: bool=False):
    method duplicateNodes (line 574) | def duplicateNodes(self, srcNodes):
    method outEdges (line 611) | def outEdges(self, attribute):
    method nodeInEdges (line 616) | def nodeInEdges(self, node):
    method nodeOutEdges (line 621) | def nodeOutEdges(self, node):
    method removeNode (line 627) | def removeNode(self, nodeName):
    method addNewNode (line 678) | def addNewNode(
    method _triggerNodeCreatedCallback (line 701) | def _triggerNodeCreatedCallback(self, nodes: Iterable[Node]):
    method _createUniqueNodeName (line 710) | def _createUniqueNodeName(self, inputName: str, existingNames: Optiona...
    method node (line 727) | def node(self, nodeName) -> Optional[Node]:
    method upgradeNode (line 730) | def upgradeNode(self, nodeName) -> Node:
    method replaceNode (line 754) | def replaceNode(self, nodeName: str, newNode: BaseNode):
    method _restoreOutEdges (line 767) | def _restoreOutEdges(self, outEdges: dict[str, str], outListAttributes):
    method upgradeAllNodes (line 801) | def upgradeAllNodes(self):
    method reloadNodePlugins (line 808) | def reloadNodePlugins(self, nodeTypes: list[str]):
    method attribute (line 833) | def attribute(self, fullName):
    method internalAttribute (line 845) | def internalAttribute(self, fullName):
    method getNodeIndexFromName (line 857) | def getNodeIndexFromName(name):
    method sortNodesByIndex (line 871) | def sortNodesByIndex(nodes):
    method nodesOfType (line 883) | def nodesOfType(self, nodeType, sortedByIndex=True):
    method findInitNodes (line 896) | def findInitNodes(self):
    method findNodeCandidates (line 904) | def findNodeCandidates(self, nodeNameExpr: str) -> list[Node]:
    method findNode (line 908) | def findNode(self, nodeExpr: str) -> Node:
    method findNodes (line 919) | def findNodes(self, nodesExpr):
    method edge (line 924) | def edge(self, dstAttributeName):
    method getLeafNodes (line 927) | def getLeafNodes(self, dependenciesOnly):
    method getRootNodes (line 931) | def getRootNodes(self, dependenciesOnly):
    method addEdge (line 936) | def addEdge(self, srcAttr: Attribute, dstAttr: Attribute) -> tuple[lis...
    method removeEdge (line 957) | def removeEdge(self, dstAttr: Attribute):
    method getDepth (line 968) | def getDepth(self, node, minimal=False):
    method getInputEdges (line 983) | def getInputEdges(self, node, dependenciesOnly):
    method _getInputEdgesPerNode (line 986) | def _getInputEdgesPerNode(self, dependenciesOnly):
    method _getOutputEdgesPerNode (line 994) | def _getOutputEdgesPerNode(self, dependenciesOnly):
    method dfs (line 1002) | def dfs(self, visitor, startNodes=None, longestPathFirst=False):
    method dfsVisit (line 1032) | def dfsVisit(self, u, visitor, colors, nodeChildren, longestPathFirst):
    method _dfsVisit (line 1038) | def _dfsVisit(self, u, visitor, colors, nodeChildren, longestPathFirst):
    method dfsOnFinish (line 1062) | def dfsOnFinish(self, startNodes=None, longestPathFirst=False, reverse...
    method dfsOnDiscover (line 1085) | def dfsOnDiscover(self, startNodes=None, filterTypes=None, longestPath...
    method dfsToProcess (line 1115) | def dfsToProcess(self, startNodes=None):
    method canComputeTopologically (line 1159) | def canComputeTopologically(self, node):
    method updateNodesTopologicalData (line 1177) | def updateNodesTopologicalData(self):
    method dfsMaxEdgeLength (line 1239) | def dfsMaxEdgeLength(self, startNodes=None, dependenciesOnly=True):
    method flowEdges (line 1265) | def flowEdges(self, startNodes=None, dependenciesOnly=True):
    method getEdges (line 1282) | def getEdges(self, dependenciesOnly=False):
    method getInputNodes (line 1298) | def getInputNodes(self, node, recursive, dependenciesOnly):
    method getOutputNodes (line 1306) | def getOutputNodes(self, node, recursive, dependenciesOnly):
    method canSubmitOrCompute (line 1315) | def canSubmitOrCompute(self, startNode):
    method _applyExpr (line 1346) | def _applyExpr(self):
    method toDict (line 1351) | def toDict(self):
    method asString (line 1357) | def asString(self):
    method copy (line 1360) | def copy(self) -> "Graph":
    method serialize (line 1366) | def serialize(self, asTemplate: bool = False) -> dict:
    method serializePartial (line 1379) | def serializePartial(self, nodes: list[Node]) -> dict:
    method save (line 1391) | def save(self, filepath=None, setupProjectFile=True, template=False):
    method _generateNextPath (line 1408) | def _generateNextPath(self):
    method saveAsNewVersion (line 1436) | def saveAsNewVersion(self):
    method _save (line 1449) | def _save(self, filepath=None, setupProjectFile=True, template=False):
    method saveAsTemp (line 1465) | def saveAsTemp(self, tmpFolder=None):
    method _saveAsTemp (line 1476) | def _saveAsTemp(self, tmpFolder=None):
    method _setFilepath (line 1480) | def _setFilepath(self, filepath):
    method _unsetFilepath (line 1504) | def _unsetFilepath(self):
    method updateInternals (line 1510) | def updateInternals(self, startNodes=None, force=False):
    method updateStatusFromCache (line 1516) | def updateStatusFromCache(self, force=False):
    method updateStatisticsFromCache (line 1521) | def updateStatisticsFromCache(self):
    method updateNodesPerUid (line 1525) | def updateNodesPerUid(self):
    method updateJobManagerWithNode (line 1543) | def updateJobManagerWithNode(self, node):
    method update (line 1560) | def update(self):
    method updateMonitoredFiles (line 1583) | def updateMonitoredFiles(self):
    method markNodesDirty (line 1586) | def markNodesDirty(self, fromNode):
    method stopExecution (line 1602) | def stopExecution(self):
    method forceUnlockNodes (line 1613) | def forceUnlockNodes(self, nodes=None):
    method clearSubmittedNodes (line 1621) | def clearSubmittedNodes(self, nodes=None):
    method clearLocallySubmittedNodes (line 1627) | def clearLocallySubmittedNodes(self):
    method getChunksByStatus (line 1632) | def getChunksByStatus(self, status):
    method getChunks (line 1639) | def getChunks(self, nodes=None):
    method getOrderedChunks (line 1648) | def getOrderedChunks(self):
    method nodes (line 1657) | def nodes(self):
    method edges (line 1661) | def edges(self):
    method cacheDir (line 1665) | def cacheDir(self):
    method cacheDir (line 1669) | def cacheDir(self, value):
    method fileDateVersion (line 1679) | def fileDateVersion(self):
    method fileDateVersion (line 1683) | def fileDateVersion(self, value):
    method getFileDateVersionFromPath (line 1687) | def getFileDateVersionFromPath(self, value):
    method setVerbose (line 1690) | def setVerbose(self, v):
  function loadGraph (line 1715) | def loadGraph(filepath, strictCompatibility: bool = False) -> Graph:
  function getAlreadySubmittedChunks (line 1740) | def getAlreadySubmittedChunks(nodes):
  function executeGraph (line 1749) | def executeGraph(graph, toNodes=None, forceCompute=False, forceStatus=Fa...
  function submitGraph (line 1806) | def submitGraph(graph, submitter, toNodes=None, submitLabel="{projectNam...
  function submit (line 1845) | def submit(graphFile, submitter, toNode=None, submitLabel="{projectName}"):

FILE: meshroom/core/graphIO.py
  class GraphIO (line 13) | class GraphIO:
    class Keys (line 18) | class Keys:
    class Features (line 29) | class Features(Enum):
    method getFeaturesForVersion (line 39) | def getFeaturesForVersion(fileVersion: Union[str, Version]) -> tuple["...
  class GraphSerializer (line 65) | class GraphSerializer:
    method __init__ (line 68) | def __init__(self, graph: "Graph") -> None:
    method serialize (line 71) | def serialize(self) -> dict:
    method nodes (line 81) | def nodes(self) -> list[Node]:
    method serializeHeader (line 84) | def serializeHeader(self) -> dict:
    method _getNodeTypesVersions (line 99) | def _getNodeTypesVersions(self) -> dict[str, str]:
    method serializeContent (line 110) | def serializeContent(self) -> dict:
    method serializeNode (line 114) | def serializeNode(self, node: Node) -> dict:
  class TemplateGraphSerializer (line 119) | class TemplateGraphSerializer(GraphSerializer):
    method serializeHeader (line 122) | def serializeHeader(self) -> dict:
    method serializeNode (line 127) | def serializeNode(self, node: Node) -> dict:
  class PartialGraphSerializer (line 168) | class PartialGraphSerializer(GraphSerializer):
    method __init__ (line 171) | def __init__(self, graph: "Graph", nodes: list[Node]):
    method nodes (line 176) | def nodes(self) -> list[Node]:
    method serializeNode (line 180) | def serializeNode(self, node: Node) -> dict:
    method _serializeAttribute (line 198) | def _serializeAttribute(self, attribute: Attribute) -> Any:

FILE: meshroom/core/keyValues.py
  class KeyValues (line 7) | class KeyValues(BaseObject):
    class KeyValuePair (line 12) | class KeyValuePair(BaseObject):
      method __init__ (line 16) | def __init__(self, key: int, value: Any, parent=None):
    method __init__ (line 24) | def __init__(self, desc: desc.Attribute, parent=None):
    method reset (line 36) | def reset(self):
    method resetFromDict (line 43) | def resetFromDict(self, pairs: dict):
    method add (line 52) | def add(self, key: str, value: Any):
    method remove (line 68) | def remove(self, key: str):
    method getSerializedValues (line 79) | def getSerializedValues(self) -> Any:
    method getKeys (line 85) | def getKeys(self) -> list:
    method getJson (line 91) | def getJson(self) -> str:
    method uid (line 97) | def uid(self) -> str:
    method hasKey (line 107) | def hasKey(self, key: str) -> bool:
    method getValueAtKeyOrDefault (line 114) | def getValueAtKeyOrDefault(self, key: str) -> Any:

FILE: meshroom/core/node.py
  function getWritingFilepath (line 26) | def getWritingFilepath(filepath: str) -> str:
  function renameWritingToFinalPath (line 30) | def renameWritingToFinalPath(writingFilepath: str, filepath: str) -> str:
  class Status (line 43) | class Status(Enum):
  class ExecMode (line 56) | class ExecMode(Enum):
  class NodeStatusData (line 67) | class NodeStatusData(BaseObject):
    method __init__ (line 71) | def __init__(self, nodeName='', nodeType='', packageName='',
    method reset (line 84) | def reset(self):
    method resetChunkInfo (line 88) | def resetChunkInfo(self):
    method resetDynamicValues (line 91) | def resetDynamicValues(self):
    method setNodeType (line 96) | def setNodeType(self, node):
    method setNode (line 105) | def setNode(self, node):
    method setJob (line 110) | def setJob(self, jid, submitterName):
    method jobName (line 118) | def jobName(self):
    method initExternSubmit (line 124) | def initExternSubmit(self):
    method initLocalSubmit (line 134) | def initLocalSubmit(self):
    method toDict (line 144) | def toDict(self):
    method fromDict (line 156) | def fromDict(self, d):
    method loadFromCache (line 173) | def loadFromCache(self, statusFile):
    method nbChunks (line 184) | def nbChunks(self):
    method fullSize (line 189) | def fullSize(self):
    method getChunkRanges (line 193) | def getChunkRanges(self):
    method setChunks (line 206) | def setChunks(self, chunks):
  class ChunkStatusData (line 215) | class ChunkStatusData(BaseObject):
    method __init__ (line 225) | def __init__(self, nodeName='', mrNodeType: MrNodeType = MrNodeType.NO...
    method resetDynamicValues (line 237) | def resetDynamicValues(self):
    method setNode (line 246) | def setNode(self, node):
    method merge (line 251) | def merge(self, other):
    method reset (line 256) | def reset(self):
    method initStartCompute (line 262) | def initStartCompute(self):
    method initIsolatedCompute (line 274) | def initIsolatedCompute(self):
    method initExternSubmit (line 284) | def initExternSubmit(self):
    method initLocalSubmit (line 294) | def initLocalSubmit(self):
    method initEndCompute (line 304) | def initEndCompute(self):
    method elapsedTimeStr (line 311) | def elapsedTimeStr(self):
    method toDict (line 314) | def toDict(self):
    method fromDict (line 322) | def fromDict(self, d):
  class LogManager (line 335) | class LogManager:
    method __init__ (line 338) | def __init__(self, logger, logFile):
    class Formatter (line 344) | class Formatter(logging.Formatter):
      method format (line 345) | def format(self, record):
    method configureLogger (line 350) | def configureLogger(self):
    method restorePreviousLogger (line 362) | def restorePreviousLogger(self):
    method clearLogFile (line 369) | def clearLogFile(self):
    method start (line 372) | def start(self, level):
    method end (line 381) | def end(self):
    method makeProgressBar (line 386) | def makeProgressBar(self, end, message=''):
    method updateProgressBar (line 408) | def updateProgressBar(self, value):
    method completeProgressBar (line 424) | def completeProgressBar(self):
    method textToLevel (line 430) | def textToLevel(text):
  function clearProcessesStatus (line 452) | def clearProcessesStatus():
  class NodeChunk (line 457) | class NodeChunk(BaseObject):
    method __init__ (line 458) | def __init__(self, node, range, parent=None):
    method __repr__ (line 470) | def __repr__(self):
    method index (line 474) | def index(self):
    method name (line 478) | def name(self):
    method logManager (line 485) | def logManager(self):
    method getStatusName (line 491) | def getStatusName(self):
    method logger (line 495) | def logger(self):
    method getExecModeName (line 498) | def getExecModeName(self):
    method shouldMonitorChanges (line 501) | def shouldMonitorChanges(self):
    method updateStatusFromCache (line 512) | def updateStatusFromCache(self):
    method _getFile (line 542) | def _getFile(self, fileType: str):
    method getStatusFile (line 555) | def getStatusFile(self):
    method getStatisticsFile (line 558) | def getStatisticsFile(self):
    method getLogFile (line 561) | def getLogFile(self):
    method saveStatusFile (line 564) | def saveStatusFile(self):
    method upgradeStatusFile (line 578) | def upgradeStatusFile(self):
    method upgradeStatusTo (line 587) | def upgradeStatusTo(self, newStatus, execMode=None):
    method updateStatisticsFromCache (line 596) | def updateStatisticsFromCache(self):
    method saveStatistics (line 609) | def saveStatistics(self):
    method isAlreadySubmitted (line 619) | def isAlreadySubmitted(self):
    method isAlreadySubmittedOrFinished (line 622) | def isAlreadySubmittedOrFinished(self):
    method isFinishedOrRunning (line 625) | def isFinishedOrRunning(self):
    method isRunning (line 628) | def isRunning(self):
    method isStopped (line 631) | def isStopped(self):
    method isFinished (line 634) | def isFinished(self):
    method process (line 637) | def process(self, forceCompute=False, inCurrentEnv=False):
    method _processInIsolatedEnvironment (line 687) | def _processInIsolatedEnvironment(self):
    method stopProcess (line 712) | def stopProcess(self):
    method isExtern (line 737) | def isExtern(self):
  class BaseNode (line 774) | class BaseNode(BaseObject):
    method __init__ (line 783) | def __init__(self, nodeType: str, position: Position = None, parent: B...
    method __getattr__ (line 840) | def __getattr__(self, k):
    method getMrNodeType (line 850) | def getMrNodeType(self):
    method getName (line 857) | def getName(self):
    method getDefaultLabel (line 860) | def getDefaultLabel(self):
    method getLabel (line 863) | def getLabel(self) -> str:
    method getNodeLogLevel (line 874) | def getNodeLogLevel(self) -> str:
    method getColor (line 883) | def getColor(self) -> str:
    method getInvalidationMessage (line 893) | def getInvalidationMessage(self) -> str:
    method getComment (line 902) | def getComment(self) -> str:
    method getFontSize (line 911) | def getFontSize(self) -> int:
    method getFontColor (line 920) | def getFontColor(self) -> str:
    method getNodeWidth (line 929) | def getNodeWidth(self) -> int:
    method getNodeHeight (line 938) | def getNodeHeight(self) -> int:
    method nameToLabel (line 949) | def nameToLabel(self, name):
    method getDocumentation (line 957) | def getDocumentation(self):
    method getNodeInfo (line 965) | def getNodeInfo(self):
    method attribute (line 993) | def attribute(self, name):
    method internalAttribute (line 1016) | def internalAttribute(self, name):
    method setInternalAttributeValues (line 1021) | def setInternalAttributeValues(self, values):
    method getAttributes (line 1027) | def getAttributes(self):
    method getInternalAttributes (line 1030) | def getInternalAttributes(self):
    method hasAttribute (line 1034) | def hasAttribute(self, name):
    method hasInternalAttribute (line 1043) | def hasInternalAttribute(self, name):
    method _applyExpr (line 1046) | def _applyExpr(self):
    method nodeType (line 1051) | def nodeType(self):
    method position (line 1055) | def position(self):
    method position (line 1060) | def position(self, value):
    method alive (line 1072) | def alive(self):
    method alive (line 1076) | def alive(self, value):
    method depth (line 1083) | def depth(self):
    method minDepth (line 1087) | def minDepth(self):
    method valuesFile (line 1091) | def valuesFile(self):
    method getInputNodes (line 1094) | def getInputNodes(self, recursive, dependenciesOnly):
    method getOutputNodes (line 1098) | def getOutputNodes(self, recursive, dependenciesOnly):
    method toDict (line 1102) | def toDict(self):
    method _computeUid (line 1105) | def _computeUid(self):
    method _computeInternalFolder (line 1133) | def _computeInternalFolder(self, cacheDir):
    method _buildExpVars (line 1139) | def _buildExpVars(self):
    method createCmdLineVars (line 1209) | def createCmdLineVars(self):
    method isParallelized (line 1261) | def isParallelized(self):
    method cpu (line 1265) | def cpu(self):
    method gpu (line 1273) | def gpu(self):
    method ram (line 1281) | def ram(self):
    method hasStatus (line 1288) | def hasStatus(self, status: Status):
    method _isComputed (line 1298) | def _isComputed(self):
    method _isComputableType (line 1303) | def _isComputableType(self):
    method clearData (line 1311) | def clearData(self):
    method getStartDateTime (line 1332) | def getStartDateTime(self):
    method isAlreadySubmitted (line 1338) | def isAlreadySubmitted(self):
    method isAlreadySubmittedOrFinished (line 1344) | def isAlreadySubmittedOrFinished(self):
    method isSubmittedOrRunning (line 1351) | def isSubmittedOrRunning(self):
    method isRunning (line 1366) | def isRunning(self):
    method isFinishedOrRunning (line 1371) | def isFinishedOrRunning(self):
    method isPartiallyFinished (line 1381) | def isPartiallyFinished(self):
    method isExtern (line 1385) | def isExtern(self):
    method clearSubmittedChunks (line 1405) | def clearSubmittedChunks(self):
    method clearLocallySubmittedChunks (line 1423) | def clearLocallySubmittedChunks(self):
    method upgradeStatusTo (line 1434) | def upgradeStatusTo(self, newStatus, execMode=None):
    method updateStatisticsFromCache (line 1451) | def updateStatisticsFromCache(self):
    method _resetChunks (line 1455) | def _resetChunks(self):
    method createChunksFromCache (line 1458) | def createChunksFromCache(self):
    method _createChunks (line 1461) | def _createChunks(self):
    method evaluateSize (line 1464) | def evaluateSize(self):
    method _updateNodeSize (line 1470) | def _updateNodeSize(self):
    method _getAttributeChangedCallback (line 1473) | def _getAttributeChangedCallback(self, attr: Attribute) -> Optional[Ca...
    method _onAttributeChanged (line 1486) | def _onAttributeChanged(self, attr: Attribute):
    method onAttributeClicked (line 1523) | def onAttributeClicked(self, attr):
    method updateInternals (line 1538) | def updateInternals(self, cacheDir=None):
    method updateInternalAttributes (line 1573) | def updateInternalAttributes(self):
    method internalFolder (line 1577) | def internalFolder(self):
    method sourceCodeFolder (line 1581) | def sourceCodeFolder(self):
    method nodeStatusFile (line 1585) | def nodeStatusFile(self):
    method shouldMonitorChanges (line 1588) | def shouldMonitorChanges(self):
    method updateNodeStatusFromCache (line 1600) | def updateNodeStatusFromCache(self):
    method updateStatusFromCache (line 1620) | def updateStatusFromCache(self):
    method upgradeStatusFile (line 1645) | def upgradeStatusFile(self):
    method setJobId (line 1658) | def setJobId(self, jid, submitterName):
    method initStatusOnSubmit (line 1662) | def initStatusOnSubmit(self, forceCompute=False):
    method initStatusOnCompute (line 1685) | def initStatusOnCompute(self, forceCompute=False):
    method processIteration (line 1707) | def processIteration(self, iteration):
    method preprocess (line 1710) | def preprocess(self):
    method process (line 1714) | def process(self, forceCompute=False, inCurrentEnv=False):
    method postprocess (line 1718) | def postprocess(self):
    method getLogHandlers (line 1723) | def getLogHandlers(self):
    method prepareLogger (line 1726) | def prepareLogger(self, iteration=-1):
    method restoreLogger (line 1737) | def restoreLogger(self):
    method updateOutputAttr (line 1740) | def updateOutputAttr(self):
    method resetOutputAttr (line 1751) | def resetOutputAttr(self):
    method loadOutputAttr (line 1762) | def loadOutputAttr(self):
    method saveOutputAttr (line 1789) | def saveOutputAttr(self):
    method endSequence (line 1809) | def endSequence(self):
    method stopComputation (line 1812) | def stopComputation(self):
    method getGlobalStatus (line 1824) | def getGlobalStatus(self):
    method getFusedStatus (line 1857) | def getFusedStatus(self):
    method getRecursiveFusedStatus (line 1868) | def getRecursiveFusedStatus(self):
    method _isCompatibilityNode (line 1875) | def _isCompatibilityNode(self):
    method _isInputNode (line 1878) | def _isInputNode(self):
    method _isBackdropNode (line 1881) | def _isBackdropNode(self) -> bool:
    method globalExecMode (line 1885) | def globalExecMode(self):
    method _getJobName (line 1893) | def _getJobName(self):
    method getChunks (line 1902) | def getChunks(self) -> list[NodeChunk]:
    method getSize (line 1905) | def getSize(self):
    method setSize (line 1908) | def setSize(self, value):
    method __repr__ (line 1914) | def __repr__(self):
    method getLocked (line 1917) | def getLocked(self):
    method setLocked (line 1920) | def setLocked(self, lock):
    method updateDuplicatesStatusAndLocked (line 1927) | def updateDuplicatesStatusAndLocked(self):
    method updateLocked (line 1935) | def updateLocked(self):
    method updateDuplicates (line 1986) | def updateDuplicates(self, nodesPerUid):
    method initFromThisSession (line 2016) | def initFromThisSession(self) -> bool:
    method isMainNode (line 2026) | def isMainNode(self) -> bool:
    method canBeStopped (line 2037) | def canBeStopped(self) -> bool:
    method canBeCanceled (line 2060) | def canBeCanceled(self) -> bool:
    method hasImageOutputAttribute (line 2082) | def hasImageOutputAttribute(self) -> bool:
    method hasSequenceOutputAttribute (line 2094) | def hasSequenceOutputAttribute(self) -> bool:
    method has3DOutputAttribute (line 2106) | def has3DOutputAttribute(self):
    method hasTextOutputAttribute (line 2113) | def hasTextOutputAttribute(self) -> bool:
    method _hasDisplayableShape (line 2120) | def _hasDisplayableShape(self):
  class Node (line 2200) | class Node(BaseNode):
    method __init__ (line 2204) | def __init__(self, nodeType, position=None, parent=None, uid=None, **k...
    method setAttributeValues (line 2241) | def setAttributeValues(self, values):
    method upgradeAttributeValues (line 2250) | def upgradeAttributeValues(self, values):
    method setInternalAttributeValues (line 2262) | def setInternalAttributeValues(self, values):
    method upgradeInternalAttributeValues (line 2271) | def upgradeInternalAttributeValues(self, values):
    method toDict (line 2283) | def toDict(self):
    method _resetChunks (line 2303) | def _resetChunks(self):
    method __createChunks (line 2351) | def __createChunks(self, ranges):
    method createChunksFromCache (line 2380) | def createChunksFromCache(self):
    method createChunks (line 2394) | def createChunks(self):
  class BackdropNode (line 2419) | class BackdropNode(BaseNode):
    method __init__ (line 2420) | def __init__(self, nodeType: str, position=None, parent=None, uid=None...
    method _isBackdropNode (line 2434) | def _isBackdropNode(self) -> bool:
    method toDict (line 2437) | def toDict(self):
  class CompatibilityIssue (line 2453) | class CompatibilityIssue(Enum):
  class CompatibilityNode (line 2465) | class CompatibilityNode(BaseNode):
    method __init__ (line 2471) | def __init__(self, nodeType, nodeDict, position=None, issue=Compatibil...
    method _isCompatibilityNode (line 2509) | def _isCompatibilityNode(self):
    method _updateNodeSize (line 2512) | def _updateNodeSize(self):
    method attributeDescFromValue (line 2517) | def attributeDescFromValue(attrName, value, isOutput):
    method attributeDescFromName (line 2578) | def attributeDescFromName(refAttributes, name, value, strict=True):
    method _addAttribute (line 2618) | def _addAttribute(self, name, val, isOutput, internalAttr=False):
    method issueDetails (line 2649) | def issueDetails(self):
    method inputs (line 2663) | def inputs(self):
    method internalInputs (line 2672) | def internalInputs(self):
    method toDict (line 2678) | def toDict(self):
    method canUpgrade (line 2692) | def canUpgrade(self):
    method upgrade (line 2697) | def upgrade(self):

FILE: meshroom/core/nodeFactory.py
  function nodeFactory (line 10) | def nodeFactory(
  function getNodeConstructor (line 33) | def getNodeConstructor(nodeType: str, position: Optional[Position]=None,...
  class _NodeCreator (line 41) | class _NodeCreator:
    method __init__ (line 43) | def __init__(
    method create (line 68) | def create(self) -> Union[Node, BackdropNode, CompatibilityNode]:
    method _normalizeNodeData (line 77) | def _normalizeNodeData(self):
    method _checkCompatibilityIssues (line 84) | def _checkCompatibilityIssues(self) -> Optional[CompatibilityIssue]:
    method _checkUidCompatibility (line 101) | def _checkUidCompatibility(self) -> bool:
    method _checkVersionCompatibility (line 104) | def _checkVersionCompatibility(self) -> bool:
    method _checkDescriptionCompatibility (line 116) | def _checkDescriptionCompatibility(self) -> bool:
    method _checkAttributesNamesMatchDescription (line 125) | def _checkAttributesNamesMatchDescription(self) -> bool:
    method _checkAttributesAreCompatibleWithDescription (line 132) | def _checkAttributesAreCompatibleWithDescription(self) -> bool:
    method _checkInputAttributesNames (line 140) | def _checkInputAttributesNames(self) -> bool:
    method _checkOutputAttributesNames (line 151) | def _checkOutputAttributesNames(self) -> bool:
    method _checkInternalAttributesNames (line 163) | def _checkInternalAttributesNames(self) -> bool:
    method _checkAttributesNamesStrictlyMatch (line 167) | def _checkAttributesNamesStrictlyMatch(
    method _checkAttributesCompatibility (line 174) | def _checkAttributesCompatibility(
    method _createNode (line 182) | def _createNode(self) -> Union[BackdropNode, Node]:
    method _createCompatibilityNode (line 196) | def _createCompatibilityNode(self, compatibilityIssue) -> Compatibilit...
    method _tryUpgradeCompatibilityNode (line 202) | def _tryUpgradeCompatibilityNode(self, node: CompatibilityNode) -> Uni...

FILE: meshroom/core/plugins.py
  function validateNodeDesc (line 21) | def validateNodeDesc(nodeDesc: desc.BaseNode) -> list[tuple[str, ValueTy...
  function formatNodeDescriptionErrorMessage (line 56) | def formatNodeDescriptionErrorMessage(error: tuple[str, ValueTypeErrors]...
  class ProcessEnvType (line 77) | class ProcessEnvType(Enum):
  class ProcessEnv (line 83) | class ProcessEnv(BaseObject):
    method __init__ (line 95) | def __init__(self, folder: str, configEnv: dict[str, str],
    method getEnvDict (line 104) | def getEnvDict(self) -> dict:
    method getCommandPrefix (line 108) | def getCommandPrefix(self) -> str:
    method getCommandSuffix (line 112) | def getCommandSuffix(self) -> str:
  class DirTreeProcessEnv (line 117) | class DirTreeProcessEnv(ProcessEnv):
    method __init__ (line 120) | def __init__(self, folder: str, configEnv: dict[str: str]):
  class RezProcessEnv (line 174) | class RezProcessEnv(ProcessEnv):
    method __init__ (line 180) | def __init__(self, folder: str, configEnv: dict[str: str], uri: str = ...
    method resolveRezSubrequires (line 185) | def resolveRezSubrequires(self) -> list[str]:
    method getCommandPrefix (line 243) | def getCommandPrefix(self):
    method getCommandSuffix (line 253) | def getCommandSuffix(self):
  function processEnvFactory (line 257) | def processEnvFactory(folder: str, configEnv: dict[str: str], envType: s...
  class NodePluginStatus (line 263) | class NodePluginStatus(Enum):
  class Plugin (line 274) | class Plugin(BaseObject):
    method __init__ (line 291) | def __init__(self, name: str, path: str):
    method name (line 307) | def name(self):
    method path (line 312) | def path(self):
    method nodes (line 317) | def nodes(self):
    method templates (line 325) | def templates(self):
    method processEnv (line 330) | def processEnv(self):
    method processEnv (line 335) | def processEnv(self, processEnv: ProcessEnv):
    method configEnv (line 340) | def configEnv(self):
    method configFullEnv (line 348) | def configFullEnv(self):
    method addNodePlugin (line 352) | def addNodePlugin(self, nodePlugin: NodePlugin):
    method removeNodePlugin (line 364) | def removeNodePlugin(self, name: str):
    method loadTemplates (line 377) | def loadTemplates(self):
    method loadConfig (line 388) | def loadConfig(self):
    method containsNodePlugin (line 434) | def containsNodePlugin(self, name: str) -> bool:
  class NodePlugin (line 445) | class NodePlugin(BaseObject):
    method __init__ (line 463) | def __init__(self, nodeDesc: desc.BaseNode, plugin: Plugin = None):
    method reload (line 479) | def reload(self) -> bool:
    method plugin (line 531) | def plugin(self):
    method plugin (line 540) | def plugin(self, plugin: Plugin):
    method processEnv (line 545) | def processEnv(self):
    method runtimeEnv (line 557) | def runtimeEnv(self) -> dict:
    method commandPrefix (line 562) | def commandPrefix(self) -> str:
    method commandSuffix (line 569) | def commandSuffix(self) -> str:
    method configFullEnv (line 576) | def configFullEnv(self) -> dict[str: str]:
  class NodePluginManager (line 582) | class NodePluginManager(BaseObject):
    method __init__ (line 593) | def __init__(self):
    method isRegistered (line 599) | def isRegistered(self, name: str) -> bool:
    method belongsToPlugin (line 608) | def belongsToPlugin(self, name: str) -> Plugin:
    method getPlugins (line 624) | def getPlugins(self) -> dict[str: Plugin]:
    method getPlugin (line 631) | def getPlugin(self, name: str) -> Plugin:
    method addPlugin (line 645) | def addPlugin(self, plugin: Plugin, registerNodePlugins: bool = True):
    method removePlugin (line 661) | def removePlugin(self, plugin: Plugin, unregisterNodePlugins: bool = T...
    method getRegisteredNodePlugins (line 678) | def getRegisteredNodePlugins(self) -> dict[str: NodePlugin]:
    method getRegisteredNodePlugin (line 685) | def getRegisteredNodePlugin(self, name: str) -> NodePlugin:
    method registerNode (line 699) | def registerNode(self, nodePlugin: NodePlugin):
    method unregisterNode (line 718) | def unregisterNode(self, nodePlugin: NodePlugin):

FILE: meshroom/core/stats.py
  function bytes2human (line 13) | def bytes2human(n):
  class ComputerStatistics (line 31) | class ComputerStatistics:
    method __init__ (line 32) | def __init__(self):
    method initOnFirstTime (line 45) | def initOnFirstTime(self):
    method _addKV (line 66) | def _addKV(self, k, v):
    method update (line 76) | def update(self):
    method updateGpu (line 89) | def updateGpu(self):
    method toDict (line 136) | def toDict(self):
    method fromDict (line 139) | def fromDict(self, d):
  class ProcStatistics (line 144) | class ProcStatistics:
    method __init__ (line 180) | def __init__(self):
    method _addKV (line 187) | def _addKV(self, k, v):
    method update (line 197) | def update(self, proc):
    method toDict (line 219) | def toDict(self):
    method fromDict (line 226) | def fromDict(self, d):
  class Statistics (line 232) | class Statistics:
    method __init__ (line 237) | def __init__(self, maxPoints=100):
    method _filterDataPoints (line 244) | def _filterDataPoints(self, keepEveryN):
    method update (line 259) | def update(self, proc):
    method toDict (line 281) | def toDict(self):
    method fromDict (line 291) | def fromDict(self, d):
  class StatisticsThread (line 317) | class StatisticsThread(threading.Thread):
    method __init__ (line 318) | def __init__(self, chunk):
    method updateStats (line 325) | def updateStats(self):
    method run (line 330) | def run(self):
    method stopRequest (line 343) | def stopRequest(self):

FILE: meshroom/core/submitter.py
  class SubmitterOptionsEnum (line 19) | class SubmitterOptionsEnum(IntFlag):
    method get (line 27) | def get(cls, option):
  class SubmitterOptions (line 41) | class SubmitterOptions:
    method __init__ (line 42) | def __init__(self, *args):
    method addOption (line 47) | def addOption(self, option):
    method includes (line 51) | def includes(self, option):
    method __iter__ (line 55) | def __iter__(self):
    method __repr__ (line 60) | def __repr__(self):
  class BaseSubmittedJob (line 68) | class BaseSubmittedJob:
    method __init__ (line 73) | def __init__(self, jobId, submitter):
    method __repr__ (line 78) | def __repr__(self):
    method stopChunkTask (line 84) | def stopChunkTask(self, node, iteration):
    method skipChunkTask (line 93) | def skipChunkTask(self, node, iteration):
    method restartChunkTask (line 100) | def restartChunkTask(self, node, iteration):
    method pauseJob (line 109) | def pauseJob(self):
    method resumeJob (line 116) | def resumeJob(self):
    method interruptJob (line 123) | def interruptJob(self):
    method restartErrorTasks (line 130) | def restartErrorTasks(self):
  class JobManager (line 137) | class JobManager(BaseObject):
    method __init__ (line 140) | def __init__(self):
    method addJob (line 145) | def addJob(self, job: BaseSubmittedJob, nodes):
    method resetNodeJob (line 155) | def resetNodeJob(self, node):
    method getJob (line 160) | def getJob(self, jobId: str) -> Optional[BaseSubmittedJob]:
    method removeJob (line 163) | def removeJob(self, jobId: str):
    method getNodeJob (line 168) | def getNodeJob(self, node):
    method getAllNodesUIDForJob (line 175) | def getAllNodesUIDForJob(self, job):
    method retreiveJob (line 178) | def retreiveJob(self, submitter, jid) -> Optional[BaseSubmittedJob]:
  class BaseSubmitter (line 189) | class BaseSubmitter(BaseObject):
    method __init__ (line 193) | def __init__(self, parent=None):
    method name (line 200) | def name(self):
    method createJob (line 203) | def createJob(self, nodes, edges, filepath, submitLabel="{projectName}"):
    method createChunkTask (line 210) | def createChunkTask(self, node, graphFile, **kwargs):
    method retrieveJob (line 216) | def retrieveJob(self, jobId) -> BaseSubmittedJob:
    method submit (line 219) | def submit(self, nodes, edges, filepath, submitLabel="{projectName}") ...
    method killRunningJob (line 231) | def killRunningJob():

FILE: meshroom/core/taskManager.py
  class State (line 15) | class State(Enum):
  class TaskThread (line 26) | class TaskThread(QThread):
    method __init__ (line 30) | def __init__(self, manager):
    method isRunning (line 38) | def isRunning(self):
    method waitForChunkCreation (line 41) | def waitForChunkCreation(self, node):
    method run (line 71) | def run(self):
  class TaskManager (line 149) | class TaskManager(BaseObject):
    method __init__ (line 153) | def __init__(self, parent: BaseObject = None):
    method join (line 166) | def join(self):
    method createChunks (line 171) | def createChunks(self, node: Node):
    method isChunkCancelled (line 183) | def isChunkCancelled(self, chunk):
    method requestBlockRestart (line 190) | def requestBlockRestart(self):
    method blockRestart (line 197) | def blockRestart(self):
    method pauseProcess (line 214) | def pauseProcess(self):
    method restart (line 230) | def restart(self):
    method compute (line 263) | def compute(self, graph: Graph = None, toNodes: list[Node] = None, for...
    method onNodeDestroyed (line 339) | def onNodeDestroyed(self, obj, name):
    method contains (line 349) | def contains(self, node):
    method containsNodeName (line 352) | def containsNodeName(self, name):
    method removeNode (line 358) | def removeNode(self, node, displayList=True, processList=False, extern...
    method clear (line 374) | def clear(self):
    method updateNodes (line 383) | def updateNodes(self):
    method update (line 393) | def update(self, graph):
    method checkCompatibilityNodes (line 404) | def checkCompatibilityNodes(self, graph, nodes, context):
    method checkDuplicates (line 416) | def checkDuplicates(self, nodesToProcess, context):
    method checkNodesDependencies (line 428) | def checkNodesDependencies(self, graph, toNodes, context):
    method raiseDependenciesMessage (line 462) | def raiseDependenciesMessage(self, context):
    method raiseImpossibleProcess (line 470) | def raiseImpossibleProcess(self, context):
    method submit (line 476) | def submit(self, graph, submitter=None, toNodes=None, submitLabel="{pr...
    method submitFromFile (line 556) | def submitFromFile(self, graphFile, submitter, toNode=None, submitLabe...
    method getAlreadySubmittedChunks (line 563) | def getAlreadySubmittedChunks(self, nodes):

FILE: meshroom/core/test.py
  function checkTemplateVersions (line 11) | def checkTemplateVersions(path: str, nodesAlreadyLoaded: bool = False) -...
  function checkAllTemplatesVersions (line 71) | def checkAllTemplatesVersions() -> bool:

FILE: meshroom/env.py
  class VarDefinition (line 21) | class VarDefinition:
    method __str__ (line 31) | def __str__(self) -> str:
  class EnvVar (line 35) | class EnvVar(Enum):
    method get (line 55) | def get(envVar: "EnvVar") -> Any:
    method getList (line 61) | def getList(envVar: "EnvVar") -> list[Any]:
    method _cast (line 68) | def _cast(value: str, valueType: Type) -> Any:
    method help (line 76) | def help(cls) -> str:
  class EnvVarHelpAction (line 81) | class EnvVarHelpAction(argparse.Action):
    method __call__ (line 86) | def __call__(self, parser, namespace, value, option_string=None):

FILE: meshroom/multiview.py
  function hasExtension (line 73) | def hasExtension(filepath, extensions):
  class FilesByType (line 80) | class FilesByType:
    method __init__ (line 81) | def __init__(self):
    method __bool__ (line 88) | def __bool__(self):
    method extend (line 91) | def extend(self, other):
    method addFile (line 98) | def addFile(self, file):
    method addFiles (line 110) | def addFiles(self, files):
  function findFilesByTypeInFolder (line 115) | def findFilesByTypeInFolder(folder, recursive=False):

FILE: meshroom/nodes/general/Backdrop.py
  class Backdrop (line 5) | class Backdrop(desc.BackdropNode):

FILE: meshroom/nodes/general/CopyFiles.py
  class CopyFiles (line 11) | class CopyFiles(desc.Node):
    method resolvedPaths (line 47) | def resolvedPaths(self, inputFiles, outDir):
    method processChunk (line 58) | def processChunk(self, chunk):

FILE: meshroom/nodes/general/InputFile.py
  class InputFile (line 8) | class InputFile(desc.InputNode, desc.InitNode):
    method initialize (line 23) | def initialize(self, node, inputs, recursiveInputs):

FILE: meshroom/submitters/localFarmSubmitter.py
  function wrapMeshroomBin (line 29) | def wrapMeshroomBin(_bin):
  function getResolvedVersionsDict (line 37) | def getResolvedVersionsDict():
  function getRequestPackages (line 52) | def getRequestPackages(packagesDelimiter="=="):
  function rezWrapCommand (line 80) | def rezWrapCommand(cmd, useCurrentContext=False, useRequestedContext=Tru...
  class LocalFarmJob (line 114) | class LocalFarmJob(BaseSubmittedJob):
    method __init__ (line 117) | def __init__(self, jid, submitter, farmPath=None):
    method __getJobInfo (line 126) | def __getJobInfo(self):
    method localfarmJob (line 132) | def localfarmJob(self):
    method localfarmTasks (line 138) | def localfarmTasks(self):
    method __getChunkTasks (line 143) | def __getChunkTasks(self, nodeUid, iteration):
    method stopChunkTask (line 154) | def stopChunkTask(self, node, iteration):
    method skipChunkTask (line 160) | def skipChunkTask(self, node, iteration):
    method restartChunkTask (line 166) | def restartChunkTask(self, node, iteration):
    method getJobErrors (line 174) | def getJobErrors(self):
    method pauseJob (line 178) | def pauseJob(self):
    method resumeJob (line 182) | def resumeJob(self):
    method interruptJob (line 186) | def interruptJob(self):
    method restartJob (line 190) | def restartJob(self):
    method restartErrorTasks (line 194) | def restartErrorTasks(self):
  class LocalFarmSubmitter (line 199) | class LocalFarmSubmitter(BaseSubmitter):
    method __init__ (line 208) | def __init__(self, parent=None):
    method setFarmPath (line 214) | def setFarmPath(self, path: str):
    method setJobEnv (line 217) | def setJobEnv(self, env: dict):
    method retrieveJob (line 220) | def retrieveJob(self, jid) -> LocalFarmJob:
    method getChunks (line 225) | def getChunks(chunkParams) -> list[Chunk]:
    method getExpandWrappedCmd (line 239) | def getExpandWrappedCmd(cmdArgs, rezPackages):
    method __createChunkTasks (line 247) | def __createChunkTasks(self, job: Job, parentTask: Task, children: Lis...
    method createTask (line 263) | def createTask(self, meshroomFile: str, node) -> CreatedTask:
    method buildDependencies (line 297) | def buildDependencies(self, job: Job, nodeUidToTask: Dict[str, Created...
    method createJob (line 328) | def createJob(self, nodes, edges, filepath, submitLabel="{projectName}...
    method createChunkTask (line 354) | def createChunkTask(self, node, graphFile, **kwargs):

FILE: meshroom/ui/app.py
  class FileStatus (line 38) | class FileStatus(Enum):
  class MessageHandler (line 44) | class MessageHandler:
    method handler (line 71) | def handler(cls, messageType, context, message):
  function createMeshroomParser (line 88) | def createMeshroomParser(args):
  class MeshroomApp (line 217) | class MeshroomApp(QApplication):
    method __init__ (line 219) | def __init__(self, inputArgs):
    method terminateManual (line 366) | def terminateManual(self):
    method _pipelineTemplateFiles (line 371) | def _pipelineTemplateFiles(self):
    method _pipelineTemplateNames (line 381) | def _pipelineTemplateNames(self):
    method reloadTemplateList (line 385) | def reloadTemplateList(self):
    method forceUIUpdate (line 390) | def forceUIUpdate(self):
    method showMessage (line 396) | def showMessage(self, message, status=None, duration=5000):
    method _retrieveThumbnailPath (line 399) | def _retrieveThumbnailPath(self, filepath: str) -> str:
    method _getRecentProjectFilesFromSettings (line 432) | def _getRecentProjectFilesFromSettings(self) -> list[dict[str, str]]:
    method updateRecentProjectFilesThumbnails (line 457) | def updateRecentProjectFilesThumbnails(self) -> None:
    method _updateRecentProjectFilesThumbnails (line 467) | def _updateRecentProjectFilesThumbnails(self) -> None:
    method addRecentProjectFile (line 475) | def addRecentProjectFile(self, projectFile) -> None:
    method removeRecentProjectFile (line 533) | def removeRecentProjectFile(self, projectFile) -> None:
    method _recentImportedImagesFolders (line 576) | def _recentImportedImagesFolders(self):
    method addRecentImportedImagesFolder (line 590) | def addRecentImportedImagesFolder(self, imagesFolder):
    method removeRecentImportedImagesFolder (line 625) | def removeRecentImportedImagesFolder(self, imagesFolder):
    method markdownToHtml (line 657) | def markdownToHtml(self, md):
    method _systemInfo (line 674) | def _systemInfo(self):
    method _changelogModel (line 685) | def _changelogModel(self):
    method _licensesModel (line 702) | def _licensesModel(self):
    method _default8bitViewerEnabled (line 724) | def _default8bitViewerEnabled(self):
    method _defaultSequencePlayerEnabled (line 727) | def _defaultSequencePlayerEnabled(self):
    method _getEnvironmentVariableValue (line 730) | def _getEnvironmentVariableValue(self, key: str, defaultValue: bool) -...
    method _submittersList (line 746) | def _submittersList(self):
    method setDefaultSubmitter (line 767) | def setDefaultSubmitter(self, name):

FILE: meshroom/ui/commands.py
  class UndoCommand (line 16) | class UndoCommand(QUndoCommand):
    method __init__ (line 17) | def __init__(self, parent=None):
    method setEnabled (line 21) | def setEnabled(self, enabled):
    method redo (line 24) | def redo(self):
    method undo (line 32) | def undo(self):
    method redoImpl (line 40) | def redoImpl(self):
    method undoImpl (line 44) | def undoImpl(self):
  class UndoStack (line 49) | class UndoStack(QUndoStack):
    method __init__ (line 50) | def __init__(self, parent=None):
    method tryAndPush (line 63) | def tryAndPush(self, command):
    method setUndoableIndex (line 77) | def setUndoableIndex(self, value):
    method setLockedRedo (line 83) | def setLockedRedo(self, value):
    method lockAtThisIndex (line 89) | def lockAtThisIndex(self):
    method unlock (line 97) | def unlock(self):
  class GraphCommand (line 123) | class GraphCommand(UndoCommand):
    method __init__ (line 124) | def __init__(self, graph, parent=None):
  class AddNodeCommand (line 129) | class AddNodeCommand(GraphCommand):
    method __init__ (line 130) | def __init__(self, graph, nodeType, position, parent=None, **kwargs):
    method redoImpl (line 145) | def redoImpl(self):
    method undoImpl (line 151) | def undoImpl(self):
  class RenameNodeCommand (line 155) | class RenameNodeCommand(GraphCommand):
    method __init__ (line 156) | def __init__(self, graph, node, name, parent=None):
    method redoImpl (line 164) | def redoImpl(self):
    method undoImpl (line 169) | def undoImpl(self):
  class RemoveNodeCommand (line 173) | class RemoveNodeCommand(GraphCommand):
    method __init__ (line 174) | def __init__(self, graph, node, parent=None):
    method redoImpl (line 182) | def redoImpl(self):
    method undoImpl (line 187) | def undoImpl(self):
  class DuplicateNodesCommand (line 195) | class DuplicateNodesCommand(GraphCommand):
    method __init__ (line 199) | def __init__(self, graph, srcNodes, parent=None):
    method redoImpl (line 204) | def redoImpl(self):
    method undoImpl (line 211) | def undoImpl(self):
  class PasteNodesCommand (line 217) | class PasteNodesCommand(GraphCommand):
    method __init__ (line 221) | def __init__(self, graph: "Graph", data: dict, position: Position, par...
    method redoImpl (line 227) | def redoImpl(self):
    method undoImpl (line 246) | def undoImpl(self):
    method _boundingBox (line 250) | def _boundingBox(self, nodes) -> tuple[int, int, int, int]:
    method _boundingBoxCenter (line 265) | def _boundingBoxCenter(self, nodes):
  class ImportProjectCommand (line 269) | class ImportProjectCommand(GraphCommand):
    method __init__ (line 274) | def __init__(self, graph: Graph, filepath: PathLike, position=None, yO...
    method redoImpl (line 281) | def redoImpl(self):
    method undoImpl (line 299) | def undoImpl(self):
  class SetAttributeCommand (line 305) | class SetAttributeCommand(GraphCommand):
    method __init__ (line 306) | def __init__(self, graph, attribute, value, parent=None):
    method redoImpl (line 313) | def redoImpl(self):
    method undoImpl (line 322) | def undoImpl(self):
  class AddAttributeKeyValueCommand (line 328) | class AddAttributeKeyValueCommand(GraphCommand):
    method __init__ (line 329) | def __init__(self, graph, attribute, key, value, parent=None):
    method redoImpl (line 340) | def redoImpl(self):
    method undoImpl (line 349) | def undoImpl(self):
  class RemoveAttributeKeyCommand (line 364) | class RemoveAttributeKeyCommand(GraphCommand):
    method __init__ (line 365) | def __init__(self, graph, attribute, key, parent=None):
    method redoImpl (line 375) | def redoImpl(self):
    method undoImpl (line 384) | def undoImpl(self):
  class SetObservationCommand (line 393) | class SetObservationCommand(GraphCommand):
    method __init__ (line 394) | def __init__(self, graph, attribute, key, observation, parent=None):
    method redoImpl (line 402) | def redoImpl(self):
    method undoImpl (line 409) | def undoImpl(self):
  class RemoveObservationCommand (line 422) | class RemoveObservationCommand(GraphCommand):
    method __init__ (line 423) | def __init__(self, graph, attribute, key, parent=None):
    method redoImpl (line 430) | def redoImpl(self):
    method undoImpl (line 437) | def undoImpl(self):
  class AddEdgeCommand (line 444) | class AddEdgeCommand(GraphCommand):
    method __init__ (line 445) | def __init__(self, graph, src, dst, parent=None):
    method redoImpl (line 456) | def redoImpl(self) -> bool:
    method undoImpl (line 464) | def undoImpl(self) -> bool:
  class RemoveEdgeCommand (line 472) | class RemoveEdgeCommand(GraphCommand):
    method __init__ (line 473) | def __init__(self, graph, edge, parent=None):
    method redoImpl (line 480) | def redoImpl(self) -> bool:
    method undoImpl (line 484) | def undoImpl(self) -> bool:
  class ListAttributeAppendCommand (line 490) | class ListAttributeAppendCommand(GraphCommand):
    method __init__ (line 491) | def __init__(self, graph, listAttribute, value, parent=None):
    method redoImpl (line 500) | def redoImpl(self):
    method undoImpl (line 510) | def undoImpl(self):
  class ListAttributeRemoveCommand (line 515) | class ListAttributeRemoveCommand(GraphCommand):
    method __init__ (line 516) | def __init__(self, graph, attribute, parent=None):
    method redoImpl (line 525) | def redoImpl(self):
    method undoImpl (line 530) | def undoImpl(self):
  class RemoveImagesCommand (line 535) | class RemoveImagesCommand(GraphCommand):
    method __init__ (line 536) | def __init__(self, graph, cameraInitNodes, parent=None):
    method redoImpl (line 544) | def redoImpl(self):
    method undoImpl (line 556) | def undoImpl(self):
  class MoveNodeCommand (line 563) | class MoveNodeCommand(GraphCommand):
    method __init__ (line 565) | def __init__(self, graph, node, position, parent=None):
    method redoImpl (line 572) | def redoImpl(self):
    method undoImpl (line 576) | def undoImpl(self):
  class UpgradeNodeCommand (line 580) | class UpgradeNodeCommand(GraphCommand):
    method __init__ (line 584) | def __init__(self, graph, node, parent=None):
    method redoImpl (line 591) | def redoImpl(self):
    method undoImpl (line 597) | def undoImpl(self):
  class EnableGraphUpdateCommand (line 608) | class EnableGraphUpdateCommand(GraphCommand):
    method __init__ (line 612) | def __init__(self, graph, enabled, parent=None):
    method redoImpl (line 617) | def redoImpl(self):
    method undoImpl (line 621) | def undoImpl(self):
  function GroupedGraphModification (line 626) | def GroupedGraphModification(graph, undoStack, title, disableUpdates=True):

FILE: meshroom/ui/components/__init__.py
  function registerTypes (line 2) | def registerTypes():

FILE: meshroom/ui/components/clipboard.py
  class ClipboardHelper (line 5) | class ClipboardHelper(QObject):
    method __init__ (line 10) | def __init__(self, parent=None):
    method setText (line 15) | def setText(self, value):
    method getText (line 19) | def getText(self):
    method clear (line 23) | def clear(self):

FILE: meshroom/ui/components/csvData.py
  class CsvData (line 11) | class CsvData(QObject):
    method __init__ (line 13) | def __init__(self, parent=None):
    method getColumn (line 22) | def getColumn(self, index):
    method getFilepath (line 26) | def getFilepath(self):
    method getNbColumns (line 30) | def getNbColumns(self):
    method setFilepath (line 37) | def setFilepath(self, filepath):
    method setReady (line 44) | def setReady(self, ready):
    method updateData (line 51) | def updateData(self):
    method read (line 59) | def read(self):
  class CsvColumn (line 92) | class CsvColumn(QObject):
    method __init__ (line 94) | def __init__(self, title="", parent=None):
    method appendValue (line 100) | def appendValue(self, value):
    method getFirst (line 104) | def getFirst(self):
    method getLast (line 110) | def getLast(self):
    method fillChartSerie (line 116) | def fillChartSerie(self, serie):

FILE: meshroom/ui/components/edge.py
  class MouseEvent (line 6) | class MouseEvent(QObject):
    method __init__ (line 10) | def __init__(self, evt):
  class EdgeMouseArea (line 23) | class EdgeMouseArea(QQuickItem):
    method __init__ (line 28) | def __init__(self, parent=None):
    method contains (line 39) | def contains(self, point):
    method hoverEnterEvent (line 42) | def hoverEnterEvent(self, evt):
    method hoverLeaveEvent (line 46) | def hoverLeaveEvent(self, evt):
    method geometryChange (line 50) | def geometryChange(self, newGeometry, oldGeometry):
    method mousePressEvent (line 54) | def mousePressEvent(self, evt):
    method mouseReleaseEvent (line 62) | def mouseReleaseEvent(self, evt):
    method updateShape (line 67) | def updateShape(self):
    method getThickness (line 84) | def getThickness(self):
    method setThickness (line 87) | def setThickness(self, value):
    method getCurveScale (line 94) | def getCurveScale(self):
    method setCurveScale (line 97) | def setCurveScale(self, value):
    method getContainsMouse (line 104) | def getContainsMouse(self):
    method setContainsMouse (line 107) | def setContainsMouse(self, value):
    method intersectsSegment (line 114) | def intersectsSegment(self, p1, p2):

FILE: meshroom/ui/components/filepath.py
  class FilepathHelper (line 11) | class FilepathHelper(QObject):
    method asStr (line 20) | def asStr(path):
    method basename (line 38) | def basename(self, path):
    method dirname (line 44) | def dirname(self, path):
    method extension (line 50) | def extension(self, path):
    method removeExtension (line 56) | def removeExtension(self, path):
    method accessible (line 62) | def accessible(self, path):
    method isFile (line 69) | def isFile(self, path):
    method exists (line 75) | def exists(self, path):
    method urlToString (line 80) | def urlToString(self, url):
    method stringToUrl (line 85) | def stringToUrl(self, path):
    method normpath (line 91) | def normpath(self, path):
    method globFirst (line 97) | def globFirst(self, path):
    method fileSizeMB (line 107) | def fileSizeMB(self, path):
    method resolve (line 112) | def resolve(self, path, vp):
    method getFilenamesFromFolder (line 128) | def getFilenamesFromFolder(self, folderPath: str, extension: str = None):
    method resolveSequence (line 141) | def resolveSequence(self, path, includesSeqMissingFiles):

FILE: meshroom/ui/components/geom2D.py
  class Geom2D (line 4) | class Geom2D(QObject):
    method rectRectIntersect (line 6) | def rectRectIntersect(self, rect1: QRectF, rect2: QRectF) -> bool:
    method rectRectFullIntersect (line 11) | def rectRectFullIntersect(self, rect1: QRectF, rect2: QRectF) -> bool:

FILE: meshroom/ui/components/logLinesModel.py
  class LogLevel (line 7) | class LogLevel(IntEnum):
  class LogLevelEnum (line 23) | class LogLevelEnum(QObject):
    method __init__ (line 35) | def __init__(self, parent=None):
    method UNKNOWN (line 39) | def UNKNOWN(self):
    method TRACE (line 43) | def TRACE(self):
    method DEBUG (line 47) | def DEBUG(self):
    method INFO (line 51) | def INFO(self):
    method WARNING (line 55) | def WARNING(self):
    method ERROR (line 59) | def ERROR(self):
    method CRITICAL (line 63) | def CRITICAL(self):
    method FATAL (line 67) | def FATAL(self):
  class LogLinesModel (line 70) | class LogLinesModel(QAbstractListModel):
    method __init__ (line 113) | def __init__(self, parent=None):
    method rowCount (line 127) | def rowCount(self, parent=QModelIndex()):
    method data (line 141) | def data(self, index, role=Qt.DisplayRole):
    method roleNames (line 168) | def roleNames(self):
    method setText (line 183) | def setText(self, text):
    method parseMetadata (line 229) | def parseMetadata(self, line):
    method count (line 278) | def count(self):
    method get (line 290) | def get(self, index):
    method clear (line 307) | def clear(self):
    method levelToString (line 318) | def levelToString(self, level):

FILE: meshroom/ui/components/messaging.py
  class Message (line 7) | class Message:
    method __init__ (line 8) | def __init__(self, msg, status=None):
    method dateStr (line 13) | def dateStr(self, fullDate=False):
  class MessageController (line 20) | class MessageController(QObject):
    method __init__ (line 28) | def __init__(self, parent):
    method sendMessage (line 32) | def sendMessage(self, msg, status, duration):
    method storeMessage (line 37) | def storeMessage(self, msg, status):
    method _getMessagesDict (line 42) | def _getMessagesDict(self, fullDate=False):
    method getMessages (line 53) | def getMessages(self):
    method getMessagesAsString (line 61) | def getMessagesAsString(self):
    method clearMessages (line 73) | def clearMessages(self):

FILE: meshroom/ui/components/scene3D.py
  class Scene3DHelper (line 10) | class Scene3DHelper(QObject):
    method findChildrenByProperty (line 13) | def findChildrenByProperty(self, entity, propertyName):
    method addComponent (line 26) | def addComponent(self, entity, component):
    method removeComponent (line 31) | def removeComponent(self, entity, component):
    method vertexCount (line 36) | def vertexCount(self, entity):
    method faceCount (line 41) | def faceCount(self, entity):
    method vertexColorCount (line 49) | def vertexColorCount(self, entity):
  class TrackballController (line 56) | class TrackballController(QObject):
    method __init__ (line 62) | def __init__(self, parent=None):
    method projectToTrackball (line 69) | def projectToTrackball(self, screenCoords):
    method clamp (line 83) | def clamp(x):
    method createRotation (line 86) | def createRotation(self, firstPoint, nextPoint):
    method rotate (line 94) | def rotate(self, lastPosition, currentPosition, dt):
  class Transformations3DHelper (line 110) | class Transformations3DHelper(QObject):
    method rotationBetweenAandB (line 115) | def rotationBetweenAandB(self, A, B):
    method fromEquirectangular (line 126) | def fromEquirectangular(self, vector):
    method toEquirectangular (line 130) | def toEquirectangular(self, vector):
    method updatePanorama (line 134) | def updatePanorama(self, euler, ptStart, ptEnd):
    method updatePanoramaInPlane (line 172) | def updatePanoramaInPlane(self, euler, ptStart, ptEnd):
    method pointFromWorldToScreen (line 206) | def pointFromWorldToScreen(self, point, camera, windowSize):
    method relativeLocalTranslate (line 233) | def relativeLocalTranslate(self, transformQtInstance, initialPosMat, i...
    method relativeLocalRotate (line 252) | def relativeLocalRotate(self, transformQtInstance, initialPosMat, init...
    method relativeLocalScale (line 275) | def relativeLocalScale(self, transformQtInstance, initialPosMat, initi...
    method modelMatrixToMatrices (line 302) | def modelMatrixToMatrices(self, modelMat):
    method computeModelMatrixWithEuler (line 323) | def computeModelMatrixWithEuler(self, translation, rotation, scale):
    method convertRotationFromCV2GL (line 347) | def convertRotationFromCV2GL(self, rotation):
    method getRotatedCameraViewVector (line 360) | def getRotatedCameraViewVector(self, camereViewVector, cameraUpVector,...
    method computeScaleUnitFromModelMatrix (line 377) | def computeScaleUnitFromModelMatrix(self, axis, modelMat, camera, wind...
    method copyMatrix4x4 (line 409) | def copyMatrix4x4(self, mat):
    method decomposeModelMatrix (line 416) | def decomposeModelMatrix(self, modelMat):
    method quaternionToRotationMatrix (line 430) | def quaternionToRotationMatrix(self, q):

FILE: meshroom/ui/components/scriptEditor.py
  class ScriptEditorManager (line 13) | class ScriptEditorManager(QObject):
    method __init__ (line 19) | def __init__(self, parent=None):
    method _defaultScript (line 28) | def _defaultScript(self):
    method _lastScript (line 39) | def _lastScript(self):
    method _hasPreviousScript (line 45) | def _hasPreviousScript(self):
    method _hasNextScript (line 51) | def _hasNextScript(self):
    method process (line 58) | def process(self, script):
    method clearHistory (line 90) | def clearHistory(self):
    method getNextScript (line 96) | def getNextScript(self):
    method getPreviousScript (line 108) | def getPreviousScript(self):
    method loadLastScript (line 122) | def loadLastScript(self):
    method saveScript (line 127) | def saveScript(self, script):
  class CharFormat (line 145) | class CharFormat(QtGui.QTextCharFormat):
    method __init__ (line 149) | def __init__(self, color, bold=False, italic=False):
  class PySyntaxHighlighter (line 167) | class PySyntaxHighlighter(QtGui.QSyntaxHighlighter):
    method __init__ (line 209) | def __init__(self, parent=None):
    method __rules (line 225) | def __rules(self):
    method highlightBlock (line 263) | def highlightBlock(self, text):
    method textDoc (line 285) | def textDoc(self):
    method setTextDocument (line 289) | def setTextDocument(self, document):

FILE: meshroom/ui/components/shapes/shapeFile.py
  class ShapeFile (line 5) | class ShapeFile(BaseObject):
    class ShapeData (line 10) | class ShapeData(BaseObject):
      method __init__ (line 14) | def __init__(self, name: str, type: str, properties={}, observations...
      method _getVisible (line 31) | def _getVisible(self) -> bool:
      method _setVisible (line 37) | def _setVisible(self, visible:bool):
      method setViewId (line 44) | def setViewId(self, viewId: str):
      method _getObservation (line 51) | def _getObservation(self):
      method _getNbObservations (line 59) | def _getNbObservations(self):
      method hasObservation (line 68) | def hasObservation(self, key: str) -> bool:
    method __init__ (line 100) | def __init__(self, fileAttribute: Attribute, viewId: str, parent=None):
    method _getVisible (line 117) | def _getVisible(self) -> bool:
    method _setVisible (line 123) | def _setVisible(self, visible:bool):
    method _getBasename (line 132) | def _getBasename(self) -> str:
    method setViewId (line 138) | def setViewId(self, viewId: str):
    method _loadShapesFromJsonFile (line 146) | def _loadShapesFromJsonFile(self):

FILE: meshroom/ui/components/shapes/shapeFilesHelper.py
  class ShapeFilesHelper (line 11) | class ShapeFilesHelper(BaseObject):
    method __init__ (line 16) | def __init__(self, activeProject:Scene, parent=None):
    method _loadShapeFilesFromAttributes (line 24) | def _loadShapeFilesFromAttributes(self, attributes):
    method _loadShapeFiles (line 38) | def _loadShapeFiles(self):
    method _onSelectedViewIdChanged (line 48) | def _onSelectedViewIdChanged(self):
    method _onSelectedNodeChanged (line 54) | def _onSelectedNodeChanged(self):

FILE: meshroom/ui/components/shapes/shapeViewerHelper.py
  class ShapeViewerHelper (line 3) | class ShapeViewerHelper(BaseObject):
    method __init__ (line 10) | def __init__(self, parent=None):
    method _getSelectedShapeName (line 17) | def _getSelectedShapeName(self) -> str:
    method _getContainerWidth (line 20) | def _getContainerWidth(self) -> float:
    method _getContainerHeight (line 23) | def _getContainerHeight(self) -> float:
    method _getContainerScale (line 26) | def _getContainerScale(self) -> float:
    method _setSelectedShapeName (line 29) | def _setSelectedShapeName(self, shapeName:str):
    method _setContainerWidth (line 33) | def _setContainerWidth(self, width: float):
    method _setContainerHeight (line 37) | def _setContainerHeight(self, height: float):
    method _setContainerScale (line 41) | def _setContainerScale(self, scale: float):
    method getDefaultObservation (line 46) | def getDefaultObservation(self, shapeType: str) -> Variant:

FILE: meshroom/ui/components/thumbnail.py
  class ThumbnailCache (line 16) | class ThumbnailCache(QObject):
    method __del__ (line 65) | def __del__(self):
    method initialize (line 70) | def initialize():
    method clean (line 103) | def clean():
    method thumbnailPath (line 167) | def thumbnailPath(imgPath):
    method removeOutdated (line 181) | def removeOutdated(imgPath, path):
    method checkThumbnail (line 197) | def checkThumbnail(path):
    method thumbnail (line 214) | def thumbnail(self, imgSource, callerID):
    method createThumbnail (line 252) | def createThumbnail(self, imgSource, callerID):
    method handleRequestsAsync (line 296) | def handleRequestsAsync(self):
    method clearRequests (line 317) | def clearRequests(self):

FILE: meshroom/ui/graph.py
  class PollerRefreshStatus (line 41) | class PollerRefreshStatus(Enum):
  class FilesModTimePollerThread (line 47) | class FilesModTimePollerThread(QObject):
    method __init__ (line 54) | def __init__(self, parent=None):
    method __del__ (line 67) | def __del__(self):
    method start (line 71) | def start(self, files=None):
    method setFiles (line 88) | def setFiles(self, files):
    method stop (line 99) | def stop(self):
    method getFileLastModTime (line 108) | def getFileLastModTime(f):
    method run (line 115) | def run(self):
    method onFilePollerRefreshChanged (line 125) | def onFilePollerRefreshChanged(self, value):
  class NodeStatusMonitor (line 138) | class NodeStatusMonitor(QObject):
    method __init__ (line 148) | def __init__(self, parent=None):
    method setWatchedFiles (line 159) | def setWatchedFiles(self):
    method setMonitored (line 164) | def setMonitored(self, nodes):
    method stop (line 168) | def stop(self):
    method getMonitoredFiles (line 172) | def getMonitoredFiles(self):
    method compareFilesTimes (line 192) | def compareFilesTimes(self, times):
    method onFilePollerRefreshUpdated (line 224) | def onFilePollerRefreshUpdated(self):
    method onComputeStatusChanged (line 234) | def onComputeStatusChanged(self):
  class GraphLayout (line 246) | class GraphLayout(QObject):
    class DepthMode (line 251) | class DepthMode(Enum):
    method __init__ (line 262) | def __init__(self, graph):
    method autoLayout (line 271) | def autoLayout(self, fromNode=None, toNode=None, startX=0, startY=0):
    method reset (line 306) | def reset(self):
    method positionBoundingBox (line 310) | def positionBoundingBox(self, nodes=None):
    method boundingBox (line 336) | def boundingBox(self, nodes=None):
    method setDepthMode (line 351) | def setDepthMode(self, mode):
  class UIGraph (line 369) | class UIGraph(QObject):
    method __init__ (line 376) | def __init__(self, undoStack: commands.UndoStack, taskManager: TaskMan...
    method setGraph (line 397) | def setGraph(self, g):
    method onGraphUpdated (line 432) | def onGraphUpdated(self):
    method updateChunks (line 437) | def updateChunks(self):
    method updateChunkMonitor (line 464) | def updateChunkMonitor(self):
    method clear (line 474) | def clear(self):
    method stopChildThreads (line 483) | def stopChildThreads(self):
    method loadGraph (line 489) | def loadGraph(self, filepath):
    method initFromTemplate (line 499) | def initFromTemplate(self, filepath, copyOutputs=False):
    method importProject (line 507) | def importProject(self, filepath, position=None):
    method saveAs (line 522) | def saveAs(self, url):
    method saveAsTemplate (line 526) | def saveAsTemplate(self, url):
    method _saveAs (line 529) | def _saveAs(self, url, setupProjectFile=True, template=False):
    method saveAsTemp (line 545) | def saveAsTemp(self):
    method save (line 550) | def save(self):
    method saveAsNewVersion (line 555) | def saveAsNewVersion(self):
    method updateLockedUndoStack (line 560) | def updateLockedUndoStack(self):
    method execute (line 569) | def execute(self, nodes: Optional[Union[list[Node], Node]] = None):
    method stopExecution (line 576) | def stopExecution(self):
    method stopNodeComputation (line 585) | def stopNodeComputation(self, node):
    method cancelNodeComputation (line 596) | def cancelNodeComputation(self, node):
    method isChunkComputingLocally (line 609) | def isChunkComputingLocally(self, chunk):
    method isChunkComputingExternally (line 616) | def isChunkComputingExternally(self, chunk):
    method stopTask (line 623) | def stopTask(self, chunk: NodeChunk):
    method stopNode (line 654) | def stopNode(self, node: Node):
    method restartTask (line 673) | def restartTask(self, chunk: NodeChunk):
    method skipTask (line 698) | def skipTask(self, chunk: NodeChunk):
    method pauseJob (line 723) | def pauseJob(self, node: Node):
    method resumeJob (line 743) | def resumeJob(self, node: Node):
    method interruptJob (line 762) | def interruptJob(self, node: Node):
    method restartJobErrorTasks (line 797) | def restartJobErrorTasks(self, node: Node):
    method submit (line 827) | def submit(self, nodes: Optional[Union[list[Node], Node]] = None):
    method updateGraphComputingStatus (line 845) | def updateGraphComputingStatus(self):
    method isComputing (line 877) | def isComputing(self):
    method isComputingExternally (line 881) | def isComputingExternally(self):
    method isComputingLocally (line 885) | def isComputingLocally(self):
    method push (line 895) | def push(self, command):
    method groupedGraphModification (line 904) | def groupedGraphModification(self, title, disableUpdates=True):
    method beginModification (line 918) | def beginModification(self, name):
    method endModification (line 928) | def endModification(self):
    method addNewNode (line 935) | def addNewNode(self, nodeType, position=None, **kwargs):
    method renameNode (line 952) | def renameNode(self, node: Node, newName: str):
    method moveNode (line 977) | def moveNode(self, node: Node, position: Position):
    method resizeNode (line 988) | def resizeNode(self, node, width, height):
    method resizeAndMoveNode (line 1004) | def resizeAndMoveNode(self, node, width, height, position=None):
    method addBackdropNode (line 1024) | def addBackdropNode(self, position, width, height):
    method moveSelectedNodesBy (line 1045) | def moveSelectedNodesBy(self, offset: QPoint):
    method getMeanPosition (line 1053) | def getMeanPosition(self):
    method alignHorizontally (line 1066) | def alignHorizontally(self):
    method alignVertically (line 1087) | def alignVertically(self):
    method removeNodes (line 1099) | def removeNodes(self, nodes: list[Node]):
    method removeSelectedNodes (line 1114) | def removeSelectedNodes(self):
    method removeNodesFrom (line 1119) | def removeNodesFrom(self, nodes: list[Node]):
    method duplicateNodes (line 1134) | def duplicateNodes(self, nodes: list[Node]) -> list[Node]:
    method duplicateNodesFrom (line 1167) | def duplicateNodesFrom(self, nodes: list[Node]) -> list[Node]:
    method canExpandForLoop (line 1184) | def canExpandForLoop(self, currentEdge):
    method expandForLoop (line 1200) | def expandForLoop(self, currentEdge):
    method collapseForLoop (line 1216) | def collapseForLoop(self, currentEdge):
    method clearSelectedNodesData (line 1232) | def clearSelectedNodesData(self):
    method clearData (line 1237) | def clearData(self, nodes: list[Node]):
    method clearDataFrom (line 1243) | def clearDataFrom(self, nodes: list[Node]):
    method addEdge (line 1253) | def addEdge(self, src, dst):
    method _addEdge (line 1263) | def _addEdge(self, src, dst):
    method removeEdge (line 1270) | def removeEdge(self, edge):
    method deleteEdgesByIndices (line 1279) | def deleteEdgesByIndices(self, indices):
    method disconnectSelectedNodes (line 1286) | def disconnectSelectedNodes(self):
    method replaceEdge (line 1298) | def replaceEdge(self, edge, newSrc, newDst):
    method getEdge (line 1305) | def getEdge(self, dst):
    method setAttribute (line 1309) | def setAttribute(self, attribute, value):
    method resetAttribute (line 1313) | def resetAttribute(self, attribute):
    method addAttributeKeyValue (line 1325) | def addAttributeKeyValue(self, attribute, key, value):
    method addAttributeKeyDefaultValue (line 1330) | def addAttributeKeyDefaultValue(self, attribute, key):
    method removeAttributeKey (line 1335) | def removeAttributeKey(self, attribute, key):
    method setObservationFromName (line 1340) | def setObservationFromName(self, shapeFullName, key, observation):
    method setObservation (line 1348) | def setObservation(self, shape, key, observation):
    method removeObservation (line 1353) | def removeObservation(self, shape, key):
    method upgradeNode (line 1358) | def upgradeNode(self, node):
    method upgradeAllNodes (line 1363) | def upgradeAllNodes(self):
    method forceNodesStatusUpdate (line 1372) | def forceNodesStatusUpdate(self):
    method appendAttribute (line 1377) | def appendAttribute(self, attribute, value=QJsonValue()):
    method removeAttribute (line 1388) | def removeAttribute(self, attribute):
    method removeImage (line 1392) | def removeImage(self, image):
    method removeAllImages (line 1417) | def removeAllImages(self):
    method removeImagesFromAllGroups (line 1422) | def removeImagesFromAllGroups(self):
    method selectNodes (line 1428) | def selectNodes(self, nodes, command=QItemSelectionModel.SelectionFlag...
    method selectFollowing (line 1435) | def selectFollowing(self, node: Node, command=QItemSelectionModel.Sele...
    method selectNodeByIndex (line 1444) | def selectNodeByIndex(self, index: int, command=QItemSelectionModel.Se...
    method selectNodesByIndices (line 1456) | def selectNodesByIndices(
    method iterSelectedNodes (line 1480) | def iterSelectedNodes(self) -> Iterator[Node]:
    method getSelectedNodes (line 1486) | def getSelectedNodes(self) -> list[Node]:
    method isSelected (line 1491) | def isSelected(self, node: Node) -> bool:
    method clearNodeSelection (line 1496) | def clearNodeSelection(self):
    method clearNodeHover (line 1501) | def clearNodeHover(self):
    method setSelectedNodesColor (line 1506) | def setSelectedNodesColor(self, color: str):
    method getSelectedNodesContent (line 1521) | def getSelectedNodesContent(self) -> str:
    method pasteNodes (line 1533) | def pasteNodes(self, serializedData: str, position: Optional[QPoint]=N...
    method canComputeNode (line 1567) | def canComputeNode(self, node: Node) -> bool:
    method canSubmitNode (line 1578) | def canSubmitNode(self, node: Node) -> bool:

FILE: meshroom/ui/palette.py
  class PaletteManager (line 6) | class PaletteManager(QObject):
    method __init__ (line 10) | def __init__(self, qmlEngine, parent=None):
    method togglePalette (line 50) | def togglePalette(self):

FILE: meshroom/ui/qml/Utils/errorHandler.js
  function analyseError (line 10) | function analyseError(error) {

FILE: meshroom/ui/qml/Utils/format.js
  function intToString (line 3) | function intToString(v) {
  function plainToHtml (line 11) | function plainToHtml(t) {
  function divmod (line 16) | function divmod(x, y) {
  function sec2timeHMS (line 24) | function sec2timeHMS(totalSeconds) {
  function sec2timecode (line 35) | function sec2timecode(timeSeconds) {
  function sec2timeStr (line 42) | function sec2timeStr(timeSeconds) {
  function GB2GBMBKB (line 70) | function GB2GBMBKB(GB) {
  function GB2SizeStr (line 82) | function GB2SizeStr(GB) {

FILE: meshroom/ui/qml/Utils/request.js
  function get (line 6) | function get(url, callback) {

FILE: meshroom/ui/scene.py
  class Message (line 30) | class Message(QObject):
    method __init__ (line 33) | def __init__(self, title, text, detailedText="", parent=None):
  class ViewpointWrapper (line 44) | class ViewpointWrapper(QObject):
    method __init__ (line 57) | def __init__(self, viewpointAttribute, scene):
    method _updateInitialParams (line 100) | def _updateInitialParams(self):
    method _updateSfMParams (line 117) | def _updateSfMParams(self):
    method _updateUndistortedImageParams (line 130) | def _updateUndistortedImageParams(self):
    method initialIntrinsics (line 157) | def initialIntrinsics(self):
    method metadata (line 162) | def metadata(self):
    method imageSize (line 167) | def imageSize(self):
    method orientation (line 174) | def orientation(self):
    method orientedImageSize (line 179) | def orientedImageSize(self):
    method isReconstructed (line 187) | def isReconstructed(self):
    method solvedIntrinsics (line 192) | def solvedIntrinsics(self):
    method translation (line 196) | def translation(self):
    method rotation (line 203) | def rotation(self):
    method pose (line 217) | def pose(self):
    method upVector (line 231) | def upVector(self):
    method uvCenterOffset (line 236) | def uvCenterOffset(self):
    method fieldOfView (line 246) | def fieldOfView(self):
    method pixelAspectRatio (line 266) | def pixelAspectRatio(self):
    method undistortedImageSource (line 274) | def undistortedImageSource(self):
  function parseSfMJsonFile (line 279) | def parseSfMJsonFile(sfmJsonFile):
  class ActiveNode (line 306) | class ActiveNode(QObject):
    method __init__ (line 310) | def __init__(self, nodeType, parent=None):
  class Scene (line 319) | class Scene(UIGraph):
    method __init__ (line 351) | def __init__(self, undoStack: commands.UndoStack, taskManager: TaskMan...
    method __del__ (line 396) | def __del__(self):
    method setActive (line 400) | def setActive(self, active):
    method clear (line 404) | def clear(self):
    method setDefaultPipeline (line 409) | def setDefaultPipeline(self, defaultPipeline):
    method setSubmitLabel (line 412) | def setSubmitLabel(self, submitLabel):
    method initActiveNodes (line 415) | def initActiveNodes(self):
    method clearActiveNodes (line 427) | def clearActiveNodes(self):
    method onCameraInitChanged (line 431) | def onCameraInitChanged(self):
    method reloadPlugins (line 439) | def reloadPlugins(self):
    method _reloadPlugins (line 443) | def _reloadPlugins(self):
    method _onPluginsReloaded (line 462) | def _onPluginsReloaded(self, reloadedNodes: list, errorNodes: list):
    method new (line 471) | def new(self, pipeline=None):
    method _initFromTemplateWithCopyOutputs (line 481) | def _initFromTemplateWithCopyOutputs(self, filepath):
    method newWithCopyOutputs (line 486) | def newWithCopyOutputs(self, pipeline=None):
    method load (line 496) | def load(self, url):
    method _loadWithErrorReport (line 505) | def _loadWithErrorReport(self, loadFunction: Callable[[str], None], fi...
    method onGraphChanged (line 543) | def onGraphChanged(self):
    method getViewpoints (line 557) | def getViewpoints(self):
    method updateCameraInits (line 567) | def updateCameraInits(self):
    method getCameraInitIndex (line 579) | def getCameraInitIndex(self):
    method setCameraInitIndex (line 588) | def setCameraInitIndex(self, idx):
    method setCameraInitNode (line 595) | def setCameraInitNode(self, node):
    method clearTempCameraInit (line 601) | def clearTempCameraInit(self):
    method setupTempCameraInit (line 605) | def setupTempCameraInit(self, node, attrName):
    method getAutoFisheyeCircle (line 623) | def getAutoFisheyeCircle(self, panoramaInit):
    method lastSfmNode (line 646) | def lastSfmNode(self):
    method lastNodeOfType (line 650) | def lastNodeOfType(self, nodeTypes, startNode, preferredStatus=None):
    method allImagePaths (line 678) | def allImagePaths(self):
    method allViewIds (line 682) | def allViewIds(self):
    method handleFilesUrl (line 689) | def handleFilesUrl(self, filesByType, cameraInit=None, position=None):
    method getFilesByTypeFromDrop (line 798) | def getFilesByTypeFromDrop(self, urls):
    method importImagesFromFolder (line 824) | def importImagesFromFolder(self, path, recursive=False):
    method importImagesUrls (line 841) | def importImagesUrls(self, imagePaths, recursive=False):
    method importImagesSync (line 853) | def importImagesSync(self, images, cameraInit):
    method onImportImagesFailed (line 861) | def onImportImagesFailed(self, msg):
    method buildIntrinsics (line 870) | def buildIntrinsics(self, cameraInit, additionalViews, rebuild=False):
    method rebuildIntrinsics (line 916) | def rebuildIntrinsics(self, cameraInit):
    method onIntrinsicsAvailable (line 925) | def onIntrinsicsAvailable(self, cameraInit, views, intrinsics, rebuild...
    method setBuildingIntrinsics (line 944) | def setBuildingIntrinsics(self, value):
    method setActiveNode (line 972) | def setActiveNode(self, node, categories=True, inputs=True):
    method setActiveNodes (line 1008) | def setActiveNodes(self, nodes):
    method resetActiveNodePerCategory (line 1015) | def resetActiveNodePerCategory(self):
    method updateSfMResults (line 1022) | def updateSfMResults(self):
    method getSfm (line 1034) | def getSfm(self):
    method _unsetSfm (line 1038) | def _unsetSfm(self):
    method _setSfm (line 1042) | def _setSfm(self, node):
    method setSfm (line 1060) | def setSfm(self, node):
    method isInViews (line 1071) | def isInViews(self, viewpoint):
    method isReconstructed (line 1078) | def isReconstructed(self, viewpoint):
    method hasValidIntrinsic (line 1088) | def hasValidIntrinsic(self, viewpoint):
    method getIntrinsic (line 1094) | def getIntrinsic(self, viewpoint):
    method hasMetadata (line 1109) | def hasMetadata(self, viewpoint):
    method setSelectedViewId (line 1113) | def setSelectedViewId(self, viewId):
    method _setSelectedViewpoint (line 1124) | def _setSelectedViewpoint(self, viewpointAttribute):
    method setPickedViewId (line 1131) | def setPickedViewId(self, viewId):
    method updateSelectedViewpoint (line 1138) | def updateSelectedViewpoint(self, viewId):
    method reconstructedCamerasCount (line 1145) | def reconstructedCamerasCount(self):
    method getSolvedIntrinsics (line 1154) | def getSolvedIntrinsics(self, viewpoint):
    method getPoseRT (line 1164) | def getPoseRT(self, viewpoint):
    method setCurrentViewPath (line 1187) | def setCurrentViewPath(self, path):
    method evaluateMathExpression (line 1194) | def evaluateMathExpression(self, expr):

FILE: meshroom/ui/utils.py
  class QmlInstantEngine (line 12) | class QmlInstantEngine(QQmlApplicationEngine):
    method __init__ (line 19) | def __init__(self, sourceFile="", watching=True, verbose=False, parent...
    method load (line 52) | def load(self, sourceFile):
    method setWatching (line 56) | def setWatching(self, watchValue):
    method watchedExtensions (line 80) | def watchedExtensions(self):
    method watchedExtensions (line 85) | def watchedExtensions(self, extensions):
    method setVerbose (line 89) | def setVerbose(self, verboseValue):
    method addFile (line 93) | def addFile(self, filename):
    method addFiles (line 119) | def addFiles(self, filenames):
    method addFilesFromDirectory (line 131) | def addFilesFromDirectory(self, dirname, recursive=False):
    method removeFile (line 152) | def removeFile(self, filename):
    method getRegisteredFiles (line 162) | def getRegisteredFiles(self):
    method onFileChanged (line 167) | def onFileChanged(self, filepath):
    method reload (line 195) | def reload(self):
  function makeProperty (line 200) | def makeProperty(T, attributeName, notify=None, resetOnDestroy=False):

FILE: setup.py
  class PlatformExecutable (line 11) | class PlatformExecutable(Executable):
    method __init__ (line 26) | def __init__(self, script, initScript=None, base=None, targetName=None...

FILE: setupInitScriptUnix.py
  function run (line 35) | def run(*args):

FILE: setupInitScriptWindows.py
  function run (line 23) | def run(*args):

FILE: tests/conftest.py
  function graphSavedOnDisk (line 9) | def graphSavedOnDisk():

FILE: tests/nodes/test/Color.py
  class Color (line 4) | class Color(desc.Node):
  class NestedColor (line 19) | class NestedColor(desc.Node):

FILE: tests/nodes/test/GroupAttributes.py
  class GroupAttributes (line 4) | class GroupAttributes(desc.Node):

FILE: tests/nodes/test/InputDynamicOutputs.py
  class InputDynamicOutputs (line 3) | class InputDynamicOutputs(desc.InputNode):

FILE: tests/nodes/test/NestedTest.py
  class NestedTest (line 4) | class NestedTest(desc.Node):

FILE: tests/nodes/test/Position.py
  class Position (line 4) | class Position(desc.Node):
  class NestedPosition (line 19) | class NestedPosition(desc.Node):

FILE: tests/nodes/test/appendFiles.py
  class AppendFiles (line 4) | class AppendFiles(desc.CommandLineNode):

FILE: tests/nodes/test/appendText.py
  class AppendText (line 4) | class AppendText(desc.CommandLineNode):

FILE: tests/nodes/test/ls.py
  class Ls (line 4) | class Ls(desc.CommandLineNode):

FILE: tests/plugins/meshroom/pluginA/PluginAInputInitNode.py
  class PluginAInputInitNode (line 6) | class PluginAInputInitNode(desc.InputNode, desc.InitNode):
    method initialize (line 25) | def initialize(self, node, inputs, recursiveInputs):

FILE: tests/plugins/meshroom/pluginA/PluginAInputNode.py
  class PluginAInputNode (line 6) | class PluginAInputNode(desc.InputNode):

FILE: tests/plugins/meshroom/pluginA/PluginANodeA.py
  class PluginANodeA (line 8) | class PluginANodeA(desc.Node):
    method process (line 27) | def process(self, node):

FILE: tests/plugins/meshroom/pluginA/PluginANodeB.py
  class PluginANodeB (line 8) | class PluginANodeB(desc.Node):
    method process (line 33) | def process(self, node):

FILE: tests/plugins/meshroom/pluginB/PluginBNodeA.py
  class PluginBNodeA (line 6) | class PluginBNodeA(desc.Node):

FILE: tests/plugins/meshroom/pluginB/PluginBNodeB.py
  class PluginBNodeB (line 6) | class PluginBNodeB(desc.Node):

FILE: tests/plugins/meshroom/pluginC/PluginCNodeA.py
  class PluginCNodeA (line 7) | class PluginCNodeA(desc.Node):

FILE: tests/plugins/meshroom/pluginSubmitter/PluginSubmitter.py
  class PluginSubmitterA (line 11) | class PluginSubmitterA(desc.BaseNode):
    method processChunk (line 34) | def processChunk(self, chunk):
  class PluginSubmitterB (line 41) | class PluginSubmitterB(PluginSubmitterA):
  class PluginSubmitterC (line 49) | class PluginSubmitterC(PluginSubmitterA):

FILE: tests/test_attributeChoiceParam.py
  class NodeWithChoiceParams (line 7) | class NodeWithChoiceParams(desc.Node):
  class NodeWithChoiceParamsSavingValuesOverride (line 32) | class NodeWithChoiceParamsSavingValuesOverride(desc.Node):
  class TestChoiceParam (line 57) | class TestChoiceParam:
    method setup_class (line 60) | def setup_class(cls):
    method teardown_class (line 64) | def teardown_class(cls):
    method test_customValueIsSerialized (line 67) | def test_customValueIsSerialized(self, graphSavedOnDisk):
    method test_customMultiValueIsSerialized (line 77) | def test_customMultiValueIsSerialized(self, graphSavedOnDisk):
    method test_overridenValuesAreNotSerialized (line 87) | def test_overridenValuesAreNotSerialized(self, graphSavedOnDisk):
    method test_connectionPropagatesOverridenValues (line 97) | def test_connectionPropagatesOverridenValues(self):
    method test_connectionsAreSerialized (line 107) | def test_connectionsAreSerialized(self, graphSavedOnDisk):
  class TestChoiceParamSavingCustomValues (line 123) | class TestChoiceParamSavingCustomValues:
    method setup_class (line 126) | def setup_class(cls):
    method teardown_class (line 130) | def teardown_class(cls):
    method test_customValueIsSerialized (line 133) | def test_customValueIsSerialized(self, graphSavedOnDisk):
    method test_overridenValuesAreSerialized (line 145) | def test_overridenValuesAreSerialized(self, graphSavedOnDisk):
    method test_connectionsAreSerialized (line 159) | def test_connectionsAreSerialized(self, graphSavedOnDisk):

FILE: tests/test_attributeDescDefaults.py
  class NodeWithMinimalInputs (line 22) | class NodeWithMinimalInputs(desc.Node):
    method process (line 34) | def process(self, node):
  class NodeWithDynamicOutputsMinimal (line 42) | class NodeWithDynamicOutputsMinimal(desc.Node):
    method process (line 52) | def process(self, node):
  function test_param_minimal_creation (line 76) | def test_param_minimal_creation(attrDesc):
  function test_param_no_value_is_dynamic (line 93) | def test_param_no_value_is_dynamic(attrDesc):
  function test_list_and_group_attributes_not_dynamic (line 98) | def test_list_and_group_attributes_not_dynamic():
  function test_label_auto_generated_from_camel_case (line 106) | def test_label_auto_generated_from_camel_case():
  function test_label_auto_generated_from_snake_case (line 113) | def test_label_auto_generated_from_snake_case():
  function test_explicit_label_overrides_auto_generated (line 119) | def test_explicit_label_overrides_auto_generated():
  function test_explicit_description_preserved (line 125) | def test_explicit_description_preserved():
  class TestInputParamDefaults (line 135) | class TestInputParamDefaults:
    method setup_class (line 139) | def setup_class(cls):
    method teardown_class (line 143) | def teardown_class(cls):
    method node (line 147) | def node(self):
    method test_file_input_default (line 151) | def test_file_input_default(self, node):
    method test_bool_input_default (line 154) | def test_bool_input_default(self, node):
    method test_int_input_default (line 157) | def test_int_input_default(self, node):
    method test_float_input_default (line 160) | def test_float_input_default(self, node):
    method test_string_input_default (line 163) | def test_string_input_default(self, node):
    method test_color_input_default (line 166) | def test_color_input_default(self, node):
    method test_choice_input_default (line 169) | def test_choice_input_default(self, node):
  class TestOutputParamDynamicValue (line 174) | class TestOutputParamDynamicValue:
    method setup_class (line 178) | def setup_class(cls):
    method teardown_class (line 182) | def teardown_class(cls):
    method node (line 186) | def node(self):
    method test_output_desc_is_dynamic (line 190) | def test_output_desc_is_dynamic(self, node):
    method test_file_output_value_is_none (line 197) | def test_file_output_value_is_none(self, node):
    method test_bool_output_value_is_none (line 200) | def test_bool_output_value_is_none(self, node):
    method test_int_output_value_is_none (line 203) | def test_int_output_value_is_none(self, node):
    method test_float_output_value_is_none (line 206) | def test_float_output_value_is_none(self, node):
    method test_string_output_value_is_none (line 209) | def test_string_output_value_is_none(self, node):

FILE: tests/test_attributeKeyValues.py
  class NodeWithKeyableAttributes (line 7) | class NodeWithKeyableAttributes(desc.Node):
  class TestKeyableAttribute (line 37) | class TestKeyableAttribute:
    method setup_class (line 40) | def setup_class(cls):
    method teardown_class (line 44) | def teardown_class(cls):
    method test_initialization (line 47) | def test_initialization(self):
    method test_createReadUpdateDelete (line 88) | def test_createReadUpdateDelete(self):
    method test_multipleKeys (line 149) | def test_multipleKeys(self):
    method test_linkAttribute (line 210) | def test_linkAttribute(self):
    method test_uid (line 248) | def test_uid(self):

FILE: tests/test_attributeLambda.py
  class NodeWithCallableValue (line 7) | class NodeWithCallableValue(desc.Node):
  class TestExecuteValue (line 41) | class TestExecuteValue:
    method setup_class (line 45) | def setup_class(cls):
    method teardown_class (line 49) | def teardown_class(cls):
    method test_executeValue_with_node_parameter (line 52) | def test_executeValue_with_node_parameter(self):
    method test_executeValue_with_attr_parameter (line 60) | def test_executeValue_with_attr_parameter(self):
    method test_callable_default_value_with_node_param (line 68) | def test_callable_default_value_with_node_param(self):
    method test_callable_default_value_with_attr_param (line 77) | def test_callable_default_value_with_attr_param(self):
    method test_set_value_with_callable (line 86) | def test_set_value_with_callable(self):
    method test_set_value_with_attr_callable (line 94) | def test_set_value_with_attr_callable(self):
    method test_callable_default_reflects_current_state (line 102) | def test_callable_default_reflects_current_state(self):
    method test_reset_to_default_with_callable (line 114) | def test_reset_to_default_with_callable(self):

FILE: tests/test_attributeShape.py
  class NodeWithShapeAttributes (line 7) | class NodeWithShapeAttributes(desc.Node):
  class TestShapeAttribute (line 81) | class TestShapeAttribute:
    method setup_class (line 84) | def setup_class(cls):
    method teardown_class (line 88) | def teardown_class(cls):
    method test_initialization (line 91) | def test_initialization(self):
    method test_staticShapeGeometry (line 157) | def test_staticShapeGeometry(self):
    method test_keyableShapeGeometry (line 222) | def test_keyableShapeGeometry(self):
    method test_shapeList (line 325) | def test_shapeList(self):
    method test_linkAttribute (line 377) | def test_linkAttribute(self):
    method test_exportDict (line 426) | def test_exportDict(self):

FILE: tests/test_attributes.py
  function test_attribute_retrieve_linked_input_and_output_attributes (line 17) | def test_attribute_retrieve_linked_input_and_output_attributes():
  function test_attribute_is3D_file_extensions (line 55) | def test_attribute_is3D_file_extensions(givenFile, expected):
  function test_attribute_i3D_by_description_semantic (line 73) | def test_attribute_i3D_by_description_semantic():
  function test_attribute_is2D_file_semantic (line 90) | def test_attribute_is2D_file_semantic(givenSemantic, expected):
  function test_attribute_isText_file_extensions (line 110) | def test_attribute_isText_file_extensions(givenFile, expected):
  function test_attribute_isText_by_description_semantic (line 128) | def test_attribute_isText_by_description_semantic():

FILE: tests/test_compatibility.py
  class SampleNodeV1 (line 56) | class SampleNodeV1(desc.Node):
  class SampleNodeV2 (line 68) | class SampleNodeV2(desc.Node):
  class SampleNodeV3 (line 82) | class SampleNodeV3(desc.Node):
  class SampleNodeV4 (line 95) | class SampleNodeV4(desc.Node):
  class SampleNodeV5 (line 112) | class SampleNodeV5(desc.Node):
  class SampleNodeV6 (line 129) | class SampleNodeV6(desc.Node):
  class SampleInputNodeV1 (line 146) | class SampleInputNodeV1(desc.InputNode):
  class SampleInputNodeV2 (line 157) | class SampleInputNodeV2(desc.InputNode):
  function replaceNodeTypeDesc (line 170) | def replaceNodeTypeDesc(nodeType: str, nodeDesc: Type[desc.Node]):
  function test_unknown_node_type (line 175) | def test_unknown_node_type():
  function test_description_conflict (line 211) | def test_description_conflict():
  function test_upgradeAllNodes (line 331) | def test_upgradeAllNodes():
  function test_conformUpgrade (line 383) | def test_conformUpgrade():
  class TestGraphLoadingWithStrictCompatibility (line 424) | class TestGraphLoadingWithStrictCompatibility:
    method test_failsOnUnknownNodeType (line 426) | def test_failsOnUnknownNodeType(self, graphSavedOnDisk):
    method test_failsOnNodeDescriptionCompatibilityIssue (line 435) | def test_failsOnNodeDescriptionCompatibilityIssue(self, graphSavedOnDi...
  class TestGraphTemplateLoading (line 447) | class TestGraphTemplateLoading:
    method test_failsOnUnknownNodeTypeError (line 449) | def test_failsOnUnknownNodeTypeError(self, graphSavedOnDisk):
    method test_loadsIfIncompatibleNodeHasDefaultAttributeValues (line 458) | def test_loadsIfIncompatibleNodeHasDefaultAttributeValues(self, graphS...
    method test_loadsIfValueSetOnCompatibleAttribute (line 468) | def test_loadsIfValueSetOnCompatibleAttribute(self, graphSavedOnDisk):
    method test_loadsIfValueSetOnIncompatibleAttribute (line 479) | def test_loadsIfValueSetOnIncompatibleAttribute(self, graphSavedOnDisk):
  class TestVersionConflict (line 490) | class TestVersionConflict:
    method test_loadingConflictingNodeVersionCreatesCompatibilityNodes (line 492) | def test_loadingConflictingNodeVersionCreatesCompatibilityNodes(self, ...
    method test_loadingUnspecifiedNodeVersionAssumesCurrentVersion (line 507) | def test_loadingUnspecifiedNodeVersionAssumesCurrentVersion(self, grap...
  class UidTestingNodeV1 (line 521) | class UidTestingNodeV1(desc.Node):
  class UidTestingNodeV2 (line 529) | class UidTestingNodeV2(desc.Node):
  class UidTestingNodeV3 (line 552) | class UidTestingNodeV3(desc.Node):
  class TestUidConflict (line 576) | class TestUidConflict:
    method test_changingInvalidateOnAttributeDescCreatesUidConflict (line 577) | def test_changingInvalidateOnAttributeDescCreatesUidConflict(self, gra...
    method test_uidConflictingNodesPreserveConnectionsOnGraphLoad (line 593) | def test_uidConflictingNodesPreserveConnectionsOnGraphLoad(self, graph...
    method test_upgradingConflictingNodesPreserveConnections (line 613) | def test_upgradingConflictingNodesPreserveConnections(self, graphSaved...
    method test_uidConflictDoesNotPropagateToValidDownstreamNodeThroughConnection (line 644) | def test_uidConflictDoesNotPropagateToValidDownstreamNodeThroughConnec...
    method test_uidConflictDoesNotPropagateToValidDownstreamNodeThroughListConnection (line 659) | def test_uidConflictDoesNotPropagateToValidDownstreamNodeThroughListCo...

FILE: tests/test_compute.py
  function executeChunks (line 23) | def executeChunks(node, size):
  class TestNodeA (line 61) | class TestNodeA(desc.BaseNode):
    method processChunk (line 72) | def processChunk(self, chunk):
  class TestNodeB (line 81) | class TestNodeB(TestNodeA):
  class TestNodeC (line 91) | class TestNodeC(desc.BaseNode):
    method process (line 101) | def process(self, node):
  class TestNodeLogger (line 105) | class TestNodeLogger:
    method setup_class (line 114) | def setup_class(cls):
    method teardown_class (line 120) | def teardown_class(cls):
    method test_processChunks (line 125) | def test_processChunks(self, tmp_path):
    method test_process (line 150) | def test_process(self, tmp_path):
  class TestLockUpdates (line 163) | class TestLockUpdates:
    method setup_class (line 171) | def setup_class(cls):
    method teardown_class (line 181) | def teardown_class(cls):
    method checkNodeStatusAndLock (line 188) | def checkNodeStatusAndLock(node, expectedStatus, expectedLock):
    method test_lockDuringComputation (line 192) | def test_lockDuringComputation(self, graphSavedOnDisk):
    method test_lockResetOnParameterChange (line 218) | def test_lockResetOnParameterChange(self, graphSavedOnDisk):
    method test_lockResetOnDuplicatedParameterChange (line 235) | def test_lockResetOnDuplicatedParameterChange(self, graphSavedOnDisk):
    method test_noLockResetOnGraphLoad (line 283) | def test_noLockResetOnGraphLoad(self, graphSavedOnDisk):
    method test_noDownstreamNodeLockDuringComputation (line 310) | def test_noDownstreamNodeLockDuringComputation(self, graphSavedOnDisk):
    method test_upstreamLockDuringComputation (line 337) | def test_upstreamLockDuringComputation(self, graphSavedOnDisk):
    method test_noDownstreamLockAfterParameterChange (line 367) | def test_noDownstreamLockAfterParameterChange(self, graphSavedOnDisk):
    method test_noUpstreamLockAfterParameterChange (line 392) | def test_noUpstreamLockAfterParameterChange(self, graphSavedOnDisk):
  class TestNode_SizeA (line 418) | class TestNode_SizeA(desc.BaseNode):
    method processChunk (line 445) | def processChunk(self, chunk):
  class TestNode_SizeB (line 448) | class TestNode_SizeB(TestNode_SizeA):
  class TestNode_SizeC (line 453) | class TestNode_SizeC(TestNode_SizeA):
  class TestSizeUpdate (line 459) | class TestSizeUpdate:
    method setup_class (line 463) | def setup_class(cls):
    method teardown_class (line 469) | def teardown_class(cls):
    method checkNodeSizeAndStatus (line 475) | def checkNodeSizeAndStatus(node, nodeSize, nbChunks, status):
    method test_correctSizeUpdate (line 480) | def test_correctSizeUpdate(self, graphSavedOnDisk):

FILE: tests/test_graph.py
  function test_depth (line 7) | def test_depth():
  function test_depth_diamond_graph (line 22) | def test_depth_diamond_graph():
  function test_depth_diamond_graph2 (line 59) | def test_depth_diamond_graph2():
  function test_transitive_reduction (line 114) | def test_transitive_reduction():
  function test_graph_reverse_dfsOnDiscover (line 151) | def test_graph_reverse_dfsOnDiscover():
  function test_graph_dfsOnDiscover (line 183) | def test_graph_dfsOnDiscover():
  function test_graph_nodes_sorting (line 223) | def test_graph_nodes_sorting():
  function test_duplicate_nodes (line 241) | def test_duplicate_nodes():
  function test_rename_nodes (line 275) | def test_rename_nodes():

FILE: tests/test_graphIO.py
  class SimpleNode (line 13) | class SimpleNode(desc.Node):
  class NodeWithListAttributes (line 22) | class NodeWithListAttributes(desc.Node):
  function assertPathsAreEqual (line 48) | def assertPathsAreEqual(pathA, pathB):
  function compareGraphsContent (line 52) | def compareGraphsContent(graphA: Graph, graphB: Graph) -> bool:
  class TestImportGraphContent (line 71) | class TestImportGraphContent:
    method test_importEmptyGraph (line 72) | def test_importEmptyGraph(self):
    method test_importGraphWithSingleNode (line 81) | def test_importGraphWithSingleNode(self):
    method test_importGraphWithSeveralNodes (line 92) | def test_importGraphWithSeveralNodes(self):
    method test_importingGraphWithNodesAndEdges (line 104) | def test_importingGraphWithNodesAndEdges(self):
    method test_edgeRemappingOnImportingGraphSeveralTimes (line 117) | def test_edgeRemappingOnImportingGraphSeveralTimes(self):
    method test_edgeRemappingOnImportingGraphWithUnkownNodeTypesSeveralTimes (line 130) | def test_edgeRemappingOnImportingGraphWithUnkownNodeTypesSeveralTimes(...
    method test_importGraphWithUnknownNodeTypesCreatesCompatibilityNodes (line 147) | def test_importGraphWithUnknownNodeTypesCreatesCompatibilityNodes(self):
    method test_importGraphContentInPlace (line 159) | def test_importGraphContentInPlace(self):
    method test_importGraphContentFromFile (line 172) | def test_importGraphContentFromFile(self, graphSavedOnDisk):
    method test_importGraphContentFromFileWithCompatibilityNodes (line 189) | def test_importGraphContentFromFileWithCompatibilityNodes(self, graphS...
    method test_importingDifferentNodeVersionCreatesCompatibilityNodes (line 206) | def test_importingDifferentNodeVersionCreatesCompatibilityNodes(self, ...
  class TestGraphSave (line 223) | class TestGraphSave:
    method test_generateNextPath (line 224) | def test_generateNextPath(self, graphSavedOnDisk):
    method test_saveAsNewVersion (line 244) | def test_saveAsNewVersion(self, tmp_path):
  class TestGraphPartialSerialization (line 261) | class TestGraphPartialSerialization:
    method test_emptyGraph (line 262) | def test_emptyGraph(self):
    method test_serializeAllNodesIsSimilarToStandardSerialization (line 270) | def test_serializeAllNodesIsSimilarToStandardSerialization(self):
    method test_listAttributeToListAttributeConnectionIsSerialized (line 291) | def test_listAttributeToListAttributeConnectionIsSerialized(self):
    method test_singleNodeWithInputConnectionFromNonSerializedNodeRemovesEdge (line 306) | def test_singleNodeWithInputConnectionFromNonSerializedNodeRemovesEdge...
    method test_serializeSingleNodeWithInputConnectionToListAttributeRemovesListEntry (line 324) | def test_serializeSingleNodeWithInputConnectionToListAttributeRemovesL...
    method test_serializeSingleNodeWithInputConnectionToNestedListAttributeRemovesListEntry (line 339) | def test_serializeSingleNodeWithInputConnectionToNestedListAttributeRe...
  class TestGraphCopy (line 355) | class TestGraphCopy:
    method test_graphCopyIsIdenticalToOriginalGraph (line 356) | def test_graphCopyIsIdenticalToOriginalGraph(self):
    method test_graphCopyWithUnknownNodeTypesDiffersFromOriginalGraph (line 368) | def test_graphCopyWithUnknownNodeTypesDiffersFromOriginalGraph(self):
  class TestImportGraphContentFromMinimalGraphData (line 381) | class TestImportGraphContentFromMinimalGraphData:
    method test_nodeWithoutVersionInfoIsUpgraded (line 382) | def test_nodeWithoutVersionInfoIsUpgraded(self):
    method test_connectionsToMissingNodesAreDiscarded (line 399) | def test_connectionsToMissingNodesAreDiscarded(self):

FILE: tests/test_groupAttributes.py
  class TestGroupAttributes (line 19) | class TestGroupAttributes:
    method test_saveLoadGroupDirectConnections (line 20) | def test_saveLoadGroupDirectConnections(self):
    method test_saveLoadGroupConnections (line 44) | def test_saveLoadGroupConnections(self):
    method test_groupAttributesFlatChildren (line 72) | def test_groupAttributesFlatChildren(self):
    method test_groupAttributesDepthLevels (line 104) | def test_groupAttributesDepthLevels(self):
    method test_groupAttributesWithMatchingStructure (line 133) | def test_groupAttributesWithMatchingStructure(self):
    method test_groupAttributesWithDifferentStructures (line 149) | def test_groupAttributesWithDifferentStructures(self):
    method test_connectGroupsWithSubAttributes (line 165) | def test_connectGroupsWithSubAttributes(self):
    method test_connectSubAttributes (line 233) | def test_connectSubAttributes(self):
    method test_connectGroupSubAttributesByValue (line 285) | def test_connectGroupSubAttributesByValue(self):

FILE: tests/test_invalidation.py
  class SampleNode (line 9) | class SampleNode(desc.Node):
  function test_output_invalidation (line 22) | def test_output_invalidation():
  function test_inputLinkInvalidation (line 51) | def test_inputLinkInvalidation():

FILE: tests/test_listAttribute.py
  class NodeWithListAttribute (line 7) | class NodeWithListAttribute(desc.Node):
  class TestListAttribute (line 18) | class TestListAttribute:
    method setup_class (line 21) | def setup_class(cls):
    method teardown_class (line 25) | def teardown_class(cls):
    method test_lengthUsesLinkParam (line 28) | def test_lengthUsesLinkParam(self):
    method test_iterationUsesLinkParam (line 40) | def test_iterationUsesLinkParam(self):
    method test_elementAccessUsesLinkParam (line 53) | def test_elementAccessUsesLinkParam(self):

FILE: tests/test_model.py
  class DummyNode (line 9) | class DummyNode(QObject):
    method __init__ (line 11) | def __init__(self, name="", parent=None):
    method getName (line 15) | def getName(self):
  function test_DictModel_add_remove (line 21) | def test_DictModel_add_remove():
  function test_listModel_typed_add (line 41) | def test_listModel_typed_add():

FILE: tests/test_nodeAttributeChangedCallback.py
  class NodeWithAttributeChangedCallback (line 10) | class NodeWithAttributeChangedCallback(desc.BaseNode):
    method onInputChanged (line 33) | def onInputChanged(self, instance: Node):
    method processChunk (line 36) | def processChunk(self, chunk):
  class TestNodeWithAttributeChangedCallback (line 40) | class TestNodeWithAttributeChangedCallback:
    method setup_class (line 43) | def setup_class(cls):
    method teardown_class (line 47) | def teardown_class(cls):
    method test_assignValueTriggersCallback (line 50) | def test_assignValueTriggersCallback(self):
    method test_specifyDefaultValueDoesNotTriggerCallback (line 57) | def test_specifyDefaultValueDoesNotTriggerCallback(self):
    method test_assignDefaultValueDoesNotTriggerCallback (line 61) | def test_assignDefaultValueDoesNotTriggerCallback(self):
    method test_assignNonDefaultValueTriggersCallback (line 66) | def test_assignNonDefaultValueTriggersCallback(self):
  class TestAttributeCallbackTriggerInGraph (line 72) | class TestAttributeCallbackTriggerInGraph:
    method setup_class (line 75) | def setup_class(cls):
    method teardown_class (line 79) | def teardown_class(cls):
    method test_connectionTriggersCallback (line 82) | def test_connectionTriggersCallback(self):
    method test_connectedValueChangeTriggersCallback (line 94) | def test_connectedValueChangeTriggersCallback(self):
    method test_defaultValueOnlyTriggersCallbackDownstream (line 107) | def test_defaultValueOnlyTriggersCallbackDownstream(self):
    method test_valueChangeIsPropagatedAlongNodeChain (line 120) | def test_valueChangeIsPropagatedAlongNodeChain(self):
    method test_disconnectionTriggersCallback (line 138) | def test_disconnectionTriggersCallback(self):
    method test_loadingGraphDoesNotTriggerCallback (line 152) | def test_loadingGraphDoesNotTriggerCallback(self, graphSavedOnDisk):
    method test_loadingGraphDoesNotTriggerCallbackForConnectedAttributes (line 165) | def test_loadingGraphDoesNotTriggerCallbackForConnectedAttributes(
  class NodeWithCompoundAttributes (line 186) | class NodeWithCompoundAttributes(desc.BaseNode):
  class TestAttributeCallbackBehaviorWithUpstreamCompoundAttributes (line 244) | class TestAttributeCallbackBehaviorWithUpstreamCompoundAttributes:
    method setup_class (line 247) | def setup_class(cls):
    method teardown_class (line 252) | def teardown_class(cls):
    method test_connectionToListElement (line 256) | def test_connectionToListElement(self):
    method test_connectionToGroupElement (line 271) | def test_connectionToGroupElement(self):
    method test_connectionToGroupElementInList (line 283) | def test_connectionToGroupElementInList(self):
    method test_connectionToListElementInGroup (line 299) | def test_connectionToListElementInGroup(self):
  class NodeWithDynamicOutputValue (line 316) | class NodeWithDynamicOutputValue(desc.BaseNode):
    method processChunk (line 341) | def processChunk(self, chunk):
  class TestAttributeCallbackBehaviorWithUpstreamDynamicOutputs (line 345) | class TestAttributeCallbackBehaviorWithUpstreamDynamicOutputs:
    method setup_class (line 350) | def setup_class(cls):
    method teardown_class (line 355) | def teardown_class(cls):
    method test_connectingUncomputedDynamicOutputDoesNotTriggerDownstreamAttributeChangedCallback (line 359) | def test_connectingUncomputedDynamicOutputDoesNotTriggerDownstreamAttr...
    method test_connectingComputedDynamicOutputTriggersDownstreamAttributeChangedCallback (line 371) | def test_connectingComputedDynamicOutputTriggersDownstreamAttributeCha...
    method test_dynamicOutputValueComputeDoesNotTriggerDownstreamAttributeChangedCallback (line 385) | def test_dynamicOutputValueComputeDoesNotTriggerDownstreamAttributeCha...
    method test_clearingDynamicOutputValueDoesNotTriggerDownstreamAttributeChangedCallback (line 399) | def test_clearingDynamicOutputValueDoesNotTriggerDownstreamAttributeCh...
    method test_loadingGraphWithComputedDynamicOutputValueDoesNotTriggerDownstreamAttributeChangedCallback (line 418) | def test_loadingGraphWithComputedDynamicOutputValueDoesNotTriggerDowns...
  class TestAttributeCallbackBehaviorOnGraphImport (line 439) | class TestAttributeCallbackBehaviorOnGraphImport:
    method setup_class (line 441) | def setup_class(cls):
    method teardown_class (line 445) | def teardown_class(cls):
    method test_importingGraphDoesNotTriggerAttributeChangedCallbacks (line 448) | def test_importingGraphDoesNotTriggerAttributeChangedCallbacks(self):

FILE: tests/test_nodeAttributesFormatting.py
  class NodeWithAttributesNeedingFormatting (line 10) | class NodeWithAttributesNeedingFormatting(desc.Node):
  class TestAttributesFormatting (line 104) | class TestAttributesFormatting:
    method setup_class (line 107) | def setup_class(cls):
    method teardown_class (line 111) | def teardown_class(cls):
    method test_formatting_listOfFiles (line 114) | def test_formatting_listOfFiles(self):
    method test_formatting_strings (line 145) | def test_formatting_strings(self):
    method test_formatting_groups (line 179) | def test_formatting_groups(self):

FILE: tests/test_nodeCallbacks.py
  class NodeWithCreationCallback (line 8) | class NodeWithCreationCallback(desc.InputNode):
    method onNodeCreated (line 21) | def onNodeCreated(cls, node: Node):
  class TestNodeCreationCallback (line 26) | class TestNodeCreationCallback:
    method setup_class (line 29) | def setup_class(cls):
    method teardown_class (line 33) | def teardown_class(cls):
    method test_notTriggeredOnNodeInstantiation (line 36) | def test_notTriggeredOnNodeInstantiation(self):
    method test_triggeredOnNewNodeCreationInGraph (line 40) | def test_triggeredOnNewNodeCreationInGraph(self):
    method test_notTriggeredOnNodeDuplication (line 45) | def test_notTriggeredOnNodeDuplication(self):
    method test_notTriggeredOnGraphLoad (line 53) | def test_notTriggeredOnGraphLoad(self, graphSavedOnDisk):
    method test_triggeredOnGraphInitializationFromTemplate (line 62) | def test_triggeredOnGraphInitializationFromTemplate(self, graphSavedOn...

FILE: tests/test_nodeCommandLineFormatting.py
  class NodeWithCommandLineFormatting_usingNodeAndLambda (line 10) | class NodeWithCommandLineFormatting_usingNodeAndLambda(desc.CommandLineN...
  function customFunction_commandline (line 34) | def customFunction_commandline(node):
  class NodeWithCommandLineFormatting_usingNodeAndFunction (line 38) | class NodeWithCommandLineFormatting_usingNodeAndFunction(desc.CommandLin...
  class NodeWithCommandLineFormatting_usingNode (line 63) | class NodeWithCommandLineFormatting_usingNode(desc.CommandLineNode):
  class NodeWithCommandLineFormatting_usingValue (line 88) | class NodeWithCommandLineFormatting_usingValue(desc.CommandLineNode):
  class TestCommandLineFormatting (line 113) | class TestCommandLineFormatting:
    method setup_class (line 116) | def setup_class(cls):
    method teardown_class (line 123) | def teardown_class(cls):
    method test_commandLine_node (line 129) | def test_commandLine_node(self):

FILE: tests/test_nodeDynamicOutputs.py
  class NodeWithDynamicOutputs (line 12) | class NodeWithDynamicOutputs(desc.Node):
    method process (line 79) | def process(self, node):
  class InputNodeWithDynamicOutputs (line 88) | class InputNodeWithDynamicOutputs(desc.InputNode):
  class TestNodesWithDynamicOutputs (line 108) | class TestNodesWithDynamicOutputs:
    method setup_class (line 110) | def setup_class(cls):
    method teardown_class (line 114) | def teardown_class(cls):
    method test_processWithDynamicOutputs (line 117) | def test_processWithDynamicOutputs(self, graphSavedOnDisk):
    method test_processWithDynamicOutputsNonDefaultInputs (line 130) | def test_processWithDynamicOutputsNonDefaultInputs(self, graphSavedOnD...
    method test_loadGraphWithUncomputedDynamicOutputs (line 149) | def test_loadGraphWithUncomputedDynamicOutputs(self, graphSavedOnDisk):
    method test_loadGraphWithComputedDynamicOutputs (line 164) | def test_loadGraphWithComputedDynamicOutputs(self, graphSavedOnDisk):
  class TestInputNodeWithDynamicOutputs (line 193) | class TestInputNodeWithDynamicOutputs:
    method test_registerInputNodeWithDynamicOutputs (line 194) | def test_registerInputNodeWithDynamicOutputs(self):
    method test_registerInputNodeWithDynamicOutputsV2 (line 215) | def test_registerInputNodeWithDynamicOutputsV2(self):

FILE: tests/test_nodes.py
  class TestNodeInfo (line 16) | class TestNodeInfo:
    method setup_class (line 20) | def setup_class(cls):
    method teardown_class (line 30) | def teardown_class(cls):
    method test_loadedPlugin (line 36) | def test_loadedPlugin(self):
  class TestNodeVariables (line 59) | class TestNodeVariables:
    method setup_class (line 63) | def setup_class(cls):
    method teardown_class (line 73) | def teardown_class(cls):
    method test_staticVariables (line 79) | def test_staticVariables(self):
    method test_expVariables (line 94) | def test_expVariables(self):
  class TestInitNode (line 114) | class TestInitNode:
    method setup_class (line 118) | def setup_class(cls):
    method teardown_class (line 128) | def teardown_class(cls):
    method test_initNode (line 134) | def test_initNode(self):
  class TestBackdropNode (line 149) | class TestBackdropNode:
    method setup_class (line 153) | def setup_class(cls):
    method teardown_class (line 157) | def teardown_class(cls):
    method test_backdropNode (line 164) | def test_backdropNode(self):
    method test_backdropNode_customAttributes (line 188) | def test_backdropNode_customAttributes(self):
    method test_backdropNode_defaultSerialization (line 218) | def test_backdropNode_defaultSerialization(self):
    method test_backdropNode_customSerialization (line 238) | def test_backdropNode_customSerialization(self):
  class TestResourceLevels (line 273) | class TestResourceLevels:
    method test_staticResourceLevels (line 276) | def test_staticResourceLevels(self):
    method test_callableResourceLevels (line 295) | def test_callableResourceLevels(self):
    method test_mixedResourceLevels (line 329) | def test_mixedResourceLevels(self):
  class TestNodeColor (line 354) | class TestNodeColor:
    method test_defaultColor (line 357) | def test_defaultColor(self):
    method test_descriptorColor (line 370) | def test_descriptorColor(self):
    method test_instanceColorOverridesDescriptorColor (line 385) | def test_instanceColorOverridesDescriptorColor(self):
    method test_resetToDefaultRestoresDescriptorColor (line 401) | def test_resetToDefaultRestoresDescriptorColor(self):
  class TestNodeSizeLambda (line 422) | class TestNodeSizeLambda:
    method test_size_lambda_single_arg (line 425) | def test_size_lambda_single_arg(self):
    method test_size_static_node_size (line 450) | def test_size_static_node_size(self):
    method test_size_dynamic_node_size (line 464) | def test_size_dynamic_node_size(self):
    method test_size_custom_function (line 489) | def test_size_custom_function(self):
    method test_size_custom_callable_class (line 517) | def test_size_custom_callable_class(self):

FILE: tests/test_pipeline.py
  function test_pipeline (line 11) | def test_pipeline():

FILE: tests/test_plugins.py
  class TestPluginWithValidNodesOnly (line 12) | class TestPluginWithValidNodesOnly:
    method setup_class (line 16) | def setup_class(cls):
    method teardown_class (line 26) | def teardown_class(cls):
    method test_loadedPlugin (line 32) | def test_loadedPlugin(self):
    method test_unloadPlugin (line 51) | def test_unloadPlugin(self):
    method test_updateRegisteredNodes (line 89) | def test_updateRegisteredNodes(self):
  class TestPluginWithInvalidNodes (line 120) | class TestPluginWithInvalidNodes:
    method setup_class (line 124) | def setup_class(cls):
    method teardown_class (line 134) | def teardown_class(cls):
    method test_loadedPlugin (line 140) | def test_loadedPlugin(self):
    method test_reloadNodePluginInvalidDescrpition (line 163) | def test_reloadNodePluginInvalidDescrpition(self):
    method test_reloadNodePluginSyntaxError (line 222) | def test_reloadNodePluginSyntaxError(self):
  class TestPluginsConfiguration (line 256) | class TestPluginsConfiguration:
    method test_loadedConfig (line 263) | def test_loadedConfig(self):
    method test_loadedConfigWithOnlyExistingKeys (line 296) | def test_loadedConfigWithOnlyExistingKeys(self):
    method test_loadedConfigWithSomeExistingKeys (line 334) | def test_loadedConfigWithSomeExistingKeys(self):

FILE: tests/test_submit.py
  function get_submitter (line 27) | def get_submitter() -> LocalFarmSubmitter:
  function getJobEnv (line 34) | def getJobEnv():
  function waitForNodeCompletion (line 42) | def waitForNodeCompletion(job: LocalFarmJob, node: Node, timeout=25):
  function processSubmit (line 62) | def processSubmit(node: Node, graph, tmp_path):
  class TestNodeSubmit (line 103) | class TestNodeSubmit:
    method setup_class (line 107) | def setup_class(cls):
    method teardown_class (line 122) | def teardown_class(cls):
    method setupNode (line 128) | def setupNode(self, graph, name):
    method test_submitNoParallel (line 136) | def test_submitNoParallel(self, tmp_path):
    method test_submitStaticSize (line 143) | def test_submitStaticSize(self, tmp_path):
    method test_submitDynamicSize (line 150) | def test_submitDynamicSize(self, tmp_path):

FILE: tests/utils.py
  function registeredNodeTypes (line 11) | def registeredNodeTypes(nodeTypes: list[desc.Node]):
  function overrideNodeTypeVersion (line 25) | def overrideNodeTypeVersion(nodeType: desc.Node, version: str):
  function registerNodeDesc (line 36) | def registerNodeDesc(nodeDesc: desc.Node):
  function unregisterNodeDesc (line 42) | def unregisterNodeDesc(nodeDesc: desc.Node):
  function registeredPlugins (line 49) | def registeredPlugins(folder: str):
  function overrideOsEnvironmentVariables (line 58) | def overrideOsEnvironmentVariables(envVariables: dict):
Condensed preview — 343 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,595K chars).
[
  {
    "path": ".codecov.yml",
    "chars": 1535,
    "preview": "# Codecov configuration for Meshroom\n# This configuration prevents CI from failing due to small coverage decreases\n# whi"
  },
  {
    "path": ".git-blame-ignore-revs",
    "chars": 2983,
    "preview": "# Linting: Harmonize docstrings and comments\n039e0620ad05d673a2ef9aa501e9a509219671c9\n# Linting: Remove all trailing whi"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 78,
    "preview": "github: [alicevision]\ncustom: ['https://alicevision.org/association/#donate']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1020,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[bug]\"\nlabels: bug\nassignees: ''\n\n---\n\n**Describe"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 622,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"[request]\"\nlabels: feature request\nassignees: "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question_help.md",
    "chars": 1122,
    "preview": "---\nname: Question or help needed\nabout: Ask question or for help for issues not related to program failures (e.g. \"wher"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 717,
    "preview": "<!-- Checklist before submission:\n\n - I have read the [contribution guidelines](../CONTRIBUTING.md).\n - I have updated t"
  },
  {
    "path": ".github/stale.yml",
    "chars": 838,
    "preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 120\n# Number of days of inactivity before a"
  },
  {
    "path": ".github/workflows/continuous-integration.yml",
    "chars": 3535,
    "preview": "name: Continuous Integration\n\non:\n  push:\n    branches:\n      - master\n      - develop\n    # Skip jobs when only documen"
  },
  {
    "path": ".gitignore",
    "chars": 520,
    "preview": "# temporary files\n*~\n# vim\n.*.swp\n# emacs\n*.flc\n\\#*\\#\n.\\#*\n# xemacs\n# MacOS\n.DS_Store\n# Windows\nThumbs.db\n# vscode\n.vsco"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 417,
    "preview": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
  },
  {
    "path": "CHANGES.md",
    "chars": 91596,
    "preview": "# Meshroom Changelog\n\nFor algorithmic changes related to the photogrammetric pipeline, \nplease refer to [AliceVision cha"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 1958,
    "preview": "cmake_minimum_required(VERSION 3.12)\nproject(meshroom LANGUAGES C CXX)\n\nif(NOT CMAKE_BUILD_TYPE)\n  set(CMAKE_BUILD_TYPE "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3211,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1632,
    "preview": "Contributing to Meshroom\n===========================\n\nMeshroom relies on a friendly and community-driven effort to creat"
  },
  {
    "path": "COPYING.md",
    "chars": 1175,
    "preview": "## Meshroom License\n\nMeshroom is licensed under the [MPL2 license](LICENSE-MPL2.md).\n\n## Third parties licenses\n\n * __Al"
  },
  {
    "path": "INSTALL.md",
    "chars": 9476,
    "preview": "# Meshroom Installation\nThis guide will help you setup a development environment to launch and contribute to Meshroom.\n\n"
  },
  {
    "path": "INSTALL_PLUGINS.md",
    "chars": 1893,
    "preview": "# Meshroom plugins installation\n\nPlugins are collections of nodes and templates with their own dependencies. Plugin main"
  },
  {
    "path": "LICENSE-MPL2.md",
    "chars": 16726,
    "preview": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\""
  },
  {
    "path": "NODE_DEVELOPMENT.md",
    "chars": 12794,
    "preview": "# Meshroom Node Development\n\n\n## Node Creation\n\nThis guide shows how to implement three common Meshroom node types: Pyth"
  },
  {
    "path": "README.md",
    "chars": 9032,
    "preview": "# ![Meshroom - 3D Reconstruction Software](/docs/logo/banner-meshroom.png)\n\nMeshroom is an open-source, node-based visua"
  },
  {
    "path": "RELEASING.md",
    "chars": 2021,
    "preview": "\n### Versioning\n\nVersion = MAJOR (>=1 year), MINOR (>= 1 month), PATCH\n\nVersion Status = Develop / Release\n\n\n### Git\n\nBr"
  },
  {
    "path": "WINDOWS_EXE.md",
    "chars": 1593,
    "preview": "# Meshroom executable generation on Windows\n\nThis describes how to generate Meshroom's executable on Windows. This does "
  },
  {
    "path": "bin/meshroom_batch",
    "chars": 12456,
    "preview": "#!/usr/bin/env python\nimport argparse\nimport json\nimport logging\nimport os\nimport re\nimport sys\n\nimport meshroom.core.gr"
  },
  {
    "path": "bin/meshroom_compute",
    "chars": 6745,
    "preview": "#!/usr/bin/env python\nimport argparse\nimport logging\nimport os\nimport sys\nfrom typing import NoReturn\n\ntry:\n    import m"
  },
  {
    "path": "bin/meshroom_createChunks",
    "chars": 6298,
    "preview": "#!/usr/bin/env python\n\n\"\"\"\nThis is a script used to wrap the process of processing a node on the farm\nIt will handle chu"
  },
  {
    "path": "bin/meshroom_newNodeType",
    "chars": 9157,
    "preview": "#!/usr/bin/env python\n\nimport argparse\nimport os\nimport re\nimport sys\nimport shlex\nfrom pprint import pprint\n\ndef trim(s"
  },
  {
    "path": "bin/meshroom_statistics",
    "chars": 3339,
    "preview": "#!/usr/bin/env python\nimport argparse\nimport os\nimport sys\nimport logging\nfrom collections import defaultdict\nfrom colle"
  },
  {
    "path": "bin/meshroom_status",
    "chars": 2419,
    "preview": "#!/usr/bin/env python\nimport argparse\nimport os\nimport sys\nimport pprint\nimport logging\n\nimport meshroom\nmeshroom.setupE"
  },
  {
    "path": "bin/meshroom_submit",
    "chars": 1043,
    "preview": "#!/usr/bin/env python\nimport argparse\n\nimport meshroom\nmeshroom.setupEnvironment()\n\nimport meshroom.core.graph\n\nparser ="
  },
  {
    "path": "dev_requirements.txt",
    "chars": 87,
    "preview": "# packaging\ncx_Freeze==7.2.10\n\n# Python binding packaging\nnumpy==1.*\n\n# testing\npytest\n"
  },
  {
    "path": "docker/Dockerfile_rocky",
    "chars": 4542,
    "preview": "ARG MESHROOM_VERSION\nARG AV_VERSION\nARG CUDA_VERSION\nARG ROCKY_VERSION\nFROM alicevision/meshroom-deps:${MESHROOM_VERSION"
  },
  {
    "path": "docker/Dockerfile_rocky_deps",
    "chars": 1984,
    "preview": "ARG AV_VERSION\nARG CUDA_VERSION\nARG ROCKY_VERSION\nFROM alicevision/alicevision:${AV_VERSION}-rocky${ROCKY_VERSION}-cuda$"
  },
  {
    "path": "docker/Dockerfile_ubuntu",
    "chars": 4146,
    "preview": "ARG MESHROOM_VERSION\nARG AV_VERSION\nARG CUDA_VERSION\nARG UBUNTU_VERSION\nFROM alicevision/meshroom-deps:${MESHROOM_VERSIO"
  },
  {
    "path": "docker/Dockerfile_ubuntu_deps",
    "chars": 2468,
    "preview": "ARG AV_VERSION\nARG CUDA_VERSION\nARG UBUNTU_VERSION\nFROM alicevision/alicevision:${AV_VERSION}-ubuntu${UBUNTU_VERSION}-cu"
  },
  {
    "path": "docker/build-all.sh",
    "chars": 247,
    "preview": "#!/bin/sh\n\nset -e\n\ntest -d docker || (\n        echo This script must be run from the top level Meshroom directory\n\texit "
  },
  {
    "path": "docker/build-rocky.sh",
    "chars": 1420,
    "preview": "#!/bin/bash\nset -e\n\ntest -z \"$MESHROOM_VERSION\" && MESHROOM_VERSION=\"$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse "
  },
  {
    "path": "docker/build-ubuntu.sh",
    "chars": 1436,
    "preview": "#!/bin/bash\nset -e\n\ntest -z \"$MESHROOM_VERSION\" && MESHROOM_VERSION=\"$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse "
  },
  {
    "path": "docker/extract-rocky.sh",
    "chars": 747,
    "preview": "#!/bin/bash\nset -ex\n\ntest -z \"$MESHROOM_VERSION\" && MESHROOM_VERSION=\"$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse"
  },
  {
    "path": "docker/extract-ubuntu.sh",
    "chars": 755,
    "preview": "#!/bin/bash\nset -ex\n\ntest -z \"$MESHROOM_VERSION\" && MESHROOM_VERSION=\"$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse"
  },
  {
    "path": "docs/.gitignore",
    "chars": 34,
    "preview": "# Sphinx\nbuild/\nsource/generated/\n"
  },
  {
    "path": "docs/Makefile",
    "chars": 638,
    "preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the "
  },
  {
    "path": "docs/README.md",
    "chars": 681,
    "preview": "# Documentation\n\nWe use [Sphinx](https://www.sphinx-doc.org) to generate Meshroom's documentation.\n\n## Requirements\n\nTo "
  },
  {
    "path": "docs/make.bat",
    "chars": 769,
    "preview": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-bu"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 12,
    "preview": "myst-parser\n"
  },
  {
    "path": "docs/source/_ext/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/source/_ext/fetch_md.py",
    "chars": 1749,
    "preview": "# Sphinx extension defining the fetch_md directive\n#\n# Goal:\n# include the content of a given markdown file\n#\n# Usage:\n#"
  },
  {
    "path": "docs/source/_ext/meshroom_doc.py",
    "chars": 2034,
    "preview": "# Sphinx extension defining the meshroom_doc directive\n#\n# Goal:\n# create specific documentation content for meshroom ob"
  },
  {
    "path": "docs/source/_ext/utils.py",
    "chars": 678,
    "preview": "# Utility functions for custom Sphinx extensions\n\nfrom myst_parser.docutils_ import Parser\nfrom myst_parser.mdit_to_docu"
  },
  {
    "path": "docs/source/_templates/autosummary/class.rst",
    "chars": 666,
    "preview": "{{ fullname | escape | underline}}\n\n\n.. inheritance-diagram:: {{ fullname }}\n\n\n.. meshroom_doc::\n   :module: {{ module }"
  },
  {
    "path": "docs/source/_templates/autosummary/module.rst",
    "chars": 1106,
    "preview": "{{ fullname | escape | underline}}\n\n\n.. automodule:: {{ fullname }}\n\n   {% block attributes %}\n   {% if attributes %}\n  "
  },
  {
    "path": "docs/source/api.rst",
    "chars": 121,
    "preview": "Python API Reference\n====================\n\n\n.. autosummary::\n   :recursive:\n   :toctree: generated\n\n   meshroom\n   tests"
  },
  {
    "path": "docs/source/changes.rst",
    "chars": 55,
    "preview": "Release Notes\n=============\n\n\n.. fetch_md:: CHANGES.md\n"
  },
  {
    "path": "docs/source/conf.py",
    "chars": 1309,
    "preview": "# Configuration file for the Sphinx documentation builder.\n#\n# For the full list of built-in configuration values, see t"
  },
  {
    "path": "docs/source/index.rst",
    "chars": 184,
    "preview": "Welcome to meshroom's documentation!\n====================================\n\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Co"
  },
  {
    "path": "docs/source/install.rst",
    "chars": 43,
    "preview": "Install\n=======\n\n\n.. fetch_md:: INSTALL.md\n"
  },
  {
    "path": "localfarm/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "localfarm/localFarm.py",
    "chars": 10400,
    "preview": "#!/usr/bin/env python\n\n\"\"\"\nLocal Farm : A simple local job runner\n\"\"\"\n\nfrom __future__ import annotations  # For forward"
  },
  {
    "path": "localfarm/localFarmBackend.py",
    "chars": 24091,
    "preview": "#!/usr/bin/env python\n\n\"\"\"\nLocal Farm : A simple local job runner\n\"\"\"\n\nimport os\nimport sys\nimport random\nimport argpars"
  },
  {
    "path": "localfarm/localFarmLauncher.py",
    "chars": 6009,
    "preview": "#!/usr/bin/env python\n\nimport os\nimport shutil\nimport sys\nimport time\nimport signal\nimport argparse\nfrom pathlib import "
  },
  {
    "path": "localfarm/test.py",
    "chars": 3655,
    "preview": "#!/usr/bin/env python\n\nimport os\nfrom time import sleep\nfrom localfarm.localFarm import Task, Job, LocalFarmEngine\nfrom "
  },
  {
    "path": "meshroom/__init__.py",
    "chars": 7626,
    "preview": "from enum import Enum, IntEnum\nimport logging\nimport os\nimport sys\n\n\nclass VersionStatus(Enum):\n    release = 1\n    deve"
  },
  {
    "path": "meshroom/common/PySignal.py",
    "chars": 8712,
    "preview": "# https://github.com/dgovil/PySignal\n\n__author__ = \"Dhruv Govil\"\n__copyright__ = \"Copyright 2016, Dhruv Govil\"\n__credits"
  },
  {
    "path": "meshroom/common/__init__.py",
    "chars": 1518,
    "preview": "\"\"\"\nThis module provides an abstraction around standard non-gui Qt notions (like Signal/Slot),\nso it can be used in pyth"
  },
  {
    "path": "meshroom/common/core.py",
    "chars": 4038,
    "preview": "from . import PySignal\n\n\nclass CoreDictModel:\n\n    def __init__(self, keyAttrName, **kwargs):\n        self._objects = {}"
  },
  {
    "path": "meshroom/common/deprecated.py",
    "chars": 1414,
    "preview": "\"\"\"Utilities for marking function parameters as deprecated.\"\"\"\n\nimport warnings\nimport logging\n\n\ndef depreciateParam(par"
  },
  {
    "path": "meshroom/common/qt.py",
    "chars": 14672,
    "preview": "from PySide6 import QtCore, QtQml\nimport shiboken6\n\n\nclass QObjectListModel(QtCore.QAbstractListModel):\n    \"\"\"\n    QObj"
  },
  {
    "path": "meshroom/core/__init__.py",
    "chars": 16366,
    "preview": "from contextlib import contextmanager\nimport hashlib\nimport importlib\nimport inspect\nimport logging\nimport os\nfrom pathl"
  },
  {
    "path": "meshroom/core/attribute.py",
    "chars": 62163,
    "preview": "#!/usr/bin/env python\nfrom __future__ import annotations\n\nimport copy\nimport os\nimport re\nimport weakref\nimport logging\n"
  },
  {
    "path": "meshroom/core/cgroup.py",
    "chars": 2483,
    "preview": "#!/usr/bin/env python\n\nimport os\n\n\n# Try to retrieve limits of memory for the current process' cgroup\ndef getCgroupMemor"
  },
  {
    "path": "meshroom/core/desc/__init__.py",
    "chars": 732,
    "preview": "from .attribute import (\n    Attribute,\n    BoolParam,\n    ChoiceParam,\n    ColorParam,\n    File,\n    FloatParam,\n    Gr"
  },
  {
    "path": "meshroom/core/desc/attribute.py",
    "chars": 33587,
    "preview": "import ast\nimport os\nimport re\nfrom collections.abc import Iterable\nfrom enum import auto, Enum\n\nfrom meshroom.common im"
  },
  {
    "path": "meshroom/core/desc/computation.py",
    "chars": 4354,
    "preview": "import math\nfrom enum import IntEnum\n\nfrom .attribute import ListAttribute, IntParam\n\n\nclass Level(IntEnum):\n    SCRIPT="
  },
  {
    "path": "meshroom/core/desc/geometryAttribute.py",
    "chars": 3619,
    "preview": "from meshroom.core.desc import GroupAttribute, FloatParam\n\n\nclass Geometry(GroupAttribute):\n    \"\"\"\n    Base attribute f"
  },
  {
    "path": "meshroom/core/desc/node.py",
    "chars": 20370,
    "preview": "import enum\nfrom inspect import getfile, getattr_static\nfrom pathlib import Path\nimport logging\nimport shlex\nimport shut"
  },
  {
    "path": "meshroom/core/desc/shapeAttribute.py",
    "chars": 7579,
    "preview": "from meshroom.core.desc import ListAttribute, GroupAttribute, StringParam, FloatParam, Geometry, Size2d, Vec2d\n\nclass Sh"
  },
  {
    "path": "meshroom/core/evaluation.py",
    "chars": 1817,
    "preview": "#!/usr/bin/env python\n\nimport ast, math\n\n\nclass MathEvaluator:\n    \"\"\" Evaluate math expressions\n\n    ..code::py\n       "
  },
  {
    "path": "meshroom/core/exception.py",
    "chars": 1956,
    "preview": "#!/usr/bin/env python\n\n\nclass MeshroomException(Exception):\n    \"\"\" Base class for Meshroom exceptions \"\"\"\n    pass\n\n\ncl"
  },
  {
    "path": "meshroom/core/fileUtils.py",
    "chars": 2149,
    "preview": "import os\nimport re\n\npattern = r\"(?P<FILESTEM_PREFIX>.*?)(?P<FRAMEID_STR>[-._]\\d+)?(?P<EXTENSION>\\.\\w{3,4})\"\ncompiled_pa"
  },
  {
    "path": "meshroom/core/graph.py",
    "chars": 72079,
    "preview": "import json\nimport logging\nimport os\nimport re\nfrom typing import Any, Optional\nfrom collections.abc import Iterable\nfro"
  },
  {
    "path": "meshroom/core/graphIO.py",
    "chars": 8539,
    "preview": "from enum import Enum\nfrom typing import Any, TYPE_CHECKING, Union\n\nimport meshroom\nfrom meshroom.core import Version\nfr"
  },
  {
    "path": "meshroom/core/keyValues.py",
    "chars": 4257,
    "preview": "import json\nfrom typing import Any\n\nfrom meshroom.common import BaseObject, Property, Variant, Signal, DictModel, Slot\nf"
  },
  {
    "path": "meshroom/core/mtyping.py",
    "chars": 128,
    "preview": "\"\"\"\nCommon typing aliases used in Meshroom.\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Union\n\nPathLike = Union[Pat"
  },
  {
    "path": "meshroom/core/node.py",
    "chars": 110375,
    "preview": "#!/usr/bin/env python\nimport sys\nimport atexit\nimport copy\nimport datetime\nimport json\nimport logging\nimport os\nimport p"
  },
  {
    "path": "meshroom/core/nodeFactory.py",
    "chars": 9268,
    "preview": "import logging\nfrom typing import Any, Optional, Union\nfrom collections.abc import Iterable\n\nimport meshroom.core\nfrom m"
  },
  {
    "path": "meshroom/core/plugins.py",
    "chars": 29583,
    "preview": "from __future__ import annotations\n\nimport glob\nimport importlib\nimport json\nimport logging\nimport os\nimport re\nimport s"
  },
  {
    "path": "meshroom/core/stats.py",
    "chars": 11690,
    "preview": "from collections import defaultdict\nimport os\nimport platform\nimport time\nimport threading\nimport xml.etree.ElementTree "
  },
  {
    "path": "meshroom/core/submitter.py",
    "chars": 8881,
    "preview": "#!/usr/bin/env python\n\nimport sys\nimport logging\nimport operator\n\nfrom enum import IntFlag, auto\nfrom typing import Opti"
  },
  {
    "path": "meshroom/core/taskManager.py",
    "chars": 23120,
    "preview": "import traceback\nimport logging\nfrom threading import Thread\nfrom PySide6.QtCore import QThread, QEventLoop, QTimer\nfrom"
  },
  {
    "path": "meshroom/core/test.py",
    "chars": 3120,
    "preview": "#!/usr/bin/env python\n\nimport json\n\nfrom meshroom.core import pipelineTemplates, Version\nfrom meshroom.core.node import "
  },
  {
    "path": "meshroom/core/utils.py",
    "chars": 1034,
    "preview": "COLORSPACES = [\"AUTO\", \"sRGB\", \"rec709\", \"Linear\", \"ACES2065-1\", \"ACEScg\", \"Linear ARRI Wide Gamut 3\",\n               \"A"
  },
  {
    "path": "meshroom/env.py",
    "chars": 3123,
    "preview": "\"\"\"\nMeshroom environment variable management.\n\"\"\"\n\n__all__ = [\n    \"EnvVar\",\n    \"EnvVarHelpAction\",\n]\n\nimport argparse\n"
  },
  {
    "path": "meshroom/multiview.py",
    "chars": 5067,
    "preview": "import os\n\n# Supported image extensions\nimageExtensions = [\n    # bmp:\n    '.bmp',\n    # cineon:\n    '.cin',\n    # dds\n "
  },
  {
    "path": "meshroom/nodes/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "meshroom/nodes/general/Backdrop.py",
    "chars": 204,
    "preview": "__version__ = \"1.0\"\n\nfrom meshroom.core import desc\n\nclass Backdrop(desc.BackdropNode):\n    \"\"\" Backdrop node. Any node "
  },
  {
    "path": "meshroom/nodes/general/CopyFiles.py",
    "chars": 2941,
    "preview": "__version__ = \"1.3\"\n\nfrom meshroom.core import desc\nfrom meshroom.core.utils import VERBOSE_LEVEL\n\nimport shutil\nimport "
  },
  {
    "path": "meshroom/nodes/general/InputFile.py",
    "chars": 1660,
    "preview": "__version__ = \"1.0\"\n\nimport logging\nimport os\n\nfrom meshroom.core import desc\n\nclass InputFile(desc.InputNode, desc.Init"
  },
  {
    "path": "meshroom/nodes/general/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "meshroom/submitters/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "meshroom/submitters/localFarmSubmitter.py",
    "chars": 15432,
    "preview": "#!/usr/bin/env python\n\nimport os\nimport re\nimport shutil\nimport logging\nfrom pathlib import Path\nfrom typing import List"
  },
  {
    "path": "meshroom/ui/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "meshroom/ui/__main__.py",
    "chars": 393,
    "preview": "import signal\nimport sys\nimport meshroom\nfrom meshroom.common import Backend\n\nmeshroom.setupEnvironment(backend=Backend."
  },
  {
    "path": "meshroom/ui/app.py",
    "chars": 32633,
    "preview": "import logging\nimport os\nimport re\nimport argparse\nimport json\nfrom enum import Enum\n\nfrom PySide6 import __version__ as"
  },
  {
    "path": "meshroom/ui/commands.py",
    "chars": 24853,
    "preview": "import logging\nimport traceback\nfrom contextlib import contextmanager\n\nfrom PySide6.QtGui import QUndoCommand, QUndoStac"
  },
  {
    "path": "meshroom/ui/components/__init__.py",
    "chars": 1607,
    "preview": "\ndef registerTypes():\n    from PySide6.QtQml import qmlRegisterType, qmlRegisterSingletonType\n    from meshroom.ui.compo"
  },
  {
    "path": "meshroom/ui/components/clipboard.py",
    "chars": 596,
    "preview": "from PySide6.QtCore import Slot, QObject\nfrom PySide6.QtGui import QGuiApplication\n\n\nclass ClipboardHelper(QObject):\n   "
  },
  {
    "path": "meshroom/ui/components/csvData.py",
    "chars": 3914,
    "preview": "from meshroom.common.qt import QObjectListModel\n\nfrom PySide6.QtCore import QObject, Slot, Signal, Property\nfrom PySide6"
  },
  {
    "path": "meshroom/ui/components/edge.py",
    "chars": 4639,
    "preview": "from PySide6.QtCore import Signal, Property, QPointF, Qt, QObject, Slot, QRectF\nfrom PySide6.QtGui import QPainterPath, "
  },
  {
    "path": "meshroom/ui/components/filepath.py",
    "chars": 5683,
    "preview": "#!/usr/bin/env python\n# coding:utf-8\nfrom PySide6.QtCore import QUrl, QFileInfo\nfrom PySide6.QtCore import QObject, Slot"
  },
  {
    "path": "meshroom/ui/components/geom2D.py",
    "chars": 791,
    "preview": "from PySide6.QtCore import QObject, Slot, QRectF\n\n\nclass Geom2D(QObject):\n    @Slot(QRectF, QRectF, result=bool)\n    def"
  },
  {
    "path": "meshroom/ui/components/logLinesModel.py",
    "chars": 9998,
    "preview": "from PySide6.QtCore import QAbstractListModel, Qt, QModelIndex, Slot, QObject, Property\n\nimport re\nfrom enum import IntE"
  },
  {
    "path": "meshroom/ui/components/messaging.py",
    "chars": 2483,
    "preview": "import json\nfrom PySide6.QtCore import QObject\nfrom datetime import datetime\nfrom meshroom.common import Signal, Slot, P"
  },
  {
    "path": "meshroom/ui/components/scene3D.py",
    "chars": 19155,
    "preview": "from math import acos, pi, sqrt, atan2, cos, sin, asin\n\nfrom PySide6.QtCore import QObject, Slot, QSize, Signal, QPointF"
  },
  {
    "path": "meshroom/ui/components/scriptEditor.py",
    "chars": 10941,
    "preview": "\"\"\" Script Editor for Meshroom.\n\"\"\"\n# STD\nfrom io import StringIO\nfrom contextlib import redirect_stdout\nimport tracebac"
  },
  {
    "path": "meshroom/ui/components/shapes/__init__.py",
    "chars": 111,
    "preview": "from .shapeFilesHelper import (\n    ShapeFilesHelper\n)\nfrom .shapeViewerHelper import (\n    ShapeViewerHelper\n)"
  },
  {
    "path": "meshroom/ui/components/shapes/shapeFile.py",
    "chars": 8207,
    "preview": "from meshroom.common import BaseObject, Property, Variant, Signal, ListModel, Slot\nfrom meshroom.core.attribute import A"
  },
  {
    "path": "meshroom/ui/components/shapes/shapeFilesHelper.py",
    "chars": 3715,
    "preview": "from meshroom.ui.scene import Scene\nfrom meshroom.common import BaseObject, Property, Variant, Signal, ListModel, Slot\nf"
  },
  {
    "path": "meshroom/ui/components/shapes/shapeViewerHelper.py",
    "chars": 2979,
    "preview": "from meshroom.common import BaseObject, Property, Variant, Signal, Slot\n\nclass ShapeViewerHelper(BaseObject):\n    \"\"\"\n  "
  },
  {
    "path": "meshroom/ui/components/thumbnail.py",
    "chars": 12688,
    "preview": "from meshroom.common import Signal\n\nfrom PySide6.QtCore import QObject, Slot, QSize, QUrl, Qt, QStandardPaths\nfrom PySid"
  },
  {
    "path": "meshroom/ui/graph.py",
    "chars": 67645,
    "preview": "#!/usr/bin/env python\nfrom collections.abc import Iterable\nimport logging\nimport os\nimport re\nimport json\nfrom enum impo"
  },
  {
    "path": "meshroom/ui/palette.py",
    "chars": 4889,
    "preview": "from PySide6.QtCore import QObject, Qt, Slot, Property, Signal\nfrom PySide6.QtGui import QPalette, QColor\nfrom PySide6.Q"
  },
  {
    "path": "meshroom/ui/qml/AboutDialog.qml",
    "chars": 7417,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport Utils 1.0\nimport MaterialIcons 2.2\n\n\n/**\n * Meshroo"
  },
  {
    "path": "meshroom/ui/qml/Application.qml",
    "chars": 60953,
    "preview": "import QtCore\n\nimport QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQml.Models\n\nimport Qt.labs.platfor"
  },
  {
    "path": "meshroom/ui/qml/Charts/ChartViewCheckBox.qml",
    "chars": 816,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\n/**\n * A custom CheckBox designed to be used in ChartView's legend.\n */\n\nCheckBo"
  },
  {
    "path": "meshroom/ui/qml/Charts/ChartViewLegend.qml",
    "chars": 2932,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtCharts\n\n/**\n * ChartViewLegend is an interactive legend component for Ch"
  },
  {
    "path": "meshroom/ui/qml/Charts/InteractiveChartView.qml",
    "chars": 611,
    "preview": "import QtQuick\nimport QtQuick.Layouts\nimport QtCharts\n\nChartView {\n    id: root\n    antialiasing: true\n\n    Rectangle {\n"
  },
  {
    "path": "meshroom/ui/qml/Charts/qmldir",
    "chars": 149,
    "preview": "module Charts\n\nChartViewLegend 1.0 ChartViewLegend.qml\nChartViewCheckBox 1.0 ChartViewCheckBox.qml\nInteractiveChartView "
  },
  {
    "path": "meshroom/ui/qml/Controls/ColorChart.qml",
    "chars": 1911,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport Utils 1.0\n\n/**\n * ColorChart is a color picker based on a set of predefin"
  },
  {
    "path": "meshroom/ui/qml/Controls/ColorSelector.qml",
    "chars": 4001,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport Utils 1.0\nimport MaterialIcons 2.2\n\n/**\n * ColorSelector is a color picke"
  },
  {
    "path": "meshroom/ui/qml/Controls/DelegateSelectionBox.qml",
    "chars": 1889,
    "preview": "import QtQuick\nimport Meshroom.Helpers\n\n/*\nA SelectionBox that can be used to select delegates in a model instantiator ("
  },
  {
    "path": "meshroom/ui/qml/Controls/DelegateSelectionLine.qml",
    "chars": 1237,
    "preview": "import QtQuick\nimport Meshroom.Helpers\n\n/*\nA SelectionLine that can be used to select delegates in a model instantiator "
  },
  {
    "path": "meshroom/ui/qml/Controls/DirectionalLightPane.qml",
    "chars": 9615,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQuick.Shapes\nimport MaterialIcons 2.2\nimport Util"
  },
  {
    "path": "meshroom/ui/qml/Controls/ExifOrientedViewer.qml",
    "chars": 802,
    "preview": "import QtQuick\n\nimport Utils 1.0\n\n/**\n * Loader with a predefined transform to orient its content according to the provi"
  },
  {
    "path": "meshroom/ui/qml/Controls/ExpandableGroup.qml",
    "chars": 2079,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\n\n/**\n * A custom GroupBox with p"
  },
  {
    "path": "meshroom/ui/qml/Controls/FilterComboBox.qml",
    "chars": 4465,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport Utils 1.0\n\nimport MaterialIcons\n\n/**\n* ComboBox wit"
  },
  {
    "path": "meshroom/ui/qml/Controls/FloatingPane.qml",
    "chars": 479,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * FloatingPane provides a Pane with a slightly trans"
  },
  {
    "path": "meshroom/ui/qml/Controls/Group.qml",
    "chars": 1018,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * A custom GroupBox with predefined header.\n */\n\nGro"
  },
  {
    "path": "meshroom/ui/qml/Controls/IntSelector.qml",
    "chars": 2284,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\n\n/*\n* IntSelector with arrows an"
  },
  {
    "path": "meshroom/ui/qml/Controls/KeyValue.qml",
    "chars": 1471,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * KeyValue allows to create a list of key/value, lik"
  },
  {
    "path": "meshroom/ui/qml/Controls/MScrollBar.qml",
    "chars": 762,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\n/**\n * MScrollBar is a custom scrollbar implementation.\n * It is a vertical scro"
  },
  {
    "path": "meshroom/ui/qml/Controls/MSplitView.qml",
    "chars": 745,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nSplitView {\n    id: splitView\n\n    handle: Rectangle {\n        id: handleDelegat"
  },
  {
    "path": "meshroom/ui/qml/Controls/MessageDialog.qml",
    "chars": 4223,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\n\nDialog {\n    id: root\n\n    prop"
  },
  {
    "path": "meshroom/ui/qml/Controls/NodeActions.qml",
    "chars": 16240,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Utils 1.0\n\nItem {\n    id:"
  },
  {
    "path": "meshroom/ui/qml/Controls/Panel.qml",
    "chars": 3662,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * Panel is a container control with preconfigured he"
  },
  {
    "path": "meshroom/ui/qml/Controls/SearchBar.qml",
    "chars": 2931,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\n\n/**\n * Basic SearchBar componen"
  },
  {
    "path": "meshroom/ui/qml/Controls/SelectionBox.qml",
    "chars": 1702,
    "preview": "import QtQuick\n\n/*\nSimple selection box that can be used by a MouseArea.\n\nUsage:\n1. Create a MouseArea and a SelectionBo"
  },
  {
    "path": "meshroom/ui/qml/Controls/SelectionLine.qml",
    "chars": 2150,
    "preview": "import QtQuick\nimport QtQuick.Shapes\n\n/*\nSimple selection line that can be used by a MouseArea.\n\nUsage:\n1. Create a Mous"
  },
  {
    "path": "meshroom/ui/qml/Controls/StatusBar.qml",
    "chars": 3420,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport MaterialIcons 2.2\n\nimport Utils 1.0\n\nRowLayout {\n  "
  },
  {
    "path": "meshroom/ui/qml/Controls/StatusMessages.qml",
    "chars": 5388,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Utils 1.0\n\nApplicationWin"
  },
  {
    "path": "meshroom/ui/qml/Controls/TabPanel.qml",
    "chars": 3039,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nPage {\n    id: root\n\n    property alias headerBar: header"
  },
  {
    "path": "meshroom/ui/qml/Controls/TextFileViewer.qml",
    "chars": 17395,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Utils 1.0\nimport DataObje"
  },
  {
    "path": "meshroom/ui/qml/Controls/qmldir",
    "chars": 809,
    "preview": "module Controls\n\nColorChart 1.0 ColorChart.qml\nColorSelector 1.0 ColorSelector.qml\nExpandableGroup 1.0 ExpandableGroup.q"
  },
  {
    "path": "meshroom/ui/qml/DialogsFactory.qml",
    "chars": 1041,
    "preview": "import QtQuick\nimport Controls 1.0\n\n/**\n * DialogsFactory is utility object to instantiate generic purpose Dialogs.\n */\n"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/AttributeControls/Choice.qml",
    "chars": 784,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons\nimport Controls\n\n/**\n * A combobox-t"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/AttributeControls/ChoiceMulti.qml",
    "chars": 1138,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport Controls\n\n/**\n * A multi-checkboxes control with a current `value` (list o"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/AttributeEditor.qml",
    "chars": 2824,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport Controls 1.0\n\n/**\n * A component to display and edit the attributes of a "
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml",
    "chars": 39224,
    "preview": "import QtQuick\nimport QtQuick.Layouts\nimport QtQuick.Controls\nimport QtQuick.Dialogs\n\nimport MaterialIcons 2.2\nimport Ut"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/AttributePin.qml",
    "chars": 22507,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Utils 1.0\nimport MaterialIcons 2.2\n\n/**\n * The rep"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/Backdrop.qml",
    "chars": 15580,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport Qt5Compat.GraphicalEffects\n\nimport Utils 1.0\n\nimpor"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/ChunksListView.qml",
    "chars": 3136,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Utils 1.0\n\n/**\n * ChunksListView\n */\n\nColumnLayout"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/CompatibilityBadge.qml",
    "chars": 2284,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\n\n/**\n * Node Badge to inform abo"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/CompatibilityManager.qml",
    "chars": 5382,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Controls 1.0\nimport Utils"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/Edge.qml",
    "chars": 5327,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Shapes 1.6\n\nimport GraphEditor 1.0\nimport MaterialIcons 2.2\n\n/**\n "
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/GraphEditor.qml",
    "chars": 68970,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Controls 1.0\nimport MaterialIcons 2.2\nimport Utils"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/GraphEditorSettings.qml",
    "chars": 497,
    "preview": "pragma Singleton\nimport QtCore\n\n/**\n * Persistent Settings related to the GraphEditor module.\n */\n\nSettings {\n    catego"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/Node.qml",
    "chars": 39740,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQuick.Effects\n\nimport MaterialIcons 2.2\nimport Ut"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeChunks.qml",
    "chars": 1152,
    "preview": "import QtQuick\n\nimport Utils 1.0\n\nListView {\n    id: root\n    interactive: false\n    property bool highlightChunks: true"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeDocumentation.qml",
    "chars": 4621,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Controls 1.0\n\n/**\n * Displays Node documentation\n "
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeEditor.qml",
    "chars": 26763,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Controls 1.0\nimport MaterialIcons 2.2\nimport Utils"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeFileBrowser.qml",
    "chars": 7345,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport Qt.labs.folderlistmodel\n\nimport Controls 1.0\nimport"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeLog.qml",
    "chars": 1148,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Controls 1.0\n\n/**\n * NodeLog displays the log file"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeStatistics.qml",
    "chars": 1522,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Controls 1.0\nimport Utils 1.0\n\n/**\n * NodeStatisti"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/NodeStatus.qml",
    "chars": 6189,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * NodeStatus displays the status-related information"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/ScriptEditor.qml",
    "chars": 11509,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Dialogs\nimport QtQuick.Layouts\n\nimport Controls 1.0\nimport Materia"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/StatViewer.qml",
    "chars": 17446,
    "preview": "import QtCharts\nimport QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Charts 1.0\nimport MaterialIcons 2."
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/TaskManager.qml",
    "chars": 18860,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Controls 1.0\nimport Utils"
  },
  {
    "path": "meshroom/ui/qml/GraphEditor/qmldir",
    "chars": 559,
    "preview": "module GraphEditor\n\nGraphEditor 1.0 GraphEditor.qml\nNodeEditor 1.0 NodeEditor.qml\nNode 1.0 Node.qml\nNodeChunks 1.0 NodeC"
  },
  {
    "path": "meshroom/ui/qml/Homepage.qml",
    "chars": 17896,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport Utils 1.0\nimport MaterialIcons 2.2\nimport Controls"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/ImageBadge.qml",
    "chars": 312,
    "preview": "import QtQuick\n\nimport MaterialIcons 2.2\nimport Utils 1.0\n\n/**\n * ImageBadge is a preset MaterialLabel to display an ico"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/ImageDelegate.qml",
    "chars": 11548,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Utils 1.0\n\n/**\n * ImageDe"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/ImageGallery.qml",
    "chars": 32036,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQml.Models\nimport Qt.labs.qmlmodels\n\nimport Contr"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/ImageGridView.qml",
    "chars": 7534,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQml.Models\nimport Qt.labs.qmlmodels\n\nimport Contr"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/ImageListView.qml",
    "chars": 7270,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQml.Models\nimport Qt.labs.qmlmodels\n\nimport Contr"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/IntrinsicDisplayDelegate.qml",
    "chars": 6250,
    "preview": "import QtQuick\nimport QtQuick.Layouts\nimport QtQuick.Controls\n\nRowLayout {\n    id: root\n\n    Layout.fillWidth: true\n\n   "
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/IntrinsicsIndicator.qml",
    "chars": 4782,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport MaterialIcons 2.2\nimport Utils 1.0\n\n/**\n * Display camera initialization "
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/SensorDBDialog.qml",
    "chars": 2600,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\nimport MaterialIcons 2.2\nimport Controls 1.0\n\nMessageDial"
  },
  {
    "path": "meshroom/ui/qml/ImageGallery/qmldir",
    "chars": 326,
    "preview": "module ImageGallery\n\nImageGallery 1.0 ImageGallery.qml\nImageDelegate 1.0 ImageDelegate.qml\nImageGridView 1.0 ImageGridVi"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MLabel.qml",
    "chars": 529,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\n/**\n * MLabel is a standard Label.\n * If ToolTip.text is set, it shows up a tool"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MaterialIcons.qml",
    "chars": 115756,
    "preview": "pragma Singleton\nimport QtQuick\n\nQtObject {\n    property FontLoader fl: FontLoader {\n        source: \"./MaterialIcons-Re"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MaterialLabel.qml",
    "chars": 587,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\n/**\n * MaterialLabel is a standard Label using MaterialIcons font.\n * If ToolTip"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MaterialToolButton.qml",
    "chars": 1016,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * MaterialToolButton is a standard ToolButton using "
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MaterialToolLabel.qml",
    "chars": 1559,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * MaterialToolLabel is a Label with an icon (using M"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/MaterialToolLabelButton.qml",
    "chars": 1523,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\n\n/**\n * MaterialToolButton is a standard ToolButton using "
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/generate_material_icons.py",
    "chars": 2180,
    "preview": "import argparse\nimport os\n\nparser = argparse.ArgumentParser(description='Generate a MaterialIcons.qml singleton from cod"
  },
  {
    "path": "meshroom/ui/qml/MaterialIcons/qmldir",
    "chars": 271,
    "preview": "module MaterialIcons\nsingleton MaterialIcons 2.2 MaterialIcons.qml\nMaterialToolButton 2.2 MaterialToolButton.qml\nMateria"
  },
  {
    "path": "meshroom/ui/qml/Shapes/Editor/Items/ShapeAttributeItem.qml",
    "chars": 722,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport \"Utils\" as ItemUtils\n\n/**\n* ShapeAttributeItem\n*\n* @biref ShapeAttribute "
  },
  {
    "path": "meshroom/ui/qml/Shapes/Editor/Items/ShapeDataItem.qml",
    "chars": 629,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport \"Utils\" as ItemUtils\n\n/**\n* ShapeDataItem\n*\n* @biref ShapeData component "
  },
  {
    "path": "meshroom/ui/qml/Shapes/Editor/Items/ShapeFileItem.qml",
    "chars": 1289,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport \"Utils\" as ItemUtils\n\n/**\n* ShapeFileItem\n*\n* @biref ShapeFile component "
  },
  {
    "path": "meshroom/ui/qml/Shapes/Editor/Items/ShapeListAttributeItem.qml",
    "chars": 1428,
    "preview": "import QtQuick\nimport QtQuick.Controls\n\nimport \"Utils\" as ItemUtils\n\n/**\n* ShapeListAttributeItem\n*\n* @biref ShapeListAt"
  },
  {
    "path": "meshroom/ui/qml/Shapes/Editor/Items/Utils/ItemHeader.qml",
    "chars": 17730,
    "preview": "import QtQuick\nimport QtQuick.Controls\nimport QtQuick.Layouts\nimport QtQuick.Dialogs\nimport MaterialIcons 2.2\nimport Con"
  }
]

// ... and 143 more files (download for full content)

About this extraction

This page contains the full source code of the alicevision/Meshroom GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 343 files (2.4 MB), approximately 637.2k tokens, and a symbol index with 2151 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!