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

    Want to create a DR render helper

    Scheduled Pinned Locked Moved PYTHON Development
    17 Posts 0 Posters 1.2k 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 07/11/2016 at 17:15, xxxxxxxx wrote:

      I have a desire to use Distributed Rendering of an image sequence using the existing Team Render setup.

      I attempted to setup something using Automator on OS X, but it is a little sporadic in success.

      What I'm trying to do:

      Have a python script (or plug) that reads the c4d.RDATA_FRAMEFROM and c4d.RDATA_FRAMETO.

      I'd then want to have it place the current time to the start frame, and kick off a Team Render for only that frame. When that frame is finished, it should increment up a step and repeat the process until all the frames in the frame range have been rendered.

      This will allow me to do image sequence renders using Team Render's great Distributed Render buckets.

      My script is getting hung up on the c4d.RDATA_FRAMEFROM

      That specific part of my code is:

      doc = c4d.documents.GetActiveDocument();
      rd = doc.GetActiveRenderData();
      startFrame = rd[c4d.RDATA_FRAMEFROM];

      print "START FRAME: %s" % startFrame;

      When I execut it I get this:

      START FRAME: <c4d.BaseTime object at 0x124b25120> (and that hex code changes each time I run it)

      What I need is a frame integer.

      Or perhaps one of you awesome python guys can point me in a smarter direction altogether?

      Thanks in advance for any help you can provide

      Cheers

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

        On 07/11/2016 at 18:16, xxxxxxxx wrote:

        Get:

            fps = doc.GetFps()  
          rd = doc.GetActiveRenderData()  
          start = rd[c4d.RDATA_FRAMEFROM].GetFrame(fps)  
          print start
        

        Set:

            fps = doc.GetFps()  
          rd = doc.GetActiveRenderData()  
          frame = 5  #<---Change as desired  
          start = rd[c4d.RDATA_FRAMEFROM]= c4d.BaseTime(frame, fps)
        

        -ScottA

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

          On 08/11/2016 at 07:00, xxxxxxxx wrote:

          Ah ok. Thanks!

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

            On 08/11/2016 at 09:32, xxxxxxxx wrote:

            Hi,

            thanks, to Scott for providing the perfect solution.
            Just want to add some additional information here (even though Scott's snippets explain it already) :
            The data stored under ID RDATA_FRAMEFROM is of type BaseTime. Our C++ documentation provides some more information on this in the BaseTime manual.

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

              On 08/11/2016 at 10:46, xxxxxxxx wrote:

              Thank you Andreas! I'm very much new at this, but I know the basics.

              I seem to be struggling with errors involving document versus basetime, etc.

              And I'm confused why there is NetRenderService.StopRendering, but not StartRendering.

              I probably expect it to be too simple.

              I could really use some help getting the basics of this working properly.   I don't want it to run outside of C4D. I just want to be able to basically control picture viewer rendering with an open document, with the goal being:

              Using Team Render to picture viewer to do bucket rendering on an image sequence (animation) by tricking it into rendering successive single image renders.

              Thanks for your helpful nudges. I'll continue to work at it!

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

                On 08/11/2016 at 10:51, xxxxxxxx wrote:

                Maybe I should ask a more directed question:

                Can I achieve what I'm trying to achieve through python?

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

                  On 08/11/2016 at 10:59, xxxxxxxx wrote:

                  I have it all working so far, except the actual call to render the active document using teamrender to picture viewer

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

                    On 08/11/2016 at 11:21, xxxxxxxx wrote:

                    I'm using RENDERFLAGS_EXTERNAL, and it is working...but how do I specify to do "Team Render to Picture Viewer"

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

                      On 08/11/2016 at 12:07, xxxxxxxx wrote:

                      I'm still using R13 so I don't have TR to test this myself.
                      What happens if you use: RENDERFLAGS_NET

                      -ScottA

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

                        On 08/11/2016 at 12:43, xxxxxxxx wrote:

                        Thanks for you help!

                        Hmmm....well that didn't throw an error. However, in the Team Render Machines window, the status of the clients does not change.

                        Also, I decided to move my iterative code into a function that could be called and checked as we go, and I'm getting a scope error. I'm guessing I need to declare my variables in a more global way?

                        Here's all my code thus far:

                        import c4d
                        import os

                        from c4d import bitmaps, documents, gui

                        def main() :
                            # Get Basic Vairables

                        doc = c4d.documents.GetActiveDocument();
                            fps = doc.GetFps();
                            rd = doc.GetActiveRenderData().GetData();
                            xres = int(rd[c4d.RDATA_XRES]);
                            yres = int(rd[c4d.RDATA_YRES]);
                            bmp = bitmaps.BaseBitmap();
                            bmp.Init(x=xres, y=yres, depth=24);
                            startFrame = rd[c4d.RDATA_FRAMEFROM].GetFrame(fps);
                            endFrame = rd[c4d.RDATA_FRAMETO].GetFrame(fps);
                            thisFrame = startFrame;
                            
                            #set current frame for render
                            def setRenderFrame() :
                                rd[c4d.RDATA_FRAMEFROM] = c4d.BaseTime(thisFrame,fps);
                                rd[c4d.RDATA_FRAMETO] = c4d.BaseTime(thisFrame, fps);
                            
                           
                            def doRender() :
                                res = documents.RenderDocument(doc,rd, bmp, c4d.RENDERFLAGS_NET);
                                if res==c4d.RENDERRESULT_OK:
                                    bitmaps.ShowBitmap(bmp);
                                    thisFrame +=1;
                                    if thisFrame > endFrame:
                                       return
                                    setRenderFrame();
                                    doRender();
                               
                               
                            doRender();
                            
                            c4d.EventAdd();
                            
                        if __name__=='__main__':
                            main();

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

                          On 08/11/2016 at 12:45, xxxxxxxx wrote:

                          The error:

                          Traceback (most recent call last) :
                          File "'scriptmanager'", line 44, in <module>
                          File "'scriptmanager'", line 39, in main
                          File "'scriptmanager'", line 32, in doRender
                          UnboundLocalError: local variable 'thisFrame' referenced before assignment

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

                            On 08/11/2016 at 13:33, xxxxxxxx wrote:

                            I can't help you with the Team Render stuff. But I can show you how to write your code so it runs.
                            Note the changes.
                            When posting code. Please use this type of forum code: "["code"]" your code here "["/code"]"
                            Without the quotes.

                            import c4d  
                            import os  
                            from c4d import bitmaps, documents, gui  
                              
                            def setRenderFrame(rd, thisFrame, endFrame) :  
                              fps = doc.GetFps()  
                              rd[c4d.RDATA_FRAMEFROM] = c4d.BaseTime(thisFrame,fps)  
                              rd[c4d.RDATA_FRAMETO] = c4d.BaseTime(endFrame, fps)   
                              
                            def doRender(doc, rd, bmp, thisFrame, endFrame) :  
                              res = documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)  
                              if res==c4d.RENDERRESULT_OK:  
                                  bitmaps.ShowBitmap(bmp)  
                                  thisFrame +=1  
                                  if thisFrame > endFrame: return  
                                  setRenderFrame(rd, thisFrame, endFrame)  
                              
                            def main() :      
                              
                              doc = c4d.documents.GetActiveDocument()  
                              fps = doc.GetFps()  
                              rd = doc.GetActiveRenderData().GetData()  
                              xres = int(rd[c4d.RDATA_XRES])  
                              yres = int(rd[c4d.RDATA_YRES])  
                              bmp = bitmaps.BaseBitmap()  
                              bmp.Init(x=xres, y=yres, depth=24)  
                              startFrame = rd[c4d.RDATA_FRAMEFROM].GetFrame(fps)  
                              endFrame = rd[c4d.RDATA_FRAMETO].GetFrame(fps)  
                              thisFrame = startFrame     
                                
                              for i in xrange(startFrame, endFrame - startFrame) :  
                                  doRender(doc, rd, bmp, thisFrame, endFrame)  
                                
                              c4d.EventAdd()  
                                
                            if __name__=='__main__':  
                              main()
                            

                            Someone else who has TR will need to help you with that part.

                            -ScottA

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

                              On 08/11/2016 at 14:03, xxxxxxxx wrote:

                              You are so helpful. Thank you for taking the time.

                              I've run your version of the script and I'm getting the following NameError:

                              Traceback (most recent call last) :
                              File "'scriptmanager'", line 36, in <module>
                              File "'scriptmanager'", line 31, in main
                              File "'scriptmanager'", line 11, in doRender
                              NameError: global name 'setRenderFrame' is not defined

                              Looks like it's trying to parse the definition of setRenderFrame() before it is defined.

                              I've never been great at wrapping my brain around scope issues like this. ha.

                              Thanks for all your help thus far.

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

                                On 08/11/2016 at 14:23, xxxxxxxx wrote:

                                OK I've tweaked things a little and the iteration is working within the variables...however, it is rendering the same frame over and over, and for some reason now it is not naming them appropriately. It keeps saving the same file over and over without iterating the filename, and doesn't appear to actually be stepping through the timeline either.

                                import c4d   
                                import os   
                                from c4d import bitmaps, documents, gui   
                                  
                                  
                                  
                                def main() :       
                                  
                                    doc = c4d.documents.GetActiveDocument()   
                                    fps = doc.GetFps()   
                                    rd = doc.GetActiveRenderData().GetData()   
                                    xres = int(rd[c4d.RDATA_XRES])   
                                    yres = int(rd[c4d.RDATA_YRES])   
                                    bmp = bitmaps.BaseBitmap()   
                                    bmp.Init(x=xres, y=yres, depth=16)   
                                    startFrame = rd[c4d.RDATA_FRAMEFROM].GetFrame(fps)   
                                    endFrame = rd[c4d.RDATA_FRAMETO].GetFrame(fps)   
                                    thisFrame = startFrame   
                                    print "thisFrame: %s" % thisFrame   
                                    print "endFrame: %s" % endFrame   
                                       
                                    #set current frame for render   
                                  
                                          
                                    def doRender(doc, rd, bmp, thisFrame, endFrame) :   
                                        rd[c4d.RDATA_FRAMEFROM] = c4d.BaseTime(thisFrame,fps)   
                                        rd[c4d.RDATA_FRAMETO] = c4d.BaseTime(thisFrame, fps)   
                                        res = documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_NET)   
                                        if res==c4d.RENDERRESULT_OK:   
                                            bitmaps.ShowBitmap(bmp)   
                                            thisFrame +=1   
                                            if thisFrame > endFrame: return   
                                            print "thisFrame: %s" % thisFrame   
                                            doRender(doc, rd, bmp, thisFrame, endFrame)   
                                  
                                    doRender(doc, rd, bmp, thisFrame, endFrame)   
                                       
                                    c4d.EventAdd()   
                                       
                                if __name__=='__main__':   
                                    main()
                                
                                1 Reply Last reply Reply Quote 0
                                • H Offline
                                  Helper
                                  last edited by

                                  On 08/11/2016 at 14:56, xxxxxxxx wrote:

                                  Doh! I missed that one. Sorry about that. I changed it.
                                  Those custom methods that you are creating using "def" don't go inside of the def main() : code block.
                                  They should be placed before, or after, the main code block. Then you call them as needed.
                                  Also. A script runs once then stops.
                                  So if you want to execute code more than once. You'll need to use a loop where the frame value increments every time the loop iterates.

                                  -ScottA

                                  Edit-
                                  After changing the code. I'm getting the feeling that you're still not going to get the results you are looking for. So take a look at this code example. It might help answer your questions better than trying to edit your code.
                                  Feel free to edit it to fit your needs.

                                  #This script rotates an object by a set amount. Then renders it to the path set in the render settings  
                                  #NOTE: The frame Range render setting in "Output" should be set to "Current Frame"  
                                  #The script will change the file name each time a new image is rendered to save the multiple images  
                                    
                                  import c4d, math  
                                  from c4d import bitmaps, documents, utils  
                                    
                                  ROTANGLE = 30.0  
                                  ROTVEC = c4d.Vector(utils.Rad(ROTANGLE), 0, 0)  
                                    
                                  def main() :  
                                    
                                    if op:  
                                        maxstep = int(math.floor(360.0 / ROTANGLE))  
                                        rd = doc.GetActiveRenderData().GetData()    #Gets the render settings  
                                        xres = int(rd[c4d.RDATA_XRES])              #Gets the X size value from the render settings  
                                        yres = int(rd[c4d.RDATA_YRES])              #Gets the Y size value from the render settings  
                                        fn = rd[c4d.RDATA_PATH]                     #Gets the file path from the render settings  
                                    
                                        bmp = bitmaps.BaseBitmap()                  #Create an instance of the bitmap class  
                                        bmp.Init(x=xres, y=yres, depth=24)          #Initialize it using the render settings  
                                    
                                        for i in xrange(maxstep) :  
                                            c4d.StatusSetSpin()  
                                            c4d.StatusSetText('Rendering image {0} of {1}.'.format(i, maxstep))  
                                    
                                            rd[c4d.RDATA_PATH] = '{0}_{1}'.format(fn, i)  #Adds a _SomeNumber to the end of the file path  
                                            filename = str(rd[c4d.RDATA_PATH])  
                                            result = documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)  
                                            bmp.Save(filename + ".png", c4d.FILTER_PNG, c4d.BaseContainer(), c4d.SAVEBIT_ALPHA)  
                                    
                                            if result != c4d.RENDERRESULT_OK: break  #Error handling  
                                            else: bitmaps.ShowBitmap(bmp)  
                                    
                                            op.SetMg(op.GetMg() * utils.HPBToMatrix(ROTVEC))  #Rotate the active object by it's matrix  
                                    
                                    c4d.StatusClear()  
                                    c4d.EventAdd()  
                                      
                                  if __name__=='__main__':  
                                    main()
                                  

                                  -ScottA

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

                                    On 08/11/2016 at 18:08, xxxxxxxx wrote:

                                    Good stuff. Thanks.

                                    I'll chip away at it some more.

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

                                      On 08/11/2016 at 18:28, xxxxxxxx wrote:

                                      NP.
                                      Just be aware that your custom methods are a bit strange. I fixed them so that they would work by pulling them out of the main code block. But the setRenderFrame() method really doesn't make much sense to be used that way.
                                      I recommend not using any external methods like This. Or maybe just use one for all of the rendering code.
                                      Using custom methods and dealing with their parameters just adds more complexity to the code.
                                      That's just a suggestion though. Do whatever you want.

                                      That's all the help I can be with this. I can't help with the Team Render stuff.

                                      GoodLuck,
                                      -ScottA

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post