Getting Point coordinates [python]

I usually get coordinates with point.X, point.Y, point.Z, but it doesn’t work in the following code:


import scriptcontext as rs
import Rhino.Geometry as rg
import Rhino.DocObjects
import Rhino.Input

rs, list = Rhino.Input.RhinoGet.GetMultipleObjects("select control points",False,Rhino.DocObjects.ObjectType.AnyObject)

gripList = []

for gr in list:
    gripList.append(gr.Object())
    print(type(gr))

groList = []
for gro in gripList:
    groList.append(gro.DuplicateGeometry())
    print(type(gro))

for geo in groList:
    print(type(geo))
    
p1 = groList[0]

for p in groList:
    print(p)
    print(p.X)

image

and according to type(p) it is normal Rhino.Geometry.Point

image

Small trap there that I have run into often… Try p.Location to get the Point3d object which has .X, .Y and .Z

Thanks that worked.

So far so good, but the nightmare continues.

if I set p.Location it only sets the coordinates of that Duplicate object, and not the actual object that was grabbed. Which is a control point.

That AnyObject reminds me of StarCraft intro. “It says ‘press any key’, but which one’s the 'any” key" :smiley: :rofl:

You get the current location with p.Location, then you modify the point coordinates, then you set the grip with rs.ObjectGripLocation…

image

Hell

import scriptcontext as rs
import Rhino.Geometry as rg
import Rhino.DocObjects
import Rhino.Input

rs, list = Rhino.Input.RhinoGet.GetMultipleObjects("select control points",False,Rhino.DocObjects.ObjectType.AnyObject)

gripList = []

for gr in list:
    gripList.append(gr.Object())
    print(type(gr))

groList = []
for gro in gripList:
    groList.append(gro.DuplicateGeometry())
    print(type(gro))

for geo in groList:
    print(type(geo))
    
p1 = groList[0]

for p in groList:
    print(p)
    print(type(p))
    print(p.Location.X)
    print(p.Location.Y)
    print(p.Location.Z)
    p.Location.X = p1.Location.X
    p.Location.Y = p1.Location.Y
    p.Location.Z = p1.Location.Z
    print(type(gripList[groList.index(p)]))
    rs.ObjectGripLocation(gripList[groList.index(p)], groList.index(p), p1)


I really don’t understand what you are trying to do - perhaps you can explain with a concrete example of what you are trying to achieve… Why are you mixing rhinoscriptsyntax and RhinoCommon in this case?

You maybe want to read the help items for both RhinoCommon methods and rhinoscriptsyntax and see what types of objects they want as arguments and what they return.

For example here is the RhinoCommon GripObject (properties and methods)
https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_DocObjects_GripObject.htm
The grip’s location is found with GripObject.CurrentLocation, but it’s also {get ; set ; } - the ‘set’ means you can also give it a new location (haven’t tried, but that’s how it should work)

As for what rs.ObjectGripLocation wants it’s
https://developer.rhino3d.com/api/RhinoScriptSyntax/#grips-ObjectGripLocation
which says it wants a parent object ID, a grip index and the point to which you want to move it (optional)

Two different methods of attacking the same problem, but you just can’t freely mix and match without knowing what data types you are throwing back and forth.

Also if you want to see what RhinoCommon functions rhinoscriptsyntax methods are calling behind the scenes, read the function libraries here:

C:\Users\<username>\AppData\Roaming\McNeel\Rhinoceros\6.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript

–Mitch

You are overwriting rs on the first code line after your imports…

rs, list = Rhino.Input.RhinoGet.GetMultipleObjects("select control points",False,Rhino.DocObjects.ObjectType.AnyObject)

A mild case of PEBCAK. Also, you should not use the keyword list as a variable name.

alist = list()
print(alist)
list = "muahaha"
anotherlist = list() # oops

Whatever you do, never overwrite keywords - unless you know what you are doing.

Yes, well, since not everything is in rhinoscriptsyntax I have to mix it with RhinoCommon.

