# VEX-Wrangles

## Rotate each packed primitive

``//----------rotate each packed primitives (for ex: fractured pieces of RBD sim)--------//``

``// store the current rotation matrix of each packed prims``
``matrix3 trns = primintrinsic(0,"transform",@primnum); ``

``//Create a matrix and variable to manipulate``
``matrix3 m = ident(); ``
``vector axis = chv("axis");          ``
``float angle = radians(ch("angle"));``

``// rotate the matrix and apply it to the original matrix``
``rotate(m,angle,axis); ``
``trns *= m; ``

``// modify the prim intrinsic``
``setattrib(0, "primintrinsic", "transform", @ptnum, @primnum, trns, "set"); ``

## BBox Related:

### Normalize Geometry using bounding box

• wrangle this on point level
• connect geo on 1st input
``vector min,size,scale;``
``min = getbbox_min(0);``
``size = getbbox_size(0);``
``scale = 1/max(size);``

``matrix m = maketransform(0,0,0,0,scale);``

``@P -= min ; ``
``@P *= m ;``

### Normalize Geometry using bounding box and move centroid to origin

• wrangle this on point level
• connect geo on 1st input
``vector size,scale,center,relP;``
``matrix m;``

``size   = getbbox_size(0);``
``center = getbbox_center(0);``
``relP   = @P - center;``
``scale  = 1/max(size); ``

``m = maketransform(0,0,0,0,scale);``
``@P = relP * m;``

### Fit a geometry inside a bounding box

• wrangle this
• connect geo on 1st input
• connect bbox geo in 2nd input

### Delete by bounding box:

Connect a bound sop in 2nd input and adjust its size to delete whatever outside that. run on primitive mode(can me modified easily for points)

## Matrix and quaternion related:

#maketransform - Builds a 3×3 or 4×4 transform matrix.

#cracktransform - returns value of rotation scale or translate from a matrix

#qconvert - Converts quaternion into a matrix

### To Convert a Vector to matrix:

such as converting a normal to a matrix and then to quaternion for getting orient

``matrix3 m = maketransform(@N,@up);``
``p@orient  = quaternion(m);``

### To Rotate a vector by a matrix;

• just multiply the vector by the matrix, example below
• turn on velocity visualization on points
``vector up = {0,1,0};``
``vector dir = {1,0,0};``
``float ga = 137.5;``
``matrix3 m = maketransform(dir,up);``
``float inc = @Frame;``
``float angle = (ga*inc);``

``rotate(m,angle,up);``

``@v = dir;``
``@v *= m;``

### Getting proper orientation from a vector for when copying objects over points:

``vector dir = @`chs("initial_vector")`; // initial vector it can be N or v or custom vector attrib``
``float rampDriver = @`chs("rampDirver")`; // this can be something like "curveu" to offset the rotations``

``vector up = {0,1,0.001};        ``
``vector temp = cross(dir,up);``

``//create natrix from vector``
``matrix3 m = maketransform(dir,temp);``
``vector axis = normalize(dir);``
``float angle = 1;``

``//set rotation to the matrix``
``angle *= chramp("twist",rampDriver) * ch("twist_count");``
``angle += radians(ch("rotation"));``
``rotate(m,angle,axis);``

``//convert the rotated matrix into quaternion @orient attrib``
``p@orient = quaternion(m);``

## 0-1 values on Curves based on vertex (similar to @curvueu)

• create pointwrangle

## Simple spiral

• create attribute wrangle , connect nothing
• run over > detail(only once)
• then create add sop set to polygon > by group

## Phylotaxi formation

• add detail wrangle , paste this , set angle interval to 137.5(which is golden angle)

## Helper for wedging

create a seperate attrib wrangle and set it to detail mode.paste the code.

set values for wedging and then link the detail attrib "value" to the parameter you want to wedge. on the wedge node>channel link the iteration channel of this channel

## If statement in single line:

``(condition != 1) ? iftrue : iffalse;``

## Find attribute value:

Usefull for finding matching points on other inputs based on certain attr

``int matching_pt = findattribval(@OpInput2, “point”, “id”, @id);``

## Infection:

set infection = 1 for start points

put a solver sop and wrangle inside and infect!

## Color By point density:

``int maxPts = chi("maxPts");``
``i@nearCount = len(nearpoints(0,@P,ch("rad"),maxPts));``
``v@Cd = chramp("color",float(@nearCount)/float(maxPts));``

## stickPoints to animated mesh:

``int primID;``
``vector primUV ,tempP;``
``// Offset the points inside the geometry``
``vector pointOffset = @P - (@N * .1);``
``// use the offset points to shoot a ray along the normal , To query UV info off the mesh ( static mesh )``
``primID = intersect(1,pointOffset,@N,tempP,primUV.x,primUV.y);``
``// Use the UV information, to query the pos information off the animated mesh,``
``@P = primuv(2,"P",primID,primUV);``

## Point Jitter along surface:

