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 theRenderData
instance, since there can be multiple render data instances with different values, so theBasePlugin
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.
At the end of the posting, you can find some example code for your exact use case.
Cheers,
FerdinandThe 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()
-
Hi Ferdinant,
Thanks for the example.
I'm trying to use a python tag to set the view to raw when doing final renders and have it on SDR during interactive renders.
The settings are being set but somehow this doesnt trigger an update it appears. Only when manually forcing an update on the rendersetting it is changed. This is the code I'm using:import c4d import redshift def changeSettings(obj, videoPost, isRendering): if isRendering: segs = 24 view = r"Raw" else: segs = 3 view = r"ACES 1.0 SDR-video" # avoid applying redundant changes if obj[c4d.PRIM_SPHERE_SUB] != segs: print("Setting to %d" %segs) obj[c4d.PRIM_SPHERE_SUB] = segs print(view) videoPost[c4d.REDSHIFT_RENDERER_COLOR_MANAGEMENT_OCIO_VIEW] = view obj.Message(c4d.MSG_CHANGE) # EvenAdd is only needed when modifying the active document if doc == c4d.documents.GetActiveDocument(): c4d.EventAdd() def main(): pass def message(msgType, data): print # Check for final renders if msgType==c4d.MSG_MULTI_RENDERNOTIFICATION: redshiftRenderEngineId = 1036219 my_render_data = c4d.documents.GetActiveDocument().GetActiveRenderData() videoPost = my_render_data.GetFirstVideoPost() while (videoPost): if videoPost.CheckType(redshiftRenderEngineId): break videoPost = videoPost.GetNext() started = data["start"] if started: print("Render Started") else: print("Render Finished") changeSettings(op.GetObject(), videoPost, started)
I've also incuded a test file
Render_viewTransform.c4d -
Hey @wen,
so, I had a look at your file and to me it mostly looks like it is doing what it is supposed to do. You also did not mention the version of Cinema 4D you are using. Your code looks a bit "Python 2.X"-ish, which would mean you are using S22 or older. In R25 Redshift does not have a "Raw" color profile anymore, which makes this a bit hard to test.
When you rely on c4d.MSG_MULTI_RENDERNOTIFICATION, you should however use the document associated with the render and not the active one. The rendering document is being sent with the message data, see link above. Which would also alleviate the need for "switching things back".
I cannot say much more without understanding what you would consider not working in your file.
Cheers,
Ferdinand -
Hi Ferdinand,
I am indeed running R22. Your comment about using the document associated with the render was spot on. I assumed they would be the same document but apparently they are not. After changing this it works as expected.
I've included a working example incase someone else is looking for the same thing.
Render_viewTransform.c4dGot a new question though, what do you mean with:
"In R25 Redshift does not have a "Raw" color profile anymore"
Had a look at R25 and didn't see anything different in that regard.Thanks!
-
Hey @wen,
Thanks for sharing the example scene!
Got a new question though, what do you mean with:
"In R25 Redshift does not have a "Raw" color profile anymore"
I looked at the wrong parameter; I thought your second script was still for
REDSHIFT_RENDERER_COLOR_MANAGEMENT_OCIO_RENDERING_COLORSPACE
as the previous example, but it is forREDSHIFT_RENDERER_COLOR_MANAGEMENT_OCIO_VIEW
. So, you are right, "Raw" is still thereCheers,
Ferdinand