Find Closest Primitives to a point

   1881   19   2
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,
Edited by TheDude123 - 2024年1月4日 21:18:33
User Avatar
Member
4515 posts
Joined: 2月 2012
Offline
TheDude123
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,

There is no single function that can return multiple nearest primitives but you can use xyzdist iteratively and use adhoc group to continuously exclude the previously found prims as you go, but it will be slow depending on how many primitives you want to gather as each call with a changing adhoc group will rebuild the acceleration data structures.
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 | animatrix2k7.gumroad.com
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
animatrix_
TheDude123
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,

There is no single function that can return multiple nearest primitives but you can use xyzdist iteratively and use adhoc group to continuously exclude the previously found prims as you go, but it will be slow depending on how many primitives you want to gather as each call with a changing adhoc group will rebuild the acceleration data structures.

I see, bummer. Thanks for the info. I'll try the xyzdist method. I have ~50,000 points to loop over and find their nearest prims within a given radius.
So, each point will probably find 3-5 prims. Not sure how slow that's going to be.
Edited by TheDude123 - 2024年1月5日 12:54:13
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
Here is an example of what I'm trying to do:

This will be looped over ~50,000 points

Attachments:
example.JPG (143.9 KB)

User Avatar
Member
8554 posts
Joined: 7月 2007
Offline
TheDude123
I see, bummer. Thanks for the info. I'll try the xyzdist method. I have ~50,000 points to loop over and find their nearest prims within a given radius.
So, each point will probably find 3-5 prims. Not sure how slow that's going to be.

doesn't matter how many points you have, its more about how many prims in the lookup geo and how many unique acceleration structures it needs for your points, there is still a high potential for reuse or many points may not even find any prim within radius so they will never get past the default xyzdist call

but it's easy to try and see how fast/slow it is for your case
Edited by tamte - 2024年1月5日 22:16:30
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
4515 posts
Joined: 2月 2012
Offline
TheDude123
Here is an example of what I'm trying to do:

This will be looped over ~50,000 points

In this case you can also store the primitive number on the points and do a regular point cloud lookup using pcfind and then loop over these points to gather unique primitive numbers found. This should be much faster for the vast majority of cases where you don't have an overwhelming number of points to filter through.
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 | animatrix2k7.gumroad.com
User Avatar
Member
475 posts
Joined: 7月 2005
Offline
You can also try to (pre)filter the primitives using their (local) bounding box, because the distance from any point to the bounding box is always less or equal compared to the distance itself. But the prefiltered distances doesn't need to have the same order as the original distances, so if you want to use something like maximum search number, you need more points to be sure to get all (or maybe check the maximum distance to the primtives aswell).

Attachments:
closest_prims.hipnc (233.9 KB)

User Avatar
Member
64 posts
Joined: 1月 2019
Offline
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?
Edited by TheDude123 - 2024年1月7日 12:44:03
User Avatar
Member
4515 posts
Joined: 2月 2012
Offline
TheDude123
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?

What you are looking for is a pointmany VEX function. It doesn't exist. There is an RFE for this: SESI #19043. Submit an RFE and reference this number so they can bump it up.

For now you have to do it manually:

float vals [ ] = array ( );

int pts [ ] = array ( 1, 2, 3 );
foreach ( int pt; pts )
{
    float val = point ( 0, "attrib", pt );
    append ( vals, val );
}
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 | animatrix2k7.gumroad.com
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
animatrix_
TheDude123
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?

What you are looking for is a pointmany VEX function. It doesn't exist. There is an RFE for this: SESI #19043. Submit an RFE and reference this number so they can bump it up.

For now you have to do it manually:

float vals [ ] = array ( );

int pts [ ] = array ( 1, 2, 3 );
foreach ( int pt; pts )
{
    float val = point ( 0, "attrib", pt );
    append ( vals, val );
}

ooooooooh, thats interesting.
It looks like the 'manual' part, besides the writing of the code, is I have to input the amount of points into:
int pts = array(manually input here) correct???

Something likes this seems to work as well:

