Skip to content

New Custom Attributes#3136

Open
nicolas-lambert-tc wants to merge 4 commits into
developfrom
feature/custom-attributes
Open

New Custom Attributes#3136
nicolas-lambert-tc wants to merge 4 commits into
developfrom
feature/custom-attributes

Conversation

@nicolas-lambert-tc

@nicolas-lambert-tc nicolas-lambert-tc commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Description

Peek 2026-06-15 10-45

CustomAttributes concept:
It's a container of custom attributes. It can be input/output as usual attribute.
When an attribute is connected to it's slot, a clone of the attribute connected is added to the container, and both attributes a re connected by default.

Features list

  • Add the CustomAttributes concept: A connection on it duplicate the connected attribute as a child of the CustomAttributes.

Known Limitations:

  • No rename / deletion of a created attribute yet
  • Group is collapsed when an attribute is created, need a store of the collapsed/expanded state
  • No reorder possible yet

Implementation remarks

  • To avoid concepts conflict, the parameter is called CustomAttributes, and no more DynamicAttributes.
    The Dynamic attribute/value already exists for output attributes that have a value of None.

  • In this version there is no way to rename/delete an attribute created by the user using the UI.
    It would be added in an other PR

  • Add the Collapsable class as a mixin to indicate in qml if the attribute should have the Collapsable behavior.
    The idea is to add some internal properties later to store the expanded state, ...

  • A forceEdgesVisualUpdate has been added in the GraphEditor.qml to force the edge evaluation when an attribute is added at runtime.

  • A refacto of the AttributePin.qml/AttributeItemDelegate.qml should be done to help writing of new attributes display.
    It should be decomposed in smaller parts

  • At serialization, the CustomAttributes serialize it's children atttribute with the necessary information to recreate the same attributes at deserialization time.
    -> name, label, type, value

image

Copilot AI review requested due to automatic review settings June 15, 2026 08:48
@nicolas-lambert-tc nicolas-lambert-tc added this to the Meshroom 2026.1.0 milestone Jun 15, 2026
@nicolas-lambert-tc nicolas-lambert-tc self-assigned this Jun 15, 2026
@nicolas-lambert-tc nicolas-lambert-tc marked this pull request as draft June 15, 2026 08:49
Comment thread meshroom/core/attribute.py Fixed
Comment thread tests/test_dynamic_attribute.py Fixed
Comment thread meshroom/ui/commands.py Fixed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new CustomAttributes feature to Meshroom, enabling dynamic input and output attributes on nodes that can be duplicated, removed, and connected dynamically. It includes core attribute model updates, serialization support, UI adjustments for collapsable attributes, and new tests. The review feedback identifies several critical issues, including a missing mixin initialization in GroupAttribute that leads to an AttributeError, potential KeyError crashes when querying DictModel with .get(), incomplete cleanup during command execution failures, property loss in Attribute.clone(), a security risk from using exec() in a test node, and a syntax issue with a non-breaking space in QML.

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.

Comment thread meshroom/core/attribute.py
Comment thread meshroom/core/attribute.py Outdated
Comment thread meshroom/core/attribute.py
Comment thread meshroom/ui/commands.py
Comment thread tests/nodes/test/DynamicNode.py
Comment thread meshroom/core/desc/attribute.py Outdated
Comment thread meshroom/ui/qml/GraphEditor/GraphEditor.qml Outdated
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.18919% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.55%. Comparing base (85b9544) to head (13fbbbb).
⚠️ Report is 14 commits behind head on develop.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
meshroom/core/attribute.py 81.55% 19 Missing ⚠️
meshroom/core/graphIO.py 30.00% 7 Missing ⚠️
meshroom/core/desc/attribute.py 80.00% 5 Missing ⚠️
meshroom/core/desc/anySet.py 92.30% 1 Missing ⚠️
meshroom/core/node.py 88.88% 1 Missing ⚠️
meshroom/core/nodeFactory.py 90.90% 1 Missing ⚠️
tests/nodes/test/AllAttributesNodes.py 90.00% 1 Missing ⚠️
tests/nodes/test/DynamicNode.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3136      +/-   ##
===========================================
+ Coverage    85.36%   85.55%   +0.19%     
===========================================
  Files           73       78       +5     
  Lines        11455    11779     +324     
