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
Visual Basic |
---|
Public Class ReferenceIntersector _
Implements IDisposable |
Visual C++ |
---|
public ref class ReferenceIntersector : IDisposable |
Examples
CopyC#
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();
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;
}
Line line = CalculateLineAboveFloor(doc, skylight);
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);
TaskDialog.Show("Distance", "Distance to floor: " + String.Format("{0:f2}", line.Length));
return Result.Succeeded;
}
private Line CalculateLineAboveFloor(Document doc, FamilyInstance skylight)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
View3D view3D = collector.OfClass(typeof(View3D)).Cast<View3D>().First<View3D>(isNotTemplate);
BoundingBoxXYZ box = skylight.get_BoundingBox(view3D);
XYZ center = box.Min.Add(box.Max).Multiply(0.5);
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;
Line result = Line.CreateBound(center, intersection);
return result;
}
}
CopyVB.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()
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
Dim line As Line = CalculateLineAboveFloor(doc, skylight)
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)
TaskDialog.Show("Distance", "Distance to floor: " & [String].Format("{0:f2}", line.Length))
Return Result.Succeeded
End Function
Private Function CalculateLineAboveFloor(doc As Document, skylight As FamilyInstance) As Line
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)
Dim box As BoundingBoxXYZ = skylight.BoundingBox(view3D)
Dim center As XYZ = box.Min.Add(box.Max).Multiply(0.5)
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
Dim result As Line = Line.CreateBound(center, intersection)
Return result
End Function
End Class
Inheritance Hierarchy
See Also