Grasshopper

algorithmic modeling for Rhino

Hi guys.

I am sorting collection of points by whether they are on a curve or not. My code runs through all the points and measures the distance to the curve, if this is small enough the points belong to the given curve. But in my case I have around 60 curves and about 30 points pr. curve. 

So the calcs are pretty slow (4-5s).

Does anybody have a smatter and faster way to do it?

Thanks

Rasmus 

Views: 3732

Replies to This Discussion

I think you made need to post some code. It's hard to tell if there's a potential bottleneck otherwise.

Hi Ramus,

In case you are using rhinoscriptsyntax, try RhinoCommon! It is magically faster in some cases.

Mostapha

PS: If there was a like option, I would like Anders's comment! ;)

I think I meant to say "..you may need to post some code". But yeah, what Mostapha is saying certainly seems to be the case sometimes. From looking at the code on the Mcneel Github this may have to do with the rhinoscriptsyntax functions often working on GUIDs and the reference/adding of geometry to the current script context. Not sure about this theory though! 

Consider it liked :D

Hi guys. 

The reason why I did not post the code, was because it is very simple, but here it goes:

Here I have been trying with rs.isPointOnCurve boolean instead of measuring the distance, but it is only marginally faster. So @Mostahpa yes I am using the rhinoscriptsyntax. How would you propose using the rhinocommon here?

Rasmus

Hi Rasmus,

Have a look at the attached file. It shows how one might implement the corresponding RhinoCommon method and also profiles and compare the two. It turns out that RhinoCommon is indeed substantially faster. You'll notice that I use Pythons own time library for the profiling. Sometimes Grasshoppers profiling may be a bit misleading if you're trying to optimize functions within a scripting component. BTW, you can upload .py files with code, which is a convenient workaround for the lacking code representation of the Bing forum.

Best,

Anders

The file somehow got corrupted, here's a re-upload.

BTW the call to the RhinoCommon function could also be done right on the object like so:


curveToCheck.ClosestPoint(pointToCheck,0.0001)[0]:

Attachments:

Hi Rasmus,

Beside using RhinoCommon (Thanks Anders!), in case each and every point on your test is only and only on one curve you can also add a break to your for loop.

Mostapha

Hi Guys.

@Anders - Thanks alot for taking your time for this. Perfect. It is funny how the RhinoCommon makes it around 5 times faster. Is that a general thing? So that it in many cases would be better to use rhinocommon that rhinoscript syntax?

@Mostapha - Thanks for your tips. I am not sure what you mean exactly? Do you mean count the points and then break when there is "enough" points on the curve?

for curve in curves 

Hi Rasmus,

Sorry not to be clear enough and sorry to reply late.

I meant that if you don't have any point that is on multiple curves then the first curve you find is the answer and you don't need to check the rest of the list. The pseudo-code would be something like this:

# make an empty list for each curve

# for point in points:

   # for curve in curves:

      # if point is on the curve:

          # append it to the corresponding list

          #break [so you don't check it for the rest of the curve...

            Except of the points which are on the last curve,

            or the points which are not on any of the curves

            It saves you some time!]

# do the branching here for the points in your list

I hope it helps,

Mostapha

Hi again Anders. I forgot to ask you, when you used:

rc.geometry.curve.curveClosestPoint.... etc. - you ended you statement with [0], is that just to get the first item of the return? And also, when using an if-statement and then no ==, does that just look for True?
Nice trick, but I would like to understand it fully.

Cheers Rasmus

The brackets are indeed for accessing the first element in the tuple returned by the function. I can't quite remember it but I believe it returns (isPointCurve, parameterOnCurve). By the way it is possible to directly assign both these elements by "unpacking" the tuple like so:

boolean, parameter = curveToCheck.ClosestPoint(pointToCheck,0.0001)

This will assign the first element in the tuple to the variable boolean and the second to parameter.

Regarding you second question, yes that is correct. It would be the same as writing "If variableName == True:" I tend to just use this shorthand if there are no "if/else statements following it. Otherwise it can be a bit hard to read the logic. But in general Python is full of this useful shorthand stuff.

Personally I prefer to use RhinoCommon for most things. In particular in GH components since you can more or less completely get around using GUIDs and such and just focus on objects. And if that also means a boost in performance, well then that's just gravy on top I should say :)

RSS

About

Translate

Search

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service