Hey Brad, I wondered if using math directly would be faster than working with XSIMath objects, so I tried. You probably knew this, but to get a distance between two 3D vectors the formula is quite easy:
* d = √ (Ax-Bx)2 + (Ay-By)2 + (Az-Bz)2 * where A and B are two vectors to measure from. However, you can skip the squareroot if you're only comparing relative distances. Squareroots can be computationally expensive. Knowing this, I wrote a version which appears to run about 77% faster, and it's shorter too! (It takes 4.5s testing a null near a 1000x1000 pointcloud grid, vs your code taking about 20.3s on the same task.) def FindClosestPoint( inObj, inPos ): fX, fY, fZ = inPos.Get2() pts = inObj.ActivePrimitive.Geometry.Points pos = pts.PositionArray d = dict( [ (i, (fX-pos[0][i])**2 + (fY-pos[1][i])**2 + (fZ-pos[2][i])**2 ) for i in xrange(pts.Count) ] ) closestIndices = sorted(d, key=d.get) # distance = d[closestIndices[0]]**0.5 return closestIndices[0] I love me a Python optimization challenge. :) Cheers, -- Alan ps: Friendly nod to Xavier for pointing out "**" syntax does "to the power of" so I don't need to use math.pow() in my code. On Tue, May 1, 2012 at 5:55 PM, Bradley Gabe <witha...@gmail.com> wrote: > Sure, have at it: > > def FindClosestPoint( inObj, inPos): > dist = 10000 > ID = -1 > Pos = XSIMath.CreateVector3() > PosArr = inObj.ActivePrimitive.Geometry.Points.PositionArray > for index in range(inObj.ActivePrimitive.Geometry.Points.Count): > Pos.Set( > PosArr[0][index], > PosArr[1][index], > PosArr[2][index] > ) > Pos.SubInPlace(inPos) > D = Pos.Length() > if D < dist: > dist = D > ID = index > return ID > > > > > On Tue, May 1, 2012 at 5:52 PM, Alan Fregtman <alan.fregt...@gmail.com>wrote: > >> Care to share a sample snippet? Maybe there are even faster ways to >> approach it. >> >> >> On Tue, May 1, 2012 at 5:42 PM, Bradley Gabe <witha...@gmail.com> wrote: >> >>> UPDATE: >>> >>> All things considered, it's not too horrible simply looping through >>> every position from the Geometry.Points.PositionArray, and comparing the >>> distance in order to find the closest point in the cloud. So far, that >>> technique is faster than anything else I've attempted to cook up. >>> >>> -Bradley >>> >>> >>> On Tue, May 1, 2012 at 3:01 PM, Bradley Gabe <witha...@gmail.com> wrote: >>> >>>> Nah, it was raising errors when I tried it before starting this thread, >>>> and it still is now [?]: >>>> >>>> # ERROR : 2028 - Traceback (most recent call last): >>>> # File "<Script Block >", line 2, in <module> >>>> # obj.ActivePrimitive.Geometry.GetClosestLocations([0, 0, 0]) >>>> # File "<COMObject <unknown>>", line 2, in GetClosestLocations >>>> # COM Error: Invalid argument specified. - [line 2] >>>> >>>> >>>> On Tue, May 1, 2012 at 2:58 PM, Bradley Gabe <witha...@gmail.com>wrote: >>>> >>>>> I was going by the following quote from the docs: >>>>> >>>>> Note: Point locators are currently only supported by NurbsSurfaceMeshand >>>>>> PolygonMesh objects. >>>>> >>>>> >>>>> But I'll still give it a shot... >>>>> >>>>> >>>>> On Tue, May 1, 2012 at 2:54 PM, Stephen Blair < >>>>> stephen.bl...@autodesk.com> wrote: >>>>> >>>>>> But doesn't a PointCloudGeometry support GetClosestLocations? Can you >>>>>> use that (I didn't try it yet) ? >>>>>> >>>>>> >>>> >>> >> >
<<347.gif>>