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]); } }
Previous
Previous

Useful basic python commands for Houdini

Next
Next

Get animation cache frame range to a variable in Houdini (Python)