Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    The forum rollback caused push notifications and recent user data to malfunction. The problem will fix itself naturally within the next days. See the topic Broken Push Notifications for a more in detail explanation. You can fix this yourself by forcibly clearing your browser cache (for most browsers: CTRL + F5).

    Getting UV coordinates from a plane

    Cinema 4D SDK
    python r21
    3
    9
    1.2k
    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.
    • R
      rui_mac
      last edited by

      uvs.png

      I have the coordinates of the vertexes P1, P2, P3 and P4 that define a rectangular rectangle.

      Those coordinates always define a regular rectangular area and the distortion of the plane defined by those coordinates, in the image above, is only due to perspective.

      I have those coordinates (P1, P2, P3 and P4) in world-space.
      I also have the coordinates of a point C, in world-space, that is not in the plane defined by P1, P2, P3 and P4 but is somewhere between the camera location and the plane defined by P1, P2, P3 and P4.

      I already have a way to calculate if, seen from the camera, C is inside the boundary defined by P1, P2, P3 and P4, by converting all the coordinates from world to screen-space and checking if the screen-space point C is inside the screen-space triangle P1 - P2 - P3 or triangle P1 - P3 - P4.
      So, if P1, P2, P3 and P4 always define a regular rectangle and if C in inside the area defined by P1, P2, P3 and P4 as they are seen from the camera, how can I calculate the uniform coordinates from 0,0 (at P2, for example) to 1,1 (at P4, for example) of the point C, if it was projected to the plane defined by P1, P2, P3 and P4?
      I mean, in the example image, I would need to get a result of around 0.8, 0.45 for the location of point C.

      If the point C screen projection was correspondent to the screen location of point P2, I should get 0,0
      If the point C screen projection was correspondent to the screen location of point P1, I should get 1,0
      If the point C screen projection was correspondent to the screen location of point P3, I should get 0,1
      If the point C screen projection was correspondent to the screen location of point P4, I should get 1,1

      Basically, I need to calculate the uniform coordinates from 0,0 to 1,1 inside a single regular plane that can be distorted in the view/render due to perspective, of the projection of a point that is between the camera and that plane, onto that plane. However, I don't have the plane as an object, I just have its vertex coordinates.
      I hope I explained it all clearly enough.
      Can anyone help? Thank you so much.

      i_mazlovI 1 Reply Last reply Reply Quote 0
      • R
        rui_mac
        last edited by

        Ok, I guess I managed to get a way to obtain UV coordinates from a screen space set of coordinates, using barycentric calculations.
        Lets see if I can make it work for the rest of the project.

        R 1 Reply Last reply Reply Quote 0
        • R
          rui_mac @rui_mac
          last edited by

          I managed to solve this by calculating the barycentric coordinates of the two triangles that form the quadrilateral shape. So, I can check if the point is inside the rectangle and also derive the uv coordinates from the calculated u,v and w components of the barycentric coordinates.

          def get_uvs(pw1,pw2,pw3,pw4):
              # quadrilateral is defined by pw1,pw2,pw3 and pw4 2d vectors, in screen-space
          
              vv = 1.0/(2*area(pw1,pw2,pw3)) * (pw1.y*pw3.x - pw1.x*pw3.y + (pw3.y-pw1.y) * p_uv.x + (pw1.x-pw3.x)*p_uv.y)
              ww = 1.0/(2*area(pw1,pw2,pw3)) * (pw1.x*pw2.y - pw1.y*pw2.x + (pw1.y-pw2.y) * p_uv.x + (pw2.x-pw1.x)*p_uv.y)
              uu = 1.0 - vv - ww  
              if uu>0 and vv>0 and ww>0: return uu,ww
          
              vv = 1.0/(2*area(pw3,pw4,pw1)) * (pw3.y*pw1.x - pw3.x*pw1.y + (pw1.y-pw3.y) * p_uv.x + (pw3.x-pw1.x)*p_uv.y)
              ww = 1.0/(2*area(pw3,pw4,pw1)) * (pw3.x*pw4.y - pw3.y*pw4.x + (pw3.y-pw4.y) * p_uv.x + (pw4.x-pw3.x)*p_uv.y)
              uu = 1.0 - vv - ww
              if uu>0 and vv>0 and ww>0: return = 1.0-uu,1.0-ww
          
              return -1,-1 # return negative results if not inside quadrilateral
              
          #---------------------------------------------------------
          
          def area(p0, p1, p2):
              return 0.5*(-p1.y*p2.x + p0.y*(-p1.x+p2.x) + p0.x*(p1.y-p2.y)+ p1.x*p2.y)
          
          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @rui_mac
            last edited by

            Hey @rui_mac,

            thank you for reaching out to us. This topic has been assigned to @i_mazlov. I just wanted to stop you there in your tracks. Cinema 4D does not use plain barycentric coordinates but weighted s, t coordinates. The interface for that is in a bit weird place in Python, in the hair library. You can check out this thread or wait for Ilia's answer.

            But you are very likely in a rabbit hole with what you are doing there (did not read all your code, just saw all the barycentric coordinate number pushing).

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            R 1 Reply Last reply Reply Quote 0
            • R
              rui_mac @ferdinand
              last edited by

              @ferdinand

              Thank you for the replay, Ferdinand.
              By "weighted s, t coordinates" you mean that distribution of the u,v coordinates is not uniform along the quadrilateral?
              This project will only work with single face quadrilaterals. I mean, it will always be a regular rectangle and the only distortion it will get is "perspective distortion". In that case, I can use simple barycentric calculations, right?

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

                Hey @rui_mac,

                please wait for Ilia's answer or just help yourself with my old thread there. I cannot take this thread over, I just wanted to make sure that you do not waste time on a route which is a dead end. And no, you cannot use barycentric coordinates as long as you want to match what Cinema does, as it does not use (plain) barycentric coordinates.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 0
                • i_mazlovI
                  i_mazlov @rui_mac
                  last edited by

                  Hi @rui_mac,

                  I have to point out that your question is generally out of scope of our support according to the Support Procedures due to being plainly algorithmic question.

                  I think Ferdinand implicitly assumes you switching from raw trigonometry to using our built-in functions for handling barycentric coordinates, namely GetPolyPointST() in Python and CalculatePolygonPointST() in C++. Of course he's not 100% correct saying that "you can not use barycentric coordinates" 😊 You can use them, if you like, but this would require you to implement everything yourself (the way you tried in your code). However, this approach is prone to errors and would only fit as an educational project.

                  In case you just need to have thinks working, it's recommended to use the functionality that we already have, namely the above mentioned functions. The way they work differs from the conventional definition of the barycentric coordinates (which operate with linear combination of vertices of your object. Wiki for more info: Barycentric coordinates). The difference is in the coordinates space: conventional definition uses vectors from the point C to your vertices Pi, while our implementation uses base vectors of your quad - <P2P3, P2P1> according to your image. This is the reason why they are named differently.

                  With that's said, I invite you to explore yourself the thread: Discussion on Methods for Calculating the Inner Points of a Quadrilateral, which hopefully answers your questions regarding the GetPolyPointST() function usage. You can particularly check the scene I shared in one of the answers here.

                  If I understand your initial question right, the only difference you need to account for (comparing to the scene from the thread) is to define points in the GetPolyPointST() function call in the screen space rather than world space (these will effectively turn them into 2D coordinates).

                  Cheers,
                  Ilia

                  MAXON SDK Specialist
                  developers.maxon.net

                  R 1 Reply Last reply Reply Quote 0
                  • R
                    rui_mac @i_mazlov
                    last edited by

                    @i_mazlov
                    Thank you so much, Ilia.
                    I would never expect to find those function inside the HairLibrary. I performed a search inside the SDK for "barycenter" or "bary" and I only got some stuff about RayCollider and VolumeData. I guess the GetPolyPointST function will be fine and faster than my calculation.
                    The s and t roughly correspond to the u and v coordinates?

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

                      Hey @rui_mac,

                      no, they do not match the uvw coordinates. They are weights, please have look at the example I have linked to above, it likely does everything you need. GetPolyPointST expects a value in local object coordinates and returns weights for the polygon UVW coordinates. You get then your final coordinate by the bilinear interpolation of the UVW quad over the s,t weights. You can of course technically replicate all the math yourself, but as Ilia has pointed out this would be out of scope of support.

                      Cheers,
                      Ferdinand

                      MAXON SDK Specialist
                      developers.maxon.net

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