A class used to intersect and return elements based on an origin point and direction. 
   Namespace:   Autodesk.Revit.DB  
  Assembly:   RevitAPI  (in RevitAPI.dll) Version: 2015.0.0.0 (2015.0.0.0) 
  Since:  2013 
Syntax
| C# | 
|---|
|  | 
| Visual Basic | 
|---|
|  | 
| Visual C++ | 
|---|
|  | 
Examples
 Copy  C#
 Copy  C# public class RayProjection : IExternalCommand
{
    public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements)
    {
        Document doc = revit.Application.ActiveUIDocument.Document;
        ICollection<ElementId> selectedIds = revit.Application.ActiveUIDocument.Selection.GetElementIds();
        // If skylight is selected, process it.
        FamilyInstance skylight = null;
        if (selectedIds.Count == 1)
        {
            foreach (ElementId id in selectedIds)
            {
                Element e = doc.GetElement(id);
                if (e is FamilyInstance)
                {
                    FamilyInstance instance = e as FamilyInstance;
                    bool isWindow = (instance.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Windows);
                    bool isHostedByRoof = (instance.Host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Roofs);
                    if (isWindow && isHostedByRoof)
                    {
                        skylight = instance;
                    }
                }
            }
        }
        if (skylight == null)
        {
            message = "Please select one skylight.";
            return Result.Cancelled;
        }
        // Calculate the height
        Line line = CalculateLineAboveFloor(doc, skylight);
        // Create a model curve to show the distance
        Plane plane = revit.Application.Application.Create.NewPlane(new XYZ(1, 0, 0), line.GetEndPoint(0));
        SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
        ModelCurve curve = doc.Create.NewModelCurve(line, sketchPlane);
        // Show a message with the length value
        TaskDialog.Show("Distance", "Distance to floor: " + String.Format("{0:f2}", line.Length));
        return Result.Succeeded;
    }
    /// <summary>
    /// Determines the line segment that connects the skylight to the nearest floor.
    /// </summary>
    /// <returns>The line segment.</returns>
    private Line CalculateLineAboveFloor(Document doc, FamilyInstance skylight)
    {
        // Find a 3D view to use for the ReferenceIntersector constructor
        FilteredElementCollector collector = new FilteredElementCollector(doc);
        Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
        View3D view3D = collector.OfClass(typeof(View3D)).Cast<View3D>().First<View3D>(isNotTemplate);
        // Use the center of the skylight bounding box as the start point.
        BoundingBoxXYZ box = skylight.get_BoundingBox(view3D);
        XYZ center = box.Min.Add(box.Max).Multiply(0.5);
        // Project in the negative Z direction down to the floor.
        XYZ rayDirection = new XYZ(0, 0, -1);
        ElementClassFilter filter = new ElementClassFilter(typeof(Floor));
        ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D);
        ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, rayDirection);
        Reference reference = referenceWithContext.GetReference();
        XYZ intersection = reference.GlobalPoint;
        // Create line segment from the start point and intersection point.
        Line result = Line.CreateBound(center, intersection);
        return result;
    }
} Copy  VB.NET
 Copy  VB.NET <Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)> _
<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)> _
Public Class RayProjection
    Implements IExternalCommand
    Public Function Execute(revit As ExternalCommandData, ByRef message As String, elements As ElementSet) As Autodesk.Revit.UI.Result Implements IExternalCommand.Execute
        Dim doc As Document = revit.Application.ActiveUIDocument.Document
        Dim selectedIds As ICollection(Of ElementId) = revit.Application.ActiveUIDocument.Selection.GetElementIds()
        ' If skylight is selected, process it.
        Dim skylight As FamilyInstance = Nothing
        If selectedIds.Count = 1 Then
            For Each id As ElementId In selectedIds
                Dim e As Element = doc.GetElement(id)
                If TypeOf e Is FamilyInstance Then
                    Dim instance As FamilyInstance = TryCast(e, FamilyInstance)
                    Dim isWindow As Boolean = (instance.Category.Id.IntegerValue = CInt(BuiltInCategory.OST_Windows))
                    Dim isHostedByRoof As Boolean = (instance.Host.Category.Id.IntegerValue = CInt(BuiltInCategory.OST_Roofs))
                    If isWindow AndAlso isHostedByRoof Then
                        skylight = instance
                    End If
                End If
            Next
        End If
        If skylight Is Nothing Then
            message = "Please select one skylight."
            Return Result.Cancelled
        End If
        ' Calculate the height
        Dim line As Line = CalculateLineAboveFloor(doc, skylight)
        ' Create a model curve to show the distance
        Dim plane As Plane = revit.Application.Application.Create.NewPlane(New XYZ(1, 0, 0), line.GetEndPoint(0))
        Dim sketchPlane__1 As SketchPlane = SketchPlane.Create(doc, plane)
        Dim curve As ModelCurve = doc.Create.NewModelCurve(line, sketchPlane__1)
        ' Show a message with the length value
        TaskDialog.Show("Distance", "Distance to floor: " & [String].Format("{0:f2}", line.Length))
        Return Result.Succeeded
    End Function
    ' <summary>
    ' Determines the line segment that connects the skylight to the nearest floor.
    ' </summary>
    ' <returns>The line segment.</returns>
    Private Function CalculateLineAboveFloor(doc As Document, skylight As FamilyInstance) As Line
        ' Find a 3D view to use for the ReferenceIntersector constructor
        Dim collector As New FilteredElementCollector(doc)
        Dim isNotTemplate As Func(Of View3D, Boolean) = Function(v3) Not (v3.IsTemplate)
        Dim view3D As View3D = collector.OfClass(GetType(View3D)).Cast(Of View3D)().First(isNotTemplate)
        ' Use the center of the skylight bounding box as the start point.
        Dim box As BoundingBoxXYZ = skylight.BoundingBox(view3D)
        Dim center As XYZ = box.Min.Add(box.Max).Multiply(0.5)
        ' Project in the negative Z direction down to the floor.
        Dim rayDirection As New XYZ(0, 0, -1)
        Dim filter As New ElementClassFilter(GetType(Floor))
        Dim refIntersector As New ReferenceIntersector(filter, FindReferenceTarget.Face, view3D)
        Dim referenceWithContext As ReferenceWithContext = refIntersector.FindNearest(center, rayDirection)
        Dim reference As Reference = referenceWithContext.GetReference()
        Dim intersection As XYZ = reference.GlobalPoint
        ' Create line segment from the start point and intersection point.
        Dim result As Line = Line.CreateBound(center, intersection)
        Return result
    End Function
End Class