PolyCurve Segments

Hi,

I believe a PolyCurve can be made up of different line types, like straight lines and arcs? If this is true is there a way to gain access to each segment to control, for example, the end points of line or the radius and center point of an arc. I understand that if the curve is converted to a Polyline one does have access to the points. Problem is polylines with arcs have many points around the arcs.

Here is a screen shot where I have marked the points of a polyline. You can see the arc problem when converted to a polyline.

Any help with this would be appreciated.


Yes

Use PolyCurve.SegmentCurve.

– Dale

Thanks Dale. I’ll look at that.

Eric

That will work. Thank you.

Eric

Follow up question: PolyCurve.SegmentCurve gives me access to the segment, that much works. If one wanted to modify a segment, for example an ArcCurve Radius, is this possible to do? Can you manipulate the properties of the curve and ultimately the PolyCurve?

Eric

Hi @eric.bunn,

Yes. The process would be to create a new polycurve and then add the segments from the old one to the new one, include any curves you want modified.

– Dale

Dale,

Can you steer me in the direction of any example code?

Eric

How about this?

import Rhino
import scriptcontext as sc

def test_duplicate_polycurve():
    
    filter = Rhino.DocObjects.ObjectType.Curve
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select polycurve", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success: 
        return

    curve = objref.Curve()
    if not curve:
        return
        
    if not isinstance(curve, Rhino.Geometry.PolyCurve):
        return
        
    polycurve = Rhino.Geometry.PolyCurve()
    
    for i in range(0, curve.SegmentCount):
        segment = curve.SegmentCurve(i).DuplicateCurve()
        # todo: modify segment curve...
        polycurve.AppendSegment(segment)
    
    sc.doc.Objects.AddCurve(polycurve)
    sc.doc.Views.Redraw()
        
test_duplicate_polycurve()

– Dale

Dale

Thank you. I think this will work for me.

Eric

Dale,

This does what I need up to manipulating the segments. See modified code below. I am trying to modify the segment (ArcCurve) Radius but get a read only error. I used TryGetArc to get the arc and then modify it’s radius, which works. Problem is now that when trying to append the arc to the new polycurve I get the error: Message: expected Curve, got Arc. I’m guessing I need to get the curve from the arc but cannot determine how to do this?

Any help would be greatly appreciated. Look in #todo section.

import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs

def test_duplicate_polycurve():
    
    filter = Rhino.DocObjects.ObjectType.Curve
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select polycurve", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success: 
        return

    curve = objref.Curve()
    if not curve:
        return
        
    if not isinstance(curve, Rhino.Geometry.PolyCurve):
        return
        
    polycurve = Rhino.Geometry.PolyCurve()
    
    for i in range(0, curve.SegmentCount):
        segment = curve.SegmentCurve(i).DuplicateCurve()

        # todo: modify segment curve...
        if segment.IsArc():
            arc = Rhino.Geometry.PolyCurve.TryGetArc(segment)
            arc[1].Radius = 2
            polycurve.AppendSegment(arc[1])

        polycurve.AppendSegment(segment)
    
    sc.doc.Objects.AddCurve(polycurve)
    sc.doc.Views.Redraw()
        
test_duplicate_polycurve()

Eric

Follow up on last post:

I have determined that this will work to append the arc:

    arc = Rhino.Geometry.PolyCurve.TryGetArc(segment)
    arc[1].Radius = 2
    polycurve.Append(arc[1])

Thanks again,

Eric

To get an ArcCurve object from an Arc, you can also use arc_crv=Rhino.Geometry.ArcCurve(arc)

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

1 Like

Thank you. That did the trick. I also used Rhino.Geometry.PolylineCurve to convert a Polyliine back to a polycurve for use with the straight line segments.

Here is the code:

import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs

l = 10
h = 10
r = 2

p_0 = Rhino.Geometry.Point3d(0,0,0)
p_1 = Rhino.Geometry.Point3d(l-r,0,0)
p_2 = Rhino.Geometry.Point3d(l,r,0)
p_3 = Rhino.Geometry.Point3d(l,h,0)
p_4 = Rhino.Geometry.Point3d(0,h,0)

def test_duplicate_polycurve():
    
    filter = Rhino.DocObjects.ObjectType.Curve
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select polycurve", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success: 
        return

    curve = objref.Curve()
    if not curve:
        return
        
    if not isinstance(curve, Rhino.Geometry.PolyCurve):
        return
        
    polycurve = Rhino.Geometry.PolyCurve()
    
    for i in range(0, curve.SegmentCount):
        segment = curve.SegmentCurve(i).DuplicateCurve()

        # todo: modify segment curve...
        if segment.IsArc():
            arc = Rhino.Geometry.PolyCurve.TryGetArc(segment)
            arc[1].Radius = r
            arc[1].Center = Rhino.Geometry.Point3d(l-r,r,0)
            arc_crv=Rhino.Geometry.ArcCurve(arc[1])
            polycurve.AppendSegment(arc_crv)
        if segment.IsPolyline():
            pline = Rhino.Geometry.PolyCurve.TryGetPolyline(segment)
            if len(pline[1]) == 2:
                pline[1][0] = p_0
                pline[1][1] = p_1
            if len(pline[1]) == 4:
                pline[1][0] = p_2
                pline[1][1] = p_3  
                pline[1][2] = p_4
                pline[1][3] = p_0  
            pCurve=Rhino.Geometry.PolylineCurve(pline[1])
            polycurve.AppendSegment(pCurve)


    sc.doc.Objects.Replace(objref,polycurve)
    sc.doc.Views.Redraw()
        
test_duplicate_polycurve()

Yes, Lines, Polylines, Arcs and Circles are not actually curve objects, they are mathematical constructs (“Structures”). They each have a curve equivalent in RhinoCommon which can be derived from the construct as the arc example above. Full circles are included in ArcCurve() so there is no CircleCurve().

1 Like

Great information. Thank you again. So you know, I am using this to modify a PolyCurve that pre-exists with toolpaths assigned to it using RhinoCam. I’m actually getting ready to update the code with Replace instead of AddCurve since I discovered previous to this that the toolpath would remain attached to the polycurve and just needed to be regenerated.

Eric

Yep, this is quite useful.

Here’s a quick video. I ran the macro in the background half way through to update the polycurve size.

Eric

1 Like