alternative fuse vex function

   4392   4   1
User Avatar
Member
8 posts
Joined: Feb. 2018
Offline
Hi, im having trouble with some code - I am trying to create an alternative to the fuse node that fuses points according to their position, but will keep the point with the greatest @density.

this is what i have so far, based off this code (https://www.sidefx.com/docs/houdini/vex/functions/argsort.html) but a type error occurs at line 5 “push ()” - I dont understand why this error is coming from as the types seem right to me. this breaks the rest of the code due to null array pd

int points[]=pcfind(0,"P",@P,chf("fuse_dist"),10);

float pd[] = {};
foreach(int j; points){
    push(pd, point(0, "density", j));
}

int ordering[] = argsort(pd);
int points_by_dens[] = reorder(points, ordering);

print_once(sprintf("%d, %d, %d, %d\n",len(points), len(pd), len(ordering), len(points_by_dens)));

int fused = pop(points_by_dens,0);
float d = point(0,"density", fused);
//vector c = point(0,"Cd", fused);
foreach(int i; points_by_dens){
    d += point(0, "density", i);
    //c = max(point(0, "density", i),c);
    removepoint(0,i);
}
setpointattrib(0,"density",fused, d);
//setpointattrib(0,"Cd",fused, c);

if i put a random float in instead of the point() at line 5 it works better (code still doesnt function as planned if anyone else has tips on how to achieve what i want!)
any help is much appreciated as I am new to houdini!

Thanks
Edited by jordaneast - March 11, 2020 08:50:42
User Avatar
Member
555 posts
Joined: Feb. 2017
Offline
i'm not a vexpert but i did this:

    push(pd, float(point(0, "density", j)));
User Avatar
Member
555 posts
Joined: Feb. 2017
Offline
to dig a bit deeper…you could put int instead of float…it may not error out…but
step back a bit…if you put 1.1 as when you first tested it with a float…it worked
now put int(1.1) it will error out…so i guess it was forewarning you about the possibility
of getting an int returned…

but still it should have errored out on push(pd, int(point(0, “density”, j))); IMO
User Avatar
Member
72 posts
Joined: April 2016
Offline
The type error happens because vex tries to be smart and figure out all the types before it runs. The type returned by the
point
function can only be determined when the code runs though, so vex gets confused because point can return a single float or a float array. The cast to float that vusta recommends is the right way to fix that. You are basically telling vex that you promise the point function will return a single float value.

However, if all you want is a regular fuse that keeps the highest density value between fused points, you can use the Attributes to Snap parameter on fuse to choose the maximum density value.

Attachments:
fuse-max-density.png (15.3 KB)

User Avatar
Member
8 posts
Joined: Feb. 2018
Offline
thanks @vusta that seemed to work!! id did try (float), tho seems I'm still learning VEX syntax

and thanks @lfranceschini for the more in depth explanation, that is very helpful for my learning

ahhh gotcha - I see my mistake now. I understood the output attributes to snap as a “post” fuse action that didnt effect the choice of point to keep (i thought it was just @P that effected this) but using snapped_points and Maximum output I can get to where i need to!
Good to practice a bit of VEX though!

thank you guys very much, very helpful!!
  • Quick Links