Remove prim from group in VEX

   8399   11   4
User Avatar
Member
55 posts
Joined: March 2015
Offline
Hi

So basically I have two groups of primitives called internalPolys and externalPolys.

Now since some of the external primitives are also part of the internalPolys group I want to check in a prim wrangle, for each prim of the external poly (the wrangle looks in that group) if that prim is also in the internalPoly group, and if so, delete it from the externalPolys.

So far I got what you can see in the screen.


On this thread https://www.sidefx.com/forum/topic/34494/?page=1#post-160086 [sidefx.com] a guy mentioned a removegroup() function, wich I cant find in the docs vor VEX functions…so I cant use it since I dont know what to write inside the function.

Probably what youll see in the screen is wrong in some part, thats because I didnt fully understood what to write inside the functions, for example in the inprimgroup() the first argument of the functions should be a int input (from docs –> int inprimgroup(int input, string groupname, int primnum)) but what does it mean for input.?

Thanks

Attachments:
Screenshot_2.jpg (32.3 KB)

https://vimeo.com/user43100796 [vimeo.com]
User Avatar
Member
1743 posts
Joined: March 2012
Offline
You're pretty close, at least close to the long way to do it:
// If the current primitive (of input 0) is in the "internalPolys" group,
if (inprimgroup(0, "internalPolys", @primnum)) {
    // Remove the current primitive from the "externalPolys" group.
    // The mode parameter defaults to "set", meaning that we're setting
    // the group membership to the specified value of 0,
    // and 0 means not in the group.
    setprimgroup(geoself(), "externalPolys", @primnum, 0);
}

Because you're only dealing with the single input, and you're only modifying the group membership of the current primitive, you can alternatively use the automatic group bindings:
// If the current primitive is in the "internalPolys" group,
if (@group_internalPolys) {
    // Remove the current primitive from the "externalPolys" group.
    @group_externalPolys = 0;
}

