When I test the surface normals on a new Box Brep I noticed that the “bottom” surface has its Normal pointing upwards (inwards that is). How can that be?
Fig. 1. My solid Box, with two identical (length) Normals on top of each other, one Normal starting from the uppermost surfaceand the other one starting from the bottom surface going up through the Box :
A Surface is a fairly simple object, basically just a rectangle that can be stretched and bend into some other shape. Some types of surfaces supported in Rhino are PlaneSurface (a literal rectangle with interior), Revolution (one curve swept (partially) in a circle, SumSurface (one curve swept along another curve), and NurbsSurface.
When a surface becomes part of a Brep, it needs additional information and it is wrapped up into a BrepFace. BrepFaces add additional functionality such as trimming edges, some topological stuff, and also a normal-inversion-flag.
The normal direction of a surface is implied by the direction of U and V in any given point. It’s the right-hand-rule; if your index finger points along U, and your middle finger points along V, your thumb is the normal direction. In order to flip the normal direction of a surface, either U or V must be reversed, or U and V must be swapped with each other. This can be difficult depending on the surface type, and always requires the creation of a new surface.
Since faces in a brep often need to be flipped to keep the normal direction consistent across edges, we have a single boolean on BrepFace which allows us to invert the normal of the underlying surface without having to reconstruct the surface itself.
Personally I’d have preferred for this boolean to exist on Surface rather than BrepFace, because in the current system it is very easy to lose that information, and this is causing lots of problems in Grasshopper in particular.
BTW, I did test the BrepFace orientation as well for the “bottom” surface (see code below). This surface seems to have it’s Normal pointing inwards (up) although the Rhino Analyze Direction command indicates that the Normal is OK.
And no surprise, I never encounter OrientationIsReversed = True, but still its Normal points inward(up) when I display using VectorDisplay (see pictures above). All other 5 surfaces are OK except for the “bottom” srf.
srf = InBrep.Surfaces(4)
srf.GetSurfaceSize(u, v)
If InBrep.Faces(4).OrientationIsReversed Then
DA.SetData(4, srf.NormalAt(u/2, v/2).Reverse())
Else
DA.SetData(4, srf.NormalAt(u/2, v/2))
End If
I think the problem comes from assuming that the underlying surface has the same index as the face.
I mean: Brep.Faces and Brep.Surfaces are independent arrays.