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()