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

    Safeframe to Render Resolution [SOLVED]

    Scheduled Pinned Locked Moved PYTHON Development
    7 Posts 0 Posters 585 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 13/10/2016 at 05:17, xxxxxxxx wrote:

      Hi there,

      comparing the safeframe aspect with the renderaspect by using the BaseDraw( ).GetSafeFrame() function in the way described later , always gives me wrong results.

      How should we calculate the resulting resolution from e.g. mouse recognition data; or the other way round,
      which calculation/values uses the "copy from IRR" button??

      Can anybody help me solving it, please?
      best wishes
      Martin

        
      import c4d,math  
        
      def main() :  
        # compare BaseDrawResolution and RenderResolution  
        doc = c4d.documents.GetActiveDocument()  
        bd = doc.GetActiveBaseDraw()  
        if bd is None:  
            return  
        rd = doc.GetActiveRenderData()  
        rdata = rd.GetData()  
        xren = rdata[c4d.RDATA_XRES]  
        yren = rdata[c4d.RDATA_YRES]  
        
        rendersafe = bd.GetSafeFrame()#safe frame  
        xsafe = float(rendersafe["cr"]) - float(rendersafe["cl"])   
        ysafe = float(rendersafe["cb"]) - float(rendersafe["ct"])  
          
        print xsafe, "xsafe"  
        print ysafe, "ysafe"  
        print xsafe/ysafe, "aspectSAFE"   
        print rdata[c4d.RDATA_FILMASPECT], "aspectRENDER"  
        print xren/xsafe, yren/ysafe,"SAFEtoREN"  
          
      if __name__=='__main__':  
        main()  
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 14/10/2016 at 01:27, xxxxxxxx wrote:

        Hello,

        I don't fully understand what you are trying to do here. But I'm wondering why your are comparing the safe frame dimensions of a BaseDraw with the render settings. The safe frame of a BaseDraw window depends on the resolution of that BaseDraw. That resolution is obtained with GetFrame().

        best wishes,
        Sebastian

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

          On 14/10/2016 at 06:04, xxxxxxxx wrote:

          Hi Sebastian,

          let´s kepp it simple and say: I want to do the calculation the "copy from IRR" button does.
          If I do my calculation on the dimension(let´s say x) of a bas draw where no safeframe is shown,
          the calculation is correct.
          If I try the same with the y-dimension subtracting the safeframe delta from the drawviewframe the calculation is sometimes right sometimes not.

          Thanks for your help
          Martin

            
          import c4d,math  
            
          def main() :  
            # compare BaseDrawResolution and RenderResolution  
            doc = c4d.documents.GetActiveDocument()  
            bd = doc.GetActiveBaseDraw()  
            if bd is None:  
                return  
            rd = doc.GetActiveRenderData()  
            rdata = rd.GetData()  
            xren = rdata[c4d.RDATA_XRES]  
            yren = rdata[c4d.RDATA_YRES]  
            
            rendersafe = bd.GetSafeFrame()#safe frame  
            xsafe = float(rendersafe["cr"]) - float(rendersafe["cl"])   
            ysafe = float(rendersafe["cb"]) - float(rendersafe["ct"])  
              
            # get base view  
            viewsize = bd.GetFrame()  
            xview = viewsize ["cr"]   
            yview = viewsize ["cb"]  
            print xview, "xview"  
            print yview, "yview"  
              
            # get data  
            bc = bd.GetDataInstance()  
            if bc is None:  
                return  
            
            # get subcontainer of IRR and it´s data  
            subcontainer = bc.GetContainer(430000020)        
            xleft =  xview*subcontainer.GetReal(0)#or right FLIP!!  
            xright = xview*subcontainer.GetReal(2)#or left FLIP!!  
            ytop =  yview *subcontainer.GetReal(1)#or bot FLIP!!  
            ybot =  yview*subcontainer.GetReal(3)#or top FLIP!!  
              
            # check and swap of IRR values  
            if xright<xleft:  
                xleft,xright = xright,xleft         
            if ybot<ytop:  
                ytop,ybot = ybot,ytop  
                  
              
            print xleft, xright, ytop, ybot, "Res of irr"  
            xIRR = abs(subcontainer.GetReal(0)-subcontainer.GetReal(2))*xview  
            yIRR = abs(subcontainer.GetReal(1)-subcontainer.GetReal(3))*yview  
            print xIRR, yIRR, "IRR drawsize"  
              
            # try several conversions  
            xdelta=((xsafe-xview))  
            ydelta=((ysafe-yview))  
            print xdelta,ydelta,"deltas"  
            
              
            # decide which factor view to rendersize  
            factor = 0.0  
            if xdelta==0.0:  
                factor = xren/xsafe         
            else:  
                factor = yren/ysafe      
            print factor, "factor on view"     
            xsaview = xsafe/xview  
            ysaview = ysafe/yview  
            print ysaview ,"view to safe", xsaview  
            
                  
            #find IRR in renderspace  
            'test x without safeframe area'  
            'ok so far'  
            print math.floor(xleft*factor), "left"  
            print xren-math.ceil(xright*factor), "right"  
              
            'here wrong results with the safeframe'  
            print round((ytop-rendersafe["ct"])*factor), "top"  
              
              
            
          if __name__=='__main__':  
            main()  
            
          
          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 14/10/2016 at 14:17, xxxxxxxx wrote:

            again...
            Even if I only use the basedraw´s frame resolution and the renderaspect,
            I´ll only somtimes get the right values.
            What is c4d´s convention of rounding those values or how they are calculatedConfused

            thanks in advance
            martin

              
            import c4d,math  
              
            def main() :  
              # compare BaseDrawResolution and RenderResolution  
              doc = c4d.documents.GetActiveDocument()  
              bd = doc.GetActiveBaseDraw()  
              if bd is None:  
                  return  
              
              # get base view  
              viewsize = bd.GetFrame()  
              xview = viewsize ["cr"]   
              yview = viewsize ["cb"]  
                
              # get data  
              bc = bd.GetDataInstance()  
              if bc is None:  
                  return  
              
              # get subcontainer of IRR and it´s data  
              subcontainer = bc.GetContainer(430000020)        
              xleft =  xview*subcontainer.GetReal(0)#or right FLIP!!  
              xright = xview*subcontainer.GetReal(2)#or left FLIP!!  
              ytop =  yview *subcontainer.GetReal(1)#or bot FLIP!!  
              ybot =  yview*subcontainer.GetReal(3)#or top FLIP!!  
                
              # check and swap of IRR values  
              if xright<xleft:  
                  xleft,xright = xright,xleft         
              if ybot<ytop:  
                  ytop,ybot = ybot,ytop  
                
              # decide which factor and aspect, view to rendersize  
              rd = doc.GetActiveRenderData()  
              rdata = rd.GetData()  
              xren = rdata[c4d.RDATA_XRES]  
              yren = rdata[c4d.RDATA_YRES]  
              aspectren = rdata[c4d.RDATA_FILMASPECT]  
              aspectview = float(xview)/float(yview)  
                
              factor = 0.0  
              safex = 0.0  
              safey = 0.0  
              if aspectren>=aspectview:  
                  factor = xren/xview   
                  safey = (yview-xview/aspectren)*0.5  
              else:  
                  factor = yren/yview      
                  safex = (xview-yview*aspectren)*0.5  
              
              # get IRR values in renderspace  
              left = max(math.floor((xleft-safex)*factor), 0)   
              right = max(xren-math.ceil((xright-safex)*factor),0)  
              top = max(math.floor((ytop-safey)*factor),0)  
              bot = max(yren-math.ceil((ybot-safey)*factor),0)  
                
              # compare with irr button  
              print left,"left"  
              print right, "right"  
              print top, "top"  
              print bot, "bot"  
              
            if __name__=='__main__':  
              main()  
            
            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 17/10/2016 at 04:28, xxxxxxxx wrote:

              Hello,

              inside the "Copy from IRR" functionality there is a lot of casting, adding and scaling happening. I tried to recreate the handling of the width in Python:

                
                bd = doc.GetActiveBaseDraw()  
                if bd is None:  
                    return  
                
                viewsize = bd.GetFrame()  
                 
                cr =  viewsize['cr']  
                cl =  viewsize['cl']  
                w = (cr - cl) + 1  
                    
                bc = bd.GetDataInstance()  
                if bc is None:  
                    return  
                  
                subcontainer = bc.GetContainer(430000020)   
                  
                x1 = subcontainer.GetFloat(0)  
                x2 = subcontainer.GetFloat(2)  
                  
                rendersafe = bd.GetSafeFrame()  
                mr = rendersafe["cr"]  
                ml = rendersafe["cl"]  
                  
                rd = doc.GetActiveRenderData()  
                rdata = rd.GetData()  
                xres = rdata[c4d.RDATA_XRES]  
                    
                  
                scale = float(xres) / float(mr - ml + 1)  
                left = int((x1 * w + cl - ml) * scale)  
                right = int(xres -(x2 * w + cl - ml) * scale)  
                  
                print(left)  
                print(right)  
              

              best wishes,
              Sebastian

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

                On 17/10/2016 at 11:43, xxxxxxxx wrote:

                Hi Sebastian,

                I see, adding one pixel has it´s benefits e.g. avoiding divisions by zero.
                But it seem a bit odd to me that even for the calculation of the y values the relation xsafe to xrender resolution is used.

                Thanks for your time! That helped a lot !
                Martin

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

                  On 20/10/2016 at 01:14, xxxxxxxx wrote:

                  Hi there,

                  if somone tracks this topic....

                  Investigating further, the calculation behind the Irr button leads to wrong results.
                  Especially if the relation between viewport and desired render resolution get´s taller,
                  one wont be able to get pixels on the lower border.
                  I´ve sent a report to Maxon, so I guess this issue will be fixed in further releases and the presented solution will be obsolete. (state: Cinema 4D R18.028)

                  best wishes
                  Martin

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