Attributes

Set attrib type info

int pnt = addpoint(0,0);
vector4 quat = quaternion(0);
setpointattrib(0, 'orient', pnt, quat);
setattribtypeinfo(0, 'point', 'orient', 'quaternion');

Transform

Quaternion

  • Quaternion to Euler
    • Specify the rotation order with the order integer. Use the constants defined in $HH/vex/include/math.h (for example, XFORM_XYZ)
    • Note! You do not need to include math.h in a wrangle (like this: #include <math.h>) it is included by default.
      vector euler = degrees(quaterniontoeuler(p@orient, XFORM_XYZ));
      

Matrix

  • Get matrix components
    • You can use getcomp function…
      getcomp(<matrix>m, int row, int column)
      
    • …but you can also access components using m.xx, m.xy, m.xz etc…
      matrix3 rm = qconvert(p@orient);
      vector v = set(rm.zx, rm.zy, rm.zz);
      

pscale

We have control over the distribution of various sizes (bias), the size over life (note that we use the internal @nage i.e. normalized age an attr that comes by default when we do a popsim), min and max scale as well as an overall multiplier.

float ps_life = chramp('ps_life', @nage);
float ps_bias = fit01(chramp('ps_bias', rand(@id)), chf('ps_min'), chf('ps_max'));
@pscale = ps_life*ps_bias*chf('ps_mult');

String

Regex

Replace

Using capture group and replace

string names[] = {'monkeys_12', 'X_AE_A-12', 'my_name', 'Forty_Two____42'};
// remove trailing digits including underscore/dash...
// ...matching as few as possible in our capturing group
// note that we use the first capturing group in our replacement string
string regex = r'^([a-zA-Z_]*?)[-_0-9]*$';

int pnt;
foreach(int i; string name; names){
    pnt = addpoint(0, 0);
    name = re_replace(regex, r"\1", name);
    setpointattrib(0, 'name', pnt, name);
}

Slashes to underscrore

string names[] = {'/mat/one', '/mat/two'};

foreach(int i; string name; names){
    int pnt = addpoint(0, 0);
    name = re_replace('/', '_', name);
    setpointattrib(0, 'name', pnt, name);
}

Formatting

Zero padding

int i = int(rand(@ptnum+chi('seed'))*(chi('max_num')+1));
s@z_padded = sprintf('hello_%03i', i);

Round float

s@name = sprintf('%.1f', u@uv.u);

UV

Scale UVs around UDIM center

int u = int(floor(v@uv[0]));
int v = int(floor(v@uv[1]));
int udim = 1000 + u+1 + v*10;
i@udim = udim;

vector2 center = set(u+.5, v+.5);
vector disp = (@uv-center)*chf('uv_mult');
@uv += disp;

Points

Partition points

Here is a vex version of a techique I saw John Kunz use in Vops. Note that the points comming in on the second input will be the “cluster centers”. Theese points can be generated anyway you want, for instance by the scatter node or by fusing “the original points” and with the snap distance control how many centers you want.

Point wrangle

int npt = nearpoint(1, @P);
vector p = point(1, 'P', npt);
vector relbb = relbbox(0, p);
if(relbb.y <= chf('threshold')){
    @my_attrib = 1;
}
else {
    @my_attrib = 0;
}

Primitives

adjustPrimLength

Here we can use a measure sop measure the perimeter of the prim. This is needed for the function to work. Note that if we does not clamp the length it will extend the prims to match the length of the longest prim.

#include <groom.h>

float length = clamp(chf('length'), 0, @perimeter);
adjustPrimLength(0, @primnum, @perimeter, length);

Detail

Array of Unique (detail)

int nprim = nprimitives(0);
s[]@mat_names = {};

int count = nuniqueval(0, "prim", "shop_materialpath");
for (int i = 0; i < count; i++) {
    string val = uniqueval(0, "prim", "shop_materialpath", i);
    push(s[]@mat_names, val);
}

For fun

Position

“Manually” calc relbbox

int use_relbb = chi('use_relbb');
vector relbb;

// use relbbox
if(use_relbb){
    relbb = relbbox(0, @P);
} 
// for fun, calc relbb from bbox- min & size
else {
    vector bb_min = getbbox_min(0);
    vector bb_size = getbbox_size(0);
    relbb = (v@P-bb_min)/bb_size;
}

v@Cd = relbb;

Docs