Similar to below perhaps:
Create DirectShape along path of picked points then use ElementIntersectsElement filter to get the elements. Rollback the transaction to remove the added shapes.
Things to consider:
- Tested for view plans only
- Should create DirectShape element whose vertical extent matches the view range (so that height of elements in view vs height of fence doesn't give unexpected results).
- Not verified the accuracy of the ElementIntersectsElement filter results.
VB.Net
Private Function TObj17(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData, _
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
Dim IntApp As UIApplication = commandData.Application
Dim UIDoc As UIDocument = IntApp.ActiveUIDocument
If UIDoc Is Nothing Then Return Result.Cancelled Else
Dim IntDoc As Document = UIDoc.Document
Dim Mls As New List(Of Element)
Dim LastEp As XYZ = Nothing
Dim Selection As New List(Of ElementId)
Dim GetPipeShp = Function(Pt1 As XYZ, Pt2 As XYZ) As DirectShape
Const Rad As Double = 50 / 304.8 '50mm
Dim LN As Line = Line.CreateBound(Pt1, Pt2)
Dim T As Transform = LN.ComputeDerivatives(0, True)
Dim P As Plane = Plane.CreateByNormalAndOrigin(T.BasisX.Normalize, LN.GetEndPoint(0))
Dim a1 As Arc = Arc.Create(P, Rad, 0, Math.PI)
Dim a2 As Arc = Arc.Create(P, Rad, Math.PI, Math.PI * 2)
Dim CL As List(Of CurveLoop) = New CurveLoop(0) {CurveLoop.Create(New Curve(1) {a1, a2}.ToList)}.ToList
Dim CL_P As CurveLoop = CurveLoop.Create(New Curve(0) {LN}.ToList)
Dim S As Solid = GeometryCreationUtilities.CreateSweptGeometry(CL_P, 0, LN.GetEndParameter(0), CL)
Dim Out As DirectShape = Nothing
Using Tx As New SubTransaction(IntDoc)
If Tx.Start = TransactionStatus.Started Then
Out = DirectShape.CreateElement(IntDoc, New ElementId(BuiltInCategory.OST_GenericModel))
Out.AppendShape(New GeometryObject(0) {S})
Tx.Commit()
End If
End Using
Return Out
End Function
Using Tx As New Transaction(IntDoc, "Fence")
If Tx.Start = TransactionStatus.Started Then
Using ST As New SubTransaction(IntDoc)
If ST.Start = TransactionStatus.Started Then
Dim Plane As Plane = Plane.CreateByNormalAndOrigin(IntDoc.ActiveView.ViewDirection, IntDoc.ActiveView.Origin)
IntDoc.ActiveView.SketchPlane = SketchPlane.Create(IntDoc, Plane)
ST.Commit()
End If
End Using
While True
Try
Dim XYZ As XYZ = UIDoc.Selection.PickPoint("Pick points then press escape to cause an exception ahem...exit selection")
If LastEp Is Nothing Then
LastEp = XYZ
Else
Dim Dist As Double = LastEp.DistanceTo(XYZ)
If Dist <= IntApp.Application.ShortCurveTolerance Then
Continue While
End If
Dim El As Element = GetPipeShp(LastEp, XYZ)
If El Is Nothing = False Then
Mls.Add(El)
End If
IntDoc.Regenerate()
LastEp = XYZ
End If
Catch ex As Exception
Exit While
End Try
End While
End If
If Mls.Count > 0 Then
Dim FEC As New FilteredElementCollector(IntDoc, IntDoc.ActiveView.Id)
Dim EF As ElementFilter = Nothing
If Mls.Count = 1 Then
EF = New ElementIntersectsElementFilter(Mls(0))
Else
Dim Filts As New List(Of ElementFilter)
For Each item As Element In Mls
Dim EIE As New ElementIntersectsElementFilter(item)
Filts.Add(EIE)
Next
EF = New LogicalOrFilter(Filts)
End If
Selection = FEC.WherePasses(EF).ToElementIds
End If
Tx.RollBack()
End Using
TaskDialog.Show("Count", CStr(Selection.Count))
Return Result.Succeeded
End Function
C#
public Result TObj17(Autodesk.Revit.UI.ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
UIApplication IntApp = commandData.Application;
UIDocument UIDoc = IntApp.ActiveUIDocument;
if (UIDoc == null)
return Result.Cancelled;
Document IntDoc = UIDoc.Document;
List<Element> Mls = new List<Element>();
XYZ LastEp = null;
ICollection<ElementId> Selection = new List<ElementId>();
Func<XYZ,XYZ,Element> GetPipeShp;
GetPipeShp = (XYZ Pt1, XYZ Pt2) =>
{
const double Rad = 50 / 304.8;
//50mm
Line LN = Line.CreateBound(Pt1, Pt2);
Transform T = LN.ComputeDerivatives(0, true);
Plane P = Plane.CreateByNormalAndOrigin(T.BasisX.Normalize(), LN.GetEndPoint(0));
Arc a1 = Arc.Create(P, Rad, 0, Math.PI);
Arc a2 = Arc.Create(P, Rad, Math.PI, Math.PI * 2);
List<CurveLoop> CL = new CurveLoop[1] { CurveLoop.Create(new Curve[2] {
a1,
a2
}.ToList()) }.ToList();
CurveLoop CL_P = CurveLoop.Create(new Curve[1] { LN }.ToList());
Solid S = GeometryCreationUtilities.CreateSweptGeometry(CL_P, 0, LN.GetEndParameter(0), CL);
DirectShape Out = null;
using (SubTransaction Tx = new SubTransaction(IntDoc))
{
if (Tx.Start() == TransactionStatus.Started)
{
Out = DirectShape.CreateElement(IntDoc, new ElementId(BuiltInCategory.OST_GenericModel));
Out.AppendShape(new GeometryObject[1] { S });
Tx.Commit();
}
}
return Out;
};
using (Transaction Tx = new Transaction(IntDoc, "Fence"))
{
if (Tx.Start() == TransactionStatus.Started)
{
using (SubTransaction ST = new SubTransaction(IntDoc))
{
if (ST.Start() == TransactionStatus.Started)
{
Plane Plane = Plane.CreateByNormalAndOrigin(IntDoc.ActiveView.ViewDirection, IntDoc.ActiveView.Origin);
IntDoc.ActiveView.SketchPlane = SketchPlane.Create(IntDoc, Plane);
ST.Commit();
}
}
Boolean EndWhile = false;
while (EndWhile == false)
{
try
{
XYZ XYZ = UIDoc.Selection.PickPoint("Pick points then press escape to cause an exception ahem...exit selection");
if (LastEp == null)
{
LastEp = XYZ;
}
else
{
double Dist = LastEp.DistanceTo(XYZ);
if (Dist <= IntApp.Application.ShortCurveTolerance)
{
continue;
}
Element El = GetPipeShp(LastEp, XYZ);
if (El == null == false)
{
Mls.Add(El);
}
IntDoc.Regenerate();
LastEp = XYZ;
}
}
catch
{
EndWhile = true;
break; // TODO: might not be correct. Was : Exit While
}
}
}
if (Mls.Count > 0)
{
FilteredElementCollector FEC = new FilteredElementCollector(IntDoc, IntDoc.ActiveView.Id);
ElementFilter EF = null;
if (Mls.Count == 1)
{
EF = new ElementIntersectsElementFilter(Mls.First());
}
else
{
List<ElementFilter> Filts = new List<ElementFilter>();
foreach (Element item in Mls)
{
ElementIntersectsElementFilter EIE = new ElementIntersectsElementFilter(item);
Filts.Add(EIE);
}
EF = new LogicalOrFilter(Filts);
}
Selection = FEC.WherePasses(EF).ToElementIds();
}
Tx.RollBack();
}
TaskDialog.Show("Count", Convert.ToString(Selection.Count));
return Result.Succeeded;
}