VEX snippets

regex string replace

thanks to F1!

@name = re_replace(r'(.+?)\d+', r'\1', @name);

https://regexr.com/3k7l4

from space - to space - and back again

thanks to F1!

vector P = ptransform("/obj/cam1", @P);

vector pos = set(abs(P.x), abs(P.y), @Time);
vector noise = efit(vector(noise(pos)), 0, 1, -1, 1);
vector mirror = set(sign(P.x), sign(P.y), 1);

@P = ptransform("/obj/cam1", "space:current", P + noise * mirror);

for each group

thanks to acey195!

string grps[] = detailintrinsic(0, "primitivegroups");
foreach(string grp; grps)
{
    int groupCenterPt = addpoint(0,getbbox_center(0, grp));
}

to and from camera space

thanks to F1!

@P = toNDC(chs("camera"), @P);
@P.z = -ch("depth");
@P = fromNDC(chs("camera"), @P);

evaluate @ as string

thanks to Jake Rice!

int selector = chi("test");
string group = "\@class=" + itoa(selector);
int handle = pcfind(0, group, "P", @P, 10, 10);

Find min / max value

thanks to petz!

setdetailattrib(geoself(), "min_val", @uv.y, "min");
setdetailattrib(geoself(), "max_val", @uv.y, "max");

List of Primitive neighbours by half edges

thanks to petz!

int     prim_edge, edge, prim, i, n, num;
string  neighbours = "";

i = 0;
prim_edge = primhedge(@OpInput1, @primnum);
while(i < primvertexcount(@OpInput1, @primnum))
{
    num = hedge_equivcount(@OpInput1, prim_edge);
    n = 0;
    while(n < num)
    {
        edge = hedge_nextequiv(@OpInput1, prim_edge);
        prim = hedge_prim(@OpInput1, edge);
        if(prim != @primnum)
            neighbours += sprintf("%g ", prim);

        prim_edge = edge;
        n++;
    }

    prim_edge = hedge_next(@OpInput1, prim_edge);
    i++;      
}

s@neighbours = neighbours;

Insert a point to the middle of the curve

thanks to awong from discord

int prim_num = 0;
int new_point = addpoint(0, {0,0,0});
int insert_position = 3;

// store the old vertices
int old_vertices[] = primvertices(0, prim_num);

// add a placeholder using an arbitrary point
addvertex(0, prim_num, 0);

// replace the vertex at the desired position
setvertexpoint(0, prim_num, insert_position, new_point);

// replace the vertices after the inserted position
for(int i = insert_position; i < len(old_vertices); i++)
    setvertexpoint(0, prim_num, i + 1, old_vertices[i]);

U coordinate on closed prim

thanks to f1480187

// Detail wrangle.
float length = primintrinsic(0, "measuredperimeter", 0);

// Set to false if value of 1.0 is unwanted for the last point
// of closed prims and instead need to be treated as if point with
// u=1 is coincident with the first point (like in unrolled prims).
int as_open = true;

// Compensate for closing auto-edge length.
if (as_open && primintrinsic(0, "closed", 0))
{
    vector auto_edge = point(0, "P", 0) - point(0, "P", @numpt-1);
    length -= length(auto_edge);
}

// Compute curve u.
float passed = 0;
for (int i = 1; i < @numpt; i++)
{
    vector d = point(0, "P", i) - point(0, "P", i-1);
    passed += length(d);
    setpointattrib(0, "u", i, passed/length);
}

Print to console

printf("OUT=%f;  ", out); //  %s string,   %i integer

Compilable For Each Material

s@shop_materialpath = "/obj/butterflies/shop/hud";
s@shop_materialpath += itoa( detail(1,"iteration") %10 );

Random unit vector in the direction

thanks to Javier

vector center = {0,0,1};
float  maxangle = chf("maxangle");
v@N = sample_direction_cone(center, maxangle, rand(@ptnum) );

Other inputs

v@P.y = v@opinput1_P.y;
f@y = v@opinput1_P.y;

//2015: @opinput1_P binds as a float

Group

@group_my = 1;
if (@group_my) v@N = {0,1,0};

Group adhoc syntax / expression

n-m:step
@myattr="foo bar"
@P.y>0
@ptnum%(@numpt-1)==0 // first and last point

String

s@name = sprintf("piece%d", @class);
s@name = sprintf("nameX%dY%d",@P.x,@P.y);

// padzero
int padzero = chi("padzero");
string format = '%0' + itoa(padzero) + 'd';
s@frame = sprintf(format, @Frame) ;

Time Globals

@Time //Float time ($T)
@Frame //Float frame ($FF)
@SimTime //Float simulation time ($ST), only present in DOP contexts.
@SimFrame //Float simulation frame ($SF), only present in DOP contexts.
@TimeInc //Float time step (1/$FPS)

Centroid

vector min, max;
getbbox(0, min, max);
v@center = (min+max)/2;

Attrib type info

setattribtypeinfo(0, "point", "myvector", "vector");

Comparisons

==, !=, <, <=, >, >=

The logical (&&, ||, and !) and bitwise (& |, ^, and ~) operators are only defined for integers. AND OR:

if( res.x<precis || t>tmax ) break;

Shortcut to if statement

float a = condition? b: c;

 

@Cd

@Cd.g;
@Cd.y;

Find and delete ngons

int np[] = primpoints(0,@primnum);
int lnp = len(np);

if( lnp > 3 ) {
    removeprim(0, @primnum, 1); // 1 = and points
}

P smooth

int maxpoints = chi("maxpoints");
float radius = chf("radius");

int handle = pcopen(0, "P", @P, radius, maxpoints);
@P = pcfilter(handle,"P");
pcclose(handle);

Init Attrib Interpolate

//random prim
int prim = floor( rand(@ptnum) * nprimitives(1) );
i@sourceprim = prim;

//random speed, looping
float speed = fit01( rand(@ptnum), chf("speed_min"), chf("speed_max") );
float dist = (@Time * speed) % 1;
v@sourceprimuv = set(dist,0.5,1.0);

Prims from point array

thanks to @petz from odforce:

int point = addpoint(0, @P);
int points[] = primpoints(0, @primnum);
for(int i = 0; i < len(points); i++)
{
    int point_array[] = array(points[i - 1], points[i], point);
    int prim = addprim(0, "poly", point_array); 
}
removeprim(0, @primnum, 0);

 

The geometry functions, table from the docs

http://www.sidefx.com/docs/houdini/vex/geometry

vertexpoint()
pointvertex()
vertexnext()
vertexprev()
vertexindex()
primvertexcount()
vertexprim()
vertexprimindex()

Write point numbers to an array

thanks to @petz from odforce

//in detail mode
i[]@points = expandpointgroup(@OpInput1, "!");

//in point mode
int point[] = array(@ptnum);
setdetailattrib(geoself(), "points", point, "append");

Carve

#include <groom.h>

adjustPrimLength(0, @primnum, @perimeter, @perimeter*@dist);

Visibility

thanks to houdinitricks.com

@gl_wireframe = true;
@gl_lit = true;

Split string

thanks to Chris, http://blog.cerebero.com

//Split based on '_'
string bars[] = split(s@shop_materialpath, "_");

//Use last element as attribute value
s@mtlGrpName = bars[-1];

0-360 angle between vectors

thanks to f1480187

#define PI 3.1415926535897932384

float angle = acos(dot(v@up, v@aim));
int first_half = sign(dot(v@z, cross(v@up, v@aim))) >= 0;
angle = first_half ? angle : 2*PI - angle;

@angle = degrees(angle);

Arrays

append() // end
push() // end
insert() // index (negative from the end, inserting past the end will grow the array)