Fillet all filletable edges of a Brep using Fillet Edge

(this has a long preamble. I think it’s needed, but the question about how to write an actual definition is below in bold if you want to skip ahead)

There seems to be a lot of confusion about how to use the fillet edge component in Grasshopper.

I’ve read a bunch of posts about it and I think one issue may be a key difference in how Rhino’s _FilletEdge command works and how the Grasshopper component works.

In Rhino, if attempt to fillet every edge of a polysurface, Rhino will automatically ignore naked edges and linear edges that divide two subsurfaces with continuity that’s tangent or better, because neither of those edge types can be filleted.

Thus, if I attempt to fillet the objects below and select all edges, I get this:


And filleting just works:

But in Grasshopper, the Fillet Edge Component does not filter out these edges. So if a user wants to fillet all filletable edges of a brep in Grasshopper, they need to be able to sort the edges shown below out of a tree.

(Question begins)
I have a way of doing this sort, which I’m sharing below. But it’s incomplete. I’m hoping someone can help me out. Here’s my definition:


My definition works by culling all linear edges of all non-planar subsurfaces of the breps.
(This also appears to be how the Rhino _FilletEdge command ignores the same edges.)

But there can be other types of edges that can’t be filleted and will cause the Fillet Edge component to fail. I want to cull those too.

My Question is: How do I cull all edges of a brep that are
- interior edges
- edges with a surface continuity of tangent or better.

I believe these two traits define which edges of a brep can never be filleted to any radius.
The Fillet Edge component will ignore naked edges on it’s own and return an error mentioning them, so I didn’t bother culling interior edges. My definition fails to be universally usable because it doesn’t cull curved edges with tangent or better surface continuity. I think Rhino’s FilletEdge command also doesn’t do this.

Are there Grasshopper components that can test surface edge continuity?
How can I use them here if they exist? Is there another way to get this done?

2 Likes

I’d use Brep Edges + Curve Middle + Edges From Points to find the index of interior edges.

For your second inquiry, on top of my head, use Brep Topology to get all adjacent faces to each edge, test the normal vector each side of the edge, maybe at 1/4, 1/2 and 3/4 of the length of the edge, and if the vector is the same you can cull the edge.

It’s not perfect but only uses GH components.

I’ll have a look in C# if some tangency/continuity are stored.

1 Like

Did not found anything useful really.

I have another idea, but unsure if it’s mathematically correct. I think a filletable edge is either strictly concave or convex. Which means you could use Convex Edges component and merge both outputs to retrieve a list of all usable edges.

1 Like

you mean naked edges or holes ?

naked edges are easy to test with
BrepEdge.Valence

“holes” will be quite complex to identify for all cases - as this examples shows. Holes that positioned between surfaces will cause surfaces only to have outer trim loops. (and no interior trims / edges)

Rhinocommon / c# / python has:
BrepEdge.IsSmoothManifoldEdge

BrepEdge.ConcavityAt
test at several positions/ parameters

I don’t mean holes. “interior edge” is the opposite of “naked edge”

This works with my test geometry. I’m going to see if it works in some more situation. It would be awesome if it was this easy. Thank you.

I tested the convex edges component method with more complicated breps.
Feeding the concave edges to the Fillet Edge component broke it.

Then I decided to check the edge continuity manually in Rhino.

I now suspect that part of the problem here is a tolerance issue of some kind.


Some of the edges the component decided were concave or mixed show up as barely beyond a zero angle.

The convex edges component completely ignored all edges with a true zero angle, which is what we want. The edges it sorted as convex and filleted were all well beyond zero.

So it looks like maybe if there was a tolerance input on the convex edges component that allowed it to sort edges that meet at a near-zero angle, this would solve the problem of being able to quickly fillet all fillet-able edges of a brep in Grasshopper.

(the edges that break fillet edge in grasshopper also break the fillet edge command in Rhino when I try to fillet all edges at once)

Anyway. Thank you for your help. The first method you showed me works for my project. I was hoping to find a universal method because I see a lot of frustrated posts about the GH fillet edge component, and one of the most user-friendly and newbie-friendly ways to use it would be to use it to fillet all possible edges, and build workflow around that.

BrepEdge.ConcavityAt
test at several positions/ parameters

I saw that but I was looking for a global criteria as a property of BrepEdge.
Turns out it’s exactly the method used in the component, with several tests performed along the edge, and an absolute tolerance of 0.001 radians.

So to actually get the angle tolerance active, you could test the angle between the normal vectors I mentioned above. For your regular enough cases, I think a single test in the middle of the edge is sufficient.
Or use that wonderful C# component just edited for the occasion.

ConvexEdgesTol.gh (4.4 KB)

3 Likes

This is super helpful.

Thank you so much.

I’m adding a heavily labeled definition that’s an example of how to use your C# component to fillet all fillet-able edges of Breps, so that hopefully even a total newb will be able to use this as part of a workflow.
ConvexEdgesTol Fillet All Edges.gh (176.4 KB)

I really need to find time to go through Jose Luis García del Castillo’s C# youtube courses. Presumably what you did is something I could figure out relatively early in the learning process?

4 Likes

I really need to find time to go through Jose Luis García del Castillo’s C# youtube courses. Presumably what you did is something I could figure out relatively early in the learning process?

In terms of syntax it’s not that complex, especially if you already know about variables, loops and conditions, which is probably the case if you’re used to GH.
However it forces you to dive into the Brep and BrepEdge types and you probably don’t want to start your learning with such complex objects.

1 Like