If it compiles (I haven't tried), and you're comfortable with boolean operations, you can do it in one line:
// If the current primitive is in the "internalPolys" group,
// remove it from the "externalPolys" group.
@group_externalPolys &= !@group_internalPolys;

Happy VEXing!
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
55 posts
Joined: March 2015
Offline
Awesome, thank you so much!

All three solutions seems to work fine!

So let me understand..writing @group_GroupName means checking if the group exist?

https://vimeo.com/user43100796 [vimeo.com]
User Avatar
Member
1743 posts
Joined: March 2012
Offline
If you write to @group_GroupName, it will set the content of the group of the type specified by the “Run Over” parameter with name “GroupName”. If it doesn't exist, it will be created.

Caveat:

When using the @ syntax, things will get written-to if and only if the name is matched by the pattern in “Attributes to Create”. On the “only if” side, if your VEX code tries to write to an attribute using the @ syntax and it's not matched by “Attributes to Create”, it will usually give a compile error. On the “if” side, if your VEX code reads from an attribute using the @ syntax and doesn't write to it, but it *is* matched by the “Attributes to Create” pattern, Houdini will redundantly write to the attribute after the VEX code is done, so if you have attributes that you only read from using the @ syntax, it may give a slight performance boost to have “Attributes to Create” not match them.

Pro tip:

If the name of an attribute you want your VEX code to read/write is based on a string parameter, you can set up an explicit mapping to the @ syntax on the Bindings tab. Some people use backtick expressions instead, but that can get messy-looking, and if the name changes, it'd recompile the VEX code if you're using backtick expressions, but it can use the same VEX code if you've set up your own bindings. You can also use setprimattrib, etc, but those aren't as efficient as @ syntax for the cases where @ syntax will work, (i.e. you're only reading from the current element in input 0).
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
55 posts
Joined: March 2015
Offline
Ok I took my time to understand what you wrote, Im sure it will be usefull in future

And what about if I want to check if a group exist?

Like

If group exist:
{
do stuff;
}

Thanks


Edited by SteN - Aug. 8, 2016 19:01:12
https://vimeo.com/user43100796 [vimeo.com]
User Avatar
Member
1743 posts
Joined: March 2012
Offline
SteN
And what about if I want to check if a group exist?
Good question… I just checked all of the places that seem obvious to me to check for ways to do this in VEX, and nothing reliable turned up. The closest I could find was (nprimsgroup(0, “GroupName”)!=0), which will check if there's a non-empty primitive group, but the primitive group might still exist and be empty. There also doesn't seem to be a way to conditionally add a group, like the equivalent addattrib for numeric, string, and array attributes.

There should probably be a haspointgroup, hasvertexgroup, hasprimgroup, and hasgroup, as well as addpointgroup, addvertexgroup, addprimgroup, and addgroup. Edge group support might be nice too, but that's another issue.
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
459 posts
Joined: Oct. 2011
Offline
SteN
And what about if I want to check if a group exist?
The detail level of a geo-stream has intrinsic attributes that can help you with this.
With “detailintrinsic” you can check the existense/contents of: intrinsic:pointgroups, intrinsic:vertexgroups, intrinsic:edgegroups and/or intrinsic:primgroups

string pointgroups[] = detailintrinsic(0, "pointgroups");
i@len = arraylength(pointgroups);
foreach(string group;pointgroups)
{
    if(group == "grp_externalpts"){
        s@bug = "Its here!";
    }
}

-b

Attachments:
check_if_group.hiplc (61.2 KB)

http://www.racecar.no [www.racecar.no]
User Avatar
Member
1743 posts
Joined: March 2012
Offline
bonsak
With “detailintrinsic” you can check the existense/contents of: intrinsic:pointgroups, intrinsic:vertexgroups, intrinsic:edgegroups and/or intrinsic:primgroups
Riiiiiight! I just mentioned this to someone who said that it's what they always recommend to people, except that you can make it shorter using find().

string pointgroups[] = detailintrinsic(0, "pointgroups");
if (find(pointgroups, "grp_externalpts") >= 0) {
    s@bug = "Its here!";
}
i@len = len(pointgroups);

It'd still probably be good to have hasgroup/addgroup.
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
459 posts
Joined: Oct. 2011
Offline
Cool! Never used find() before. Thanks.

-b
http://www.racecar.no [www.racecar.no]
User Avatar
Member
55 posts
Joined: March 2015
Offline
detailintrinsic seems very powerfull…thanks!

What about implement one of these functions in a channel field?


In this scenario I have a peak node wich acts on one of the two poly groups, but this group may be empty, so I wrote what you can see in the screenshot to make it act only if the group has something, but it gives inwalid source…this is because your not supposed to write VEX functions in channel fields…?
Edited by SteN - Aug. 9, 2016 17:19:20

Attachments:
Screenshot_6.jpg (96.6 KB)

https://vimeo.com/user43100796 [vimeo.com]
User Avatar
Member
459 posts
Joined: Oct. 2011
Offline
That will not work unfortunately. The parameter channel needs to be of type snippet for VEX to work.
Check this [sidefx.com] link for how to use parameter expressions.

-b
http://www.racecar.no [www.racecar.no]
User Avatar
Member
55 posts
Joined: March 2015
Offline
Ok so I dont like to do this dirty workarounds but to make it work I created an attribute at detail level called @rom (casual name) and in an attribute wrangle, running on detail I wrote the following:


if (  nprimitivesgroup(0 , "internalPolys" )!= 0) 
{
@ron = 1;
}

So if the group has something @ron will be 1.
Now in the peak node, making it run on the group I want I wrote:

{
    if (@ron !=0)
    {
        return 5;
    }
}

And now no errors but nothing appens… .-.


Check this link for how to use parameter expressions.

I red on that page that they are kinda moving away from channel expression and Hscript to make VEX work on everything.
This is good since VEX is more efficent than Hscript…cant wait.
Edited by SteN - Aug. 10, 2016 04:59:04
https://vimeo.com/user43100796 [vimeo.com]
  • Quick Links