Jump to content
Sign in to follow this  
Martin B

nearpoint() loop/exclude group.

Recommended Posts

I've found a few threads on this but still can't get it to work. I have a bunch of curves and I want to find the distance to the nearest point that isn't part of the same curve. Each curve has its own @id.

So my thinking was to use nearpoint(), if the @ptnum it returns has the same @id as the current point, run it again excluding that point, so it'll loop until it finds a point with a different @id. But for the life of me I can't get it to build a group/list for points to ignore.

If I manually make a @group_ignore or a string "ignore" it'll work for the first @id, but I can't get it to update for the next curve.

Below is roughly where I'm at with it, though Houdini crashed, I know the ignore section is wrong.

Thanks for any help!

int closept = nearpoint(0, @P); // find closest point
string ignore = ""; // empty string to build list in

while(@id == point(0, "id", closept)) // check if found point matches current points @id
    {
    ignore = ignore + sprintf(" %g", closept); //Trying to make a list for nearpoint to ignore
    closept = nearpoint(0, !ignore, @P); // check for the nearest point ignoring already checked points
    }

i@closept = closept;

 

Edited by Martin B

Share this post


Link to post
Share on other sites

So I can get it working using nearpoints() with the below VEX but it feels horribly inefficient, and I'll need to make sure the maxdist and maxpoints on the nearpoints() are dialled in which seems silly...

 

Quote


int closept[] = nearpoints(0, @P, 5, 20); // find 20 nearest points within 5 units

foreach(int nb_ptnum; closept) // loop through array
    {
    if (point(0, "id", nb_ptnum) != @id) // checking if @id's match
        {
        i@test= nb_ptnum;
        break;
        }
    }
 

 

Edited by Martin B

Share this post


Link to post
Share on other sites

Hello Martin !

As you noticed, there is a ptgroup argument to the nearpoint function.
If we read the description, this part is very interesting.. "[...] Can be a SOP-style group pattern such as 0-10 or @Cd.x>0.5. [...]"

What that means is that you can do some nice inclusion/exclusion based on not only point groups per se, but even attributes on your geometry !
This odForce thread talks about this.

So in your case, what you want is to find the nearest point that does not have the same id value as the current one.

This might be a bit confusing, but this is the logic I went through while investigating this.
So, keeping in mind that the ptgroup should be a string (check the doc), something like "@id != @id" should do it ?..
But this doesn't work. For what I understand is that since this is SOP-style statement, it works a bit different than in VEX, and doesn't have direct access to the attribute value of the current point.
So instead of trying to get the current id value in the statement, we should get it "outside".
Since this is a string, we can use the sprintf function to "insert" the id value into it. And thus, "sprintf("@id != %d", i@id)".

I don't know if I'm making any sense, so here's a gif of my solution
I run for a single point for example sake, coloring the source green and the found point red.

nearpointWithGroup.thumb.gif.c5bc5d8f2a8913c8e4afe9a88d4b480b.gif

Hope that helps !

nearpointWithGroup.hipnc

Share this post


Link to post
Share on other sites

Thats amazing, thank you so much! I was getting completely lost in the syntax of the SOP-style group stuff I'd read in the docs.

You went above and beyond with the gif as well :D

Share this post


Link to post
Share on other sites

This was what I was trying to do, measure the distance between curves and set a pscale/width attrib. Definitely going to need some massaging but reckon it'll work. Thanks again!

image.thumb.png.0e2202e24cb9fc697793079e438314e3.png

 

Edited by Martin B

Share this post


Link to post
Share on other sites

Hi,

adhoc group syntax feels more elegant but it's not always an automatic win in performance. Every unique adhoc group in a pcfind (what nearpoints internally calls) call will construct a new acceleration data structure which is very costly in performance. Depending on your use case, your overhead of constructing new acceleration data structures might surpass the performance cost of skipping the points on the original curve.

Best to profile it using your input :)

Share this post


Link to post
Share on other sites

@Librarian HIP attached, the swirly lines are from one of entagma's tutorials. SOP solver with a curl noise. Play the timeline from the resample to get a nice frame, then you can click down the nearpoint() wrangle which is quite heavy.

 

@animatrix Yep I just had a lockup when houdini went over 64gig with a load more points... Would you have any pointers on how to avoid the adhoc grouping? I had a thought on using a for-each piece SOP, then do the nearpoint() to a second input which has the current piece removed, no need for any grouping.

 

trailSwirl_v07_clean.hiplc

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Yes you need to skip them like in your second post. I posted the opposite operation here also:

https://www.sidefx.com/forum/topic/75781/

Just pad the max point count by rough estimation of max_curve_pts_from_any_curve * 2. It might be faster than adhoc group method, but even if it was slower, it wouldn't blow your memory away.

Share this post


Link to post
Share on other sites

@animatrix Haha, yep I switched back to the second method and its super quick and handles loads more points. Doh!

Thanks @Alain2131, learnt a load about ad-hoc grouping!

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×