Move end point of curve to make it close [Rhino, Python]

For NOT closed curve, any ways to just move the end point of it to the start point to make it close, while the rest of the curve is the same?

Thanks a lot!!!

Hi James,

If I understood you correctly, try this:

import rhinoscriptsyntax as rs

crv = rs.GetObject("pick up your curve")
crv_degree = rs.CurveDegree(crv)
stPt = rs.CurveStartPoint(crv)

pts = rs.CurvePoints(crv)
pts[-1] = stPt

rs.AddCurve(pts, crv_degree)

The problem is that your new curve might be slightly deformed in comparison to the original one, even though they have the same control points.
So this method will basically only work with curve of degree 1 (polylines).

I don’t know if this will work with all curves, but you might try the following:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

def CloseCrvMoveEndPt():
    crvID=rs.GetObject("Select curve to close",4,True)
    if not crvID: return
    if rs.IsCurveClosed(crvID):
        print "Curve is already closed!" ; return
        
    if rs.CurvePointCount(crvID)>=3:    
        crvGeo=sc.doc.Objects.Find(crvID).Geometry
        sPt=crvGeo.PointAtStart
        crvGeo.SetEndPoint(sPt)
        sc.doc.Objects.Replace(crvID,crvGeo)
        sc.doc.Views.Redraw()
    
CloseCrvMoveEndPt()

Edit - added a couple of safeguards…
–Mitch

1 Like

Thank you all!!

But i suddenly think that the command “CloseCrv” is the best method to do it. The question is after: rs.Command("-CloseCrv"), it requires me to manually select an open curve. How can i assign an object for it automatically?

Thx!!!

1 Like

You could create a line between your curve start and end points, and then join that line with curve:

import rhinoscriptsyntax as rs

crv = rs.GetObject("pick up the curve")
stPt = rs.CurveStartPoint(crv)
endPt = rs.CurveEndPoint(crv)
line = rs.AddLine(stPt, endPt)
rs.JoinCurves([crv,line])
rs.DeleteObjects([crv,line])

or use Rhino’s “CloseCrv” command:

import rhinoscriptsyntax as rs

crv = rs.GetObject("pick up the curve")
rs.Command("_CloseCrv SelId %s _Enter" % crv)
1 Like

Hello,
Can you explain why replace is necessary? Is there a way to do it by just drawing a new curve from the geometry?

Sure. The Replace method was just to maintain the same object ID as the original. Otherwise instead of

sc.doc.Objects.Replace(crvID,crvGeo)

use this

new_crv_ID=sc.doc.Objects.AddCurve(crvGeo)

which will give you a new curve and leave the original.

ok, thanks