f@vals = array();
int pts = expandpointgroup(0, "");
foreach(int pt; pts){
float val = point(0, 'angle_diff_C', pt);
append(@vals, val);
}
Edited by TheDude123 - 2024年1月7日 13:23:30

Attachments:
code.txt (157 バイト)

User Avatar
Member
4515 posts
Joined: 2月 2012
Offline
TheDude123
animatrix_
TheDude123
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?

What you are looking for is a pointmany VEX function. It doesn't exist. There is an RFE for this: SESI #19043. Submit an RFE and reference this number so they can bump it up.

For now you have to do it manually:

float vals [ ] = array ( );

int pts [ ] = array ( 1, 2, 3 );
foreach ( int pt; pts )
{
    float val = point ( 0, "attrib", pt );
    append ( vals, val );
}

ooooooooh, thats interesting.
It looks like the 'manual' part, besides the writing of the code, is I have to input the amount of points into:
int pts = array(manually input here) correct???

Something likes this seems to work as well:

f@vals = array();
int pts = expandpointgroup(0, "");
foreach(int pt; pts){
float val = point(0, 'angle_diff_C', pt);
append(@vals, val);
}

If you want all points, you can use either:

expandpointgroup ( 0, "" );
expandpointgroup ( 0, "*" );
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 | animatrix2k7.gumroad.com
User Avatar
Member
8554 posts
Joined: 7月 2007
Offline
Not sure how is expandpointgroup() gonna help in your case

If you say you found some prims and now want attrib array of all points of one or all of those prims then it's more like you need to use primpoints() to get array of points per prim
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
tamte
Not sure how is expandpointgroup() gonna help in your case

If you say you found some prims and now want attrib array of all points of one or all of those prims then it's more like you need to use primpoints() to get array of points per prim

I wasn't sure what you meant by this, and then I ran into the problem, LOL. The damn expandpointgroup() was returning ALL points. So...I used another array I had created (that included only the points within a certain distance to my search point...a nearpoints) and that seems to work.
Thanks for the warning!
User Avatar
Member
8554 posts
Joined: 7月 2007
Offline
TheDude123
I wasn't sure what you meant by this
To me it sounded like you wanted to get closest prims within radius and then get points of those found prims and get the attrib value array from them, that's why I suggested primpoints()

But whatever works for your particular case, since it's not very clear to me what exactly you were trying to get
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
tamte
TheDude123
I wasn't sure what you meant by this
To me it sounded like you wanted to get closest prims within radius and then get points of those found prims and get the attrib value array from them, that's why I suggested primpoints()

But whatever works for your particular case, since it's not very clear to me what exactly you were trying to get

I wanted to try both. Wasn't sure which would work the way i needed.

I was trying to fuse curves together that had overlapping points. HOWEVER, I need to run different checks so they wouldn't all fuse together. I only wanted the points with the smallest vector angle differences to fuse together (so there was a nice flow from curve to curve).

Another part was making sure each curve had a correct 'level' attribute that was calculated by looking at the closest prim/point to its root and adding 1 to the previous level found.

I think i got it working, probably way to overcomplicated...but I think it's working...until I click on another node down the chain
Edited by TheDude123 - 2024年1月9日 12:05:38
User Avatar
Member
131 posts
Joined: 8月 2012
Offline
TheDude123
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?

Attribute Promote (to Detail), "Array of All"?
User Avatar
Member
9 posts
Joined: 6月 2019
Offline
animatrix_
TheDude123
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,

There is no single function that can return multiple nearest primitives but you can use xyzdist iteratively and use adhoc group to continuously exclude the previously found prims as you go, but it will be slow depending on how many primitives you want to gather as each call with a changing adhoc group will rebuild the acceleration data structures.

Hey, I just need the second closest prim but can't figure out the syntax of how to add the closest prim into the group to ignore. I tried something like this but wasn't working haha.

float closestPrimDist = xyzdist(1, @P, closestPrim, closestUV);
float secClosestPrimDist = xyzdist(1, '!closestPrim', @P, secondClosestPrim, secondClosestUV)



