Jump to content

sort


MENOZ

Recommended Posts

hello

I'm trying to sort a random attribute and count it, similar to what enumerate would do, but a bit different.

I tried both python and vex, both works but i had to be a bit more creative in vex and in my case it looks like it underperform python, Even if reading the cook time on the node is still much lower than python, in reality is much slower, and time is spent to "running vex code". isn't it the same as cooking? I'm confused now.

 

anyway here is the scene i am testing on

r is a random attribute, can start from any numer, is repeating sometimes, and when is repeating i don't want to continue counting.

order is the counting of the sorted r attribute, starting from 1. 

see the image 

post-1766-0-50559500-1428967190_thumb.jp

 

 

so I tried python and vex, both give me what i want, but I'd like to know a better approach to solve this problem in vex, because obviously is not the optimal way of doing it if it underperforms python.

 

 

if you go high enough with point count you should see a huge difference in performance between vex and python.

I noticed that in this case vex becomes slow when it's setting the attribute to the geo, if i comment out the setattrib() at the bottom it doesn't hang for so long.

 

 

i'll put python code here

node = hou.pwd()
geo = node.geometry()
mylist=[]


for point in geo.points():
    mylist.append(point.attribValue("r"))


dic={}
mylist.sort()
i=0
for idx, val in enumerate(mylist):
    if mylist[idx-1]!=val:
        i+=1
    dic[val]=i
#print dic
    
for point in geo.points():
    getval=point.attribValue("r")
   
    point.setAttribValue("order",dic[getval])

and vex here


int pts=i@numpt;
int curValList[];
for(int i=0;i<pts;i++)
{
getattribute("opinput:0",curValList[i],"point","r",i,0);
}


//ordered is a sorted curVarList
int ordered[]=sort(curValList);


//indexed create "enumerated" indexes for each value in the ordered list
int indexed[];
int idx=0;


for(int i=0;i<len(ordered);i++)
{
if (ordered[i]!=ordered[i-1]) 
    {idx+=1;
    }
indexed[i]=idx;
}


/*create a third list to store index and value pairs. this will be parsed per point
to get the correct index for each number */


int pairs[];


int i=0;
int v=0;
while(i<len(indexed)*2)
{
pairs[i]=ordered[v];//val
pairs[i+1]=indexed[v];//index
i+=2;
v+=1;
}
/*loop through  pairs to find the value and setting the index to the point*/




for( i=0;i<pts;i++)
{
    for(int d=0;d<len(pairs);d+=2)
    {
    if(curValList[i]==pairs[d])
        {setattrib(0,"point","order",i,0,pairs[d+1],"set");
        break;
        }
    }
}

I know, it's horrible  -_-  and probably also python can be written with another approach and more efficiently.

 

sort.hip

Link to comment
Share on other sites

Python could be quite fast, try this:

# Author: Petr Zloty
from itertools import izip, count

node = hou.pwd()
geo = node.geometry()

# Get tuple of all values at once
all_r = geo.pointFloatAttribValues('r')

# Get only unique values
all_unique_r = list(set(all_r))

# Sort them
all_unique_r.sort()

# Build dictionary from them
idx_dic = {v:k for k,v in izip(count(1), all_unique_r)}
# izip and count are usually faster for big datasets 
# and have much better memory management (imap = generator)
# (but there is slowdown from import statement)
# 
# Variation without itertools:
# idx_dic = {v:k for k,v in enumerate(all_unique_r, start=1)}
# order = map(idx_dic.get, all_r)

# Map occurence index to the original all_r list 
order = map(idx_dic.get, all_r)

# Debug
# new_values = (1,)*len(all_r)

# Set new attrib values at once
geo.setPointFloatAttribValues('order', order)
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...