Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Cutome Render Token do not update Filename each Frame

    Cinema 4D SDK
    4
    11
    1.3k
    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.
    • N
      nason
      last edited by Manuel

      Hello,

      I switched from R21 to the new C4D R25.010 and trying to get my projects to work.
      Unfortunately my Xpresso Setup to update filename each frame during rendering animation don´t work. I tried to solve the problem with custome render tokens like the token $frame. This one work as a charm. I wrote this little skript but my filename don´t update. May someon of your guys can give me a hint? I found a post with take System but my problem seams a bit differnt.

      I searce for the obj ">>>Listcontrol<<<" and the UserData "Dateiname_Render" and return the value for the token:

      import c4d
      
      def PythonUserdataToken(data):
          obj = data[0].SearchObject('>>>Listcontrol<<<')
          if obj == None:
              return "None"
          else:
              if obj.GetName() == '>>>Listcontrol<<<':
                  for ids, bc in obj.GetUserDataContainer():
                      if bc.GetString(c4d.DESC_NAME) == "Dateiname_Render":
                          filename = obj[c4d.ID_USERDATA, ids[1].id]
              return filename
      
      
      if __name__=="__main__":
          for registeredToken in c4d.modules.tokensystem.GetAllTokenEntries():
              if registeredToken.get("_token") in ["PythonUserdataToken"]:
                  exit()
      
          c4d.plugins.RegisterToken("PythonUserdataToken", "get userdata of Listcontrol", "UserData", PythonUserdataToken)
      

      My solution in R21 was a simple XPresso Setup with a python node. But her is the issue the same. Unfortunately the file name won't be actualized during rendering

      Screenshot 2021-11-04 171100.jpg

      import c4d, os
      
      def getframe():
          frame = doc.GetTime().GetFrame(doc.GetFps())
          return frame
      
      
      def main():
          global output
          filename = ['File_RENDER-0001','File_RENDER-0002','File_RENDER-0003']
          join = os.path.join(path,filename[getframe()])
          output = join
      

      I attached a test file. Hoping someone have some experience with this kind of setup and can help me

      So long! Christian

      R25_Output_Test.c4d

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        Hi,

        your xpresso is working for me using R25. I got in result 3 frames rendered with the frame number.

        About the token, special characters are not allowed in tokens. They are replaced by an underscore. The Path d:\render\temp will be changed to d__render_temp.

        # list of special character
        .     /  ?  <  >  \\  :  *  |  (  )  
        

        Otherwise it should work.

        One point, you are always returning filename, but if your object doesn't have a userdata called the right name, you should return "None".

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • N
          nason
          last edited by

          Hi Manuel,

          thank you for your quick reply.
          I prepared a new test scene according your hints and did some tests but my filename won't be updated. For some reason it don´t work. Maybe I have to work completely different.

          the new token code:

          import c4d
          
          def PythonUserdataToken(data):
              obj = data[0].SearchObject('Output')
              if obj == None:
                  return None
              else:
                  if obj.GetName() == 'Output':
                      for ids, bc in obj.GetUserDataContainer():
                          if bc.GetString(c4d.DESC_NAME) == "Filename":
                              filename = obj[c4d.ID_USERDATA, ids[1].id]
                              return filename
                          else:
                              return None
          
          
          if __name__=="__main__":
              for registeredToken in c4d.modules.tokensystem.GetAllTokenEntries():
                  if registeredToken.get("_token") in ["PythonUserdataToken"]:
                      exit()
          
              c4d.plugins.RegisterToken("PythonUserdataToken", "get userdata of Listcontrol", "UserData", PythonUserdataToken)
          

          maybe you can look again...

          Cheers,
          Christian

          1 Reply Last reply Reply Quote 0
          • N
            nason
            last edited by

            c4d-R25-token example.c4d

            1 Reply Last reply Reply Quote 0
            • ManuelM
              Manuel
              last edited by

              Hi,

              Sorry i wasn't clear. Your idea was to retrieve a data from a userdata and use it as a token. This works.
              Unfortunately, using specials characters is not allowed. As a path contain specials characters (: \ /), they will be removed.

              Your xpresso setup is working on my R25.

              MAXON SDK Specialist

              MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • N
                nason
                last edited by

                Hi Manuel,

                did you see the new testfile c4d-R25-token example.c4d without using XPresso and specials characters like 🙂 \ /)?
                I don't use any special characters any longer but nevertheless it don´t update the filenames. Each frame are named like the first on. In this example Red0000.tif, Red0001.tif, Red0002.tif
                The expected output should be Red0000.tif, Green0000.tif, Blue0000.tif ... possibly I misunderstood something or it's not possible to realize it like my thought. Maybe you could look over again?

                Much obliged Christian

                1 Reply Last reply Reply Quote 0
                • ferdinandF
                  ferdinand
                  last edited by ferdinand

                  Hello @nason,

                  you are right, this is not solved. I have reset the topic to 'unsolved'. I had a brief look at this, and the render token is indeed being interpreted incorrectly, all output files end on the state the user data were in when the rendering was launched, e.g., 'red'. I have modified your plugin example and Python Programing Tag a bit, which shows that this works in principle, but that there is something going wrong in the way Cinema 4D handles the render document (documents get cloned for rendering). @m_magalhaes is currently on vacation and will only come back on Monday. I unfortunately do not have the time to start a debugging session on that with Cinema 4D, you will have to wait for Manuel.

                  Thank you for your understanding,
                  Ferdinand

                  The plugin:

                  """
                  """
                  
                  import c4d
                  
                  
                  def PythonUserdataToken(data):
                      """
                      """
                      doc = data[0]
                      if not isinstance(doc, c4d.documents.BaseDocument):
                          print ("No document.")
                          return
                  
                      obj = doc.SearchObject("Output")
                      if obj is None:
                          print ("No object.")
                          return
                  
                      for descId, bc in obj.GetUserDataContainer():
                          if bc.GetString(c4d.DESC_NAME) == "Filename":
                              filename = obj[c4d.ID_USERDATA, descId[1].id]
                              print ("Resolved Token:", filename)
                              return filename
                  
                      print ("Fail.")
                  
                  
                  if __name__ == "__main__":
                      doRegister = True
                      for registeredToken in c4d.modules.tokensystem.GetAllTokenEntries():
                          if registeredToken.get("_token") == "PythonUserdataToken":
                              doRegister = False
                  
                      if doRegister:
                          c4d.plugins.RegisterToken("PythonUserdataToken",
                                                    "PythonUserdataToken",
                                                    "UserData",
                                                    PythonUserdataToken)
                  
                  

                  The tag:

                  import c4d
                  
                  def main():
                      obj = op.GetObject()
                      doc = op.GetDocument()
                      frame = doc.GetTime().GetFrame(doc.GetFps())
                      filename = ['Red','Green','Blue', 'Yellow']
                      obj[c4d.ID_USERDATA, 1] = filename[frame]
                      print (filename[frame])
                  

                  Example output when starting a render (which does not necessarily have to be in order of execution due to threading):

                  Set name: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Set name: Red
                  Set name: Red
                  Set name: Red
                  Resolved Token: Red
                  Resolved Token: Red
                  Resolved Token: Red
                  Resolved Token: Red
                  Resolved Token: Red
                  Set name: Green
                  Set name: Green
                  Set name: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Resolved Token: Green
                  Set name: Blue
                  Set name: Blue
                  Set name: Blue
                  Resolved Token: Blue
                  

                  MAXON SDK Specialist
                  developers.maxon.net

                  1 Reply Last reply Reply Quote 0
                  • N
                    nason
                    last edited by

                    Hello Ferdinand,

                    thank you for answering me and deal with the topic. It's true it isn't solved yet. The console output is quite interesting. I'll waiting for Manuel and hopefully he has an idea or having some time for debugging. After his vacation he'll build up new energy.

                    Cheers and many thanks,
                    Christian

                    1 Reply Last reply Reply Quote 0
                    • ManuelM
                      Manuel
                      last edited by Manuel

                      Hi,

                      To "fix" that, you can use the field data[4] to check if the frame number is set or not.

                      the problem is that the frame will still have a number after the name....

                      def PythonUserdataToken(data):
                          if data[4] == c4d.NOTOK:
                              return None 
                      
                          obj = data[0].SearchObject('Output')
                          if obj == None:
                              return None
                          else:
                              if obj.GetName() == 'Output':
                                  for ids, bc in obj.GetUserDataContainer():
                                      if bc.GetString(c4d.DESC_NAME) == "Filename":
                                          filename = obj[c4d.ID_USERDATA, ids[1].id]
                                          print (filename)
                                          return filename
                                      else:
                                          return None
                      
                      
                      if __name__=="__main__":
                          for registeredToken in c4d.modules.tokensystem.GetAllTokenEntries():
                              if registeredToken.get("_token") in ["PythonUserdataToken"]:
                                  exit()
                      
                          c4d.plugins.RegisterToken("PythonUserdataToken", "get userdata of Listcontrol", "UserData", PythonUserdataToken)
                      

                      I will probably need more time to check why you must do this.

                      But at least the filename are named correctly.

                      Cheers,
                      Manuel

                      MAXON SDK Specialist

                      MAXON Registered Developer

                      1 Reply Last reply Reply Quote 0
                      • N
                        nason
                        last edited by

                        Hi Manuel,

                        thanks a lot for helping me in this case. It's quite interesting for me and maybe also helpful for someone in this forum.
                        I'm absolutely satisfied with this solution, it works like a charm...

                        Greetings and best wishes
                        Christian

                        1 Reply Last reply Reply Quote 0
                        • ferdinandF
                          ferdinand
                          last edited by

                          Hello @nason,

                          without any further questions we will consider this topic as solved by Friday, December the 17th.

                          Thank you for your understanding,
                          Ferdinand

                          MAXON SDK Specialist
                          developers.maxon.net

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