MENOZ Posted April 13, 2015 Share Posted April 13, 2015 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 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 Quote Link to comment Share on other sites More sharing options...
pezetko Posted April 15, 2015 Share Posted April 15, 2015 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) Quote Link to comment Share on other sites More sharing options...
MENOZ Posted April 15, 2015 Author Share Posted April 15, 2015 wow, yes, pretty fast indeed! very interesting thank you! I really appreciate this! I would be curious to see if there's a clever way of coding this in vex which is not as slow as my code.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.