Different Surface Normal when Using Brep.Faces?

Hi all,

I wonder if someone might be able to help me understand something? I am finding surface normals for Brep faces (as part of a larger script) and I am finding that in some cases I get a different result if I use the native Grasshopper methods vs. the Brep.Faces attribute to iterate through each of the faces? For instance:

If I create a simple _Box in Rhino and pass it into my normal-finder, I can find the normal by either:

a) using the Brep.Faces to iterate over each face, or
b) use Grasshopper DeconstructBrep() to get the faces, then iterate.

if I do both, I get normals for all surfaces, except that the ‘bottom’ surface yields a different surface normal for some reason? When I use the .Faces() method it shows the ‘bottom’ surface as pointing ‘up’ (normal=0,0,1) whereas the GH method shows the ‘bottom’ surface pointing ‘down’ (normal=0,0,-1)?

Does anyone know what I am doing wrong here and why this might be? Using native GH components I get the (as expected) ‘down’ normal for the bottom surface as well.

Does anyone know why this would be the case? All the other surfaces appear consistent, its just that ‘bottom’ surface for some reason?

Any advice is much appreciated! Example .GH attached here as well.


import Rhino
import ghpythonlib.components as ghc

def get_surface_normal(_srfc):
    centroid = Rhino.Geometry.AreaMassProperties.Compute(_srfc).Centroid
    p, uv, d = ghc.SurfaceClosestPoint(centroid, _srfc)
    face_normal = ghc.EvaluateSurface(_srfc, uv).normal

    return face_normal

# Try it using .Faces method on the brep
using_dot_face = []
for i, face in enumerate(_brep_input.Faces):
    result = "Surface {}: {}".format(i, get_surface_normal(face))

# Now try it using the Grasshopper Deconstruct Brep 
using_deconstruct_brep = []
for i, face in enumerate(ghc.DeconstructBrep(_brep_input).faces):
    result = "Surface {}: {}".format(i, get_surface_normal(face))

example.gh (10.1 KB)

Similar questions: