UNSOLVED Access renderer specific settings with python

Access renderer specific settings with python

I'm looking for a way to acces the renderer specific rendersettings with Python. I can adjust common rendersettings like the width, height, start, end, etc. since they are stored in the RenderData. These are accessible through:

#Store the RenderData object in a variable so it's easier to access
my_render_data = c4d.documents.GetActiveDocument().GetActiveRenderData()

#Set the render width
my_render_data[c4d.RDATA_XRES] = 1920

#Set the render height
my_render_data[c4d.RDATA_YRES] = 1080

#Set the startframe
# - note we get a BaseTime object so we need to use GetFrame() to get a frameNumber from that. 
my_render_data[c4d.RDATA_FRAMEFROM].GetFrame(25)

#Set the endframe
my_render_data[c4d.RDATA_FRAMETO].GetFrame(25)

Unfortunately something like this won't work:

my_render_data = c4d.documents.GetActiveDocument().GetActiveRenderData()

print (my_render_data[c4d.REDSHIFT_RENDERER_COLOR_MANAGEMENT_OCIO_RENDERING_COLORSPACE])

This returns "None" so the renderer specific settings seem to live somewhere else.
Now I'm assuming if I want to to change renderer specific values I should point to the renderer somehow.
With RDATA_RENDERENGINE I get the plugin ID. So let's go from there:

my_render_data = c4d.documents.GetActiveDocument().GetActiveRenderData()
print (c4d.plugins.FindPlugin(my_render_data[c4d.RDATA_RENDERENGINE]))

This returns:

<c4d.plugins.BasePlugin object called 'Redshift' with ID 8 at 0x0000027D8A30E590>

Now I'm not sure if this is the right direction as it doesn't get me much further. I still can't acces plugin specific values.
How do I get/adjust those?

Hello @wen,

Thank you for reaching out to us. You got it almost right, but you must access the actual BaseVideoPost attached to the RenderData instance, since there can be multiple render data instances with different values, so the BasePlugin cannot hold these values.

The underlying "trick" is here that some things that are render settings are expressed directly in the render data and some by video post nodes. Non-removeable entries like "Output" or "Save" are represented in the render data directly, the rest is represented by video post nodes. You can find out more tangibly with the console as demonstrated by the screen grab below.

videopost.gif

At the end of the posting, you can find some example code for your exact use case.

Cheers,
Ferdinand

The output:

Found <c4d.documents.BaseVideoPost object called Redshift/Redshift with ID 1036219 at 1699066826048> for 'redshiftRenderEngineId = 1036219'.
Old value for color space: ACEScg
New value for color space: ACES2065-1

The code:

"""Demonstrates how to access Redshift render engine render settings attached
to render data.
"""

import c4d

def main():
    """Entry point.
    """
    # doc in predefined in script manger scripts, so this would not be 
    # necessary, but since you did call GetActiveDocument() I copied this
    # here.
    doc = c4d.documents.GetActiveDocument()
    if not isinstance(doc, c4d.documents.BaseDocument):
        raise RuntimeError("Could not access active document.")

    renderData = doc.GetActiveRenderData()

    # The elements in the render settings are video post plugins. Some of
    # the common entries, e.g., Output/Save are mapped automatically to the
    # render data, for everything that is optional, we must access the 
    # corresponding BaseVideoPost. Your idea with FindPlugin was not bad, but
    # that will only give you the BasePlugin and not the actual video post
    # instance associated with the concrete render data instance.

    # We could also get the Redshift id like you did with RDATA_RENDERENGINE,
    # but this assumes that the Redshift is indeed the active render engine.
    # So, for me it is a bit more comfy to hard-code it.
    redshiftRenderEngineId = 1036219

    # Iterate over the video post to find one matching the render engine.
    videoPost = renderData.GetFirstVideoPost()
    while (videoPost):
        if videoPost.CheckType(redshiftRenderEngineId):
            break
        videoPost = videoPost.GetNext()

    if not isinstance(videoPost, c4d.documents.BaseVideoPost):
        raise RuntimeError(
            f"Could not access video post for '{redshiftRenderEngineId = }'")

    print (f"Found {videoPost} for '{redshiftRenderEngineId = }'.")

    # This is now normal parameter access, man that is a long symbol :)
    csId = c4d.REDSHIFT_RENDERER_COLOR_MANAGEMENT_OCIO_RENDERING_COLORSPACE
    print (f"Old value for color space: {videoPost[csId]}")
    videoPost[csId] = "ACES2065-1"
    print (f"New value for color space: {videoPost[csId]}")

    c4d.EventAdd()


if __name__ == '__main__':
    main()