### Post your favourite Wrangle SOP presets

108317   38   30
Member
665 posts
Joined: 7月 2005
Offline
Not to rain on anyone's parade, but have you seen the new Attribrandomize SOP?

It's got just about every randomize preset you could want, and even works w/ Quaternions!
Member
665 posts
Joined: 7月 2005
Offline
And just to remain on topic, here's a quick Point Cloud method to find if a point is inside, or below a surface based on normals.

i@maxPoints = 10;
i@handle = pcopen(@OpInput2, “P”, @P, @radius,@maxPoints);
@N = pcfilter(@handle,“N”);
v@groundP = pcfilter(@handle,“P”);
v@up = normalize(@P - @groundP);
@Cd = dot(@up,@N);
Member
4595 posts
Joined: 2月 2012
Offline
Jitter with Scale Attribute and Exponent

```#include "math.h"
#define PI M_PI

int pt = @ptnum;
if ( chi("id") )
pt = i@pt;

float s = 1;
if ( chi("scale") )
s = @scaleAttribute;

int maxsafeint = 100000;
float val = pt % maxsafeint + PI * ( pt / maxsafeint ) + ch("seed") * 0.618033988749895;
float x = rand ( val );
float y = rand ( 1231 + val );
float z = rand ( 773 + val );

vector v = ( set ( x, y, z ) - 0.5 ) * chv("s") * ch("amount") * pow ( s, ch("exponent") );
@P += v;
```
Edited by animatrix_ - 2023年12月10日 09:29:12

