I am trying to duplicate the function of Grasshopper’s Discontinuity component with Python/Rhinocommon. (I know I can just script the component, but I’m looking at applications where GH might not be present, like Mac)
I’ve hacked something together that works, but I’m not really sure it’s correct. In particular, how to determine when I’ve found all the discontinuities and break out of the loop. The GetNextDiscontinuity method returns a tuple with a boolean value and a number (parameter), it’s not explained exactly what the boolean represents, but I noticed it appeared to switch to False when I had found all discontinuities… At this point, it also returns a parameter of “virtual negative infinity” (-1.23432101234321E+308) - funny number! But I don’t know if I’m using the method correctly.
Anyway, code I hacked below… It just creates a square polycurve with two extraneous points which should not be found as discontinuous.
Thx, --Mitch
import Rhino
import scriptcontext as sc
pts=[]
pts.append(Rhino.Geometry.Point3d(0,0,0))
pts.append(Rhino.Geometry.Point3d(5,0,0))
pts.append(Rhino.Geometry.Point3d(10,0,0))
pts.append(Rhino.Geometry.Point3d(10,10,0))
pts.append(Rhino.Geometry.Point3d(5,10,0))
pts.append(Rhino.Geometry.Point3d(0,10,0))
pts.append(Rhino.Geometry.Point3d(0,0,0))
#create a polycurve
pc=Rhino.Geometry.PolyCurve()
for i in range(len(pts)-1):
pc.Append(Rhino.Geometry.Line(pts[i],pts[i+1]))
sc.doc.Objects.AddCurve(pc)
#find discontinuities
dom=pc.Domain
cornerParams=[]
t=dom[0]
cont=Rhino.Geometry.Continuity.C1_locus_continuous
while True:
result=pc.GetNextDiscontinuity(cont,t,dom[1])
if not result[0]: break
t=result[1]
cornerParams.append(t)
#add points to see
for t in cornerParams:
sc.doc.Objects.AddPoint(pc.PointAt(t))
sc.doc.Views.Redraw()
The virtual infinity value that you mention is in fact a RhinoCommon constant called RhinoMath.UnsetValue. YOu can test if a value is Infinity, NaN or UnsetValue using RhinoMath.IsValidDouble
They’re very useful in all kinds of algorithms to test if an assignment, that may depend on a lot of operations and if-statements, was ultimately successful.
Anyone have any comments on whether this is the correct way of using FindDiscontinuities (from the original post)?
#find discontinuities
dom=curve.Domain
cornerParams=[]
t=dom[0]
cont=Rhino.Geometry.Continuity.C1_locus_continuous
while True:
result=pc.GetNextDiscontinuity(cont,t,dom[1])
if not result[0]: break
t=result[1]
cornerParams.append(t)
i am not sure if there is a bug in the rs function and RhinoCommon. With the below curve example, the rhinoscript method and Rhino.Geometry.Curve.GetNextDiscontinuity() does not find the G2 (value = 5) and G1 (value = 4) discontinuities between both segments. I tested using RhinoCommon in python and using this script:
import rhinoscriptsyntax as rs
curve_id = rs.GetObject("Select a curve", rs.filter.curve)
if rs.IsCurve(curve_id):
points = rs.CurveDiscontinuity(curve_id, 5)
if points: rs.AddPoints(points)
If i explode the curve into its two segments and measure with GCon, the continuity between both segments is reported as G0.