Safeframe to Render Resolution [SOLVED]



  • 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()  
    


  • 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



  • 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()  
      
    


  • 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 calculated

    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()  
    


  • 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



  • 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



  • 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


Log in to reply