Extrusion of a brep face produces very small face

Good morning!
When I extrude this face, which looks pretty simple to me, vertically downwards, I get a face with a very small area.

This face then prevents further processing because the following operations fail (BooleanUnion, Split, etc.)

Probably because the edges of this face are within the defined tolerance? FaceExtrusion.3dm (431.6 KB)

Can someone perhaps give me a hint how to
A: Clean up the initial geometry
B: Clean up the extrusion so that the BREP is still closed.

Thanks a lot

that face has a faulty edge:

Hi @Gijs
Thank you for the tip. I have never seen anything like this before.
How can I get rid of this spike?

_RebuildEdges should fix it

Thank you very much. This works perfectly.

Hi @Gijs
Is there any way to find out if a BrepFace.RebuildEdges is necessary?
Probably it is not a good idea to do this by default on all BrepFaces.

in this case you could count the brep edges. It should have 4 whereas this one has 5

There are too many buildings…I can’t visually verify that :wink: Must find a way through RhinoCommon and identify such microedges.

Hi @thomas.k,

you can iterate over the brep.Faces, then for each face, iterate over AdjacentEdges. For each edge, you can query the edge Tolerance, or alternatively the edge curve’s length and when it is larger than your preferred value, apply RebuildEdges to the face using your preferred tolerance. Then replace the brep with the one you changed.


Hi @clement
Thank you for the support.
When I iterate over the edges the edge tolerances are all below the desired 1mm.
I.e. via the tolerance I can’t identify them.
As I understand it this spike is shorter than the defined tolerance.
If I just blindly do a RebuildEdges() then the problem is fixed, although I don’t understand exactly what the difference before and after the RebuildEdges should be:

  • A TL_NurbsCurve is converted to an ON_LineCurve.
  • Edge vertices get more decimal places.
  • Some edge tolerances get bigger, others get smaller

Hi @thomas.k, your absolute model tolerance is set to 0.01 meters. Brep edge tolerance should be at least equal of better smaller than that for edges to stay valid. You cannot have (or enter) a larger edge tolerance than your absolute model tolerance. If you iterate over the brep in question and analyze edge lengths and tolerances you get:

Face: 0 Edge: 4 Length: 0.000448802862886 Tolerance: 0.000258490255285
Face: 0 Edge: 1 Length: 12.4395487453 Tolerance: 0.000258490255282
Face: 0 Edge: 0 Length: 0.997529948667 Tolerance: 0.0
Face: 0 Edge: 3 Length: 12.4402831545 Tolerance: 0.0
Face: 0 Edge: 2 Length: 0.915166650612 Tolerance: 0.000258490255282

Edge 4 length is below the absolute model tolerance. The edge 4 tolerance is not bad. Maybe you can use the edge length to detect something is probably too short and flag the object for manual investigation ?

Blindly doing this for any object would lead into further problems. What i find interesting with your geometry is that even after using _RebuildEdges using an edge tolerance of 0.0001 manually, the brep still has 5 edges instead of 4. The litle edge still exists if you analyze like this:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def DoSomething():
    brep_id = rs.GetObject("Brep", 16, True, False)
    if not brep_id: return
    brep = rs.coercebrep(brep_id, True)
    for f, face in enumerate(brep.Faces):
        for e in face.AdjacentEdges():
            t = brep.Edges[e].Tolerance 
            l = brep.Edges[e].EdgeCurve.GetLength()
            print "Face: {} Edge: {} Length: {} Tolerance: {}".format(f, e, l, t)


If you detach the trim and trim again, only 4 edges are left.

An alternative way to detect this problem without any lengths or tolerances is to iterate over the brep loops. If you get. loop.To3dCurve() for your brep face, you’ll find enough self intersections to flag it.


Hi @clement
Thanks for the detailed analysis.
It doesn’t seem to be so easy to get rid of this short edge, it keeps popping up :wink:
I think the idea with the curve self intersections is an interesting option which I will have a closer look at.
Finally, I need to find a way to remove this very short edge.

Can you maybe briefly explain why a blind RebuildEdges() to repair the input geometries is not a good idea?

Or is there another way to remove such sub tolerance curves… a kind of “Clean Brep”?

Hi @thomas.k ,

Beause it could cause that 2 faces adjacent to an edge get out of tolerance to be joined after rebuilding. BrepFace.RebuildEdges has an argument to rebuildSharedEdges, it it is set to True, you’re actually rebuilding the edges of both adjacent faces.

Before writing this i’ve checked these methods but none made a change to the brep:


Tried the last one after using _RebuildEdges, but the self intersecting loop was still there. So i guess testing for self intersections is one way to analyze it.

Did you notice the trim tolerances as well ? All trims have a tolerance of zero, only the one with a Trim.TrimCurve length below your model absolute tolerance has a trim tolerance of U=8.1452509537172091e-06 and V=1.785568254364378e-08.


Hi @clement
With _RemoveAllNakedMicroEdges and then _RebuildEdges the micro edge can be removed in Rhino.

There are only four edges left:

Face: 0 Edge: 1 Length: 12.4395487426 Tolerance: 0.001
Face: 0 Edge: 0 Length: 0.997529948667 Tolerance: 0.001
Face: 0 Edge: 3 Length: 12.4402831545 Tolerance: 0.0
Face: 0 Edge: 2 Length: 0.915166614107 Tolerance: 0.001

In RhinoCommon there is a new method in version 7:

BrepEdgeList.RemoveNakedMicroEdges Method (Double, Boolean) (rhino3d.com)

Unfortunately, I can’t switch to Rhino 7 anytime soon.

Same here. But thanks for the reminder on this new method. If this still has to be done automated in R6, you could detect the edge length, then select the object and script the commands.


Hi @clement
Is there a way to delete this micro edge via RhinoCommon? Can’t find anything in the help.

I don’t see this in RhinoCommon for V6, but the method you posted is in RhinoCommon for V7.

To script the command in V6, i thought like this:

import rhinoscriptsyntax as rs

def RemoveAllNakedMicroEdges():
    brep_id = rs.GetObject("Brep", 16, True, True)
    if brep_id: rs.Command("_RemoveAllNakedMicroEdges", False)

Of course, you cannot suppress the commandline feedback.