Attachments:
attribwrangle.zip (1.5 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
4595 posts
Joined: 2月 2012
Offline
Select Border Points by Primitive Attribute

```int pointPrimsHaveDifferentAttribValues ( string input; int pt; string attribute )
{
int currentValue = 0;
int initialized = 0;
int result = 0;
int pv = pointvertex ( input, pt );
while ( pv != -1 )
{
int vp = vertexprim ( input, pv );
int value = prim ( input, attribute, vp );

if ( initialized == 0 )
{
currentValue = value;
initialized = 1;
}

if ( value != currentValue )
{
result = 1;
break;
}

pv = vertexnext ( input, pv );
}
return result;
}

i@borderpts = pointPrimsHaveDifferentAttribValues ( @OpInput1, @ptnum, chs("attribute") );
```
Edited by animatrix_ - 2023年12月10日 09:29:38

Attachments:
attribwrangle.zip (1.1 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
339 posts
Joined: 8月 2007
Offline
Convert sphere primitive intrinsic transform to pscale:

matrix3 m3 = primintrinsic(@OpInput1, “transform”, @primnum);
vector extracted = cracktransform(0, 0, 2, { 0, 0, 0 }, m3);
@pscale = max(extracted,max(extracted,extracted));
Jesse Erickson
Fx Animator
WDAS
Member
4595 posts
Joined: 2月 2012
Offline
Gnomon

```int createLine ( int pt0; int pt1 )
{
int pr = addprim ( geoself ( ), "polyline" );
addvertex ( geoself ( ), pr, pt0 );
addvertex ( geoself ( ), pr, pt1 );
return pr;
}

int createPolygon ( int pt0; int pt1; int pt2 )
{
int pr = addprim ( geoself ( ), "poly" );
addvertex ( geoself ( ), pr, pt0 );
addvertex ( geoself ( ), pr, pt1 );
addvertex ( geoself ( ), pr, pt2 );
return pr;
}

int createPolygon ( int pt0; int pt1; int pt2; int pt3 )
{
int pr = addprim ( geoself ( ), "poly" );
addvertex ( geoself ( ), pr, pt0 );
addvertex ( geoself ( ), pr, pt1 );
addvertex ( geoself ( ), pr, pt2 );
addvertex ( geoself ( ), pr, pt3 );
return pr;
}

void createAxisGeometry ( float s; vector n; vector t; vector c; int color; int arrow; int scale )
{
vector p [ ];
push ( p, 0 );
push ( p, set ( s, 0, 0 ) );

if ( arrow )
{
float x = scale ? 0.75 * s : s - 0.25;
float y = 0.03 * ( scale ? s : 1 );
push ( p, set ( x, y, y ) );
push ( p, set ( x, y, -y ) );
push ( p, set ( x, -y, y ) );
push ( p, set ( x, -y, -y ) );
}

for ( int i = 0; i < len ( p ); ++i )
{
matrix3 xform = dihedral ( { 1, 0, 0 }, { 0, 0, -1 } ) * lookat ( 0, n );
p [ i ] = p [ i ] * xform + t;
}

int pt [ ];
for ( int i = 0; i < len ( p ); ++i )
pt [ i ] = addpoint ( geoself ( ), p [ i ] );

if ( color )
{
for ( int i = 0; i < len ( pt ); ++i )
setattrib ( geoself ( ), "point", "Cd", pt [ i ], -1, c, "set" );
}

createLine ( pt [ 0 ], pt [ 1 ] );
if ( arrow )
{
createPolygon ( pt [ 1 ], pt [ 2 ], pt [ 3 ] );
createPolygon ( pt [ 1 ], pt [ 3 ], pt [ 5 ] );
createPolygon ( pt [ 1 ], pt [ 5 ], pt [ 4 ] );
createPolygon ( pt [ 1 ], pt [ 4 ], pt [ 2 ] );
createPolygon ( pt [ 2 ], pt [ 4 ], pt [ 5 ], pt [ 3 ] );
}
}

void createCenterGeometry ( float s; vector t; vector c; int color; int scale )
{
vector p [ ];
float x = 0.03 * ( scale ? s : 1 );
push ( p, set ( x, x, x ) );
push ( p, set ( x, x, -x ) );
push ( p, set ( x, -x, -x ) );
push ( p, set ( x, -x, x ) );
push ( p, set ( -x, x, x ) );
push ( p, set ( -x, x, -x ) );
push ( p, set ( -x, -x, -x ) );
push ( p, set ( -x, -x, x ) );

for ( int i = 0; i < len ( p ); ++i )
p [ i ] += t;

int pt [ ];
for ( int i = 0; i < len ( p ); ++i )
pt [ i ] = addpoint ( geoself ( ), p [ i ] );

createPolygon ( pt [ 0 ], pt [ 1 ], pt [ 2 ], pt [ 3 ] );
createPolygon ( pt [ 1 ], pt [ 5 ], pt [ 6 ], pt [ 2 ] );
createPolygon ( pt [ 5 ], pt [ 4 ], pt [ 7 ], pt [ 6 ] );
createPolygon ( pt [ 4 ], pt [ 0 ], pt [ 3 ], pt [ 7 ] );
createPolygon ( pt [ 5 ], pt [ 1 ], pt [ 0 ], pt [ 4 ] );
createPolygon ( pt [ 7 ], pt [ 3 ], pt [ 2 ], pt [ 6 ] );

if ( color )
{
for ( int i = 0; i < len ( pt ); ++i )
setattrib ( geoself ( ), "point", "Cd", pt [ i ], -1, c, "set" );
}
}

addattrib ( geoself ( ), "point", "Cd", { 1, 1, 1 } );

if ( chi("x") )
createAxisGeometry ( ch("s"), { 1, 0, 0 }, chv("t"), { 1, 0, 0 }, 1, chi("arrow"), chi("scale") );
if ( chi("y") )
createAxisGeometry ( ch("s"), { 0, 1, 0 }, chv("t"), { 0, 1, 0 }, 1, chi("arrow"), chi("scale") );
if ( chi("z") )
createAxisGeometry ( ch("s"), { 0, 0, 1 }, chv("t"), { 0, 0, 1 }, 1, chi("arrow"), chi("scale") );
if ( chi("center") )
createCenterGeometry ( ch("s"), chv("t"), { 1, 1, 0 }, 1, chi("scale") );

i@gl_lit = 0;
```
Edited by animatrix_ - 2023年12月10日 09:29:54

Attachments:
attribwrangle.zip (1.7 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
4595 posts
Joined: 2月 2012
Offline
Select Edge Loop

Run Over = Detail

```int Contains ( string collection [ ]; string item )
{
for ( int i = 0; i < arraylength ( collection ); ++i )
if ( collection [ i ] == item )
return 1;
return 0;
}

int Contains ( int collection [ ]; int item )
{
for ( int i = 0; i < arraylength ( collection ); ++i )
if ( collection [ i ] == item )
return 1;
return 0;
}

string GetPrimsFromEdge ( int input; int pt0; int pt1 )
{
string prims;
int hedge = pointedge ( input, pt0, pt1 );
if ( hedge != -1 )
{
int count = hedge_equivcount ( input, hedge );
for ( int i = 0; i < count; ++i )
{
int pr = hedge_prim ( input, hedge );
if ( pr != -1 )
{
prims += itoa ( pr ) + "-";
hedge = hedge_nextequiv ( input, hedge );
}
}
}
return prims;
}

int GetNextPoint ( int input; int edgept0; int edgept1; int currentpt )
{
int pointNeighbors [ ] = neighbours ( input, currentpt );

string sprims = GetPrimsFromEdge ( input, edgept0, edgept1 );
string aprims [ ] = split ( sprims, "-" );
int prims [ ];
foreach ( string s; aprims )
push ( prims, atoi ( s ) );

int primPoints [ ];
for ( int i = 0; i < arraylength ( prims ); ++i )
{
int count = primvertexcount ( input, prims [ i ] );
for ( int f = 0; f < count; ++f )
{
int vertIndex = vertexindex ( input, prims [ i ], f );
int pointIndex = vertexpoint ( input, vertIndex );
push ( primPoints, pointIndex );
}
}

int uniquePoints [ ];
for ( int i = 0; i < arraylength ( pointNeighbors ); ++i )
{
if ( !Contains ( primPoints, pointNeighbors [ i ] ) )
push ( uniquePoints, pointNeighbors [ i ] );
}

if ( arraylength ( uniquePoints ) == 1 )
return uniquePoints [ 0 ];

return -1;
}

//  Traverse Edges

string BuildEdgeList ( int input; string edgeCollection )
{
if ( edgeCollection == "" )
return "!*";

string edges [ ];
string sedges [ ] = split ( edgeCollection, " " );

int traverseCount = 0;
int totalCount = arraylength ( sedges );

while ( arraylength ( sedges ) > 0 )
{
string sedge;
pop ( sedge, sedges );
string edgePoints [ ] = split ( sedge, "-" );

if ( !Contains ( edges, sedge ) )
{
++traverseCount;
for ( int c = 0; c < 2; ++c )
{
int points [ ];
int pt0 = atoi ( edgePoints [ c ] );
int pt1 = atoi ( edgePoints [ 1 - c ] );
int currentpt = pt0;
int lastPoint = pt0;
push ( points, currentpt );
int nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
//printf( "nextpt: %s\n", nextPoint );
while ( nextPoint != -1 && nextPoint != lastPoint )
{
pt0 = currentpt;
pt1 = nextPoint;
currentpt = pt1;
push ( points, currentpt );
nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
//printf( "nextpt: %s\n", nextPoint );
}

for ( int i = 0; i < arraylength ( points ) - 1; ++i )
{
int p0 = min ( points [ i ], points [ i + 1 ] );
int p1 = max ( points [ i ], points [ i + 1 ] );
push ( edges, sprintf ( "%s-%s", p0, p1 ) );
//printf( "edge: %s\n", sprintf ( "%s-%s", p0, p1 ) );
}
//printf( "points: %s\n", points );
}
push ( edges, sedge );
}
//else
//printf( "BYPASS: %s\n", sedge );
}

string edgelist = "";
foreach ( string s; edges )
edgelist += "p" + s + " ";

//printf( "Traversed: %s edges out of %s edges\n", traverseCount, totalCount );
return edgelist;
}

s@edgelist = BuildEdgeList ( 0, chs("edges") );[/code:1]

[code:1]edges = ""
geo = hou.node ( "." ).geometry ( )
names = hou.evalParm ( "group" ).split ( ' ' )

for name in names:
try:
group = geo.globEdges ( name )
except hou.OperationFailed:
group = ( )

for e in group:
p0 = e.points ( ) [ 0 ]
p1 = e.points ( ) [ 1 ]

try:
isValidEdge = geo.findEdge ( p0, p1 )
except:
isValidEdge = False

if not isValidEdge:
continue

a = str ( min ( p0.number ( ), p1.number ( ) ) )
b = str ( max ( p0.number ( ), p1.number ( ) ) )
edges += "{0}-{1} ".format ( a, b )

return edges[:-1]
```

Unfortunately working with edges is really hard in VEX. If we had the ability to highlight elements as well as be able to work with edges, it would really help with these kinds of tools. For example we have expandpointgroup, expandprimgroup, but not expandedgegroup, which could return edge points sequentially.
Edited by animatrix_ - 2023年12月10日 09:30:39
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
538 posts
Joined: 12月 2006
Offline
Member
4595 posts
Joined: 2月 2012
Offline
vux

That will take quite some work
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
4595 posts
Joined: 2月 2012
Offline
Color Random with the ability to use attributes (int/float/string) for seed in addition to global seed

Special thanks to SESI for the hash functions workaround

```int index = 0;
string name = chs("seedAttribute");
if ( chi("type") == 1 )
index = @primnum;
else if ( chi("type") == 2 )
index = @ptnum;
else if ( chi("type") == 3 )
index = @vtxnum;

if ( chi("useSeed") )
{
int exist = 0;
int hash = 1;
int type = attribtype ( @OpInput1, chs("type"), name );
if ( type == 0 )
{
int value = 0;
exist = getattribute ( @OpInput1, value, chs("type"), name, index, @vtxnum );
if ( exist )
hash = random_ihash ( value ) % 65536;
}
else if ( type == 1 )
{
float value = 0;
exist = getattribute ( @OpInput1, value, chs("type"), name, index, @vtxnum );
if ( exist )
hash = random_fhash ( value ) % 65536;
}
else if ( type == 2 )
{
string value = "";
exist = getattribute ( @OpInput1, value, chs("type"), name, index, @vtxnum );
if ( exist )
hash = random_shash ( value ) % 65536;
}
if ( exist )
index = hash;
}

float seed = 0.99 + ch("seed");
float r = rand ( index + seed + sin ( 13 * index + 19 * seed ) );
float s = fit ( random ( 17 * index + 91 * seed ), 0, 1, ch("srangex"), ch("srangey"));
s = ch("s") * ( 1 - ch("srand") ) + s * ch("srand") * ch("s");
float val = fit ( random ( 173 * index + 11 * seed ), 0, 1, ch("vrangex"), ch("vrangey"));
val = ch("v") * ( 1 - ch("vrand") ) + val * ch("vrand") * ch("v");
@Cd = hsvtorgb ( ( r + 0.618033988749895 ) % 1, s, val );
```

RFE: @elemnum that works based on the current Run Over mode instead of @ptnum, @primnum, @vtxnum
Edited by animatrix_ - 2023年12月10日 09:31:04

Attachments:
attribwrangle.zip (1.7 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
4595 posts
Joined: 2月 2012
Offline
Attribute From Array

Sometimes you need to manually set attribute values by hand for a small set of values. This preset lets you do that and also allows setting indices manually if you don't want the values to be assigned from 0 to N sequentially as they appear in the values array.

Code is dynamically generated so no need to post here.

Attachments:
attribwrangle.zip (1.5 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
678 posts
Joined: 7月 2005
Offline
It would be nice if someone could make this topic STICKY, don't you think?
Member
4595 posts
Joined: 2月 2012
Offline
mantragora
It would be nice if someone could make this topic STICKY, don't you think?

That would be nice, or if SESI integrates some of the useful ones to Houdini as presets (under gear menu)

Attribute Hash

Allows you to generate hash (integer) values from an int/float/string attribute.

```int ctype = chi("type");
int primorpt = -1;
if ( ctype == 0 )
primorpt = @ptnum;
if ( ctype == 1 )
primorpt = @primnum;

int hash = -1;
string name = chs("attribute");
int type = attribtype ( @OpInput1, chs("stype"), name );
if ( type == 0 )
{
int value = 0;
int exist = getattribute ( @OpInput1, value, chs("stype"), name, primorpt, @vtxnum );
if ( exist )
hash = random_ihash ( value ) % 65536;
}
else if ( type == 1 )
{
float value = 0;
int exist = getattribute ( @OpInput1, value, chs("stype"), name, primorpt, @vtxnum );
if ( exist )
hash = random_fhash ( value ) % 65536;
}
else if ( type == 2 )
{
string value = "";
int exist = getattribute ( @OpInput1, value, chs("stype"), name, primorpt, @vtxnum );
if ( exist )
hash = random_shash ( value ) % 65536;
}

i@hash = hash;
```
Edited by animatrix_ - 2023年12月10日 09:31:53

Attachments:
attribwrangle.zip (1.4 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
4595 posts
Joined: 2月 2012
Offline
Particle Gnomon

```int createPolygon ( int pt0; int pt1; int pt2 )
{
int pr = addprim ( geoself ( ), "poly" );
addvertex ( geoself ( ), pr, pt0 );
addvertex ( geoself ( ), pr, pt1 );
addvertex ( geoself ( ), pr, pt2 );
return pr;
}

void createGeometry ( float s )
{
float ss = 0.25 * s;

vector p [ ];
push ( p, set ( 0, 0, s ) );
push ( p, set ( -ss, 0, 0 ) );
push ( p, set ( ss, 0, 0 ) );
push ( p, set ( 0, 0, 0 ) );
push ( p, set ( 0, -ss, 0 ) );

int pt [ ];
for ( int i = 0; i < len ( p ); ++i )
pt [ i ] = addpoint ( geoself ( ), p [ i ] );

createPolygon ( pt [ 0 ], pt [ 2 ], pt [ 3 ] );
createPolygon ( pt [ 0 ], pt [ 3 ], pt [ 1 ] );
createPolygon ( pt [ 0 ], pt [ 4 ], pt [ 3 ] );

setattrib ( geoself ( ), "primitive", "Cd", 0, -1, { 1, 0, 0 }, "set" );
setattrib ( geoself ( ), "primitive", "Cd", 1, -1, { 0, 0, 1 }, "set" );
setattrib ( geoself ( ), "primitive", "Cd", 2, -1, { 0, 1, 0 }, "set" );
}

addattrib ( geoself ( ), "primitive", "Cd", { 1, 1, 1 } );
createGeometry ( ch("s") );

i@gl_lit = 0;
```

Edited by animatrix_ - 2023年12月10日 09:32:17

Attachments:
attribwrangle.zip (1.2 KB)

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

Member
2 posts
Joined: 9月 2011
Offline
Been using compile sop workflows a lot recently and have been looking for wrangley ways to do some of the things which are not compilable -

//Attribute Transfer

int handle = pcopen(@OpInput2, “P”, @P, chf(“rad”), chi(“num”));
vector lookup_P = pcfilter(handle, “P”); //Average P
vector lookup_attrib = pcfilter(handle, chs(“attrib”)); //Average of attrib

i@many = pcnumfound(handle);
if(i@many>0){
`chs(“attrib_cast”)` = lookup_attrib; //Supply the attribute you want to transfer
v@P = lerp(v@P, lookup_P, chf(“mix”));
}
Member
1029 posts
Joined: 4月 2017
Offline
Convert from imperial to metric (feets, inches, numerator/denominator, pounds)

A simple but useful tool. I always find imperial measures online and convert to meters, etc. Does anyone know how to show the detail attributes in the UI of the asset?

```float feet = chf("feet");
float inchesperfeet = 12;

float inches = chf("inches");
float inchespermeter = 39.3701;

int numerator = chi("numerator");
int denominator = chi("denominator");
float decimal = float(numerator) / float(denominator);

f@meters = ((feet*inchesperfeet) + inches + decimal)/inchespermeter;

float lbsToKg = 0.45359237;
float lbs = chf("pounds");

f@Kg = lbs * lbsToKg;
```

Attachments:
imperial_to_metric.JPG (32.0 KB)

Member
194 posts
Joined: 8月 2011
Offline
This is a great thread! I was thinking earlier today that it would be nice to have more wrangle presets (or python, VEXpressions or any code snippets or presets for nodes, really)

I was thinking about the online function of the Game Dev shelf tool. It would be really awesome if there were a way to have more of that type of online modularity in houdini.

Vex wrangle community presets would awesome (or any presets, or even hdas and shelf tools). maybe sidefx forum members could share their best presets public list to a channel. then, anyone using houdini with internet can select a public preset channel and use that person's presets.

I think an online preset ecosystem would be great for everyone:

• Our precious presets can live safe on a cloud with access from anywhere, and safe from hard drive failure and laptop thief
• Newbs would have more examples to get to speed
• There can be a bit of networking, we could subscribe to each others sidefx preset channels similar to youtube. maybe your next good job will have liked and subscribed to your preset channel?
• Maybe sidefx will have less work to do updating the help card examples, if a good community example is a click away
• This can encourage all of us to be more organized in our work with houdini (especially me, of course)

What do people think of this idea?

To keep on topic: my finest attribute wrangle preset:

@N = @N;

Because if you are like I am, you have a lack of normal.
Especially when you dive into your new SOP network..

Many times, you wish for normal, though.

Well, friends, there is no easier way than this to have normal!

you can even choose the flavor of your normal. just select an option from the “Run Over” Menu! Houdini will give you that flavor of normal! Point normal, Vertex normal, Primitive, or even a Detail Normal

But don't choose “Numbers” from the menu. numbers can't have normals, due to math. You can trust me, in school I passed Vector Calculus one time (barely). Besides that, houdini won't do anything, except waste a couple of cpu cycles parsing a do-nothing node. So don't be vexed if you don't see a “number normal” in your geometry sheet or your middle mouse menu. There is nothing wrong with your computer just because of that website you visited.

I hope this preset serves you all well.

Maybe next post, I will make and give to you a preset…
to change your normal into a tangent…!

(which is my specialty, of course)
Member
6 posts
Joined: 7月 2018
Offline
olivierth
Convert from imperial to metric (feets, inches, numerator/denominator, pounds)

Does anyone know how to show the detail attributes in the UI of the asset?

Hi Oliver,

I just stumped-upon your conversion code, thanks for sharing. I was able to update it with the detail attributes visible in the node. I created one for the length and the weight.

In the Edit Parameter Interface, I added a new float called Meters, and then gave it this expression in the Attribute Wrangle:
detail(“op:./”, “meters”, 0)

And then the same approach for the weight.

Hope this helps.

Cheers,
Dave
Edited by howitzer99 - 2019年4月26日 01:45:49

Attachments:
Convert_Units.hipnc (124.6 KB)

Member
4595 posts
Joined: 2月 2012
Offline
```if(ch("sourcegrouptype") == 4, 0, ch("sourcegrouptype"))