Linetype "anomaly" with splines

I am in the process of writing a substitute for the missing ExplodeLinetypes plug-in (from RhinoLabsTools for V4) that is missing in V5. I have run into an anomaly with splines which has caused me to hit the wall here… Essentially I am re-creating a linetype on a curve from the linetype pattern definition. I found a nice, simple, clean algorithm for doing this which works perfectly on all types of curves - except splines. :confounded: Splines seem to have had some sort of weird tolerance factor added in and so far I have not been able to discover where it’s being done or how to reproduce it.

It is not necessary to script this to see the problem, just have a look at how Rhino attributes a linetype differently to a line and a spline of exactly the same length in the attached file/image… For the most part the behavior is the same, but there is a “fuzz zone” where the curve length approaches an exact multiple of the pattern length. For lines, polylines, circles, arcs etc. when the curve length hits an exact multiple of the pattern length, the first segment is divided in half and a half segment is put on either end…

For splines, the same thing happens, but it happens a tiny amount BEFORE the exact multiple is reached. So there is a small zone where a line curve and a spline curve of the same length do not get the same pattern attributed to them. This makes it unreliable to try to reconstruct the linetype for splines, as I am unable to determine exactly how this tolerance is calculated and therefore am unable to reproduce the Rhino behavior exactly.

Hopefully the attached file and image will explain the problem. The pattern length is 10; 100.000 is an even multiple of the pattern length. When the degree 3 spline in the file is between 99.950 and 100.000 long it behaves differently from a line of the same length.

Without knowing how to calculate this “fuzz” factor, my script will end up being inaccurate with spline curves. :frowning:

Thanks, --Mitch

SplineLineType.3dm (246.1 KB)

@lowell, is this something you can help with?


@dale, @lowell, @pascal, @Helvetosaur,

i’ve encountered the same and need to convert linetypes into curve segments using python with Rhino 5 and 6. While i’ve looked at the script Mitch posted, i’ve found cases where i am lost to understand the logic using pattern length, line type scale, segment length etc. to reconstruct the split parameters required to get the proper curve segments.

Would it be possible to share the logic how line type patterns are applied or provide an example how to compute the split parameters ? I’ll attach a 3dm file where i thought i understood the logic partially.

DefaultLineTypes.3dm (66.7 KB)

In this file each default line type is assigned to a green line. If the pattern overshoots the line length at a segment (red arrow), it seems it sets back the whole pattern by half it’s total length (shown in blue) and then assigns it to the curve. So the pattern is overlayed somehow from the midpoint of the curve or curve segment. The points in the file mark the pattern length.

However, if i look at the line type named “Border”, this rule does not apply. It has a segment at start which does not match its definition which is:

4.00, 1.00, 4.00, 1.00, 1.00, 1.00

The first segment of the pattern in Rhino’s display has a length of 7. Is there a logic behind which you could post to enlighten me ?


Hi Clement - the only logic I can think of (re: Border) is that there’s an attempt to make sure lines do not end on a space, or perhaps even on a too-short segment, combined with the mid-point base that you point out. I am guessing…


@clement - This is the guts of aligning the pattern

    // pattern_repeat_count = number of times pattern is repeated
    // for this subdomain
    const int pattern_repeat_count = (int)( curve_length / pattern_length);

    // total_segment_count = number of active and inactive regions
    // for this subdomain of the nurbs_curve.
    const int total_segment_count = pattern_repeat_count * pattern_segment_count + 1;

    // always put a solid segment at each end
    const double ideal_length = pattern_repeat_count*pattern_length + pattern_segment_length[0];

    // if the length of this portion of the curve is not the same
    // as ideal length, center the pattern on the curve by
    // shifting it.
    const double shift = (curve_length - ideal_length) * 0.5;
1 Like

Thank you @pascal and @lowell, i’ll try to figure out the rest.