Replace hairs that share root position (VEX)
Example: You want to add detail to the groom without changing the point order. Split a part of the hair you want to edit by percentage masking and edit. Merge the hair to the second input of the first wrangle. This wrangle will read the point positions of the changed hair and store the values in a vector array. The second wrangle will assign these point positions to the groom. Point order doesn’t need to match. Root point position and amount of points on each hair will need to match.
Logic around the script:
in the first wrangle
Assign “rootpoint” attrib for the first points in the primitives
if point position is equal to the array first point position, the point is root point
assign “replace” attrib for the points which P attribute will be overrided
if the second stream has a primitive that shares the same root position the primitives’ points will have a replace value of 1
if the point is a root point
find the closest point from the second stream and store its point number to a variable “nearest” (this is the root point that they share)
find the nearest points’ primitive with pointprims() vex function
find all the points that belong to this primitive and store them in an array “refpts”
find all of these points’ positions and store them in an array “refpos” by looping over the members of “refpts” array
assign this array to all of the points.
in the second wrangle
Read the vector array “refpos”
if replace attrib equals zero
set the primitives points point positions to the positions read from the “refpos” array.
//First Wrangle int pts[] = primpoints(0,@primnum); vector rootP = point(0,’P’,pts[0]); i@rootpoint = 0; if ( @P == rootP ) @rootpoint=1; i@replace = 0; if (xyzdist(1,@P) == 0) { for (int i=0; i<len(pts); i++){ setpointattrib(0,"replace",pts[i],1); } } if (@rootpoint == 1){ int nearest = nearpoint(1,@P); int nearprim[] = pointprims(1,nearest); int refpts[] = primpoints(1,nearprim[0]); vector refpos[]; for (int i=0; i<len(refpts); i++){ vector pos = point(1,"P",refpts[i]); append(refpos,pos); } for (int i=0; i<len(refpts); i++){ setpointattrib(0,"refpos", pts[i], refpos); } }
//Second Wrangle vector refpos[] = v[]@refpos; int pts[] = primpoints(0,@primnum); if (@replace == 1){ for (int i=0; i<len(pts); i++){ setpointattrib(0, "P", pts[i], refpos[i]); } }