A hands-on guide to creating Meshroom plugins, from the simplest possible node to ML-powered semantic segmentation.
mrHelloWorld is a pedagogical repository containing seven progressive, functional Meshroom nodes across six tutorials. Each node introduces new concepts — starting with a simple image copy and ending with a pretrained deep learning model for semantic segmentation. The goal is to give developers a clear, working reference instead of having to reverse-engineer production plugins.
This is not a library or framework. It is a collection of annotated examples designed to be read, modified, and used as starting points for your own plugins.
- Clone the repository:
git clone https://github.com/meshroomHub/mrHelloWorld.git
cd mrHelloWorld- Create a virtual environment and install dependencies:
python -m venv venv
source venv/bin/activate # Linux/macOS
pip install -r requirements.txtImportant: The virtual environment must be named exactly venv (not .venv, env, or anything else). Meshroom detects and uses this specific name for dependency resolution.
- Configure the tutorial projects (replaces path placeholders in
.mgfiles):
bash scripts/setup_projects.sh- Set the plugin path and launch Meshroom:
export MESHROOM_PLUGINS_PATH=/path/to/mrHelloWorld
meshroomAll seven nodes will appear in the node list under the Hello World category.
You can also open the pre-configured tutorial projects directly:
meshroom meshroom/tuto01-hello-world.mgmrHelloWorld/
meshroom/
helloWorld/
__init__.py # Empty — required for Python package discovery
HelloWorld.py # Node 1: minimal node (image copy)
HelloParams.py # Node 2: parameter types + rotation
HelloCrop.py # Node 3: interactive Rectangle crop
HelloCommandLine.py # Node 4: CommandLineNode + external script
HelloAdvanced.py # Node 5a: synthetic camera rig generator
HelloTransform.py # Node 5b: rigid body transformation on SfMData
HelloML.py # Node 6: semantic segmentation (DeepLabV3) [WIP]
config.json # Configuration for HelloML model path [WIP]
helloWorldPipeline.mg # Pipeline template: HelloWorld -> HelloParams -> HelloCrop
# (only the first 3 nodes — advanced nodes require specific inputs)
tuto01-hello-world.mg # Tutorial project files (one per node)
tuto02-hello-params.mg
tuto03-hello-crop.mg
tuto04-hello-command-line.mg
tuto05-hello-advanced.mg
tuto06-hello-ml.mg # [WIP]
scripts/
hello_process.py # External script called by HelloCommandLine
docs/
tutorials/ # Per-node step-by-step tutorials
images/ # Screenshots (user-provided)
requirements.txt
LICENSE # MPL-2.0
| Node | What it teaches | Tutorial |
|---|---|---|
| HelloWorld | Minimal node structure, processChunk, logManager, lazy imports | Tutorial 01 |
| HelloParams | IntParam, FloatParam, BoolParam, ChoiceParam, StringParam, advanced, invalidate | Tutorial 02 |
| HelloCrop | Rectangle descriptor, 2D viewer interaction, pixel coordinates | Tutorial 03 |
| HelloCommandLine | CommandLineNode, {allParams}, external scripts, group mechanism | Tutorial 04 |
| HelloAdvanced | pyalicevision SfMData creation, coordinate systems, .abc export | Tutorial 05 |
| HelloTransform | SfMData I/O (.abc), rigid body transformations, node chaining | Tutorial 05 |
| HelloML | ML inference, config.json, GPU management, model weights API | Tutorial 06 (WIP) |
Here is the minimal structure, taken from HelloWorld.py with annotations:
# Version string — Meshroom uses this for cache invalidation.
__version__ = "1.0"
# Standard module-level imports. Heavy libraries (cv2, torch) go inside processChunk.
import os
from meshroom.core import desc
from meshroom.core.utils import VERBOSE_LEVEL
class HelloWorld(desc.Node):
# Category in the node creation menu.
category = "Hello World"
# Displayed in the UI when the node is selected.
documentation = """Description of what this node does."""
# Input parameters — each needs name, label, description.
inputs = [
desc.File(
name="input",
label="Input Image",
description="Path to the input image file.",
value="",
),
desc.ChoiceParam(
name="verboseLevel",
label="Verbose Level",
description="Verbosity level for logging.",
values=VERBOSE_LEVEL,
value="info",
exclusive=True,
),
]
# Outputs use {nodeCacheFolder} for isolated output paths.
outputs = [
desc.File(
name="output",
label="Output Image",
description="Path to the output image.",
value="{nodeCacheFolder}/output.jpg",
),
]
def processChunk(self, chunk):
try:
chunk.logManager.start(chunk.node.verboseLevel.value)
import cv2 # Lazy import — heavy library loaded only when computing.
image = cv2.imread(chunk.node.input.value)
cv2.imwrite(chunk.node.output.value, image)
finally:
chunk.logManager.end() # Always in finally — ensures cleanup.The rules are simple:
- Class name must match the filename (
HelloWorld.pycontainsclass HelloWorld). __version__is required for cache invalidation.- Heavy imports go inside
processChunk, not at module level. processChunkalways usestry/finallywithlogManager.start()andlogManager.end().- Every parameter needs
name,label, anddescription.
Meshroom plugins can read values from a config.json file at the plugin root. This is useful for environment-specific settings like model paths or feature flags. See Tutorial 06 for the full pattern.
The desc.Rectangle descriptor lets users draw shapes directly in Meshroom's 2D image viewer. Coordinates are in pixel space using a center+size format. See Tutorial 03 for implementation details.
For nodes that need to create or read Structure-from-Motion data (camera poses, 3D points, intrinsics), pyalicevision provides the API. It is bundled with Meshroom binary releases. See Tutorial 05 for the creation and I/O API reference.
Production ML nodes follow a specific pattern: lazy imports, device selection, model loading (with config.json fallback for offline use), preprocessing, inference, postprocessing, and GPU cleanup in finally. See Tutorial 06.
When your processing logic lives in a standalone script or binary, use desc.CommandLineNode instead of desc.Node. Meshroom builds and executes the command automatically. See Tutorial 04.
These patterns are not fully implemented in mrHelloWorld but are documented for reference:
- Docker: Some plugins (mrGSplat) use Docker containers for complex dependencies. The node builds a Docker command line with volume mounts.
- ShapeList: For nodes that need multiple shapes (e.g., multiple bounding boxes), use
desc.ShapeListinstead ofdesc.Rectangle. See mrSegmentation'sImageSegmentationBox.py. - PushButtonParam: Interactive buttons in the Meshroom UI that trigger callbacks (e.g., loading bounding boxes from a file). See mrSegmentation's
VideoSegmentationSam3.py. - MultiDynamicNodeSize: For nodes with multiple dynamic inputs that affect sizing. See mrSegmentation for an advanced example.
| Plugin | What it demonstrates |
|---|---|
| mrSegmentation | ShapeList, PushButton, advanced parallelization, SAM models |
| mrRoma | CommandLineNode with external script, image matching |
| mrSDMUniPS | pyalicevision SfMData I/O, GPU-intensive processing |
| mrGSplat | Docker integration, Gaussian splatting |
| mrVideoUtils | Simple CommandLineNode, video processing |
| mrDepthEstimation | Monocular depth estimation with ML models |
| mrGeolocation | Geolocation from images |
- Verify
MESHROOM_PLUGINS_PATHpoints to the mrHelloWorld root directory (the one containing themeshroom/folder). - Check that the
meshroom/helloWorld/__init__.pyfile exists (even if empty). - Check the Meshroom console for import errors at startup.
- Make sure you created the virtual environment with
python -m venv venv(exactlyvenv, not.venvorenv). - Activate the venv and run
pip install -r requirements.txt. - Meshroom automatically detects the
venvdirectory at the plugin root.
pyalicevision is bundled with Meshroom binary releases and is not pip-installable. HelloAdvanced and HelloTransform require pyalicevision for SfMData creation/I/O and .abc export. They only work when run inside Meshroom's Python environment (i.e., when Meshroom computes the node). They cannot be tested standalone.
This is expected. DeepLabV3-MobileNetV3 weights (~35MB) are downloaded automatically by torchvision. For offline environments, pre-download the weights and configure config.json with the path. See Tutorial 06.
The helloWorldPipeline.mg file contains a releaseVersion field. If Meshroom warns about version mismatch, update this field to match your Meshroom version.
See CONTRIBUTING.md for guidelines on adding new example nodes, writing tutorials, and contributing screenshots.
- Meshroom — the open-source 3D reconstruction software that provides the plugin framework used by this project.
- AliceVision — the photogrammetric computer vision framework behind Meshroom, including the pyalicevision bindings used in HelloAdvanced.
- The snail test image (
hello-world-snail.png) is from the Skoltech3D dataset, a multi-sensor dataset for multi-view 3D surface reconstruction developed by Skoltech (Moscow Institute of Science and Technology). The dataset is available under the Creative Commons Attribution-NonCommercial 4.0 International License.
Voynov et al., "Multi-Sensor Large-Scale Dataset for Multi-View 3D Reconstruction", CVPR 2023. arXiv:2203.06111
This project is licensed under the Mozilla Public License 2.0.
