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

    Refresh viewport after updating RenderData width and height

    Cinema 4D SDK
    windows python
    2
    8
    1.1k
    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.
    • S
      shivamist
      last edited by

      Hello,
      I have a script that is used to update the resolution of the active document. Recently we implemented a way to get overscan size data (VFX work) and i'm having trouble with refreshing the viewport.
      The issue resides in the fact that if you don't interact with the resolution slider or input something manually, the viewport show effectively the change with the Safe Frames but if there is an existing Background object/ Material with Frontal projection it will not update. Only an user interaction can help.

      Here are some code snippets that i used to showcase the issue and what i tried in terms of flags/update/dirty states :

      import c4d
      import random
      
      def main():
          doc = c4d.documents.GetActiveDocument()
          rd = doc.GetActiveRenderData()
          bd = doc.GetActiveBaseDraw()
          print(f"Render Data X_Res before : {rd[c4d.RDATA_XRES]}")
          print(f"Render Data Y_Res before : {rd[c4d.RDATA_YRES]}")
          print("-------------------------------------------------")
          xres = random.randint(0, 1920)
          yres = random.randint(0, 1080)
          rd[c4d.RDATA_XRES] = xres
          print(f"Render Data X_Res after : {rd[c4d.RDATA_XRES]}")
          rd[c4d.RDATA_YRES] = yres
          print(f"Render Data Y_Res after : {rd[c4d.RDATA_YRES]}")
          print("-------------------------------------------------")
      
          rd.Message(c4d.MSG_UPDATE)
          rd.SetDirty(c4d.DIRTYFLAGS_ALL)
          rd.SetDirty(c4d.DIRTYFLAGS_DATA)
          c4d.GeSyncMessage(c4d.EVMSG_UPDATEBASEDRAW)
      
          c4d.EventAdd()
      
      if __name__=='__main__':
          main()
      
      import c4d
      import random
      
      def main():
          doc = c4d.documents.GetActiveDocument()
          rd = doc.GetActiveRenderData()
          bd = doc.GetActiveBaseDraw()
      
          print(f"Render Data X_Res before: {rd[c4d.RDATA_XRES]}")
          print(f"Render Data Y_Res before: {rd[c4d.RDATA_YRES]}")
          print("-------------------------------------------------")
      
          xres = random.randint(1000, 1920)
          print(f"Random X_Res: {xres}")
          yres = random.randint(500, 1080)
          print(f"Random Y_Res: {yres}")
      
          # Set the new X and Y resolution using SetParameter
          rd.SetParameter(c4d.RDATA_XRES, xres, c4d.DESCFLAGS_SET_USERINTERACTION | c4d.DESCFLAGS_SET_FORCESET | c4d.DESCFLAGS_SET_INDRAG)
          rd.SetParameter(c4d.RDATA_YRES, yres, c4d.DESCFLAGS_SET_USERINTERACTION | c4d.DESCFLAGS_SET_FORCESET | c4d.DESCFLAGS_SET_INDRAG)
      
          print(f"Render Data X_Res after: {rd[c4d.RDATA_XRES]}")
          print(f"Render Data Y_Res after: {rd[c4d.RDATA_YRES]}")
          print("-------------------------------------------------")
          print("-------------------------------------------------")
      
          rd.Message(c4d.MSG_UPDATE)
          rd.SetDirty(c4d.DIRTYFLAGS_ALL)
          rd.SetDirty(c4d.DIRTYFLAGS_DATA)
          c4d.GeSyncMessage(c4d.EVMSG_UPDATEBASEDRAW)
          c4d.DrawViews(c4d.DRAWFLAGS_FORCEFULLREDRAW)
          c4d.EventAdd()
      
      if __name__=='__main__':
          main()
      
      

      Video showcasing the issue :

      Thanks for your help in advance 🙂
      C4D R2025.0.2

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

        Hello @shivamist,

        Welcome to the Maxon developers forum and its community, it is great to have you with us!

        Getting Started

        Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.

        • Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
        • Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
        • Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.

        It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions.

        About your First Question

        You did a great job in your first posting with providing all the information we need. But I still struggle a bit with understanding your core issue. Your claim is "The issue resides in the fact that if you don't interact with the resolution slider or input something manually, the viewport [do not] show [...] the change with the Safe Frames [...] if there is an existing Background object/ Material with Frontal projection [...]".

        I cannot reproduce this, nor does your video show that IMHO. Could you please elaborate and/or give us a scene file?

        Cheers,
        Ferdinand

        This is what I did:

        MAXON SDK Specialist
        developers.maxon.net

        S 1 Reply Last reply Reply Quote 0
        • S
          shivamist @ferdinand
          last edited by

          @ferdinand
          Here is the User action that fixes the viewport aspect ratio :

          The process is :

          • Launch script
          • Open "Render Settings" windows
          • Either click or drag the width/height box in the Output videopost

          Let me know if it's still unclear!

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

            What I more meant was: What would you consider incorrect in my video/when running your script? And while I write this I sort of have an epiphany 😄 So, you mean your script fails when you have a BG object and the user manually interacts with the Render settings to change a value and you then run your script?

            Because in my video and also yours, things are updating just fine I would say?

            MAXON SDK Specialist
            developers.maxon.net

            S 1 Reply Last reply Reply Quote 0
            • S
              shivamist @ferdinand
              last edited by

              @ferdinand
              What's incorrect is the aspect ratio of the Background object or anything material that is in a Frontal projection

              In the following screenshot you can see that on the border of the Safe Frames (turned them red for easier readability), the Background object stops at the border of the image
              364ab08d-9427-49c4-891f-d572f485c04b-image.png
              646d3eb2-32c6-4436-9ba2-8edb497220c8-image.png

              Here is the result after using the script with SetParameter() :
              ac63e480-bd3f-40fd-92aa-c18883c6c6cf-image.png
              e60af422-4c4f-4323-964d-e2a217a29125-image.png

              I hope the issue is clear now, the expected behavior would be that if the resolution changes, the background object should follow

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

                Yes, this clarifies things, thanks a lot. I will have a look (but only tomorrow since I am now already on my Linux machine).

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

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

                  Hey @shivamist,

                  After some poking in the code, I found out you were effectively writing to the wrong parameter, you should write to the virtual resolutions in this case, and also learnt something myself. Find my answer in detail below.

                  Cheers,
                  Ferdinand

                  Result

                  Code

                  """Changes the resolution of the active RenderData in the active Cinema 4D document so that 
                  resolution dependent scene elements such as a Background object are updated accordingly.
                  """
                  
                  import c4d
                  from random import randint
                  
                  # The active Cinema 4D document, you do not have to get that manually, it is automatically injected
                  # into most script modules by the Cinema 4D Python environment.
                  doc: c4d.documents.BaseDocument
                  
                  def main() -> None:
                      """Main logic of the script.
                      """
                      # Get the active render settings for the active document.
                      rData: c4d.documents.RenderData = doc.GetActiveRenderData()
                  
                      # I quite frankly myself never did really understood the difference between the XRES and
                      # XRES_VIRTUAL and YRES and YRES_VIRTUAL values until now. Just not to long ago I was joking
                      # that VIRTUAL values are for when you only hypothetically want to change the resolution ;) But
                      # after looking at some render data implementation code I now understand that you generally want
                      # to write virtual values. One can think of XRES and YRES as hard set values where Cinema 4D will
                      # not run extra logic to make sure that these values harmonize with the scene. XRES_VIRTUAL
                      # and YRES_VIRTUAL on the other hand are soft set values which come with such checks. So, unless 
                      # one wants to specifically bypass these checks, one should always write to the _VIRTUAL values.
                  
                      # One also does need indeed to set the DESCFLAGS_SET_USERINTERACTION flag here as 
                      # RenderData.SetParameter does check for this. This also means that one should not use 
                      # GeListNode.__setitem__ (the bracket operator) to set parameters on render data when one
                      # requires correct GUI updates (for pure rendering it does not matter as far as I can tell).
                      rData.SetParameter(c4d.RDATA_YRES_VIRTUAL, randint(1000, 1920), c4d.DESCFLAGS_SET_USERINTERACTION)
                      rData.SetParameter(c4d.RDATA_XRES_VIRTUAL, randint(500, 1080), c4d.DESCFLAGS_SET_USERINTERACTION)
                  
                      c4d.EventAdd()
                  
                  
                  if __name__=='__main__':
                      main()
                  

                  MAXON SDK Specialist
                  developers.maxon.net

                  1 Reply Last reply Reply Quote 0
                  • S
                    shivamist
                    last edited by

                    Hello @ferdinand ! Thanks for answer it is very clear, i will use virtual resolution from now on 🙂

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