Skip to content

render_setup_tools

Export stuff in render setup layer context.

Export Maya nodes from Render Setup layer as if flattened in that layer instead of exporting the defaultRenderLayer as Maya forces by default

Credits: Roy Nieterau (BigRoy) / Colorbleed Modified for use in AYON

allow_export_from_render_setup_layer()

Context manager to override Maya settings to allow RS layer export

Source code in client/ayon_maya/api/render_setup_tools.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@contextlib.contextmanager
def allow_export_from_render_setup_layer():
    """Context manager to override Maya settings to allow RS layer export"""
    try:

        rs = renderSetup.instance()

        # Exclude Render Setup nodes from the export
        rs._setAllRSNodesDoNotWrite(True)

        # Disable Render Setup forcing the switch to master layer
        os.environ["MAYA_BATCH_RENDER_EXPORT"] = "1"

        yield

    finally:
        # Reset original state
        rs._setAllRSNodesDoNotWrite(False)
        os.environ.pop("MAYA_BATCH_RENDER_EXPORT", None)

export_in_rs_layer(path, nodes, export=None)

Export nodes from Render Setup layer.

When exporting from Render Setup layer Maya by default forces a switch to the defaultRenderLayer as such making it impossible to export the contents of a Render Setup layer. Maya presents this warning message: # Warning: Exporting Render Setup master layer content #

This function however avoids the renderlayer switch and exports from the Render Setup layer as if the edits were 'flattened' in the master layer.

It does so by
  • Allowing export from Render Setup Layer
  • Enforce Render Setup nodes to NOT be written on export
  • Disconnect connections from any applyOverride nodes to flatten the values (so they are written correctly)*

*Connection overrides like Shader Override and Material Overrides export correctly out of the box since they don't create an intermediate connection to an 'applyOverride' node. However, any scalar override (absolute or relative override) will get input connections in the layer so we'll break those to 'store' the values on the attribute itself and write value out instead.

Parameters:

Name Type Description Default
path str

File path to export to.

required
nodes list

Maya nodes to export.

required
export callable

Callback to be used for exporting. If not specified, default export to .ma will be called.

None

Returns:

Type Description

None

Raises:

Type Description
AssertionError

When not in a Render Setup layer an AssertionError is raised. This command assumes you are currently in a Render Setup layer.

Source code in client/ayon_maya/api/render_setup_tools.py
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
def export_in_rs_layer(path, nodes, export=None):
    """Export nodes from Render Setup layer.

    When exporting from Render Setup layer Maya by default
    forces a switch to the defaultRenderLayer as such making
    it impossible to export the contents of a Render Setup
    layer. Maya presents this warning message:
        # Warning: Exporting Render Setup master layer content #

    This function however avoids the renderlayer switch and
    exports from the Render Setup layer as if the edits were
    'flattened' in the master layer.

    It does so by:
        - Allowing export from Render Setup Layer
        - Enforce Render Setup nodes to NOT be written on export
        - Disconnect connections from any `applyOverride` nodes
          to flatten the values (so they are written correctly)*
    *Connection overrides like Shader Override and Material
    Overrides export correctly out of the box since they don't
    create an intermediate connection to an 'applyOverride' node.
    However, any scalar override (absolute or relative override)
    will get input connections in the layer so we'll break those
    to 'store' the values on the attribute itself and write value
    out instead.

    Args:
        path (str): File path to export to.
        nodes (list): Maya nodes to export.
        export (callable, optional): Callback to be used for exporting. If
            not specified, default export to `.ma` will be called.

    Returns:
        None

    Raises:
        AssertionError: When not in a Render Setup layer an
            AssertionError is raised. This command assumes
            you are currently in a Render Setup layer.

    """
    rs = renderSetup.instance()
    assert rs.getVisibleRenderLayer().name() != "defaultRenderLayer", \
        ("Export in Render Setup layer is only supported when in "
         "Render Setup layer")

    # Break connection to any value overrides
    history = cmds.listHistory(nodes) or []
    nodes_all = list(
        set(cmds.ls(nodes + history, long=True, objectsOnly=True)))
    overrides = cmds.listConnections(nodes_all,
                                     source=True,
                                     destination=False,
                                     type="applyOverride",
                                     plugs=True,
                                     connections=True) or []
    for dest, src in pairwise(overrides):
        # Even after disconnecting the values
        # should be preserved as they were
        # Note: animated overrides would be lost for export
        cmds.disconnectAttr(src, dest)

    # Export Selected
    with allow_export_from_render_setup_layer():
        cmds.select(nodes, noExpand=True)
        if export:
            export()
        else:
            cmds.file(path,
                      force=True,
                      typ="mayaAscii",
                      exportSelected=True,
                      preserveReferences=False,
                      channels=True,
                      constraints=True,
                      expressions=True,
                      constructionHistory=True)

    if overrides:
        # If we have broken override connections then Maya
        # is unaware that the Render Setup layer is in an
        # invalid state. So let's 'hard reset' the state
        # by going to default render layer and switching back
        layer = rs.getVisibleRenderLayer()
        rs.switchToLayer(None)
        rs.switchToLayer(layer)