{"owner":"alicevision","repo":"Meshroom","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Meshroom Agent Guide\n\nYou are assisting on **Meshroom**, a node-based visual programming framework. Use the relative links and directory structure below to orient yourself in the codebase.\n\nMeshroom is a general-purpose Python/QML engine for building, editing, and executing node graphs — it provides a graph editor UI, a node execution engine, and CLI tools, but is domain-agnostic on its own. Concrete functionality is delivered through **plugins** that contribute node types and pipeline templates. Its flagship plugin is **AliceVision**, whose nodes wrap the AliceVision photogrammetry binaries; those C++ computer-vision algorithms live in the separate AliceVision repository, not here.\n\n## Documentation Index\n\nRead the relevant source-of-truth file before working in the area it covers:\n* **Project, Concepts & Vocabulary:** [README.md](README.md)\n* **Installation & System Setup:** [INSTALL.md](INSTALL.md) — read before touching build, dependency, or environment setup.\n* **Plugin Architecture:** [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md) — read before working on plugin loading/packaging.\n* **Node Development:** [NODE_DEVELOPMENT.md](NODE_DEVELOPMENT.md) — read before working on node types or their descriptors (`meshroom/nodes/`, `meshroom/core/desc/`).\n\n## Codebase Directory Map\n\nWhere this map and the actual tree diverge, trust the tree — then update the map to match (see [Workflow & Delivery](#workflow--delivery)).\n\n```\n.\n├── .github/                    # CI/CD workflows, issue templates, and automated testing setups\n├── .vscode/                    # Shared VS Code debugging and workspace configurations\n├── bin/                        # CLI entry points, packaged as executables in setup.py (meshroom_batch,\n│                               # meshroom_compute, meshroom_createChunks, meshroom_info, meshroom_newNodeType,\n│                               # meshroom_statistics, meshroom_status, meshroom_submit).\n│                               # The GUI has NO bin/ script — launch it with ./start.sh (see \"Run the app\").\n├── docker/                     # Dockerfiles for containerized environments (Rocky Linux, Ubuntu, etc.)\n├── docs/                       # Documentation resources, developer guides, and illustrations\n├── localfarm/                  # Standalone local render-farm daemon (backend/client/launcher); the matching\n│                               # submitter lives in meshroom/submitters/localFarm/ (Unix-only, uses fork)\n├── meshroom/                   # MAIN SOURCE CODE DIRECTORY\n│   ├── common/                 # Qt/headless backend abstraction (BaseObject, models) used across the engine\n│   ├── core/                   # Engine logic (Graph, Node, Attribute, execution, (de)serialization)\n│   │   └── desc/               # Node/attribute DESCRIPTORS: desc.Node, desc.CommandLineNode, desc.*Param\n│   │                           #   (imported as `from meshroom.core import desc`)\n│   ├── nodes/                  # Concrete node types, grouped by category (e.g. general/)\n│   ├── submitters/             # Built-in render-farm submitters (drive meshroom_submit; e.g. localFarm)\n│   ├── ui/                     # User Interface layer (PySide6 / QML-based components)\n│   │   ├── qml/                # QML design layouts (GraphEditor, NodeEditor, 3D/2D Viewers, RTI Viewer)\n│   │   ├── components/         # Qt helper components exposed to QML (scene3D, scriptEditor, clipboard, ...)\n│   │   └── ...                 # Python backends (app.py, graph.py, commands.py, scene.py) binding core to Qt\n│   ├── env.py                  # EnvVar registry: MESHROOM_PLUGINS_PATH / NODES_PATH / PIPELINE_TEMPLATES_PATH, etc.\n│   └── multiview.py            # Image-extension lists & helpers for building multiview/photogrammetry pipelines\n├── tests/                      # Comprehensive suite of unit tests and pipeline validation tests\n├── CHANGES.md                  # Changelog tracking features, optimizations, and API breaks\n├── CMakeLists.txt              # Build system file for compiling external modules/packaging\n├── CONTRIBUTING.md             # Guidelines for developer onboarding and codebase contributions\n├── INSTALL.md                  # Detailed steps for building from source and configuring dependencies\n└── INSTALL_PLUGINS.md          # Framework documentation explaining how to load custom Python plugins\n```\n\n## How It Fits Together (Mental Model)\n\nA few distinctions are easy to confuse. Keep them straight before changing engine code:\n\n* **Descriptor vs. instance.** A *node type* is a **descriptor** class in `meshroom/nodes/<Category>/<Name>.py` that subclasses `desc.Node` (Python-scripted) or `desc.CommandLineNode` (wraps an external command-line program, e.g. an AliceVision tool). It can additionally mix in `desc.InputNode` for batch/drag-and-drop initialization or `desc.OutputNode` for pipeline exports. The descriptor declares static schema only: `inputs`/`outputs` (lists of `desc.*` attributes such as `desc.File`, `desc.IntParam`, `desc.ChoiceParam`), plus `category`, `documentation`, `size`, and optional `parallelization`. `OutputNode` declares the inputs that can be configured as export settings with `outputAttributes`; its exposed `File` attributes are output folders. At runtime the engine instantiates it into a live **`Node`** (`meshroom/core/node.py`) whose **`Attribute`** objects (`meshroom/core/attribute.py`) hold the actual values. Rule of thumb: `core/desc/` = schema/definition; `core/node.py` + `core/attribute.py` = live, valued objects.\n* **Graph = DAG of attributes.** A **`Graph`** (`meshroom/core/graph.py`) holds nodes connected by **`Edge`**s that link one node's *output* attribute to another node's *input* attribute. A connected input reads its value from upstream; the graph is a DAG and defines evaluation order. Each node computes a content-based **UID** (hash of its inputs) so unchanged nodes can be cached and skipped on recompute.\n* **Execution = chunks.** Work is split into **`NodeChunk`**s for parallelism (driven by the descriptor's `size`/`parallelization`). `desc.Node` subclasses implement **`processChunk(chunk)`** in Python; `desc.CommandLineNode` builds a command line from its `commandLine` template plus the chunk's range and runs the external binary. **`TaskManager`** (`meshroom/core/taskManager.py`) orchestrates execution — either **locally** (`compute`) or by **submitting** to a render farm (`submit`) via `meshroom/submitters/`.\n* **Persistence.** Graphs are saved as **`.mg`** JSON files (`meshroom/core/graphIO.py`): a versioned `header` plus a `graph` payload. On load, `nodeFactory` reconciles descriptor changes so old projects still open — a node that no longer matches its current descriptor becomes a **`CompatibilityNode`** instead of failing. Pipeline **templates** are just `.mg` files registered at startup. Output nodes are excluded from a template by default and retained only when explicitly requested, allowing `meshroom_batch -o/--output` and the UI startup `-o/--output` to configure export destinations.\n* **Discovery.** Node types and pipeline templates are loaded at import time (`meshroom/core/__init__.py`, `meshroom/core/plugins.py`) from the built-in `meshroom/nodes/` plus any plugin/template paths (see [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md)).\n* **UI bridge.** The engine is Qt-agnostic: `meshroom/common/` selects either a Qt or a headless backend for `BaseObject`, so the core runs without a UI. The `meshroom/ui/*.py` layer wraps it for Qt — `app.py` (application/entry), `graph.py` (a `UIGraph` exposing the core `Graph` as Qt models + async compute), `commands.py` (undo/redo command stack), `scene.py`. QML in `meshroom/ui/qml/` binds to these.\n\n## Development & Verification\n\n* **Supported Python versions:** Target 3.9–3.11. The full test suite runs on **3.11** (Linux + Windows) in CI; `meshroom_compute` (`bin/meshroom_compute`) additionally gets a `-h` smoke test on **3.9**, the minimum supported version. Avoid syntax/features newer than 3.9 in any code reachable from it (`meshroom/core/`, CLI entry points).\n* **Lint:** Run `flake8 . --max-line-length=127` locally. CI ([.github/workflows/run-tests.yml](.github/workflows/run-tests.yml)) runs two passes: a **hard-failing** one for real errors (`--select=E9,F63,F7,F82` — syntax/undefined names) and a **non-blocking** style pass (`--exit-zero --max-complexity=10 --max-line-length=127`). Keep both clean; the [Code Style](#code-style) section lists the specific style warnings to avoid.\n* **Tests:** `pytest tests/` from the repo root. Add/run targeted tests with `pytest tests/path/to/test_file.py::test_name`.\n* **Run the app:** There is no `bin/` script for the GUI. Launch it with `./start.sh` (or `start.bat` on Windows) (sets `MESHROOM_ROOT`/`PYTHONPATH`, then runs `python3 meshroom/ui`), or run `python3 meshroom/ui` directly. For headless pipeline runs use `bin/meshroom_batch`. Manually verify UI/pipeline changes this way before reporting them done.\n\n## Code Style\n\n### Python (`meshroom/core/`, `meshroom/core/desc/`, `meshroom/nodes/`, `meshroom/ui/*.py`, `bin/`)\n\n1. **Style Uniformity (Highest Priority):** If an existing file does not perfectly follow PEP 8 or the rules below, **always prefer code uniformity** with the surrounding codebase over strict rule enforcement.\n\n2. **Naming Conventions:** Use **camelCase** for variable names and function/method names (e.g., `myFunction`, `nodeVariable`). Match existing repository naming patterns rather than default PEP 8 snake_case.\n\n3. **Quality Standards (Modified PEP 8):**\n   * **Line Length:** Do not apply the PEP 8 79/100 characters-per-line limit. Long lines are acceptable.\n   * **Linter Compliance:** Avoid causing these specific issues: `E128` (visual indent), `E222`/`E225` (operator spacing), `E251` (spaces around parameter `=`), `E261` (2 spaces before inline comments), `E275` (space after keyword), `E301`/`E302`/`E303`/`E306` (blank line constraints), `W291`/`W292`/`W293`/`W391` (whitespaces/newlines), `E711`/`E712` (`is None`/`is True`), `F401` (unused imports), `F841` (unused variables), and `F541` (empty f-strings).\n\n4. **Documentation & Comments:**\n   * **Functions & Methods:** Every function or method whose purpose is not self-explanatory from its name and signature must include a clear, concise docstring covering its purpose, parameters, and return value. Trivial one-liners and obvious getters/setters may be left undocumented, matching the surrounding file.\n   * **Complex Logic:** Add inline comments to explain non-explicit or intricate blocks of code.\n   * **Keep it Concise:** Do not over-explain or add redundant descriptions in comments.\n\n5. **Testing:** For changes made to **Core code** (`meshroom/core/`), you must add corresponding unit tests for any new features.\n\n### QML / UI (`meshroom/ui/qml/`)\n\n1. **Style Uniformity:** Match the patterns, indentation, and structure already used in the surrounding `.qml` file.\n\n2. **Naming Conventions:** Use **camelCase** for properties, signals, and functions, consistent with standard QML/JS convention and the existing codebase.\n\n3. **Documentation & Comments:** Same principle as Python — add comments for non-obvious or intricate logic, keep them concise, skip them where the code is self-explanatory.\n\n4. **Testing:** Changes purely to the UI/QML layer do not require unit tests.\n\n5. **Structure:** Split overly complex components into dedicated `.qml` files. For data models, avoid complex JavaScript implementations; instead, construct models on the Python UI side and utilize them via context properties.\n\n## Workflow & Delivery\n\n* Provide only targeted code patches instead of full files.\n* Propose changes structured to perform **atomic commits** (one distinct, self-contained change per commit), one feature per PR where possible, per [CONTRIBUTING.md](CONTRIBUTING.md).\n* Link the relevant GitHub issue in the PR description, and open it as a draft PR while work is in progress, matching the existing contributor workflow.\n* **Keep this file accurate:** whenever a change makes any statement in `AGENTS.md` incorrect or incomplete — a moved/renamed path in the Directory Map, a changed command or CI setting, a shift in the architecture described by the Mental Model — update `AGENTS.md` in the same change so it never drifts from the codebase.\n"},"files":{"AGENTS.md":"# Meshroom Agent Guide\n\nYou are assisting on **Meshroom**, a node-based visual programming framework. Use the relative links and directory structure below to orient yourself in the codebase.\n\nMeshroom is a general-purpose Python/QML engine for building, editing, and executing node graphs — it provides a graph editor UI, a node execution engine, and CLI tools, but is domain-agnostic on its own. Concrete functionality is delivered through **plugins** that contribute node types and pipeline templates. Its flagship plugin is **AliceVision**, whose nodes wrap the AliceVision photogrammetry binaries; those C++ computer-vision algorithms live in the separate AliceVision repository, not here.\n\n## Documentation Index\n\nRead the relevant source-of-truth file before working in the area it covers:\n* **Project, Concepts & Vocabulary:** [README.md](README.md)\n* **Installation & System Setup:** [INSTALL.md](INSTALL.md) — read before touching build, dependency, or environment setup.\n* **Plugin Architecture:** [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md) — read before working on plugin loading/packaging.\n* **Node Development:** [NODE_DEVELOPMENT.md](NODE_DEVELOPMENT.md) — read before working on node types or their descriptors (`meshroom/nodes/`, `meshroom/core/desc/`).\n\n## Codebase Directory Map\n\nWhere this map and the actual tree diverge, trust the tree — then update the map to match (see [Workflow & Delivery](#workflow--delivery)).\n\n```\n.\n├── .github/                    # CI/CD workflows, issue templates, and automated testing setups\n├── .vscode/                    # Shared VS Code debugging and workspace configurations\n├── bin/                        # CLI entry points, packaged as executables in setup.py (meshroom_batch,\n│                               # meshroom_compute, meshroom_createChunks, meshroom_info, meshroom_newNodeType,\n│                               # meshroom_statistics, meshroom_status, meshroom_submit).\n│                               # The GUI has NO bin/ script — launch it with ./start.sh (see \"Run the app\").\n├── docker/                     # Dockerfiles for containerized environments (Rocky Linux, Ubuntu, etc.)\n├── docs/                       # Documentation resources, developer guides, and illustrations\n├── localfarm/                  # Standalone local render-farm daemon (backend/client/launcher); the matching\n│                               # submitter lives in meshroom/submitters/localFarm/ (Unix-only, uses fork)\n├── meshroom/                   # MAIN SOURCE CODE DIRECTORY\n│   ├── common/                 # Qt/headless backend abstraction (BaseObject, models) used across the engine\n│   ├── core/                   # Engine logic (Graph, Node, Attribute, execution, (de)serialization)\n│   │   └── desc/               # Node/attribute DESCRIPTORS: desc.Node, desc.CommandLineNode, desc.*Param\n│   │                           #   (imported as `from meshroom.core import desc`)\n│   ├── nodes/                  # Concrete node types, grouped by category (e.g. general/)\n│   ├── submitters/             # Built-in render-farm submitters (drive meshroom_submit; e.g. localFarm)\n│   ├── ui/                     # User Interface layer (PySide6 / QML-based components)\n│   │   ├── qml/                # QML design layouts (GraphEditor, NodeEditor, 3D/2D Viewers, RTI Viewer)\n│   │   ├── components/         # Qt helper components exposed to QML (scene3D, scriptEditor, clipboard, ...)\n│   │   └── ...                 # Python backends (app.py, graph.py, commands.py, scene.py) binding core to Qt\n│   ├── env.py                  # EnvVar registry: MESHROOM_PLUGINS_PATH / NODES_PATH / PIPELINE_TEMPLATES_PATH, etc.\n│   └── multiview.py            # Image-extension lists & helpers for building multiview/photogrammetry pipelines\n├── tests/                      # Comprehensive suite of unit tests and pipeline validation tests\n├── CHANGES.md                  # Changelog tracking features, optimizations, and API breaks\n├── CMakeLists.txt              # Build system file for compiling external modules/packaging\n├── CONTRIBUTING.md             # Guidelines for developer onboarding and codebase contributions\n├── INSTALL.md                  # Detailed steps for building from source and configuring dependencies\n└── INSTALL_PLUGINS.md          # Framework documentation explaining how to load custom Python plugins\n```\n\n## How It Fits Together (Mental Model)\n\nA few distinctions are easy to confuse. Keep them straight before changing engine code:\n\n* **Descriptor vs. instance.** A *node type* is a **descriptor** class in `meshroom/nodes/<Category>/<Name>.py` that subclasses `desc.Node` (Python-scripted) or `desc.CommandLineNode` (wraps an external command-line program, e.g. an AliceVision tool). It can additionally mix in `desc.InputNode` for batch/drag-and-drop initialization or `desc.OutputNode` for pipeline exports. The descriptor declares static schema only: `inputs`/`outputs` (lists of `desc.*` attributes such as `desc.File`, `desc.IntParam`, `desc.ChoiceParam`), plus `category`, `documentation`, `size`, and optional `parallelization`. `OutputNode` declares the inputs that can be configured as export settings with `outputAttributes`; its exposed `File` attributes are output folders. At runtime the engine instantiates it into a live **`Node`** (`meshroom/core/node.py`) whose **`Attribute`** objects (`meshroom/core/attribute.py`) hold the actual values. Rule of thumb: `core/desc/` = schema/definition; `core/node.py` + `core/attribute.py` = live, valued objects.\n* **Graph = DAG of attributes.** A **`Graph`** (`meshroom/core/graph.py`) holds nodes connected by **`Edge`**s that link one node's *output* attribute to another node's *input* attribute. A connected input reads its value from upstream; the graph is a DAG and defines evaluation order. Each node computes a content-based **UID** (hash of its inputs) so unchanged nodes can be cached and skipped on recompute.\n* **Execution = chunks.** Work is split into **`NodeChunk`**s for parallelism (driven by the descriptor's `size`/`parallelization`). `desc.Node` subclasses implement **`processChunk(chunk)`** in Python; `desc.CommandLineNode` builds a command line from its `commandLine` template plus the chunk's range and runs the external binary. **`TaskManager`** (`meshroom/core/taskManager.py`) orchestrates execution — either **locally** (`compute`) or by **submitting** to a render farm (`submit`) via `meshroom/submitters/`.\n* **Persistence.** Graphs are saved as **`.mg`** JSON files (`meshroom/core/graphIO.py`): a versioned `header` plus a `graph` payload. On load, `nodeFactory` reconciles descriptor changes so old projects still open — a node that no longer matches its current descriptor becomes a **`CompatibilityNode`** instead of failing. Pipeline **templates** are just `.mg` files registered at startup. Output nodes are excluded from a template by default and retained only when explicitly requested, allowing `meshroom_batch -o/--output` and the UI startup `-o/--output` to configure export destinations.\n* **Discovery.** Node types and pipeline templates are loaded at import time (`meshroom/core/__init__.py`, `meshroom/core/plugins.py`) from the built-in `meshroom/nodes/` plus any plugin/template paths (see [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md)).\n* **UI bridge.** The engine is Qt-agnostic: `meshroom/common/` selects either a Qt or a headless backend for `BaseObject`, so the core runs without a UI. The `meshroom/ui/*.py` layer wraps it for Qt — `app.py` (application/entry), `graph.py` (a `UIGraph` exposing the core `Graph` as Qt models + async compute), `commands.py` (undo/redo command stack), `scene.py`. QML in `meshroom/ui/qml/` binds to these.\n\n## Development & Verification\n\n* **Supported Python versions:** Target 3.9–3.11. The full test suite runs on **3.11** (Linux + Windows) in CI; `meshroom_compute` (`bin/meshroom_compute`) additionally gets a `-h` smoke test on **3.9**, the minimum supported version. Avoid syntax/features newer than 3.9 in any code reachable from it (`meshroom/core/`, CLI entry points).\n* **Lint:** Run `flake8 . --max-line-length=127` locally. CI ([.github/workflows/run-tests.yml](.github/workflows/run-tests.yml)) runs two passes: a **hard-failing** one for real errors (`--select=E9,F63,F7,F82` — syntax/undefined names) and a **non-blocking** style pass (`--exit-zero --max-complexity=10 --max-line-length=127`). Keep both clean; the [Code Style](#code-style) section lists the specific style warnings to avoid.\n* **Tests:** `pytest tests/` from the repo root. Add/run targeted tests with `pytest tests/path/to/test_file.py::test_name`.\n* **Run the app:** There is no `bin/` script for the GUI. Launch it with `./start.sh` (or `start.bat` on Windows) (sets `MESHROOM_ROOT`/`PYTHONPATH`, then runs `python3 meshroom/ui`), or run `python3 meshroom/ui` directly. For headless pipeline runs use `bin/meshroom_batch`. Manually verify UI/pipeline changes this way before reporting them done.\n\n## Code Style\n\n### Python (`meshroom/core/`, `meshroom/core/desc/`, `meshroom/nodes/`, `meshroom/ui/*.py`, `bin/`)\n\n1. **Style Uniformity (Highest Priority):** If an existing file does not perfectly follow PEP 8 or the rules below, **always prefer code uniformity** with the surrounding codebase over strict rule enforcement.\n\n2. **Naming Conventions:** Use **camelCase** for variable names and function/method names (e.g., `myFunction`, `nodeVariable`). Match existing repository naming patterns rather than default PEP 8 snake_case.\n\n3. **Quality Standards (Modified PEP 8):**\n   * **Line Length:** Do not apply the PEP 8 79/100 characters-per-line limit. Long lines are acceptable.\n   * **Linter Compliance:** Avoid causing these specific issues: `E128` (visual indent), `E222`/`E225` (operator spacing), `E251` (spaces around parameter `=`), `E261` (2 spaces before inline comments), `E275` (space after keyword), `E301`/`E302`/`E303`/`E306` (blank line constraints), `W291`/`W292`/`W293`/`W391` (whitespaces/newlines), `E711`/`E712` (`is None`/`is True`), `F401` (unused imports), `F841` (unused variables), and `F541` (empty f-strings).\n\n4. **Documentation & Comments:**\n   * **Functions & Methods:** Every function or method whose purpose is not self-explanatory from its name and signature must include a clear, concise docstring covering its purpose, parameters, and return value. Trivial one-liners and obvious getters/setters may be left undocumented, matching the surrounding file.\n   * **Complex Logic:** Add inline comments to explain non-explicit or intricate blocks of code.\n   * **Keep it Concise:** Do not over-explain or add redundant descriptions in comments.\n\n5. **Testing:** For changes made to **Core code** (`meshroom/core/`), you must add corresponding unit tests for any new features.\n\n### QML / UI (`meshroom/ui/qml/`)\n\n1. **Style Uniformity:** Match the patterns, indentation, and structure already used in the surrounding `.qml` file.\n\n2. **Naming Conventions:** Use **camelCase** for properties, signals, and functions, consistent with standard QML/JS convention and the existing codebase.\n\n3. **Documentation & Comments:** Same principle as Python — add comments for non-obvious or intricate logic, keep them concise, skip them where the code is self-explanatory.\n\n4. **Testing:** Changes purely to the UI/QML layer do not require unit tests.\n\n5. **Structure:** Split overly complex components into dedicated `.qml` files. For data models, avoid complex JavaScript implementations; instead, construct models on the Python UI side and utilize them via context properties.\n\n## Workflow & Delivery\n\n* Provide only targeted code patches instead of full files.\n* Propose changes structured to perform **atomic commits** (one distinct, self-contained change per commit), one feature per PR where possible, per [CONTRIBUTING.md](CONTRIBUTING.md).\n* Link the relevant GitHub issue in the PR description, and open it as a draft PR while work is in progress, matching the existing contributor workflow.\n* **Keep this file accurate:** whenever a change makes any statement in `AGENTS.md` incorrect or incomplete — a moved/renamed path in the Directory Map, a changed command or CI setting, a shift in the architecture described by the Mental Model — update `AGENTS.md` in the same change so it never drifts from the codebase.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Meshroom Agent Guide\n\nYou are assisting on **Meshroom**, a node-based visual programming framework. Use the relative links and directory structure below to orient yourself in the codebase.\n\nMeshroom is a general-purpose Python/QML engine for building, editing, and executing node graphs — it provides a graph editor UI, a node execution engine, and CLI tools, but is domain-agnostic on its own. Concrete functionality is delivered through **plugins** that contribute node types and pipeline templates. Its flagship plugin is **AliceVision**, whose nodes wrap the AliceVision photogrammetry binaries; those C++ computer-vision algorithms live in the separate AliceVision repository, not here.\n\n## Documentation Index\n\nRead the relevant source-of-truth file before working in the area it covers:\n* **Project, Concepts & Vocabulary:** [README.md](README.md)\n* **Installation & System Setup:** [INSTALL.md](INSTALL.md) — read before touching build, dependency, or environment setup.\n* **Plugin Architecture:** [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md) — read before working on plugin loading/packaging.\n* **Node Development:** [NODE_DEVELOPMENT.md](NODE_DEVELOPMENT.md) — read before working on node types or their descriptors (`meshroom/nodes/`, `meshroom/core/desc/`).\n\n## Codebase Directory Map\n\nWhere this map and the actual tree diverge, trust the tree — then update the map to match (see [Workflow & Delivery](#workflow--delivery)).\n\n```\n.\n├── .github/                    # CI/CD workflows, issue templates, and automated testing setups\n├── .vscode/                    # Shared VS Code debugging and workspace configurations\n├── bin/                        # CLI entry points, packaged as executables in setup.py (meshroom_batch,\n│                               # meshroom_compute, meshroom_createChunks, meshroom_info, meshroom_newNodeType,\n│                               # meshroom_statistics, meshroom_status, meshroom_submit).\n│                               # The GUI has NO bin/ script — launch it with ./start.sh (see \"Run the app\").\n├── docker/                     # Dockerfiles for containerized environments (Rocky Linux, Ubuntu, etc.)\n├── docs/                       # Documentation resources, developer guides, and illustrations\n├── localfarm/                  # Standalone local render-farm daemon (backend/client/launcher); the matching\n│                               # submitter lives in meshroom/submitters/localFarm/ (Unix-only, uses fork)\n├── meshroom/                   # MAIN SOURCE CODE DIRECTORY\n│   ├── common/                 # Qt/headless backend abstraction (BaseObject, models) used across the engine\n│   ├── core/                   # Engine logic (Graph, Node, Attribute, execution, (de)serialization)\n│   │   └── desc/               # Node/attribute DESCRIPTORS: desc.Node, desc.CommandLineNode, desc.*Param\n│   │                           #   (imported as `from meshroom.core import desc`)\n│   ├── nodes/                  # Concrete node types, grouped by category (e.g. general/)\n│   ├── submitters/             # Built-in render-farm submitters (drive meshroom_submit; e.g. localFarm)\n│   ├── ui/                     # User Interface layer (PySide6 / QML-based components)\n│   │   ├── qml/                # QML design layouts (GraphEditor, NodeEditor, 3D/2D Viewers, RTI Viewer)\n│   │   ├── components/         # Qt helper components exposed to QML (scene3D, scriptEditor, clipboard, ...)\n│   │   └── ...                 # Python backends (app.py, graph.py, commands.py, scene.py) binding core to Qt\n│   ├── env.py                  # EnvVar registry: MESHROOM_PLUGINS_PATH / NODES_PATH / PIPELINE_TEMPLATES_PATH, etc.\n│   └── multiview.py            # Image-extension lists & helpers for building multiview/photogrammetry pipelines\n├── tests/                      # Comprehensive suite of unit tests and pipeline validation tests\n├── CHANGES.md                  # Changelog tracking features, optimizations, and API breaks\n├── CMakeLists.txt              # Build system file for compiling external modules/packaging\n├── CONTRIBUTING.md             # Guidelines for developer onboarding and codebase contributions\n├── INSTALL.md                  # Detailed steps for building from source and configuring dependencies\n└── INSTALL_PLUGINS.md          # Framework documentation explaining how to load custom Python plugins\n```\n\n## How It Fits Together (Mental Model)\n\nA few distinctions are easy to confuse. Keep them straight before changing engine code:\n\n* **Descriptor vs. instance.** A *node type* is a **descriptor** class in `meshroom/nodes/<Category>/<Name>.py` that subclasses `desc.Node` (Python-scripted) or `desc.CommandLineNode` (wraps an external command-line program, e.g. an AliceVision tool). It can additionally mix in `desc.InputNode` for batch/drag-and-drop initialization or `desc.OutputNode` for pipeline exports. The descriptor declares static schema only: `inputs`/`outputs` (lists of `desc.*` attributes such as `desc.File`, `desc.IntParam`, `desc.ChoiceParam`), plus `category`, `documentation`, `size`, and optional `parallelization`. `OutputNode` declares the inputs that can be configured as export settings with `outputAttributes`; its exposed `File` attributes are output folders. At runtime the engine instantiates it into a live **`Node`** (`meshroom/core/node.py`) whose **`Attribute`** objects (`meshroom/core/attribute.py`) hold the actual values. Rule of thumb: `core/desc/` = schema/definition; `core/node.py` + `core/attribute.py` = live, valued objects.\n* **Graph = DAG of attributes.** A **`Graph`** (`meshroom/core/graph.py`) holds nodes connected by **`Edge`**s that link one node's *output* attribute to another node's *input* attribute. A connected input reads its value from upstream; the graph is a DAG and defines evaluation order. Each node computes a content-based **UID** (hash of its inputs) so unchanged nodes can be cached and skipped on recompute.\n* **Execution = chunks.** Work is split into **`NodeChunk`**s for parallelism (driven by the descriptor's `size`/`parallelization`). `desc.Node` subclasses implement **`processChunk(chunk)`** in Python; `desc.CommandLineNode` builds a command line from its `commandLine` template plus the chunk's range and runs the external binary. **`TaskManager`** (`meshroom/core/taskManager.py`) orchestrates execution — either **locally** (`compute`) or by **submitting** to a render farm (`submit`) via `meshroom/submitters/`.\n* **Persistence.** Graphs are saved as **`.mg`** JSON files (`meshroom/core/graphIO.py`): a versioned `header` plus a `graph` payload. On load, `nodeFactory` reconciles descriptor changes so old projects still open — a node that no longer matches its current descriptor becomes a **`CompatibilityNode`** instead of failing. Pipeline **templates** are just `.mg` files registered at startup. Output nodes are excluded from a template by default and retained only when explicitly requested, allowing `meshroom_batch -o/--output` and the UI startup `-o/--output` to configure export destinations.\n* **Discovery.** Node types and pipeline templates are loaded at import time (`meshroom/core/__init__.py`, `meshroom/core/plugins.py`) from the built-in `meshroom/nodes/` plus any plugin/template paths (see [INSTALL_PLUGINS.md](INSTALL_PLUGINS.md)).\n* **UI bridge.** The engine is Qt-agnostic: `meshroom/common/` selects either a Qt or a headless backend for `BaseObject`, so the core runs without a UI. The `meshroom/ui/*.py` layer wraps it for Qt — `app.py` (application/entry), `graph.py` (a `UIGraph` exposing the core `Graph` as Qt models + async compute), `commands.py` (undo/redo command stack), `scene.py`. QML in `meshroom/ui/qml/` binds to these.\n\n## Development & Verification\n\n* **Supported Python versions:** Target 3.9–3.11. The full test suite runs on **3.11** (Linux + Windows) in CI; `meshroom_compute` (`bin/meshroom_compute`) additionally gets a `-h` smoke test on **3.9**, the minimum supported version. Avoid syntax/features newer than 3.9 in any code reachable from it (`meshroom/core/`, CLI entry points).\n* **Lint:** Run `flake8 . --max-line-length=127` locally. CI ([.github/workflows/run-tests.yml](.github/workflows/run-tests.yml)) runs two passes: a **hard-failing** one for real errors (`--select=E9,F63,F7,F82` — syntax/undefined names) and a **non-blocking** style pass (`--exit-zero --max-complexity=10 --max-line-length=127`). Keep both clean; the [Code Style](#code-style) section lists the specific style warnings to avoid.\n* **Tests:** `pytest tests/` from the repo root. Add/run targeted tests with `pytest tests/path/to/test_file.py::test_name`.\n* **Run the app:** There is no `bin/` script for the GUI. Launch it with `./start.sh` (or `start.bat` on Windows) (sets `MESHROOM_ROOT`/`PYTHONPATH`, then runs `python3 meshroom/ui`), or run `python3 meshroom/ui` directly. For headless pipeline runs use `bin/meshroom_batch`. Manually verify UI/pipeline changes this way before reporting them done.\n\n## Code Style\n\n### Python (`meshroom/core/`, `meshroom/core/desc/`, `meshroom/nodes/`, `meshroom/ui/*.py`, `bin/`)\n\n1. **Style Uniformity (Highest Priority):** If an existing file does not perfectly follow PEP 8 or the rules below, **always prefer code uniformity** with the surrounding codebase over strict rule enforcement.\n\n2. **Naming Conventions:** Use **camelCase** for variable names and function/method names (e.g., `myFunction`, `nodeVariable`). Match existing repository naming patterns rather than default PEP 8 snake_case.\n\n3. **Quality Standards (Modified PEP 8):**\n   * **Line Length:** Do not apply the PEP 8 79/100 characters-per-line limit. Long lines are acceptable.\n   * **Linter Compliance:** Avoid causing these specific issues: `E128` (visual indent), `E222`/`E225` (operator spacing), `E251` (spaces around parameter `=`), `E261` (2 spaces before inline comments), `E275` (space after keyword), `E301`/`E302`/`E303`/`E306` (blank line constraints), `W291`/`W292`/`W293`/`W391` (whitespaces/newlines), `E711`/`E712` (`is None`/`is True`), `F401` (unused imports), `F841` (unused variables), and `F541` (empty f-strings).\n\n4. **Documentation & Comments:**\n   * **Functions & Methods:** Every function or method whose purpose is not self-explanatory from its name and signature must include a clear, concise docstring covering its purpose, parameters, and return value. Trivial one-liners and obvious getters/setters may be left undocumented, matching the surrounding file.\n   * **Complex Logic:** Add inline comments to explain non-explicit or intricate blocks of code.\n   * **Keep it Concise:** Do not over-explain or add redundant descriptions in comments.\n\n5. **Testing:** For changes made to **Core code** (`meshroom/core/`), you must add corresponding unit tests for any new features.\n\n### QML / UI (`meshroom/ui/qml/`)\n\n1. **Style Uniformity:** Match the patterns, indentation, and structure already used in the surrounding `.qml` file.\n\n2. **Naming Conventions:** Use **camelCase** for properties, signals, and functions, consistent with standard QML/JS convention and the existing codebase.\n\n3. **Documentation & Comments:** Same principle as Python — add comments for non-obvious or intricate logic, keep them concise, skip them where the code is self-explanatory.\n\n4. **Testing:** Changes purely to the UI/QML layer do not require unit tests.\n\n5. **Structure:** Split overly complex components into dedicated `.qml` files. For data models, avoid complex JavaScript implementations; instead, construct models on the Python UI side and utilize them via context properties.\n\n## Workflow & Delivery\n\n* Provide only targeted code patches instead of full files.\n* Propose changes structured to perform **atomic commits** (one distinct, self-contained change per commit), one feature per PR where possible, per [CONTRIBUTING.md](CONTRIBUTING.md).\n* Link the relevant GitHub issue in the PR description, and open it as a draft PR while work is in progress, matching the existing contributor workflow.\n* **Keep this file accurate:** whenever a change makes any statement in `AGENTS.md` incorrect or incomplete — a moved/renamed path in the Directory Map, a changed command or CI setting, a shift in the architecture described by the Mental Model — update `AGENTS.md` in the same change so it never drifts from the codebase.\n","category":"root","tokens":3082}]}