===========================================
+ Hits          9778    10077     +299     
- Misses        1677     1702      +25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new CustomAttributes container attribute type that can dynamically create (duplicate) child attributes when users connect an edge to the container, with supporting UI changes and serialization/deserialization support so these runtime-created attributes persist across save/load.

Changes:

  • Add desc.CustomAttributes + core.attribute.CustomAttributes with runtime child duplication/removal and serialization support.
  • Update Graph Editor QML to treat CustomAttributes as collapsable/group-like and to keep edge visuals/pin mapping working with dynamic attributes.
  • Add UI commands + tests to validate duplication, connection, and graph save/load behavior.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
tests/test_dynamic_attribute.py New tests covering CustomAttributes creation, duplication, serialization, and graph save/load.
tests/nodes/test/DynamicNode.py Test node exposing CustomAttributes input/output containers.
meshroom/ui/qml/GraphEditor/Node.qml Collapsable logic updated to use isCollapsable/fullName; model helper added.
meshroom/ui/qml/GraphEditor/GraphEditor.qml Edge pin lookup switched to attribute.fullName; adds a forced visual update mechanism.
meshroom/ui/qml/GraphEditor/CollapsableAttributePin.qml New QML component stub.
meshroom/ui/qml/GraphEditor/AttributePinCollapsable.qml New QML component stub.
meshroom/ui/qml/GraphEditor/AttributePin.qml Adds dynamic/custom styling + adjusts connection validation call direction.
meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml Renders CustomAttributes using the group attribute component.
meshroom/ui/graph.py Routes edge creation involving CustomAttributes to a dedicated undoable command.
meshroom/ui/commands.py Adds ConnectCustomAttributesCommand to duplicate + connect attributes via undo stack.
meshroom/nodes/general/PluginSubmitter.py Adds new submitter-related nodes under shipped node set.
meshroom/core/nodeFactory.py Adjusts compatibility checks to ignore CustomAttributes dynamic children.
meshroom/core/node.py Treats CustomAttributes as dynamic-output-bearing for values I/O; tweaks output serialization filtering.
meshroom/core/mixins.py Adds Collapsable mixin with collapsed state and QML-facing properties.
meshroom/core/graphIO.py Adds CustomAttributes serialization behavior (notably for partial graph serialization).
meshroom/core/graph.py Alters edge compatibility checks (special-casing CustomAttributes).
meshroom/core/desc/node.py Marks nodes with CustomAttributes outputs as having dynamic outputs.
meshroom/core/desc/customAttributes.py New descriptor for CustomAttributes.
meshroom/core/desc/attribute.py Adds clone() / asDict() helpers and adjusts a GroupAttribute error message.
meshroom/core/desc/__init__.py Exports CustomAttributes and adds a string→desc-class map for reconstruction.
meshroom/core/attribute.py Core runtime implementation for CustomAttributes + child duplication, plus Collapsable integration.
meshroom/common/core.py Adds count and ordered insert() support to the core DictModel.
.vscode/launch.json Enables QML debug by default in repo launch config.
Comments suppressed due to low confidence (1)

