Importing Rhino extractpt as point 3d in Python

Hi there,

I am trying to import points I have generated using extractpt in the base Rhino software for use in running a Python script.

As it stands right now, I have a version of a script that generates points by dividing the surface (in this case, a topo surface). I would like to be able to use the points that were created within Rhino to give the user more control over how these are generated. The problem I keep running into is that they are apparently coming in as ‘Guid’ objects, not point 3d objects.

To add to this I know nothing about Python and scripting language (this is for a class project, for which scripting is a requirement) so identifying where the issue is is not within my wheelhouse.

I’ve uploaded the current Python script I’ve been able to run that divides the surface to create the points, but as I mentioned before, I need it to be able to run using points created within the Rhino software itself.

Thanks in advance for any help you can provide!

Tool.py (1.9 KB)

Hi @jessyesterday,

The rs.AddPoint method adds a point object to Rhino. Point objects, like other Rhino objects, have properties such as layer, color, etc., in addition to their geometric properties.

If you want the 3-D point location of a point object, then use rs.PointCoordinates.

import rhinoscriptsyntax as rs

object_id = rs.GetObject("Select point object", rs.filter.point)
if object_id:
    point = rs.PointCoordinates(object_id)
    if point:
        print point

Does this help?

– Dale

@dale

I tried using rs.AddPoint and using the list of points from the original GetObject command as the list, but there is still something in the script causing it to fail.

I’m not sure if this is something leftover from the original method I was using to generate the points or if there is something going wrong with the AddPoint feature.

Hi @jessyesterday,

Your script runs here without any error. Thus, I am unable to determine what you really want to do. Perhaps more of an explanation as to what you want to do and why might help?

– Dale

@dale

My goal is to have a script that runs with points that are not generated within the Python script itself. Ultimately, I need the user to be able to control how the points are generated.

As the script currently stands, the points it is using are generated within the script. I need it to be able to run using points not generated within the script. Essentially, the whole first part of the script that deals with point generation needs to operate more as a rs.GetObjects component. The problem I’m encountering is the points that come in from that are Guid objects, not point3d, therefore the rest of the script cannot run.

Hi @jessyesterday,

Again, if you have the Id of a point object and you need it’s 3-D location, use rs.PointCoordinates.

import rhinoscriptsyntax as rs

# Select one or more point objects
objects = rs.GetObjects("Select point objects", rs.filter.point)
if objects:
    points = []
    # Get the 3-D location of the point objects
    for obj in objects:
        points.append(rs.PointCoordinates(obj))
    # TODO: Do something with locations
    for pt in points:
        print pt

Not sure how else to help.

– Dale

@dale

My problem, as I explained, is that when I use rs.GetObjects to grab points from Rhino, the script brings back an error telling me they are Guid, not 3d point objects, which is causing errors in the rest of the script. That tells me (again, I don’t know scripting, so this may be completely wrong) that trying to grab the 3d location would also bring back an error since they’re not coming in as 3d points. I’m trying to convert from Guid to 3d points that I can use in the script.

I’m not sure how else to explain my issue. I’ve been told it’s a relatively simple one, it seems simple enough to understand to me, but Google searches have been unhelpful.

Have a look at the coerce functions:

Hi Jess - I think the key thing here is to differentiate between points as Rhino objects in the file and points as a list of xyz coordinates or Rhino.Geometry.Point3d() - what you’re getting as guids are the former and you need to extract the coordinates form the objects of you need to do something with those.
When you get a point that is an object in the Rhino file with rs.GetObject() you get a point “thing” that has a guid and that guid is what rs.GetObject() returns. The point ‘thing’ that the guid refers to has an existence. so to speak, in the Rhino document just like a line or a sphere that you can pick and move or delete etc. BUT among the characteristics of the point is its location - its xyz coordinates. So you can ask Rhino what the coordinates are by using rs.PointCoordunates(guid) With those coordinates you can make, if you need to a Rhino.Geometry.Point3d() (or coerce3dpoint() as mentioned above)

@jessyesterday. I monkeyed with your script a bit and added a couple of comments - I’ll attach it in case it helps.

Tool_PG.py (3.3 KB)

-Pascal

@pascal @AndersDeleuran

I’ve tried the coerce commands, but I must be completely misunderstanding something about how they work.

I tried bringing in the points I created in Rhino and creating spheres from them to test if the coerce command is working, but it’s not. I’m attaching a screenshot of what I’m getting. Of course, I need these points to run through a more complex script than just creating spheres, but if they can’t even do that I’m hopeless.

Please point me in the direction of what I’m doing wrong (and try to keep the language as free of jargon as possible).

As the original post states, I know nothing about scripting language. I wouldn’t even be working with this if it wasn’t a requirement of my “thesis” studio.

Hello - as you’ve typed it, ptguid is a list of guids (from rs.GetObjects() plural) so you’d need to iterate that list to get a list of points

pts = [rs.coerce3dpoint(guid) for guid in ptguid]

And then of course iterate the list of points to make spheres:

sph = [rs.AddSphere(pt, 5) for pt in pts]

In this case, sph will be a list of new guids for the spheres.

-Pascal

@pascal

That does not seem to be working either, and at this point, I am unable to comprehend the problem.

PS, thank you for trying to help me through this!

Hello - try-

ptIds = rs.GetObjects(filter=1) #< list of point object GUIDS!
pts = [rs.coerce3dpoint(id) for id in ptIds] # < list of point3ds
sph = [rs.AddSphere(pt, 5) for pt in pts] # < list of sphere object GUIDS

-Pascal

I copied that exactly into the script, and it came back with:

Message: ‘module’ object has no attribute ‘coerce3dpt’

Traceback:
line 5, in , “C:\Users\Jess\AppData\Local\Temp\TempScript.py”

line 5 is where I am trying to run the coerce3dpoint

Yes, sorry - coerce3dpoint

-Pascal

That worked! Thank you!

So now I should, in theory, be able to follow those steps for my initial point selection and replace the point generation section of my original script, and it will hopefully be able to run since the points are 3d now?

Hello - yes, in general - you need to keep asking yourself whether you’re dealing with objects (guids) or point3ds when ever you find yourself using the word ‘point’. And one dimension deeper, as I see this also caused you problems, you need to understand whether you’re dealing with one or a list (of points ot guids or anything else)

-Pascal

Thanks again! That took care of a major snag that kept holding me back.

Can I ask the inverse of this question? I have a list of points in the form of x,y,z and I need their GUID, is there any way to do that? thanks in advance