hi everyone ,
i want to make an automatic line for family like l shape. i made this code . The line connecting the family did not meet what I expected. kindly tell me what is wrong in this code.
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PlaceDim
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
try
{
// Prompt the user to select multiple elements
var selectedElements = uidoc.Selection.PickObjects(ObjectType.Element, "Select multiple families (or elements)");
if (selectedElements.Count < 2)
{
message = "Please select at least two elements.";
return Result.Failed;
}
// Get the points of the selected elements
List<XYZ> points = new List<XYZ>();
foreach (var selected in selectedElements)
{
Element element = doc.GetElement(selected);
LocationPoint location = element.Location as LocationPoint;
if (location == null)
{
message = "Selected elements must have valid location points.";
return Result.Failed;
}
points.Add(location.Point);
}
if (points.Count < 2)
{
message = "Failed to retrieve sufficient points from selected elements.";
return Result.Failed;
}
// Remove duplicate points using a HashSet
HashSet<XYZ> uniquePoints = new HashSet<XYZ>(points);
// Convert the HashSet back to a List (to allow sorting)
points = uniquePoints.ToList();
// Sort the points in ascending order first by X, then by Y
points = points.OrderBy(p => p.X).ThenBy(p => p.Y).ToList();
// Get the active view's plane
View activeView = doc.ActiveView;
Plane viewPlane = Plane.CreateByNormalAndOrigin(activeView.ViewDirection, activeView.Origin);
// Start transaction to draw lines
using (Transaction tx = new Transaction(doc, "Create 90 Degree L-shaped Lines"))
{
tx.Start();
// Create the SketchPlane inside the transaction
SketchPlane sketchPlane = SketchPlane.Create(doc, viewPlane);
if (sketchPlane == null)
{
message = "Failed to create sketch plane.";
return Result.Failed;
}
// Iterate through sorted points and create L-shaped lines
for (int i = 0; i < points.Count - 1; i++)
{
XYZ startPoint = ProjectOntoPlane(points[i], viewPlane);
XYZ endPoint = ProjectOntoPlane(points[i + 1], viewPlane);
// If the points are in the same horizontal (X) or vertical (Y) direction, create a single line
if (startPoint.X == endPoint.X) // Vertical line
{
Line verticalLine = Line.CreateBound(startPoint, endPoint);
doc.Create.NewDetailCurve(activeView, verticalLine);
}
else if (startPoint.Y == endPoint.Y) // Horizontal line
{
Line horizontalLine = Line.CreateBound(startPoint, endPoint);
doc.Create.NewDetailCurve(activeView, horizontalLine);
}
else
{
// Create an L-shaped line (90-degree turn)
// First, create a horizontal line from the start to the same X as the endPoint
XYZ horizontalEnd = new XYZ(endPoint.X, startPoint.Y, startPoint.Z);
Line horizontalLine = Line.CreateBound(startPoint, horizontalEnd);
doc.Create.NewDetailCurve(activeView, horizontalLine);
// Second, create a vertical line from horizontalEnd to the endPoint
Line verticalLine = Line.CreateBound(horizontalEnd, endPoint);
doc.Create.NewDetailCurve(activeView, verticalLine);
}
}
tx.Commit();
}
return Result.Succeeded;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
catch (Exception ex)
{
message = $"Error: {ex.Message} \nStackTrace: {ex.StackTrace}";
return Result.Failed;
}
}
private XYZ ProjectOntoPlane(XYZ point, Plane plane)
{
// Project a point onto a given plane
XYZ normal = plane.Normal;
double distance = normal.DotProduct(point - plane.Origin);
return point - distance * normal;
}
}
} the first image actual result from code
![thsa2501_0-1735891506819.png thsa2501_0-1735891506819.png]()
I want like this
![thsa2501_1-1735891569389.png thsa2501_1-1735891569389.png]()