// 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;
}
}
}