How are normal vectors decided?

When i have a polysurface and explode/deconstruct it i end up with a bunch of surfaces. Most of the time the surfaces gets a normal vector facing away from the center of the original shape. However, i have noticed that this isnt the case all the time. Some times the normal vector of some surfaces are facing towards the center of the original shape. Is there any logic behind this? i am trying to automate a task that is dependent on the normal vectors facing outwards (away from center of original shape). Is there any way to make sure they always face this direction?

Hi @Sofie_Mo
Any file to share where this is the case ?

For a general question , a general answer.

Usually, to “enforce” a polysurface/brep orientation, you can try to close it (Cap).
A closed brep will always have the normals going out. (or not, in rare cases when from typed scripts…)

for example, extruding a curve, the curve direction is U, the extrusion direction is V, your normal will be W.
You can foresee the normal direction of geometries you are creating. At least most of the times…

This should be a problem only with open breps…
Detect an area where you are sure your brep should be locally closed, create a point there.
Find the brep closest point and the normal in that point.
Compare the resulting normal with the vector you are more or less expeting.
If the angle is >Pi/2 , flip your brep.

This is due to an optimisation in Rhino. The normal direction of a single surface is controlled fully by the u and v directions and the right-hand-rule. The only way to flip the direction of a surface is to either:

  1. Reverse the u direction.
  2. Reverse the v direction.
  3. Swap the u and v directions.

These all require brand new surfaces to be constructed which costs processor time and memory space. When joining surfaces into polysurfaces their normals ought to be unified along the edges, which in many cases would require flipping the surface prior to joining it. To avoid all that, Rhino keeps the original surfaces and instead adds a single boolean value to brep faces stating whether their normal direction is ‘natural’ (i.e. the same as the underlying surface) or ‘reversed’. That boolean doesn’t exist on surfaces, only on brep faces, so when a brep is exploded back into loose surfaces that information has a hard time sticking around.

1 Like

In Rhino V8, and previous versions since at least V4, the normal direction of a “surface” can be changed using the Flip and Dir commands. The u and v directions are not affected when the normal direction is reversed using Flip or Dir. This is true whether the surface was ever part of a polysurface or not.

I put “surface” in quotes above because I don’t know if what the user sees as and is referred to a “surface” in the UI and documentation in Rhino is a “surface” or “brep” internally.

1 Like

You’re right.

AFAIK, single, untrimmed surfaces are also stored as Brep’s in Rhino.

In the 3dm document yes. They are also stored as Breps in Grasshopper. However any algorithm which at some point in its process treats brep faces as surfaces will probably flush the normal flipping information.

1 Like

That will probably modify the u and v directions of the surface. We don’t really care about the additional processor and memory cost when the user requests it, only when surfaces are joined together. Also, as long as the surfaces are in fact stored as single-face breps, the flipping can be achieved by toggling the normal direction boolean.

The u and v directions as displayed by Dir do not change when the normal direction is flipped using Dir or Flip. My guess the normal shown is what is in the brep data.