Stuck on wrangle expressions looping group prims

   5225   4   1
User Avatar
Member
61 posts
Joined: Feb. 2006
Offline
Hi,

I'm stuck on looping foreach on groups in vex wrangle.

I want to grab randomly named groups and apply a random attribute number or color to the prims of that group. Its sort of a learning experience (trying to move away from hscript as much as possible) since I can do this easily anyway with a name sop followed by a createAttribute or color SOP set to random by variable (name). But since looping groups in a wrangle node seems incredibly useful for many things, I want to properly get this understood.

From a wrangle example here, I get the bits that setup the groups into an array but I just don't seem to get sensible results when I try to change the foreach loop to set a random color attribute per group (but not per prim, like the wrangle preset examples. I want a random color applied once across the entire group prim range, for each group, but not just random per face everywhere).

Wonder if any vex guru could show how that's done from this.

s@groups = detailintrinsic(0, ‘primitivegroups’);
int rand = int(rand(@Frame)*len(groups));
i@prims = expandprimgroup(0, s@groups);
// delete the prims
Int p; foreach (p; prims) {
removeprim(0,p,1);
}


Thank you!
User Avatar
Member
22 posts
Joined: June 2006
Offline
hey Frankvw,
assuming your geometry has a certain number of primitive groups and the primitive attribute Cd,
try this code in an Attrib Wrangle SOP set to Detail mode:


// groups array
string groups = detailintrinsic(0, ‘primitivegroups’);

for (int g=0; g<len(groups); g++)
{
// prims array per group
int prims = expandprimgroup(0, groups);
// random color every frame different per group
vector randCol=vector(rand(g*4.2343+@Frame));
// assign random color to all the prims of the group
foreach(int p; prims)
setprimattrib(geoself(), “Cd”, p, randCol, “set”);
}
Alessandro Pepe
http://www.alessandropepe.com [www.alessandropepe.com]
http://pepefx.blogspot.com [pepefx.blogspot.com]
User Avatar
Member
61 posts
Joined: Feb. 2006
Offline
hi,

Cool! Thanks for that, works perfectly. I didn't know you could assign rand values across all elements of a vector in one go, in the line;

vector randCol=vector(rand(g*4.2343+@Frame));

This was the main area I was tripping up, trying to set each element individually. But that kinda focuses my bigger issue moving over to vex in that declaring and setting variables and arrays in vex doesn't seem to act like in hscript, python or even C (which it looks like).

Just rambling here in case its useful to any other folk trying to transition to vex or maybe any of the sidefx docs/tutorial folks. I'll admit I'm not a very good coder but usually get there in the end through sheer determination in the face of the odd daunting task that motivates me to try and script it.

So, for example;

f@red = rand(@P*0.123);
f@green = rand(@P*4.567);
f@blue = rand(@P*89.123);

Will not work in the vex expression if I try to set each color component in the loop. But setting from global variables will work;

@Cd.x = rand(@P*0.123);
@Cd.y = rand(@P*4.567);
@Cd.z = rand(@P*89.123);

That is outside the main loop. Inside the main loop, it still works but just returns greyscale colors, ie, it sets Cd.r, Cd.g and Cd.b to one random value, not individual like it does outside the loop.

I totally get these ideas in hscript and hom using referencing but vex syntax doesn't seem as clear to me yet. Still, plan to swallow all the vex docs over the coming week to get attributes, declaring and setting variable and array elements clearer in my head.

cheers!
frank
User Avatar
Member
61 posts
Joined: Feb. 2006
Offline
Hi,

So this was good learning experience now, had chance to dig through docs again and seen my earlier issues were trying to declare and set attributes all at same time and too liberally mixing casts. I've found declaring any calculations separately then assigning with explicit casts each item makes vex happier.

Adding into your working example with my earlier failed attempts will in fact also now work for me, if I want to set vector elements separately. Here it is if that's handy for any other vex apprentices also on the transition road. Really cleared things up in my mind a lot more.

// groups array
string groups = detailintrinsic(0, ‘primitivegroups’);
for (int g=0; g<len(groups); g++)
{
// prims array per group
int prims = expandprimgroup(0, groups);
// random color every frame different per group per color CrCgCb
float randCol1 = float(rand(g*0.123));
float randCol2 = float(rand(g*4.567));
float randCol3 = float(rand(g*89.123));
// assign random color to all the prims of the group
vector randCol = set(float(randCol1), float(randCol2), float(randCol3));
foreach(int p; prims)
setprimattrib(geoself(), “Cd”, p, randCol, “set”);
}

Thanks again!
User Avatar
Member
22 posts
Joined: June 2006
Offline
hey Frankvw,
yes I've been banging my head on the casting thing a few times in the past.
In VEX, functions overloading is used massively, so explicit casting is critical.
I'm glad it worked in the end !
Alessandro Pepe
http://www.alessandropepe.com [www.alessandropepe.com]
http://pepefx.blogspot.com [pepefx.blogspot.com]
  • Quick Links