MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Expose node version control in MaterialXGraphEditor

Open ld-kerley opened this issue 3 months ago • 4 comments

The OpenPBR team would like for multiple versions of the OpenPBR MaterialX node to be present in a scene at the same time. It is important for adoption that old and new assets can be used in the same scene together.

We would like to validate that the MaterialX node versioning mechanism is robust, and start to explore what the user experience story is here surrounding how an artist might interact with node versions.

Initially we would like to see a UI control added to the MaterialXGraphEditor that would allow users to both visualize and select which version of a node exists in their graph.

I think this work breaks down in to three parts, in increasing difficulty.

  1. Add a read-only UI label that informs the user of the version number, if any, for the currently viewed node. Likely somewhere in the highlighted area in the image below.
  2. Add a new UI control that allows users to select which version they are creating when creating a new node, once created that version would then be visible in the read-only control added in (1)
  3. (stretch-goal) Add a editable UI control to allow the version of the selected node to be changed. It is unclear if this is something that we want to support in general, as it suggests potentially needed to mutate the data, but the first step in exploring this idea would be to add this UI element to allow mutating the version in an active document.
Image

Note we can use the existing standard surface node to test with - as that currently has two different versions. It may be necessary to add extra nodes or extra version to test with.

ld-kerley avatar Nov 12 '25 19:11 ld-kerley

  1. The UI side is pretty easy to do. There is a "node info" button but if this is too obscure the version can be added to the top.

  2. The "add node" popup lists all versions but it's non user-friendly as it uses the internal definition id string instead of node category + version so seems a simple UI change as well if acceptable.

  3. For the version switching, has there been thought put into have translation graphs that convert from one version to another ? std surface is a bit trivial since it's mostly pass-through.

Maybe 1+2 can be "good first issue" task -- probably a days work. While 3. can be split out into a sub-issue ?

kwokcb avatar Nov 13 '25 03:11 kwokcb

UsdUVTexture also has multiple versions.

kwokcb avatar Nov 13 '25 03:11 kwokcb

For the version switching, has there been thought put into have translation graphs that convert from one version to another ? std surface is a bit trivial since it's mostly pass-through.

For the OpenPBR version switching, I plan (ASAP) to write down the detailed logic needed to translate from OpenPBR v1.1 to v1.2 (which will be stated for convenience in the OpenPBR repo), and then someone (possibly me) needs to create a translation graph implementing that.

portsmouth avatar Nov 20 '25 16:11 portsmouth

I have some thoughts on how to support versioning for translation graphs. I did a review of what's there here

I think the simplest option is to add source version and target version attributes and beef up the search logic a bit.

<nodedef name="ND_open_pbr_surface_to_standard_surface" node="open_pbr_surface_to_standard_surface" nodegroup="translation">  

becomes

<nodedef name="ND_open_pbr_surface_to_standard_surface" node="open_pbr_surface_to_standard_surface" nodegroup="translation"
         source_version="1.1" target_version="1.01" 
         source="open_pbr_surface" target="standard_surface" >

a new version would look like this for example:

<nodedef name="ND_open_pbr_surface_to_standard_surface" node="open_pbr_surface_to_standard_surface" nodegroup="translation"
         source_version="1.2" target_version="1.01" 
         source="open_pbr_surface" target="standard_surface" >

Search logic update is pretty trivial and this is not exposed to the API user at all so no compatibility issues:

def find_translator(doc : mx.Document, 
                    source : str, target : str, 
                    source_version : str, target_version: str) -> mx.NodeDef | None:
    '''
    @brief Find a translator nodedef from source to target with specific versions.
    @param doc The document to search in.
    @param source The source nodedef nodeString.
    @param target The target nodedef nodeString.
    @param source_version The source version string.
    @param target_version The target version string.
    @return The found translator nodedef or None.
    '''
    nodedefs = doc.getNodeDefs()
    for nodedef in nodedefs:
        if nodedef.getNodeGroup() == "translation":
            nodedef_source = nodedef.getAttribute('source')
            nodedef_target = nodedef.getAttribute('target')
            nodedef_source_version = nodedef.getAttribute('source_version')
            nodedef_target_version = nodedef.getAttribute('target_version')
            if (nodedef_source == source and nodedef_target == target and
                nodedef_source_version == source_version and
                nodedef_target_version == target_version):
                return nodedef
    return None

A few days work. Existing definitions should be updated with explicit versioning.

kwokcb avatar Nov 27 '25 23:11 kwokcb