Gh Python - Join Curve Segments

Hello,

I am trying to create a Component
wich snaps the ends of an open curve in the middle of the endpoints to close it.
Since the curve is an assambly of various bended segments wich has some sharp edges I explode it first.
Then I rebuild the start- and endsegments.
Now I want to rejoin everything, but get an error.

import rhinoscriptsyntax as rs

##############################################
##############################################

# Ensure variable is defined
try:
    tol
except NameError:
    tol = None

# Test whether variable is defined to be None
if tol is None:
    tol = 0
##############################################
##############################################

#get endpoints and the middle between them - Point


if rs.IsCurve(opCrv): # and not rs.IsCurveClosed(opCrv) and rs.IsCurveClosable( opCrv, tol ):
    cePt = rs.CurveEndPoint(opCrv)
    csPt = rs.CurveStartPoint(opCrv)
else:
    print "not an open curve in respect to the given tolerance"


dist = rs.Distance(cePt, csPt)
nePt = cePt - csPt
nePt = rs.VectorUnitize(nePt)
nePt *= dist/2


midVec = rs.VectorCreate(cePt, csPt)
midVec = rs.VectorDivide(midVec,2)
matrix = rs.XformTranslation(midVec)

nePt = rs.PointTransform(csPt, matrix)

##############################################

#get points of start and end segment for rebuild
segCrvList = rs.ExplodeCurves(opCrv) #gives a list

sSeg = segCrvList[0]
eSeg = segCrvList[len(segCrvList)-1]

sSegPt = rs.CurveEditPoints(sSeg)
ssSegPt = sSegPt[0]
 
eSegPt = rs.CurveEditPoints(eSeg)
eeSegPt = eSegPt[len(eSegPt)-1]

#replace points and rebuild of segments

sSegPt[0] = eSegPt[len(eSegPt)-1] = nePt

sSeg = rs.AddInterpCurve(sSegPt)
eSeg = rs.AddInterpCurve(eSegPt)

#replace segments and join all into closed curve
segCrvList[0] = sSeg
segCrvList[len(segCrvList)-1] = eSeg


clCrv = rs.JoinCurves( segCrvList, delete_input=True, tolerance=tol)

Error:

0. Runtime error (NullReferenceException): Object reference not set to an instance of an object.

Traceback (most recent call last):
SystemError: Object reference not set to an instance of an object.

What is wrong?

Hey can your upload your file?
Most Problems with ghpython -in my experience- stem from the inputs, typehints and acces paramters on the component itself. also it would be really helpful to see in which line your error occurs.

Here it comes:
openCloseCrv_.gh (16.1 KB)

Hi, My Pufferfish Plug-in has a component Close Curve which has a Meet Ends option that does just that.


Close Meet Ends.gh (11.8 KB)

Hi Michael,
thanks for the reply. I am perfectly aware of Pufferfish.
I have to deliver files without plugins! That’s wy I have to build tools myself.
I already built a solution with GH-components.
The reason for asking me here, is to learn Python.

Ah well the method is simpler than what you are doing. Once you have the mid point you can just change the end points to be that point with SetStartPoint and SetEndPoint.

Thanks again. That’s helpful.
For learning purposes I would be interested in a solution for the initial question:
Why does this not work:

clCrv = rs.JoinCurves( segCrvList, delete_input=True, tolerance=tol)

Coming back to your script, if delete_input is set to False it works.

Also i agree with Michael that your method seems rather complex for what you want to do.

this might be a bug with the rs.joincurves i will do some testing on that

1 Like

Thanks, I’ll have a look tomorrow.

I try to stay away from exploding and then joining curves as much as possible as it often doesn’t keep the segment order (then your seam location is really up to whatever Rhino decides it should be) Where as with Set Start and Set End you will know your curves seam will always be at that midpoint. Also, re-interpolating curves will be less accurate to the original curve (if you really wanted to be accurate you would know the initial segments degree and control point weights and set those back to the new segment - but who wants to do all that when setting the points takes care of it for you :smiley: )

Oh totally i just tried to fix what was already there, personally i stay away from rhinoscriptsyntax entirely because everytime i use it i find myself scraping to here trying to find out what those functions actually do and why it doesn’t work.

In this case the problematic part is in the rs.joincurves function

    if rc and delete_input:
    for id in object_ids:
        id = rhutil.coerceguid(id, True)
        scriptcontext.doc.Objects.Delete(id, False)

i don’t understand enough about how gh references internalized curves in the Rhinodoc.Activedoc but probably some

scriptcontext.doc = Rhino.Rhinodoc.Activedoc
# do stuff
scriptcontext.doc = ghdoc

is called for here.

And i suppose there is no good reason to delete those curves to begin with because they are feeding into the component. SO we come back to the originial argument:
this could be solved more easy

1 Like

…That’s the hard fate beeing a greenhorn!

I have a working solution now, using SetStartPoint and SetEndPoint.
I tried to go a step further avoiding rs completely, but I got stuck.
I am not sure about the syntax.
Another question is how to know, wich library I have to import.
Are there any hints about this?

openCloseCrv__.gh (12.8 KB)

I added an example using just Rhinocommon

openCloseCrv__.gh (17.6 KB)

in Words:

  • check for bad input
  • draw a line between start and end point of your curve
  • set start and endpoint of your curve to the midpoint of the line Line.PointAt(0.5)

Edit:

import Rhino
import scriptcontext as sc

should be enough for most things. For scriptcontext and when to change it, trial and error will show and also this wa sa great help for me http://cu.t-ads.org/tips-script-context-in-gh-python/

Thanks again.
I am digging into it.