NEW: Welcome to the Rhino 6 version of this page! Looking for the older Rhino 5 version?

Determine Normal Direction of Brep Face

Demonstrates how to determine the normal direction of a Brep face at a specified point.

partial class Examples
{
  public static Result DetermineNormalDirectionOfBrepFace(RhinoDoc doc)
  {
    // select a surface
    var gs = new GetObject();
    gs.SetCommandPrompt("select surface");
    gs.GeometryFilter = ObjectType.Surface;
    gs.DisablePreSelect();
    gs.SubObjectSelect = false;
    gs.Get();
    if (gs.CommandResult() != Result.Success)
      return gs.CommandResult();
    // get the selected face
    var face = gs.Object(0).Face();
    if (face == null)
      return Result.Failure;

    // pick a point on the surface.  Constain
    // picking to the face.
    var gp = new GetPoint();
    gp.SetCommandPrompt("select point on surface");
    gp.Constrain(face, false);
    gp.Get();
    if (gp.CommandResult() != Result.Success)
      return gp.CommandResult();

    // get the parameters of the point on the
    // surface that is clesest to gp.Point()
    double u, v;
    if (face.ClosestPoint(gp.Point(), out u, out v))
    {
      var direction = face.NormalAt(u, v);
      if (face.OrientationIsReversed)
        direction.Reverse();
      RhinoApp.WriteLine(
        string.Format(
          "Surface normal at uv({0:f},{1:f}) = ({2:f},{3:f},{4:f})",
          u, v, direction.X, direction.Y, direction.Z));
    }
    return Result.Success;
  }
}
Partial Friend Class Examples
  Public Shared Function DetermineNormalDirectionOfBrepFace(ByVal doc As RhinoDoc) As Result
	' select a surface
	Dim gs = New GetObject()
	gs.SetCommandPrompt("select surface")
	gs.GeometryFilter = ObjectType.Surface
	gs.DisablePreSelect()
	gs.SubObjectSelect = False
	gs.Get()
	If gs.CommandResult() <> Result.Success Then
	  Return gs.CommandResult()
	End If
	' get the selected face
	Dim face = gs.Object(0).Face()
	If face Is Nothing Then
	  Return Result.Failure
	End If

	' pick a point on the surface.  Constain
	' picking to the face.
	Dim gp = New GetPoint()
	gp.SetCommandPrompt("select point on surface")
	gp.Constrain(face, False)
	gp.Get()
	If gp.CommandResult() <> Result.Success Then
	  Return gp.CommandResult()
	End If

	' get the parameters of the point on the
	' surface that is clesest to gp.Point()
	Dim u As Double = Nothing, v As Double = Nothing
	If face.ClosestPoint(gp.Point(), u, v) Then
	  Dim direction = face.NormalAt(u, v)
	  If face.OrientationIsReversed Then
		direction.Reverse()
	  End If
	  RhinoApp.WriteLine(String.Format("Surface normal at uv({0:f},{1:f}) = ({2:f},{3:f},{4:f})", u, v, direction.X, direction.Y, direction.Z))
	End If
	Return Result.Success
  End Function
End Class
import rhinoscriptsyntax as rs
from scriptcontext import *
import Rhino
from Rhino.Commands import Result

def RunCommand():
  # select a surface
  gs = Rhino.Input.Custom.GetObject()
  gs.SetCommandPrompt("select surface")
  gs.GeometryFilter = Rhino.DocObjects.ObjectType.Surface
  gs.DisablePreSelect()
  gs.SubObjectSelect = False
  gs.Get()
  if gs.CommandResult() != Result.Success:
    return gs.CommandResult()

  # get the selected face
  face = gs.Object(0).Face()
  if face == None:
    return

  # pick a point on the surface.  Constain
  # picking to the face.
  gp = Rhino.Input.Custom.GetPoint()
  gp.SetCommandPrompt("select point on surface")
  gp.Constrain(face, False)
  gp.Get()
  if gp.CommandResult() != Result.Success:
    return gp.CommandResult()

  # get the parameters of the point on the
  # surface that is clesest to gp.Point()
  b, u, v = face.ClosestPoint(gp.Point())
  if b:
    dir = face.NormalAt(u, v)
    if face.OrientationIsReversed:
      dir.Reverse()
    print "Surface normal at uv({0:f},{1:f}) = ({2:f},{3:f},{4:f})".format(
        u, v, dir.X, dir.Y, dir.Z)

if __name__ == "__main__":
  RunCommand()