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)