SOLVED How to check if document is rendering?

Hello everyone,

some objects like the Subdivision Surface or the Metaballs have different parameters to be applied if the document is rendering.

Is there a way in python to check if the document is currently being rendered or not, to make if/else statements that only apply during rendering?

Hello @orestiskon,

thank you for reaching out to us. Please remember to add the required tags to your posting as lined out in the Forum Guidelines, most notably the tags and the information on what plugin interface you are implementing. I am going to assume here Python and S24/R25 for the tag information.

About your question: The answer to that heavily depends on what you are trying to do precisely, as you do not make clear if you are implementing your own node and want to change its behavior on rendering or want to change the behavior of other nodes which are not being implemented by you.

Generally, there are two relevant bits of the Python SDK for this topic: The function c4d.CheckIsRunning() and the node message c4d.MSG_MULTI_RENDERNOTIFICATION. Both convey information about a rendering status. There are however multiple rendering types (internal, external, interactive) and one must mix both approaches in some cases to cover all of them. For an ObjectData plugin, i.e., the case that you implement your own node, I have provided a pattern below. For the other case things will get more complicated because you would then have to hook into the specific parameter set an arbitrary other node can have. This can be solved via implementing a TagData plugin for BaseObjects targeted in such fashion in Python, although this would probably be quite a bit of work. Driving in such external fashion shader, materials and other node types will be very hard or even impossible in Python, because for that you would truly need SceneHookData which are not available in Python.

The example below is a Python generator object which acts as a cube while in the editor and as a sphere when being rendered.

I hope this helps and cheers,
Ferdinand

The file: render_cube_sphere.c4d
The result:
render_cube_sphere.gif
The code:

"""The example below is for a Python generator object which acts as a cube 
while in the editor and as a sphere when being rendered.

As discussed in:
    https://plugincafe.maxon.net/topic/13605/

"""
import c4d

# A boolean parameter we use to store the current rendering for the node.
ID_IS_EDITOR_RENDERING = (c4d.ID_USERDATA, 1)

def message(mid, mdata):
    """Processes messages send to the node.
    
    Used here to react to the MSG_MULTI_RENDERNOTIFICATION message.
    
    Args:
        mid (int): The message id
        mdata (any): The message data (in case of RENDERNOTIFICATION a dict)
    """
    # The render notification for an editor rendering does come in a pair. One
    # for the start of the rendering and one for the end. We set our object
    # parameter ID_IS_EDITOR_RENDERING to the value that message data to be
    # used later in the cache building.

    if mid == c4d.MSG_MULTI_RENDERNOTIFICATION and isinstance(mdata, dict):
        # Set the render flag parameter we did attach to our generator with
        # the start field of the message data.
        op[ID_IS_EDITOR_RENDERING] = mdata.get("start", False)

def main():
    """Provides the cache for the generator.
    """
    is_render = (op[ID_IS_EDITOR_RENDERING] or
                 c4d.CheckIsRunning(c4d.CHECKISRUNNING_EXTERNALRENDERING) or
                 c4d.CheckIsRunning(c4d.CHECKISRUNNING_INTERACTIVERENDERING))

    # Return a sphere while rendering.
    if is_render:
        return c4d.BaseObject(c4d.Osphere)
    # Or a cube while not.
    return c4d.BaseObject(c4d.Ocube)

@ferdinand Hey Ferdinand, thanks for the elaborate reply.

I didn't mean to put you through all of this work, I was literally searching for an "if rendering" statement. I'm trying to use a python expression tag, and only run a line of the code if it's rendering externally (picture viewer or render queue) .

Based on your solution, I tried:

value = 10
if c4d.CheckIsRunning(c4d.CHECKISRUNNING_EXTERNALRENDERING):
    value = 20

and it seems to work. You mentioned that I couldn't affect other objects but I guess in this case it's ok?

Hey @orestiskon,

no worries, was no hassle for me.

and it seems to work. You mentioned that I couldn't affect other objects, but I guess in this case it's ok?

Hard to say because I still do not know what you are doing specifically, but if it does run, it runs 😉 It would be best if you would share your setup and/code if you want an assessment on if what you are doing can lead to problems. In general, there is not much which can go wrong with CheckIsRunning on a technical level, it is just that when you want for example drive the color of a shader (which you have not implemented yourself) in this way, you will run into obstacles in Python, not necessarily unsolvable ones, but still obstacles.

I really cannot say much more than that without the concrete thing you are trying to achieve.

Cheers,
Ferdinand

Thanks Ferdinand,

"if it does run, it runs ;)"

Haha, that's my motto.

In this case I'm doing a brute-force script for a specific 1-time use, I'm sure it won't pass the test of approval. But if I see a sign of problem I'll fall-back to other solutions.

It seems to work well and I'll keep that solution for future uses.
Thanks again. 🙂