Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Message if (render-) frame changes

    Scheduled Pinned Locked Moved PYTHON Development
    2 Posts 0 Posters 370 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      On 22/10/2017 at 11:03, xxxxxxxx wrote:

      hi there...

      does anybody know if there is a message on a new frame when rendering?
      (goal is to change things in the scene for each frame while rendering)

      i'm also doing this from a python tag... so it should work there, too 🙂

      tx for any hints!

      ps... while i'm at it...
      would it be possible to manipulate the render process (renderdata?)
      to maybe not render each frame but only a selection. ie frame 1,5,7,10

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 23/10/2017 at 09:15, xxxxxxxx wrote:

        Hi,

        there is no message when rendering a new frame. Actually a tag plugin gets executed (Execute() called) on every change. So maybe here the problem is not so much being executed, but the wish to be executed only on this specific event?
        Then I'd suggest to store the last frame, when one was executed, either in the BaseContainer or in a member/global variable. Then you can compare against the current frame and execute only if changed.

        On the second question (actually we'd prefer to have different threads for different questions, as it greatly increases overview and "searchability" of the forum), well, I guess you already know you can edit RenderData (render settings), but the options for the rendered frames are limited and such an arbitrary selection of frames can not be rendered by a single RenderData.

        There are a whole bunch of options to work around this limitation, I'll just suggest two from the top of my head:

        a) Clone the RenderData for every frame you need to render. Then for example have a Take per RenderData and use the "Render All Takes to PV" command.

        b) Do it manually via a CommandData plugin. A skeleton which demonstrates asynchronous rendering is shown below. You'd still need to add a loop to render only those frames you want, the example only renders a single image.

        import c4d
        from c4d.threading import C4DThread
        from c4d import bitmaps, documents
          
          
        PLUGIN_ID =  <your unique plugin ID here>  # DON'T FORGET TO GET A UNIQUE ID
        PLUGIN_ID_MSGDATA = <your unique plugin ID here>  # DON'T FORGET TO GET A UNIQUE ID
        CUSTOM_ID_RENDER_FINISH = <your unique plugin ID here>  # DON'T FORGET TO GET A UNIQUE ID
          
          
        g_bmp = None
        g_thread = None
          
          
        # provide this thread with a cloned document and sz
        class RenderThread(C4DThread) :
          
            _docRender = None
          
            def Main(self) :
                global g_bmp
          
                rd = self._docRender.GetActiveRenderData().GetData()
          
                # Set frame to render
                rd[c4d.RDATA_FRAMESEQUENCE] = 0 # render manual frame sequence (from .. to)
                frameNumber = 0
                t = c4d.BaseTime(frameNumber, self._docRender.GetFps())
                rd[c4d.RDATA_FRAMEFROM] = t
                rd[c4d.RDATA_FRAMETO] = t
          
                #Initialize the bitmap with the result size
                #The resolution must match with the output size of the render settings
                xres = int(rd[c4d.RDATA_XRES])
                yres = int(rd[c4d.RDATA_YRES])
          
                g_bmp = bitmaps.BaseBitmap()
                g_bmp.Init(x = xres, y = yres, depth = 24)
            
                res = c4d.documents.RenderDocument(self._docRender, rd, g_bmp, c4d.RENDERFLAGS_NODOCUMENTCLONE | c4d.RENDERFLAGS_EXTERNAL, None)
                if res == c4d.RENDERRESULT_OK:
                    c4d.SpecialEventAdd(CUSTOM_ID_RENDER_FINISH) # Notify MessageData plugiin about successful render
          
          
        # As the thread renders asynchronously the command can not catch the end/success of the rendering.
        # Instead this MessageData receives a custom finish message and shows the rendered image in PV.
        class RenderFinishMessage(c4d.plugins.MessageData) :
          
            def CoreMessage(self, id, bc) :
                if id == CUSTOM_ID_RENDER_FINISH:
                    if g_bmp:
                        bitmaps.ShowBitmap(g_bmp)
                return True
          
          
        # Command sets data in thread and then starts the thread
        class RenderToPVCommandData(c4d.plugins.CommandData) :
          
            def Execute(self, doc) :
                global g_thread
          
                # ToDo: take care of already running thread
                g_thread = RenderThread()
                g_thread._docRender = doc.GetClone(c4d.COPYFLAGS_0) # ToDo: rather have setter function in RenderThread
                g_thread.Start()
                return True
          
          
        if __name__ == "__main__":
            c4d.plugins.RegisterCommandPlugin(id = PLUGIN_ID, str = "Py-Render to PV",
                                              help = "Render asynchronously.",info = 0,
                                              dat = RenderToPVCommandData(), icon = None)
            c4d.plugins.RegisterMessagePlugin(id=PLUGIN_ID_MSGDATA, str="", info=0, dat=RenderFinishMessage())
        
        1 Reply Last reply Reply Quote 0
        • First post
          Last post