Problem with Curve NormalizedLengthParameters

When I run the command below on the curve in the attached document, the method NormalizedLengthParameters returns a null array. I think this is due to the fact that two controlpoints are in the same place. Note that this is a valid curve, and I expect to get parameters for normalized lengths.

Problem Curve.3dm (23.2 KB)

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
    ObjRef pRef;
    Result res = RhinoGet.GetOneObject("Select a curve", false, ObjectType.Curve, out pRef);
    if (res != Result.Success)
        return res;

    Curve c = pRef.Curve();

    NurbsCurve nc = c.ToNurbsCurve();
    int n = 0;
    foreach(ControlPoint cp in nc.Points)
    {
        Point3d pt = cp.Location;
        String xyz = String.Format(CultureInfo.InvariantCulture, "({0}, {1}, {2})", 
                                 pt.X.ToString("R"), 
                                 pt.Y.ToString("R"),
                                 pt.Z.ToString("R"));
        RhinoApp.WriteLine("CP {0} at {1}", n++, xyz);
    }

    RhinoApp.WriteLine("Knots: "+String.Join(", ", nc.Knots.Select(u => u.ToString("R"))));

    double[] fractions = Enumerable.Range(0, 21).Select(u => u / 20.0).ToArray();
    double[] t = c.NormalizedLengthParameters(fractions, 1e-3);
    if (null == t)
    {
        RhinoApp.WriteLine("NormalizedLengthParameters failed on this curve.");
        return Result.Failure;
    }
    foreach(double v in t)
    {
        doc.Objects.AddPoint(c.PointAt(v));
    }

    doc.Views.Redraw();
    return Result.Success;
}

Some more investigation seems to suggest this condition for the problem to present itself:

(degree + 1) or more control points at the same location at the start or end of a curve.

That is:
Up to, but not including (degree + 1) control points at start or end of the curve is no problem.
(degree + 1) or more control points but not at start or end of curve (i.e. between start and end) is no problem.

This may have escaped your attention, @dale or @stevebaer

Could you please confirm this is a bug or suggest how to get the length parameters on the problematic curve as defined above?

I am looking that this now…

Stacked control points and zero-length curve segments can cause problems, such as you are seeing here. The solution, of course, is to fix the curve creation code so that these types of curve are not created. (if you had the Rhino C++ SDK installed, you would have see the following warning roll by your output window when you opened the file):

openNURBS ERROR # 1 rhino3DocObjManager.cpp.815 CRhinoDoc::AddObject got a curve with zero length segments - fix creation code.

The Rhino C++ SDK has a RhinoRemoveShortSegments() function that will clean up these types of curves. I see that is is not wrapped by RhinoCommon (yet). I’ll see that adding this is on the to-do list.

Hi Dale,

Thanks for clearing that up :smile:

The truth is though, that it is not code, but actual people, creating these surfaces. I found this problem in a surface representing a ship skeg. The surface has a knuckle line in it. I will instruct to draw differently, or try to figure out a workaround in code.

In fact it looks like RhinoCommon does have it:

http://4.rhino3d.com/5/rhinocommon/html/M_Rhino_Geometry_Curve_RemoveShortSegments.htm

I’ll try this tomorrow and see if that solves my problem. Thanks for the hint :smile:

Looks like Curve.RemoveShortSegments works.

1 Like

But the description is misleading: “Looks for segments that are shorter than tolerance that can be removed”. Fom the description I would say that the method identifies the short segments but does not remove them.