Using VEX to create groups by attribute

   59087   14   5
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
I want to create an arbitrary number of groups based on an attribute using VEX. The basic set-up is pretty simple:

Put down some Geo > Scatter arbitrary number of points on Geo > Feed those points into POPNet > Feed particles from POPNet into a Trail SOP > Use Add SOP to create lines from particle trails by grouping by attribute (id). That works great but I want to use VEX to create the groups instead of using the Add SOP.

My problem is that I haven't been able to figure out the correct VEX syntax, in particular, how to set the group name to the @id attribute (each trail inherits the @id of the originating particle) like so:


i@startpoints = chi(“../scatter1/npts”); // get the number of scattered points
s@test = itoa(@id); // convert id to string

for (int i=0; i < @startpoints+1; i++){ // loop over points

s@groupname = concat(“group_”, @test); // this creates strings matched to @ids, e.g., group_0
// not what I need
if (i==@id){
i@group_***** = 1; // ***** is where I'm stuck, how to read i into the groupname
} // I thought I could use ` ` to read it in but that fails. ?
}

I can achieve the effect I need with the Add SOP but I feel like I'm missing something in my understanding of VEX here and would love to sort it out. Any help would be much appreaciated.
Edited by kevinthebright - April 10, 2017 13:05:51
User Avatar
Member
2036 posts
Joined: Sept. 2015
Offline
Maybe try using the vex function setpointgroup:

http://www.sidefx.com/docs/houdini/vex/functions/setpointgroup [sidefx.com]

Edit: Also, I've noticed that on your line;

s@concat(“group_”,@test") = 1; // create group for each id - this doesn't work

It looks like your trying to assign 1 to a string. Maybe 1 can't be implicitly cast?
Edited by BabaJ - April 10, 2017 12:53:16
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
Hi BabaJ,
Thanks! Setpointgroup works perfectly! The string concat work (creates the string). I meant it didn't accomplish what I needed. I'll edit to clarify that. Here's the final code in case its helpful for others.

i@startpoints = chi(“../scatter1/npts”);
s@test = itoa(@id);

for (int i=0; i < @startpoints+1; i++){

s@groupname = concat(“group_”, @test);

if (i==@id){

setpointgroup (0, @groupname, @ptnum, 1, “set”);

}
}
User Avatar
Member
7737 posts
Joined: Sept. 2011
Offline
Why are you binding all of your variables to attributes, is this just for testing?
You also appear to be looping over the points, and comparing index to id. Normally, you can just bind id since you are building the group name directly from id anyways.

your code can be simplified to:

string prefix = chs("prefix");
string groupname = sprintf("%s_%d", prefix, @id);
setpointgroup(0, groupname, @ptnum, 1);
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
Thanks for this jsmack. I see what you did.

Yes, I usually bind variables while writing VEX so I can see them in the geo spreadsheet. I set up a loop so I could do other stuff to the group.

-k
User Avatar
Member
2036 posts
Joined: Sept. 2015
Offline
Hi kevinthebright:

I suspect you already know this…but if in cases where the only reason you bind a ‘variable’ so that you can see it in the spreadsheet; There is another option.

I sometimes create Detail Attributes for ‘data sets’ in vex to be used multiple times elsewhere in my Network but have no need for the points, prims or say vertices that the data was derived from (in the context that I am using the data sets.)

In those cases when they are not bound they still show up and are available to view in the spreadsheet under the Detail tab.
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
I hadn't thought of that approach BabaJ. That's handy, thanks.
User Avatar
Member
45 posts
Joined: Aug. 2012
Offline
Hello! I'm little confused with reading existing group in vex editor (Attribute Wrangle). Can't find in documentation mention of this. Example: Exist one group of Points “group1”, need call this group using vexpression. If I use “@”, it just creating new attribute.
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
Hi Felix6699

Here I set up some colors, then create 3 groups, an allPoints group, a neg_zed group and red group, then call the neg_zed group in an if loop. Does that help?

@Cd = set (0, 0, 1);
if (@P.x > 0){
    @Cd.r = 1;
    }
i@group_allPoints = 1;
i@group_neg_zed = @P.z < 0;
i@group_red = @Cd.r > 0.6 ? 1 : 0;

if (@group_neg_zed == 1){
    @Cd = @P.z;
    }

Also, as ever, check out Matt's blog:
http://www.tokeru.com/cgwiki/index.php?title=HoudiniVex#Access_group_names_procedurally_in_vex [tokeru.com]
User Avatar
Member
45 posts
Joined: Aug. 2012
Offline
Hi, kevinthebright!
Yes, if we will write i@group_NAMEGROUP, we can call exist group. Strange, that I missed it somewhere in the documentation. Thanks a lot
User Avatar
Member
2036 posts
Joined: Sept. 2015
Offline
Hello! I'm little confused with reading existing group in vex editor (Attribute Wrangle). Can't find in documentation mention of this. Example:

Not sure what you mean by ‘reading’ but there is an easy way to get points, primitives or edges from an existing group in vex;

expandpointgroup
expandprimgroup
expandedgegroup



http://www.sidefx.com/docs/houdini/vex/functions/expandpointgroup [sidefx.com]
http://www.sidefx.com/docs/houdini/vex/functions/expandprimgroup [sidefx.com]
http://www.sidefx.com/docs/houdini/vex/functions/expandedgegroup [sidefx.com]
User Avatar
Member
8525 posts
Joined: July 2007
Offline
Felix6699
Strange, that I missed it somewhere in the documentation
http://www.sidefx.com/docs/houdini/vex/snippets#accessing-group-membership [sidefx.com]
http://www.sidefx.com/docs/houdini/nodes/sop/groupexpression [sidefx.com]
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
9 posts
Joined: Nov. 2020
Offline
kevinthebright
string prefix = chs("prefix");
string groupname = sprintf("%s_%d", prefix, @id);
setpointgroup(0, groupname, @ptnum, 1);


Hi Kevin, so i have used this code to create point attributes with lets say "group_0", "group_1" etcc but i want to convert these point attributes to actual groups... so basically the points i have assigned an attribute "group_0" to convert them into a point group with the same name...

any help would be greatly appreciated... thanks!
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
Onyro
i want to convert these point attributes to actual groups
Hi Onyro, By actual groups, I take it you are not seeing the groups when you click on the node information? Is your wrangle after the trail SOP? You should be able to create a group from any attribute with the i@group_groupname = 1 syntax. For example, i@group_blueteam = (@Cd.b == 1) ? 1 : 0; sets a points membership to the blueteam group if point's blue color value is 1. Post your hip if you get stuck.
User Avatar
Member
5 posts
Joined: Sept. 2015
Offline
So, is it also possible to use the created group immediately. So in the same wrangle? Instead of using multiple wrangles and selecting the group.

Lets say something like this?

if(@P.z <= 0)
{
i@group_max = 1;
}
if(@P.z >= 0)
{
i@group_min = 1;
}

// just a sample expression
if(i@group_max=1)
{
@Cd = set(0,1,0);
}

if(i@group_min=1)
{
@Cd = set(0,0,1);
}
  • Quick Links