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.
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?
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()
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().
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.