I’m finally moving to Python from VBscript, and I have a hiccup with the DivideCurveLength function–actually it’s a pretty big problem since I can’t possibly “afford” to work around this by actually splitting curves up, this could be called a million times per run–in Python it doesn’t seem to accept the option of specifying a range to divide? The context help in the editor doesn’t mention it and I get an error about too many arguments.
Hi Jim,
This is best done without actually creating the split curve objects. Doing this leads you in the realm of RhinoCommon and that is much easier navigated with some help.
However I have no time atm to help out, so if you don’t get a proper answer soon, send me a message and I’ll try to help you out when I have more time at hand.
-Willem
As Willem said, you’re going to need to dive into RhinoCommon for this one…
Have a look at the following quick sample, I need to go to bed now, but can pick it up again tomorrow - or someone closer to your time zone will continue…
CHeers, --Mitch
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def DivideCrvInterval(crv,sParam,eParam,count):
#this part actually divides the curve (virtually) and returns the parameters
crv_seg=crv.Trim(sParam,eParam)
out_params=crv_seg.DivideByCount(count,True)
return out_params
def TestDivideCurveInterval():
crv_ID=rs.GetObject("Select curve to divide",4,True)
if crv_ID:
#get interval on curve
pt_0=rs.GetPointOnCurve(crv_ID,"Pick start point of interval")
if not pt_0: return
pt_1=rs.GetPointOnCurve(crv_ID,"Pick end point of interval")
if not pt_1: return
divs=rs.GetInteger("Number of divisions?",minimum=2)
if not divs: return
par_0=rs.CurveClosestPoint(crv_ID,pt_0)
par_1=rs.CurveClosestPoint(crv_ID,pt_1)
if par_0==par_1: return
#reverse interval if descending
if par_0>par_1: par_1,par_0=[par_0,par_1]
#get the underlying geometry from the curve object
crv_geo=sc.doc.Objects.Find(crv_ID).Geometry
#do the divide
div_params=DivideCrvInterval(crv_geo,par_0,par_1,divs)
#Add points to see
pts=[crv_geo.PointAt(param) for param in div_params]
rs.AddPoints(pts)
TestDivideCurveInterval()
Hi Jim,
you might use attached DivideCurveLengthEx()
method. It should work like the RhinoScript (vb) method and allows to specify an interval.
For the interval you can use a list or two floats or Rhino.Geometry.Interval(t0, t1)
. Note that the interval is not normalized, as in the RhinoScript (vb) method.
DivideCurveLengthEx.py (1.5 KB)
c.
I see I answered the wrong method here… Thanks Clement for picking up where I left off.
Here is a mod of my above scriptlet which works by length. Divides from the first picked point to the last along the curve regardless of the curve direction.
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def DivideCrvIntervalByLength(crv,sParam,eParam,s_len,add_end):
#this part actually divides the curve (virtually) and returns the div points
flip=False
if sParam>eParam:
sParam,eParam=[eParam,sParam] ; flip=True
crv_seg=crv.Trim(sParam,eParam)
if crv_seg.GetLength()<=s_len: return
if flip: crv_seg.Reverse()
div_params=crv_seg.DivideByLength(s_len,True)
div_pts=[crv_seg.PointAt(param) for param in div_params]
#add end point if desired
if add_end: div_pts.append(crv_seg.PointAtEnd)
return div_pts
def TestDivideCurveIntervalByLength():
crv_ID=rs.GetObject("Select curve to divide",4,True)
if not crv_ID: return
tol=sc.doc.ModelAbsoluteTolerance
#get interval on curve
pt_0=rs.GetPointOnCurve(crv_ID,"Pick start point of interval")
if not pt_0: return
pt_1=rs.GetPointOnCurve(crv_ID,"Pick end point of interval")
if not pt_1: return
len=rs.GetReal("Segment length?",minimum=tol)
if not len: return
par_0=rs.CurveClosestPoint(crv_ID,pt_0)
par_1=rs.CurveClosestPoint(crv_ID,pt_1)
if par_0==par_1: return
#get the underlying geometry from the curve object
crv_geo=sc.doc.Objects.Find(crv_ID).Geometry
#do the divide
pts=DivideCrvIntervalByLength(crv_geo,par_0,par_1,len,True)
if not pts: return
#Add points to see
rs.AddPoints(pts)
TestDivideCurveIntervalByLength()
Thanks a lot guys, I wound up modifying Mitch’s to return the parameters only.