I typically bundle these snippets as presets in a wrangle node as I get to use most of these functions from day to day. This generally gives me a good head start for similar wrangle tasks and also aids my efficiency.
Spiral From Line
//SPIRAL FROM LINE
//CIRCLE OF REFERENCE AND LINE MUST LIE IN THE SAME PLANE
//(ZX) PLANE IS SUGGESTED
//RADIUS OF CIRCLE SHOULD IDEALLY BE THE SAME AS LENGTH OF LINE
//Use uvtexture node to compute uv attrib on points
//Texture type is set to Row & Columns
//Get velocity vector along line
int total = npoints(0)-1; //last point
int after = total-1;//penultimate point
int ntm = @ptnum+1;
vector npos = point(0,"P",ntm);
v@v = @P-npos;
//get vel of last point
if(@ptnum==total){
v@v = point(0,"P",after)-point(0,"P",total);
}
v@v = normalize(v@v);
v@up = chv("up");
v@side = cross(v@v,v@up);
//Matrices
matrix3 xform = ident();
float freq = chf("frequency");
float angle = @uv.x * freq;
vector axis = v@up;
rotate(xform,angle,axis);
@P*=xform;
Limit the Velocity of Crowd Agents
//Modifying the 'v_agent' array vector attribute
//Use inside a SOP Solver
vector myvel[] = v[]@v_agent;
float mult = chf("mult");
foreach(int i; vector k; myvel)
{
if(length(k)!=0.0)
{
if(length(k)>chf("max_speed"))
continue;
else
myvel[i] = myvel[i] * mult;
}
}
v[]@v_agent = myvel;
Flow Vector Along Geo (Cross Product)
vector up = set(0,1,0); vector side = normalize(v@N); vector flew = cross(side,up); vector flow = cross(side,flew); v@side = flow; //visualize flow vector
Attribute Transfer Color from Second Input
int handle = pcopen(@OpInput2, "P", @P, chf("rad"), chi("num"));
vector lookup_P = pcfilter(handle, "P");
vector lookup_Cd = pcfilter(handle, "Cd");
i@many = pcnumfound(handle);
if(i@many>0){
@Cd = lookup_Cd;
v@P = lerp(v@P, lookup_P, chf("mix"));
}
Rest Position from (Array) Name Attribute
//Set rest position from array
//This two part code uses two attrib wrangle nodes
//It generates an array that contains the name attribs
//of selected pieces and stores this array attrib on a single point
//Part 1: Store names
i[]@pts = pcfind(1, "P", @P, chf("rad"), chi("num"));
string nnme[];
s[]@nme= nnme;
string tok;
foreach(int a;@pts){
tok = prim(1,"name",a);
push(@nme,tok);
}
//Part 2: Set rest position
string names[] = point(1,"nme",0);
foreach(string nme; names){
if(s@name==nme)@P = v@rest;
}
Quaternion Rotate
v@N = set(0,1,0);
matrix3 xform = ident();
float amt = chf("amt");
vector axis = set(chf("axisx"),chf("axisy"),chf("axisz"));
rotate(xform, amt, axis);
p@roti = normalize(quaternion(xform));
v@up= qrotate(p@roti,v@N);
v@N*=xform;
A Random Rotation Matrix
matrix3 myrot = ident();
float amt = fit(rand(@id+chf("seed")),0,1,chf("minamt"),chf("maxamt"));
vector axis = sample_direction_uniform(rand(@id));
rotate(myrot, amt, axis);
@P*=myrot;
Shrink Wrap
int handle = pcopen(@OpInput2, "P", @P, chf("rad"), chi("num"));
vector lookup_P = pcfilter(handle, "P");
i@many = pcnumfound(handle);
if(i@many>=1)v@N = @P-lookup_P;
else v@N = set(0,0,0);
@P-=v@N;
Cull Based on Ray Direction
int handle = pcopen(@OpInput1, "P", @P, chf("rad"), chi("num"));
vector up = {0,1,0};
vector dir,pos;
float angle;
i@many = pcnumfound(handle);
while(pciterate(handle)){
if(i@many>1){
pcimport(handle,"P",pos);
dir = pos - @P;
angle = dot(normalize(dir),up);
if(angle>chf("mix"))removepoint(geoself(),@ptnum);
};
};
pcclose(handle);
Rotate by Matrix
float xrotamt = radians(chf("xrotamt"));
float yrotamt = radians(chf("yrotamt"));
float zrotamt = radians(chf("zrotamt"));
vector min, max, centroid;
vector xrotaxis = set(1,0,0);
vector yrotaxis = set(0,1,0);
vector zrotaxis = set(0,0,1);
getbbox(0, min, max);
centroid = (max + min) * 0.5;
3@xform = ident();
rotate(3@xform, xrotamt, xrotaxis);
rotate(3@xform, yrotamt, yrotaxis);
rotate(3@xform, zrotamt, zrotaxis);
v@P -= centroid;
@P = @P * 3@xform;
v@P += centroid;
Move Points to Surface (SDF)
float vsample = volumesample(1,0,@P);
vector dirtosurf = volumegradient(1, 0, @P);
@P -= normalize(dirtosurf) * (vsample - chf("offset"));
Quantize Position - Cubify
float ps = chf("scale");
@P.x = rint(@P.x/ps) * ps;
@P.y = rint(@P.y/ps) * ps;
@P.z = rint(@P.z/ps) * ps;
Volume Frustrum Cull
vector pndc = toNDC(chs("camera_name"), @P);
float pad = .2;
if(pndc.x<0-pad || pndc.x>1+pad || pndc.y<0-pad || pndc.y>1+pad || pndc.z>=0){
@density=0;
}
Velocity Along Path
int total = npoints(0)-1;
int after = total-1;
int ntm = @ptnum+1;
vector npos = point(0,"P",ntm);
v@v = @P-npos;
if(@ptnum==total){
v@v = point(0,"P",after)-point(0,"P",total);
}
Get Centroid
vector min, max; getbbox(0, min, max); vector centroid = (max + min) * 0.5;
Group Roots and Tips of Curves
i@root = (vertexprimindex(0, @vtxnum) == 0); i@tip = (vertexprimindex(0, @vtxnum) == (@numvtx-1)); setpointgroup(0, "roots", @ptnum, @root, "set"); setpointgroup(0, "tips", @ptnum, @tip, "set");
Orient Attribute from Normal
matrix3 m = dihedral({0,0,1},@N);
@orient = quaternion(m);
Simplex Noise on Velocity
v@v *= chf("vel_scale");
vector freq = chv("freq");
vector offset = chv("offset");
float amp = chf("amp");
vector nn = xnoise(@P * freq + offset);
nn = fit(nn,{0,0,0},{1,1,1},{-1,-1,-1},{1,1,1});
nn *= amp;
v@v += nn;
Connect Points
//Run over detail
int num = npoints(geoself());
int vtx_limit = num-1;
for(int i=0;i<vtx_limit;i++){
int prim = addprim(0,"polyline");
addvertex(0,prim,i);
addvertex(0,prim,i+1);
}
Reduce Points
if(rand(@id)<ch("kill"))
removepoint(geoself(), @ptnum);
Tighten Points
int handle = pcopen(@OpInput1, "P", @P, chf("rad"), chi("num"));
vector lookUp_P = pcfilter(handle, "P");
v@P = lerp(v@P, lookUp_P, chf("mix"));
Delete Lone Points
int handle = pcopen(@OpInput1, "P", @P, chf("rad"), chi("num"));
i@many = pcnumfound(handle);
if(i@many<chi("num"))removepoint(geoself(),@ptnum);
Scale by Matrix
vector p = getbbox_center(0);
float sx, sy, sz;
sx = sy = sz = chf("scale");
matrix idan = maketransform(0,0,{0,0,0},{0,0,0},set(sx,sy,sz),{0,0,0});
@P -= p;
@P *= idan;
@P += p;
Cull Points Based on Speed
float vlen = length(v@v);
if(vlen<chf("speed"))removepoint(geoself(),@ptnum);
Interpolate Line Into Circle
//Input is a line, resample for more points
//UV texture SOP as point attrib, rows and columns
int num = npoints(0);
vector lineStart = point(0,"P",0);
vector lineEnd = point(0,"P",num-1);
vector lineDir = lineStart-lineEnd;
float l = length(lineDir);
vector up = set(0,1,0);
vector side = cross(normalize(lineDir),normalize(up));
if(dot(up,normalize(lineDir))<0) up=set(1,0,0);
float t = @uv.x;
float pivot = chf("pivot");
float lineLength = length(lineDir);
float bendFactor = chf("bend_Factor");
float circleRad = lineLength / (2 * PI);
vector circleCenter = lineStart + (-lineDir * pivot);
circleCenter += up * circleRad;
float angle = PI + bendFactor * (1.0 - (t+pivot)) * 2 * PI;
vector posOnCircle = circleCenter + set(cos(angle),sin(angle),0) * circleRad;
@P = lerp(@P, posOnCircle, bendFactor);
Look At: Generate Radial Velocities
v@v = set(1,0,1); vector pp = getbbox_center(geoself()); matrix3 mm = lookat(pp,@P); @v *= mm;
Bend Curve
//Activate curveu attrib in resample SOP
@curveu = chramp("ramp",@curveu);
float bamt = chf("bend_amt");
vector benddir = chv("bend_dir");
@P += benddir * bamt * @curveu;
Median Point Number
int npt = npoints(0);
if(npt%2==0)
i@midpt = (npt/2) -1;
else
i@midpt = (int(ceil(float(npt)/2))) -1;
Point Cloud Density
float rad = chf("rad");
int num = chi("num");
int handle = pcopen(@OpInput1, "P", @P, rad, num);
vector lookup_P = pcfilter(handle, "P");
int many = pcnumfound(handle);
i@many = many;
f@viz = float(many)/float(num);
@Cd = vector(f@viz);
Transform by Primitive Intrinsic
matrix xform = primintrinsic(@OpInput2, "packedfulltransform", 0); @P *= xform;