How to use Surface.ClosestPoint method?

I’m lookling at this:

https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.surface/closestpoint

Expecting to be able to do this:

u1, v1 = surface1.ClosestPoint(surface2.PointAt(0.5, 0.5))

But that fails with “too many values to unpack”. What am I missing?

Actually, there are too few values to unpack…
Surface closest point has 3 outputs. So you need to do like this:

OK, u1, v1 = surface1.ClosestPoint(surface2.PointAt(0.5, 0.5))
if not OK: print(" Closest Point Error ")

OK is either True or False depending on ClosestPoint success.

2 Likes

In general with RhinoCommon API and Python, when in doubt about what you receive from an API call you can always just put into one variable, and then print out the variable to inspect it (or put breakpoint and use debugger). You should see what sort of sequence you get back, how many elements.

1 Like

Wow, thank you!

I did not understand that from the documentation given.

Interesting. Whoever wrote the error message was apparently looking at things from the lefthand side of the assignment’s point of view: ie: the LHS is receiving “too many values to unpack” into the 2 variables it contains.

From what I have seen, that message can be either side of any operation where one side doesn’t match the expected number of items.

That is the Python implementation. This is unpacking works.

Python 3.11.7 (main, Apr 25 2024, 07:02:47) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def three_vals():
...     return 1,2,3
... 
>>> v = three_vals()
>>> v
(1, 2, 3)
>>> v1, v2 = three_vals()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>> 

On the left you say “I expect two values”, which will tell the interpreter that whatever sequence you get must be unpacked. On the right hand you have a method returning a tuple of length three. There is a mismatch there.

Edit: I suppose you could do extended unpacking, but that then requires you to write code to handle that. With the three_vals method from above:

v1, *vrest = three_vals()

This will put 1 in v1 and [2,3] in vrest.

1 Like