I’m in the process of converting this script into Python, and I have hit a wall.
Particularly, in the curve.Intersect function, the function passes an argument by-reference, instead of by-value, using the ‘out’ functionality of C Sharp, which isn’t available in Python. This Iron Python page suggests two solutions, but I have not been able to implement either of them successfully. I favor the implicit approach, but if I have to use the explicit approach, how can I pass Array[Type] into clr.Reference[]?
See my attempts below. The code ought to work if you have at least two gridlines set up in your project. Search for the word ‘Attempt’ to see where I’m struggling.
import clr
import array
from pyrevit import DB, revit, script, forms
from rpw import ui
doc = revit.doc
output = script.get_output()
selection = ui.Selection()
from Autodesk.Revit.UI import TaskDialog
# Function to find the nearest intersection point
def get_nearest_intersection_point():
selected_ids = selection.GetElementIds()
# Get intersection points from the get_intersections function
intersection_points = get_intersections(doc)
intersection = "??"
for selected_id in selected_ids:
elem = doc.GetElement(selected_id)
elem_point = elem.Location.Point
xyz = DB.XYZ(elem_point.X, elem_point.Y, 0)
distance_min = 0
distance = 0
# Find the minimum distance to an intersection point
first_intersection = list(intersection_points.values())[0]
distance_min = xyz.DistanceTo(first_intersection)
for key, point in intersection_points.items():
distance = xyz.DistanceTo(point)
if distance < distance_min:
distance_min = distance
intersection = key
distance_in_meter = distance_min / 3.281 # Convert to meters
TaskDialog.Show("Intersection", intersection)
# Function to build a dictionary of intersection points
def get_intersections(doc):
coordinate = None
coord_a = None
coord_b = None
coord_c = None
intersection_points = {}
# Collect all grid elements
grids = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Grids).WhereElementIsNotElementType().ToElements()
ref_grid = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Grids).WhereElementIsNotElementType().ToElements()
# Loop through all grid elements
for elem_1 in grids:
coord_a = elem_1.Name
c1 = elem_1.Curve
ref_grid.Remove(elem_1)
for elem_2 in ref_grid:
coord_b = elem_2.Name
c2 = elem_2.Curve
# Check if the two grid lines intersect
## Attempt 1 - Returns TypeError: 'SetComparisonResult' object is not iterable
# result, results = c1.Intersect(c2)
## Attempt 2 - Returns TypeError: expected StrongBox[IntersectionResultArray], got IntersectionResultArray
# results = DB.IntersectionResultArray()
# result = c1.Intersect(c2, results)
## Attempt 3 - Returns TypeError: expected Array[Type], got IntersectionResultArray
results = clr.Reference[DB.IntersectionResultArray()]()
result = c1.Intersect(c2, results)
print(result)
print(results)
if result != DB.SetComparisonResult.Overlap:
continue
if results is None or results.Size != 1:
continue
for i in range(results.Size):
i_result = results.get_Item(i)
coord_c = str(i)
coordinate = "{},{}-{}".format(coord_a,coord_b, coord_c)
point = i_result.XYZPoint
intersection_points[coordinate] = point
return intersection_points
# Call the get_nearest_intersection_point function
get_nearest_intersection_point()