Cannot write specific values to UVWTag



  • Hi,
    I am trying to create precise UV coordinates, but am not able to store the wanted UV values.

    Say I create a single polygon object (primitive plane with subdivision 1x1, make editable). And want to map a texture bitmap of 1920x1080.
    I then use following script to modify the plane's UV to fit exactly to the top 72 pixels of my bitmap.
    The bottom UV coordinates should be 72 / 1080 = 0.06666666...

    import c4d
    from c4d import gui
    
    def readUV(uvwtag):
        for i in xrange(uvwtag.GetDataCount()):
            uvwdict = uvwtag.GetSlow(i)
            uvwA = uvwdict["a"]
            uvwB = uvwdict["b"]
            uvwC = uvwdict["c"]
            uvwD = uvwdict["d"]
            print "read UV", i, ":"
            print " A: %.15f %.15f" % (uvwA.x, uvwA.y)
            print " B: %.15f %.15f" % (uvwB.x, uvwB.y)
            print " C: %.15f %.15f" % (uvwC.x, uvwC.y)
            print " D: %.15f %.15f" % (uvwD.x, uvwD.y)
        return
    
    # Main function
    def main():
        # reads the UVs of the object
        if op == None:
            print "No active object!"
            return
        if not op.CheckType(c4d.Opolygon):
            print "Active object is not Opolygon"
            return
    
        # get the UVW tag of the object
        uvwtag = op.GetTag(c4d.Tuvw)
        if uvwtag == None:
            print "Active object has no UVW tag"
            return
    
        readUV(uvwtag)
    
        # write UVs
        uvwA = c4d.Vector(0.0, 0.0, 0.0)
        uvwB = c4d.Vector(1.0, 0.0, 0.0)
        uvwC = c4d.Vector(1.0, 72.0 / 1080.0, 0.0)
        uvwD = c4d.Vector(0.0, 72.0 / 1080.0, 0.0)
        print "write UV"
        print " A: %.15f %.15f" % (uvwA.x, uvwA.y)
        print " B: %.15f %.15f" % (uvwB.x, uvwB.y)
        print " C: %.15f %.15f" % (uvwC.x, uvwC.y)
        print " D: %.15f %.15f" % (uvwD.x, uvwD.y)
        uvwtag.SetSlow(0, uvwA, uvwB, uvwC, uvwD)
    
        readUV(uvwtag)
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    This is the result I get:

    read UV 0 :
     A: 0.000000000000000 1.000000000000000
     B: 0.000000000000000 0.000000000000000
     C: 1.000000000000000 0.000000000000000
     D: 1.000000000000000 1.000000000000000
    write UV
     A: 0.000000000000000 0.000000000000000
     B: 1.000000000000000 0.000000000000000
     C: 1.000000000000000 0.066666666666667
     D: 0.000000000000000 0.066666666666667
    read UV 0 :
     A: 0.000000000000000 0.000000000000000
     B: 1.000000000000000 0.000000000000000
     C: 1.000000000000000 0.066666662693024
     D: 0.000000000000000 0.066666662693024
    

    The values read after writing are close, but not what they are supposed to be. Why?
    I know the problem with floating point representation.
    But since the wanted value can be hold in a variable and printed out, I would expect this value to be able to be written into the UVWtag ... and read back. But apparently this is not the case.

    I had encountered this issue within a C++ plugin, and tried this simple script just to point out the issue.

    Is this a bug, a limitation, ... something else?
    I know that for most users a UV pixel coordinate of 71.999999 or 72.0 would not make a big difference, but for some users sending this information to a LED processor it apparently is.



  • This post is deleted!


  • Hi @C4DS, thanks for reaching out us.

    With regard to your issue, I confirm that, by design, the values stored in UVWTag are rounded to 8 significant digits.

    Best, R



  • @r_gigante
    Bummer ... But thanks for confirming!



  • @r_gigante
    Just a quick question about this. Is the truncation the result of using a Float32 type, or is there another technique used to limit to the 8 significant digits?



  • It's actually due to a lower number of bits used to store the floating value.