GHPython component can't interpret Rhino.Geometry.Curve[]?

Hi,

Say I have a Rhino.Geometry.Polyline pline and a couple of Rhino.Geometry.Arcs a1, a2, and a3.

When I do the following to join them into a single curve, I get a Rhino.Geometry.Curve[], as specified in the documentation.

import Rhino.Geometry as rg

a = rg.Curve.JoinCurves(
    [a1.ToNurbsCurve(), pline.ToPolylineCurve(), a2.ToNurbsCurve(), a3.ToNurbsCurve()], 0.01
)

When piping it through output a of a GHPython component, the latter seems unable to cast the curve array to a curve type that Grasshopper can interpret, and thus no geometry is previewed in Rhino, nor available to work on further.

Screenshot 2023-03-28 at 17.12.22

How do I get a joined curve that I can continue processing in Grasshopper?

Are the inputs Rhino Curves or GH curves?

1 Like

There are no geometry inputs. The arcs and polylines are generated with API code (rhinocommon).

Don’t those shapes need to be added to a document’s object table before they get a guid that the Geo param can find?

I think the trailing just means it’s an array, so you could also try a = list(a)

1 Like

No, I’m working in Grasshopper Python. No geometry is added to the Rhino document until you bake it, which I don’t and don’t want to.

There’s a pseudo document - ghdoc too

1 Like

I tried recreating the problem and couldn’t - it works OK for me. There’s probably an issue with your curves or polylines, or with your setup. The code below is heavily based on yours:


circ = Rhino.Geometry.Circle(Rhino.Geometry.Plane.WorldXY,5)
arc = Rhino.Geometry.Arc(circ,1)
p_1 = Rhino.Geometry.Point3d(5,0,0)
p_2 = Rhino.Geometry.Point3d(5,-5,0)
p_line = Rhino.Geometry.Polyline([p_1, p_2])
objs = [arc.ToNurbsCurve(), p_line.ToPolylineCurve()]

joined = Rhino.Geometry.Curve.JoinCurves(objs)

a = joined

joined_curve

1 Like

Thanks for the example. I’ve posted it into a fresh GHPython and it works for me too.

What I’ve noticed is that the end point of the first arc that needs to be joined to the start point of the polyline deviates ever so slightly, but that difference should be absorbed by the tolerance value.

1 Like

I don’t get it. When I output the arcs and polyline separately and join them in Grasshopper, it works.

How strange. Well done working that out.

1 Like

I haven’t worked it out yet. No idea why it doesn’t work? I’ll revisit it tomorrow evening, when I have less on my plate. :slight_smile:

All to be joined curves have the appropriate directions, the meeting end points line up within the set tolerance, and my code is very similar to yours, yet the GHPython outputs a Rhino.Geometry.Curve[], instead of a Planar Curve, which Grasshopper can not post-process.

Have you increased the tolerance, to see if it’s an unusual metric or a units problem?

1 Like

I did this:

import Rhino
import math

p0=Rhino.Geometry.Point3d(0,0,0)
p1=Rhino.Geometry.Point3d(10,10,0)
p2=Rhino.Geometry.Point3d(20,10,0)
p3=Rhino.Geometry.Point3d(20,0,0)
p4=Rhino.Geometry.Point3d(10,0,0)
p5=Rhino.Geometry.Point3d(5,0,0)

pline=Rhino.Geometry.Polyline([p1,p2,p3,p4])
arc1=Rhino.Geometry.Arc(p5,5.0,-math.pi)
arc2=Rhino.Geometry.Arc(p0,Rhino.Geometry.Vector3d.YAxis,p1)

plc=Rhino.Geometry.PolylineCurve(pline)
arc_crv1=Rhino.Geometry.ArcCurve(arc1)
arc_crv2=Rhino.Geometry.ArcCurve(arc2)
a=Rhino.Geometry.Curve.JoinCurves([plc,arc_crv1,arc_crv2])

Which results in a outputting a closed planar curve.

If I change the line

arc1=Rhino.Geometry.Arc(p5,5.0,-math.pi)

to

arc1=Rhino.Geometry.Arc(p5,5.0,-math.pi/2)

so that the curve doesn’t close, I get an open planar curve.

Edit: Note this also works here:

import Rhino
import math

