Handling exception

Dear all,

I am working on bit of python script on grasshopper which enable to simulate movement of drops of water on a surface.
It works well with most of points(drops) on the surface, but it makes an error when it comes to points on edges of the surface.
I guess it is because normal vectors at a few of points are invalid. After all, because of these invalid points, an error message comes out which is saying " Runtime error (PythonException) : Unable to add polyline to document " and it results in no output. Please give me some help if you know how to handle this problem. I post a code below.
Thanks in advance.


import Rhino
import rhinoscriptsyntax as rs
import math
import ghpythonlib.components as gh

output_crvs = []

for pt1 in input_pt :
output_pts = []
newPt = pt1
output_pts.append(newPt)

while len(output_pts) <= 100:
    newPt = outputpoint(base_srf, newPt, distance_factor)
    output_pts.append(newPt)    

output_crv = rs.AddPolyline(output_pts)
output_crvs.append(output_crv)

A = output_crvs

def outputpoint(base_srf, input_pt, distance_factor):
centre_point = rs.AddPoint(0,0,0)
height_point = rs.AddPoint(0,0,10)

zaxis = rs.VectorAdd(centre_point, height_point)

cp_pt = rs.SurfaceClosestPoint(base_srf, input_pt)
normal_vector = rs.SurfaceNormal(base_srf, cp_pt)
drain_vector = rs.VectorCrossProduct(normal_vector, zaxis)

dvector2 = rs.VectorUnitize(drain_vector)
dvector3 = rs.VectorRotate(dvector2, 90, normal_vector)

mpt = gh.DeconstructVector(distance_factor*dvector3)
moved_pt = rs.PointAdd(input_pt, mpt)
moved_uv = rs.SurfaceClosestPoint(base_srf, moved_pt)
output_pt = rs.EvaluateSurface(base_srf, moved_uv[0], moved_uv[1])

return output_pt

Well, if it’s erroring out at rs.AddPolyline(), you either need to verify in advance that what you’re feeding it will produce a valid polyline (hard to check all cases), or throw in a try/except clause to catch exceptions thrown by rs.AddPolyline() and continue around them.

Something like:

try:
    output_crv = rs.AddPolyline(output_pts)
    output_crvs.append(output_crv)
except:
    pass

A third way to do this would be to use RhinoCommon to create the polyline before adding it to the document and check for validity before trying to do so…

#need to add this at the top
import scriptcontext
#==================

pl=Rhino.Geometry.Polyline(output_pts)
if pl.IsValid:
    output_crv=scriptcontext.doc.Objects.AddPolyline(pl)
    if output_crv: output_crvs.append(output_crv)

–Mitch

Hi Helvetosaur,

Many thanks for your post. I try your code, but it fails again with a message in this pic.

Probably, the problem would be related to the normal vector on the surface, it fails to make a valid list of points, then it couldn’t do ‘Addpolyline’. I guess the problem happens before adding polyline stage.

I put Try,Exception into the code at rs.SurfaceNormal and VecorCrossProduct, but it’s not helpful. Could you let me know how to apply what you suggest in this case?

Many thanks