Explicit templates file management - #3153
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for template files with the .mgt extension, allowing users to save, load, and manage templates separately from standard .mg project files. Key changes include a new files.py utility module, updated template discovery in core modules, and UI enhancements such as a 'Recent Templates' menu, a template badge, and improved drag-and-drop handling. The review feedback highlights several high-quality improvement opportunities, including preventing a fall-through bug in file drop handling, specifying UTF-8 encoding when reading files, refactoring path operations to be more Pythonic, optimizing loops that parse file extensions, and adding defensive null checks in QML to avoid potential runtime errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if filesByType["meshroomTemplates"]: | ||
| if len(filesByType["meshroomTemplates"]) > 1: | ||
| self.error.emit( | ||
| Message( | ||
| "Too Many Meshroom Templates", | ||
| "A single Meshroom template (.mgt file) can be opened at once." | ||
| ) | ||
| ) | ||
| elif filesByType["meshroomScenes"]: | ||
| self.error.emit( | ||
| Message( | ||
| "Mixed Meshroom Files", | ||
| "Do not mix Meshroom projects and templates." | ||
| ) | ||
| ) | ||
| else: | ||
| return self.loadTemplate(filesByType["meshroomTemplates"][0]) |
There was a problem hiding this comment.
Add return False immediately after emitting errors for too many templates or mixed files. Otherwise, the function will fall through and still attempt to load the scene file if exactly one scene is present in the dropped files, bypassing the error handling.
| if filesByType["meshroomTemplates"]: | |
| if len(filesByType["meshroomTemplates"]) > 1: | |
| self.error.emit( | |
| Message( | |
| "Too Many Meshroom Templates", | |
| "A single Meshroom template (.mgt file) can be opened at once." | |
| ) | |
| ) | |
| elif filesByType["meshroomScenes"]: | |
| self.error.emit( | |
| Message( | |
| "Mixed Meshroom Files", | |
| "Do not mix Meshroom projects and templates." | |
| ) | |
| ) | |
| else: | |
| return self.loadTemplate(filesByType["meshroomTemplates"][0]) | |
| if filesByType["meshroomTemplates"]: | |
| if len(filesByType["meshroomTemplates"]) > 1: | |
| self.error.emit( | |
| Message( | |
| "Too Many Meshroom Templates", | |
| "A single Meshroom template (.mgt file) can be opened at once." | |
| ) | |
| ) | |
| return False | |
| elif filesByType["meshroomScenes"]: | |
| self.error.emit( | |
| Message( | |
| "Mixed Meshroom Files", | |
| "Do not mix Meshroom projects and templates." | |
| ) | |
| ) | |
| return False | |
| else: | |
| return self.loadTemplate(filesByType["meshroomTemplates"][0]) |
| if extensionLower(path) != MESHROOM_LEGACY_TEMPLATE_EXTENSION: | ||
| return False | ||
| try: | ||
| with open(path) as file: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3153 +/- ##
===========================================
+ Coverage 85.39% 85.43% +0.04%
===========================================
Files 73 75 +2
Lines 11498 11607 +109
===========================================
+ Hits 9819 9917 +98
- Misses 1679 1690 +11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
e6659e4 to
c24ebd3
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces explicit Meshroom template file handling by adding the .mgt extension, centralizing template detection rules in core, and wiring UI flows to open templates as unsaved graphs while tracking template origin separately for indicators and recent-files.
Changes:
- Added
meshroom.core.fileshelpers/constants to detect templates via.mgtextension or legacy.mgheader metadata. - Updated UI load/drop flows to route template files through a dedicated “open template” path, track
graph.templateFilepath, and maintain a separate recent-templates list. - Added UI affordances (GraphEditor stripes + toolbar badge) to indicate when the active graph originates from a template.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_template_files.py | Adds unit tests for extension/header-based template detection, template init behavior, and template discovery. |
| meshroom/core/files.py | Introduces centralized template/project extension constants and detection/extension helpers. |
| meshroom/core/init.py | Updates pipeline template discovery to support .mgt and legacy .mg templates. |
| meshroom/core/plugins.py | Updates plugin template discovery to support .mgt and legacy .mg templates with deterministic ordering. |
| meshroom/core/graph.py | Adds templateFilepath to Graph model and clears it when the graph becomes a regular saved project. |
| meshroom/multiview.py | Extends dropped-file categorization to include Meshroom templates separately from projects. |
| meshroom/ui/scene.py | Routes loads to template flow, adds template drop handling, and updates unknown-extension reporting. |
| meshroom/ui/graph.py | Ensures save-as uses the correct extension for projects vs templates via withExtension. |
| meshroom/ui/app.py | Adds recent-templates persistence and QML-facing properties/slots for template recents. |
| meshroom/ui/qml/main.qml | Adds template recent-file tracking when opening a file at startup. |
| meshroom/ui/qml/WorkspaceView.qml | Updates drop-to-open behavior and recent-file updates for projects vs templates. |
| meshroom/ui/qml/Application.qml | Updates template dialogs/actions/menus and adds a template badge indicator in the UI. |
| meshroom/ui/qml/GraphEditor/GraphEditor.qml | Adds background stripe indicator for template graphs and recognizes .mgt in drag/drop. |
| meshroom/ui/qml/ImageGallery/ImageListView.qml | Treats templates like projects for drag/drop exclusivity and updates copy text. |
| meshroom/ui/qml/ImageGallery/ImageGridView.qml | Treats templates like projects for drag/drop exclusivity and updates copy text. |
| meshroom/ui/qml/ImageGallery/ImageGallery.qml | Updates mixed-file warning text to mention both projects and templates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {images, videos, panoramaInfo, meshroomScenes, meshroomTemplates, otherFiles}: Map containing the | ||
| lists of paths for recognized images, videos, Meshroom scenes, Meshroom templates and other files. | ||
| Node: cameraInit node used to add new images to it | ||
| QPoint: position to locate the node (usually the mouse position) | ||
| """ |
| def load(self, url): | ||
| localFile = self._urlToLocalFile(url) | ||
| if isTemplateFile(localFile): | ||
| return self.loadTemplate(localFile) | ||
| return self._loadWithErrorReport(self.loadGraph, localFile) |
c24ebd3 to
ee14941
Compare
|
|
||
| import meshroom | ||
| from meshroom.core import pluginManager | ||
| from meshroom.core.files import isTemplateFile |
| from meshroom.core import submitters | ||
| from meshroom.core.attribute import Attribute, ListAttribute, GroupAttribute | ||
| from meshroom.core.exception import GraphCompatibilityError, InvalidEdgeError, StopGraphVisit, StopBranchVisit, CyclicDependencyError | ||
| from meshroom.core.files import MESHROOM_PROJECT_EXTENSION, isTemplateFile |
|
Why don't we use the header to check .mgt validity ? |
Description
This PR makes Meshroom template files explicit in the project flow. Templates can now be detected from their file extension or serialized header, opened through a dedicated template flow, tracked in their own recent-files list, and clearly identified in the GraphEditor when an opened graph comes from a template.
Features list
template:true) are still loadableImplementation remarks
Template detection is centralized in
meshroom.core.filesso both core and UI code use the same rules.Opening a template still initializes an unsaved graph, but the source template filepath is stored separately on the graph model for UI feedback and recent-template tracking.
The GraphEditor indicator is intentionally lightweight and disappears once the graph becomes a regular saved project.