p0=Rhino.Geometry.Point3d(0,0,0)
p1=Rhino.Geometry.Point3d(10,10,0)
p2=Rhino.Geometry.Point3d(20,10,0)
p3=Rhino.Geometry.Point3d(20,0,0)
p4=Rhino.Geometry.Point3d(10,0,0)
p5=Rhino.Geometry.Point3d(5,0,0)

pline=Rhino.Geometry.Polyline([p1,p2,p3,p4])
arc1=Rhino.Geometry.Arc(p5,5.0,-math.pi)
arc2=Rhino.Geometry.Arc(p0,Rhino.Geometry.Vector3d.YAxis,p1)

a=Rhino.Geometry.Curve.JoinCurves([pline.ToPolylineCurve(),arc1.ToNurbsCurve(),arc2.ToNurbsCurve()])
1 Like

You might try building a PolyCurve, instead of joinnig the curves.
PolyCurve Class (rhino3d.com)
If it does not work, then I guess some curve may have problems.

1 Like

Sure, I’ve tested the tolerances 0.0001, 0.001, 0.01, 0.1, 1.0, and 10.0 just to make sure, but to no avail. Thanks for keeping on suggesting things.

Cool, …, cool, cool, cool that’s exactly what I do, but I get a Rhino.Geometry.Curve[] as output.
My polyline and arcs also build an open curve. Thanks for the reply.

Thanks, I’ve tried that already. I’ve tested joining to NurbsCurve, PolyCurve, and the mother of all curves Curve. :slight_smile:

Yes, that was my suspicion too, but I previously had output the three curves separately and joined them in Grasshopper and that had worked flawlessly. Unless there’s some magic fixing going on under the hood, the curves should be fine.

Back to drawing board I guess. None of you are on macOS, right?

You’ll have to post more context wrt the code you use.

I’m on MacOS and I have no problem getting a single curve out of it using Rhino 7 using the code by @Helvetosaur.

Instead of focusing on JoinCurves you should look at (and show us) how you do the rest, otherwise it’ll be just a guessing game.

1 Like

That’s exactly what JoinCurves() returns…

As Nathan said, I think we’ll need to test with the same data you are using.

1 Like

I unfortunately can’t post the code for various reasons, otherwise I would have! I’ve done my best to describe the situation as clear as possible!

I’ve figured it out!! The issue is not my data…

I do all of the above within a function that returns a list of objects, namely the first arc (Rhino.Geometry.Arc), the polyline (Rhino.Geometry.Polyline), the second arc (Rhino.Geometry.Arc), the newly joined curve array (Rhino.Geometry.Curve[]), and another joined curve array (Rhino.Geometry.Curve[]).

Now, when I call the function and pipe its return values through output a, the GHPython component seems unable to do it’s casting thing in the background or something?

import Rhino
import math


def foo():
    p0 = Rhino.Geometry.Point3d(0,0,0)
    p1 = Rhino.Geometry.Point3d(10,10,0)
    p2 = Rhino.Geometry.Point3d(20,10,0)
    p3 = Rhino.Geometry.Point3d(20,0,0)
    p4 = Rhino.Geometry.Point3d(10,0,0)
    p5 = Rhino.Geometry.Point3d(5,0,0)

    pline = Rhino.Geometry.Polyline([p1,p2,p3,p4])
    arc1 = Rhino.Geometry.Arc(p5,5.0,-math.pi)
    arc2 = Rhino.Geometry.Arc(p0,Rhino.Geometry.Vector3d.YAxis,p1)
    
    crv = Rhino.Geometry.Curve.JoinCurves([pline.ToPolylineCurve(),arc1.ToNurbsCurve(),arc2.ToNurbsCurve()])
    
    return arc1, pline, arc2, crv


if __name__ == "__main__":
    a = foo()

When I only return one joined curve array (Rhino.Geometry.Curve[]), I also get a planar curve.

@nathanletwory As soon as a list is returned from the function, the output doesn’t seem to be able handle the situation any more. Maybe it confuses the iterable types within the list as a list or lists?

@Helvetosaur A big thanks for the boiler plate code, which eventually lead to a diagnose at least. :slight_smile:

Thanks for the support everybody!! :smiling_face_with_three_hearts:

It probably gets confused indeed.

If you are always expecting at most one curve out of the JoinCurves you can use crv[0] in the return statement.

1 Like