My kingdom for a good curve FILLET module

The Rhino common Module is baulks with some curves. I dont know why. I am hoping to find a module that is more tolerant of whatever the problem is between the two curves posted above.

your input is causing the trouble. The curve that doesn’t fillet has a very tiny radius like transition with radius of approx. 0.002mm…

A good chamfer module would be awesome too.

there were a few solutions to that in this thread

There’s also this.. All it needs is the ability to accept a list of which corners to chamfer, so we can do things like chamfer only concave or convex vertices.

your input is causing the trouble. The curve that doesn’t fillet has a very tiny radius like transition with radius of approx. 0.002mm…

Well yes, the RADIUS at the transition between these two curves is actually ZERO. Rhino created this tiny radius when it joined the curves. But keep in mind the same algorithm created all the other curves, most of which resulted in a FILLET.

Perhaps you could explain why this radius is important and how to join two curves at something approaching a right angle without this resulting micro curve. I am being forced to deal with issues that are not relevant to creating a fillet between two curves much like BLEND does, except a true tangential fillet. I dont need joined curves for that.

But this discussion is irrelevant. The curvature of the join between the two curves is no where near the tangency point resulting from the rolling ball. It just doesnt matter.

The problem is the underling algorithm is too simplistic or requires inputs that cause the problems it then baulks at.

These were originally TWO CURVES that were joined and to be able to feed into the module as ONE CURVE along with a t value of the location of the crease. It should expect this kind of input curve or accept TWO CURVES as an input.

The module that accepts two curves as input doesnt produce a resulting fillet on any of the 60+ curves. No idea why. Thats why I was forced to use this module.

I am again today faced with rewriting a fillet algo from first principals because the resulting surface doesnt follow the curves created, so the brep wont join and volume cant be calculated. Its frustrating.

In this case the fillet gradually fades out alone the length of the curves.

The algo must accommodate a change in the location of the vectors by which the curves are move to find their intersection. If the curves are curved, the error in vectors causes the rolling ball position to be calculated incorrectly.

Ill create a simple demo later and post it

Another problem: It appears that my curves are not TWO single curves in places due to the way they were derived:


So before I do any surfacing, or filleting I must deal with curves that are posing as a single curve from the output of BREP/PLANE INTERSECTION. I assume FIT CURVE will generate a single curve? such that the original curve is matched at the project tolerance setting or CCX will fail further down the page

Then the next problem with the curves is that the direction varies depending on the surface they are derived from. so before creating surfaces, before filleting, before even working on these curves, back to the surfaces that they were derived from and thus back to the curves that made them. Basically scroll back to the top and start again.

The central problem appears to be overlapping at the intersection of some of the curves.


we are talking about .005 or so, but its enough to cause CCX to find 2 intersections between these two curves, and for JOIN to create something that all the FILLET modules baulk at.

Both these curves have been trimmed using the same XY plane, one set of curves above, the other below. They should all meet perfectly at the plane… but no.

1 Like

like this?:

1 Like

It might have to do again with the way your file is set up / tolerances. So yes if you can post example files I’d be interested to take a look at how and why this happens

My tolerance is set to .001. Ill work on an example file. My current idea is to divide one of the curves so 100 points are put on it, then just replace the point where the join is to occur with the first point from the other curve.

WHICH WORKED. all the curves joined nicely. The output of JOIN is completely random (bears no relation to input) so a SORT was required and FILLET produced a fillet on all the curves.

That’s a LOT of blood an sweat to fillet come curves! IT would be nice if it had an output for just the fillet curves

1 Like

Pretty much. Though ideally it’d just accept a list of points so a user could exclude or include any vertex they want to.

One of the fillet components already does that. But as mentioned elsewhere there are other shortcomings with some of the fillet components. Ideally there’d be one fillet, chamfer, blend component for curves, like with solids, and it’d take point input to select what corners get changed, it’d output a single curve, and it’d have an input that was either fillet/blend radius or chamfer length depending on whether the user selected fillet, blend, or chamfer.

Trying to figure this out as a cluster was on my list of things to do but I have so, so many things to do.

for polylines it shouldn’t be too difficult:

This module works well once its input requirements are understood.

It wants two curves that are not connected, so in my case, I divided one of the lines into >100 points and just deleted the point closest to the second line and then rebuilt the curve with INTERPOLATE CURVE.

The advantage of this module is that the fillet curves are available as a separate output. The only way to get these from FILLET is to CCX with the input curves. Unfortunately you run into the limits of tolerance of the CCX module operation with fading fillets rendering the FILLET module useless if you want anything other than joined filleted curves as output.

The secondary benefit to using this module is that the curves do not need to be JOINed - an operation that inexplicably shuffles all the curves in a seemingly random manner requiring a sort operation.

Fillet is not nuclear science … but requires a lot of checks not only related with the result itself (i.e. if a fillet is possible) but with the “reverse” situations as well. Study these indicative captures (with or without the checkReverse option).


@ Peter,
Thank you. Could you please post a .gh file )

Er … I don’t have access to a vast variety of C#'s (in the practice workstations) related with similar stuff.

The above are just some screenshots found in a laptop : I’m in some sort of extended vacation state having sealed the practice for the summer (N95 masks are not my style).

Yes I was sure you already had code for this lying around :slight_smile:
Any hints for reverse checking ?

Are you familiar with C#?

Yes I can read it quite well

When the wind stops (meteo says soon == disaster) I’ll post some pseudo code for that matter.

In the mean time you sould sort your curves first in some CW or CCW order and use a tTree (of type double) for the t1/2 values (i.e. crv1.ClosestPoints(crv2, out t1, out t2)) and check the fillet possibility for each current, next pair (for a List of curves, curr = crvList[i], next = crvList[(i+1)%count].

If the fillet is not possible (from the R Method: Curve.CreateFillet(curr, next, R, t1, t2)) add null to the fillets List (at pos i) and 0,1 to the tTree. If is possible check for the reverse case captured above (if the option is true): if i>0 and if the previous fillet item (at i-1) is not null then check the t value strored in tree branch(i) [from the previous loop] against the new t value (having the CW or CCW state in mind). If the check fails add null to the fillets List (and 0,1 to the tTree). If the check is OK then store the t1/2 values (used for trimming the curve at i later on) in the tTree.Branch(i) … meaning that at check time the tTree has just one value (prior storing).

Then having the tTree and the fillets List on hand the rest are easy.

BTW: Found another screenshot related with the general case that requires a proper prox clustering (crvs sampled in random order):

thanks that makes sense. Right now I figured out the t1/t2 by moving the corners pts along the polylines, then closest points to get t. Is that how you would do it? Did you manage to get this working for polycurves as well?