Bug Curve.Extend

Hi,

I ran into an issue with a curve that does not extend to a boundary brep.
The cause for the failure is not clear to me.
So I’m looking for a way to identify the cause so I can work around it (likely by sanitizing the curve first)

image
no_extend.3dm (46.0 KB)

The attached 3dm has a red curve that does not extend smooth towards the brep.
Another black curve does extend as expected.

To replicate, either run the script below or try to manually extend the curve towards the brep.

Thanks
-Willem

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino.Geometry as RG


breps = []
crvs = []
for rid in rs.NormalObjects():
    if rs.IsBrep(rid):
        breps.append(rs.coercebrep(rid))
    elif rs.IsCurve(rid):
        crvs.append(rid)


smooth_style = RG.CurveExtensionStyle.Smooth
start_side = RG.CurveEnd.Start

for crv_id in crvs:
    crv = rs.coercecurve(crv_id)
    ext_crv = crv.Extend(start_side, smooth_style, breps)
    if not ext_crv:
        rs.SelectObject(crv_id)
    else:
       sc.doc.Objects.Replace(crv_id, ext_crv)

if rs.SelectedObjects():
    rs.MessageBox('Selected curves did not extend succesfully')

Hi @Willem ,

b, t = curve.ClosestPoint(curve_obj_ref.SelectionPoint())
if not b: return Result.Failure
curve_end = CurveEnd.Start if t <= curve.Domain.Mid else CurveEnd.End
 
geometry = [obj.Geometry() for obj in boundary_obj_refs]
extended_curve = curve.Extend(curve_end, CurveExtensionStyle.Line, geometry)
if extended_curve != None and extended_curve.IsValid:
    if not doc.Objects.Replace(curve_obj_ref.ObjectId, extended_curve):
        return Result.Failure
    doc.Views.Redraw()
    return Result.Success
else:
    RhinoApp.WriteLine("No boundary object was intersected so curve not extended")
    return Result.Nothing

As always hope this helps,
Farouk

Hi @farouk.serragedine

Thanks for your reply, but the issue occurs with a Smooth extension style:
CurveExtensionStyle.Smooth

-Willem

Simplify the curves using Simplify(RG.CurveSimplifyOptions.All, 1, 1) before extending them.

Unfortunately, Simplify creates a curve outside of the allowed tolerance

    crv = rs.coercecurve(crv_id)
    crv2 = crv.Simplify(RG.CurveSimplifyOptions.All,1,1)
    sc.doc.Objects.AddCurve(crv2)
    dbtwc = crv.GetDistancesBetweenCurves(crv, crv2, sc.doc.ModelAbsoluteTolerance)
    if dbtwc[0]:
        print 'max_delta', dbtwc[1]
        print 'max_delta > ModelAbsoluteTolerance :', dbtwc[1] > sc.doc.ModelAbsoluteTolerance
        ptA = crv.PointAt(dbtwc[2])
        ptB = crv2.PointAt(dbtwc[3])
        lid = rs.AddLine(ptA, ptB)
        rs.ObjectColor(lid, [255, 255, 255])

max_delta 0.0242666296338
max_delta > ModelAbsoluteTolerance : True

The input curve is not linear within file tolerance:
image

I understand this might look like nitpicking, but I cannot afford to throw in a simplify or rebuild every time a method fails to produce a proper result. These rebuilds and simplifications add up resulting in possibly way too large deviations in the end.

1 Like

If I extend the curve manually not all the way to the end, I do see that the curve is curling back:
no_extend_curl.3dm (83.4 KB)

Hoi Gijs,
Indeed. Do you consider this a bug as well or might there be something I’m missing?

Thanks

hi @Willem I’m not sure, so first I just wanted to point that out, thinking it is inherent to the geometry,. So there seems to be no feasible solution to extend that curve to that boundary. If you think the result should be different, if possible can you create the result you are expecting manually?

I think what’s more concerning is that the tollerance is not being followed, and that seems like bug behavoir. @Gijs
That is not the first instance that this happens, as it happened to myself aswell in other commands.
I think the tollerance bug is critical personally as It appears more often than not.

From that perspective I agree that there is no solution for a smooth extension.

I see now that basically the curvature trend towards the end is extended resulting in the “sharp” corner of the extension. On the mathematical level this indeed makes sense.
image

For now I’ve come up with a solution to join the extension of a rebuild curve to the original.
However some investigation just now, reveals that an arc extension might be an even better solution.

The challenge will be to decide on the type of extension to use.

Thanks @Gijs and @farouk.serragedine for taking the time to point me in the right direction as of what the cause and possible solution is.

1 Like

Can you explain exactly what you mean here. How is the file tolerance not being followed? If you have examples of cases where you think Rhino does the wrong thing, it would be good to have a look at that.