Any help would be appreciated

Thanks
Edited by TimOrSomething - 2024年3月11日 03:28:25
User Avatar
Member
4515 posts
Joined: 2月 2012
Offline
TimOrSomething
animatrix_
TheDude123
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,

There is no single function that can return multiple nearest primitives but you can use xyzdist iteratively and use adhoc group to continuously exclude the previously found prims as you go, but it will be slow depending on how many primitives you want to gather as each call with a changing adhoc group will rebuild the acceleration data structures.

Hey, I just need the second closest prim but can't figure out the syntax of how to add the closest prim into the group to ignore. I tried something like this but wasn't working haha.

float closestPrimDist = xyzdist(1, @P, closestPrim, closestUV);
float secClosestPrimDist = xyzdist(1, '!closestPrim', @P, secondClosestPrim, secondClosestUV)



Any help would be appreciated

Thanks

Hi,

You can do it like this:

int closestPrim = -1;
vector closestUV = 0;

float closestPrimDist = xyzdist(1, @P, closestPrim, closestUV);
string excludeprim = "!" + itoa ( closestPrim );

int secondClosestPrim = -1;
vector secondClosestUV = 0;
float secClosestPrimDist = xyzdist(1, excludeprim, @P, secondClosestPrim, secondClosestUV);

Just passing closestPrim as an adhoc group won't work because a primitive group with that name doesn't exist. If you create that group in the same wrangle, then you would have to do the second lookup using another wrangle that comes after so it can find it.
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 | animatrix2k7.gumroad.com
User Avatar
Member
9 posts
Joined: 6月 2019
Offline
animatrix_
TimOrSomething
animatrix_
TheDude123
Hi, is there a vex function (or node) that finds the closest PRIMITIVES to a specified point position? Something that looks within a certain distance? I need to find multiple primitives...not just one.

Thanks,

There is no single function that can return multiple nearest primitives but you can use xyzdist iteratively and use adhoc group to continuously exclude the previously found prims as you go, but it will be slow depending on how many primitives you want to gather as each call with a changing adhoc group will rebuild the acceleration data structures.

Hey, I just need the second closest prim but can't figure out the syntax of how to add the closest prim into the group to ignore. I tried something like this but wasn't working haha.

float closestPrimDist = xyzdist(1, @P, closestPrim, closestUV);
float secClosestPrimDist = xyzdist(1, '!closestPrim', @P, secondClosestPrim, secondClosestUV)



Any help would be appreciated

Thanks

Hi,

You can do it like this:

int closestPrim = -1;
vector closestUV = 0;

float closestPrimDist = xyzdist(1, @P, closestPrim, closestUV);
string excludeprim = "!" + itoa ( closestPrim );

int secondClosestPrim = -1;
vector secondClosestUV = 0;
float secClosestPrimDist = xyzdist(1, excludeprim, @P, secondClosestPrim, secondClosestUV);

Just passing closestPrim as an adhoc group won't work because a primitive group with that name doesn't exist. If you create that group in the same wrangle, then you would have to do the second lookup using another wrangle that comes after so it can find it.

Ah I see. Thanks a bunch!!
User Avatar
Member
64 posts
Joined: 1月 2019
Offline
Jikian
TheDude123
Thanks everyone for the help! I'm running into another issue though: I've found an attribute on the points (of the primitives found) and I'd like to store those values into an array of values (they are float values, btw). I can't seem to find a function that will do this. Basically, create an array from an attribute that exists on multiple points (and has different float values).

Example:
point0 f@attribute = 2.3
point1 f@attribute = 73.3
point2 f@attribute = 54.34
point3 f@attribute = 22.6
point4 f@attribute = 5.3
point5 f@attribute = 67.3

create array {2.3, 73.3, 54.43, 22.6, 5.3, 67.3}

Any suggestions?

Attribute Promote (to Detail), "Array of All"?

haha, Yeah, that works too! Super Simple.
Thanks so much!
Edited by TheDude123 - 2024年4月13日 20:33:17
  • Quick Links