Creating a gap in a curve

Hi all,
I am working on a Rhino Python script, intended to prepare a file for cnc cutting. I know there is dedicated software to do this, but I would like to keep it within Rhino, just using scripting, no plugins.
To start I have a set of surfaces, from which I extract the edge curves and offset those by a fixed distance. That is actually how far I have succeeded, including getting he offset in the correct direction.
Now, I need to create gaps in the curves I have generated, to hold the parts within the base material sheet. I want this to be initiated by the user, with a single click on the relevant spot on the curve. I have come as far as getting the curve ID, and the point coordinates, but I have run out of ideas on how to gap the curve. All CurveBoolean operations seem to work on closed curves only, but after creating one gap it will no longer be closed, so I have stopped investigating that route. SplitCurve and TrimCurve seem to require curve parameters, but I cannot think of a way to generate those from a user defined point.
Does anybody have any ideas, hopefully with a concrete reference to the Rhinoscriptsyntax to be used?


Well, I might do it something like this:

  1. Divide the offset curve into the number of points you want to have ‘bridges’.
  2. Create circles using those points as centers, the diameter will be approximately the width of the bridge
  3. Intersect the circles with the offset curve and collect all the parameters on the offset curve of the intersections. You will need something like rs.CurveCurveIntersection() for this. If you have never worked with the result of an intersection before in scripting, it’s a bit complex - it’s a nested list - but the help is pretty explanatory.
  4. Split the offset curve at all the parameters found
  5. Now, get all the split segments and see if the any of the original circle centers lies on them.
  6. If so, delete the segment, otherwise keep it.
  7. The leftover segments will be your offset curve with gaps

It sounds complex - actually it is a bit - but it does work.

There are some cheap hacks though, such as using rs.Command(“Split”) then checking the results for curve length and deleting the ones that are near the circle diameter (assumes the other segments are always larger)

Thanks Mitch. I know it sounds cheap, but I have actually thought about that route right after I wrote the above question, but I did not see a way to take your step 5. But I have found it now, IsPointOnCurve should do it (unsurprisingly, how could I have overlooked that…).
Thanks again,

Just reporting: it worked well along the lines that Mitch suggested, albeit slightly different.

  • the parameters of the curve intersect points are created in ascending order, leading to using the first parameter in the list to make the first split in the original curve, and after that reassigning the second (in the list) split-off part of the curve (which is the higher parameter part of the original curve, and now has a new ID) as the target of the split with the second intersection parameter.
  • by the same token the first (in the list) part of the second split result sits inside the circle, so you can delete that to create the gap. No need to search for the line part with the original circle center.
  • avoid placing your cutting circle too close to a curve end or start point, the above procedure will not work reliably anymore (and neither will the procedure where you delete the bit with the circle center on it).

Even writing about it confuses me, it took me a while to get my head around it. Not so much the intersect function, as Mitch said it is pretty well explained in the help. But it works fine now.


You should be able to split the curve with all the parameters at once… the Help for rs.SplitCurve() is somewhat ambiguous - the argument is named ‘parameter’ and the description says

Splits, or divides, a curve at a specified parameter. The parameter must
be in the interior of the curve’s domain

but in fact it takes either a single parameter (only works for open curves) or a list.


curve_id (guid): the curve to split parameter ({number, …]) one or more parameters to split the curve at delete_input (bool, optional): delete the input curve

Although things are generally returned in order, I am never certain of that and I don’t like to assume - therefore I personally prefer a concrete test that works no matter what the order.

I agree with you in general, but in this case the result is immediately visible to the user, and I have tested it on multiple curves in the development process, so I will leave it for now. More testing ahead anyway.

I was wondering why your description is more comprehensive than mine, I found out it’s because you are using the Rhino 6 syntax list, and I use the Rhino 5 equivalent (as I am not upgrading to R.6). But the R.5 list does mention splitting by multiple parameters, although it does not say how…(and I am wondering what the curly brace is doing in the syntax?)