Detail Array Attributes - Problems creating/adding

   929   3   0
User Avatar
Member
3 posts
Joined: March 2023
Offline
I'm a few months new to Houdini but a veteran programmer. I'm having a hard time figuring out how to work with detail array attributes. It's easy for every other type.

These 3 nodes are the basis of my inquiry:


1) Intersection analysis creates sourceprim array attribute on points

2) add_detail_array - contains 1 line run over detail to add a detail array attribute. I tried creating the detail attribute on the fly in lower node but wasn't working. This works for now though.
i[]@lowestprims = array();

3) add_lowest_prims_to_detail_array - What I'm trying to do here is simply run over all points and add the lowest prim number in the sourceprim attribute array to a detail array attribute.

int prims[] = i[]@sourceprim;

int lowestid = 99999;

for (int i = 0; i < len(prims); i++){
    if (prims[i] < lowestid) {
        lowestid = floor(prims[i]);
    }
}

int success;
int existingList[] = getattrib(geoself(), "detail", "lowestprims", 0, success);
i[]@oldExistingList = existingList;

if (find(existingList, lowestid) < 0) {
    append(existingList, floor(lowestid));
    i[]@existingList = existingList;
    setdetailattrib(0, "lowestprims", existingList );
}

You can see in the code above I'm grabbing that sourceprim array, finding the lowest value, and then trying to append it to the detail attribute if it's not already in there. However, existingList is ALWAYS empty after the getattrib function call.

Does anyone know a way to do this or what I'm doing wrong?

Thank you!

Attachments:
Nodes.png (55.1 KB)

User Avatar
Member
8599 posts
Joined: July 2007
Offline
getattrib(), detail() and similar functions can't sample live geo, and geoself() doesn't really represent live geo but 0 which in those functions would sample first input data

setdetailattrib() however has "append" mode so you can use that to append to array attrib
also to make setattrib() functions know they are appending to an array attribute the value has to be array itself even if its appending just a single value
to illustrate this you can for example replace both of your wrangles with point wrangle:
int minprim = min( i[]@sourceprim );
int minprims[] = array(minprim); // just to make setdetailattrib aware that it's saving array attrib
setdetailattrib( 0, "lowestprims", minprims, "append");
however it will likely contain duplicates since you can't read the array per point as its run in parallel it
so you will need to do Detail wrangle afterwards to remove them

or just do everything in a single Detail wrangle instead:
for (int pt=0; pt<npoints(0); pt++){
    int sourceprim[] = point(0, "sourceprim", pt);
    int minprim = min( sourceprim );
    
    if (find( i[]@lowestprims, minprim ) < 0 ){
        append( i[]@lowestprims, minprim ); 
    }
}
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
3 posts
Joined: March 2023
Offline
Thank you Tomas that is very helpful! I had figured out about the parallel processing after some troubleshooting but I never figured out how to append to a detail attribute.

Thank you so much!
Will
User Avatar
Member
4531 posts
Joined: Feb. 2012
Offline
If you don't care about duplicates, you can also use Attribute Promote after saying lowestprim attribute for each point. It's faster than using VEX for promotion.

Unique Array of All is an RFE pending.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
  • Quick Links