Getting RGB from barycentrix coordinates



  • On 22/06/2014 at 18:20, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   14 
    Platform:      Mac OSX  ; 
    Language(s) :     C++  ;

    ---------
    One of the values I get from GeRayCollider are the barycentric coordinates of the hit of the ray on a surface.
    I have the RGB values that are associated with each vertex of the surface (for tri and quad faces).
    How can I get the RGB value resulting from the mix of my 3 or 4 RGB values, at that specific barycentric coordinate?



  • On 22/06/2014 at 19:20, xxxxxxxx wrote:

    Barycentric coordinates are not RGB coordinates.  They are the coordinates relative to the polygon in a 2-dimensional plane in which it resides (simplistically put).  The three vectors are vertices of the polygon.  These coordinates can be construed as UVW coordinates of the polygon as well (if that is what you mean by RGB).  'position' is the point being converted to Barycentric and the return is whether or not it is within the bounds of the polygon or not.

    // Get Barycentric Coordinates in alpha, beta, gamma
    //*---------------------------------------------------------------------------*
    Bool GMPSupport::GetBarycentricCoordinates(Vector vector1, Vector vector2, Vector vector3, const Vector& position, Real& alpha, Real& beta, Real& gamma)
    //*---------------------------------------------------------------------------*
    {
    	Real	area =	(0.5 * Len((vector2 - vector1) % (vector3 - vector1)));
    	area =			(Abs(area) > 0.0) ? (0.5 / area) : 0.0;
    	vector1	-=		position;
    	vector2	-=		position;
    	vector3	-=		position;
      
    	alpha =			Len(vector2 % vector3) * area;
    	beta =			Len(vector1 % vector3) * area;
    	gamma =			Len(vector1 % vector2) * area;
      
    	return (Abs( 1.0 - alpha - beta - gamma ) <= 0.00001);
    }
    


  • On 23/06/2014 at 03:43, xxxxxxxx wrote:

    I know barycentric coordinates are not RGB coordinates, Robert.
    However, using barycentric coordinates, if there are specific RGB values that correspond to each vertex, we should be able to calculate what is the RGB value at a specific point in the surface (barycentric coordinate).
    I want to know what functions should I use to get a RGB value from a set of four RGB values and a set of barycentric coordinates and also a RGB value from a set of three RGB values and a set of barycentric coordinates.



  • On 23/06/2014 at 06:36, xxxxxxxx wrote:

    Howdy,

    Barycentric coordinates can be thought of as percentages of the 3 points of a triangle (a + b + c = 1).

    Adios,
    Cactus Dan



  • On 23/06/2014 at 06:41, xxxxxxxx wrote:

    Well, I found this:

    result = [color a] * (1.0-r-s) + [color d]*r + [color c]*s

    I must see if I can use this to implement what I want. I'm confident that I can :-)
    Also, the quadrangular version is very easy to understand.

    Rui Batista



  • On 25/06/2014 at 00:24, xxxxxxxx wrote:

    multiply each color with the according barrycentric coordinate, then sum the colors.



  • On 25/06/2014 at 02:22, xxxxxxxx wrote:

    Thank you Katachi.
    I figured it out. Actually, it had to be a little more complex, like this:

      
    f_id1=res.face_id;   
    f_id2=res.tri_face_id;   
    rr=res.barrycoords.x;   
    ss=res.barrycoords.y;   
      
    pol_abcd=s_poly[f_id1];   
    a=pol_abcd.a;   
    b=pol_abcd.b;   
    c=pol_abcd.c;   
    d=pol_abcd.d;   
      
    rgb1=s_store->GetVector(a);   
    rgb2=s_store->GetVector(b);   
    rgb3=s_store->GetVector(c);   
    rgb4=s_store->GetVector(d);   
      
    if (f_id2==(f_id1+1))   
         color=rgb1*(1.0-rr-ss)+rgb3*rr+rgb2*ss;   
    else   
         color=rgb1*(1.0-rr-ss)+rgb3*rr+rgb4*ss;   
    


  • On 25/06/2014 at 08:49, xxxxxxxx wrote:

    Can you please post more code about this Rui?
    I've been asking, and asking, and asking, for years  how to get the color values for a polygon face. And I've never gotten an answer.

    I know how to get the barycentric values of a polygon.
    But I don't know how to get the colors for the four vertices. And the colors for the polygon face between the points.

    Can you elaborate more about what this is?: s_store->GetVector(a);

    I'm 99% there.
    But I just don't know how to get the colors for the 4 verts. And the colors for the barycentric locations on the polygon's face.

    -ScottA



  • On 25/06/2014 at 09:06, xxxxxxxx wrote:

    There is a lot going on here, Scott.
    I don't mind telling you what I found out but first you need to know what I have been doing for you to understand where the colors are coming from.
    Please, watch these videos showing my tools and then feel free to ask me what you want to know exactly, from what you see there.
    By the way, I guess all my tools are working now. I just need to test them out a bit more before writing the documentation and releasing them. They include a tag, a shader, a sceenhook and two tool :-)

    https://vimeo.com/98089097

    https://vimeo.com/98694731

    https://vimeo.com/99060291



  • On 25/06/2014 at 09:54, xxxxxxxx wrote:

    Suppose I add a gradient material to an object.
    I'm trying to get the color values for that gradient from the barycentric locations of the polygons.
    I have a ray collider that gets the barry coods. And the polygon face ID#s.
    But I don't know how to get the color values.

    In your last video you pick a color by selecting some verts. And I'm wondering how you're doing that? And I'm also wondering how I can get the color value not just from a vertice. But also anywhere within the hit polygon at the barry coords.

    -ScottA



  • On 25/06/2014 at 12:50, xxxxxxxx wrote:

    My methods will not help you, I'm afraid, Scott :-(
    You need to sample UV coordinates from the surface and sub-UVs (barrycentric coordinates).
    My method doesn't deal with UVs. In fact, it is all about NOT using UVs and, instead, have RGB values assigned to each vertex.
    These RGB values are stored inside a BaseContainer that is inside a tag that must be attached to polygonal objects.



  • On 25/06/2014 at 13:47, xxxxxxxx wrote:

    I was afraid of that. I don't think I'll ever find an answer to that.
    Thanks anyway.

    I did try out what you're doing though with the RGB vertex colors.
    I'm assuming that you're using the DisplayControl() method to set the colors?
    I can set the colors of the vertices using that method. But I'm not getting good results from it.

    If I set the four vertices to the colors: red, green blue, black. I get a polygon consisting of a yellow triangle and an aqua color.
    But you seem to be able to color the polygons with a falloff to them.
    I'm curious how you're using the barycentric values to control the colors and the blending.
    If you aren't going to sell this plugin. I'd like to see the code to learn from it.

    -ScottA



  • On 25/06/2014 at 14:12, xxxxxxxx wrote:

    I use two methods to display the polygons in color.
    The fast method is through a scenehook, using the DisplayControl, that simply fills the cds.vertex_color[n] with the RGB values.
    I also set the cds.vertex_color_shading to TRUE.
    This method has the disadvantage of only showing the color when the objects are selected.

    The other method is slower but it displays the shaded polygons all the time. It uses DrawPoly and that method already works with shaded vertexes also.

    I'm going to sell the plugin but we can talk through PM or mail, if you want to ask and check more stuff about my code. I bet it is not a very clean code (after all, I just started coding in C++ two or three weeks ago) but it is working ;-)



  • On 25/06/2014 at 14:18, xxxxxxxx wrote:

    However, if there is a way to bake textures (and it sure is), if you find a way to do it internally, you can easily find the values of the RGB inside the polygons. At least in theory, I guess :-)



  • On 25/06/2014 at 14:57, xxxxxxxx wrote:

    I'm using the overloaded DisplayControl() and cds.vertex_color[n] in a tool plugin to play around with it. I don't think I want to get into the whole Scene hook thing for this.
    I was just curious why setting a color value for four corners of a polygon makes the polygon split up into two colored triangles. With no blurring.
    I was expecting to get a polygon with red, green, blue and black corners that gradually blended together. But instead I got this split polygon result.
    I thought maybe your code would help me understand it better. But if you're going to sell it, don't worry about it.

    The other problem of getting the the RGB color values from the polygon's barycentric position is something that I've wanted to know how to do for years.
    Some people say they know how to do it. But then they never show any code on how to do it.
    It's become my white whale. 

    -ScottA



  • On 25/06/2014 at 15:10, xxxxxxxx wrote:

    I didn't know that we could use the DisplayControl method in a plugin that was not a sceenhook :-(

    Did you set the cds.vertex_color_shading to TRUE?

    If what you want to know is the interpolated RGB value, from a barrycentric coordinate, if you know the RGB values of each vertex, I can tell you how I did. I used the barrycentric coordinates returned by the GeRayCollider.



  • On 25/06/2014 at 15:21, xxxxxxxx wrote:

    Yes. There's two DisplayControl() methods available. One for a SH, and one for ToolData plugins.
    I can't set mine to cds.vertex_color_shading. Because that option is not in R13. It was added in R14.

    I think I can get the vertice color values from my current toolData plugin's DisplayControl() code.
    So I'd really like to know how you're getting the interpolated RGB values for the barrycentric coordinates.
    What I really want is the material color values. But maybe your code getting the vertex colors will help me get there.

    -ScottA



  • On 25/06/2014 at 15:33, xxxxxxxx wrote:

    My code snippet at the top shows how I do it. I will paste it here again but I will comment it:

    // these are the values returned from the GeRayCollider
    // I don't know if you can get them in some other way.

    // the index of the polygon
    f_id1=res.face_id;

    // a way to know if it is a triangular face or, if it is a quadrangle, if we are on what triangle of that quadrangle.
    f_id2=res.tri_face_id;

    // the barrycentric coordinates
    rr=res.barrycoords.x;
    ss=res.barrycoords.y;

    // pol_abcd is a Cpolygon
    // s_poly is a Cpolygon* holding all the polygons of the object
    pol_abcd=s_poly[f_id1];

    // getting the point indexes
    // for a triangular face, c will be the same as d
    a=pol_abcd.a;
    b=pol_abcd.b;
    c=pol_abcd.c;
    d=pol_abcd.d;

    // getting the rgb values assigned to the vertexes
    // in my case, they are inside a BaseContainer
    rgb1=s_store->GetVector(a);
    rgb2=s_store->GetVector(b);
    rgb3=s_store->GetVector(c);
    rgb4=s_store->GetVector(d);

    // if f_id2==(f_id1+1) then the barrycentric coordinates
    // correspond to a triangle or to the first triangle of
    // a quadrilateral polygon

    if (f_id2==(f_id1+1))

    color=rgb1*(1.0-rr-ss)+rgb3*rr+rgb2*ss;

    else // it corresponds to the secont triangle of a quadragular polygon

    color=rgb1*(1.0-rr-ss)+rgb3*rr+rgb4*ss;

    I hope this helps somehow, Scott.



  • On 25/06/2014 at 17:04, xxxxxxxx wrote:

    OK Thanks.

    I figured out why I was getting a split colored polygon instead of a gradient type result.
    I was using the wrong color value range.

    I was using: Red = Vector(255,0,0)
    But I needed to use: Red =  Vector(1,0,0)

    -ScottA



  • On 25/06/2014 at 19:01, xxxxxxxx wrote:

    Yes.  RGB is stored in 0..255 range but C4D (and others) store the values in the 0.0-1.0 range.  Good to be aware of that difference.


Log in to reply