very handy snippet from Konstantin Magnus

``int seed        = chi('seed');``
``vector shift    = rand(@ptnum + seed);``
``int prims_nb[]  = pointprims(0, @ptnum); ``
``float prims_num = 1 / float( len(prims_nb) ); ``
``int prim_choose = int( floor(shift.z / prims_num) );``
``int prim        = prims_nb[prim_choose]; ``
``vector pos      = primuv(0, "P", prim, shift);``
``@t = prims_num; @P = pos;``

To move points to the surface of an sdf, add the sdf's gradient multiplied by the absolute value of the sdf value to the point's position

Connect the sdf volume with gradient field in the 2nd input

dont forgot to fill the interior of the sdf

``vector grad = volumegradient(1, 0, @P);``
``@dist = volumesample(1, 0, @P);``
``if(@dist <= 0){``
``    @P -= normalize(grad) * @dist;``
``    }``

## Curve equations:

// test it in a curve

``float npt = (@numpt-1) ;``
``float pt01 = @ptnum/npt ;``
``float amp = ch("amp") ;``
``float curv = ch("curv") ;``
``//linear range ``
``//@P.y = amp*pt01 ;``
``//linear with small rand``
``//@P.y = amp*pt01 + 0.5*rand(@ptnum) ;``
``//sharp mountain ``
``//@P.y = 2*amp*(0.5 - abs(0.5-pt01)) ;``
``//smooth mountain ``
``//@P.y = 4*amp*pt01*(1-pt01) ;``
``//ease in mountain``
``//@P.y = pow(amp*(0.5-abs(0.5-pt01)), curv)  ;``
``//exponentail decay``
``//@P.y = amp/pow(2.718, curv*pt01) ;``
``//ease in ``
``//@P.y = amp*pt01*pt01*pt01  ;``
``//ease out ``
``//@P.y = amp*(1-pt01)*(pt01-1) + amp  ;``
``//ease in-out``
``//@P.y = -amp*(0.333*pow(pt01, 3) - 0.5*pow(pt01, 2)) ;``
``//cubic``
``//@P.y = amp*pow(pt01-0.5, 3) + 0.125*amp ;``
``//cubic sine wave``
``@P.y = amp*pt01*(pt01-0.5)*(1-pt01) ;``

## Delete by Cam Frustrum:

``v@ndcP= toNDC(chs("cam"),v@P);``
``float padding = chf("padding");``
``float nearclip = chf("nearclip");``
``if(v@ndcP.x > (1 + padding) || v@ndcP.x < (0 - padding) || v@ndcP.y > (1 + padding) || v@ndcpos12321.y < (0 - padding) || -v@ndcP.z < nearclip){``
``    removepoint(0,@ptnum);``
``}``

__________________________________________________________________________

## Debug your 3d models - visualize tris,and ngons

``// run it on primitive wrangle and set colors for each type``
``int pts[] = primpoints(0,@primnum);``
``@Cd = 0;``
``if (len(pts) < 3){``
``    @Cd = chv("lines");``
``}``
``if (len(pts) == 3){``
``    @Cd = chv("tris");``
``}``
``if (len(pts) == 4){``
``    @Cd = chv("polygons");``
``}``
``if (len(pts) == 5){``
``    @Cd = chv("petagons");``
``}``
``if (len(pts) > 5){``
``    @Cd = chv("ngons");``
``}``

## Find the longest or shortest edge length for each primitive

``// run this on primitive mode``

``int pts[] = primpoints(0,@primnum);``

``int p1 = pts[0];``
``int p2 = pts[1];``
``int p4 = pts[3];``

``vector pp1 = point(0,"P",p1);``
``vector pp2 = point(0,"P",p2);``
``vector pp4 = point(0,"P",p4);``

``float a = length(pp1 - pp2);``
``float b = length(pp1 - pp4);``

``vector2 size = set(a,b);``

``f@longest = max(size); // longest edge length``
``f@shortest = min(size); // shortest edge length``

## Noise in Wrangle

``vector scale = set(ch('scaleX'), ch('scaleY'), ch('scaleZ'));``
``vector noise = vector(onoise(@P * scale, chi('turb'), ch('rough'), ch('atten')));``
``noise *= ch('mult');``
``@Cd = noise;``

__________________________________________________________________________________

## Get the points near the given points:

For simulations like wet sand or snow,in some cases we might need to delete the points whichever is not clumped together .

simple vex function will do the work

nearpoints() will give the list of points around current point and then we get the total number of points around the point using len() function so we get number of points around each points. we can delete the points which having less points around it.

``if (len(nearpoints(0,@P,ch("distance"))) < ch("threshold")){``
``    removepoint(0,@ptnum);``
``}``

__________________________________________________________________________

Create points in the average point position of bunch of close points:

I used this trick to get a curve from the given tube , which is exaclty in the center of the the tube!

What i did is type this in pointwrangle and deleted the original points then used add sop for connecting the points which is created by the point wrangle and then fused them !