meshroom/core/attribute.py:1205

  • GroupAttribute now mixes in Collapsable, but Collapsable.init is never called, so '_collapsed' is never initialized. Accessing the 'collapsed' property will raise at runtime.
    def __init__(self, node, attributeDesc: desc.GroupAttribute, isOutput: bool,
                 root=None, parent=None):
        super().__init__(node, attributeDesc, isOutput, root, parent)


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread meshroom/core/attribute.py
Comment thread meshroom/core/attribute.py
Comment thread meshroom/core/attribute.py
Comment thread meshroom/core/attribute.py
Comment thread meshroom/core/graph.py Outdated
Comment thread meshroom/ui/qml/GraphEditor/GraphEditor.qml Outdated
Comment thread meshroom/core/desc/attribute.py Outdated
Comment thread meshroom/core/desc/__init__.py
Comment thread .vscode/launch.json Outdated
Comment thread meshroom/nodes/general/PluginSubmitter.py Outdated
@nicolas-lambert-tc nicolas-lambert-tc force-pushed the feature/custom-attributes branch 3 times, most recently from a57a2af to bbc9a8e Compare June 15, 2026 10:10
@nicolas-lambert-tc nicolas-lambert-tc marked this pull request as ready for review June 15, 2026 10:12
@nicolas-lambert-tc nicolas-lambert-tc force-pushed the feature/custom-attributes branch 2 times, most recently from 8b25b52 to 9b8a205 Compare June 15, 2026 10:21
@fabiencastan fabiencastan changed the title Feature/custom attributes New Custom Attributes Jun 15, 2026
Comment thread meshroom/ui/commands.py Dismissed
@nicolas-lambert-tc nicolas-lambert-tc force-pushed the feature/custom-attributes branch from ce78a1f to fd6028c Compare June 24, 2026 09:15
@nicolas-lambert-tc nicolas-lambert-tc force-pushed the feature/custom-attributes branch from fd6028c to 43bbe20 Compare June 24, 2026 09:23
Comment on lines +52 to +72
STR_TO_ATTRIBUTE_DESCRIPTION = {
'ColorParam': ColorParam,
'File': File,
'FloatParam': FloatParam,
'Flow': Flow,
'Geometry': Geometry,
'Size2d': Size2d,
'Vec2d': Vec2d,
'GroupAttribute': GroupAttribute,
'AnySet': AnySet,
'IntParam': IntParam,
'ListAttribute': ListAttribute,
'PushButtonParam': PushButtonParam,
'StringParam': StringParam,
'Shape': Shape,
'ShapeList': ShapeList,
'Point2d': Point2d,
'Line2d': Line2d,
'Rectangle': Rectangle,
'Circle': Circle,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's only used in attribute.py... why not putting it there ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've chosen to put it closer to the sources. A new description added will need the developer to expose it to other modules via init so it is easier to see that it needs to add this to the dictionary, it would be easy to forget to update the core.attributes.py

@Alxiice

Alxiice commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Would it be possible to implement the reset at least ?

@Alxiice

Alxiice commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

I had several errors :

class DynamicNode(desc.InputNode):
    inputs = [
        desc.File(
            name="test"
        ),
        desc.AnySet(
            name="ins",
            label="Custom Inputs",
            description="Custom Inputs",
            exposed=True
        )
    ]
image

connect a ListImages -> we get these errors:

meshroom/ui/qml/GraphEditor/GraphEditor.qml:557: TypeError: Cannot read property 'value' of null
meshroom/ui/qml/GraphEditor/GraphEditor.qml:557: TypeError: Cannot read property 'value' of null
meshroom/ui/qml/GraphEditor/GraphEditor.qml:557: TypeError: Cannot read property 'value' of null
meshroom/ui/qml/GraphEditor/GraphEditor.qml:557: TypeError: Cannot read property 'value' of null

Then remove the File input and do a hot reload -> the connection breaks and we get this :

meshroom/ui/qml/GraphEditor/GraphEditor.qml:557: TypeError: Cannot read property 'value' of null
meshroom/ui/qml/GraphEditor/GraphEditor.qml:555: TypeError: Cannot read property 'value' of null
meshroom/ui/qml/GraphEditor/AttributePin.qml:93:13: Unable to assign [undefined] to QColor
meshroom/ui/qml/GraphEditor/AttributePin.qml:93:13: Unable to assign [undefined] to QColor

(For some reasons we get the error messages multiple times)

Comment thread meshroom/core/desc/attribute.py
from meshroom.common import Property, Variant


class AnySet(GroupAttribute):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not "DynamicGroupAttribute" ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chose to not used the dynamic term to avoid confusion with dynamic values.

@@ -0,0 +1,180 @@
"""Tests for the AnySet feature."""

from meshroom.core import desc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants