// Author:  Malcolm Kesson
// Date:    May 20 2017
// Details: fundza.com/rfm/osl/verts2color/index.html
//
// MAX_NUM must match the value specified by verticesToRiAttr()
// that is used as a PreMel injection proc.
// For example, 
//        verticesToRiAttr("group1", 1000);
// Where "group1" is the group containing all the poly geometry whose
// vertices will be written as a custom attributes of the form,
//        Attribute "user" "int num_verts" [100]
//        Attribute "user" "point[10000] vertices" [100 valid + 9900 padding points]
#define MAX_NUM 1000
// Returns the distance from a point and a line.
// See: http://fundza.com/vectors/point2line/index.html
float distToLine(point p, point start, point end) {
    vector line_vec = start - end;
    vector pnt_vec = start - p;
    float  line_len = length(line_vec);
    vector line_unitvec = normalize(line_vec);
    vector pnt_vec_scaled = pnt_vec * (1.0/line_len);
    float  delta_t = dot(line_unitvec, pnt_vec_scaled);
    if(delta_t < 0)
        delta_t = 0.0;
    else if(delta_t > 1.0)
        delta_t = 1.0;
    point nearest = line_vec * delta_t;
    return distance(nearest, pnt_vec);
    }
  
shader
vertsToColor(
    float radius = 0.1,
    float blur = 0.02,
    color bakcolor = 1,
    color patcolor = color(1,0,0),
    output float resultF = 0,
    output color resultRGB = 0)
{
resultRGB = color(1,0,1);
int num;
int result = getattribute("user:num_verts", num);
if(result && num < MAX_NUM) {
    point data[MAX_NUM];
    result = getattribute("user:vertices", data);
    if(result) {
        point p = transform("object", P);
        point origin = point(0,0,0);
        point pnt;
        float dist, smoothed, max_smoothed = 0;
        for(int n = 0; n < num; n++) {
            pnt = transform("world", "object", data[n]);
            dist = distToLine(p, pnt, origin);
            smoothed = 1 - smoothstep(radius - blur, radius + blur, dist);
            if(smoothed > max_smoothed)
                max_smoothed = smoothed;    
            }
        resultRGB = mix(bakcolor, patcolor, max_smoothed);
        resultF = max_smoothed;
        }
    }
}