``i[]@np = nearpoints(0,@P,ch("dist"));``
``i[]@npp ;``
``foreach(int n ; @np){``
``    v@nPP += point(0,"P",n);``
``}``
``v@nPP /= len(@np);``
``addpoint(0,@nPP);``

______________________________________________________________________________________

Mid point of an edge

`vector center =` `(p0+p1)/2;`

________________________________________________________________________________________

XYZ dist VOP:

Takes two inputs lets say input A and input B Find the distance between the points on A and the closest position on the surface of B,

No matter what the total number of points is. It will also return the parametric uv of the closest primitive and its index.

___________________________________________________________________________________________

To add points to the centre of each primitive

``addpoint(0,@P);``
``removeprim(0,@primnum,1);// delete the prims``

___________________________________________________________________________________________

Equalent of \$FPS in vex

1/@TimeInc

Where @TimeInc is the time between frames or substeps

____________________________________________________________________________________________

Round off float to nearest integer:

Searched this for a long time and finally its so simple.. use rint(float) instead of int(float) , For Ex : int(0.8) will return 0 and rint(0.8) will return 1

rint means round to nearest integer

__________________________________________________________________________________

Get Random direction:

At first every time I need a random vector like a random direction for copying something in points or random direction for velocity I usually build it like this

``vector randomDir = set(fit01(rand(@ptnum+ch('seed')+2),-1,1),fit01(rand(@ptnum+ch('seed')+3),-1,1),fit01(rand(@ptnum+ch('seed')+5),-1,1));``

This works fine for me , But There is a very simple solution for this which I dont know at that time.

The "rand()" function will automatically gives you 3dimentional value if you store it in a vector.

For example:

``float myrandom = rand(@ptnum);``

will give you random floats between 0-1 , if you store it in vector then it will return a random vector like the below

``vector myrandom = rand(@ptnum);``

this will give you random directional vector, But Wait your directional vectors will get values from 0 - 1 in each component

that means for V.x random 0-1 and so on , which will give you only random positive directions, you can take that and fit it between -1 , 1

which will give you full 360 random directional vectors. final code should look something like this

``vector myrandom = fit01(rand(@ptnum),-1,1);``

FUCK UP ALL THE ABOVE THINGS ALL ARE WRONG . below will do the trick in one line

``v@N = (rand(@ptnum+ch("seed1"))-{0.5,0.5,0.5})*2;``

_________________________________________________________________________________

Normal toward nearest neighbour

``int handle = pcopen(0, 'P', @P, ch('radius'), 2);``
``vector closeP;``
``while(pciterate(handle)){``
``    pcimport(handle, "P", closeP);``
``    @N = closeP - @P;``
``}``

__________________________________________________________________________________

Get CENTROID using wrangle:

``vector min, max;``
``getbbox(min, max);``
``vector center = (min+max)/2;``

__________________________________________________________________________

Group based on attribute:

``string grp_name = sprintf("name_%g", @attribute);``
``setpointgroup(0, grp_name, @ptnum, 1, "set");``

__________________________________________________________________________

Create grid with vex:

MUST RUN THE Wrangle SOp in 'Detail' mode

``//add points``
``int pt0 = addpoint(0,{0,0,0});``
``int pt1 = addpoint(0,{0,1,0});``
``int pt2 = addpoint(0,{0,1,1});``
``int pt3 = addpoint(0,{0,0,1});``
``//add primitives``
``int prim0 = addprim(0,"poly");  // "polyline" for lines or curves``
``//add vertices which will connect the points and prims``
``int vert0 = addvertex(0,prim0,pt0);``
``int vert1 = addvertex(0,prim0,pt1);``
``int vert2 = addvertex(0,prim0,pt2);``
``int vert3 = addvertex(0,prim0,pt3);``

For generating primitives lines or polys in vex

first we need to create a primitive using addprim function

then add vertices to describe which point the primitive is connected

Example:

• add two points in a scene and drop a detail wrangle

__________________________________________________________________________

Little , useful and 'often used to forgot' fucntions,

#maketransform

Builds a 3×3 or 4×4 transform matrix.

#cracktransform

returns value of rotation scale or translate from a matrix

#qconvert

Converts quaternion into a matrix

# hasprimattrib

check if the primitive has this attribute - hasprimattrib(opfullpath("../PATH"),"attribute")

# strcmp

CHECK IF INPUT 0 IS CONNECTED TO NOTHING - !strcmp(opinputpath("..", 0), "") - \

# printf

sprintf

Formats a string like printf but returns the result as a string instead of printing it.

# itoa

converts integer to string

Dont know why its itoa but i remember this like "Integer to alphabets"

# smooth

Smooth the given "amout" , and clamp it between given two values.

# match

This function returns 1 if the subject matches the pattern specified, or 0 if the subject doesn’t match.

best vex refrence

https://github.com/jtomori/vex_tutorial