UNSOLVED Getting Current Render Frame

Hello,

I am trying to write a script to be able to read the progress of a render. I would like to be able to output the frame number that the current render is on. I just need to be able to output it into the console - the rest I can figure out.

I basically already have code that listens to if the render is starting and complete - now I would like to have interval console outputs whenever a new frame is being rendered.

I looked into the python syntaxes but I couldn't get anything useful!
Anyone know how to solve this??

Thanks in advance!

Hi @NibblingFeet may I ask what code you are using to "listen if the render starts and ends". I ask this because there are different ways to do this and depending on that there are several solutions for you.

The simplest solution would be that if you are the renderer via c4d.documents.RenderDocument, you could set a render progress callback that would report the current progress or even a callback when each frame is exported to a file, that way you could know the exact frame that has finished rendering.

Cheers,
Maxime.

Hi @m_adam ,

Thanks for reaching out - I tried to look through the linked document but I couldn't seem to output any render information.
Below is the python code I am using - I am essentially making a thread to check while it is still rendering, and the moment it's complete it will continue the script. I would now like to make a callback for everytime a frame is done rendering, and how long it took to render it, etc

import c4d
import os,time,_thread, datetime

def isRendering(time,os) :

    RenderData = doc.GetActiveRenderData()
    FrameStart = RenderData[c4d.RDATA_FRAMEFROM].GetFrame(doc.GetFps())
    FrameEnd = RenderData[c4d.RDATA_FRAMETO].GetFrame(doc.GetFps())

    while c4d.CheckIsRunning ( c4d.CHECKISRUNNING_EXTERNALRENDERING ) :
        #print(c4d.RENDERRESULT_OK)
        time.sleep(1)

    print("render complete.")


def main() :

    c4d.CallCommand(12099) #Render To PV

    if c4d.CheckIsRunning ( c4d.CHECKISRUNNING_EXTERNALRENDERING ) :
        _thread.start_new(isRendering,(time,os))

if __name__=='__main__':
  main()

Hi @NibblingFeet sorry for the late reply, as said everything you need is provided by RenderDocumen callbacks.

Find bellow a code that start the render and print something to the console for each frame rendered.

import c4d


def PythonWriteCallBack(mode, bmp, fn, mainImage, frame, renderTime, streamnum, streamname):
    """Function passed in RenderDocument.
    It will be called automatically by Cinema 4D when the file rendered file should be saved.

    Args:
        mode (c4d.WRITEMODE): The write mode.
        bmp (c4d.bitmaps.BaseBitmap): The bitmap written to.
        fn (str): The path where the file should be saved.
        mainImage (bool): True for main image, otherwise False.
        frame (int): The frame number.
        renderTime (int): The bitmap frame time.
        streamnum (int): The stream number.
        streamname (streamname: str): The stream name.
    """
    if not fn:
        return

    if frame == -1:
        frame = 0

    print(f"ProgressWriteHook called [Frame: {frame} / Render Time: {renderTime}, Name: {fn}]")


def main():
    rd = doc.GetActiveRenderData()

    # Allocate a picture, that will receive the rendered picture.
    # In case of animation this one will be cloned for each frame of the animation
    # and this one will be used for the last frame. Therefor if you want to access the picture of each frame
    # you should do it through the ##wprog callback passed to RenderDocument
    bmp = c4d.bitmaps.MultipassBitmap(int(rd[c4d.RDATA_XRES]), int(rd[c4d.RDATA_YRES]), c4d.COLORMODE_RGB)

    # Renders the document
    if c4d.documents.RenderDocument(doc, rd.GetData(), bmp, c4d.RENDERFLAGS_EXTERNAL | c4d.RENDERFLAGS_OPEN_PICTUREVIEWER | c4d.RENDERFLAGS_CREATE_PICTUREVIEWER,
                                    wprog=PythonWriteCallBack) != c4d.RENDERRESULT_OK:
        raise RuntimeError("Failed to render the temporary document.")


if __name__ == "__main__":
    main()

Cheers,
Maxime.

Hi @m_adam thanks for the response. I did go through this but it doesn't seem to work for the following reasons:

  1. When I run the script everything gets frozen until the render is complete - I can't even see the progress of the renders as it goes through the frames
  2. Somehow progress callback doesn't work if I use an external engine - I am using Octane Renderer, so I'm assuming this documentation only applies for the internal render of C4D? I can see in the normal consol Octane is shooting out info about the renders including time and current frame etc - Is there a way to directly grab that information somehow?

Maybe I am looking at the wrong direction? Maybe I should be looking at Octane documentation and how to grab info from its terminal?

Apologies for the somewhat silly assumptions and questions - I am very new to all of this!

Thanks in advance

Sorry for the late reply

  1. In order to do that you will need to start a new thread, and you need to keep alive the thread as long as it execute, meaning you will need to store it in a global variable.
  2. Best way would be to reach octane directly as 3rd party are free to implement this as they want.

Cheers,
Maxime.