Do you think I don’t do that? I want to get the result as quickly as possible, with as less coding as possible. If I have to do that mixing ghpythonlib + rhinoscriptsyntax + rhinocommon I will. The API is done in such a way that you either go the long coding way of using only RhinoCommon, or you do only simple stuff pre-defined by whoever wrote rhinoscriptsyntax and ghpythonlib.

That example I took creates GripObjects without using “create a GripObject” syntax, which is less code => preferred way to go.

by the screenshot above I wanted to indicate that rs.ObjectGripLocation is not visisble in drop down list.

I use print(type(x)) to get what types I’m working for, the problem is the API documentation is inconsistant with what the method actually allows.

Example. that Point.X if you go to Rhino.Geometry.Point (and hit “.” (dot)), at the bottom of the list you’ll see “X”, “Y” and “Z”. But if you choose them the console will spit on you saying “Point has no attribute “X””. That is bull crap.

Then you enlighten me about point.Location.X now where is that written in the documentation that you can’t use point.X? How am I supposed to know and use that api if it is misleading?

What I am trying to do is grab a few control points and change their coordinates according to some rule. Like for exapmple select three points and change their coordinates to the coordinates of the middle point you’ve selected.

I don’t see .X, .Y, or .Z as Rhino.Geometry.Point properties here:
https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_Point.htm
All I see is Location.

I don’t see .X, .Y, or .Z either in the dropdown if I type Rhino.Geometry.Point.— Don’t know why you are seeing something different.

image

Point3d != Point

1 Like

Yes, I saw.

I wonder now why does it take (duplicate) a point when I am selecting a control point.

Why is there Point, Point2d, Point3d and Point4d.

I get the Point2d and Point3d but Point is that supposed to be UI point? And WTH is Point4d do you have the time derivative in there or it is the weight and that is the one I actually need to use when grabbing NURB control points?

Represents the four coordinates of a point in four-dimensional space.
The W (fourth) dimension is often considered the weight of the point as seen in 3D space.

https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_Point4d.htm

1 Like

Do I have to explicitly transform a Rhino.Geometry.Point into Rhino.Geometry.Point4d ?

Yep, something like
your_4d_point=Rhino.Geometry.Point4d(your_point.Location)
This will create a Point4d with weight 1.0, you can change it afterwards to:
your_4d_point.W=your_weight_value

or

pt=your_point.Location
Rhino.Geometry.Point4d(pt.X,pt.Y,pt.Z,your_weight_value)

Here is a quickie piece of rhinoscriptsyntax code that will let you pick some surfaces, turns on control points, lets you pick some points, then averages the Z value of all the picked points…

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

srfs=rs.GetObjects("Select surfaces to edit",8,True)
#turn on grips
for srf in srfs: rs.EnableObjectGrips(srf,True)
#pick some
grip_list=rs.GetObjectGrips("Pick some grips")
#extract objIDs, indices and locations
objIDs,indices,locations=zip(*grip_list)
#average the Z of all picked points
avg_Z=sum(location.Z for location in locations)/len(locations)
#set all the picked grips to that average Z
for i in range(len(grip_list)):
    locations[i].Z=avg_Z
    rs.ObjectGripLocation(objIDs[i],indices[i],locations[i])
#turn off grips
for srf in srfs: rs.EnableObjectGrips(srf,False)
1 Like

Thanks @Helvetosaur, I’ll try that.

ZIP I have never used that method :slight_smile: I’ll go read some more about it first.

Very handy. Note this is sort of a “reverse zip”, used with the * unpack operator… I always have to try this one out, because I never remember exactly how it works.

On prima vista it looks like ZIP is creating a list of multiple variables. I need deeper insight so I’ll read some more about it, indeed it looks handy.

Zip “zips” multiple lists together into a single nested list of tuples.

Combined with the * operator, it “zips” together the corresponding indices of the items in a nested list into a new nested list. This is a little like the “FlipMatrix” component in Grasshopper

a=[1,2,3]
b=[4,5,6]
c=[7,8,9]
result=zip(a,b,c)
print result
>>>[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
u=zip(*result)
print u
>>>[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
3 Likes