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

    Cannot write specific values to UVWTag

    Cinema 4D SDK
    r20 r21 c++ python
    3
    6
    637
    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.
    • C4DSC
      C4DS
      last edited by C4DS

      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.

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

        This post is deleted!
        1 Reply Last reply Reply Quote 0
        • r_giganteR
          r_gigante
          last edited by

          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

          C4DSC 2 Replies Last reply Reply Quote 0
          • C4DSC
            C4DS @r_gigante
            last edited by

            @r_gigante
            Bummer ... But thanks for confirming!

            1 Reply Last reply Reply Quote 0
            • C4DSC
              C4DS @r_gigante
              last edited by

              @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?

              1 Reply Last reply Reply Quote 0
              • r_giganteR
                r_gigante
                last edited by

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

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