How is it possible to edit editpoints in Rhino common?

Hi @pascal and @stevebaer
I am working on a script where I make a simplified offset of a 3D curve and I need to adjust the location of the new curve editpoints, but I have not figured out how, so I hack around it.

Here is what I do:

  • project 3D curve to xy-plane
  • offset the 2D curve
  • find closest point of each editpoint of the offset
  • move each editpoint to corresponding height of 3D curve

In the workaround I add the offsetcurve to document, turn on editpoints and move them with rs.ObjectGripLocations() and then coerce the result and delete the temporary curve.
But this slows down the process and makes the code more messy, is it possible to do it in Common directly?


### Offset_2.5D_curve by Holo 2024

import rhinoscriptsyntax as rs
import Rhino
import Rhino.Geometry.Curve as curve
import scriptcontext as sc

def offset3dcurve(curve):
    plane = rs.WorldXYPlane()
    curve2D = Rhino.Geometry.Curve.ProjectToPlane(curve, plane)
    distance = 1
    tolerance = 0.05
    cornerstyle = Rhino.Geometry.CurveOffsetCornerStyle(1)
    offset2D = Rhino.Geometry.Curve.Offset(curve2D, plane, distance, tolerance, cornerstyle)
    offset_id = sc.doc.Objects.AddCurve(offset2D[0])
    rs.Command("_NoEcho _PointsOff _EditPtOn", False)
    grips = rs.ObjectGripLocations(offset_id, points=None)
    for i in range(len(grips)):
        param = curve2D.ClosestPoint(grips[i],0)
        closepoint = curve.PointAt(param[1])
        point = rs.coerce3dpoint((grips[i].X,grips[i].Y, closepoint.Z))
        rs.ObjectGripLocation(offset_id, i, point)
    offsetcurve = rs.coercecurve(offset_id)
    return offsetcurve

curve_id = rs.GetObject("curve to offset", rs.filter.curve, preselect=True)
if curve_id:
    curve = rs.coercecurve(curve_id)
    offsetcurve = offset3dcurve(curve)

Here you can see why I do this.
Rhino’s offset result to the left, my script to the right:

(PS! Right now I just use w0,0,0 as the offsetdirection to keep the example script as simple as possible)

Hi @Holo,

For NURBS curves, you can bypass grip editing by using NurbsCurve.GetGrevillePoints and NurbsCurve.SetGrevillePoints.

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

id = rs.GetObject(preselect=True)
crv = rs.coercecurve(id)
grvs = crv.GrevillePoints(False)

for i in range(len(grvs)): 
    pt = grvs[i]
    grvs[i] = Rhino.Geometry.Point3d(pt.X, pt.Y, 10)
print crv.SetGrevillePoints(grvs)

sc.doc.Objects.Replace(id, crv)

– Dale

1 Like

Thanks, I got it working, but it seems I can’t use it on PolyCurves as it has no greville points… and if I convert the polycurve to a NurbsCurve then all segments gets the highest degree and i end up with this (see selected curve), it deviates compared to the original that has straight sections.

I guess there are no easy workaround for this.

Question and wish:
One thing I do wonder though is why do you call these points EditPoints in Rhino, Grips in Python and Grevillepoints in Common? I wish there was one naming to rule them all (And that it was possible to manipulate all curves through code like we can manipulate them in Rhino.

For polycurves, no. In this case, grips are your friend.

– Dale

Historic. I’m sure in a discussion long ago we deemed “Greville” user unfriendly.

Grips are temporary Rhino objects that are used to manipulate their owning object. Lots of objects can have grips: curve, surfaces, annotations, etc. Grips are not just edit points.

– Dale

OK, thanks for trying to explain. One last question and I will leave this alone:
So does that mean that when “we” in Rhino 7 and 8 turn on editpoints to manipulate polycurves then you do some crazy magic to workaround Rhino Commons limitations, or are the editpoint/grips/grevillepoint magic just not hooked up to our side of Rhino Common?
(I kind of dug to deep to not be satisfied with just letting it go before I understand… Hope you can relate to that itch :wink: )