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