ReferenceIntersector Class


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#
public class ReferenceIntersector : IDisposable
Visual Basic
Public Class ReferenceIntersector _
	Implements IDisposable
Visual C++
public ref class ReferenceIntersector : IDisposable

Examples

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

Inheritance Hierarchy

System Object
Autodesk.Revit.DB ReferenceIntersector

See Also