SpencerL Posted September 1, 2010 Share Posted September 1, 2010 Hey Everyone, I have a point cloud question. Lets say I have 5 curves with a "v" attribute and on the points I am feeding into the point cloud I have an attribute with the number of the curve (0-4) that I want to get "v" from. Question is, how do I grab "v" from only the curve which corresponds to the pts whose number matches the curve number? I understand that I could use a foreach/feedback loop and just cull the curves I dont want to sample from, but in this case, that would be too expensive. I am wondering if there is a VOPSOP solution for this? Thanks! Quote Link to comment Share on other sites More sharing options...
Macha Posted September 2, 2010 Share Posted September 2, 2010 Tricky, but perhaps it would help if you could give more information: Do you have many points and/or many curves? (ie the problem is the amount of curves or the amount of points?) Is there a reason why you can't do it with an expression in sops? Quote Link to comment Share on other sites More sharing options...
DanBode Posted September 2, 2010 Share Posted September 2, 2010 If you have an attribute on each point in the point cloud that denotes which curve it came from, you could import that into your pciterate loop and just ignore all the points in the point cloud that don’t match the attribute on the points you’re processing. If you’re using pcfilter, you’ll need to rewrite it with the extra pcimport and if statement, but that shouldn’t be too bad. I guess also you may need to raise the max points on your pcopen to compensate for all the points that are being ignored. Hope this helps! Quote Link to comment Share on other sites More sharing options...
pclaes Posted September 2, 2010 Share Posted September 2, 2010 The above solution with the pcimport will most likely be the fastest as it can be multithreaded. In regards of speeding up the foreach: if each curve corresponds to a single primitive, you can create an attribute "primnum" based on $PR. You can then use the foreach based on attribute and it will loop over all your primnum values. I found this to be a lot faster than working with numbers and even faster than working with groups. (Since the partition sop is often using a primitive attribute to create groups, you can use that directly with the foreach. -creating a lot of groups becomes very slow and if you can avoid it and instead use primitive attribute to make your selections that will be faster.) Quote Link to comment Share on other sites More sharing options...
Macha Posted September 2, 2010 Share Posted September 2, 2010 Here is a naive python solution. As it stands it is not very fast but I am certain with a bit of thinking and searching a much faster algorithm can be found. A clever mind could transcribe it to VEX I suppose. geo = hou.pwd().geometry() points = geo.points() for p in points: if p.attribValue("class") != -1: for p1 in points: if p1.attribValue("class") == -1 and p1.attribValue("num") == p.attribValue("class"): p1.setAttribValue("v", p.attribValue("v")) curveattrib.hipnc Quote Link to comment Share on other sites More sharing options...
Macha Posted September 2, 2010 Share Posted September 2, 2010 and a screenshot Quote Link to comment Share on other sites More sharing options...
SpencerL Posted September 2, 2010 Author Share Posted September 2, 2010 and a screenshot Thanks for your replies! Basically, I have a sim of around 50k pts and on each frame I need to grab the velocity attr from the curve which the point is assigned. Because of the high point count and that it needs to be calculated within the sim each frame, I really would prefer a vex/multithreaded solution over a foreach/python one. Peter, I knew that groups make foreach slow down considerably but I wasnt aware that using a prim attr is faster than using the numbers method. Ill definitely test that one, thanks for the tip! I have managed to mash together a pretty scary vopsop which does it using a method similar to what Peter suggested but its still lacking a few things. Once I get something working, Ill post an example. Thanks! Quote Link to comment Share on other sites More sharing options...
Macha Posted September 3, 2010 Share Posted September 3, 2010 I did some test with python and calculating 50000 points can be done in 0.15 seconds easily. Setting the attributes however pushes it up to about 1 second. How does that compare to vex? Is setting the attributes the bottleneck there as well? Quote Link to comment Share on other sites More sharing options...
SpencerL Posted September 3, 2010 Author Share Posted September 3, 2010 I did some test with python and calculating 50000 points can be done in 0.15 seconds easily. Setting the attributes however pushes it up to about 1 second. How does that compare to vex? Is setting the attributes the bottleneck there as well? 0.15s? I took your example file and on the scatter, I changed the point count from 500 to 50000 and the time went from 109ms to 8.09s. I had to copy your code from this thread into the myCurve1 SOP. Not sure where they would be, but did you somehow optimize your code so that it would run much faster? Quote Link to comment Share on other sites More sharing options...
Macha Posted September 3, 2010 Share Posted September 3, 2010 (edited) Well...I'm not sure what I did... I only rewrote it so I can test it easier, but somehow it is much much faster even though it does basically the same thing. Perhaps there is a bug in it but the output and some simple tests seem to give the same result...so I'm not sure. Here it is. sorry it's still messy. import time # This code is called when instances of this SOP cook. geo = hou.pwd().geometry() points = geo.points() # this is the object class P(object): def __init__(self, index=None, type=None, num=None, value=None): self.index = index self.type = type self.num = num self.value = value pList = [] for i in points: if i.attribValue("class")!=-1: pList.append(P(index=i.number(), type=i.attribValue("class"), num=None, value=i.attribValue("v"))) else: pList.append(P(index=i.number(), type=i.attribValue("class"), num=i.attribValue("num"), value=None)) #for item in pList: # print "index",item.index, " type",item.type, " num",item.num, " value",item.value print len(pList) t0 = time.time() for p in pList: if p.type != -1: for p1 in pList: if p1.type == -1 and p1.num == p.type: p1.value = p.value print "time0", time.time()-t0 for p in points: if p.attribValue("class") == -1: p.setAttribValue("v",pList[p.number()] Edited September 4, 2010 by Macha Quote Link to comment Share on other sites More sharing options...
Macha Posted September 3, 2010 Share Posted September 3, 2010 screen Quote Link to comment Share on other sites More sharing options...
Macha Posted September 3, 2010 Share Posted September 3, 2010 screen Quote Link to comment Share on other sites More sharing options...
Macha Posted September 3, 2010 Share Posted September 3, 2010 forgot... Quote Link to comment Share on other sites More sharing options...
Macha Posted September 4, 2010 Share Posted September 4, 2010 One more test. I thought that perhaps the assignment of attributes is random or incomplete, but partitioning them in a known configuration still gives a seemingly correct result. 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.