Hello,
I tried to complete this task, but the selection between the two points is unstable. Sometimes, the script selects all the axes, sometimes it works correctly, and other times it doesn't work at all. Could you please help identify the error?
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;
try
{
// Ask the user to select two points
XYZ point1 = uidoc.Selection.PickPoint("Select the first point");
XYZ point2 = uidoc.Selection.PickPoint("Select the second point");
// Filter all elements of type Grid in the document
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> grids = collector.OfClass(typeof(Grid)).ToElements();
// List to store curves between the two points
List<Curve> curvesBetweenPoints = new List<Curve>();
// Iterate through the grids and check if their curve passes between the two points
foreach (Element element in grids)
{
Grid grid = element as Grid;
if (grid != null)
{
Curve curve = grid.Curve;
// Check if the curve is between the two points
if (IsCurveBetweenPoints(curve, point1, point2))
{
curvesBetweenPoints.Add(curve);
}
}
}
// Display the number of curves found
TaskDialog.Show("Result", $"Number of curves found between the two points: {curvesBetweenPoints.Count}");
Selection sel = uidoc.Selection;
sel.SetElementIds(curvesBetweenPoints.Select(c => c.Reference.ElementId).ToList());
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
// Handle user cancellation
message = "Operation canceled by the user.";
return Result.Cancelled;
}
catch (System.Exception ex)
{
message = ex.Message;
return Result.Failed;
}
return Result.Succeeded;
}
private bool IsCurveBetweenPoints(Curve curve, XYZ point1, XYZ point2)
{
// Check if the projections of the curve's endpoints on the line are between the two points
XYZ startProjection = ProjectPointOnLine(curve.GetEndPoint(0), point1, point2);
XYZ endProjection = ProjectPointOnLine(curve.GetEndPoint(1), point1, point2);
bool isStartBetween = IsPointOnSegment(startProjection, point1, point2);
bool isEndBetween = IsPointOnSegment(endProjection, point1, point2);
return isStartBetween || isEndBetween;
}
private XYZ ProjectPointOnLine(XYZ point, XYZ linePoint1, XYZ linePoint2)
{
// Calculate the direction vector of the line
XYZ lineDirection = (linePoint2 - linePoint1).Normalize();
// Calculate the projection of the point on the line
XYZ vector = point - linePoint1;
double projectionLength = vector.DotProduct(lineDirection);
return linePoint1 + projectionLength * lineDirection;
}
private bool IsPointOnSegment(XYZ point, XYZ start, XYZ end, double tolerance = 1e-6)
{
// Check if a projected point is on a segment defined by start and end with a tolerance
double segmentLength = start.DistanceTo(end);
double distToStart = point.DistanceTo(start);
double distToEnd = point.DistanceTo(end);
// The point is on the segment if the sum of the distances to the start and end is approximately equal to the length of the segment
return Math.Abs((distToStart + distToEnd) - segmentLength) < tolerance;
}