Jump to content
magneto

How to get the point number with the lowest float attribute value?

Recommended Posts

Hi,

I am trying to solve a simple problem but got stuck. I use a VOP SOP to calculate a weight (float) value for each point using a parameter VOP. The values can be positive and negative. How can I get the point with the lowest and highest weight value?

I know how I could get the lowest and highest weight values using the AttributePromote, but I want to know which points have that weight.

Thanks guys :)

Share this post


Link to post
Share on other sites
Guest mantragora

No one uses VEX anymore. All professionals are using HDK :). Come on Magneto ! You can do it ! :D

I don't have time right now to look at this but who knows ;). But to be fair, your previous questions here about custom particles behaviors seems much more interesting to look at how to implement it in HDK. I just need a little free time to investigate it.

  • Downvote 2

Share this post


Link to post
Share on other sites

lol I know I am behind the class, but I will catch up.

As for the particles, not sure if they would be better to do in the HDK because with VEX you get automatic parallelization :)

It would still be interesting to do it in the HDK and support expressions like the regular POPs. Do it :D

Share this post


Link to post
Share on other sites

Thanks John, that's an impressive trick :)

Does exactly what I need.

Additional methods are welcome :)

Share this post


Link to post
Share on other sites

I had pretty much the same idea as jkunz - except that instead of the id trick, I thought I'd make groups for the highest and the lowest, and then grouptransfer to original geo.

find_min_max_pt_attr2.hip

  • Like 1

Share this post


Link to post
Share on other sites

No one uses VEX anymore. All professionals are using HDK :).

That's kind of distressing.

Share this post


Link to post
Share on other sites

Love you guys, learnt so much from looking at your methods :) Great to know there are so many ways to do this.

Share this post


Link to post
Share on other sites

Thanks Pazuzu, but your method only finds the min/max values, not the point numbers.

Also since there are many methods posted, i decided to profile them using 1M points. Here are the results I got:

John's method:

~800ms (Sort + Delete)

Symek's method:

1.362s

Eetu's method:

1.581s

Petz's method:

2.423s

I only calculated it for the operator doing the searching, and only for the min value, so didn't count both.

Something that's interesting is this. Symek's method does both min and max searching in a single Inline VOP, so I deleted the lines that searches for max, but I still got the same timing. Is this because the VEX compiler optimizes these 2 while loops into 1? Because with this change, I was sure Symek's method was gonna be the fastest.

Either way, it's amazing to see this much variation in people's approaches :)

Edited by magneto

Share this post


Link to post
Share on other sites

Thanks Pazuzu, but your method only finds the min/max values, not the point numbers.

Also since there are many methods posted, i decided to profile them using 1M points. Here are the results I got:

John's method:

~800ms (Sort + Delete)

Symek's method:

1.362s

Eetu's method:

1.581s

Petz's method:

2.423s

I only calculated it for the operator doing the searching, and only for the min value, so didn't count both.

Something that's interesting is this. Symek's method does both min and max searching in a single Inline VOP, so I deleted the lines that searches for max, but I still got the same timing. Is this because the VEX compiler optimizes these 2 while loops into 1? Because with this change, I was sure Symek's method was gonna be the fastest.

Either way, it's amazing to see this much variation in people's approaches :)

wow didn't expect mine to be the fastest - thanks for taking the time to stress test them all and post the results!

  • Like 1

Share this post


Link to post
Share on other sites

Something that's interesting is this. Symek's method does both min and max searching in a single Inline VOP, so I deleted the lines that searches for max, but I still got the same timing. Is this because the VEX compiler optimizes these 2 while loops into 1? Because with this change, I was sure Symek's method was gonna be the fastest.

I'm guessing the surplus in my example comes from a kd-tree which is a little overshoot for something like finding limits. That's why there is no difference between finding only minimum or both values: query is fast, but the tree has to be build first. Sorting points by attribute appears to be faster, which is good news btw.

  • Like 1

Share this post


Link to post
Share on other sites

@John: I also thought the Sort SOP would be slower :)

Thanks Symek. So the pcopen function you use builds a kd-tree?

Also in your VEX example, wouldn't it execute your inline VOP code for every point in 1M points?

I made a small change, not sure if it makes sense, where I changed the input points to input #2, and added a single point to input #1 via the Add SOP, and the execution time dropped to around 1.2s.

Maybe there is a way to optimize VEX? Apart from speed another reason I did this is because I didn't want to add the same attribute to all points when it was the same value. I guess the speed increase might be due to that :)

Share this post


Link to post
Share on other sites

Thanks Symek. So the pcopen function you use builds a kd-tree?

Yes, it does.

Also in your VEX example, wouldn't it execute your inline VOP code for every point in 1M points?

I made a small change, not sure if it makes sense, where I changed the input points to input #2, and added a single point to input #1 via the Add SOP, and the execution time dropped to around 1.2s.

VEX optimizer should handle it. Functions with constant parameters are normally cached. The point is that kd-tree isn't best tool for this task. Something like std::map implementation in VEX would perform better I suppose.

Maybe there is a way to optimize VEX? Apart from speed another reason I did this is because I didn't want to add the same attribute to all points when it was the same value. I guess the speed increase might be due to that :)

Most probably.

Edited by SYmek
  • Like 1

Share this post


Link to post
Share on other sites

Based on Symek's post that the pcopen had an overhead for building a kd-tree, I decided to use a simple for loop inside an inline VOP, and got a huge speed increase bringing the total time down to 323ms :D

Here is the code if anyone wants to try:

int ptnum = 0;
float minw = 1e9;
float w = 0;
for(int i=0;i<npoints(1);i++)
{
    import( "weight", w, 1, i );
    if ( w < minw )
    {
        ptnum = i;
        minw = w;
    }
}
addattribute("minptnum", ptnum);

I am still using the actual points as the second input where the first input only has 1 point (Add SOP), thus utilizing VEX for non-parallel problems, which is still pretty fast B)

  • Like 3
  • Downvote 2

Share this post


Link to post
Share on other sites

I am still using the actual points as the second input where the first input only has 1 point (Add SOP), thus utilizing VEX for non-parallel problems, which is still pretty fast B)

Neat idea!

  • Like 1
  • Downvote 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

×